0% found this document useful (0 votes)
134 views262 pages

A Project Submitted in Partial Fulfillment of The Requirements For The Degree of

This document is a project submission for an MCA degree by Anshika Jindal at SVSU University in Meerut, India. It includes an undertaking signed by the student, a certificate signed by the supervisor Mr. Sanjeev Panwar, and an introduction outlining the goal of developing a web-based interface for an online electronics shop.

Uploaded by

anshika basuta
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
134 views262 pages

A Project Submitted in Partial Fulfillment of The Requirements For The Degree of

This document is a project submission for an MCA degree by Anshika Jindal at SVSU University in Meerut, India. It includes an undertaking signed by the student, a certificate signed by the supervisor Mr. Sanjeev Panwar, and an introduction outlining the goal of developing a web-based interface for an online electronics shop.

Uploaded by

anshika basuta
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 262

ONLINE ELECTRONIC SHOP

A project submitted
in partial fulfillment of the requirements
for the degree of
MCA
By
ANSHIKA JINDAL

1906000001794

DEPARTMENT OF COMPUTER APPLICATION

KERAL VERMA SUBHARTI COLLEGE OF SCIENCE

SWAMI VIVEKANAND SUBHARTI UNIVERSITY, MEERUT, UP


January , 2024

i
UNDERTAKING

I declare that the work presented in this project titled “ONLINE


ELECTRONIC SHOP ”, submitted to the Name of the Department,
Keral Verma Subharti College of Science (SVSU), Meerut for the
award of the Course name degree is my original work. I have not
plagiarized or submitted the same work for the award of any other
degree. In case this undertaking is found incorrect, I accept that my
degree may be unconditionally withdrawn.

January , 2024 (Student signature & Name)


Meerut ANSHIKA JINDAL

ii
iii
CERTIFICATE BY SUPERVISOR

Certified that the work contained in the project titled ““ONLINE


ELECTRONIC SHOP ”, by ANSHIKA JINDAL, has been carried
out under my supervision and that this work has not been submitted
elsewhere for a degree.

Supervisor Name: MR. SANJEEV PANWAR


Dept. Name : COMPUTER APPLICATION
K.V.SUBHARTI COLLEGE OF SCIENCE

iv
Preface

Writing a effective preface is very important and plays an important


role whether you plan to work in an industry or wish to take up
academics as a way of life.

Your project should prudently combine theory with practice. It


should result in a apprehension of reasonably intricate system
(software and/or hardware). Given various restrictions, it is always
better to expand your predecessor’s work. If you plan it suitably, you
can really build on the familiarity of your seniors.

v
Acknowledgements

I take upon this opportunity to acknowledge the many people who help me. I am
deeply indebted to my mentor MR. SANJEEV PANWAR. I would like to thank
MR. HIMANSHU SIROHI . I further thank to DR. SHASHIRAJ TEOTIA. I owe
my sincere gratitude towards all my teachers. My heartfelt thanks to you all. I also
express my deepest gratitude to MR. SANJEEV PANWAR

Finally, I would like to wind up by paying my heartfelt thanks to DR. SHASHIRAJ


TEOTIA

ANSHIKA JINDAL

vi
Table of Contents

Undertaking.....................................................................ii

Abstract. .........................................................................iii

Certificate by supervisor.................................................iv

Preface.............................................................................v

Acknowledgements ........................................................vi

1 Introduction..................................................................vii

1.1 Motivation....................…………..……...……….viii
1.2 Problem and solutions.............................................ix
1.1.1 Some Important Remarks .…..……………………x
1.1.2 Solutions..................................................................1
1.1.3 Scope........................................................................2
1.1.4 Platform Specifications ...........................................3
2 Code of the project...................................................4-205
3 Related work.............................................................206-241
4 Conclusion................................................................242
5 References ................................................................245

vii
1. Introduction

1.1 Goal
Shopping has long been considered a recreational activity by many.
Shopping online is no exception. The goal of this application is to
develop a web based interface for online retailers. The system would
be easy to use and hence make the shopping experience pleasant for
the users. The goal of this application is


To develop an easy to use web based interface where users can

search for products, view a complete description of the

products and order the products.



A search engine that provides an easy and convenient way to
search for products specific to their needs. The search engine
would list a set of products based on the search term and the
user can further filter the list based on various parameters.

An AJAX enabled website with the latest AJAX controls

giving attractive and interactive look to the web pages and

prevents the annoying post backs.

viii

Drag and Drop feature which would allow the users to add a
product to or remove a product from the shopping cart by
dragging the product in to the shopping cart or out of the
shopping cart.


A user can view the complete specification of the product
along with various images and also view the customer reviews
of the product. They can also write their own reviews.

1.2 Need of the application


There are large numbers of commercial Online Shopping websites
offering large number of products tailored to meet the shopping
interests of large number of customers. These online marketplaces
have thousands of products listed under various categories.

Problem:

• The basic problems with the existing systems are the non-interactive
environment they provide to the users.
• The use of traditional user interfaces which make continuous post backs to
the server; each post back makes a call to the server, gets the response and
then refreshes the entire web form to display the result. This scenario adds an
extra trade off causing a delay in displaying the results
• A search engine that would display the results without allowing the users to
further filter the results based on various parameters.

ix
Solution:

• The motive of this Online Shopping Web Application is to


allow the user to play with the search tool and create different
combinatorial search criterion to perform exhaustive search.

• Making the application AJAX enabled gets rid of these


unnecessary delays letting the user to perform exhaustive
search. The users of this application can easily feel the
difference between the Ajax empowered user interfaces vs.
traditional user interfaces.

• Provide Interactive interface through which a user can interact

with different areas of application easily.

• A search engine that provides an easy and convenient way to


search for products specific to their needs. The search engine
would list a set of products based on the search term and the
user can further filter the list based on various parameters.

• Provide Drag and Drop feature thereby allowing the user to


add products to or remove products from the shopping cart by
dragging the products in to or out of the shopping cart.
1.3 Scope
• The current system can be extended to allow the users to create

accounts and save products in to wish list.

• The users could subscribe for price alerts which would enable

them to receive messages when price for products fall below a

particular level.

• The current system is confined only to the shopping cart

process. It can be extended to have a easy to use check out

process.

• Users can have multiple shipping and billing information


saved. During checkout they can use the drag and drop feature
to select shipping and billing information.

2
1.4 Platform Specifications – Deployment
1.4.1 Hardware Specification

Processor P IV

RAM 250 MB

Minimum Space Required 100 MB


Display 16 bit color

1.4.2 Software Specification

Operating Environment Win 2000/XP

Platform .Net Framework & IIS Visual Studio 2008

Database SQL Server 2005

3
CODE OF THE PROJECT

Eclipse.preferences.version=1

Encoding//src/main/java=UTF-8

Encoding//src/main/resources=UTF-8

Encoding//src/test/java=UTF-8

Encoding/<project>=UTF-8

Eclipse.preferences.version=1

Org.eclipse.jdt.apt.aptEnabled=true

4
Org.eclipse.jdt.apt.genSrcDir=target\\generated-sources\\annotations
Org.eclipse.jdt.apt.genTestSrcDir=target\\generatedtestsources\\testannotat
ions

Eclipse.preferences.version=1

Org.eclipse.jdt.core.compiler.codegen.methodParameters=generate

Org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8

Org.eclipse.jdt.core.compiler.compliance=1.8

Org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled

Org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning

Org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore

Org.eclipse.jdt.core.compiler.processAnnotations=enabled

Org.eclipse.jdt.core.compiler.release=disabled

Org.eclipse.jdt.core.compiler.source=1.8

5
activeProfiles=

eclipse.preferences.version=1

resolveWorkspaceProjects=true

version=1 boot.validation.initialized=true

eclipse.preferences.version=1

package com.khomsi.site_project.configuration;

import org.springframework.context.annotation.Bean; import

org.springframework.context.annotation.Configuration;

import
org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

import org.springframework.security.crypto.password.PasswordEncoder;

6
@Configuration
Public class EncryptionConfig {

@Bean

Public PasswordEncoder encoder() {


Return new BCryptPasswordEncoder();

Package com.khomsi.site_project.configuration;

Import org.springframework.context.annotation.Bean;

Import org.springframework.context.annotation.Configuration; Import


org.springframework.web.servlet.LocaleResolver;

7
Import
org.springframework.web.servlet.config.annotation.InterceptorRegistry;
Import
org.springframework.web.servlet.config.annotation.WebMvcConfigurer
;

Import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;

Import org.springframework.web.servlet.i18n.SessionLocaleResolver;

Import java.util.Locale;

@Configuration

Public class WebConfig implements WebMvcConfigurer {

//Declare default language

@Bean

Public LocaleResolver localeResolver() {


SessionLocaleResolver localeResolver = new

SessionLocaleResolver();

8
localeResolver.setDefaultLocale(Locale.US);

return localeResolver;

@Bean

Public LocaleChangeInterceptor localeChangeInterceptor() {


LocaleChangeInterceptor localeChangeInterceptor = new
LocaleChangeInterceptor();

//When change to dif lang, we need to pass params by

url localeChangeInterceptor.setParamName(“lang”);

return localeChangeInterceptor;

@Override

Public void addInterceptors(InterceptorRegistry registry) {

Registry.addInterceptor(localeChangeInterceptor());

}
}

9
Package com.khomsi.site_project.configuration;

Import com.khomsi.site_project.entity.Role;

Import org.springframework.beans.factory.annotation.Autowired;

Import org.springframework.context.annotation.Bean;

Import
org.springframework.security.config.annotation.authentication.builders.A
u thenticationManagerBuilder;

Import
org.springframework.security.config.annotation.web.builders.HttpSecurity
;

Import

10
org.springframework.security.config.annotation.web.configuration.Enabl
e WebSecurity; Import
org.springframework.security.config.annotation.web.configuration.WebSe
curityConfigurerAdapter;
Import
org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

Import org.springframework.security.crypto.password.PasswordEncoder;
Import
org.springframework.security.web.util.matcher.AntPathRequestMatcher;
Import javax.sql.DataSource;

@EnableWebSecurity
Public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired

Private DataSource dataSource;

@Autowired

Private PasswordEncoder passwordEncoder;

/*

loginPage() – the custom login page

loginProcessingUrl() – the URL to submit the username and


11
password defaultSuccessUrl() – the landing page after a

successful login failureUrl() – the landing page after an

unsuccessful login

*/

//
@Override
Protected void configure(HttpSecurity http) throws Exception {

// http.csrf().disable().authorizeRequests()
http.authorizeRequests().antMatchers(“/admin/**”).hasAuthority(Role.A
DMIN.getAuthority())

.antMatchers(“/js/**”, “/css/**”, “/**”).permitAll()

.anyRequest().authenticated()

.and()

.formLogin()

.loginPage(“/login”)

.loginProcessingUrl(“/login”)

.defaultSuccessUrl(“/”, true)

12
.permitAll()

.and()

.logout().logoutSuccessUrl(“/”)

.logoutRequestMatcher(new
AntPathRequestMatcher(“/logout”)).permitAll().and().exceptionHandling(
)

.accessDeniedPage(“/error403”);

@Override
Protected void configure(AuthenticationManagerBuilder auth) throws
Exception {

Auth.jdbcAuthentication().dataSource(dataSource)
.passwordEncoder(passwordEncoder)
.usersByUsernameQuery(“select login, password, ‘true’ as
enabled from user where login=?”)
.authoritiesByUsernameQuery(“select login, role from user
where login=?”);

Package com.khomsi.site_project.controller;
13
Import com.khomsi.site_project.entity.*;

Import com.khomsi.site_project.exception.CategoryNotFoundException;

Import com.khomsi.site_project.exception.OrderNotFoundException;

Import com.khomsi.site_project.exception.ProductNotFoundException;

Import com.khomsi.site_project.exception.UserNotFoundException;

Import com.khomsi.site_project.service.*;
Import org.springframework.beans.factory.annotation.Autowired;

Import org.springframework.data.domain.Page;

Import org.springframework.data.repository.query.Param;
Import org.springframework.stereotype.Controller;

Import org.springframework.ui.Model;

Import org.springframework.web.bind.annotation.*;

Import org.springframework.web.servlet.mvc.support.RedirectAttributes;

Import org.webjars.NotFoundException;

14
Import java.util.List;

@Controller

@RequestMapping(“/admin”)

Public class AdminController {

@Autowired

Private ProductService productService;

@Autowired

Private UserService userService;


@Autowired

Private UserInfoService userInfoService;

@Autowired

Private CategoryService categoryService;


@Autowired

Private VendorService vendorService;

15
@Autowired

Private OrdersService ordersService;

@Autowired

Private OrderBasketService orderBasketService;

@Autowired

Private AdminTools adminTools; @GetMapping({“”, “/”, “/admin-


panel”})

Public String showAdminPanel() {

Return “admin/admin-panel”;

@GetMapping(“/products”)

Public String listProductsFirstPage(Model model) { Return


adminTools.listProductsByPage(1, model, “title”, “asc”, null,
0);

16
@GetMapping(“/products/edit/{id}”)
Public String updateProduct(@PathVariable(name = “id”) int id, Model
model, RedirectAttributes attributes) {

Try {

Product product = productService.getProduct(id);

List<Vendor> vendorList = vendorService.getAllVendors();


List<Category> categoryList =
categoryService.listCategoriesUserInForm();

Model.addAttribute(“product”, product);

Model.addAttribute(“vendorList”, vendorList);

Model.addAttribute(“categoryList”, categoryList);
} catch (ProductNotFoundException e) {

Attributes.addFlashAttribute(“message”, e.getMessage());

Return “redirect:/admin/product/products”;

Return “admin/product/product_form”;

@GetMapping(“/products/new”)
Public String addProduct(Model model) {
17
List<Vendor> vendorList = vendorService.getAllVendors();
List<Category> categoryList =
categoryService.listCategoriesUserInForm();
Model.addAttribute(“product”, new Product());
Model.addAttribute(“vendorList”, vendorList);
Model.addAttribute(“categoryList”, categoryList);

Return “admin/product/product_form”;

}
@PostMapping(“/products/save”)

Public String saveProduct(Product product, RedirectAttributes redirect)


{

productService.saveProduct(product);

redirect.addFlashAttribute(“message”, “The product was saved

successfully”); return “redirect:/admin/products”;

@GetMapping(“/products/delete/{id}”)

18
Public String deleteProduct(@PathVariable(name = “id”) Integer id,

RedirectAttributes redirect) { Try {

productService.deleteProduct(id);

redirect.addFlashAttribute(“message”,

“The product ID “ + id + “ has been deleted successfully”);


} catch (ProductNotFoundException e) {

Redirect.addFlashAttribute(“message”, e.getMessage());

Return “redirect:/admin/products”;

@GetMapping(“/users”)
Public String listUsersFirstPage(Model model) {

Return adminTools.listUsersByPage(1, model);

@GetMapping(“/users/new”)

Public String newUser(Model model) {

Model.addAttribute(“user”, new User());

Model.addAttribute(“userInfo”, new UserInfo());


19
Model.addAttribute(“roles”, Role.values());

Return “admin/user/user_form”;

}
@PostMapping(“/users/save”)

Public String createUser(UserInfo userInfo, User user,


RedirectAttributes redirect) {
User.setUserInfo(userInfo); userInfo.setUser(user);

userService.saveUser(user);

redirect.addFlashAttribute(“message”, “The user was saved

successfully”);

return “redirect:/admin/users”;

@GetMapping(“/users/edit/{id}”)
Public String updateUser(@PathVariable(name = “id”) int id, Model
model, RedirectAttributes redirect) {

Try {

User user = userService.getUser(id);

20
UserInfo userInfo = userInfoService.getUserDetail(id);

Model.addAttribute(“user”, user);

Model.addAttribute(“userInfo”, userInfo);
Model.addAttribute(“roles”, Role.values());

} catch (UserNotFoundException e) {

Redirect.addFlashAttribute(“message”, e.getMessage());

Return “redirect:/admin/users”;

Return “admin/user/user_form”; }

@GetMapping(“/users/delete/{id}”)
Public String deleteUser(@PathVariable(name = “id”) Integer id,
RedirectAttributes redirect) {

Try { userService.deleteUser(id);

redirect.addFlashAttribute(“message”,

“The user ID “ + id + “ has been deleted successfully”);

} catch (UserNotFoundException e) {

Redirect.addFlashAttribute(“message”, e.getMessage());

21
}

Return “redirect:/admin/users”;

@GetMapping(“/categories”)
Public String listCategoriesFirstPage(Model model) {

Return adminTools.listCategoriesByPage(1, model);

@GetMapping(“/categories/edit/{id}”)

Public String updateCategory(@PathVariable int id, Model model,


RedirectAttributes attributes) {
Try {
Category category = categoryService.getCategory(id);
List<Category> categoryList =
categoryService.listCategoriesUserInForm();

Model.addAttribute(“category”, category);

Model.addAttribute(“categoryList”, categoryList);

Return “admin/category/category_form”;

22
} catch (CategoryNotFoundException e) {

Attributes.addFlashAttribute(“message”, e.getMessage());

Return “redirect:/admin/categories”;

@GetMapping(“/categories/new”)
Public String addCategory(Model model) {

List<Category> categoryList =
categoryService.listCategoriesUserInForm();

// Category category = new Category();

Model.addAttribute(“category”, new Category());

Model.addAttribute(“categoryList”, categoryList);

Return “admin/category/category_form”; }

@PostMapping(“/categories/save”)
Public String saveCategory(@ModelAttribute Category category,
RedirectAttributes attributes) {

23
categoryService.saveCategory(category);
attributes.addFlashAttribute(“message”, “The category has been
saved successfully”); return “redirect:/admin/categories”;

@GetMapping(“/categories/delete/{id}”)

Public String deleteCategory(@PathVariable(name = “id”) Integer id,

RedirectAttributes redirect) { Try {

categoryService.deleteCategory(id);

redirect.addFlashAttribute(“message”,

“The category ID “ + id + “ has been deleted successfully”);

} catch (CategoryNotFoundException e) {

Redirect.addFlashAttribute(“message”, e.getMessage());
}

Return “redirect:/admin/categories”;

@GetMapping(“/vendors”)

24
Public String listVendorsFirstPage(Model model) {

Return adminTools.listVendorsByPage(1, model);

@GetMapping(“/vendors/new”)

Public String newVendor(Model model) {

Model.addAttribute(“vendor”, new Vendor());

Return “admin/vendor/vendor_form”;
}

@PostMapping(“/vendors/save”)

Public String createVendor(Vendor vendor, RedirectAttributes redirect)


{

vendorService.saveVendor(vendor);

redirect.addFlashAttribute(“message”, “The vendor was saved

successfully”); return “redirect:/admin/vendors”;

}
@GetMapping(“/vendors/edit/{id}”)
Public String updateVendor(@PathVariable(name = “id”) int id, Model
model, RedirectAttributes redirect) {

Try {

25
Vendor vendor = vendorService.getVendor(id);

Model.addAttribute(“vendor”, vendor);

} catch (NotFoundException e) {

Redirect.addFlashAttribute(“message”, e.getMessage());

Return “redirect:/admin/vendors”;

Return “admin/vendor/vendor_form”;

@GetMapping(“/vendors/delete/{id}”)
Public String deleteVendor(@PathVariable(name = “id”) Integer id,

RedirectAttributes redirect) { Try {

vendorService.deleteVendor(id);

redirect.addFlashAttribute(“message”,

“The vendor ID “ + id + “ has been deleted successfully”);


} catch (NotFoundException e) {

Redirect.addFlashAttribute(“message”, e.getMessage());

26
}

Return “redirect:/admin/vendors”;
}

@GetMapping(“/orders”)

Public String listOrdersFirstPage(Model model) {

Return adminTools.listOrdersByPage(1, model);

@PostMapping(“/orders/save”)

Public String createOrder(Order order, RedirectAttributes redirect) {

ordersService.saveOrder(order);

redirect.addFlashAttribute(“message”, “The order was

saved successfully”); return “redirect:/admin/orders”;

@GetMapping(“/orders/edit/{id}”)

Public String updateOrder(@PathVariable(name = “id”) int id, Model


model, RedirectAttributes redirect) {

Try {
Order order = ordersService.getOrder(id);
27
Model.addAttribute(“orderTypes”, OrderType.values());

Model.addAttribute(“order”, order);
} catch (NotFoundException e) {

Redirect.addFlashAttribute(“message”, e.getMessage());

Return “redirect:/admin/orders”;

Return “admin/orders/order_form”;

@GetMapping(“/orders/delete/{id}”)

Public String deleteOrder(@PathVariable(name = “id”) Integer id,


RedirectAttributes redirect) {
Try { ordersService.deleteOrder(id);

redirect.addFlashAttribute(“message”,
“The orders ID “ + id + “ has been deleted successfully”);

} catch (OrderNotFoundException e) {

Redirect.addFlashAttribute(“message”, e.getMessage());

28
}

Return “redirect:/admin/orders”;

@GetMapping(“/order_baskets”)

Public String allOrderBasket(Model model) {


Try {

Model.addAttribute(“orderBaskets”,
orderBasketService.getAllOrderBaskets());

} catch (NotFoundException ex) {

Model.addAttribute(“error”,
ex.getCause().getCause().getMessage());

Return “/error/404”;

Return “admin/order_basket/order_baskets”;

29
Package com.khomsi.site_project.controller;

Import com.khomsi.site_project.entity.*;
Import com.khomsi.site_project.service.*;
Import org.springframework.beans.factory.annotation.Autowired;
Import org.springframework.data.domain.Page;
Import org.springframework.data.repository.query.Param;
Import org.springframework.stereotype.Controller;
Import org.springframework.ui.Model;
Import org.springframework.web.bind.annotation.GetMapping; Import
org.springframework.web.bind.annotation.PathVariable;
Import org.springframework.web.bind.annotation.PostMapping;
Import org.springframework.web.bind.annotation.ResponseBody;

30
Import java.util.List;

@Controller
Public class AdminTools {
@Autowired
Private UserService userService;
@Autowired
Private VendorService vendorService;
@Autowired
Private OrdersService ordersService;

@Autowired
Private ProductService productService;
@Autowired
Private CategoryService categoryService;

@PostMapping(“/users/check_login”)
Public @ResponseBody String checkLoginUnique(@Param(“id”)
Integer id, @Param(“login”) String login) {
Return userService.isLoginUnique(id, login);
}
/*
Added this method to check unique login for user while he’s registration
You can modify it to have more unique fields.

31
(if you need unique fields in admin panel for user, change another
methods like isLoginUnique)
*/
@PostMapping(“/user/check”) Public
@ResponseBody String
checkLoginRegistration(@Param(“login”) String login)
{
Return userService.checkLoginRegistration(login) ? “OK” :
“Duplicate”;
}
@PostMapping(“/categories/check”)
Public @ResponseBody String checkCategory(@Param(“id”) Integer
id, @Param(“title”) String title,
@Param(“alias”) String alias) {
Return categoryService.checkCategoryTitle(id, title, alias);
}
@PostMapping(“/vendors/check”)
Public @ResponseBody String checkVendor(@Param(“id”) Integer id,
@Param(“title”) String title) {
Return vendorService.checkVendorTitle(id, title);
}
//Controller in admin panel for users
@GetMapping(“/admin/users/page/{pageNum}”)

32
Public String listUsersByPage(@PathVariable(name = “pageNum”) int
pageNum, Model model) {
Page<User> page = userService.listByPage(pageNum);
List<User> listUsers = page.getContent();

Long startCount = (pageNum – 1) * UserService.USER_PER_PAGE


+ 1;
Long endCount = startCount + UserService.USER_PER_PAGE – 1;

pageCountMethod(pageNum, model, page, startCount, endCount);


model.addAttribute(“users”, listUsers);

return “admin/user/users”;
}
//Controller in admin panel for vendors
@GetMapping(“/admin/vendors/page/{pageNum}”)
Public String listVendorsByPage(@PathVariable(name = “pageNum”)
int pageNum, Model model) {
Page<Vendor> page = vendorService.listByPage(pageNum);
List<Vendor> vendorList = page.getContent();

Long startCount = (pageNum – 1) *


VendorService.VENDORS_PER_PAGE + 1;
Long endCount = startCount +
VendorService.VENDORS_PER_PAGE – 1;

33
pageCountMethod(pageNum, model, page, startCount, endCount);

model.addAttribute(“vendors”, vendorList);

return “admin/vendor/vendors”;
}
//Controller in admin panel for orders
@GetMapping(“/admin/orders/page/{pageNum}”)
Public String listOrdersByPage(@PathVariable(name = “pageNum”) int
pageNum, Model model) {
Page<Order> page = ordersService.listByPage(pageNum);
List<Order> orderList = page.getContent();

Long startCount = (pageNum – 1) *


OrdersService.ORDERS_PER_PAGE + 1;
Long endCount = startCount + OrdersService.ORDERS_PER_PAGE
– 1;

pageCountMethod(pageNum, model, page, startCount, endCount);

model.addAttribute(“orders”, orderList);

return “admin/orders/orders”;

34
}

//Controller in admin panel for categories to display pagination


@GetMapping(“/admin/categories/page/{pageNum}”)
Public String listCategoriesByPage(@PathVariable(name =
“pageNum”) int pageNum, Model model) {
CategoryPageInfo pageInfo = new CategoryPageInfo();
List<Category> categoryList = categoryService.listByPage(pageInfo,
pageNum);

Long startCount = (pageNum – 1) *


CategoryService.TOP_CATEGORIES_PER_PAGE + 1;
Long endCount = startCount +
CategoryService.TOP_CATEGORIES_PER_PAGE – 1;

If (endCount > pageInfo.getTotalElements()) {


endCount = pageInfo.getTotalElements();
}
Model.addAttribute(“totalPages”, pageInfo.getTotalPages());
Model.addAttribute(“totalItems”, pageInfo.getTotalElements());
Model.addAttribute(“startCount”, startCount);
Model.addAttribute(“endCount”, endCount);

Model.addAttribute(“currentPage”, pageNum);
Model.addAttribute(“categories”, categoryList);
35
Return “admin/category/categories”;
}
//Controller in admin panel for products
@GetMapping(“/admin/products/page/{pageNum}”)
Public String listProductsByPage(@PathVariable(name = “pageNum”)
int pageNum, Model model,
@Param(“sortField”) String sortField,
@Param(“sortDir”) String sortDir,
@Param(“keyword”) String keyword,
@Param(“categoryId”) Integer categoryId)
{ Page<Product> page =
productService.listByPage(pageNum, sortField, sortDir, keyword,
categoryId); List<Category> listCategories =
categoryService.listCategoriesUserInForm();

List<Product> productList = page.getContent();

Long startCount = (pageNum – 1) *


ProductService.PRODUCTS_PER_ADMIN_PAGE + 1;
Long endCount = startCount +
ProductService.PRODUCTS_PER_ADMIN_PAGE – 1;

36
If (endCount > page.getTotalElements()) {
endCount = page.getTotalElements();
}
String reverseSortDir = sortDir.equals(“asc”) ? “desc” : “asc”;

If (categoryId != null) model.addAttribute(“categoryId”,categoryId);

pageCountMethod(pageNum, model, page, startCount, endCount);


model.addAttribute(“products”, productList);
model.addAttribute(“sortField”, sortField); model.addAttribute(“sortDir”,
sortDir);
model.addAttribute(“reverseSortDir”, reverseSortDir);
model.addAttribute(“keyword”, keyword);
model.addAttribute(“listCategories”, listCategories);

return “admin/product/products”;
}
Public void pageCountMethod(@PathVariable(“pageNum”) int
pageNum, Model model, Page<?> page,
Long startCount, long endCount) {
If (endCount > page.getTotalElements()) {
endCount = page.getTotalElements();
}
Model.addAttribute(“currentPage”, pageNum);
Model.addAttribute(“totalPages”, page.getTotalPages());
Model.addAttribute(“startCount”, startCount);
Model.addAttribute(“endCount”, endCount);

37
Model.addAttribute(“totalItems”, page.getTotalElements());
}
}

Package com.khomsi.site_project.controller;

Import com.khomsi.site_project.entity.*;

38
Import com.khomsi.site_project.exception.ProductNotFoundException;
Import com.khomsi.site_project.repository.CategoryRepository;
Import com.khomsi.site_project.service.ProductService;
Import com.khomsi.site_project.service.UserService;
Import org.springframework.beans.factory.annotation.Autowired; Import
org.springframework.stereotype.Controller;
Import org.springframework.ui.Model;
Import org.springframework.web.bind.annotation.GetMapping;
Import org.springframework.web.bind.annotation.PostMapping;
Import org.webjars.NotFoundException;

Import java.security.Principal;
Import java.util.List;

@Controller
Public class MainController {
@Autowired
Private UserService userService;

@Autowired
Private CategoryRepository categoryRep;
@Autowired
Private ProductService productService;

39
@GetMapping(“/”)
Public String index(Model model) {
Model.addAttribute(“listCategories”, categoryRep.findAllEnabled());
Try {
Model.addAttribute(“listProducts”,
productService.getRandomAmountOfProducts());
} catch (ProductNotFoundException ex) {
Model.addAttribute(“error”,
ex.getCause().getCause().getMessage());
Return “/error/404”;
}
Return “index”;
}
@GetMapping(“/registration”)
Public String registration(Model model) {
Model.addAttribute(“user”, new User());
Model.addAttribute(“userInfo”, new UserInfo());
Return “registration”;
}
@PostMapping(“/registration”)
Public String registration(User user, UserInfo userInfo) {
User.setRole(Role.USER);
User.setUserInfo(userInfo);

40
userInfo.setUser(user);
userService.saveUser(user);
return “redirect:/”;
}
@GetMapping(“/basket”)
Public String showShoppingCard(Model model,
Principal principal) {
If (principal != null) {
List<OrderBasket> orderBaskets =
userService.getUserByLogin(principal.getName()).getOrderBaskets();
Model.addAttribute(“orderBaskets”, orderBaskets);
Model.addAttribute(“order”, new Order());
} else {
Model.addAttribute(“error”, new NotFoundException(“Order
basket was not found”));
Return “/error/404”;
}
Return “shopping-cart”;
}
@GetMapping(“/category”)
Public String showCategories(Model model) { List<Category>
listEnabledCategories =
categoryRep.findAllEnabled();
Model.addAttribute(“listCategories”, listEnabledCategories);
Return “category”;

41
}
}

42
Package com.khomsi.site_project.controller;

Import com.khomsi.site_project.entity.Order;
Import com.khomsi.site_project.entity.OrderBasket;
Import com.khomsi.site_project.entity.OrderType;
Import com.khomsi.site_project.entity.User;
Import com.khomsi.site_project.service.OrdersService;
Import com.khomsi.site_project.service.UserService;
Import org.springframework.beans.factory.annotation.Autowired;
Import org.springframework.core.io.ClassPathResource;
Import org.springframework.mail.javamail.JavaMailSender;
Import org.springframework.mail.javamail.MimeMessageHelper;
Import org.springframework.orm.jpa.JpaSystemException;
Import org.springframework.stereotype.Controller;
Import org.springframework.ui.Model;
Import org.springframework.web.bind.annotation.GetMapping;
Import org.springframework.web.bind.annotation.PostMapping;
Import org.springframework.web.servlet.mvc.support.RedirectAttributes;
Import org.webjars.NotFoundException;

Import javax.mail.MessagingException;
Import javax.mail.internet.MimeMessage;
Import java.io.UnsupportedEncodingException;
43
Import java.security.Principal;
Import java.util.List;

@Controller
Public class OrderController {

@Autowired
JavaMailSender javaMailSender;

@Autowired
Private OrdersService ordersService;
@Autowired
Private UserService userService;

@GetMapping(“/orders”)
Public String showOrders(Model model, Principal principal) {
If (principal != null) {
User user = userService.getUserByLogin(principal.getName());
List<Order> orders = ordersService.getAllOrdersByUser(user);
Model.addAttribute(“orders”, orders);
} else {

44
Model.addAttribute(“error”, new NotFoundException(“Orders was
not found”));
Return “/error/404”;
}
Return “/user/orders”;
}
@GetMapping(“/payment”)
Public String createOrders(Model model, Principal principal) {
If (principal != null) {
User user = userService.getUserByLogin(principal.getName());
List<OrderBasket> orderBaskets = user.getOrderBaskets();
Model.addAttribute(“order”, new Order());
Model.addAttribute(“user”, user);
Model.addAttribute(“orderBaskets”, orderBaskets);
Model.addAttribute(“waiting”, “waiting”);
Model.addAttribute(“payed”, “payed”);
} else {
Model.addAttribute(“error”, new NotFoundException(“Orders for
payment was not found”));
Return “/error/404”;
}
Return “checkout”;
}
@PostMapping(“/payment”)
45
Public String saveOrder(Order newOrder, Principal principal,
Model model, RedirectAttributes attributes) {
User user = userService.getUserByLogin(principal.getName());
List<OrderBasket> orderBaskets = user.getOrderBaskets();
newOrder.setUser(user);
newOrder.setTotalPrice(ordersService.countSum(orderBaskets)); try
{
ordersService.saveOrder(newOrder);
attributes.addFlashAttribute(“message”, “Order was completed! Check
your email!”); sendVerificationEmail(newOrder);
} catch (JpaSystemException | MessagingException |
UnsupportedEncodingException ex) {
Model.addAttribute(“error”,
ex.getCause().getCause().getMessage());
Return “error/404”;
}
Return “redirect:/orders”;
}
/*
* Method that creates the email with orders that will be sent to user’s
email
* */
Private void sendVerificationEmail(Order order)

46
Throws MessagingException, UnsupportedEncodingException {
String shipping = order.getShippingType() == 0 ? “Speed Delivery” :
“Slow Delivery”;

String subject = “Thank you for ordering in DEMO”;


String senderName = “DEMO Store”;
String mailContent = “<p><b>Order number:</b> “ + order.getId() +
“</p>”; mailContent += “<p><b>Payment:</b> “ +
order.getOrderStatus() +
“</p>”;
mailContent += “<p><b>Shipping:</b> “ + shipping + “</p>”;
mailContent += “<p><b>City:</b> “ + order.getCity() + “</p>”;
mailContent += “<p><b>Address:</b> “ + order.getAddress() +
“</p>”; mailContent += “<p><b>Order total:</b> “ +
order.getTotalPrice() +
“</p>”;

mailContent += “<hr><img src=’cid:logoImage’ width=150 />”;


MimeMessage message = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message,
true);

Helper.setFrom(demo@outlook.com, senderName);
Helper.setTo(order.getUser().getEmail());
Helper.setSubject(subject);
Helper.setText(mailContent, true);

47
ClassPathResource pathResource = new
ClassPathResource(“/static/assets/email.gif”);
Helper.addInline(“logoImage”, pathResource);
// javaMailSender.send(message);
}
}

Apackage com.khomsi.site_project.controller;

Import com.khomsi.site_project.entity.Category;
Import com.khomsi.site_project.entity.Product;
Import com.khomsi.site_project.exception.CategoryNotFoundException;
Import com.khomsi.site_project.exception.ProductNotFoundException;

48
Import com.khomsi.site_project.service.CategoryService;
Import com.khomsi.site_project.service.ProductService;
Import org.springframework.beans.factory.annotation.Autowired;
Import org.springframework.data.domain.Page;
Import org.springframework.data.repository.query.Param;
Import org.springframework.stereotype.Controller;
Import org.springframework.ui.Model;
Import org.springframework.util.StringUtils;
Import org.springframework.web.bind.annotation.GetMapping;
Import org.springframework.web.bind.annotation.PathVariable;
Import org.springframework.web.bind.annotation.PostMapping; Import
org.springframework.web.bind.annotation.ResponseBody;
Import java.util.List;

@Controller
Public class ProductController {
@Autowired
Private ProductService productService;
@Autowired
Private CategoryService categoryService;
@Autowired
Private AdminTools adminTools;
@GetMapping({“/category/{category_alias}”})
Public String viewCategoryFirstPage(@PathVariable(“category_alias”)
String alias,
49
Model model) {
Return viewCategoryByPage(alias, model, 1);
}
@GetMapping(“/category/{category_alias}/page/{pageNum}”)
Public String viewCategoryByPage(@PathVariable(“category_alias”)
String alias,
Model model, @PathVariable(“pageNum”) int
pageNum) {
Try {
Category category = categoryService.getCategoryByAlias(alias);
List<Category> listCategoryParents =
categoryService.getCategoryParents(category); Page<Product>
pageProduct = productService.listByCategory(pageNum, category.getId());
List<Product> listProducts = pageProduct.getContent();
Long startCount = (pageNum – 1) *
ProductService.PRODUCTS_PER_PAGE + 1;
Long endCount = startCount +
ProductService.PRODUCTS_PER_PAGE – 1;

adminTools.pageCountMethod(pageNum, model, pageProduct,


startCount, endCount);
model.addAttribute(“pageTitle”, category.getTitle());
model.addAttribute(“listCategoryParents”, listCategoryParents);
model.addAttribute(“listProducts”, listProducts);

50
model.addAttribute(“category”, category);
return “product/products_by_category”; } catch
(CategoryNotFoundException e) {
Model.addAttribute(“error”, e.getLocalizedMessage());
Return “error/404”;

} }
@GetMapping(“/product/{product_alias}”)
Public String viewProductDetails(@PathVariable(“product_alias”)
String alias, Model model) {
Try {
Product product = productService.getProduct(alias);
// List<Category> listCategoryParents =
categoryService.getCategoryParents(product.getCategory());

// model.addAttribute(“listCategoryParents”, listCategoryParents);
Model.addAttribute(“product”, product);
Return “product/product-page”;
} catch (ProductNotFoundException e) {
Model.addAttribute(“error”, e.getLocalizedMessage());
Return “error/404”;

} }
51
@PostMapping(“/products/check_unique”)
Public @ResponseBody String checkUnique(@Param(“id”) Integer id,
@Param(“title”) String title) {
Return productService.checkUnique(id, title);
}

@GetMapping(“/search”)
Public String searchFirstPage(@Param(“keyword”) String keyword,
Model model) {
Return searchByPage(keyword, 1, model);
}
/*
* We need param of page num, so i use pathVariable
*/
@GetMapping(“/search/page/{pageNum}”)
Public String searchByPage(@Param(“keyword”) String keyword,
@PathVariable(“pageNum”) int pageNum,
Model model) {
Page<Product> productsPage = productService.search(keyword,
pageNum);
List<Product> resultList = productsPage.getContent();

Long startCount = (pageNum – 1) *

52
ProductService.SEARCH_RESULTS_PAGE + 1;
Long endCount = startCount +
ProductService.SEARCH_RESULTS_PAGE – 1;
adminTools.pageCountMethod(pageNum, model, productsPage,
startCount, endCount);

model.addAttribute(“pageTitle”, StringUtils.capitalize(keyword) + “
– Search Result”);
model.addAttribute(“keyword”, keyword);
model.addAttribute(“resultList”, resultList);
return “product/search_result”;
}
}

53
Package com.khomsi.site_project.controller;

Import com.khomsi.site_project.entity.User;
Import com.khomsi.site_project.service.OrderBasketService; Import
com.khomsi.site_project.service.UserService;
Import org.springframework.beans.factory.annotation.Autowired;
Import org.springframework.web.bind.annotation.PathVariable;
Import org.springframework.web.bind.annotation.PostMapping;
Import org.springframework.web.bind.annotation.RestController;

Import java.security.Principal;

@RestController
Public class ShoppingCartRestController {
@Autowired
Private OrderBasketService orderBasketService;
@Autowired
Private UserService userService;

@PostMapping(“/basket/add/{pid}/{qty}”)

54
Public String addProductToBasket(@PathVariable(“pid”) Integer
productId,
@PathVariable(“qty”) Integer quantity,
Principal principal) {
If (principal == null) {
Return “You must login to add this product to your shopping
basket”;
}
User user = userService.getUserByLogin(principal.getName());

If (user == null) return “You must login to add this product to your
shopping basket”;

Integer addedQuantity = orderBasketService.addProduct(productId,


quantity, user);

Return addedQuantity > 1 ? addedQuantity + “ items of this product


were added to your shopping basket”
: addedQuantity + “ item of this product was added to your
shopping basket”;
}
@PostMapping(“/basket/update/{pid}/{qty}”)
Public String updateQuantity(@PathVariable(“pid”) Integer productId,
@PathVariable(“qty”) Integer quantity,
Principal principal) {
If (principal == null) {
Return “You must login to update quantity”;
55
}
User user = userService.getUserByLogin(principal.getName());

If (user == null) return “You must login to update quantity”;

Float subtotal = orderBasketService.updateQuantity(productId,


quantity, user);

Return String.valueOf(subtotal);
}
@PostMapping(“/basket/remove/{pid}”)
Public String removeProductFromBasket(@PathVariable(“pid”) Integer
productId,
Principal principal) {
If (principal == null) {
Return “You must login to remove product”;
}
User user = userService.getUserByLogin(principal.getName());

If (user == null) return “You must login to remove product”;


orderBasketService.removeProduct(productId, user);

return “The product has been removed from your shopping basket.”;

56
}

Package com.khomsi.site_project.controller;

Import com.khomsi.site_project.entity.User; Import


com.khomsi.site_project.entity.UserInfo;
Import com.khomsi.site_project.service.UserService;
Import org.springframework.beans.factory.annotation.Autowired;
Import org.springframework.data.repository.query.Param;
Import org.springframework.security.crypto.password.PasswordEncoder;
Import org.springframework.stereotype.Controller;
Import org.springframework.ui.Model;
Import org.springframework.validation.BindingResult;
Import org.springframework.validation.ObjectError;
Import org.springframework.web.bind.annotation.GetMapping;
Import org.springframework.web.bind.annotation.PostMapping;
Import org.springframework.web.bind.annotation.RequestMapping;
Import org.springframework.web.bind.annotation.ResponseBody;
57
Import org.webjars.NotFoundException;

Import java.security.Principal;

@Controller
@RequestMapping(“/profile”)
Public class UserController {
@Autowired
Private UserService userService;
@Autowired
Private PasswordEncoder passwordEncoder;

@GetMapping({“/”, “”})
Public String getUserInfo(Principal principal, Model model) {
If (principal != null) {
User user = userService.getUserByLogin(principal.getName());
UserInfo userInfo = user.getUserInfo();
Model.addAttribute(“userDetails”, userInfo);
Model.addAttribute(“user”, user);
Return “/user/user-main”;
} else {

58
Model.addAttribute(“error”, new NotFoundException(“User was
not found”));
Return “error/404”;

} }
@Get
Mapp
ing(“/
edit”)
Public String showEditPage(Principal principal, Model model) {
User user = userService.getUserByLogin(principal.getName());
UserInfo userInfo = user.getUserInfo();
Model.addAttribute(“userDetails”, userInfo);
Model.addAttribute(“user”, user);

Return “/user/user-edit”;
}
@PostMapping(“/edit”)
Public String editUser(Principal principal, User user, BindingResult
bindingResult) {
User newUser = userService.getUserByLogin(principal.getName());

If (!user.getPassword().equals(“”)) {
If (!passwordEncoder.matches(user.getPassword(),
newUser.getPassword())) {

59
newUser.setPassword(passwordEncoder.encode(user.getPassword()));
} else {
ObjectError error = new ObjectError(“globalError”,
“The password must not be the same.”);
bindingResult.addError(error);
System.err.println(bindingResult.hasErrors());
Return “/user/user-edit”;
}
}
newUser.getUserInfo().setName(user.getUserInfo().getName());

newUser.getUserInfo().setSurname(user.getUserInfo().getSurname())
;
newUser.getUserInfo().setPhone(user.getUserInfo().getPhone());
userService.saveUser(newUser); return “redirect:/profile”; }

60
Package com.khomsi.site_project.entity;

Import lombok.Getter;
Import lombok.NoArgsConstructor;
Import lombok.Setter;
Import lombok.ToString;

Import javax.persistence.*;
Import java.util.HashSet;
Import java.util.List;
Import java.util.Set;

@NoArgsConstructor
@Getter
@Setter
@Entity
61
@Table(name = “category”)
Public class Category {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = “id”, nullable = false)
Private Integer id;

@Column(name = “title”, nullable = false, length = 155)


Private String title;

@Column(name = “alias”) Private


String alias;

@Column(name = “image”)
Private String imageURL;
@Column(name = “enabled”, nullable =
false)
Private Boolean enabled;

//parent_id refers to category id or null if it’s top-level category


@ManyToOne
@JoinColumn(name = “parent_id”)

62
Private Category parent;

@OneToMany(mappedBy = “parent”)
@OrderBy(“title asc”)
@ToString.Exclude
Private Set<Category> children = new HashSet<>();

@OneToMany(mappedBy = “category”, cascade =


{CascadeType.ALL, CascadeType.PERSIST})
@ToString.Exclude
Private List<Product> products;

@Column(name = “all_parent_ids”, length = 255, nullable = true)


@ToString.Exclude Private String allParentsIDs;

Public Integer getId() {


Return id;
}
Public void setId(Integer id) {
This.id = id;
}

63
Public String getTitle() {
Return title;
}
Public void setTitle(String title) {
This.title = title;
}
Public String getImageURL() {
Return imageURL;
}
Public void setImageURL(String imageURL) {
This.imageURL = imageURL;
}
Public Boolean getEnabled() {
Return enabled;
}
Public void setEnabled(Boolean enabled) {
This.enabled = enabled;
}
Public Category getParent() {
Return parent;
}

64
Public void setParent(Category parent) { This.parent = parent; }
Public Set<Category> getChildren() {
Return children;
}
Public void setChildren(Set<Category> children) {
This.children = children;
}
Public List<Product> getProducts() {
Return products;
}
Public void setProducts(List<Product> products) {
This.products = products;
}
Public String getAllParentsIDs() {
Return allParentsIDs;
}
Public void setAllParentsIDs(String allParentsIDs) {
This.allParentsIDs = allParentsIDs;
}

Public String getAlias() {


65
Return alias;
}
Public void setAlias(String alias) {
This.alias = alias;
}
Public Category() {}
Public static Category copyIdAndTitle(Category category) {
Category copyCategory = new Category();
copyCategory.setId(category.getId());
copyCategory.setTitle(category.getTitle());

return copyCategory;
}
Public static Category copyIdAndTitle(Integer id, String title)
{ Category copyCategory = new Category();
copyCategory.setId(id); copyCategory.setTitle(title);

return copyCategory;
}
Public static Category copyFull(Category category) {
Category copyCategory = new Category();
copyCategory.setId(category.getId());
copyCategory.setTitle(category.getTitle());
copyCategory.setAlias(category.getAlias());

66
copyCategory.setImageURL(category.getImageURL());
copyCategory.setEnabled(category.getEnabled());

return copyCategory;
}
Public static Category copyFull(Category category, String title)
{ Category copyCategory = Category.copyFull(category);
copyCategory.setTitle(title); return copyCategory;
}
Public Category(Integer id) {
This.id = id;
}
Public Category(String title, Category parent) {
This(title);
This.parent = parent;
}
Public Category(String title) {
This.title = title;
This.alias = title;
This.imageURL = “default.png”;
}
Public Category(Integer id, String title, String alias, String imageURL,
Boolean enabled, Category parent) {
This.id = id;
This.title = title;
67
This.alias = alias;
This.imageURL = imageURL;
This.enabled = enabled;
This.parent = parent;
}
}

Package com.khomsi.site_project.entity;

Import lombok.*;
Import org.hibernate.annotations.OnDelete;
Import org.hibernate.annotations.OnDeleteAction;

Import javax.persistence.*;

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter

68
@ToString
@Entity
@Table(name = “delivery”)
Public class Delivery {
@Id
@Column(name = “orders_id”)
Private Integer id;

@MapsId
@OneToOne(fetch = FetchType.LAZY, optional = false)
@OnDelete(action = OnDeleteAction.CASCADE)
@JoinColumn(name = “orders_id”)
@ToString.Exclude
Private Order order;
@Enumerated(EnumType.STRI
NG)
@Column(name = “status”) Private
DeliveryStatus status;

Package com.khomsi.site_project.entity;

69
Public enum DeliveryStatus {
Обработка,
Отправлено,
Отмена,
Доставлено,
}

70
Package com.khomsi.site_project.entity;

Import lombok.*;

Import javax.persistence.*;

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@ToString
@Entity
@Table(name = “orders”)
Public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = “id”)
Private int id;

@Enumerated(EnumType.STRING)

71
@Column(name = “order_status”)
Private OrderType orderStatus;

@ManyToOne(fetch = FetchType.LAZY, optional = false)


@JoinColumn(name = “user_id”)
@ToString.Exclude Private
User user;

@Column(name = “shipping_type”)
Private int shippingType;

@Column(name = “city”)
Private String city;

@Column(name = “address”)
Private String address;

@Column(name = “total_price”)
Private Float totalPrice;

@OneToOne(mappedBy = “order”, cascade = CascadeType.ALL)


@ToString.Exclude

72
Private Delivery delivery;
Public int getId() {
Return id;
}
Public void setId(int id) {
This.id = id;
}

Public OrderType getOrderStatus() {


Return orderStatus;
}

Public void setOrderStatus(OrderType orderStatus) {


This.orderStatus = orderStatus;
}

Public User getUser() {


Return user;
}

Public void setUser(User user) {


This.user = user;
}

73
Public int getShippingType() {
Return shippingType;
}

Public void setShippingType(int shippingType) {


This.shippingType = shippingType;
}

Public String getCity() {


Return city;
}

Public void setCity(String city) {


This.city = city;
}

Public String getAddress() {


Return address;
}

Public void setAddress(String address) {


This.address = address;

74
}

Public Float getTotalPrice() {


Return totalPrice;
}

Public void setTotalPrice(Float totalPrice) {


This.totalPrice = totalPrice;
}

Public Delivery getDelivery() {


Return delivery;
}
Public void setDelivery(Delivery delivery) {
This.delivery = delivery;
}
}

Package com.khomsi.site_project.entity;

Import lombok.*;
Import javax.persistence.*;
Import java.util.LinkedHashSet;
75
Import java.util.List;
Import java.util.Set;

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@ToString
@Entity
@Table(name = “order_basket”)
Public class OrderBasket {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = “id”)
Private int id;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = “product_id”)
@ToString.Exclude
Private Product product;

@ManyToOne(fetch = FetchType.LAZY, optional = false)

76
@JoinColumn(name = “user_id”)
@ToString.Exclude Private
User user;

@Column(name = “quantity”)
Private int quantity;

//We use temporary field that is not in db for business logic(we don’t
need to save it in db)
@Transient
Public float getSubtotal() {
Return this.product.getPrice() * quantity;
}
Public int getId() {
Return id;
}

Public void setId(int id) {


This.id = id;
}

Public Product getProduct() {


Return product;
}

77
Public void setProduct(Product product) {
This.product = product;
}

Public User getUser() {


Return user;
}

Public void setUser(User user) {


This.user = user;
}

Public int getQuantity() {


Return quantity;
}

Public void setQuantity(int quantity) {


This.quantity = quantity;
}

78
// @Transient
// public float getTotal() {
// float sum = 0;
// for (OrderBasket orderBasket : this.product.getOrderBaskets()) { //
sum += orderBasket.getSubtotal();
// }
// return sum;
// }
}

79
Package com.khomsi.site_project.entity;

Public enum OrderType {


Оплачено,
Отмена,
Ожидание,
Обработка,
Выполнен
}

80
Package com.khomsi.site_project.entity; Import lombok.*; Import
org.hibernate.annotations.OnDelete;
Import org.hibernate.annotations.OnDeleteAction;

Import javax.persistence.*;
Import java.util.LinkedHashSet;
Import java.util.List;
Import java.util.Set;

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter

81
@ToString
@Entity
@Table(name = “product”)
Public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = “id”)
Private Integer id;

@Column(name = “title”)
Private String title;

@Column(name = “alias”)
Private String alias;

@Column(name = “description”)
Private String description;
@Column(name = “price”)
Private int price;

@Column(name = “image”)
Private String imageURL;
@ManyToOne(fetch = FetchType.LAZY, optional = false)

82
@OnDelete(action = OnDeleteAction.CASCADE)
@JoinColumn(name = “vendor_id”)
@ToString.Exclude Private
Vendor vendor;

@ManyToOne(fetch = FetchType.LAZY, optional = false)


@OnDelete(action = OnDeleteAction.CASCADE)
@JoinColumn(name = “category_id”)
@ToString.Exclude
Private Category category;

@OneToMany(mappedBy = “product”)
@ToString.Exclude
Private List<OrderBasket> orderBaskets;

@Transient
Public String getShortTitle() {
If (title.length() > 40) {
Return title.substring(0, 40).concat(“...”);
}
Return title;
}
@Transient
Public String getShortAlias() {
If (alias.length() > 40) {
83
Return alias.substring(0, 40).concat(“...”);
}
Return alias;
}
@Transient
Public String getShortDescription() {

If (description != null && description.length() > 50) {


Return description.substring(0, 50).concat(“...”);
}
Return description;
}
Public Integer getId() {
Return id;
}
Public void setId(Integer id) {
This.id = id;
}
Public String getTitle() {
Return title;
}

84
Public void setTitle(String title) {
This.title = title;
}
Public String getAlias() {
Return alias;
}
Public void setAlias(String alias) {
This.alias = alias;
}
Public String getDescription() {
Return description;
}
Public void setDescription(String description) {
This.description = description;
}
Public int getPrice() {
Return price;
}
Public void setPrice(int price) {
This.price = price;
}
Public String getImageURL() {
Return imageURL;

85
}
Public void setImageURL(String imageURL) {
This.imageURL = imageURL;
}
Public Vendor getVendor() {
Return vendor;
}
Public void setVendor(Vendor vendor) { This.vendor = vendor;
}
Public Category getCategory() {
Return category;
}
Public void setCategory(Category category) {
This.category = category;
}
Public List<OrderBasket> getOrderBaskets() {
Return orderBaskets;
}
Public void setOrderBaskets(List<OrderBasket> orderBaskets) {
This.orderBaskets = orderBaskets;
}

86
//TODO add a new field in db discount if i need discount in future
// @Transient
// public float getDiscountPrice(){
// if (discountPercent > 0)
// {
// return price * ((100 – discountPercent) / 100);
// }
// return this.price;
// }
}

Package com.khomsi.site_project.entity;

Import org.springframework.security.core.GrantedAuthority;

87
/*
https://stackoverflow.com/questions/19525380/differencebetwee
nroleand-grantedauthority-in-spring-security */ Public enum
Role implements GrantedAuthority {

USER, ADMIN;

@Override
Public String getAuthority() {
Return name();
}
}

Package com.khomsi.site_project.entity;

Import lombok.*;

Import javax.persistence.*;

88
Import javax.validation.constraints.NotBlank;
Import javax.validation.constraints.NotNull;
Import javax.validation.constraints.Size;
Import java.util.LinkedHashSet;
Import java.util.List;
Import java.util.Set;

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@ToString
@Entity
@Table(name = “user”)
Public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = “id”)
Private Integer id;

@Column(name = “login”) Private


String login;

@Column(name = “password”)
89
Private String password;
@Column(name = “email”)
Private String email;

@Enumerated(EnumType.STRING)
@Column(name = “role”)
Private Role role;

@OneToOne(fetch = FetchType.LAZY, mappedBy = “user”, cascade


= CascadeType.ALL) @ToString.Exclude
Private UserInfo userInfo;

@OneToMany(mappedBy = “user”, cascade = {CascadeType.ALL,


CascadeType.PERSIST})
@ToString.Exclude
Private List<OrderBasket> orderBaskets;

@OneToMany(mappedBy = “user”)
@ToString.Exclude
Private List<Order> orders;

Public Integer getId() {


Return id;

90
}

Public void setId(Integer id) {


This.id = id;
}

Public String getLogin() {


Return login;
}

Public void setLogin(String login) {


This.login = login;
}

Public String getPassword() {


Return password;
}

Public void setPassword(String password) {


This.password = password;
}

Public String getEmail() {


Return email;
}

91
Public void setEmail(String email) {
This.email = email;
}

Public Role getRole() {


Return role;
}

Public void setRole(Role role) {


This.role = role;
}

Public UserInfo getUserInfo() {


Return userInfo;
}

Public void setUserInfo(UserInfo userInfo) {


This.userInfo = userInfo;
}

Public List<OrderBasket> getOrderBaskets() { Return orderBaskets;

92
}
Public void setOrderBaskets(List<OrderBasket> orderBaskets) {
This.orderBaskets = orderBaskets;
}

Public List<Order> getOrders() {


Return orders;
}

Public void setOrders(List<Order> orders) {


This.orders = orders;
}

93
Package com.khomsi.site_project.entity;

Import lombok.*;
Import org.hibernate.annotations.OnDelete;
Import org.hibernate.annotations.OnDeleteAction;

Import javax.persistence.*;

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@ToString
@Entity
@Table(name = “user_info”)
Public class UserInfo {
@Id
@Column(name = “user_info_id”, nullable = false)

94
Private int user_id;

@MapsId
@OneToOne(fetch = FetchType.LAZY, optional = false)
@OnDelete(action = OnDeleteAction.CASCADE)
@JoinColumn(name = “user_info_id”) @ToString.Exclude Private
User user;

@Column(name = “name”)
Private String name;

@Column(name = “surname”)
Private String surname;

@Column(name = “phone”)
Private String phone;

Public int getUser_id() {


Return user_id;
}

Public void setUser_id(int user_id) {


This.user_id = user_id;
}

95
Public User getUser() {
Return user;
}

Public void setUser(User user) {


This.user = user;
}

Public String getName() {


Return name;
}

Public void setName(String name) {


This.name = name;
}

Public String getSurname() {


Return surname;
}

Public void setSurname(String surname) {

96
This.surname = surname;
}

Public String getPhone() {


Return phone;
}

Public void setPhone(String phone) {


This.phone = phone;
}

97
Package com.khomsi.site_project.entity; Import lombok.*;

Import javax.persistence.*;
Import java.util.LinkedHashSet;
Import java.util.List;
Import java.util.Set;

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@ToString
@Entity
@Table(name = “vendor”)

98
Public class Vendor {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = “id”, nullable = false)
Private Integer id;

@Column(name = “title”, nullable = false)


Private String title;
@OneToMany(mappedBy = “vendor”)
@ToString.Exclude
Private List<Product> products;

Public Integer getId() {


Return id;
}

Public void setId(Integer id) {


This.id = id;
}

Public String getTitle() {


Return title;
}

99
Public void setTitle(String title) {
This.title = title;
}

Public List<Product> getProducts() {


Return products;
}

Public void setProducts(List<Product> products) {


This.products = products;
}

Package com.khomsi.site_project.exception;

100
Public class CategoryNotFoundException extends Exception {
Public CategoryNotFoundException(String message) {
Super(message);
}
}

Package com.khomsi.site_project.exception;

Public class OrderNotFoundException extends Exception {


Public OrderNotFoundException(String message) {
Super(message);

}
}

101
Package com.khomsi.site_project.exception;

Public class ProductNotFoundException extends Exception {


Public ProductNotFoundException(String message) {
Super(message);
}
}

Package com.khomsi.site_project.exception;

Public class UserNotFoundException extends Exception {

102
Public UserNotFoundException(String message) {
Super(message);
}
}

Package com.khomsi.site_project.repository;

Import com.khomsi.site_project.entity.Category;
Import org.springframework.data.domain.Page;
Import org.springframework.data.domain.Pageable;
Import org.springframework.data.jpa.repository.JpaRepository;
Import org.springframework.data.jpa.repository.Query;
Import org.springframework.data.repository.query.Param;

Import java.util.List;

Public interface CategoryRepository extends JpaRepository<Category,


Integer> {

103
@Query(“SELECT category FROM Category category WHERE
category.enabled = true ORDER BY category.title ASC”)
Public List<Category> findAllEnabled();

@Query(“select category from Category category where category.enabled


= true and category.alias = ?1”)
Public Category findByAliasEnabled(String alias);

Public Category findByAlias(String alias);

Public Long countById(Integer id);

@Query(“SELECT c FROM Category c WHERE c.title = :title”) Public


Category findByTitle(@Param(“title”) String title);

//For categories that doesn’t have parents,


// so we avoid error when we choose for parent category parent’s id
@Query(“SELECT c FROM Category c WHERE c.parent.id is NULL”)
Public List<Category> findRootCategories();

@Query(“SELECT c FROM Category c WHERE c.parent.id is NULL”)


Public Page<Category> findRootCategories(Pageable pageable);

104
}
Package com.khomsi.site_project.repository;

Import com.khomsi.site_project.entity.Delivery;
Import org.springframework.data.jpa.repository.JpaRepository;

Public interface DeliveryRepository extends JpaRepository<Delivery,


Integer> {
}

105
Package com.khomsi.site_project.repository;

Import com.khomsi.site_project.entity.OrderBasket;
Import com.khomsi.site_project.entity.Product;
Import com.khomsi.site_project.entity.User;
Import org.springframework.data.jpa.repository.JpaRepository;
Import org.springframework.data.jpa.repository.Modifying;
Import org.springframework.data.jpa.repository.Query;

Import java.util.List;

Public interface OrderBasketRepository extends


JpaRepository<OrderBasket, Integer> {
Public List<OrderBasket> findByUser(User user);

Public OrderBasket findByUserAndProduct(User user, Product product);

//It’s update/delete query so we use @modifying

@Query(“UPDATE OrderBasket orderBasket SET orderBasket.quantity =

106
?1 WHERE orderBasket.product.id = ?2 “ +
“AND orderBasket.user.id = ?3”)
@Modifying
Public void updateQuantity(Integer quantity, Integer productId, Integer
userId);

@Query(“DELETE FROM OrderBasket orderBasket WHERE


orderBasket.user.id = ?1 AND orderBasket.product.id = ?2”)
@Modifying
Public void deleteByUserAndProduct(Integer userId, Integer productId);

Package com.khomsi.site_project.repository;

Import com.khomsi.site_project.entity.Order;
Import com.khomsi.site_project.entity.OrderBasket;
Import com.khomsi.site_project.entity.User;
Import org.springframework.data.jpa.repository.JpaRepository;

Import java.util.List;

107
Public interface OrderRepository extends JpaRepository<Order, Integer> {
Order findByUser(User user);

List<Order> findOrdersByUser(User user);

Public Long countById(Integer id);

Package com.khomsi.site_project.repository;

Import com.khomsi.site_project.entity.Category;

108
Import com.khomsi.site_project.entity.Product;
Import org.springframework.data.domain.Page;
Import org.springframework.data.domain.Pageable;
Import org.springframework.data.jpa.repository.JpaRepository;
Import org.springframework.data.jpa.repository.Query;

Import java.util.List;

Public interface ProductRepository extends JpaRepository<Product, Integer>


{
@Query(“SELECT product FROM Product product WHERE
(product.category.id = ?1 OR product.category.allParentsIDs LIKE %?2%)”
+ “ORDER BY product.title ASC”)
Public Page<Product> listByCategory(Integer categoryId, Pageable
pageable, String categoryIDMatch);

@Query(value = “SELECT * FROM product WHERE MATCH(title,


description) AGAINST (?1)”, nativeQuery = true)
public Page<Product> search(String keyword, Pageable pageable);

public Product findByAlias(String alias);

public Product findByTitle(String title);

public List<Product> findAllByCategoryId(Integer category);

109
public Long countById(Integer id);

@Query(“SELECT p FROM Product p WHERE p.title LIKE %?1% “


+ “OR p.description LIKE %?1% “
+ “OR p.vendor.title LIKE %?1% “
+ “OR p.category.title LIKE %?1%”)
Public Page<Product> findAll(String keyword, Pageable pageable);

@Query(“SELECT p FROM Product p WHERE p.category.id = ?1 “ +


“OR p.category.allParentsIDs LIKE %?2%”)
Public Page<Product> findAllInCategory(Integer categoryId, String
categoryIdMatch,
Pageable pageable);

@Query(“SELECT p FROM Product p WHERE (p.category.id = ?1 “ +


“OR p.category.allParentsIDs LIKE %?2%) AND “
+ “(p.title LIKE %?3% “
+ “OR p.description LIKE %?3% “
+ “OR p.vendor.title LIKE %?3% “
+ “OR p.category.title LIKE %?3%)”)
Public Page<Product> searchInCategory(Integer categoryId, String
categoryIdMatch,

110
String keyword, Pageable pageable);
}

Package com.khomsi.site_project.repository;

Import com.khomsi.site_project.entity.UserInfo;
Import org.springframework.data.jpa.repository.JpaRepository;

Public interface UserInfoRepository extends JpaRepository<UserInfo,


Integer> {
}

111
Package com.khomsi.site_project.repository;

Import com.khomsi.site_project.entity.User;
Import org.springframework.data.jpa.repository.JpaRepository;
Import org.springframework.data.jpa.repository.Query;
Import org.springframework.data.repository.query.Param;

Public interface UserRepository extends JpaRepository<User, Integer> {

@Query(“SELECT u FROM User u WHERE u.login = :login”)


Public User findByLogin(@Param(“login”) String login);
Public Long countById(Integer id);

112
}

Package com.khomsi.site_project.repository;

Import com.khomsi.site_project.entity.Vendor;
Import org.springframework.data.jpa.repository.JpaRepository;
Import org.springframework.data.jpa.repository.Query;
Import org.springframework.data.repository.query.Param;

Public interface VendorRepository extends JpaRepository<Vendor, Integer>


{
Public Long countById(Integer id);
@Query(“SELECT v FROM Vendor v WHERE v.title = :title”)
Public Vendor findByTitle(@Param(“title”) String title);

113
}

Package com.khomsi.site_project.service;

Public class CategoryPageInfo

114
{ Private int totalPages;
Private long totalElements;

Public int getTotalPages() {


Return totalPages;
}
Public void setTotalPages(int totalPages) {
This.totalPages = totalPages;
}
Public long getTotalElements() {
Return totalElements;
}
Public void setTotalElements(long totalElements) {
This.totalElements = totalElements;
}
}

115
Package com.khomsi.site_project.service;

Import com.khomsi.site_project.entity.Category;
Import com.khomsi.site_project.exception.CategoryNotFoundException;
Import com.khomsi.site_project.repository.CategoryRepository;
Import org.springframework.beans.factory.annotation.Autowired;
Import org.springframework.data.domain.Page;
Import org.springframework.data.domain.PageRequest;
Import org.springframework.data.domain.Pageable;
Import org.springframework.stereotype.Service;

Import java.util.*;

@Service
Public class CategoryService implements ICategoryService { @Autowired
Private CategoryRepository categoryRep;

//Shows only main categories with sub categories per page.


//For ex if top categories is 2: Electronics, ..subcat., Clothes..subcat../next
page

116
Public static final int TOP_CATEGORIES_PER_PAGE = 1;

@Override
Public List<Category> listByPage(CategoryPageInfo pageInfo, int
pageNum) {
Pageable pageable = PageRequest.of(pageNum – 1,
TOP_CATEGORIES_PER_PAGE);

Page<Category> pageCategories =
categoryRep.findRootCategories(pageable);
List<Category> rooCategories = pageCategories.getContent();
pageInfo.setTotalElements(pageCategories.getTotalElements());
pageInfo.setTotalPages(pageCategories.getTotalPages());

return listHierarchicalCategories(rooCategories);
}
Private List<Category> listHierarchicalCategories(List<Category>
rootCategories) {
List<Category> hierarchicalCategories = new ArrayList<>();

For (Category rootCategory : rootCategories) {


hierarchicalCategories.add(Category.copyFull(rootCategory));
Set<Category> children = rootCategory.getChildren();

For (Category subCategory : children) { String title = “—”


+ subCategory.getTitle();
hierarchicalCategories.add(Category.copyFull(subCategory, title));
listSubHierarchicalCategories(hierarchicalCategories, subCategory, 1);
}
117
}
Return hierarchicalCategories;
}
Private void listSubHierarchicalCategories(List<Category>
hierarchicalCategories,
Category parent, int subLevel) {
Int newSubLevel = subLevel + 1;
Set<Category> children = parent.getChildren();

For (Category subCategory : children) {


String name = “”;
For (int i = 0; i < newSubLevel; i++) {
Name += “—“;
}
Name += subCategory.getTitle();
hierarchicalCategories.add(Category.copyFull(subCategory, name));

//call the method itself to iterate each subCategory in subCategories


listSubHierarchicalCategories(hierarchicalCategories, subCategory,
newSubLevel);

} }
@Override

118
Public List<Category> listCategoriesUserInForm() {
List<Category> categoriesUserInForm = new ArrayList<>();
Iterable<Category> categoriesInDB = categoryRep.findAll();

For (Category category : categoriesInDB) { If


(category.getParent() == null) {
categoriesUserInForm.add(Category.copyIdAndTitle(category))
;

Set<Category> children = category.getChildren();

For (Category subCat : children) {


String name = “—” + subCat.getTitle();

categoriesUserInForm.add(Category.copyIdAndTitle(subCat.getId(), name));
listSubCategoriesUsedInForm(categoriesUserInForm, subCat,
1);
}
}
}
Return categoriesUserInForm;
}
Private void listSubCategoriesUsedInForm(List<Category>
categoriesUserInForm, Category parent, int subLevel) {
Int newSubLevel = subLevel + 1;

119
Set<Category> children = parent.getChildren();

For (Category subCategory : children) {


String name = “”;
For (int i = 0; i < newSubLevel; i++) {
Name += “—“;
}
Name += subCategory.getTitle();
categoriesUserInForm.add(Category.copyIdAndTitle(subCategory.getId(),
name));
listSubCategoriesUsedInForm(categoriesUserInForm, subCategory,
newSubLevel);

} }
@Override
Public Category saveCategory(Category category) {
Category parent = category.getParent();
If (parent != null) {
String allParentIds = parent.getAllParentsIDs() == null ? “-“ :
parent.getAllParentsIDs();
allParentIds += String.valueOf(parent.getId()) + “-“;
category.setAllParentsIDs(allParentIds);
}

120
If (category.getAlias() == null || category.getAlias().isEmpty()) {
String defaultAlias = category.getTitle().toLowerCase();
Category.setAlias(convertCyrillic(defaultAlias).replaceAll(“ “, “_”));
} else {
Category.setAlias(category.getAlias().replaceAll(“ “,
“_”).toLowerCase());
}
Return categoryRep.save(category);
}
//Method to convert alias into english letters
Public String convertCyrillic(String message) {
Char[] abcCyr = {‘ ‘, ‘а’, ‘б’, ‘в’, ‘г’, ‘д’, ‘і’, ‘е’, ‘ж’, ‘з’, ‘ѕ’, ‘и’, ‘ј’,
‘к’, ‘л’, ‘ґ’, ‘м’, ‘н’, ‘є’,
‘о’, ‘п’, ‘р’, ‘с’, ‘т’, ‘ї’, ‘у’, ‘ф’, ‘х’, ‘ц’, ‘ч’, ‘џ’, ‘ш’, ‘А’, ‘Б’, ‘В’,
‘Г’, ‘Д’, ‘І’, ‘Е’, ‘Ж’,
‘З’, ‘Ѕ’, ‘И’, ‘Ј’, ‘К’, ‘Л’, ‘Ґ’, ‘М’, ‘Н’, ‘Є’, ‘О’, ‘П’, ‘Р’, ‘С’, ‘Т’,
‘Ї’, ‘У’, ‘Ф’, ‘Х’, ‘Ц’, ‘Ч’,
‘Џ’, ‘Ш’, ‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’, ‘g’, ‘h’, ‘i’, ‘j’, ‘k’, ‘l’, ‘m’, ‘n’,
‘o’, ‘p’, ‘q’, ‘r’, ‘s’,
‘t’, ‘u’, ‘v’, ‘w’, ‘x’, ‘y’, ‘z’, ‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, ‘G’, ‘H’,
‘I’, ‘J’, ‘K’, ‘L’, ‘M’, ‘N’,
‘O’, ‘P’, ‘Q’, ‘R’, ‘S’, ‘T’, ‘U’, ‘V’, ‘W’, ‘X’, ‘Y’, ‘Z’, ‘0’, ‘1’,
‘2’,
‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’, ‘/’};

String[] abcLat = {“ “, “a”, “b”, “v”, “g”, “d”, “i”, “e”, “zh”, “z”, “y”,
“i”, “j”, “k”, “l”, “g”, “m”, “n”, “e”,
121
“o”, “p”, “r”, “s”, “t”, “ї”, “u”, “f”, “h”, “c”, “ch”, “x”, “h”, “A”,
“B”, “V”, “G”, “D”, “І”, “E”, “Zh”,
“Z”, “Y”, “I”, “J”, “K”, “L”, “G”, “M”, “N”, “E”, “O”, “P”, “R”,
“S”, “T”, “I”, “U”, “F”, “H”, “C”, “:”,
“X”, “{“, “a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”, “l”,
“m”, “n”, “o”, “p”, “q”, “r”, “s”,
“t”, “u”, “v”, “w”, “x”, “y”, “z”, “A”, “B”, “C”, “D”, “E”, “F”,
“G”, “H”, “I”, “J”, “K”, “L”, “M”, “N”,
“O”, “P”, “Q”, “R”, “S”, “T”, “U”, “V”, “W”, “X”, “Y”, “Z”, “0”,
“1”, “2”, “3”, “4”, “5”, “6”, “7”, “8”, “9”, “_”};
StringBuilder builder = new StringBuilder();
For (int i = 0; i < message.length(); i++) {
For (int x = 0; x < abcCyr.length; x++) {
If (message.charAt(i) == abcCyr[x]) {
Builder.append(abcLat[x]);
}
}
}
Return builder.toString();
}
@Override

122
Public void deleteCategory(int id) throws CategoryNotFoundException {
Long countById = categoryRep.countById(id);
If (countById == null || countById == 0) {
Throw new CategoryNotFoundException(“Couldn’t find any
category with id “ + id);
}
categoryRep.deleteById(id);
}
@Override
Public Category getCategory(Integer id) throws
CategoryNotFoundException {
Try {
Return categoryRep.getReferenceById(id);
} catch (NoSuchElementException e) {
Throw new CategoryNotFoundException(“Couldn’t find any
category with id “ + id);

} }
@Override
Public Category getCategoryByAlias(String alias) throws
CategoryNotFoundException {
Category category = categoryRep.findByAliasEnabled(alias);
If (category == null) {
Throw new CategoryNotFoundException(“Couldn’t find any
category with alias “ + alias);

123
}
Return category;
}

//List up parent of categories


@Override
Public List<Category> getCategoryParents(Category child) {
List<Category> listParents = new ArrayList<>();
Category parent = child.getParent();

//look up to parent by loop


While (parent != null) {
listParents.add(0, parent);
parent = parent.getParent();
}
listParents.add(child);

return listParents;
}
@Override
Public String checkCategoryTitle(Integer id, String title, String alias) {
Category categoryByTitle = categoryRep.findByTitle(title);

124
Boolean isCreatingNew = (id == null || id == 0);

If (isCreatingNew) {
If (categoryByTitle != null) {
Return “DuplicateTitle”;
} else {
Category categoryByAlias = categoryRep.findByAlias(alias);
If (categoryByAlias != null) {
Return “DuplicateAlias”;
}
}
} else {
If (categoryByTitle != null &&
!Objects.equals(categoryByTitle.getId(), id)) {
Return “DuplicateTitle”;
}
Category categoryByAlias = categoryRep.findByAlias(alias);
If (categoryByAlias != null &&
!Objects.equals(categoryByAlias.getId(), id)) {
Return “DuplicateAlias”;
}
}
Return “OK”;
}
125
}

126
Package com.khomsi.site_project.service; Import
com.khomsi.site_project.entity.Category;
Import com.khomsi.site_project.exception.CategoryNotFoundException;
Import org.springframework.data.domain.Page;

Import java.util.List;

Public interface ICategoryService {


List<Category> listByPage(CategoryPageInfo pageInfo, int pageNum);

Public List<Category> listCategoriesUserInForm();


Public Category saveCategory(Category category);

Public void deleteCategory(int id) throws CategoryNotFoundException;

Public Category getCategory(Integer id) throws


CategoryNotFoundException;
Public Category getCategoryByAlias(String alias) throws
CategoryNotFoundException;
//list up parent of categories
List<Category> getCategoryParents(Category child);

127
String checkCategoryTitle(Integer id, String title, String alias);
}

Package com.khomsi.site_project.service;

Import com.khomsi.site_project.entity.OrderBasket;
Import com.khomsi.site_project.entity.User;

Import java.util.List;

Public interface IOrderBasketService {


List<OrderBasket> getAllOrderBaskets();

Public List<OrderBasket> listOrderBasket(User user);

Public Integer addProduct(Integer productId, Integer quantity, User user);

Public float updateQuantity(Integer productId, Integer quantity, User user);

128
Public void removeProduct(Integer productId, User user);
}

Package com.khomsi.site_project.service;

Import com.khomsi.site_project.entity.Order;
Import com.khomsi.site_project.entity.OrderBasket;
Import com.khomsi.site_project.entity.User;
Import com.khomsi.site_project.exception.OrderNotFoundException;
Import org.springframework.data.domain.Page;

129
Import java.util.List;

Public interface IOrdersService {


Public List<Order> getAllOrders();
List<Order> getAllOrdersByUser(User user);

Public void saveOrder(Order orders);

Public Order getOrder(int id);

Public Order getOrderByUser(User user) throws


OrderNotFoundException;

Float countSum(List<OrderBasket> orderBaskets);

Public void deleteOrder(int id) throws OrderNotFoundException;

Page<Order> listByPage(int pageNum);


}

Package com.khomsi.site_project.service;

130
Import com.khomsi.site_project.entity.Product;
Import com.khomsi.site_project.exception.ProductNotFoundException;
Import org.springframework.data.domain.Page;

Import java.util.List;

Public interface IProductService {

Page<Product> listByPage(int pageNum, String sortField, String sortDir,


String keyword,
Integer categoryId);
Public List<Product> getAllProducts() throws
ProductNotFoundException;

List<Product> getRandomAmountOfProducts() throws


ProductNotFoundException;

Public Page<Product> listByCategory(int pageNum, Integer categoryId);

Public void saveProduct(Product product);

Product getProduct(Integer id) throws ProductNotFoundException;

Product getProduct(String alias) throws ProductNotFoundException;

Void deleteProduct(Integer id) throws ProductNotFoundException;


131
String checkUnique(Integer id, String title);
}
Package com.khomsi.site_project.service;

Import com.khomsi.site_project.entity.UserInfo;

Import java.util.List;

Public interface IUserInfoService {

Public List<UserInfo> getAllUserDetails();

Public void saveUserDetail(UserInfo userInfo);

Public UserInfo getUserDetail(int id);

Public void deleteUserDetail(int id);


}

132
Package com.khomsi.site_project.service;

Import com.khomsi.site_project.entity.User;
Import com.khomsi.site_project.exception.UserNotFoundException;
Import org.springframework.data.domain.Page;

Import java.util.List;

Public interface IUserService {

Public List<User> getAllUsers();

Public void saveUser(User user);

Void encodePassword(User user);

String isLoginUnique(Integer id, String login);

133
Boolean checkLoginRegistration(String login);

Public User getUser(int id) throws UserNotFoundException;

Public User getUserByLogin(String login);

Public void deleteUser(Integer id) throws UserNotFoundException;

Page<User> listByPage(int pageNum);


}

Package com.khomsi.site_project.service;

Import com.khomsi.site_project.entity.Vendor;
Import org.springframework.data.domain.Page;

Import java.util.List;

Public interface IVendorService {


List<Vendor> getAllVendors();

Void saveVendor(Vendor vendor);

134
Vendor getVendor(int id);

Void deleteVendor(int id);

Page<Vendor> listByPage(int pageNum);

String checkVendorTitle(Integer id, String title);


}

Package com.khomsi.site_project.service;

Import com.khomsi.site_project.entity.OrderBasket;
Import com.khomsi.site_project.entity.Product;
Import com.khomsi.site_project.entity.User;
Import com.khomsi.site_project.repository.OrderBasketRepository; Import
com.khomsi.site_project.repository.ProductRepository; Import
org.springframework.beans.factory.annotation.Autowired;

Import org.springframework.stereotype.Service;
135
Import org.webjars.NotFoundException;

Import javax.transaction.Transactional;
Import java.util.List;

@Service
@Transactional
Public class OrderBasketService implements IOrderBasketService {
@Autowired
Private OrderBasketRepository orderBasketRep;

@Autowired
Private ProductRepository productRep;

@Override
Public List<OrderBasket> getAllOrderBaskets() {
List<OrderBasket> orderBasket = orderBasketRep.findAll();
If (orderBasket.isEmpty()) {
Throw new NotFoundException(“Couldn’t find any product in DB”);
}
Return orderBasket;
}

136
@Override
Public List<OrderBasket> listOrderBasket(User user) {
Return orderBasketRep.findByUser(user);
}

@Override
Public Integer addProduct(Integer productId, Integer quantity, User user) {
Integer addedQuantity = quantity;

Product product = productRep.getReferenceById(productId);

OrderBasket orderBasket =
orderBasketRep.findByUserAndProduct(user, product);

If (orderBasket != null) { addedQuantity =


orderBasket.getQuantity() + quantity;
orderBasket.setQuantity(addedQuantity);
}
//The product hasn’t been added to the shopping card by this user
Else { orderBasket = new OrderBasket();
orderBasket.setQuantity(quantity); orderBasket.setUser(user);
orderBasket.setProduct(product);
}
orderBasketRep.save(orderBasket);
return addedQuantity;
}

137
@Override
Public float updateQuantity(Integer productId, Integer quantity, User user)
{ orderBasketRep.updateQuantity(quantity, productId,
user.getId()); Product product =
productRep.getReferenceById(productId);

Return product.getPrice() * quantity;


}
@Override
Public void removeProduct(Integer productId, User user) {
orderBasketRep.deleteByUserAndProduct(user.getId(), productId);
}
}

138
Package com.khomsi.site_project.service;

Import com.khomsi.site_project.entity.*;
Import com.khomsi.site_project.exception.OrderNotFoundException;
Import com.khomsi.site_project.repository.OrderRepository;
Import org.springframework.beans.factory.annotation.Autowired;
Import org.springframework.data.domain.Page;
Import org.springframework.data.domain.PageRequest;

139
Import org.springframework.data.domain.Pageable;
Import org.springframework.stereotype.Service;
Import org.webjars.NotFoundException;

Import java.util.List;
Import java.util.Optional;

@Service
Public class OrdersService implements IOrdersService {
@Autowired
Private OrderRepository orderRepository;

Public static final int ORDERS_PER_PAGE = 8;

@Override
Public List<Order> getAllOrders() {
Return orderRepository.findAll();
}
@Override
Public List<Order> getAllOrdersByUser(User user) {
Return orderRepository.findOrdersByUser(user);

140
}
@Override
Public void saveOrder(Order orders) {
orderRepository.save(orders);
}
@Override
Public Order getOrder(int id) {
Order orders = null;
Optional<Order> optional = orderRepository.findById(id);
If (optional.isPresent()) orders = optional.get();
Return orders;
}
@Override
Public Order getOrderByUser(User user) throws
OrderNotFoundException {
Order order = orderRepository.findByUser(user);
If (order == null) {
Throw new OrderNotFoundException(“Couldn’t find any orders with
ID “ + order.getId());
}
Return order;
}
@Override
Public float countSum(List<OrderBasket> orderBaskets) {
141
Float sum = 0;
For (OrderBasket orderBasket : orderBaskets) {
Sum += orderBasket.getSubtotal();
}
Return sum;
}
@Override
Public void deleteOrder(int id) throws OrderNotFoundException {
Long countById = orderRepository.countById(id);
If (countById == null || countById == 0) {
Throw new OrderNotFoundException(“Couldn’t find any orders with
id “ + id);
}
orderRepository.deleteById(id);
}
@Override
Public Page<Order> listByPage(int pageNum) {
Pageable pageable = PageRequest.of(pageNum – 1,
ORDERS_PER_PAGE);
Return orderRepository.findAll(pageable);
}

142
}

Package com.khomsi.site_project.service;

143
Import com.khomsi.site_project.entity.Product;
Import com.khomsi.site_project.exception.ProductNotFoundException;
Import com.khomsi.site_project.repository.ProductRepository;
Import org.springframework.beans.factory.annotation.Autowired;
Import org.springframework.data.domain.Page;
Import org.springframework.data.domain.PageRequest;
Import org.springframework.data.domain.Pageable;
Import org.springframework.data.domain.Sort;
Import org.springframework.stereotype.Service;

Import java.util.ArrayList;
Import java.util.Collections;
Import java.util.List;
Import java.util.NoSuchElementException;
Import java.util.Objects;

@Service
Public class ProductService implements IProductService {
@Autowired
Private ProductRepository productRepository;
Public static final int PRODUCTS_PER_PAGE = 10;
Public static final int SEARCH_RESULTS_PAGE = 10;

144
Public static final int PRODUCTS_PER_ADMIN_PAGE = 5;

@Override
Public Page<Product> listByCategory(int pageNum, Integer categoryId) {
String categoryIdMatch = “-“ + String.valueOf(categoryId) + “-“;
Pageable pageable = PageRequest.of(pageNum – 1,
PRODUCTS_PER_PAGE);

Return productRepository.listByCategory(categoryId, pageable,


categoryIdMatch);
}
@Override
Public Page<Product> listByPage(int pageNum, String sortField, String
sortDir, String keyword,
Integer categoryId) {
Sort sort = Sort.by(sortField);
Sort = sortDir.equals(“asc”) ? sort.ascending() : sort.descending();

Pageable pageable = PageRequest.of(pageNum – 1,


PRODUCTS_PER_ADMIN_PAGE, sort);

If (keyword != null && !keyword.isEmpty()) {


If (categoryId != null && categoryId > 0) {

145
String categoryIdMatch = “-“ + String.valueOf(categoryId) + “-“;
Return productRepository.searchInCategory(categoryId, categoryIdMatch,
keyword, pageable);
}
Return productRepository.findAll(keyword, pageable);
}
If (categoryId != null && categoryId > 0) {
String categoryIdMatch = “-“ + String.valueOf(categoryId) + “-“;
Return productRepository.findAllInCategory(categoryId, categoryIdMatch,
pageable);
}
Return productRepository.findAll(pageable);
}
@Override
Public List<Product> getAllProducts() throws ProductNotFoundException
{
List<Product> listProducts = productRepository.findAll();
If (listProducts.isEmpty()) {
Throw new ProductNotFoundException(“Couldn’t find any product
in DB”);
}
Return listProducts;
}

146
@Override
Public List<Product> getRandomAmountOfProducts() throws
ProductNotFoundException {
// List<Product> productList =
productRepository.findAllByCategoryId(1);
List<Product> productList = productRepository.findAll();
If (productList.isEmpty()) {
Throw new ProductNotFoundException(“Couldn’t find any product
in DB”);
}
Collections.shuffle(productList);
// int randomSeriesLength = 3;
Return productList.subList(0, productList.size());

}
@Override
Public void saveProduct(Product product) {
If (product.getAlias() == null || product.getAlias().isEmpty()) {
String defaultAlias = product.getTitle().toLowerCase();
Product.setAlias((new
CategoryService().convertCyrillic(defaultAlias).replaceAll(“ “, “_”)));
} else {
Product.setAlias(product.getAlias().replaceAll(“ “,
“_”).toLowerCase());
}

147
productRepository.save(product);
}
@Override
Public Product getProduct(Integer id) throws ProductNotFoundException
{
Try {
Return productRepository.getReferenceById(id);
} catch (NoSuchElementException e) {
Throw new ProductNotFoundException(“Couldn’t find any product
with id “ + id);

} }
@Override
Public Product getProduct(String alias) throws
ProductNotFoundException {
Try {
Return productRepository.findByAlias(alias);
} catch (NoSuchElementException e) {
Throw new ProductNotFoundException(“Couldn’t find any product
with alias “ + alias);

} }
@Override

148
Public void deleteProduct(Integer id) throws ProductNotFoundException
{
Long countById = productRepository.countById(id);
If (countById == null || countById == 0) {
Throw new ProductNotFoundException(“Couldn’t find any product
with ID “ + id);
}
productRepository.deleteById(id);
}
@Override
Public String checkUnique(Integer id, String title) {
Boolean isCreatingNew = (id == null || id == 0);
Product productByName = productRepository.findByTitle(title);
If (isCreatingNew) {
If (productByName != null) return “Duplicate”;
} else {
If (productByName != null &&
!Objects.equals(productByName.getId(), id)) {
Return “Duplicate”;
}
}
Return “OK”;
}
Public Page<Product> search(String keyword, int pageNum) {

149
Pageable pageable = PageRequest.of(pageNum – 1,
SEARCH_RESULTS_PAGE);
Return productRepository.search(keyword, pageable);

}
}

150
Package com.khomsi.site_project.service;

Import com.khomsi.site_project.entity.UserInfo;
Import com.khomsi.site_project.repository.UserInfoRepository;
Import org.springframework.beans.factory.annotation.Autowired;
Import org.springframework.stereotype.Service;

Import java.util.List;
Import java.util.Optional;
@Service
Public class UserInfoService implements IUserInfoService {
@Autowired
Private UserInfoRepository userInfoRepository;

@Override
Public List<UserInfo> getAllUserDetails() {
Return userInfoRepository.findAll();
}
@Override
Public void saveUserDetail(UserInfo userInfo) {
userInfoRepository.save(userInfo);
}
@Override
Public UserInfo getUserDetail(int id) {
UserInfo userInfo = null;
151
Optional<UserInfo> optional =
userInfoRepository.findById(id); If (optional.isPresent()) {
userInfo = optional.get();
}
Return userInfo;
}
@Override
Public void deleteUserDetail(int id) {
userInfoRepository.deleteById(id);
}
}

152
Package com.khomsi.site_project.service;

Import com.khomsi.site_project.entity.User;
Import com.khomsi.site_project.exception.UserNotFoundException;
Import com.khomsi.site_project.repository.UserRepository;
Import org.springframework.beans.factory.annotation.Autowired;
Import org.springframework.data.domain.Page;
Import org.springframework.data.domain.PageRequest;
Import org.springframework.data.domain.Pageable;
Import org.springframework.security.crypto.password.PasswordEncoder;

153
Import org.springframework.stereotype.Service;

Import java.util.List;
Import java.util.NoSuchElementException;
Import java.util.Objects;

@Service
Public class UserService implements IUserService {

@Autowired
Private UserRepository userRepository;
@Autowired
Private PasswordEncoder passwordEncoder;

Public static final int USER_PER_PAGE = 4;

@Override
Public List<User> getAllUsers() {
Return userRepository.findAll();
}
@Override
Public void saveUser(User user) {

154
Boolean isUpdatedUser = (user.getId() != null);
If (isUpdatedUser) {
User existingUser = userRepository.getReferenceById(user.getId());

If (user.getPassword().isEmpty()) {
User.setPassword(existingUser.getPassword());
} else {
encodePassword(user);
}
} else {
encodePassword(user);
}
userRepository.save(user);
}
@Override
Public User getUser(int id) throws UserNotFoundException {
Try {
Return userRepository.getReferenceById(id);
} catch (NoSuchElementException ex) {
Throw new UserNotFoundException(“Couldn’t find any user with id
“ + id);

} }
@Override
Public User getUserByLogin(String login) {
155
Return userRepository.findByLogin(login);
}
@Override
Public void deleteUser(Integer id) throws UserNotFoundException {
Long countById = userRepository.countById(id);
If (countById == null || countById == 0) {
Throw new UserNotFoundException(“Couldn’t find any user with id
“ + id);
}
userRepository.deleteById(id);
}
@Override
Public void encodePassword(User user) {
String encodePass = passwordEncoder.encode(user.getPassword());
User.setPassword(encodePass);
}
@Override
Public String isLoginUnique(Integer id, String login) {
User userByLogin = userRepository.findByLogin(login);
Boolean isCreatingNew = (id == null);

If (isCreatingNew) {

156
If (userByLogin != null) return “Duplicate”;
} else {
If (!Objects.equals(userByLogin.getId(), id)) {
Return “Duplicate”;
}
}
Return “OK”;
}
/*
Added this method to check unique login for user while he’s registration
You can modify it to have more unique fields.
(if you need unique fields in admin panel for user, change another methods
like isLoginUnique)
*/
@Override
Public boolean checkLoginRegistration(String login) {
User user = userRepository.findByLogin(login);

Return user == null;


}
@Override
Public Page<User> listByPage(int pageNum) {
Pageable pageable = PageRequest.of(pageNum – 1,
USER_PER_PAGE);
Return userRepository.findAll(pageable);

157
}
}

158
Package com.khomsi.site_project.service;

Import com.khomsi.site_project.entity.Vendor;
Import com.khomsi.site_project.repository.VendorRepository;
Import org.springframework.beans.factory.annotation.Autowired;
Import org.springframework.data.domain.Page;
Import org.springframework.data.domain.PageRequest;
Import org.springframework.data.domain.Pageable;
Import org.springframework.stereotype.Service;
Import org.webjars.NotFoundException;

Import java.util.List;
Import java.util.Objects;
Import java.util.Optional;

@Service
Public class VendorService implements IVendorService { @Autowired
Private VendorRepository vendorRepository;

Public static final int VENDORS_PER_PAGE = 4;


159
@Override
Public List<Vendor> getAllVendors() {
Return vendorRepository.findAll();
}
@Override
Public void saveVendor(Vendor vendor) {
vendorRepository.save(vendor);
}
@Override
Public Vendor getVendor(int id) {
Vendor vendor = null;
Optional<Vendor> optional = vendorRepository.findById(id);
If (optional.isPresent()) {
Vendor = optional.get();
}
Return vendor;
}
@Override
Public void deleteVendor(int id) {
Long countById = vendorRepository.countById(id);

160
If (countById == null || countById == 0) {
Throw new NotFoundException(“Couldn’t find any vendor with id “
+ id);
}
vendorRepository.deleteById(id);
}
@Override
Public Page<Vendor> listByPage(int pageNum) {
Pageable pageable = PageRequest.of(pageNum – 1,
VENDORS_PER_PAGE);
Return vendorRepository.findAll(pageable);
}
@Override
Public String checkVendorTitle(Integer id, String title) {
Vendor vendor = vendorRepository.findByTitle(title);
Boolean isCreatingNew = (id == null);

If (isCreatingNew) {
If (vendor != null) return “Duplicate”;
} else {
If (!Objects.equals(vendor.getId(), id)) {
Return “Duplicate”;
}
}
161
Return “OK”;
}
} Package com.khomsi.site_project;

Import org.springframework.boot.SpringApplication; Import


org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
Public class WebStoreApplication {
Public static void main(String[] args) {
SpringApplication.run(WebStoreApplication.class, args);
}
}

162
Êþº¾ 4 6com/khomsi/site_project/configuration/EncryptionConfig
java/lang/Object <init> ()V
Code

LineNumberTable LocalVariableTable
this
8Lcom/khomsi/site_project/configuration/EncryptionConfig; encoder
@()Lorg/springframework/security/crypto/password/PasswordEncoder;
RuntimeVisibleAnnotations -
Lorg/springframework/context/annotation/Bean;
@org/springframework/security/crypto/bcrypt/BCryptPasswordEncoder

SourceFile EncryptionConfig.java
6Lorg/springframework/context/annotation/Configuration; !

/ *· ±
<?xml
version=”1.0”

163
encoding=”UTF-
8”?>

<classpath>
<classpathentry kind=”src” output=”target/classes”
path=”src/main/java”>
<attributes>
<attribute name=”optional” value=”true”/>
<attribute name=”maven.pomderived” value=”true”/>
</attributes>
</classpathentry>
<classpathentry excluding=”**” kind=”src” output=”target/classes”
path=”src/main/resources”>
<attributes>
<attribute name=”maven.pomderived” value=”true”/>
</attributes>
</classpathentry>
<classpathentry kind=”src” output=”target/test-classes”
path=”src/test/java”>
<attributes>
<attribute name=”optional” value=”true”/>
<attribute name=”maven.pomderived” value=”true”/>
<attribute name=”test” value=”true”/>

164
</attributes>
</classpathentry>
<classpathentry kind=”con”
path=”org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.d
e bug.ui.launcher.StandardVMType/JavaSE-1.8”>
<attributes>
<attribute name=”maven.pomderived” value=”true”/>
</attributes>
</classpathentry> <classpathentry kind=”con”
path=”org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER”
>
<attributes>
<attribute name=”maven.pomderived” value=”true”/>
</attributes>
</classpathentry>
<classpathentry kind=”src”
path=”target/generatedsources/annotations”>
<attributes>
<attribute name=”optional” value=”true”/>
<attribute name=”maven.pomderived” value=”true”/>
<attribute name=”ignore_optional_problems” value=”true”/>
<attribute name=”m2e-apt” value=”true”/>
</attributes>
</classpathentry>

165
<classpathentry kind=”src” output=”target/test-classes”
path=”target/generated-test-sources/test-annotations”>
<attributes>
<attribute name=”optional” value=”true”/>
<attribute name=”maven.pomderived” value=”true”/>
<attribute name=”ignore_optional_problems” value=”true”/>
<attribute name=”m2e-apt” value=”true”/>
<attribute name=”test” value=”true”/>
</attributes>
</classpathentry>
<classpathentry kind=”output” path=”target/classes”/>
</classpath>

166
<factorypath>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/boot/spring-
bootstarterdatajpa/2.7.2/spring-boot-starter-data-jpa-2.7.2.jar”
enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/springframework/boot/springbootstarteraop/
2.7.2/spring-boot-starter-aop-2.7.2.jar” enabled=”true”
runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/aspectj/aspectjweaver/1.9.7/aspectjweaver-
1.9.7.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/boot/springbootstarterjdbc/2.7.2/spr
ing-boot-starter-jdbc-2.7.2.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/com/zaxxer/HikariCP/4.0.3/HikariCP-4.0.3.jar”
enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/springframework/springjdbc/5.3.22/spring-jdbc-
5.3.22.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/jakarta/transaction/jakarta.transactionapi/1.3.3/jakarta.tr
ansaction-api-1.3.3.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/jakarta/persistence/jakarta.persistenceapi/2.2.3/jakarta.persist
ence-api-2.2.3.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/hibernate/hibernatecore/5.6.10.Final/hibernatecore5.6.10
167
.Final.jar” enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/jboss/logging/jbosslogging/3.4.3.Final/jboss-logging-
3.4.3.Final.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/net/bytebuddy/bytebuddy/1.12.12/byte-buddy-1.12.12.jar”
enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/antlr/antlr/2.7.7/antlr2.7.7.jar” enabled=”true”
runInBatchMode=”false”/> <factorypathentry kind=”VARJAR”
id=”M2_REPO/org/jboss/jandex/2.4.2.Final/jandex-
2.4.2.Final.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/com/fasterxml/classmate/1.5.1/classmate-1.5.1.jar”
enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/hibernate/common/hibernatecommonsannotati
ons/5.1.2.Final/hibernate-commons-annotations-
5.1.2.Final.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/glassfish/jaxb/jaxbruntime/2.3.6/jaxb-runtime-
2.3.6.jar” enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/glassfish/jaxb/txw2/2.3.6/txw2-2.3.6.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/com/sun/istack/istackcommons-

168
runtime/3.0.12/istackcommons-runtime-3.0.12.jar” enabled=”true”
runInBatchMode=”false”/> <factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/data/spring-
datajpa/2.7.2/springdatajpa-2.7.2.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/data/spring-
datacommons/2.7.2/springdata-commons-2.7.2.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/springorm/5.3.22/springorm5.3.22.jar”
enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/springcontext/5.3.22/springcontext5.3.
22.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/spring-tx/5.3.22/spring-tx-
5.3.22.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/spring-beans/5.3.22/spring-beans-
5.3.22.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/springaspects/5.3
.22/springaspects5.3.22.jar” enabled=”true”
runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/springframework/boot/spring-
boot-
starterdatarest/2.7.2/spring-boot-starter-data-rest-2.7.2.jar”
enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
169
id=”M2_REPO/org/springframework/data/springdata-
restwebmvc/3.7.2/spring-data-rest-webmvc-3.7.2.jar”
enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/springframework/data/springdata-
restcore/3.7.2/springdata-rest-core-3.7.2.jar” enabled=”true”
runInBatchMode=”false”/> <factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/hateoas/springhateoas/1.5.1/s
p ringhateoas-1.5.1.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/plugin/spring-
plugincore/2.0.0.RELEASE/spring-plugin-core-2.0.0.RELEASE.jar”
enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/atteo/evoinflector/1.3/evo-inflector-1.3.jar”
enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/com/fasterxml/jackson/core/jacksondatabind/2.13.3/jackson
databind-2.13.3.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/com/fasterxml/jackson/core/jackson-
annotations/2.13.3/jackson-annotations-2.13.3.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/boot/spring-boot-
startersecurity/2.7.2/spring-boot-starter-security-2.7.2.jar” enabled=”true”
runInBatchMode=”false”/>

170
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/boot/springbootstarter
/2.7.2/springboot-starter-2.7.2.jar” enabled=”true”
runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/springframework/boot/spring-boot-
starterlogging/2.7.2/spring-boot-starter-logging-2.7.2.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/ch/qos/logback/logback-
classic/1.2.11/logbackclassic1.2.11.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/ch/qos/logback/logback-core/1.2.11/logback-core-
1.2.11.jar” enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/apache/logging/log4j/log4jtoslf4j/2.17.2/log4j-to-slf4j-
2.17.2.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/apache/logging/log4j/log4j-api/2.17.2/log4j-api-
2.17.2.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/slf4j/jultoslf4j/1.7.36/jul-to-slf4j-1.7.36.jar”
enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/jakarta/annotation/jakarta.annotationapi/1.3.5/jakarta.annota
t ion-api-1.3.5.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/yaml/snakeyaml/1.30/snakeyaml-1.30.jar”
enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
171
id=”M2_REPO/org/springframework/springaop/5.3.22/springaop
5.3.22.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/security/springsecurityconfi
g/5.7.2/spring-security-config-5.7.2.jar” enabled=”true”
runInBatchMode=”false”/> <factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/security/springsecurityweb/
5.7.2/spring-security-web-5.7.2.jar” enabled=”true”
runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR” id=”M2_REPO/org/springframework/spring-
expression/5.3.22/springexpression-5.3.22.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/boot/springbootstarterthymele
af/2.7.2/spring-boot-starter-thymeleaf-2.7.2.jar” enabled=”true”
runInBatchMode=”false”/> <factorypathentry kind=”VARJAR”
id=”M2_REPO/org/thymeleaf/thymeleaf-
spring5/3.0.15.RELEASE/thymeleaf-spring5-3.0.15.RELEASE.jar”
enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/thymeleaf/thymeleaf/3.0.15.RELEASE/thymele
af
-
3.0.15.RELEASE.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/attoparser/attoparser/2.0.5.RELEASE/attoparser2.0.5.RE
LEASE.jar” enabled=”true” runInBatchMode=”false”/>

172
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/unbescape/unbescape/1.1.6.RELEASE/unbescape1.1.6.
R
ELEASE.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/thymeleaf/extras/thymeleaf-extras-
java8time/3.0.4.RELEASE/thymeleaf-extras-java8time-
3.0.4.RELEASE.jar” enabled=”true”
runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/springframework/boot/springbootstartervali
dation/2.7.2/spring-boot-starter-validation-
2.7.2.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/apache/tomcat/embed/tomcatembedel/
9.0.65/tomcatembed-el-9.0.65.jar” enabled=”true”
runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/hibernate/validator/hibernate-
validator/6.2.3.Final/hibernate-validator-6.2.3.Final.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/jakarta/validation/jakarta.validationapi/2.0.2/jakarta.validati
o n-api-2.0.2.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/boot/spring-
bootstarterweb/2.7.2/spring-boot-starter-web-2.7.2.jar”
enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR” id=”M2_REPO/org/springframework/boot/spring-
bootstarterjson/2.7.2/spring-boot-starter-json-2.7.2.jar” enabled=”true”
runInBatchMode=”false”/>

173
<factorypathentry kind=”VARJAR”
<factorypathentry kind=”VARJAR”
id=”M2_REPO/com/fasterxml/jackson/datatype/jacksondatatypejdk8/2.13.3
/ jackson-datatype-jdk8-2.13.3.jar” enabled=”true”
runInBatchMode=”false”/>
id=”M2_REPO/com/fasterxml/jackson/datatype/jackson-
datatypejsr310/2.13.3/jackson-datatype-jsr310-2.13.3.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/com/fasterxml/jackson/module/jacksonmoduleparameterna
mes/2.13.3/jackson-module-parameter-names-
2.13.3.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/boot/spring-boot-
startertomcat/2.7.2/spring-boot-starter-tomcat-2.7.2.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/apache/tomcat/embed/tomcat-
embedcore/9.0.65/tomcatembed-core-9.0.65.jar” enabled=”true”
runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/apache/tomcat/embed/tomcatembedwebsoc
ket/9.0.65/tomcat-embed-websocket-9.0.65.jar” enabled=”true”
runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/springframework/springweb/5.3.22/springw
eb5.3.22.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/springwebmvc/5.3.22/spri
ngwebmvc5.3.22.jar” enabled=”true”
runInBatchMode=”false”/>

174
<factorypathentry kind=”VARJAR”
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/thymeleaf/extras/thymeleafextrasspringsecurity5/3.0.4.R
ELEASE/thymeleaf-extrasspringsecurity53.0.4.RELEASE.jar”
enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR” id=”M2_REPO/org/slf4j/slf4japi/1.7.36/slf4j-api-
1.7.36.jar” enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR” id=”M2_REPO/mysql/mysqlconnector-
java/8.0.29/mysqlconnector-java-
8.0.29.jar” enabled=”true” runInBatchMode=”false”/>
id=”M2_REPO/org/springframework/boot/springbootstartermail/2.7.2/
spring-boot-starter-mail-2.7.2.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/spring-
contextsupport/5.3.22/springcontext-support-5.3.22.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/com/sun/mail/jakarta.mail/1.6.7/jakarta.mail-1.6.7.jar”
enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/com/sun/activation/jakarta.activation/1.2.2/jakarta.activation
1.2.2.jar” enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/springframework/boot/springbootconfigurationprocesso
r/2.7.2/spring-boot-configuration-processor2.7.2.jar” enabled=”true”
runInBatchMode=”false”/> <factorypathentry kind=”VARJAR”
id=”M2_REPO/org/projectlombok/lombok/1.18.24/lombok-
1.18.24.jar” enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”

175
<factorypathentry kind=”VARJAR”
id=”M2_REPO/com/jayway/jsonpath/json-path/2.7.0/json-path-2.7.0.jar”
enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/net/minidev/jsonsmart/2.4.8/json-smart-2.4.8.jar”
enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/net/minidev/accessors-smart/2.4.8/accessors-smart-
2.4.8.jar” enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/ow2/asm/asm/9.1/asm-9.1.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/jakarta/xml/bind/jakarta.xml.bindapi/2.3.3/jakarta.xml.binda
pi-2.3.3.jar” enabled=”true” runInBatchMode=”false”/>
id=”M2_REPO/jakarta/activation/jakarta.activationapi/1.2.2/jakarta.activati
o n-api-1.2.2.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/springcore/5.3.22/springcore5.3.22.jar
” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/spring-jcl/5.3.22/spring-jcl-
5.3.22.jar” enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/springframework/security/springsecuritycore/5.7.2/spri
n g-security-core-5.7.2.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/security/spring-
securitycrypto/5.7.2/spring-security-crypto-5.7.2.jar” enabled=”true”
runInBatchMode=”false”/>

176
<factorypathentry kind=”VARJAR”
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/webjars/npm/normalize.css/8.0.1/normalize.css-
8.0.1.jar” enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/springframework/boot/springbootdevtools/2.7.2/springb
oot-devtools-2.7.2.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/boot/springboot/2.7.2/springboot2.7.2.
jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/boot/spring-boot-
autoconfigure/2.7.2/spring-boot-autoconfigure-2.7.2.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/webjars/bootstrap/4.3.1/bootstrap-4.3.1.jar”
enabled=”true” runInBatchMode=”false”/>
id=”M2_REPO/org/webjars/popper.js/1.14.3/popper.js-
1.14.3.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/webjars/jquery/3.4.1/jquery-3.4.1.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/webjars/webjarslocator-core/0.50/webjars-locator-core-
0.50.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/io/github/classgraph/classgraph/4.8.139/classgraph4.8.1
3 9.jar” enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”

177
<factorypathentry kind=”VARJAR”
id=”M2_REPO/com/fasterxml/jackson/core/jacksoncore/2.13.3/jacksonc
ore-2.13.3.jar” enabled=”true” runInBatchMode=”false”/>
</factorypath>,

178
*.css linguist-detectable=false *.html linguistdetectable=false
HELP.md
Target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/

### STS ###


.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans .sts4cache

### IntelliJ IDEA ###


.idea
*.iws

179
*.iml
*.ipr

### NetBeans ### /nbproject/private/


/nbbuild/
/dist/
/nbdist/ /.nb-gradle/
Build/
!**/src/main/**/build/
!**/src/test/**/build/

### VS Code ###


.vscode/
/src/main/resources/sql/WebShopDB.mwb.bak
/.mvn/
/.jpb/
Src/main/java/com/khomsi/site_project/notesToFix.html

/src/main/resources/sql/WebShop_old.mwb

180
<?xml version=”1.0” encoding=”UTF-8”?>

181
<projectDescription>
<name>site_project</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.springframework.ide.eclipse.boot.validation.springbootbuil
der</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>

182
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>

#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# “License”); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
183
# KIND, either express or implied. See the License for the #
specific language governing permissions and limitations #
under the License.
# ----------------------------------------------------------------------------

# ----------------------------------------------------------------------------
# Maven Start Up Batch script
#
# Required ENV vars:
# ------------------
# JAVA_HOME – location of a JDK home dir
#
# Optional ENV vars
# -----------------
# M2_HOME – location of maven2’s installed home dir
# MAVEN_OPTS – parameters passed to the Java VM when running
Maven
# e.g. to debug Maven itself, use
# set MAVEN_OPTS=-Xdebug -
Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
# MAVEN_SKIP_RC – flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------
If [ -z “$MAVEN_SKIP_RC” ] ; then

184
If [ -f /usr/local/etc/mavenrc ] ; then
. /usr/local/etc/mavenrc
Fi

If [ -f /etc/mavenrc ] ; then
. /etc/mavenrc
Fi
If [ -f “$HOME/.mavenrc” ] ; then
. “$HOME/.mavenrc”
Fi

Fi

# OS specific support. $var _must_ be set to either true or false.


Cygwin=false;
Darwin=false;
Mingw=false
Case “`uname`” in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true;;
Darwin*) darwin=true
# Use /usr/libexec/java_home if available, otherwise fall back to
/Library/Java/Home
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html

185
If [ -z “$JAVA_HOME” ]; then
If [ -x “/usr/libexec/java_home” ]; then
Export JAVA_HOME=”`/usr/libexec/java_home`”
Else
Export JAVA_HOME=”/Library/Java/Home”
Fi
Fi
;;
Esac

If [ -z “$JAVA_HOME” ] ; then
If [ -r /etc/gentoo-release ] ; then
JAVA_HOME=`java-config –jre-home`
Fi
Fi

If [ -z “$M2_HOME” ] ; then
## resolve links - $0 may be a link to maven’s home
PRG=”$0”

# need this for relative symlinks


While [ -h “$PRG” ] ; do
Ls=`ls -ld “$PRG”`
Link=`expr “$ls” : ‘.*-> \(.*\)$’`
186
If expr “$link” : ‘/.*’ > /dev/null; then
PRG=”$link”
Else
PRG=”`dirname “$PRG”`/$link”
Fi
Done

Saveddir=`pwd`
M2_HOME=`dirname “$PRG”`/..

# make it fully qualified


M2_HOME=`cd “$M2_HOME” && pwd`

Cd “$saveddir”
# echo Using m2 at $M2_HOME
Fi

# For Cygwin, ensure paths are in UNIX format before anything is touched If
$cygwin ; then
[ -n “$M2_HOME” ] &&
M2_HOME=`cygpath –unix “$M2_HOME”`
[ -n “$JAVA_HOME” ] &&
JAVA_HOME=`cygpath –unix “$JAVA_HOME”`
[ -n “$CLASSPATH” ] &&

187
CLASSPATH=`cygpath –path –unix “$CLASSPATH”`
Fi

# For Mingw, ensure paths are in UNIX format before anything is touched If
$mingw ; then
[ -n “$M2_HOME” ] &&
M2_HOME=”`(cd “$M2_HOME”; pwd)`”
[ -n “$JAVA_HOME” ] &&
JAVA_HOME=”`(cd “$JAVA_HOME”; pwd)`”
Fi

If [ -z “$JAVA_HOME” ]; then javaExecutable=”`which javac`” if [ -n


“$javaExecutable” ] && ! [ “`expr \”$javaExecutable\” : ‘\([^ ]*\)’`”
= “no” ]; then
# readlink(1) is not available as standard on Solaris 10.
readLink=`which readlink` if [ ! `expr “$readLink” : ‘\([^ ]*\)’`
= “no” ]; then if $darwin ; then javaHome=”`dirname
\”$javaExecutable\”`” javaExecutable=”`cd \”$javaHome\”
&& pwd -P`/javac” else
javaExecutable=”`readlink -f \”$javaExecutable\”`” fi
javaHome=”`dirname \”$javaExecutable\”`”
javaHome=`expr “$javaHome” : ‘\(.*\)/bin’`
JAVA_HOME=”$javaHome”
Export JAVA_HOME
Fi
Fi
188
Fi

If [ -z “$JAVACMD” ] ; then
If [ -n “$JAVA_HOME” ] ; then
If [ -x “$JAVA_HOME/jre/sh/java” ] ; then
# IBM’s JDK on AIX uses strange locations for the executables
JAVACMD=”$JAVA_HOME/jre/sh/java”
Else
JAVACMD=”$JAVA_HOME/bin/java”
Fi
Else
JAVACMD=”`\\unset -f command; \\command -v java`”
Fi
Fi

If [ ! -x “$JAVACMD” ] ; then
Echo “Error: JAVA_HOME is not defined correctly.” >&2
Echo “ We cannot execute $JAVACMD” >&2
Exit 1 Fi

If [ -z “$JAVA_HOME” ] ; then
Echo “Warning: JAVA_HOME environment variable is not set.”
Fi

189
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.
Launcher

# traverses directory structure from process work directory to filesystem root


# first directory with .mvn subdirectory is considered project base directory
Find_maven_basedir() {

If [ -z “$1” ]
Then
Echo “Path not specified to find_maven_basedir”
Return 1
Fi
Basedir=”$1”
Wdir=”$1”
While [ “$wdir” != ‘/’ ] ; do
If [ -d “$wdir”/.mvn ] ; then
Basedir=$wdir
Break
Fi
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
If [ -d “${wdir}” ]; then
Wdir=`cd “$wdir/..”; pwd`
Fi
# end of workaround
190
Done
Echo “${basedir}”
}

# concatenates all lines of a file


Concat_lines() {
If [ -f “$1” ]; then
Echo “$(tr -s ‘\n’ ‘ ‘ < “$1”)”
Fi
}
BASE_DIR=`find_maven_basedir “$(pwd)”`
If [ -z “$BASE_DIR” ]; then
Exit 1;
Fi

# Extension to allow automatically downloading the maven-wrapper.jar from


Maven-central
# This allows using the maven wrapper in projects that prohibit checking in
binary data.

If [ -r “$BASE_DIR/.mvn/wrapper/maven-wrapper.jar” ]; then
If [ “$MVNW_VERBOSE” = true ]; then
Echo “Found .mvn/wrapper/maven-wrapper.jar”
Fi
Else
191
If [ “$MVNW_VERBOSE” = true ]; then
Echo “Couldn’t find .mvn/wrapper/maven-wrapper.jar, downloading it
...”
Fi
If [ -n “$MVNW_REPOURL” ]; then
jarUrl=”$MVNW_REPOURL/org/apache/maven/wrapper/mavenwra
pper/3.1.0/maven-wrapper-3.1.0.jar” else

jarUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/ma
ven-wrapper/3.1.0/maven-wrapper-3.1.0.jar fi while
IFS=”=” read key value; do case “$key” in
(wrapperUrl) jarUrl=”$value”; break ;; esac
done < “$BASE_DIR/.mvn/wrapper/maven-wrapper.properties” if
[ “$MVNW_VERBOSE” = true ]; then echo “Downloading
from: $jarUrl” fi
wrapperJarPath=”$BASE_DIR/.mvn/wrapper/maven-
wrapper.jar” if $cygwin; then wrapperJarPath=`cygpath –path –
windows “$wrapperJarPath”` fi

if command -v wget > /dev/null; then if [


“$MVNW_VERBOSE” = true ]; then
echo “Found wget ... using wget” fi
if [ -z “$MVNW_USERNAME” ] || [ -z “$MVNW_PASSWORD” ]; then
wget “$jarUrl” -O “$wrapperJarPath” || rm -f “$wrapperJarPath”
else
wget –http-user=$MVNW_USERNAME –http-
password=$MVNW_PASSWORD “$jarUrl” -O “$wrapperJarPath” || rm -f
“$wrapperJarPath”

192
fi
elif command -v curl > /dev/null; then if [
“$MVNW_VERBOSE” = true ]; then
echo “Found curl ... using curl” fi
if [ -z “$MVNW_USERNAME” ] || [ -z “$MVNW_PASSWORD” ]; then
curl -o “$wrapperJarPath” “$jarUrl” -f else
curl –user $MVNW_USERNAME:$MVNW_PASSWORD -o
“$wrapperJarPath” “$jarUrl” -f fi
else if [
“$M
VNW
_VER
BOS
E” =
true ]; then
echo
“Falli
ng
back to
using
Java to
downl
oad”
fi
javaClass=”$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java”
# For Cygwin, switch paths to Windows format before running javac
If $cygwin; then javaClass=`cygpath –path –windows
“$javaClass”` fi if [ -e
“$javaClass” ]; then if
193
[ ! -e
“$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class” ];
then if [ “$MVNW_VERBOSE” = true ]; then echo
“ – Compiling MavenWrapperDownloader.java ...” fi
# Compiling the Java class
(“$JAVA_HOME/bin/javac” “$javaClass”)
Fi
If [ -e
“$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class” ]; then
# Running the downloader
If [ “$MVNW_VERBOSE” = true ]; then
Echo “ – Running MavenWrapperDownloader.java ...”
Fi
(“$JAVA_HOME/bin/java” -cp .mvn/wrapper
MavenWrapperDownloader “$MAVEN_PROJECTBASEDIR”)
Fi
Fi
Fi Fi

# End of extension

Export
MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:“$BASE_DIR”}
If [ “$MVNW_VERBOSE” = true ]; then

194
Echo $MAVEN_PROJECTBASEDIR
Fi
MAVEN_OPTS=”$(concat_lines
“$MAVEN_PROJECTBASEDIR/.mvn/jvm.config”) $MAVEN_OPTS”

# For Cygwin, switch paths to Windows format before running java If


$cygwin; then
[ -n “$M2_HOME” ] &&
M2_HOME=`cygpath –path –windows “$M2_HOME”`
[ -n “$JAVA_HOME” ] &&
JAVA_HOME=`cygpath –path –windows “$JAVA_HOME”`
[ -n “$CLASSPATH” ] &&
CLASSPATH=`cygpath –path –windows “$CLASSPATH”`
[ -n “$MAVEN_PROJECTBASEDIR” ] &&
MAVEN_PROJECTBASEDIR=`cygpath –path –windows
“$MAVEN_PROJECTBASEDIR”`
Fi

# Provide a “standardized” way to retrieve the CLI args that will # work
with both Windows and non-Windows executions.
MAVEN_CMD_LINE_ARGS=”$MAVEN_CONFIG $@”
Export MAVEN_CMD_LINE_ARGS

WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain

195
Exec “$JAVACMD” \
$MAVEN_OPTS \
$MAVEN_DEBUG_OPTS \
-classpath
“$MAVEN_PROJECTBASEDIR/.mvn/wrapper/mavenwrapper.jar” \
“-Dmaven.home=${M2_HOME}” \
“-
Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}”
\
${WRAPPER_LAUNCHER} $MAVEN_CONFIG “$@”

196
<?xml version=”1.0” encoding=”UTF-8”?> <project
xmlns=http://maven.apache.org/POM/4.0.0
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
Xsi:schemaLocation=http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.2</version>
<relativePath/> <!—lookup parent from repository 
</parent>
<groupId>com.khomsi</groupId>
<artifactId>site_project</artifactId>
<version>0.0.1SNAPSHOT</version>
<name>site_project</name>
<description>Site project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>

<dependencies>
197
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>

198
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
199
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<!—https://mvnrepository.com/artifact/org.webjars.npm/normalize.css

<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>normalize.css</artifactId>
<version>8.0.1</version>
</dependency>
<!—
https://mvnrepository.com/artifact/org.springframework.boot/springbootdevto
ols 
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>

200
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>4.3.1</version>
</dependency>

<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator-core</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${project.parent.version}</version>

201
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId> </exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>

</project>

202
This E-commerce project built on Spring Boot.<br> Look demo
below.

## Used Technologies:

* Spring (Boot, Data, Security, MVC etc)


* JPA / Hibernate
* MYSQL
* Thymeleaf
* Bootstrap, CSS, JS
* Maven
* Junit
* Lombok * SQL Query

## About Project * User can


register / log in.
* User can navigate on the main pages browse products or select an item
from the showcase, preview and categories with paginations. * User can
search for the product according to the specified criteria. * User can add
products to the shopping cart and delete products from the shopping cart.
* User can order the products in the shopping cart.
* User can change their password and view their orders.

203
* User will receive email with order after it was finished successfully. *
Admin can add or modify everything in DB (product, user, category,
vendor, basket, delivery)

/*
SQLyog Ultimate v10.00 Beta1 MySQL –
5.6.23-log : Database – web_store_test

*/

/*!40101 SET NAMES utf8 */;

/*!40101 SET SQL_MODE=’’*/;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS,


UNIQUE_CHECKS=0 */;
/*!40014 SET
@OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS,
FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE,
SQL_MODE=’NO_AUTO_VALUE_ON_ZERO’ */;

204
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0
*/;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`web_store_test`
/*!40100 DEFAULT CHARACTER SET utf8 */;
USE `web_store_test`;

/*Table structure for table `category` */

DROP TABLE IF EXISTS `category`;

CREATE TABLE `category` (


`id` int(11) NOT NULL AUTO_INCREMENT,
`alias` varchar(255) DEFAULT NULL,
`all_parent_ids` varchar(255) DEFAULT NULL,
`enabled` bit(1) NOT NULL,
`image` varchar(255) DEFAULT NULL,
`title` varchar(155) NOT NULL,
`parent_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FK2y94svpmqttx80mshyny85wqr` (`parent_id`),
CONSTRAINT `FK2y94svpmqttx80mshyny85wqr` FOREIGN KEY
(`parent_id`) REFERENCES `category` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

205
/*Data for the table `category` */

Insert into
`category`(`id`,`alias`,`all_parent_ids`,`enabled`,`image`,`title`,`parent_id`)
values
(1,’TV’,’TV’,’’,’NA’,’TV’,1),(2,’Washing’,’Washing’,’’,’NA’,’Washing’,1);
/*Table structure for table `delivery` */

DROP TABLE IF EXISTS `delivery`;

CREATE TABLE `delivery` (


`orders_id` int(11) NOT NULL,
`status` varchar(255) DEFAULT NULL,
PRIMARY KEY (`orders_id`),
CONSTRAINT `FKfci970pwpbd5v3idj3agntg80` FOREIGN KEY
(`orders_id`) REFERENCES `orders` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

/*Data for the table `delivery` */

/*Table structure for table `order_basket` */

DROP TABLE IF EXISTS `order_basket`;

CREATE TABLE `order_basket` (

206
`id` int(11) NOT NULL AUTO_INCREMENT,
`quantity` int(11) DEFAULT NULL,
`product_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `FKl7rqeve9by7viqp0whwoxths0` (`product_id`),
KEY `FKopaem614pruff3g3ia1bpx6ag` (`user_id`),
CONSTRAINT `FKl7rqeve9by7viqp0whwoxths0` FOREIGN KEY
(`product_id`) REFERENCES `product` (`id`),
CONSTRAINT `FKopaem614pruff3g3ia1bpx6ag` FOREIGN KEY
(`user_id`) REFERENCES `user` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

/*Data for the table `order_basket` */

Insert into `order_basket`(`id`,`quantity`,`product_id`,`user_id`) values


(3,6,2,2),(4,7,1,2),(6,1,2,1);

/*Table structure for table `orders` */

DROP TABLE IF EXISTS `orders`;

CREATE TABLE `orders` (


`id` int(11) NOT NULL AUTO_INCREMENT,

207
`address` varchar(255) DEFAULT NULL,
`city` varchar(255) DEFAULT NULL,
`order_status` varchar(255) DEFAULT NULL,
`shipping_type` int(11) DEFAULT NULL,
`total_price` float DEFAULT NULL,
`user_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `FKel9kyl84ego2otj2accfd8mr7` (`user_id`),
CONSTRAINT `FKel9kyl84ego2otj2accfd8mr7` FOREIGN KEY
(`user_id`) REFERENCES `user` (`id`) )
ENGINE=InnoDB DEFAULT CHARSET=utf8;

/*Data for the table `orders` */

/*Table structure for table `product` */

DROP TABLE IF EXISTS `product`;

CREATE TABLE `product` (


`id` int(11) NOT NULL AUTO_INCREMENT,
`alias` varchar(255) DEFAULT NULL,
`description` varchar(255) DEFAULT NULL,
`image` varchar(255) DEFAULT NULL,
`price` int(11) DEFAULT NULL,
208
`title` varchar(255) DEFAULT NULL,
`category_id` int(11) NOT NULL,
`vendor_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `FK1mtsbur82frn64de7balymq9s` (`category_id`),
KEY `FK9tnjxr4w1dcvbo2qejikpxpfy` (`vendor_id`),
CONSTRAINT `FK1mtsbur82frn64de7balymq9s` FOREIGN KEY
(`category_id`) REFERENCES `category` (`id`) ON DELETE CASCADE,
CONSTRAINT `FK9tnjxr4w1dcvbo2qejikpxpfy` FOREIGN KEY
(`vendor_id`) REFERENCES `vendor` (`id`) ON DELETE CASCADE )
ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
/*Data for the table `product` */

Insert into
`product`(`id`,`alias`,`description`,`image`,`price`,`title`,`category_id`,`vendo
r_id`) values
(1,’Tv’,’Television’,’279813767.jpg’,999,’TV’,1,2),(2,’Mobile’,’mobile
‘,’221194930.jpg’,888,’Mobile’,1,2),(3,’cover’,’cover’,’237286899.jpg’,777,
’cover’,2,2),(4,’tempered’,’tempered ‘,’73896886.jpg’,666,’tempered’,2,2);

/*Table structure for table `user` */

DROP TABLE IF EXISTS `user`;

CREATE TABLE `user` (


`id` int(11) NOT NULL AUTO_INCREMENT,

209
`email` varchar(255) DEFAULT NULL,
`login` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
`role` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
/*Data for the table `user` */

Insert into `user`(`id`,`email`,`login`,`password`,`role`) values


(1,’admin@gmail.com’,’ADMIN’,’$2a$10$7HpFEHn053iDSZqLbERSsOy
0
V7l4ZwlccXm49/qZ0klLf1jFkKfw.’,’ADMIN’),(2,’tyagi.vishal228@gamil. c
om’,’vishal’,’$2a$10$7HpFEHn053iDSZqLbERSsOy0V7l4ZwlccXm49/qZ
0klLf1jFkKfw.’,’USER’);

/*Table structure for table `user_info` */

DROP TABLE IF EXISTS `user_info`;

CREATE TABLE `user_info` (


`user_info_id` int(11) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`phone` varchar(255) DEFAULT NULL,
`surname` varchar(255) DEFAULT NULL,
PRIMARY KEY (`user_info_id`),

210
CONSTRAINT `FKis88irnme4d39p7mbidp2yhg8` FOREIGN KEY
(`user_info_id`) REFERENCES `user` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

/*Data for the table `user_info` */

Insert into `user_info`(`user_info_id`,`name`,`phone`,`surname`) values


(1,’admin’,’+91 – 7905206011’,’admin’),(2,’vishal’,’+91 –
9760229656’,’tyagi’);

/*Table structure for table `vendor` */

DROP TABLE IF EXISTS `vendor`;

CREATE TABLE `vendor` (


`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
/*Data for the table `vendor` */

Insert into `vendor`(`id`,`title`) values (1,’ADMIN’),(2,’USER’);

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;


/*!40014 SET
211
FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

System Requirement Analysis

2.1 Information Gathering


As the goal of the application is ease of use and to provide an
interactive interface, extensive research has been done to gain an
insight into the needs and behaviors of various users. The working of
the application is made convenient and easy to use for the end user. Dr
Andresen, Associate Professor, CIS provided regular feedback on the

project.

Users can be classified into two types based on their knowledge


of the products that suit their needs. They can be classified as users
who know about the product that would satisfy their needs and users
who have to figure out the product that would satisfy their needs.
Users who know about the product should be able to find the product
easily with the click of a button. Such users can search for the
product by using the product name as the search term. Users who
have to figure out the product that would satisfy their needs could
use a search term to find a list of products and then should be able to

212
filter the results based on various parameters like product type,
manufacturer, price range, platform supported etc.

The users should be able to view the complete specification of


the product and various images at different Zoom levels. The user
should be able to read the customer reviews for the product and the
ratings provided. They should be able to write their own reviews.
They should be able to print out the specifications for a product or
email the product page to a friends etc.
To increase the ease of use the user should be able to add a
product to the shopping cart by dragging a product and dropping it
in the shopping cart. A user should able to edit the contents of a
shopping cart. They should be able to update the quantities of the
products added to the cart and remove the products from the cart.
The user should be able to remove the product from the shopping cart
by dragging the product and dropping it outside the cart.
The application can be made interactive by pop up messages
when a product has been dropped in to the shopping cart or out of
the shopping cart. The user can be notified if the cursor enters a drop
area and the object that could be dropped. Also users are impatient
making it important to load pages soon.
Other than this, I did a lot of research on various other methods
of building this application which and was able to incorporate a few
stronger features into the application. The tools and controls used in
the application are recommended ASP.NET controls and AJAX
Toolkit controls which improves the navigation and usability and
interactivity.

213
2.2 System Feasibility
The system feasibility can be divided into the following sections:

2.2.1 Economic Feasibility


The project is economically feasible as the only cost involved
is having a computer with the minimum requirements mentioned
earlier. For the users to access the application, the only cost involved
will be in getting access to the Internet.

2.2.2 Technical Feasibility


To deploy the application, the only technical aspects needed are mentioned
below:

Operating Environment Win 2000/XP

Platform .Net Framework & IIS

Database SQL Server 2005 For

Users:

214
Internet Browser

Internet Connection

2.2.3 Behavioral Feasibility


The application requires no special technical guidance and all
the views available in the application are self explanatory. The users
are well guided with warning and failure messages for all the actions
taken.

3. System Analysis
After carefully analyzing the requirements and functionality of the
web application, I had two important diagrams by the end of the
analysis phase. They are the ER diagram and data flow diagram
which were the basis for finding out entities and relationships
between them, the flow of information.

3.1 ER Diagram

215
Figure 3.1 Entity Relation Ship Diagram

3.2 Data Flow Diagram

216
Figure 3.2: A Context Level Diagram

217
Figure 3.3: A First Level Diagram

218
Figure 3.4: A Second Level Diagram

219
Figure 3.5: A Second Level Diagram

220
3.3 Use Case Diagram

Figure 3.6: Use Case Diagram


221
3.4 Class Diagram

Figure 3.7: Class Diagram

222
4. Design

4.1 Design Goals



The design of the web application involves the design of the forms for
listing the products, search for products, display the complete
specification for the product, and design a shopping cart that is easy to
use.

Design of an interactive application that enables the user to filter the

products based on different parameters.


Design of an application that has features like drag and drop etc.


Design of application that decreases data transfers between the

client and the server.

223
4.2Architectural Design

4.2.1Architectural Context Diagram

Figure 4.1 Architectural Context Diagram

224
4.2.2 Description of Architectural Design

In this context diagram, the information provided to and


received from the ‘Online Shopping’ is identified. The arrows
represent the information received or generated by the application.
The closed boxes represent the set of sources and sinks of
information.
In the system, we can observe that the user interacts with the
application through a graphical user interface. The inputs to the
system are the Search and Filter criteria provided by the user and a
new review written by the user. Also, the output is in the form of
Repeater and grid views which present the users with list of Products
available. The users can view complete specification, view Images
and reviews by other users.

225
4.3 Procedural/Modular Approach

Following are all the modules designed for the Online Shopping
System.

4.3.1 Shop Products Module

This module starts when the user visits the home page or when
a user searches for a product by entering a search term. This part of
the application includes displaying all the products that are available
or the products that match the search term entered by the user. The
user can then filter these products based on various parameters like
manufacturer, product type, operating system supported or a price
range. The user browse through the products and each product would
be displayed with an image and its features like operating system
supported, number of user licenses and if it is a full version or an
upgrade version. A user can add a product to the cart either by
dragging the product and dropping it in the cart or by clicking a
button. The user would be able to see the shopping cart summary.

226
4.3.2 Product Description Module

This module starts when a user visits the product description


page. A user can view various images of the product of different
sizes. The use can see an enlarged image in a popup window. The
user can view the complete specification of the product like its
features, operating system supported, system requirements etc. A
user can also view the manufacturer information and also
information about rebates, exchange policies etc. A user can also
view the reviews of the product. A user can also write a review for
the product.

4.3.3 Shopping Cart Module

This module starts when the user views the shopping cart. All the
products that have been added to the shopping cart by the user are
listed along with their price and the quantity. The total price of all
the products added to cart is displayed. A user can edit the quantity
of each product or remove the product from the shopping cart. A user
can remove the product from the cart by clicking a button or by
dragging the product and dropping it outside the cart. The total price
changes accordingly when a user edits the quantity of

227
5. Implementation

5.1 Database Design and Implementation


The design of the database was similar to the analysis phase. The database
has been developed using SQL Server 2005.

Figure 5.1 Database Implementation using SQL Server


2005

These are the main tables in the application and others are lookup and
query tables. The tables were derived from the ER-Diagram.

228
5.2 User Interface Design and Implementation
The user interface of the application has been designed using
Microsoft Visual Studio 2008. The main controls used in the design
are Repeaters, Ajax Update panels, Ajax toolkit controls like modal
popup, textbox watermark and Auto complete controls.

Figure 5.2 Shop Products Page


The user can see the list of products that are available. The user can
search for products by entering the search term into the search
textbox provided on the top. This text box is watermarked with the
words “Search Terms” to let the user know that this is the place to
enter the search terms. The user can filter the products by using the
dropdown lists.

229
A user can drag and drop a product in the shopping cart. This is
shown in the figure 5.3. The cart is updated accordingly as shown
in figure 5.4

Figure 5.3 Figure showing Drag and Drop a


product in the cart

230
Figure 5.4 figure showing that Cart has been
Updated
A user can view the complete description of the product by clicking
on the product link. This is shown in figure 5.5. The user can move
the cursor on to the small images to view the same image in the
enlarged position. The user can click on the enlarged picture to see a
still bigger image in a pop up window as shown Figure 5.6

231
Figure 5.5 Product Description Page

Figure 5.6 Pop up window showing an enlarged Image


A user can also write a review by clicking on the write review tab
panel as shown in figure 5.7. Similarly a user can click on the tab
panel customer reviews, specifications, manufacturer Info etc to see
the respective information.
232
Figure 5.7 Write Review Panel
The user can click on the Go to cart button to see the Items in the cart
as shown in figure

5.8. The Summary is at the bottom of the page.

233
Figure 5.8 Cart Details Page
5.3 Technical Discussions

The products can be filtered based on various parameters like


Manufacturer, Product Type, Operating System supported etc.
Initially it was decided to have the various list items predefined. But
with time new manufacturers and product types could be added. So
the values for the list of manufacturers and product types are loaded
dynamically by retrieving from the database. Also it was decided
initially to have a drop down list for price range and the user could
select a price range from the ranges available. But this would limit
the user’s ability to filter the products based on different price ranges.
Instead providing two text fields so that the user can enter their price
range would give them more flexibility. A product could be added
to a shopping cart by dragging it and dropping it in the cart area.
Items in the cart could be removed by clicking a button. To maintain
symmetry and ease of use products could be removed from the cart
by dragging the product out of the cart.
A product can be added to the cart by dragging it and dropping
it in the cart. Initially it was decided that when a product is dropped
in the cart the cart summary label could be updated on the client side
without any call to the server and later the session variables
(Shopping cart) could be updated. This would result in loss of
information when the user loses internet connection. So when a
product is dropped in the cart area a web service is called and this
service updates the session variables for the shopping cart and the
cart summary is recalculated and sent back to the client. This would
improve the reliability of the application.

234
6. Testing
Software testing is a process of running with intent of finding
errors in software. Software testing assures the quality of software
and represents final review of other phases of software like
specification, design, code generation etc.

6.1 Unit Testing


Unit testing emphasizes the verification effort on the smallest
unit of software design i.e.; a software component or module. Unit
testing is a dynamic method for verification, where program is
actually compiled and executed. Unit testing is performed in parallel
with the coding phase. Unit testing tests units or modules not the
whole software.

235
I have tested each view/module of the application individually.
As the modules were built up testing was carried out simultaneously,
tracking out each and every kind of input and checking the
corresponding output until module is working correctly.
The functionality of the modules was also tested as separate
units. Each of the three modules was tested as separate units. In each
module all the functionalities were tested in isolation.
In the Shop Products Module when a product has been added
to cart it has been made sure that if the item already exists in the
shopping cart then the quantity is increased by one else a new item
is created in the shopping cart. Also the state of the system after a
product has been dragged in to the shopping cart is same as the state
of the system if it was added by clicking the add to cart button. Also
it has been ensured that all the images of the products displayed in
the shop products page are drag gable and have the product property
so that they can be dropped in the cart area.
In the Product Description Module it has been tested that all
the images are displayed properly. Users can add review and the as
soon as a user adds a review it is updated in the view customer review
tab. It has been checked to see if the whole page refreshes or a partial
page update happens when a user writes a review.
In the Cart Details it has been tested that when a user edits a
quantity or removes a product from the cart, the total price is updated
accordingly. It has been checked to see if the whole page refreshes
or a partial page update happens when a user edits the cart.
Visual Studio 2008 has in built support for testing the
application. The unit testing can be done using visual studio 2008
without the need of any external application. Various methods have

236
been created for the purpose of unit testing. Test cases are
automatically generated for these methods. The tests run under the
ASP.NET context which means settings from Web.config file are
automatically picked up once the test case starts running.
Methods were written to retrieve all the manufacturers from the
database, strings that match a certain search term, products that
match certain filter criteria, all images that belong to a particular
product etc. Unit test cases were automatically generated for these
methods and it can be seen in figure 6.1 that the tests have passed.

6.2 Integration Testing


In integration testing a system consisting of different modules
is tested for problems arising from component interaction.
Integration testing should be developed from the system
specification. Firstly, a minimum configuration must be integrated
and tested.
In my project I have done integration testing in a bottom up
fashion i.e. in this project I have started construction and testing with
atomic modules. After unit testing the modules are integrated one by
237
one and then tested the system for problems arising from component
interaction.

Figure 6.1 Unit Testing in Visual Studio 2008

6.3 Validation Testing


It provides final assurances that software meets all functional,
behavioral & performance requirement. Black box testing
techniques are used.

There are three main components

- Validation test criteria (no. in place of no. & char in place of char)

238
- Configuration review (to ensure the completeness of s/w configuration.) -
Alpha & Beta testing-Alpha testing is done at developer’s site i.e. at home &
Beta testing once it is deployed. Since I have not deployed my application, I
could not do the Beta testing.
Test Cases- I have used a number of test cases for testing the product.
There were different cases for which different inputs were used to
check whether desired output is produced or not.

1. Addition of a new product to the cart should create a new row in the
shopping cart.
2. Addition of an existing product to the cart has to update the quantity
of the product.
3. Any changes to items in the cart have to update the summary
correctly.
4. Because same page is inserting data into more than one table in the
database atomicity of the transaction is tested.
5. The state of the system after a product has been dragged in to the
cart should be same as the state of the system if the same product is
added to the cart by clicking a button.

6.4 White Box Testing


In white box testing knowing the internal working of the
product, tests can be conducted to ensure that internal operations are
performed according to specification and all internal components
have been adequately exercised. In white box testing logical path
through the software are tested by providing test cases that exercise
specific sets of conditions and loops.

239
Using white-box testing software developer can derive test case that
• Guarantee that all independent paths within a module have been exercised
at least once.

• Exercise all logical decisions on their true and false side.

• Exercise all loops at their boundaries and within their operational bound.
• Exercise internal data structure to ensure their validity.
At every stage of project development I have tested the logics of the
program by supplying the invalid inputs and generating the
respective error messages. All the loops and conditional statements
are tested to the boundary conditions and validated properly.

6.5 Performance Testing


Jakarta JMeter, a tool for testing applications was used to simulate
the virtual users (clients) and test the performance of the system. It
can be used to test performance both on static and dynamic resources
(files, Servlets, Perl scripts, Java Objects, Data Bases and Queries,
FTP Servers and more). It can be used to simulate a heavy load on a
server, network or object to test its strength or to analyze overall
performance under different load types. It can be used to make a
240
graphical analysis of performance and test the server/script/object
behavior under heavy concurrent load.
I have done performance testing to achieve an estimate of the peak
and sustained load the application. This has done with few pages like
the Shop Products (extensive Database access, business logic
Intensive and more Images) and the Cart Details (simple page). A
few sample Screenshots of test results are shown below. The tests
have been conducted by running the application (server) and JMeter
on same machine. These test results do not include factors like
network bandwidth etc as the server is running on the same machine
along with JMeter.

Figure 6.3 Summary Reports for 100 Users and 600 Loop Count for
Cart Details Page

Comparison of Constant Users vs. Constant Loop-Count


In the following test, the number of users has been kept constant and
the Loop Count has been increased.

241
Users Up

Cart Details Page

Loop Average
Ramp
Count period(sec) Response(ms)

100 150 10 1060

100 300 10 1071

100 600 10 1021

100 1000 10 1033


The above data shows high response average which increases with the
loop count.

242
Observations
Response Time increases rapidly with number of users but not very
much when the users are kept constant and only loop-count is
increased. This is because, if the number of users is kept constant
and only the loop count is increased, the number of requests handled
by the server per second remains constant for every execution of the
loop count and for every increase in the loop count. Hence the
response time will not increase drastically in this case. Whereas, if
the users are increased and loop count is kept constant, the requests
handled by the server per second increases with increasing users and
hence the longer response time.

Comparison of Response Times of the 2 WebPages Local


Testing:
Users
Cart
Shop
Details
Loop Ramp Up Products
Count period(sec) Page(ms) page(ms)

100 150 10 1060 28177

500 150 10 8075 105388

243
1000 150 10 11993 135273

Observations:
Response Time of a complex webpage with database and business logic
functions is far more than a simple webpage.

Factors affecting Response Time:


• Limited System Hardware Resources (CPU, RAM, Disks) and
Configuration

• JMeter Tests and Application running on the same machine.


Remote Testing:
Users

Cart
Details
Shop
Loop Ramp Up Products
Count period(sec)Page(ms) page(ms)

244
100 150 10 792 8312

500 150 10 6392 99069

1000 150 10 20457 227056

Observations:
Response Time of a complex webpage with database and business
logic functions is far more than a simple webpage. The Response
times of remote testing are better than those of local testing when the
number of users is comparatively lesser.

Factors affecting Response Time:


245

Better Hardware Resources (CPU, RAM, Disks) and


Configuration for the Application as it was hosted on a web
server.


JMeter had better access to hardware resources as the application is not
on the same machine.
Using this above tabular data, I can say that the system is adequate to
handle the normal load and the users won’t lose their focus.

7. Results & Challenges

The application can be used for any Ecommerce application. It is


easy to use, since it uses the GUI provided in the user dialog. User
friendly screens are provided. The application is easy to use and
interactive making online shopping a recreational activity for
users. It has been thoroughly tested and implemented.

246
7.1 Challenges

Compatibility with browsers like Mozilla Firefox, Internet explorer

etc


Using a layered approach in developing the application which would

make the application maintainable.


Learning new technologies like using JavaScript for drag and drop

behavior and Ajax toolkit controls with little guidance.

The overall idea of doing this project is to get a real time experience. Learn
new technologies.

247
8. Conclusions
The ‘Online Shopping’ is designed to provide a web based
application that would make searching, viewing and selection of a
product easier. The search engine provides an easy and convenient
way to search for products where a user can Search for a product
interactively and the search engine would refine the products
available based on the user’s input. The user can then view the
complete specification of each product. They can also view the
product reviews and also write their own reviews. Use of Ajax
components would make the application interactive and prevents
annoying post backs. Its drag and drop feature would make it easy to
use.

8.1 Limitations
This application does not have a built in check out process. An
external checkout package has to be integrated in to this application.
Also users cannot save the shopping carts so that they can access
later i.e. they cannot create wish lists which they can access later.
This application does not have features by which user can set price
ranges for products and receive alerts once the price reaches the
particular range.

248
8.2 Scope for Future Work
The following things can be done in future.


The current system can be extended to allow the users to create
accounts and save products in to wish list.


The users could subscribe for price alerts which would
enable them to receive messages when price for products
fall below a particular level.


The current system is confined only to the shopping cart
process. It can be extended to have an easy to use check out
process.


Users can have multiple shipping and billing information
saved. During checkout they can use the drag and drop
feature to select shipping and billing information.

249
9.HARDWARE AND SOFTWARE
REQUIREMENTS:-

Software Requirement :
Spring (Boot, Data, Security, MVC etc)

• JPA / Hibernate
• MYSQL
• Thymeleaf
• Bootstrap, CSS, JS
• Maven
• Junit
• Lombok * SQL Query

Hardware Requirement : • Intel Processor 2.0 GHz or above. •


2 GB RAM or more. • 160 GB or more Hard Disk Drive or above.

250
10. References

• All about Microsoft controls in java


http://www.msdn.microsoft.com/

• Wikipedia for various diagrams & testing methods


http://www.wikipedia.org/
• Cool text for Images and Buttons http://cooltext.com/

• K-State Research Exchange for samples in report writing

• http://krex.k-state.edu/dspace/handle/2097/959

Smart Draw for drawing all the Diagrams used in this report.

http://www.smartdraw.com/

• Sample Ecommerce Application


http://www.NewEgg.com

• Ajax Toolkit controls http://asp.net/ajax

251
252

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy