From ef48c9322fca4662d7e6c5fb67596a894c3c82b5 Mon Sep 17 00:00:00 2001 From: Mahamat Nour Mahamat Abdraman <42040735+manirDev@users.noreply.github.com> Date: Fri, 11 Nov 2022 17:11:51 +0300 Subject: [PATCH 01/13] Create README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..70a9e4a --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# Spring-boot-e-commerce-rest-api +Spring Boot E-commerce Rest Api From e9d33c26dbe99df04258ec5c906657d73bacafc5 Mon Sep 17 00:00:00 2001 From: manirDev Date: Mon, 14 Nov 2022 14:57:52 +0300 Subject: [PATCH 02/13] Sign-In and Sign-Up is successfully done. --- .../config/SecurityConfig.java | 10 +++ .../controller/AuthController.java | 61 +++++++++++++++++++ .../dto/LoginDto.java | 9 +++ .../dto/SignUpDto.java | 11 ++++ .../service/Impl/UserRegisterServiceImpl.java | 57 +++++++++++++++++ .../service/UserRegisterService.java | 7 +++ 6 files changed, 155 insertions(+) create mode 100644 src/main/java/com/manir/springbootecommercerestapi/controller/AuthController.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/dto/LoginDto.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/dto/SignUpDto.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/service/Impl/UserRegisterServiceImpl.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/service/UserRegisterService.java diff --git a/src/main/java/com/manir/springbootecommercerestapi/config/SecurityConfig.java b/src/main/java/com/manir/springbootecommercerestapi/config/SecurityConfig.java index 81e3fd8..baf3107 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/config/SecurityConfig.java +++ b/src/main/java/com/manir/springbootecommercerestapi/config/SecurityConfig.java @@ -5,6 +5,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; +import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @@ -38,6 +39,8 @@ protected void configure(HttpSecurity http) throws Exception { .authorizeRequests() //to permit all get request and secure post put and delete methods .antMatchers(HttpMethod.GET, "/api/**").permitAll() + //authorize singIn and signUp + .antMatchers("/api/v1/auth/**").permitAll() .anyRequest() .authenticated() .and() @@ -67,4 +70,11 @@ protected void configure(AuthenticationManagerBuilder auth) throws Exception { PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } + + //User authentication manager bean + @Override + @Bean + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); + } } diff --git a/src/main/java/com/manir/springbootecommercerestapi/controller/AuthController.java b/src/main/java/com/manir/springbootecommercerestapi/controller/AuthController.java new file mode 100644 index 0000000..82257aa --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/controller/AuthController.java @@ -0,0 +1,61 @@ +package com.manir.springbootecommercerestapi.controller; + +import com.manir.springbootecommercerestapi.dto.LoginDto; +import com.manir.springbootecommercerestapi.dto.SignUpDto; +import com.manir.springbootecommercerestapi.repository.UserRepository; +import com.manir.springbootecommercerestapi.service.UserRegisterService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + + + +@RestController +@RequestMapping(value = "api/v1/auth") +public class AuthController { + + @Autowired + private AuthenticationManager authenticationManager; + @Autowired + private UserRepository userRepository; + @Autowired + private UserRegisterService userRegisterService; + + //login api + @PostMapping("/login") + public ResponseEntity authenticateUser(@RequestBody LoginDto loginDto){ + + Authentication authentication = authenticationManager.authenticate( + new UsernamePasswordAuthenticationToken( + loginDto.getUserNameOrEmail(), + loginDto.getPassword() + ) + ); + SecurityContextHolder.getContext().setAuthentication(authentication); + return new ResponseEntity<>("User sign-In successfully", HttpStatus.OK); + } + + //register api + @PostMapping("/register") + public ResponseEntity registerUser(@RequestBody SignUpDto signUpDto){ + + //check for username exists in DB + if (userRepository.existsByUserName(signUpDto.getUsername())){ + return new ResponseEntity<>("Username already exists", HttpStatus.BAD_REQUEST); + } + if (userRepository.existsByEmail(signUpDto.getEmail())){ + return new ResponseEntity<>("Email already exists", HttpStatus.BAD_REQUEST); + } + SignUpDto registeredUser = userRegisterService.registerUser(signUpDto); + return new ResponseEntity<>("User is successfully registered", HttpStatus.OK); + } + +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/dto/LoginDto.java b/src/main/java/com/manir/springbootecommercerestapi/dto/LoginDto.java new file mode 100644 index 0000000..1c3c8a1 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/dto/LoginDto.java @@ -0,0 +1,9 @@ +package com.manir.springbootecommercerestapi.dto; + +import lombok.Data; + +@Data +public class LoginDto { + private String userNameOrEmail; + private String password; +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/dto/SignUpDto.java b/src/main/java/com/manir/springbootecommercerestapi/dto/SignUpDto.java new file mode 100644 index 0000000..a2e2eaa --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/dto/SignUpDto.java @@ -0,0 +1,11 @@ +package com.manir.springbootecommercerestapi.dto; + +import lombok.Data; + +@Data +public class SignUpDto { + private String name; + private String username; + private String email; + private String password; +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/Impl/UserRegisterServiceImpl.java b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/UserRegisterServiceImpl.java new file mode 100644 index 0000000..7458041 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/UserRegisterServiceImpl.java @@ -0,0 +1,57 @@ +package com.manir.springbootecommercerestapi.service.Impl; + +import com.manir.springbootecommercerestapi.dto.SignUpDto; +import com.manir.springbootecommercerestapi.model.Role; +import com.manir.springbootecommercerestapi.model.User; +import com.manir.springbootecommercerestapi.repository.RoleRepository; +import com.manir.springbootecommercerestapi.repository.UserRepository; +import com.manir.springbootecommercerestapi.service.UserRegisterService; +import org.modelmapper.ModelMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; + +import java.util.Collections; + +@Service +public class UserRegisterServiceImpl implements UserRegisterService { + + @Autowired + private UserRepository userRepository; + @Autowired + private RoleRepository roleRepository; + @Autowired + private PasswordEncoder passwordEncoder; + @Autowired + private ModelMapper modelMapper; + + @Override + public SignUpDto registerUser(SignUpDto signUpDto) { + + //convert dto to entity + User user = mapToEntity(signUpDto); + //save user to db + User registeredUser = userRepository.save(user); + return mapToDto(registeredUser); + } + + //map to dto + private SignUpDto mapToDto(User user){ + SignUpDto signUpDto = modelMapper.map(user, SignUpDto.class); + return signUpDto; + } + + //map to entity + private User mapToEntity(SignUpDto signUpDto){ + User user = new User(); + user.setName(signUpDto.getName()); + user.setUserName(signUpDto.getUsername()); + user.setEmail(signUpDto.getEmail()); + user.setPassword(passwordEncoder.encode(signUpDto.getPassword())); + + //add role to the user + Role role = roleRepository.findByName("ROLE_USER").get(); + user.setRoles(Collections.singleton(role)); + return user; + } +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/UserRegisterService.java b/src/main/java/com/manir/springbootecommercerestapi/service/UserRegisterService.java new file mode 100644 index 0000000..9096440 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/service/UserRegisterService.java @@ -0,0 +1,7 @@ +package com.manir.springbootecommercerestapi.service; + +import com.manir.springbootecommercerestapi.dto.SignUpDto; + +public interface UserRegisterService { + SignUpDto registerUser(SignUpDto signUpDto); +} From 67233d517945423ade8c0a31ed3aab6e0e70aa46 Mon Sep 17 00:00:00 2001 From: manirDev Date: Tue, 15 Nov 2022 11:20:33 +0300 Subject: [PATCH 03/13] ShoppingCart changed with customer authentication --- .../controller/AuthController.java | 2 +- .../controller/ShoppingCartController.java | 82 ++++++++++++++----- .../dto/OrderDto.java | 15 ++++ .../model/Order.java | 37 +++++++++ .../model/OrderProducts.java | 38 +++++++++ .../model/Product.java | 6 ++ .../model/User.java | 12 +++ .../repository/CartItemRepository.java | 8 +- .../security/CustomUserDetails.java | 53 ++++++++++++ .../service/Impl/ShoppingCartServiceImpl.java | 25 +++--- .../service/ShoppingCartService.java | 9 +- 11 files changed, 244 insertions(+), 43 deletions(-) create mode 100644 src/main/java/com/manir/springbootecommercerestapi/dto/OrderDto.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/model/Order.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/model/OrderProducts.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/security/CustomUserDetails.java diff --git a/src/main/java/com/manir/springbootecommercerestapi/controller/AuthController.java b/src/main/java/com/manir/springbootecommercerestapi/controller/AuthController.java index 82257aa..2bf09f2 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/controller/AuthController.java +++ b/src/main/java/com/manir/springbootecommercerestapi/controller/AuthController.java @@ -54,7 +54,7 @@ public ResponseEntity registerUser(@RequestBody SignUpDto signUpDto){ if (userRepository.existsByEmail(signUpDto.getEmail())){ return new ResponseEntity<>("Email already exists", HttpStatus.BAD_REQUEST); } - SignUpDto registeredUser = userRegisterService.registerUser(signUpDto); + userRegisterService.registerUser(signUpDto); return new ResponseEntity<>("User is successfully registered", HttpStatus.OK); } diff --git a/src/main/java/com/manir/springbootecommercerestapi/controller/ShoppingCartController.java b/src/main/java/com/manir/springbootecommercerestapi/controller/ShoppingCartController.java index 4859845..593ffe0 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/controller/ShoppingCartController.java +++ b/src/main/java/com/manir/springbootecommercerestapi/controller/ShoppingCartController.java @@ -1,16 +1,22 @@ package com.manir.springbootecommercerestapi.controller; -import com.manir.springbootecommercerestapi.dto.CartItemDto; +import com.manir.springbootecommercerestapi.exception.EcommerceApiException; +import com.manir.springbootecommercerestapi.model.User; +import com.manir.springbootecommercerestapi.repository.UserRepository; import com.manir.springbootecommercerestapi.response.CartItemResponse; import com.manir.springbootecommercerestapi.service.ShoppingCartService; import com.manir.springbootecommercerestapi.utils.isAuthenticatedAsAdminOrUser; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.authentication.AnonymousAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; -import java.util.List; @RestController @RequestMapping("api/v1/cart") @@ -19,43 +25,75 @@ public class ShoppingCartController { @Resource private ShoppingCartService shoppingCartService; + @Autowired + private UserRepository userRepository; + + //find by customer api @isAuthenticatedAsAdminOrUser - @GetMapping("/findByCustomer/{customerId}") - public CartItemResponse findByCustomerId(@PathVariable Long customerId){ - CartItemResponse responseCartItems = shoppingCartService.findByCustomerId(customerId); + @GetMapping("/findByCustomer") + public CartItemResponse findByCustomerId(@AuthenticationPrincipal Authentication authentication){ + authentication = SecurityContextHolder.getContext().getAuthentication(); + if (!(authentication instanceof AnonymousAuthenticationToken)) { + String currentUserEmail = authentication.getName(); + //System.out.println("Name:" + currentUserEmail); + User customer = userRepository.findByEmail(currentUserEmail).orElseThrow(()-> new UsernameNotFoundException("Customer not found")); + CartItemResponse responseCartItems = shoppingCartService.findByCustomer(customer); + return responseCartItems; + + }else{ + throw new EcommerceApiException("User not authenticated", HttpStatus.BAD_REQUEST); + } - return responseCartItems; } //add item to the cart api @isAuthenticatedAsAdminOrUser - @PostMapping("/addItem/{customerId}/{productId}/{quantity}") - public ResponseEntity addCartItem(@PathVariable Long customerId, + @PostMapping("/addItem/{productId}/{quantity}") + public ResponseEntity addCartItem(@AuthenticationPrincipal Authentication authentication, @PathVariable Long productId, @PathVariable Integer quantity){ - CartItemResponse responseCartItem = shoppingCartService.addCartItem(customerId, productId, quantity); - - return new ResponseEntity<>(responseCartItem, HttpStatus.CREATED); + authentication = SecurityContextHolder.getContext().getAuthentication(); + if (!(authentication instanceof AnonymousAuthenticationToken)){ + String currentUserEmail = authentication.getName(); + User customer = userRepository.findByEmail(currentUserEmail).orElseThrow(() -> new UsernameNotFoundException("Customer not found")); + CartItemResponse responseCartItem = shoppingCartService.addCartItem(customer, productId, quantity); + return new ResponseEntity<>(responseCartItem, HttpStatus.CREATED); + }else { + throw new EcommerceApiException("User not authenticated", HttpStatus.BAD_REQUEST); + } } //update item quantity api @isAuthenticatedAsAdminOrUser - @PutMapping("/updateItemQuantity/{customerId}/{productId}/{quantity}") - public ResponseEntity updateItemQuantity(@PathVariable Long customerId, + @PutMapping("/updateItemQuantity/{productId}/{quantity}") + public ResponseEntity updateItemQuantity(@AuthenticationPrincipal Authentication authentication, @PathVariable Long productId, @PathVariable Integer quantity){ - - CartItemResponse responseCartItem = shoppingCartService.updateItemQuantity(customerId, productId, quantity); - - return new ResponseEntity<>(responseCartItem, HttpStatus.OK); + authentication = SecurityContextHolder.getContext().getAuthentication(); + if (!(authentication instanceof AnonymousAuthenticationToken)){ + String currentUserEmail = authentication.getName(); + User customer = userRepository.findByEmail(currentUserEmail).orElseThrow(() -> new UsernameNotFoundException("Customer Not found")); + CartItemResponse responseCartItem = shoppingCartService.updateItemQuantity(customer, productId, quantity); + return new ResponseEntity<>(responseCartItem, HttpStatus.OK); + }else{ + throw new EcommerceApiException("User not authenticated", HttpStatus.BAD_REQUEST); + } } //delete item product api @isAuthenticatedAsAdminOrUser - @DeleteMapping("/deleteItemProduct/{customerId}/{productId}") - public ResponseEntity deleteItemProduct(@PathVariable Long customerId, @PathVariable Long productId){ - shoppingCartService.deleteItemProduct(customerId, productId); - return ResponseEntity.ok("Product with id = " + productId +" is deleted successfully from your shopping cart"); + @DeleteMapping("/deleteItemProduct/{productId}") + public ResponseEntity deleteItemProduct(@AuthenticationPrincipal Authentication authentication, + @PathVariable Long productId){ + authentication = SecurityContextHolder.getContext().getAuthentication(); + if (!(authentication instanceof AnonymousAuthenticationToken)){ + String currentUserEmail = authentication.getName(); + User customer = userRepository.findByEmail(currentUserEmail).orElseThrow(() -> new UsernameNotFoundException("Customer Not found")); + shoppingCartService.deleteItemProduct(customer, productId); + return ResponseEntity.ok("Product with id = " + productId +" is deleted successfully from your shopping cart"); + }else{ + throw new EcommerceApiException("User not authenticated", HttpStatus.BAD_REQUEST); + } } } diff --git a/src/main/java/com/manir/springbootecommercerestapi/dto/OrderDto.java b/src/main/java/com/manir/springbootecommercerestapi/dto/OrderDto.java new file mode 100644 index 0000000..7f2cee5 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/dto/OrderDto.java @@ -0,0 +1,15 @@ +package com.manir.springbootecommercerestapi.dto; + +import lombok.Data; + +@Data +public class OrderDto { + private Long id; + private String name; + private String email; + private String phone; + private String address; + private double totalPrice; + private String note; + private String status; +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/model/Order.java b/src/main/java/com/manir/springbootecommercerestapi/model/Order.java new file mode 100644 index 0000000..56054d5 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/model/Order.java @@ -0,0 +1,37 @@ +package com.manir.springbootecommercerestapi.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import java.util.Set; + +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "orders") +public class Order { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private String name; + private String email; + private String phone; + private String address; + private double totalPrice; + private String note; + private String status; + + //relation with user + @ManyToOne() + @JoinColumn(name = "customer_id") + private User customer; + + //relation with order_products + @OneToMany(cascade = CascadeType.ALL, + fetch = FetchType.LAZY, orphanRemoval = true, + mappedBy = "order") + private Set orderProducts; +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/model/OrderProducts.java b/src/main/java/com/manir/springbootecommercerestapi/model/OrderProducts.java new file mode 100644 index 0000000..b9362c5 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/model/OrderProducts.java @@ -0,0 +1,38 @@ +package com.manir.springbootecommercerestapi.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; + +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "order_products") +public class OrderProducts { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private double productPrice; + private Integer productQuantity; + private double totalPrice; + private String note; + private String status; + + //relation with user + @ManyToOne() + @JoinColumn(name = "customer_id") + private User customer; + + //relation with product + @ManyToOne() + @JoinColumn(name = "product_id") + private Product product; + + //relation with order + @ManyToOne() + @JoinColumn(name = "order_id") + private Order order; +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/model/Product.java b/src/main/java/com/manir/springbootecommercerestapi/model/Product.java index 77bc06e..78c7f3b 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/model/Product.java +++ b/src/main/java/com/manir/springbootecommercerestapi/model/Product.java @@ -54,4 +54,10 @@ public class Product { //relation to cart item @OneToMany(mappedBy = "product", cascade = CascadeType.ALL, orphanRemoval = true) private Set cartItems; + + //relation with order_products + @OneToMany(cascade = CascadeType.ALL, + fetch = FetchType.LAZY, orphanRemoval = true, + mappedBy = "product") + private Set orderProducts; } diff --git a/src/main/java/com/manir/springbootecommercerestapi/model/User.java b/src/main/java/com/manir/springbootecommercerestapi/model/User.java index 5f92a22..7489091 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/model/User.java +++ b/src/main/java/com/manir/springbootecommercerestapi/model/User.java @@ -31,4 +31,16 @@ public class User { joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id")) private Set roles; + + //relation with order + @OneToMany(cascade = CascadeType.ALL, + fetch = FetchType.LAZY, orphanRemoval = true, + mappedBy = "customer") + private Set orders; + + //relation with order_product + @OneToMany(cascade = CascadeType.ALL, + fetch = FetchType.LAZY, orphanRemoval = true, + mappedBy = "customer") + private Set orderProducts; } diff --git a/src/main/java/com/manir/springbootecommercerestapi/repository/CartItemRepository.java b/src/main/java/com/manir/springbootecommercerestapi/repository/CartItemRepository.java index d315263..0f1c119 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/repository/CartItemRepository.java +++ b/src/main/java/com/manir/springbootecommercerestapi/repository/CartItemRepository.java @@ -1,6 +1,8 @@ package com.manir.springbootecommercerestapi.repository; import com.manir.springbootecommercerestapi.model.CartItem; +import com.manir.springbootecommercerestapi.model.Product; +import com.manir.springbootecommercerestapi.model.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; @@ -9,16 +11,16 @@ public interface CartItemRepository extends JpaRepository { - List findByCustomerId(Long customerId); + List findByCustomer(User customer); //CartItem findByCustomerAndProduct(User customer, Product product); - CartItem findByCustomerIdAndProductId(Long customerId, Long productId); + CartItem findByCustomerAndProduct(User customer, Product product); @Query("UPDATE CartItem c SET c.quantity = ?3 WHERE c.product.id = ?2 AND c.customer.id = ?1") void updateItemQuantity(Long customerId, Long productId, Integer quantity); @Query("DELETE FROM CartItem c WHERE c.customer.id = ?1 AND c.product.id = ?2") @Modifying - void deleteByCustomerIdAndProductId(Long customerId, Long productId); + void deleteByCustomerAndProduct(Long customerId, Long productId); } diff --git a/src/main/java/com/manir/springbootecommercerestapi/security/CustomUserDetails.java b/src/main/java/com/manir/springbootecommercerestapi/security/CustomUserDetails.java new file mode 100644 index 0000000..0fe8a10 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/security/CustomUserDetails.java @@ -0,0 +1,53 @@ +package com.manir.springbootecommercerestapi.security; + +import com.manir.springbootecommercerestapi.model.User; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import java.util.Collection; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CustomUserDetails implements UserDetails { + private User user; + @Override + public Collection getAuthorities() { + return null; + } + + @Override + public String getPassword() { + return null; + } + + @Override + public String getUsername() { + return user.getEmail(); + } + + @Override + public boolean isAccountNonExpired() { + return false; + } + + @Override + public boolean isAccountNonLocked() { + return false; + } + + @Override + public boolean isCredentialsNonExpired() { + return false; + } + + @Override + public boolean isEnabled() { + return false; + } + + +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/Impl/ShoppingCartServiceImpl.java b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/ShoppingCartServiceImpl.java index a35796b..cc98060 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/service/Impl/ShoppingCartServiceImpl.java +++ b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/ShoppingCartServiceImpl.java @@ -38,9 +38,9 @@ public class ShoppingCartServiceImpl implements ShoppingCartService { @Resource private CommonService commonService; @Override - public CartItemResponse findByCustomerId(Long customerId) { + public CartItemResponse findByCustomer(User customer) { - List cartItems = cartItemRepository.findByCustomerId(customerId); + List cartItems = cartItemRepository.findByCustomer(customer); if (cartItems.size() == 0){ throw new EcommerceApiException("User has no product in cart item", HttpStatus.BAD_REQUEST); @@ -58,18 +58,17 @@ public CartItemResponse findByCustomerId(Long customerId) { } @Override - public CartItemResponse addCartItem(Long customerId, Long productId, Integer quantity) { + public CartItemResponse addCartItem(User customer, Long productId, Integer quantity) { Integer addedQuantity = quantity; - User user = findCustomerById(customerId); Product product = findProductById(productId); - CartItem cartItem = cartItemRepository.findByCustomerIdAndProductId(customerId, productId); + CartItem cartItem = cartItemRepository.findByCustomerAndProduct(customer, product); if(cartItem != null){ addedQuantity = cartItem.getQuantity() + quantity; cartItem.setQuantity(addedQuantity); }else { cartItem = new CartItem(); - cartItem.setCustomer(user); + cartItem.setCustomer(customer); cartItem.setProduct(product); cartItem.setQuantity(quantity); } @@ -82,9 +81,9 @@ public CartItemResponse addCartItem(Long customerId, Long productId, Integer qua } @Override - public CartItemResponse updateItemQuantity(Long customerId, Long productId, Integer quantity) { - - CartItem cartItem = cartItemRepository.findByCustomerIdAndProductId(customerId, productId); + public CartItemResponse updateItemQuantity(User customer, Long productId, Integer quantity) { + Product product = findProductById(productId); + CartItem cartItem = cartItemRepository.findByCustomerAndProduct(customer, product); if (cartItem == null){ throw new EcommerceApiException("Product is not in the cart item", HttpStatus.BAD_REQUEST); } @@ -98,13 +97,13 @@ public CartItemResponse updateItemQuantity(Long customerId, Long productId, Inte @Override @Transactional - public void deleteItemProduct(Long customerId, Long productId) { - - CartItem cartItem = cartItemRepository.findByCustomerIdAndProductId(customerId, productId); + public void deleteItemProduct(User customer, Long productId) { + Product product = findProductById(productId); + CartItem cartItem = cartItemRepository.findByCustomerAndProduct(customer, product); if (cartItem == null){ throw new EcommerceApiException("Product is not in the cart item", HttpStatus.BAD_REQUEST); } - cartItemRepository.deleteByCustomerIdAndProductId(customerId, productId); + cartItemRepository.deleteByCustomerAndProduct(customer.getId(), productId); } //map to dto diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/ShoppingCartService.java b/src/main/java/com/manir/springbootecommercerestapi/service/ShoppingCartService.java index 7520bbf..f657c98 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/service/ShoppingCartService.java +++ b/src/main/java/com/manir/springbootecommercerestapi/service/ShoppingCartService.java @@ -1,14 +1,15 @@ package com.manir.springbootecommercerestapi.service; +import com.manir.springbootecommercerestapi.model.User; import com.manir.springbootecommercerestapi.response.CartItemResponse; public interface ShoppingCartService { - CartItemResponse findByCustomerId(Long customerId); + CartItemResponse findByCustomer(User customer); - CartItemResponse addCartItem(Long customerId, Long productId, Integer quantity); + CartItemResponse addCartItem(User customer, Long productId, Integer quantity); - CartItemResponse updateItemQuantity(Long customerId, Long productId, Integer quantity); + CartItemResponse updateItemQuantity(User customer, Long productId, Integer quantity); - void deleteItemProduct(Long customerId, Long productId); + void deleteItemProduct(User customer, Long productId); } From 4f28a19f8aa7b48ebad094d840bbbfb0013b970a Mon Sep 17 00:00:00 2001 From: manirDev Date: Tue, 15 Nov 2022 14:52:20 +0300 Subject: [PATCH 04/13] order and ordered products is implemented successfully. --- .../controller/OrderController.java | 63 +++++++++++++ .../controller/ShoppingCartController.java | 9 +- .../dto/OrderDto.java | 3 + .../dto/OrderProductsDto.java | 13 +++ .../model/Order.java | 7 +- .../model/User.java | 7 +- .../repository/CartItemRepository.java | 4 + .../repository/OrderProductsRepository.java | 8 ++ .../repository/OrderRepository.java | 12 +++ .../Impl/OrderProductsServiceImpl.java | 22 +++++ .../service/Impl/OrderServiceImpl.java | 94 +++++++++++++++++++ .../service/OrderProductsService.java | 7 ++ .../service/OrderService.java | 13 +++ 13 files changed, 254 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/manir/springbootecommercerestapi/controller/OrderController.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/dto/OrderProductsDto.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/repository/OrderProductsRepository.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/repository/OrderRepository.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/service/Impl/OrderProductsServiceImpl.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/service/Impl/OrderServiceImpl.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/service/OrderProductsService.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/service/OrderService.java diff --git a/src/main/java/com/manir/springbootecommercerestapi/controller/OrderController.java b/src/main/java/com/manir/springbootecommercerestapi/controller/OrderController.java new file mode 100644 index 0000000..0805dee --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/controller/OrderController.java @@ -0,0 +1,63 @@ +package com.manir.springbootecommercerestapi.controller; + +import com.manir.springbootecommercerestapi.dto.OrderDto; +import com.manir.springbootecommercerestapi.exception.EcommerceApiException; +import com.manir.springbootecommercerestapi.model.Order; +import com.manir.springbootecommercerestapi.model.User; +import com.manir.springbootecommercerestapi.repository.UserRepository; +import com.manir.springbootecommercerestapi.service.OrderService; +import com.manir.springbootecommercerestapi.utils.isAuthenticatedAsAdminOrUser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.authentication.AnonymousAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +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.RestController; + +import java.util.List; + +@RestController +@RequestMapping(value = "api/v1/order") +public class OrderController { + + @Autowired + private UserRepository userRepository; + @Autowired + private OrderService orderService; + + //place order complete order api + @isAuthenticatedAsAdminOrUser + @PostMapping("/placeOrder") + public ResponseEntity placeOrder(@AuthenticationPrincipal Authentication authentication){ + authentication = SecurityContextHolder.getContext().getAuthentication(); + if (!(authentication instanceof AnonymousAuthenticationToken)){ + String currentUserEmail = authentication.getName(); + User customer = userRepository.findByEmail(currentUserEmail).orElseThrow(() -> new UsernameNotFoundException("Customer Not found")); + orderService.placeOrder(customer); + return new ResponseEntity<>("Order placed successfully", HttpStatus.CREATED); + }else{ + throw new EcommerceApiException("User not authenticated", HttpStatus.BAD_REQUEST); + } + } + + //find order by customer api + @isAuthenticatedAsAdminOrUser + @GetMapping("/findByCustomer") + public List listOrdersByCustomer(@AuthenticationPrincipal Authentication authentication){ + authentication = SecurityContextHolder.getContext().getAuthentication(); + if (!(authentication instanceof AnonymousAuthenticationToken)){ + String currentUserEmail = authentication.getName(); + User customer = userRepository.findByEmail(currentUserEmail).orElseThrow(() -> new UsernameNotFoundException("Customer Not found")); + List customerOrders = orderService.listOrdersByCustomer(customer); + return customerOrders; + }else{ + throw new EcommerceApiException("User not authenticated", HttpStatus.BAD_REQUEST); + } + } +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/controller/ShoppingCartController.java b/src/main/java/com/manir/springbootecommercerestapi/controller/ShoppingCartController.java index 593ffe0..7cac9e1 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/controller/ShoppingCartController.java +++ b/src/main/java/com/manir/springbootecommercerestapi/controller/ShoppingCartController.java @@ -4,6 +4,7 @@ import com.manir.springbootecommercerestapi.model.User; import com.manir.springbootecommercerestapi.repository.UserRepository; import com.manir.springbootecommercerestapi.response.CartItemResponse; +import com.manir.springbootecommercerestapi.service.OrderService; import com.manir.springbootecommercerestapi.service.ShoppingCartService; import com.manir.springbootecommercerestapi.utils.isAuthenticatedAsAdminOrUser; import org.springframework.beans.factory.annotation.Autowired; @@ -24,10 +25,10 @@ public class ShoppingCartController { @Resource private ShoppingCartService shoppingCartService; - @Autowired private UserRepository userRepository; - + @Autowired + private OrderService orderService; //find by customer api @isAuthenticatedAsAdminOrUser @@ -96,4 +97,8 @@ public ResponseEntity deleteItemProduct(@AuthenticationPrincipal Authent throw new EcommerceApiException("User not authenticated", HttpStatus.BAD_REQUEST); } } + + + + } diff --git a/src/main/java/com/manir/springbootecommercerestapi/dto/OrderDto.java b/src/main/java/com/manir/springbootecommercerestapi/dto/OrderDto.java index 7f2cee5..a5c1332 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/dto/OrderDto.java +++ b/src/main/java/com/manir/springbootecommercerestapi/dto/OrderDto.java @@ -1,5 +1,6 @@ package com.manir.springbootecommercerestapi.dto; +import com.manir.springbootecommercerestapi.model.User; import lombok.Data; @Data @@ -12,4 +13,6 @@ public class OrderDto { private double totalPrice; private String note; private String status; + + private User customer; } diff --git a/src/main/java/com/manir/springbootecommercerestapi/dto/OrderProductsDto.java b/src/main/java/com/manir/springbootecommercerestapi/dto/OrderProductsDto.java new file mode 100644 index 0000000..166dad0 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/dto/OrderProductsDto.java @@ -0,0 +1,13 @@ +package com.manir.springbootecommercerestapi.dto; + +import lombok.Data; + +@Data +public class OrderProductsDto { + private Long id; + private double productPrice; + private Integer productQuantity; + private double totalPrice; + private String note; + private String status; +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/model/Order.java b/src/main/java/com/manir/springbootecommercerestapi/model/Order.java index 56054d5..73e9f68 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/model/Order.java +++ b/src/main/java/com/manir/springbootecommercerestapi/model/Order.java @@ -1,15 +1,14 @@ package com.manir.springbootecommercerestapi.model; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; +import lombok.*; import javax.persistence.*; import java.util.Set; @AllArgsConstructor @NoArgsConstructor -@Data +@Getter +@Setter @Entity @Table(name = "orders") public class Order { diff --git a/src/main/java/com/manir/springbootecommercerestapi/model/User.java b/src/main/java/com/manir/springbootecommercerestapi/model/User.java index 7489091..edc66b9 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/model/User.java +++ b/src/main/java/com/manir/springbootecommercerestapi/model/User.java @@ -1,11 +1,14 @@ package com.manir.springbootecommercerestapi.model; -import lombok.Data; +import lombok.*; import javax.persistence.*; import java.util.Set; -@Data +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor @Entity @Table(name = "users", uniqueConstraints = {@UniqueConstraint(columnNames = {"userName"}), @UniqueConstraint(columnNames = {"email"}) diff --git a/src/main/java/com/manir/springbootecommercerestapi/repository/CartItemRepository.java b/src/main/java/com/manir/springbootecommercerestapi/repository/CartItemRepository.java index 0f1c119..5ff677a 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/repository/CartItemRepository.java +++ b/src/main/java/com/manir/springbootecommercerestapi/repository/CartItemRepository.java @@ -23,4 +23,8 @@ public interface CartItemRepository extends JpaRepository { @Modifying void deleteByCustomerAndProduct(Long customerId, Long productId); + @Query("DELETE FROM CartItem c WHERE c.customer.id = ?1") + @Modifying + void deleteByCustomerId(Long customerId); + } diff --git a/src/main/java/com/manir/springbootecommercerestapi/repository/OrderProductsRepository.java b/src/main/java/com/manir/springbootecommercerestapi/repository/OrderProductsRepository.java new file mode 100644 index 0000000..4a4037b --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/repository/OrderProductsRepository.java @@ -0,0 +1,8 @@ +package com.manir.springbootecommercerestapi.repository; + +import com.manir.springbootecommercerestapi.model.OrderProducts; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface OrderProductsRepository extends JpaRepository { + +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/repository/OrderRepository.java b/src/main/java/com/manir/springbootecommercerestapi/repository/OrderRepository.java new file mode 100644 index 0000000..d0e3573 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/repository/OrderRepository.java @@ -0,0 +1,12 @@ +package com.manir.springbootecommercerestapi.repository; + +import com.manir.springbootecommercerestapi.model.Order; +import com.manir.springbootecommercerestapi.model.User; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface OrderRepository extends JpaRepository { + + List findByCustomer(User customer); +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/Impl/OrderProductsServiceImpl.java b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/OrderProductsServiceImpl.java new file mode 100644 index 0000000..a7fd767 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/OrderProductsServiceImpl.java @@ -0,0 +1,22 @@ +package com.manir.springbootecommercerestapi.service.Impl; + +import com.manir.springbootecommercerestapi.model.OrderProducts; +import com.manir.springbootecommercerestapi.repository.OrderProductsRepository; +import com.manir.springbootecommercerestapi.service.OrderProductsService; +import lombok.AllArgsConstructor; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +@Service +@AllArgsConstructor +public class OrderProductsServiceImpl implements OrderProductsService { + + @Resource(name = "orderProductsRepository") + private final OrderProductsRepository orderProductsRepository; + + @Override + public void addOrderProducts(OrderProducts orderProducts) { + orderProductsRepository.save(orderProducts); + } +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/Impl/OrderServiceImpl.java b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/OrderServiceImpl.java new file mode 100644 index 0000000..45d1970 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/OrderServiceImpl.java @@ -0,0 +1,94 @@ +package com.manir.springbootecommercerestapi.service.Impl; + +import com.manir.springbootecommercerestapi.dto.CartItemDto; +import com.manir.springbootecommercerestapi.dto.OrderDto; +import com.manir.springbootecommercerestapi.exception.EcommerceApiException; +import com.manir.springbootecommercerestapi.model.Order; +import com.manir.springbootecommercerestapi.model.OrderProducts; +import com.manir.springbootecommercerestapi.model.User; +import com.manir.springbootecommercerestapi.repository.CartItemRepository; +import com.manir.springbootecommercerestapi.repository.OrderRepository; +import com.manir.springbootecommercerestapi.response.CartItemResponse; +import com.manir.springbootecommercerestapi.service.OrderProductsService; +import com.manir.springbootecommercerestapi.service.OrderService; +import com.manir.springbootecommercerestapi.service.ShoppingCartService; +import lombok.AllArgsConstructor; +import org.modelmapper.ModelMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; + +import javax.transaction.Transactional; +import java.util.List; +import java.util.stream.Collectors; + +@Service +@AllArgsConstructor +public class OrderServiceImpl implements OrderService { + + @Autowired + private final OrderRepository orderRepository; + @Autowired + private final OrderProductsService orderProductsService; + @Autowired + private final CartItemRepository cartItemRepository; + @Autowired + private final ShoppingCartService shoppingCartService; + @Autowired + private final ModelMapper modelMapper; + + @Override + @Transactional + public void placeOrder(User customer) { + CartItemResponse cartItemDto = shoppingCartService.findByCustomer(customer); + OrderDto orderDto = new OrderDto(); + orderDto.setTotalPrice(cartItemDto.getTotalCost()); + orderDto.setEmail(customer.getEmail()); + orderDto.setName(customer.getName()); + OrderDto savedOrder = saveOrder(orderDto, customer); + List cartItemDtoList = cartItemDto.getContent(); + for(CartItemDto cartItem : cartItemDtoList){ + OrderProducts orderProducts = new OrderProducts(); + orderProducts.setCustomer(customer); + orderProducts.setProduct(cartItem.getProduct()); + orderProducts.setOrder(mapToEntity(savedOrder)); + orderProducts.setProductPrice(cartItem.getProduct().getPrice()); + orderProducts.setProductQuantity(cartItem.getQuantity()); + orderProducts.setTotalPrice(cartItemDto.getTotalCost()); + orderProductsService.addOrderProducts(orderProducts); + } + cartItemRepository.deleteByCustomerId(customer.getId()); + } + + @Override + public OrderDto saveOrder(OrderDto orderDto, User customer) { + //convert to entity + Order order = mapToEntity(orderDto); + //save order to db + Order placedOrder = orderRepository.save(order); + return mapToDto(placedOrder); + } + + @Override + public List listOrdersByCustomer(User customer) { + List orders = orderRepository.findByCustomer(customer); + if (orders.size() == 0){ + throw new EcommerceApiException("User has no order", HttpStatus.BAD_REQUEST); + } + List orderDtoList = orders.stream() + .map(order -> mapToDto(order)) + .collect(Collectors.toList()); + return orderDtoList; + } + + //map to Entity + private Order mapToEntity(OrderDto orderDto){ + Order order = modelMapper.map(orderDto, Order.class); + return order; + } + //map to Dto + private OrderDto mapToDto(Order order){ + OrderDto orderDto = modelMapper.map(order, OrderDto.class); + return orderDto; + } +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/OrderProductsService.java b/src/main/java/com/manir/springbootecommercerestapi/service/OrderProductsService.java new file mode 100644 index 0000000..c198a83 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/service/OrderProductsService.java @@ -0,0 +1,7 @@ +package com.manir.springbootecommercerestapi.service; + +import com.manir.springbootecommercerestapi.model.OrderProducts; + +public interface OrderProductsService { + void addOrderProducts(OrderProducts orderProducts); +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/OrderService.java b/src/main/java/com/manir/springbootecommercerestapi/service/OrderService.java new file mode 100644 index 0000000..e2d9da9 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/service/OrderService.java @@ -0,0 +1,13 @@ +package com.manir.springbootecommercerestapi.service; + +import com.manir.springbootecommercerestapi.dto.OrderDto; +import com.manir.springbootecommercerestapi.model.User; + +import java.util.List; + +public interface OrderService { + + void placeOrder(User customer); + OrderDto saveOrder(OrderDto orderDto, User customer); + List listOrdersByCustomer(User customer); +} From b02e91b2ddc40c2efb68a8d49498e90fd5768c32 Mon Sep 17 00:00:00 2001 From: manirDev Date: Wed, 16 Nov 2022 11:05:37 +0300 Subject: [PATCH 05/13] Find Customer order and ordered items are done. --- .../config/SecurityConfig.java | 6 ---- .../controller/OrderController.java | 20 +++++++++++- .../dto/OrderDto.java | 2 ++ .../repository/OrderProductsRepository.java | 5 ++- .../Impl/OrderProductsServiceImpl.java | 31 +++++++++++++++++++ .../service/Impl/OrderServiceImpl.java | 3 +- .../service/OrderProductsService.java | 5 +++ 7 files changed, 63 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/manir/springbootecommercerestapi/config/SecurityConfig.java b/src/main/java/com/manir/springbootecommercerestapi/config/SecurityConfig.java index baf3107..8314f0e 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/config/SecurityConfig.java +++ b/src/main/java/com/manir/springbootecommercerestapi/config/SecurityConfig.java @@ -11,14 +11,8 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.provisioning.InMemoryUserDetailsManager; - -import javax.annotation.Resource; @Configuration @EnableWebSecurity diff --git a/src/main/java/com/manir/springbootecommercerestapi/controller/OrderController.java b/src/main/java/com/manir/springbootecommercerestapi/controller/OrderController.java index 0805dee..172436f 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/controller/OrderController.java +++ b/src/main/java/com/manir/springbootecommercerestapi/controller/OrderController.java @@ -1,10 +1,11 @@ package com.manir.springbootecommercerestapi.controller; import com.manir.springbootecommercerestapi.dto.OrderDto; +import com.manir.springbootecommercerestapi.dto.OrderProductsDto; import com.manir.springbootecommercerestapi.exception.EcommerceApiException; -import com.manir.springbootecommercerestapi.model.Order; import com.manir.springbootecommercerestapi.model.User; import com.manir.springbootecommercerestapi.repository.UserRepository; +import com.manir.springbootecommercerestapi.service.OrderProductsService; import com.manir.springbootecommercerestapi.service.OrderService; import com.manir.springbootecommercerestapi.utils.isAuthenticatedAsAdminOrUser; import org.springframework.beans.factory.annotation.Autowired; @@ -30,6 +31,8 @@ public class OrderController { private UserRepository userRepository; @Autowired private OrderService orderService; + @Autowired + private OrderProductsService orderProductsService; //place order complete order api @isAuthenticatedAsAdminOrUser @@ -60,4 +63,19 @@ public List listOrdersByCustomer(@AuthenticationPrincipal Authenticati throw new EcommerceApiException("User not authenticated", HttpStatus.BAD_REQUEST); } } + + //find ordered items by Customer + @isAuthenticatedAsAdminOrUser + @GetMapping("/findOrderedItemsByCustomer") + public List findOrderedItemsByCustomer(@AuthenticationPrincipal Authentication authentication){ + authentication = SecurityContextHolder.getContext().getAuthentication(); + if (!(authentication instanceof AnonymousAuthenticationToken)){ + String currentUserEmail = authentication.getName(); + User customer = userRepository.findByEmail(currentUserEmail).orElseThrow(() -> new UsernameNotFoundException("Customer Not found")); + List customerOrderedItems = orderProductsService.findOrderItemsByCustomer(customer); + return customerOrderedItems; + }else{ + throw new EcommerceApiException("User not authenticated", HttpStatus.BAD_REQUEST); + } + } } diff --git a/src/main/java/com/manir/springbootecommercerestapi/dto/OrderDto.java b/src/main/java/com/manir/springbootecommercerestapi/dto/OrderDto.java index a5c1332..e4c5156 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/dto/OrderDto.java +++ b/src/main/java/com/manir/springbootecommercerestapi/dto/OrderDto.java @@ -1,5 +1,6 @@ package com.manir.springbootecommercerestapi.dto; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.manir.springbootecommercerestapi.model.User; import lombok.Data; @@ -14,5 +15,6 @@ public class OrderDto { private String note; private String status; + @JsonIgnore private User customer; } diff --git a/src/main/java/com/manir/springbootecommercerestapi/repository/OrderProductsRepository.java b/src/main/java/com/manir/springbootecommercerestapi/repository/OrderProductsRepository.java index 4a4037b..03d331d 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/repository/OrderProductsRepository.java +++ b/src/main/java/com/manir/springbootecommercerestapi/repository/OrderProductsRepository.java @@ -1,8 +1,11 @@ package com.manir.springbootecommercerestapi.repository; import com.manir.springbootecommercerestapi.model.OrderProducts; +import com.manir.springbootecommercerestapi.model.User; import org.springframework.data.jpa.repository.JpaRepository; -public interface OrderProductsRepository extends JpaRepository { +import java.util.List; +public interface OrderProductsRepository extends JpaRepository { + List findByCustomer(User customer); } diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/Impl/OrderProductsServiceImpl.java b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/OrderProductsServiceImpl.java index a7fd767..0a3e532 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/service/Impl/OrderProductsServiceImpl.java +++ b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/OrderProductsServiceImpl.java @@ -1,12 +1,20 @@ package com.manir.springbootecommercerestapi.service.Impl; +import com.manir.springbootecommercerestapi.dto.OrderProductsDto; +import com.manir.springbootecommercerestapi.exception.EcommerceApiException; import com.manir.springbootecommercerestapi.model.OrderProducts; +import com.manir.springbootecommercerestapi.model.User; import com.manir.springbootecommercerestapi.repository.OrderProductsRepository; import com.manir.springbootecommercerestapi.service.OrderProductsService; import lombok.AllArgsConstructor; +import org.modelmapper.ModelMapper; +import org.modelmapper.convention.MatchingStrategies; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import javax.annotation.Resource; +import java.util.List; +import java.util.stream.Collectors; @Service @AllArgsConstructor @@ -14,9 +22,32 @@ public class OrderProductsServiceImpl implements OrderProductsService { @Resource(name = "orderProductsRepository") private final OrderProductsRepository orderProductsRepository; + @Resource(name = "modelMapper") + private final ModelMapper modelMapper; @Override public void addOrderProducts(OrderProducts orderProducts) { orderProductsRepository.save(orderProducts); } + + @Override + public List findOrderItemsByCustomer(User customer) { + + List orderProducts = orderProductsRepository.findByCustomer(customer); + if (orderProducts.size() == 0){ + throw new EcommerceApiException("User has no ordered products", HttpStatus.BAD_REQUEST); + } + List orderProductsDtoList = orderProducts.stream() + .map(orderProduct -> mapToDto(orderProduct)) + .collect(Collectors.toList()); + return orderProductsDtoList; + } + + //map to dto + private OrderProductsDto mapToDto(OrderProducts orderProducts){ + modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT); + OrderProductsDto orderProductsDto = modelMapper.map(orderProducts, OrderProductsDto.class); + + return orderProductsDto; + } } diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/Impl/OrderServiceImpl.java b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/OrderServiceImpl.java index 45d1970..8b58f61 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/service/Impl/OrderServiceImpl.java +++ b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/OrderServiceImpl.java @@ -45,6 +45,7 @@ public void placeOrder(User customer) { orderDto.setTotalPrice(cartItemDto.getTotalCost()); orderDto.setEmail(customer.getEmail()); orderDto.setName(customer.getName()); + orderDto.setCustomer(customer); OrderDto savedOrder = saveOrder(orderDto, customer); List cartItemDtoList = cartItemDto.getContent(); for(CartItemDto cartItem : cartItemDtoList){ @@ -54,7 +55,7 @@ public void placeOrder(User customer) { orderProducts.setOrder(mapToEntity(savedOrder)); orderProducts.setProductPrice(cartItem.getProduct().getPrice()); orderProducts.setProductQuantity(cartItem.getQuantity()); - orderProducts.setTotalPrice(cartItemDto.getTotalCost()); + orderProducts.setTotalPrice(cartItem.getProduct().getPrice()*cartItem.getQuantity()); orderProductsService.addOrderProducts(orderProducts); } cartItemRepository.deleteByCustomerId(customer.getId()); diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/OrderProductsService.java b/src/main/java/com/manir/springbootecommercerestapi/service/OrderProductsService.java index c198a83..2fec5dc 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/service/OrderProductsService.java +++ b/src/main/java/com/manir/springbootecommercerestapi/service/OrderProductsService.java @@ -1,7 +1,12 @@ package com.manir.springbootecommercerestapi.service; +import com.manir.springbootecommercerestapi.dto.OrderProductsDto; import com.manir.springbootecommercerestapi.model.OrderProducts; +import com.manir.springbootecommercerestapi.model.User; + +import java.util.List; public interface OrderProductsService { void addOrderProducts(OrderProducts orderProducts); + List findOrderItemsByCustomer(User customer); } From b3e8afdda41c3c768c916142dc1a2cff82c5ce56 Mon Sep 17 00:00:00 2001 From: manirDev Date: Wed, 16 Nov 2022 12:48:26 +0300 Subject: [PATCH 06/13] JWT token provider is implemented. --- pom.xml | 7 ++ .../config/SecurityConfig.java | 30 ++++++++- .../controller/AuthController.java | 12 +++- .../response/JWTAuthResponse.java | 15 +++++ .../security/JwtAuthenticationEntryPoint.java | 21 ++++++ .../security/JwtAuthenticationFilter.java | 57 ++++++++++++++++ .../security/JwtTokenProvider.java | 66 +++++++++++++++++++ src/main/resources/application.properties | 3 + 8 files changed, 207 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/manir/springbootecommercerestapi/response/JWTAuthResponse.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/security/JwtAuthenticationEntryPoint.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/security/JwtAuthenticationFilter.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/security/JwtTokenProvider.java diff --git a/pom.xml b/pom.xml index 1cd8705..083ab16 100644 --- a/pom.xml +++ b/pom.xml @@ -52,6 +52,13 @@ org.springframework.boot spring-boot-starter-security + + + io.jsonwebtoken + jjwt + 0.9.1 + + org.springframework.boot spring-boot-starter-test diff --git a/src/main/java/com/manir/springbootecommercerestapi/config/SecurityConfig.java b/src/main/java/com/manir/springbootecommercerestapi/config/SecurityConfig.java index 8314f0e..cb723b4 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/config/SecurityConfig.java +++ b/src/main/java/com/manir/springbootecommercerestapi/config/SecurityConfig.java @@ -1,6 +1,8 @@ package com.manir.springbootecommercerestapi.config; import com.manir.springbootecommercerestapi.security.CustomUserDetailsService; +import com.manir.springbootecommercerestapi.security.JwtAuthenticationEntryPoint; +import com.manir.springbootecommercerestapi.security.JwtAuthenticationFilter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -11,8 +13,10 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @Configuration @EnableWebSecurity @@ -25,21 +29,43 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private CustomUserDetailsService customUserDetailsService; + @Autowired + private JwtAuthenticationEntryPoint authenticationEntryPoint; @Override protected void configure(HttpSecurity http) throws Exception { http .csrf().disable() + /*-------------------------JWT Starts------------------------------*/ + .exceptionHandling() + .authenticationEntryPoint(authenticationEntryPoint) + .and() + .sessionManagement() + .sessionCreationPolicy(SessionCreationPolicy.STATELESS) + /*-------------------------JWT ends------------------------------*/ + .and() .authorizeRequests() //to permit all get request and secure post put and delete methods .antMatchers(HttpMethod.GET, "/api/**").permitAll() //authorize singIn and signUp .antMatchers("/api/v1/auth/**").permitAll() .anyRequest() - .authenticated() - .and() + .authenticated(); + + /** + Basic auth used before JWT implementation + .and() .httpBasic(); + **/ + http + .addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); + + } + //Jwt auth filter method + @Bean + public JwtAuthenticationFilter jwtAuthenticationFilter(){ + return new JwtAuthenticationFilter(); } //In memory Auth diff --git a/src/main/java/com/manir/springbootecommercerestapi/controller/AuthController.java b/src/main/java/com/manir/springbootecommercerestapi/controller/AuthController.java index 2bf09f2..672f51a 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/controller/AuthController.java +++ b/src/main/java/com/manir/springbootecommercerestapi/controller/AuthController.java @@ -3,6 +3,8 @@ import com.manir.springbootecommercerestapi.dto.LoginDto; import com.manir.springbootecommercerestapi.dto.SignUpDto; import com.manir.springbootecommercerestapi.repository.UserRepository; +import com.manir.springbootecommercerestapi.response.JWTAuthResponse; +import com.manir.springbootecommercerestapi.security.JwtTokenProvider; import com.manir.springbootecommercerestapi.service.UserRegisterService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -28,10 +30,12 @@ public class AuthController { private UserRepository userRepository; @Autowired private UserRegisterService userRegisterService; + @Autowired + private JwtTokenProvider tokenProvider; //login api @PostMapping("/login") - public ResponseEntity authenticateUser(@RequestBody LoginDto loginDto){ + public ResponseEntity authenticateUser(@RequestBody LoginDto loginDto){ Authentication authentication = authenticationManager.authenticate( new UsernamePasswordAuthenticationToken( @@ -40,7 +44,11 @@ public ResponseEntity authenticateUser(@RequestBody LoginDto loginDto){ ) ); SecurityContextHolder.getContext().setAuthentication(authentication); - return new ResponseEntity<>("User sign-In successfully", HttpStatus.OK); + + //get token from token provider + String token = tokenProvider.generateToken(authentication); + + return new ResponseEntity<>(new JWTAuthResponse(token), HttpStatus.OK); } //register api diff --git a/src/main/java/com/manir/springbootecommercerestapi/response/JWTAuthResponse.java b/src/main/java/com/manir/springbootecommercerestapi/response/JWTAuthResponse.java new file mode 100644 index 0000000..52c7ae9 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/response/JWTAuthResponse.java @@ -0,0 +1,15 @@ +package com.manir.springbootecommercerestapi.response; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class JWTAuthResponse { + private String accessToken; + private String tokenType = "Bearer"; + + public JWTAuthResponse(String accessToken) { + this.accessToken = accessToken; + } +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/security/JwtAuthenticationEntryPoint.java b/src/main/java/com/manir/springbootecommercerestapi/security/JwtAuthenticationEntryPoint.java new file mode 100644 index 0000000..5b485e4 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/security/JwtAuthenticationEntryPoint.java @@ -0,0 +1,21 @@ +package com.manir.springbootecommercerestapi.security; + +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.stereotype.Component; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +@Component +public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint { + @Override + public void commence(HttpServletRequest request, + HttpServletResponse response, + AuthenticationException authException) throws IOException, ServletException { + + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage()); + } +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/security/JwtAuthenticationFilter.java b/src/main/java/com/manir/springbootecommercerestapi/security/JwtAuthenticationFilter.java new file mode 100644 index 0000000..620ef9e --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/security/JwtAuthenticationFilter.java @@ -0,0 +1,57 @@ +package com.manir.springbootecommercerestapi.security; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; +import org.springframework.util.StringUtils; +import org.springframework.web.filter.OncePerRequestFilter; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class JwtAuthenticationFilter extends OncePerRequestFilter { + + @Autowired + private JwtTokenProvider tokenProvider; + @Autowired + private CustomUserDetailsService userDetailsService; + + @Override + protected void doFilterInternal(HttpServletRequest request, + HttpServletResponse response, + FilterChain filterChain) throws ServletException, IOException { + + //get jwt token from http request + String token = getJWTFromToken(request); + //validate token + if (StringUtils.hasText(token) && tokenProvider.validateToken(token)){ + //retrieve user form token + String userName = tokenProvider.getUserNameFromToken(token); + //load user associated with the token + UserDetails userDetails = userDetailsService.loadUserByUsername(userName); + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken( + userDetails, null, userDetails.getAuthorities() + ); + //set spring security + authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + SecurityContextHolder.getContext().setAuthentication(authenticationToken); + } + filterChain.doFilter(request, response); + } + + //get jwt from token + //Bearer + private String getJWTFromToken(HttpServletRequest request){ + + String bearerToken = request.getHeader("Authorization"); + if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")){ + return bearerToken.substring(7, bearerToken.length()); + } + return null; + } +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/security/JwtTokenProvider.java b/src/main/java/com/manir/springbootecommercerestapi/security/JwtTokenProvider.java new file mode 100644 index 0000000..5e18a26 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/security/JwtTokenProvider.java @@ -0,0 +1,66 @@ +package com.manir.springbootecommercerestapi.security; + +import com.manir.springbootecommercerestapi.exception.EcommerceApiException; +import io.jsonwebtoken.*; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatus; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Component; + +import java.util.Date; + +@Component +public class JwtTokenProvider { + + @Value("${app.jwt-secret}") + private String jwtSecret; + @Value("${app.jwt-expiration-milliseconds}") + private int jwtExpirationTime; + + //generate token method + + public String generateToken(Authentication authentication){ + String userName = authentication.getName(); + Date currentDate = new Date(); + Date expireDate = new Date(currentDate.getTime() + jwtExpirationTime); + + String token = Jwts.builder() + .setSubject(userName) + .setIssuedAt(new Date()) + .setExpiration(expireDate) + .signWith(SignatureAlgorithm.HS512, jwtSecret) + .compact(); + + return token; + } + + //get username from the token, retrieve username from generated token + public String getUserNameFromToken(String token){ + Claims claims = Jwts.parser() + .setSigningKey(jwtSecret) + .parseClaimsJws(token) + .getBody(); + + return claims.getSubject(); + } + + //validate JWT token + public boolean validateToken(String token){ + try { + Jwts.parser() + .setSigningKey(jwtSecret) + .parseClaimsJws(token); + return true; + }catch (SignatureException e){ + throw new EcommerceApiException("Invalid JWT signature", HttpStatus.BAD_REQUEST); + }catch (MalformedJwtException e){ + throw new EcommerceApiException("Invalid JWT token", HttpStatus.BAD_REQUEST); + }catch (ExpiredJwtException e){ + throw new EcommerceApiException("Expired JWT token", HttpStatus.BAD_REQUEST); + }catch (UnsupportedJwtException e){ + throw new EcommerceApiException("Unsupported JWT token", HttpStatus.BAD_REQUEST); + }catch (IllegalArgumentException e){ + throw new EcommerceApiException("JWT claims string is empty", HttpStatus.BAD_REQUEST); + } + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 8c3a84b..bf443c7 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -13,3 +13,6 @@ logging.level.org.springframework.security=DEBUG #spring.security.customer.name= customer #spring.security.customer.roles= ADMIN +#JWT properties +app.jwt-secret = JWTSecretKey +app.jwt-expiration-milliseconds = 604800000 From fe3785411599e58c630ffeb55187b7bdf173316b Mon Sep 17 00:00:00 2001 From: manirDev Date: Wed, 16 Nov 2022 15:12:17 +0300 Subject: [PATCH 07/13] Some code refactors are done on getting authenticated user. --- .../controller/OrderController.java | 51 ++++++--------- .../controller/ShoppingCartController.java | 63 +++++-------------- .../service/CommonService.java | 5 ++ .../service/Impl/CommonServiceImpl.java | 30 +++++++++ .../service/Impl/OrderServiceImpl.java | 20 +++--- .../service/OrderService.java | 2 +- 6 files changed, 83 insertions(+), 88 deletions(-) diff --git a/src/main/java/com/manir/springbootecommercerestapi/controller/OrderController.java b/src/main/java/com/manir/springbootecommercerestapi/controller/OrderController.java index 172436f..302422b 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/controller/OrderController.java +++ b/src/main/java/com/manir/springbootecommercerestapi/controller/OrderController.java @@ -2,20 +2,17 @@ import com.manir.springbootecommercerestapi.dto.OrderDto; import com.manir.springbootecommercerestapi.dto.OrderProductsDto; -import com.manir.springbootecommercerestapi.exception.EcommerceApiException; import com.manir.springbootecommercerestapi.model.User; import com.manir.springbootecommercerestapi.repository.UserRepository; +import com.manir.springbootecommercerestapi.service.CommonService; import com.manir.springbootecommercerestapi.service.OrderProductsService; import com.manir.springbootecommercerestapi.service.OrderService; import com.manir.springbootecommercerestapi.utils.isAuthenticatedAsAdminOrUser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.security.authentication.AnonymousAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.annotation.AuthenticationPrincipal; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -27,55 +24,43 @@ @RequestMapping(value = "api/v1/order") public class OrderController { - @Autowired - private UserRepository userRepository; @Autowired private OrderService orderService; @Autowired private OrderProductsService orderProductsService; + @Autowired + private CommonService commonService; //place order complete order api @isAuthenticatedAsAdminOrUser @PostMapping("/placeOrder") public ResponseEntity placeOrder(@AuthenticationPrincipal Authentication authentication){ - authentication = SecurityContextHolder.getContext().getAuthentication(); - if (!(authentication instanceof AnonymousAuthenticationToken)){ - String currentUserEmail = authentication.getName(); - User customer = userRepository.findByEmail(currentUserEmail).orElseThrow(() -> new UsernameNotFoundException("Customer Not found")); - orderService.placeOrder(customer); - return new ResponseEntity<>("Order placed successfully", HttpStatus.CREATED); - }else{ - throw new EcommerceApiException("User not authenticated", HttpStatus.BAD_REQUEST); - } + User customer = commonService.getCurrentAuthenticatedUser(authentication); + orderService.placeOrder(customer); + return new ResponseEntity<>("Order placed successfully", HttpStatus.CREATED); } //find order by customer api @isAuthenticatedAsAdminOrUser @GetMapping("/findByCustomer") public List listOrdersByCustomer(@AuthenticationPrincipal Authentication authentication){ - authentication = SecurityContextHolder.getContext().getAuthentication(); - if (!(authentication instanceof AnonymousAuthenticationToken)){ - String currentUserEmail = authentication.getName(); - User customer = userRepository.findByEmail(currentUserEmail).orElseThrow(() -> new UsernameNotFoundException("Customer Not found")); - List customerOrders = orderService.listOrdersByCustomer(customer); - return customerOrders; - }else{ - throw new EcommerceApiException("User not authenticated", HttpStatus.BAD_REQUEST); - } + + User customer = commonService.getCurrentAuthenticatedUser(authentication); + + List customerOrders = orderService.listOrdersByCustomer(customer); + return customerOrders; } + + //find ordered items by Customer @isAuthenticatedAsAdminOrUser @GetMapping("/findOrderedItemsByCustomer") public List findOrderedItemsByCustomer(@AuthenticationPrincipal Authentication authentication){ - authentication = SecurityContextHolder.getContext().getAuthentication(); - if (!(authentication instanceof AnonymousAuthenticationToken)){ - String currentUserEmail = authentication.getName(); - User customer = userRepository.findByEmail(currentUserEmail).orElseThrow(() -> new UsernameNotFoundException("Customer Not found")); - List customerOrderedItems = orderProductsService.findOrderItemsByCustomer(customer); - return customerOrderedItems; - }else{ - throw new EcommerceApiException("User not authenticated", HttpStatus.BAD_REQUEST); - } + User customer = commonService.getCurrentAuthenticatedUser(authentication); + List customerOrderedItems = orderProductsService.findOrderItemsByCustomer(customer); + return customerOrderedItems; } + + } diff --git a/src/main/java/com/manir/springbootecommercerestapi/controller/ShoppingCartController.java b/src/main/java/com/manir/springbootecommercerestapi/controller/ShoppingCartController.java index 7cac9e1..c3bdfc5 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/controller/ShoppingCartController.java +++ b/src/main/java/com/manir/springbootecommercerestapi/controller/ShoppingCartController.java @@ -1,20 +1,15 @@ package com.manir.springbootecommercerestapi.controller; -import com.manir.springbootecommercerestapi.exception.EcommerceApiException; import com.manir.springbootecommercerestapi.model.User; -import com.manir.springbootecommercerestapi.repository.UserRepository; import com.manir.springbootecommercerestapi.response.CartItemResponse; -import com.manir.springbootecommercerestapi.service.OrderService; +import com.manir.springbootecommercerestapi.service.CommonService; import com.manir.springbootecommercerestapi.service.ShoppingCartService; import com.manir.springbootecommercerestapi.utils.isAuthenticatedAsAdminOrUser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.security.authentication.AnonymousAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.annotation.AuthenticationPrincipal; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; @@ -26,26 +21,16 @@ public class ShoppingCartController { @Resource private ShoppingCartService shoppingCartService; @Autowired - private UserRepository userRepository; - @Autowired - private OrderService orderService; + private CommonService commonService; //find by customer api @isAuthenticatedAsAdminOrUser @GetMapping("/findByCustomer") public CartItemResponse findByCustomerId(@AuthenticationPrincipal Authentication authentication){ - authentication = SecurityContextHolder.getContext().getAuthentication(); - if (!(authentication instanceof AnonymousAuthenticationToken)) { - String currentUserEmail = authentication.getName(); - //System.out.println("Name:" + currentUserEmail); - User customer = userRepository.findByEmail(currentUserEmail).orElseThrow(()-> new UsernameNotFoundException("Customer not found")); - CartItemResponse responseCartItems = shoppingCartService.findByCustomer(customer); - return responseCartItems; - - }else{ - throw new EcommerceApiException("User not authenticated", HttpStatus.BAD_REQUEST); - } + User customer = commonService.getCurrentAuthenticatedUser(authentication); + CartItemResponse responseCartItems = shoppingCartService.findByCustomer(customer); + return responseCartItems; } //add item to the cart api @@ -54,15 +39,10 @@ public CartItemResponse findByCustomerId(@AuthenticationPrincipal Authentication public ResponseEntity addCartItem(@AuthenticationPrincipal Authentication authentication, @PathVariable Long productId, @PathVariable Integer quantity){ - authentication = SecurityContextHolder.getContext().getAuthentication(); - if (!(authentication instanceof AnonymousAuthenticationToken)){ - String currentUserEmail = authentication.getName(); - User customer = userRepository.findByEmail(currentUserEmail).orElseThrow(() -> new UsernameNotFoundException("Customer not found")); - CartItemResponse responseCartItem = shoppingCartService.addCartItem(customer, productId, quantity); - return new ResponseEntity<>(responseCartItem, HttpStatus.CREATED); - }else { - throw new EcommerceApiException("User not authenticated", HttpStatus.BAD_REQUEST); - } + + User customer = commonService.getCurrentAuthenticatedUser(authentication); + CartItemResponse responseCartItem = shoppingCartService.addCartItem(customer, productId, quantity); + return new ResponseEntity<>(responseCartItem, HttpStatus.CREATED); } //update item quantity api @@ -71,15 +51,9 @@ public ResponseEntity addCartItem(@AuthenticationPrincipal Aut public ResponseEntity updateItemQuantity(@AuthenticationPrincipal Authentication authentication, @PathVariable Long productId, @PathVariable Integer quantity){ - authentication = SecurityContextHolder.getContext().getAuthentication(); - if (!(authentication instanceof AnonymousAuthenticationToken)){ - String currentUserEmail = authentication.getName(); - User customer = userRepository.findByEmail(currentUserEmail).orElseThrow(() -> new UsernameNotFoundException("Customer Not found")); - CartItemResponse responseCartItem = shoppingCartService.updateItemQuantity(customer, productId, quantity); - return new ResponseEntity<>(responseCartItem, HttpStatus.OK); - }else{ - throw new EcommerceApiException("User not authenticated", HttpStatus.BAD_REQUEST); - } + User customer = commonService.getCurrentAuthenticatedUser(authentication); + CartItemResponse responseCartItem = shoppingCartService.updateItemQuantity(customer, productId, quantity); + return new ResponseEntity<>(responseCartItem, HttpStatus.OK); } //delete item product api @@ -87,15 +61,10 @@ public ResponseEntity updateItemQuantity(@AuthenticationPrinci @DeleteMapping("/deleteItemProduct/{productId}") public ResponseEntity deleteItemProduct(@AuthenticationPrincipal Authentication authentication, @PathVariable Long productId){ - authentication = SecurityContextHolder.getContext().getAuthentication(); - if (!(authentication instanceof AnonymousAuthenticationToken)){ - String currentUserEmail = authentication.getName(); - User customer = userRepository.findByEmail(currentUserEmail).orElseThrow(() -> new UsernameNotFoundException("Customer Not found")); - shoppingCartService.deleteItemProduct(customer, productId); - return ResponseEntity.ok("Product with id = " + productId +" is deleted successfully from your shopping cart"); - }else{ - throw new EcommerceApiException("User not authenticated", HttpStatus.BAD_REQUEST); - } + + User customer = commonService.getCurrentAuthenticatedUser(authentication); + shoppingCartService.deleteItemProduct(customer, productId); + return ResponseEntity.ok("Product with id = " + productId +" is deleted successfully from your shopping cart"); } diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/CommonService.java b/src/main/java/com/manir/springbootecommercerestapi/service/CommonService.java index 1dfce02..e2156a2 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/service/CommonService.java +++ b/src/main/java/com/manir/springbootecommercerestapi/service/CommonService.java @@ -1,9 +1,11 @@ package com.manir.springbootecommercerestapi.service; import com.manir.springbootecommercerestapi.dto.CartItemDto; +import com.manir.springbootecommercerestapi.model.User; import com.manir.springbootecommercerestapi.response.CartItemResponse; import com.manir.springbootecommercerestapi.response.CommonResponse; import org.springframework.data.domain.Page; +import org.springframework.security.core.Authentication; import java.util.List; @@ -14,4 +16,7 @@ public interface CommonService { //cart iem response handler CartItemResponse getResponse(CartItemDto cartItemDto); + + //get current authenticated user + User getCurrentAuthenticatedUser(Authentication authentication); } diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/Impl/CommonServiceImpl.java b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/CommonServiceImpl.java index de3fec7..e8cfb9c 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/service/Impl/CommonServiceImpl.java +++ b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/CommonServiceImpl.java @@ -1,24 +1,39 @@ package com.manir.springbootecommercerestapi.service.Impl; import com.manir.springbootecommercerestapi.dto.CartItemDto; +import com.manir.springbootecommercerestapi.exception.EcommerceApiException; +import com.manir.springbootecommercerestapi.model.User; +import com.manir.springbootecommercerestapi.repository.UserRepository; import com.manir.springbootecommercerestapi.response.CartItemResponse; import com.manir.springbootecommercerestapi.response.CommonResponse; import com.manir.springbootecommercerestapi.service.CommonService; +import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.domain.Page; +import org.springframework.http.HttpStatus; +import org.springframework.security.authentication.AnonymousAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; + +import javax.annotation.Resource; import java.util.ArrayList; import java.util.List; @Service @Slf4j +@AllArgsConstructor public class CommonServiceImpl implements CommonService{ private static Logger logger = LoggerFactory.getLogger(CategoryServiceImpl.class); + @Resource(name = "userRepository") + private final UserRepository userRepository; + @Override public CommonResponse getResponseContent(Page page, List dtoList) { @@ -45,4 +60,19 @@ public CartItemResponse getResponse(CartItemDto cartItemDto) { cartItemResponse.setTotalCost(totalPrice); return cartItemResponse; } + + @Override + public User getCurrentAuthenticatedUser(Authentication authentication) { + authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication == null || authentication instanceof AnonymousAuthenticationToken){ + throw new EcommerceApiException("User not authenticated", HttpStatus.BAD_REQUEST); + } + String currentUserEmail = authentication.getName(); + User currentUser = userRepository.findByEmail(currentUserEmail) + .orElseThrow( + () -> new UsernameNotFoundException("User Not found") + ); + + return currentUser; + } } diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/Impl/OrderServiceImpl.java b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/OrderServiceImpl.java index 8b58f61..40527be 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/service/Impl/OrderServiceImpl.java +++ b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/OrderServiceImpl.java @@ -41,12 +41,9 @@ public class OrderServiceImpl implements OrderService { @Transactional public void placeOrder(User customer) { CartItemResponse cartItemDto = shoppingCartService.findByCustomer(customer); - OrderDto orderDto = new OrderDto(); - orderDto.setTotalPrice(cartItemDto.getTotalCost()); - orderDto.setEmail(customer.getEmail()); - orderDto.setName(customer.getName()); - orderDto.setCustomer(customer); - OrderDto savedOrder = saveOrder(orderDto, customer); + OrderDto orderDto = setFields(cartItemDto, customer); + //save order to the db + OrderDto savedOrder = saveOrder(orderDto); List cartItemDtoList = cartItemDto.getContent(); for(CartItemDto cartItem : cartItemDtoList){ OrderProducts orderProducts = new OrderProducts(); @@ -62,7 +59,7 @@ public void placeOrder(User customer) { } @Override - public OrderDto saveOrder(OrderDto orderDto, User customer) { + public OrderDto saveOrder(OrderDto orderDto) { //convert to entity Order order = mapToEntity(orderDto); //save order to db @@ -70,6 +67,15 @@ public OrderDto saveOrder(OrderDto orderDto, User customer) { return mapToDto(placedOrder); } + private OrderDto setFields(CartItemResponse cartItemDto, User customer){ + OrderDto orderDto = new OrderDto(); + orderDto.setTotalPrice(cartItemDto.getTotalCost()); + orderDto.setEmail(customer.getEmail()); + orderDto.setName(customer.getName()); + orderDto.setCustomer(customer); + + return orderDto; + } @Override public List listOrdersByCustomer(User customer) { List orders = orderRepository.findByCustomer(customer); diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/OrderService.java b/src/main/java/com/manir/springbootecommercerestapi/service/OrderService.java index e2d9da9..2ff968d 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/service/OrderService.java +++ b/src/main/java/com/manir/springbootecommercerestapi/service/OrderService.java @@ -8,6 +8,6 @@ public interface OrderService { void placeOrder(User customer); - OrderDto saveOrder(OrderDto orderDto, User customer); + OrderDto saveOrder(OrderDto orderDto); List listOrdersByCustomer(User customer); } From 4ebd51faf7c6d9d51cb20e5906c0cd429c5aebf7 Mon Sep 17 00:00:00 2001 From: manirDev Date: Wed, 16 Nov 2022 17:08:38 +0300 Subject: [PATCH 08/13] Auditing and Comment code refactors. --- ...SpringBootECommerceRestApiApplication.java | 2 + .../audit/AuditAwareImpl.java | 15 ++++++++ .../controller/CommentController.java | 27 +++++++++++-- .../model/BaseEntity.java | 38 +++++++++++++++++++ .../model/CartItem.java | 2 +- .../model/Category.java | 2 +- .../model/Comment.java | 7 +++- .../model/ImageData.java | 2 +- .../model/Order.java | 2 +- .../model/OrderProducts.java | 2 +- .../model/Product.java | 2 +- .../model/Role.java | 2 +- .../model/User.java | 8 +++- .../repository/CommentRepository.java | 2 + .../service/CommentService.java | 4 +- .../service/Impl/CommentServiceImpl.java | 25 +++++++++++- .../service/Impl/OrderServiceImpl.java | 1 + 17 files changed, 128 insertions(+), 15 deletions(-) create mode 100644 src/main/java/com/manir/springbootecommercerestapi/audit/AuditAwareImpl.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/model/BaseEntity.java diff --git a/src/main/java/com/manir/springbootecommercerestapi/SpringBootECommerceRestApiApplication.java b/src/main/java/com/manir/springbootecommercerestapi/SpringBootECommerceRestApiApplication.java index 4c07638..6b03645 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/SpringBootECommerceRestApiApplication.java +++ b/src/main/java/com/manir/springbootecommercerestapi/SpringBootECommerceRestApiApplication.java @@ -4,8 +4,10 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; @SpringBootApplication +@EnableJpaAuditing(auditorAwareRef = "auditAwareImpl") public class SpringBootECommerceRestApiApplication { public static void main(String[] args) { diff --git a/src/main/java/com/manir/springbootecommercerestapi/audit/AuditAwareImpl.java b/src/main/java/com/manir/springbootecommercerestapi/audit/AuditAwareImpl.java new file mode 100644 index 0000000..2ba6d01 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/audit/AuditAwareImpl.java @@ -0,0 +1,15 @@ +package com.manir.springbootecommercerestapi.audit; + +import org.springframework.data.domain.AuditorAware; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Component; + +import java.util.Optional; + +@Component("auditAwareImpl") +public class AuditAwareImpl implements AuditorAware { + @Override + public Optional getCurrentAuditor() { + return Optional.ofNullable(SecurityContextHolder.getContext().getAuthentication().getName()); + } +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/controller/CommentController.java b/src/main/java/com/manir/springbootecommercerestapi/controller/CommentController.java index b10c997..b119ef8 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/controller/CommentController.java +++ b/src/main/java/com/manir/springbootecommercerestapi/controller/CommentController.java @@ -1,9 +1,15 @@ package com.manir.springbootecommercerestapi.controller; import com.manir.springbootecommercerestapi.dto.CommentDto; +import com.manir.springbootecommercerestapi.model.User; import com.manir.springbootecommercerestapi.service.CommentService; +import com.manir.springbootecommercerestapi.service.CommonService; +import com.manir.springbootecommercerestapi.utils.isAuthenticatedAsAdminOrUser; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; @@ -13,17 +19,30 @@ @RequestMapping(value = "api/v1/products") public class CommentController { - @Resource + @Autowired private CommentService commentService; + @Autowired + private CommonService commonService; //create comment api + @isAuthenticatedAsAdminOrUser @PostMapping("/{productId}/createComment") - public ResponseEntity createComment(@PathVariable Long productId, + public ResponseEntity createComment(@AuthenticationPrincipal Authentication authentication, + @PathVariable Long productId, @RequestBody CommentDto commentDto){ - CommentDto responseComment = commentService.createComment(productId, commentDto); + User customer = commonService.getCurrentAuthenticatedUser(authentication); + CommentDto responseComment = commentService.createComment(customer, productId, commentDto); return new ResponseEntity<>(responseComment, HttpStatus.CREATED); } + //get comment by user + @isAuthenticatedAsAdminOrUser + @GetMapping("/comment/findByUser") + public List findByUser(@AuthenticationPrincipal Authentication authentication){ + User customer = commonService.getCurrentAuthenticatedUser(authentication); + return commentService.findCommentByCustomer(customer); + } + //get all comments api @GetMapping("/getAllComments") public List getAllComments(){ @@ -58,4 +77,6 @@ public ResponseEntity deleteComment(@PathVariable Long productId, @PathV commentService.deleteComment(productId, commentId); return ResponseEntity.ok("Comment with id: "+commentId+" is successfully:)"); } + + } diff --git a/src/main/java/com/manir/springbootecommercerestapi/model/BaseEntity.java b/src/main/java/com/manir/springbootecommercerestapi/model/BaseEntity.java new file mode 100644 index 0000000..e9e620f --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/model/BaseEntity.java @@ -0,0 +1,38 @@ +package com.manir.springbootecommercerestapi.model; + +import lombok.Data; +import org.springframework.data.annotation.CreatedBy; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedBy; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import javax.persistence.Column; +import javax.persistence.EntityListeners; +import javax.persistence.MappedSuperclass; +import java.time.LocalDateTime; + +@Data +@MappedSuperclass +/** + Auditing allows us : to see who created data and who updated + then we should enable jpa auditing... + **/ +@EntityListeners(AuditingEntityListener.class) +public abstract class BaseEntity { + + @CreatedDate + @Column(name = "created_at", updatable = false) + private LocalDateTime createdAt; + @CreatedBy + @Column(updatable = false) + private String createdBy; + + @LastModifiedDate + @Column(name = "updated_at", insertable = false) + private LocalDateTime updatedAt; + @LastModifiedBy + @Column(insertable = false) + private String updatedBy; + +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/model/CartItem.java b/src/main/java/com/manir/springbootecommercerestapi/model/CartItem.java index 70155da..5a1c4ea 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/model/CartItem.java +++ b/src/main/java/com/manir/springbootecommercerestapi/model/CartItem.java @@ -11,7 +11,7 @@ @Data @Entity @Table(name = "cart_item") -public class CartItem { +public class CartItem extends BaseEntity{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; diff --git a/src/main/java/com/manir/springbootecommercerestapi/model/Category.java b/src/main/java/com/manir/springbootecommercerestapi/model/Category.java index 6d4e01c..3862154 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/model/Category.java +++ b/src/main/java/com/manir/springbootecommercerestapi/model/Category.java @@ -14,7 +14,7 @@ @Entity @Table(name = "categories") @JsonIgnoreProperties(value = {"children"}) -public class Category { +public class Category extends BaseEntity{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/src/main/java/com/manir/springbootecommercerestapi/model/Comment.java b/src/main/java/com/manir/springbootecommercerestapi/model/Comment.java index 986eaa7..cd69ca0 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/model/Comment.java +++ b/src/main/java/com/manir/springbootecommercerestapi/model/Comment.java @@ -9,7 +9,7 @@ @Getter @Entity @Table(name = "product_comments") -public class Comment { +public class Comment extends BaseEntity{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @@ -23,4 +23,9 @@ public class Comment { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "product_id") private Product product; + + //relation with user + @ManyToOne() + @JoinColumn(name = "customer_id") + private User customer; } diff --git a/src/main/java/com/manir/springbootecommercerestapi/model/ImageData.java b/src/main/java/com/manir/springbootecommercerestapi/model/ImageData.java index 2a76534..45b3d3d 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/model/ImageData.java +++ b/src/main/java/com/manir/springbootecommercerestapi/model/ImageData.java @@ -10,7 +10,7 @@ @NoArgsConstructor @Entity @Table(name = "product_image_gallery") -public class ImageData { +public class ImageData extends BaseEntity{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; diff --git a/src/main/java/com/manir/springbootecommercerestapi/model/Order.java b/src/main/java/com/manir/springbootecommercerestapi/model/Order.java index 73e9f68..189875c 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/model/Order.java +++ b/src/main/java/com/manir/springbootecommercerestapi/model/Order.java @@ -11,7 +11,7 @@ @Setter @Entity @Table(name = "orders") -public class Order { +public class Order extends BaseEntity{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; diff --git a/src/main/java/com/manir/springbootecommercerestapi/model/OrderProducts.java b/src/main/java/com/manir/springbootecommercerestapi/model/OrderProducts.java index b9362c5..084ea70 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/model/OrderProducts.java +++ b/src/main/java/com/manir/springbootecommercerestapi/model/OrderProducts.java @@ -11,7 +11,7 @@ @Data @Entity @Table(name = "order_products") -public class OrderProducts { +public class OrderProducts extends BaseEntity{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; diff --git a/src/main/java/com/manir/springbootecommercerestapi/model/Product.java b/src/main/java/com/manir/springbootecommercerestapi/model/Product.java index 78c7f3b..1333432 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/model/Product.java +++ b/src/main/java/com/manir/springbootecommercerestapi/model/Product.java @@ -12,7 +12,7 @@ @Setter @Entity @Table(name = "products") -public class Product { +public class Product extends BaseEntity{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; diff --git a/src/main/java/com/manir/springbootecommercerestapi/model/Role.java b/src/main/java/com/manir/springbootecommercerestapi/model/Role.java index 3ad1a0e..4f792f4 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/model/Role.java +++ b/src/main/java/com/manir/springbootecommercerestapi/model/Role.java @@ -7,7 +7,7 @@ @Data @Entity @Table(name = "roles") -public class Role { +public class Role extends BaseEntity{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/src/main/java/com/manir/springbootecommercerestapi/model/User.java b/src/main/java/com/manir/springbootecommercerestapi/model/User.java index edc66b9..dcda1f3 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/model/User.java +++ b/src/main/java/com/manir/springbootecommercerestapi/model/User.java @@ -13,7 +13,7 @@ @Table(name = "users", uniqueConstraints = {@UniqueConstraint(columnNames = {"userName"}), @UniqueConstraint(columnNames = {"email"}) }) -public class User { +public class User extends BaseEntity{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @@ -46,4 +46,10 @@ public class User { fetch = FetchType.LAZY, orphanRemoval = true, mappedBy = "customer") private Set orderProducts; + + //relation with comment or review + @OneToMany(cascade = CascadeType.ALL, + fetch = FetchType.LAZY, orphanRemoval = true, + mappedBy = "customer") + private Set comments; } diff --git a/src/main/java/com/manir/springbootecommercerestapi/repository/CommentRepository.java b/src/main/java/com/manir/springbootecommercerestapi/repository/CommentRepository.java index 74fb923..8fa17c5 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/repository/CommentRepository.java +++ b/src/main/java/com/manir/springbootecommercerestapi/repository/CommentRepository.java @@ -1,10 +1,12 @@ package com.manir.springbootecommercerestapi.repository; import com.manir.springbootecommercerestapi.model.Comment; +import com.manir.springbootecommercerestapi.model.User; import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; public interface CommentRepository extends JpaRepository { List findByProductId(Long productId); + List findByCustomer(User customer); } diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/CommentService.java b/src/main/java/com/manir/springbootecommercerestapi/service/CommentService.java index 1741fed..575ad74 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/service/CommentService.java +++ b/src/main/java/com/manir/springbootecommercerestapi/service/CommentService.java @@ -2,13 +2,15 @@ import com.manir.springbootecommercerestapi.dto.CommentDto; +import com.manir.springbootecommercerestapi.model.User; import java.util.List; public interface CommentService { - CommentDto createComment(Long productId, CommentDto commentDto); + CommentDto createComment(User customer, Long productId, CommentDto commentDto); + List findCommentByCustomer(User customer); List getAllComments(); List getAllCommentsByProductId(Long productId); CommentDto getCommentById(Long productId, Long commentId); diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/Impl/CommentServiceImpl.java b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/CommentServiceImpl.java index fcbb875..f3ade8d 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/service/Impl/CommentServiceImpl.java +++ b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/CommentServiceImpl.java @@ -3,10 +3,12 @@ import com.manir.springbootecommercerestapi.dto.CommentDto; import com.manir.springbootecommercerestapi.exception.EcommerceApiException; import com.manir.springbootecommercerestapi.exception.ResourceNotFoundException; +import com.manir.springbootecommercerestapi.model.User; import com.manir.springbootecommercerestapi.repository.CommentRepository; import com.manir.springbootecommercerestapi.repository.ProductRepository; import com.manir.springbootecommercerestapi.model.Comment; import com.manir.springbootecommercerestapi.model.Product; +import com.manir.springbootecommercerestapi.repository.UserRepository; import com.manir.springbootecommercerestapi.service.CommentService; import org.modelmapper.ModelMapper; import org.springframework.http.HttpStatus; @@ -25,15 +27,18 @@ public class CommentServiceImpl implements CommentService { private CommentRepository commentRepository; @Resource private ProductRepository productRepository; + @Resource + private UserRepository userRepository; @Override - public CommentDto createComment(Long productId, CommentDto commentDto) { - + public CommentDto createComment(User customer, Long productId, CommentDto commentDto) { + User user = findCustomerById(customer.getId()); Product product = findProductById(productId); //convert to entity Comment comment = mapToEntity(commentDto); //save to db comment.setProduct(product); + comment.setCustomer(user); Comment createdComment = commentRepository.save(comment); //convert to dto CommentDto responseComment = mapToDto(createdComment); @@ -41,6 +46,18 @@ public CommentDto createComment(Long productId, CommentDto commentDto) { return responseComment; } + @Override + public List findCommentByCustomer(User customer) { + List comments = commentRepository.findByCustomer(customer); + if (comments.size() == 0){ + throw new EcommerceApiException("User has no comment or review", HttpStatus.BAD_REQUEST); + } + List commentDtoList = comments.stream() + .map(comment -> mapToDto(comment)) + .collect(Collectors.toList()); + return commentDtoList; + } + @Override public List getAllComments() { List comments = commentRepository.findAll(); @@ -120,4 +137,8 @@ private Comment findCommentById(Long commentId){ return comment; } + private User findCustomerById(Long customerId){ + User customer = userRepository.findById(customerId).orElseThrow(()->new ResourceNotFoundException("Customer", customerId)); + return customer; + } } diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/Impl/OrderServiceImpl.java b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/OrderServiceImpl.java index 40527be..72a6138 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/service/Impl/OrderServiceImpl.java +++ b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/OrderServiceImpl.java @@ -41,6 +41,7 @@ public class OrderServiceImpl implements OrderService { @Transactional public void placeOrder(User customer) { CartItemResponse cartItemDto = shoppingCartService.findByCustomer(customer); + //set order fields OrderDto orderDto = setFields(cartItemDto, customer); //save order to the db OrderDto savedOrder = saveOrder(orderDto); From 942ccfff6714bb964d1d1ad4aaed07bf3894ff6a Mon Sep 17 00:00:00 2001 From: manirDev Date: Thu, 17 Nov 2022 16:13:26 +0300 Subject: [PATCH 09/13] Setting, Contact profile are implemented --- .../config/SecurityConfig.java | 3 +- .../controller/ContactController.java | 33 ++++++++ .../controller/ProductController.java | 6 ++ .../controller/SettingController.java | 41 ++++++++++ .../dto/ContactDto.java | 15 ++++ .../dto/FaqDto.java | 11 +++ .../dto/ProfileDto.java | 11 +++ .../dto/SettingDto.java | 27 +++++++ .../model/Contact.java | 26 +++++++ .../springbootecommercerestapi/model/Faq.java | 22 ++++++ .../model/Profile.java | 27 +++++++ .../model/Setting.java | 38 ++++++++++ .../model/User.java | 4 + .../repository/ContactRepository.java | 7 ++ .../repository/ProductRepository.java | 12 +++ .../repository/SettingRepository.java | 7 ++ .../service/ContactService.java | 11 +++ .../service/Impl/ContactServiceImpl.java | 57 ++++++++++++++ .../service/Impl/ProductServiceImpl.java | 14 ++++ .../service/Impl/SettingServiceImpl.java | 75 +++++++++++++++++++ .../service/ProductService.java | 2 + .../service/SettingService.java | 8 ++ .../utils/RequestClientIP.java | 41 ++++++++++ 23 files changed, 497 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/manir/springbootecommercerestapi/controller/ContactController.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/controller/SettingController.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/dto/ContactDto.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/dto/FaqDto.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/dto/ProfileDto.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/dto/SettingDto.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/model/Contact.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/model/Faq.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/model/Profile.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/model/Setting.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/repository/ContactRepository.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/repository/SettingRepository.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/service/ContactService.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/service/Impl/ContactServiceImpl.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/service/Impl/SettingServiceImpl.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/service/SettingService.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/utils/RequestClientIP.java diff --git a/src/main/java/com/manir/springbootecommercerestapi/config/SecurityConfig.java b/src/main/java/com/manir/springbootecommercerestapi/config/SecurityConfig.java index cb723b4..e2a691e 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/config/SecurityConfig.java +++ b/src/main/java/com/manir/springbootecommercerestapi/config/SecurityConfig.java @@ -48,7 +48,8 @@ protected void configure(HttpSecurity http) throws Exception { //to permit all get request and secure post put and delete methods .antMatchers(HttpMethod.GET, "/api/**").permitAll() //authorize singIn and signUp - .antMatchers("/api/v1/auth/**").permitAll() + .antMatchers("/api/v*/auth/**").permitAll() + .antMatchers(HttpMethod.POST, "/api/v*/contact/**").permitAll() .anyRequest() .authenticated(); diff --git a/src/main/java/com/manir/springbootecommercerestapi/controller/ContactController.java b/src/main/java/com/manir/springbootecommercerestapi/controller/ContactController.java new file mode 100644 index 0000000..d440aed --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/controller/ContactController.java @@ -0,0 +1,33 @@ +package com.manir.springbootecommercerestapi.controller; + +import com.manir.springbootecommercerestapi.dto.ContactDto; +import com.manir.springbootecommercerestapi.service.ContactService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import java.util.List; + +@RestController +@RequestMapping(value = "api/v1/contact") +public class ContactController { + @Autowired + private ContactService contactService; + + @PostMapping("/sendMessage") + public ResponseEntity sendMessage(@RequestBody ContactDto contactDto, + HttpServletRequest request){ + ContactDto responseMessage = contactService.sendMessage(contactDto, request); + return new ResponseEntity<>(responseMessage, HttpStatus.CREATED); + } + + //get messages api + @PreAuthorize("hasRole('ADMIN')") + @GetMapping("/allMessages") + public List getAllMessages(){ + return contactService.getMessages(); + } +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/controller/ProductController.java b/src/main/java/com/manir/springbootecommercerestapi/controller/ProductController.java index d5e2605..b34e2ed 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/controller/ProductController.java +++ b/src/main/java/com/manir/springbootecommercerestapi/controller/ProductController.java @@ -77,4 +77,10 @@ public ResponseEntity deleteProduct(@PathVariable Long productId){ return new ResponseEntity<>("Product with id: "+ productId +" is deleted successfully:)", HttpStatus.OK); } + //search product api + @GetMapping("/search") + public List searchProduct(@RequestParam(value = "query") String query){ + return productService.searchProduct(query); + } + } diff --git a/src/main/java/com/manir/springbootecommercerestapi/controller/SettingController.java b/src/main/java/com/manir/springbootecommercerestapi/controller/SettingController.java new file mode 100644 index 0000000..053edbd --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/controller/SettingController.java @@ -0,0 +1,41 @@ +package com.manir.springbootecommercerestapi.controller; + +import com.manir.springbootecommercerestapi.dto.SettingDto; +import com.manir.springbootecommercerestapi.model.Setting; +import com.manir.springbootecommercerestapi.repository.SettingRepository; +import com.manir.springbootecommercerestapi.service.SettingService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import java.util.Optional; + +@RestController +@RequestMapping(value = "api/v1/setting") +public class SettingController { + @Autowired + private SettingService settingService; + @Autowired + private SettingRepository settingRepository; + + //post first setting api + @PreAuthorize("hasRole('ADMIN')") + @PostMapping("/createSetting") + public ResponseEntity createSetting(@RequestBody SettingDto settingDto){ + SettingDto createdSetting = settingService.addSettingFirstTime(settingDto); + return new ResponseEntity<>(createdSetting, HttpStatus.CREATED); + } + + //edit existing setting api + @PreAuthorize("hasRole('ADMIN')") + @PutMapping("/editSetting") + public ResponseEntity editSetting(@RequestBody SettingDto settingDto){ + Optional existingSetting = settingRepository.findAll().stream().findFirst(); + SettingDto editedSetting = settingService.updateSetting(settingDto, existingSetting.get().getId()); + + return ResponseEntity.ok(editedSetting); + } + +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/dto/ContactDto.java b/src/main/java/com/manir/springbootecommercerestapi/dto/ContactDto.java new file mode 100644 index 0000000..338891d --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/dto/ContactDto.java @@ -0,0 +1,15 @@ +package com.manir.springbootecommercerestapi.dto; + +import lombok.Data; + +@Data +public class ContactDto { + private Long id; + private String name; + private String email; + private String phone; + private String subject; + private String message; + private String ipAddress; + private String status; +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/dto/FaqDto.java b/src/main/java/com/manir/springbootecommercerestapi/dto/FaqDto.java new file mode 100644 index 0000000..32586c8 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/dto/FaqDto.java @@ -0,0 +1,11 @@ +package com.manir.springbootecommercerestapi.dto; + +import lombok.Data; + +@Data +public class FaqDto { + private Long id; + private String question; + private String answer; + private String status; +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/dto/ProfileDto.java b/src/main/java/com/manir/springbootecommercerestapi/dto/ProfileDto.java new file mode 100644 index 0000000..ae0c350 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/dto/ProfileDto.java @@ -0,0 +1,11 @@ +package com.manir.springbootecommercerestapi.dto; + +import lombok.Data; + +@Data +public class ProfileDto { + private Long id; + private String image; + private String address; + private String phone; +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/dto/SettingDto.java b/src/main/java/com/manir/springbootecommercerestapi/dto/SettingDto.java new file mode 100644 index 0000000..676cbc7 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/dto/SettingDto.java @@ -0,0 +1,27 @@ +package com.manir.springbootecommercerestapi.dto; + +import lombok.Data; + +@Data +public class SettingDto { + private Long id; + private String title; + private String keywords; + private String description; + private String company; + private String address; + private String phone; + private String fax; + private String email; + private String smtpServer; + private String smtpEmail; + private String smtpPassword; + private Integer smtpPort; + private String facebook; + private String instagram; + private String twitter; + private String aboutUs; + private String contact; + private String reference; + private String status; +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/model/Contact.java b/src/main/java/com/manir/springbootecommercerestapi/model/Contact.java new file mode 100644 index 0000000..e321566 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/model/Contact.java @@ -0,0 +1,26 @@ +package com.manir.springbootecommercerestapi.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; + +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "contact") +public class Contact extends BaseEntity{ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private String name; + private String email; + private String phone; + private String subject; + private String message; + private String ipAddress; + private String status; + +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/model/Faq.java b/src/main/java/com/manir/springbootecommercerestapi/model/Faq.java new file mode 100644 index 0000000..369f411 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/model/Faq.java @@ -0,0 +1,22 @@ +package com.manir.springbootecommercerestapi.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; + +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "faqs") +public class Faq extends BaseEntity{ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private String question; + private String answer; + private String status; + +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/model/Profile.java b/src/main/java/com/manir/springbootecommercerestapi/model/Profile.java new file mode 100644 index 0000000..da592e4 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/model/Profile.java @@ -0,0 +1,27 @@ +package com.manir.springbootecommercerestapi.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; + +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "user_profile") +public class Profile extends BaseEntity{ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private String image; + private String address; + private String phone; + + //relation with user + @OneToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "user_id", referencedColumnName = "id") + private User user; + +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/model/Setting.java b/src/main/java/com/manir/springbootecommercerestapi/model/Setting.java new file mode 100644 index 0000000..ea839f9 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/model/Setting.java @@ -0,0 +1,38 @@ +package com.manir.springbootecommercerestapi.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; + +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "settings") +public class Setting extends BaseEntity{ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private String title; + private String keywords; + private String description; + private String company; + private String address; + private String phone; + private String fax; + private String email; + private String smtpServer; + private String smtpEmail; + private String smtpPassword; + private Integer smtpPort; + private String facebook; + private String instagram; + private String twitter; + private String aboutUs; + private String contact; + private String reference; + private String status; + +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/model/User.java b/src/main/java/com/manir/springbootecommercerestapi/model/User.java index dcda1f3..5ca2a50 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/model/User.java +++ b/src/main/java/com/manir/springbootecommercerestapi/model/User.java @@ -52,4 +52,8 @@ public class User extends BaseEntity{ fetch = FetchType.LAZY, orphanRemoval = true, mappedBy = "customer") private Set comments; + + //relation with profile + @OneToOne(mappedBy = "user") + private Profile user_profile; } diff --git a/src/main/java/com/manir/springbootecommercerestapi/repository/ContactRepository.java b/src/main/java/com/manir/springbootecommercerestapi/repository/ContactRepository.java new file mode 100644 index 0000000..3e2911a --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/repository/ContactRepository.java @@ -0,0 +1,7 @@ +package com.manir.springbootecommercerestapi.repository; + +import com.manir.springbootecommercerestapi.model.Contact; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ContactRepository extends JpaRepository { +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/repository/ProductRepository.java b/src/main/java/com/manir/springbootecommercerestapi/repository/ProductRepository.java index 2e29f5b..419dd56 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/repository/ProductRepository.java +++ b/src/main/java/com/manir/springbootecommercerestapi/repository/ProductRepository.java @@ -2,7 +2,19 @@ import com.manir.springbootecommercerestapi.model.Product; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; public interface ProductRepository extends JpaRepository { + @Query( + "SELECT p FROM Product p WHERE " + + "p.title LIKE CONCAT('%', :query, '%') " + + "or p.description LIKE CONCAT('%', :query, '%')" + + "or p.keywords LIKE CONCAT('%', :query, '%')" + + "or p.detail LIKE CONCAT('%', :query, '%')" + ) + List searchProduct(String query); + } diff --git a/src/main/java/com/manir/springbootecommercerestapi/repository/SettingRepository.java b/src/main/java/com/manir/springbootecommercerestapi/repository/SettingRepository.java new file mode 100644 index 0000000..94b6cb4 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/repository/SettingRepository.java @@ -0,0 +1,7 @@ +package com.manir.springbootecommercerestapi.repository; + +import com.manir.springbootecommercerestapi.model.Setting; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface SettingRepository extends JpaRepository { +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/ContactService.java b/src/main/java/com/manir/springbootecommercerestapi/service/ContactService.java new file mode 100644 index 0000000..65223b0 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/service/ContactService.java @@ -0,0 +1,11 @@ +package com.manir.springbootecommercerestapi.service; + +import com.manir.springbootecommercerestapi.dto.ContactDto; + +import javax.servlet.http.HttpServletRequest; +import java.util.List; + +public interface ContactService { + ContactDto sendMessage(ContactDto contactDto, HttpServletRequest request); + List getMessages(); +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/Impl/ContactServiceImpl.java b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/ContactServiceImpl.java new file mode 100644 index 0000000..db39d0a --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/ContactServiceImpl.java @@ -0,0 +1,57 @@ +package com.manir.springbootecommercerestapi.service.Impl; + +import com.manir.springbootecommercerestapi.dto.ContactDto; +import com.manir.springbootecommercerestapi.model.Contact; +import com.manir.springbootecommercerestapi.repository.ContactRepository; +import com.manir.springbootecommercerestapi.service.ContactService; +import com.manir.springbootecommercerestapi.utils.RequestClientIP; +import lombok.AllArgsConstructor; +import org.modelmapper.ModelMapper; +import org.springframework.stereotype.Service; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.util.List; +import java.util.stream.Collectors; + +@Service +@AllArgsConstructor +public class ContactServiceImpl implements ContactService { + + @Resource(name = "contactRepository") + private final ContactRepository contactRepository; + @Resource(name = "modelMapper") + private final ModelMapper modelMapper; + @Override + public ContactDto sendMessage(ContactDto contactDto, HttpServletRequest request) { + + Contact contact = mapToEntity(contactDto); + String ipAddress = RequestClientIP.getClientIpAddress(request); + contact.setIpAddress(ipAddress); + Contact createdMessage = contactRepository.save(contact); + + return mapToDto(createdMessage); + } + + @Override + public List getMessages() { + List messages = contactRepository.findAll(); + + return messages.stream() + .map(message -> mapToDto(message)) + .collect(Collectors.toList()); + } + + //map to entity + private Contact mapToEntity(ContactDto contactDto){ + Contact contact = modelMapper.map(contactDto, Contact.class); + return contact; + } + //map to dto + private ContactDto mapToDto(Contact contact){ + ContactDto contactDto = modelMapper.map(contact, ContactDto.class); + return contactDto; + } +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/Impl/ProductServiceImpl.java b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/ProductServiceImpl.java index 2f4fd98..9b3dcb6 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/service/Impl/ProductServiceImpl.java +++ b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/ProductServiceImpl.java @@ -1,6 +1,7 @@ package com.manir.springbootecommercerestapi.service.Impl; import com.manir.springbootecommercerestapi.dto.ProductDto; +import com.manir.springbootecommercerestapi.exception.EcommerceApiException; import com.manir.springbootecommercerestapi.exception.ResourceNotFoundException; import com.manir.springbootecommercerestapi.repository.CategoryRepository; import com.manir.springbootecommercerestapi.repository.ProductRepository; @@ -17,6 +18,7 @@ import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartFile; @@ -131,6 +133,18 @@ public ProductDto saveProductByCategoryId(Long categoryId, ProductDto productDto return responseProduct; } + @Override + public List searchProduct(String query) { + List products = productRepository.searchProduct(query); + if (products.size() == 0){ + throw new EcommerceApiException("No product is found", HttpStatus.BAD_REQUEST); + } + List productDtoList = products.stream() + .map(product -> mapToDto(product)) + .collect(Collectors.toList()); + return productDtoList; + } + //upload image private String uploadProductImage(MultipartFile file){ ProductDto productDto = new ProductDto(); diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/Impl/SettingServiceImpl.java b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/SettingServiceImpl.java new file mode 100644 index 0000000..b697560 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/SettingServiceImpl.java @@ -0,0 +1,75 @@ +package com.manir.springbootecommercerestapi.service.Impl; + +import com.manir.springbootecommercerestapi.dto.SettingDto; +import com.manir.springbootecommercerestapi.exception.EcommerceApiException; +import com.manir.springbootecommercerestapi.exception.ResourceNotFoundException; +import com.manir.springbootecommercerestapi.model.Setting; +import com.manir.springbootecommercerestapi.repository.SettingRepository; +import com.manir.springbootecommercerestapi.service.SettingService; +import lombok.AllArgsConstructor; +import org.modelmapper.ModelMapper; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Optional; + +@Service +@AllArgsConstructor +public class SettingServiceImpl implements SettingService { + @Resource(name = "settingRepository") + private final SettingRepository settingRepository; + @Resource(name = "modelMapper") + private final ModelMapper modelMapper; + + @Override + public SettingDto addSettingFirstTime(SettingDto settingDto) { + + Optional setting = settingRepository.findAll().stream().findFirst(); + if (!setting.isPresent()){ + Setting firstSetting = mapToEntity(settingDto); + Setting saveSetting = settingRepository.save(firstSetting); + return mapToDto(saveSetting); + }else { + throw new EcommerceApiException("Setting already exists, please edit it only", HttpStatus.BAD_REQUEST); + } + } + + @Override + public SettingDto updateSetting(SettingDto settingDto, Long id) { + Setting setting = settingRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("Setting", id)); + setting.setTitle(settingDto.getTitle()); + setting.setKeywords(settingDto.getKeywords()); + setting.setDescription(settingDto.getDescription()); + setting.setCompany(settingDto.getCompany()); + setting.setAddress(settingDto.getAddress()); + setting.setPhone(settingDto.getPhone()); + setting.setFax(settingDto.getFax()); + setting.setEmail(settingDto.getEmail()); + setting.setSmtpServer(settingDto.getSmtpServer()); + setting.setSmtpEmail(settingDto.getSmtpEmail()); + setting.setSmtpPassword(settingDto.getSmtpPassword()); + setting.setSmtpPort(settingDto.getSmtpPort()); + setting.setFacebook(settingDto.getFacebook()); + setting.setInstagram(settingDto.getInstagram()); + setting.setTwitter(settingDto.getTwitter()); + setting.setAboutUs(settingDto.getAboutUs()); + setting.setContact(settingDto.getContact()); + setting.setContact(settingDto.getReference()); + //save setting changes + Setting editedSetting = settingRepository.save(setting); + + return mapToDto(editedSetting); + } + + //map to dto + private SettingDto mapToDto(Setting setting){ + SettingDto settingDto = modelMapper.map(setting, SettingDto.class); + return settingDto; + } + //map to entity + private Setting mapToEntity(SettingDto settingDto){ + Setting setting = modelMapper.map(settingDto, Setting.class); + return setting; + } +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/ProductService.java b/src/main/java/com/manir/springbootecommercerestapi/service/ProductService.java index 9853f05..803e650 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/service/ProductService.java +++ b/src/main/java/com/manir/springbootecommercerestapi/service/ProductService.java @@ -15,4 +15,6 @@ public interface ProductService { void deleteProduct(Long productId); ProductDto saveProductByCategoryId(Long categoryId, ProductDto productDto); + + List searchProduct(String query); } diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/SettingService.java b/src/main/java/com/manir/springbootecommercerestapi/service/SettingService.java new file mode 100644 index 0000000..05c010e --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/service/SettingService.java @@ -0,0 +1,8 @@ +package com.manir.springbootecommercerestapi.service; + +import com.manir.springbootecommercerestapi.dto.SettingDto; + +public interface SettingService { + SettingDto addSettingFirstTime(SettingDto settingDto); + SettingDto updateSetting(SettingDto settingDto, Long id); +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/utils/RequestClientIP.java b/src/main/java/com/manir/springbootecommercerestapi/utils/RequestClientIP.java new file mode 100644 index 0000000..5920839 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/utils/RequestClientIP.java @@ -0,0 +1,41 @@ +package com.manir.springbootecommercerestapi.utils; + +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; + +public class RequestClientIP { + + private static final String[] IP_HEADER_CANDIDATES = { + "X-Forwarded-For", + "Proxy-Client-IP", + "WL-Proxy-Client-IP", + "HTTP_X_FORWARDED_FOR", + "HTTP_X_FORWARDED", + "HTTP_X_CLUSTER_CLIENT_IP", + "HTTP_CLIENT_IP", + "HTTP_FORWARDED_FOR", + "HTTP_FORWARDED", + "HTTP_VIA", + "REMOTE_ADDR" + }; + + public static String getClientIpAddress(HttpServletRequest request) { + + if (RequestContextHolder.getRequestAttributes() == null) { + return "0.0.0.0"; + } + + request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); + for (String header: IP_HEADER_CANDIDATES) { + String ipList = request.getHeader(header); + if (ipList != null && ipList.length() != 0 && !"unknown".equalsIgnoreCase(ipList)) { + String ip = ipList.split(",")[0]; + return ip; + } + } + + return request.getRemoteAddr(); + } +} From 36847a17309793b5e99a9c2306f86047000268f6 Mon Sep 17 00:00:00 2001 From: manirDev Date: Thu, 17 Nov 2022 16:56:56 +0300 Subject: [PATCH 10/13] Faq CRUD is done. --- .../controller/FaqController.java | 57 ++++++++++++++++ .../repository/FaqRepository.java | 7 ++ .../service/FaqService.java | 13 ++++ .../service/Impl/FaqServiceImpl.java | 68 +++++++++++++++++++ 4 files changed, 145 insertions(+) create mode 100644 src/main/java/com/manir/springbootecommercerestapi/controller/FaqController.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/repository/FaqRepository.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/service/FaqService.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/service/Impl/FaqServiceImpl.java diff --git a/src/main/java/com/manir/springbootecommercerestapi/controller/FaqController.java b/src/main/java/com/manir/springbootecommercerestapi/controller/FaqController.java new file mode 100644 index 0000000..4c3ea0a --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/controller/FaqController.java @@ -0,0 +1,57 @@ +package com.manir.springbootecommercerestapi.controller; + +import com.manir.springbootecommercerestapi.dto.FaqDto; +import com.manir.springbootecommercerestapi.service.FaqService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("api/v1/faq") +public class FaqController { + @Autowired + private FaqService faqService; + + //add faq api + @PreAuthorize("hasRole('ADMIN')") + @PostMapping("/addFaq") + public ResponseEntity addFaq(@RequestBody FaqDto faqDto){ + FaqDto addedFaq = faqService.addFaq(faqDto); + return new ResponseEntity<>(addedFaq, HttpStatus.CREATED); + } + //list all faqs api + @PreAuthorize("hasRole('ADMIN')") + @GetMapping("/getAllFaqs") + public List listAllFaqs(){ + List faqs = faqService.listAllFaqs(); + return faqs; + } + + //get faq by id api + @PreAuthorize("hasRole('ADMIN')") + @GetMapping("/{id}") + public ResponseEntity getFaqById(@PathVariable Long id){ + FaqDto faq = faqService.getFaqById(id); + return new ResponseEntity<>(faq, HttpStatus.OK); + } + + //update faq api + @PreAuthorize("hasRole('ADMIN')") + @PutMapping("/updateFaq/{id}") + public ResponseEntity updateFaq(@RequestBody FaqDto faqDto, @PathVariable Long id){ + FaqDto updatedFaq = faqService.updateFaq(faqDto, id); + return new ResponseEntity<>(updatedFaq, HttpStatus.OK); + } + + //delete faq api + @PreAuthorize("hasRole('ADMIN')") + @DeleteMapping("/deleteFaq/{id}") + public ResponseEntity deleteFaq(@PathVariable Long id){ + faqService.deleteFaq(id); + return new ResponseEntity<>("Faq with id: "+id+ " is deleted successfully", HttpStatus.OK); + } +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/repository/FaqRepository.java b/src/main/java/com/manir/springbootecommercerestapi/repository/FaqRepository.java new file mode 100644 index 0000000..3fc9ed1 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/repository/FaqRepository.java @@ -0,0 +1,7 @@ +package com.manir.springbootecommercerestapi.repository; + +import com.manir.springbootecommercerestapi.model.Faq; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface FaqRepository extends JpaRepository { +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/FaqService.java b/src/main/java/com/manir/springbootecommercerestapi/service/FaqService.java new file mode 100644 index 0000000..acfe24e --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/service/FaqService.java @@ -0,0 +1,13 @@ +package com.manir.springbootecommercerestapi.service; + +import com.manir.springbootecommercerestapi.dto.FaqDto; + +import java.util.List; + +public interface FaqService { + FaqDto addFaq(FaqDto faqDto); + List listAllFaqs(); + FaqDto getFaqById(Long id); + FaqDto updateFaq(FaqDto faqDto, Long id); + void deleteFaq(Long id); +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/Impl/FaqServiceImpl.java b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/FaqServiceImpl.java new file mode 100644 index 0000000..d8fba99 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/FaqServiceImpl.java @@ -0,0 +1,68 @@ +package com.manir.springbootecommercerestapi.service.Impl; + +import com.manir.springbootecommercerestapi.dto.FaqDto; +import com.manir.springbootecommercerestapi.exception.ResourceNotFoundException; +import com.manir.springbootecommercerestapi.model.Faq; +import com.manir.springbootecommercerestapi.repository.FaqRepository; +import com.manir.springbootecommercerestapi.service.FaqService; +import lombok.AllArgsConstructor; +import org.modelmapper.ModelMapper; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; +import java.util.stream.Collectors; + +@Service +@AllArgsConstructor +public class FaqServiceImpl implements FaqService { + @Resource(name = "faqRepository") + private final FaqRepository faqRepository; + @Resource(name = "modelMapper") + private final ModelMapper modelMapper; + + @Override + public FaqDto addFaq(FaqDto faqDto) { + Faq faq = mapToEntity(faqDto); + Faq addedFaq = faqRepository.save(faq); + + return mapToDto(addedFaq); + } + + @Override + public List listAllFaqs() { + List faqs = faqRepository.findAll(); + return faqs.stream().map(faq -> mapToDto(faq)).collect(Collectors.toList()); + } + + @Override + public FaqDto getFaqById(Long id) { + Faq faq = faqRepository.findById(id).orElseThrow(()->new ResourceNotFoundException("Faq", id)); + return mapToDto(faq); + } + + @Override + public FaqDto updateFaq(FaqDto faqDto, Long id) { + Faq faq = faqRepository.findById(id).orElseThrow(()->new ResourceNotFoundException("Faq", id)); + faq.setQuestion(faqDto.getQuestion()); + faq.setAnswer(faqDto.getAnswer()); + Faq updatedFaq = faqRepository.save(faq); + return mapToDto(updatedFaq); + } + + @Override + public void deleteFaq(Long id) { + Faq faq = faqRepository.findById(id).orElseThrow(()->new ResourceNotFoundException("Faq", id)); + faqRepository.delete(faq); + } + + private FaqDto mapToDto(Faq faq){ + FaqDto faqDto = modelMapper.map(faq, FaqDto.class); + return faqDto; + } + //map to entity + private Faq mapToEntity(FaqDto faqDto){ + Faq faq = modelMapper.map(faqDto, Faq.class); + return faq; + } +} From 57849c8a4d0080d2e3eef6dd1e7bb0d56ceab884 Mon Sep 17 00:00:00 2001 From: manirDev Date: Fri, 18 Nov 2022 15:16:57 +0300 Subject: [PATCH 11/13] Code Refactor --- .../springbootecommercerestapi/dto/FaqDto.java | 3 ++- .../service/CommonService.java | 6 ++++++ .../service/Impl/CommonServiceImpl.java | 17 +++++++++++++++++ .../service/Impl/FaqServiceImpl.java | 3 +++ 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/manir/springbootecommercerestapi/dto/FaqDto.java b/src/main/java/com/manir/springbootecommercerestapi/dto/FaqDto.java index 32586c8..a476603 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/dto/FaqDto.java +++ b/src/main/java/com/manir/springbootecommercerestapi/dto/FaqDto.java @@ -1,9 +1,10 @@ package com.manir.springbootecommercerestapi.dto; +import com.manir.springbootecommercerestapi.model.BaseEntity; import lombok.Data; @Data -public class FaqDto { +public class FaqDto extends BaseEntity { private Long id; private String question; private String answer; diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/CommonService.java b/src/main/java/com/manir/springbootecommercerestapi/service/CommonService.java index e2156a2..f973fb0 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/service/CommonService.java +++ b/src/main/java/com/manir/springbootecommercerestapi/service/CommonService.java @@ -19,4 +19,10 @@ public interface CommonService { //get current authenticated user User getCurrentAuthenticatedUser(Authentication authentication); + + //entity mapper + T mapToEntity(T type); + + //dto mapper + T mapToDto(T type); } diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/Impl/CommonServiceImpl.java b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/CommonServiceImpl.java index e8cfb9c..bc633ab 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/service/Impl/CommonServiceImpl.java +++ b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/CommonServiceImpl.java @@ -9,6 +9,7 @@ import com.manir.springbootecommercerestapi.service.CommonService; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.modelmapper.ModelMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.domain.Page; @@ -17,6 +18,7 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; @@ -27,12 +29,15 @@ @Service @Slf4j @AllArgsConstructor +@Component("commonService") public class CommonServiceImpl implements CommonService{ private static Logger logger = LoggerFactory.getLogger(CategoryServiceImpl.class); @Resource(name = "userRepository") private final UserRepository userRepository; + @Resource(name = "modelMapper") + private final ModelMapper modelMapper; @Override public CommonResponse getResponseContent(Page page, List dtoList) { @@ -75,4 +80,16 @@ public User getCurrentAuthenticatedUser(Authentication authentication) { return currentUser; } + + @Override + public Object mapToEntity(Object type) { + Object entityObject = modelMapper.map(type, Object.class); + return entityObject; + } + + @Override + public Object mapToDto(Object type) { + Object dtoObject = modelMapper.map(type, Object.class); + return dtoObject; + } } diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/Impl/FaqServiceImpl.java b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/FaqServiceImpl.java index d8fba99..6ea6cb8 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/service/Impl/FaqServiceImpl.java +++ b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/FaqServiceImpl.java @@ -4,6 +4,7 @@ import com.manir.springbootecommercerestapi.exception.ResourceNotFoundException; import com.manir.springbootecommercerestapi.model.Faq; import com.manir.springbootecommercerestapi.repository.FaqRepository; +import com.manir.springbootecommercerestapi.service.CommonService; import com.manir.springbootecommercerestapi.service.FaqService; import lombok.AllArgsConstructor; import org.modelmapper.ModelMapper; @@ -20,6 +21,8 @@ public class FaqServiceImpl implements FaqService { private final FaqRepository faqRepository; @Resource(name = "modelMapper") private final ModelMapper modelMapper; + @Resource(name = "commonService") + private final CommonService commonService; @Override public FaqDto addFaq(FaqDto faqDto) { From e7907878183fff1336bc089ae45f9abd8d64e9e2 Mon Sep 17 00:00:00 2001 From: manirDev Date: Fri, 18 Nov 2022 17:30:20 +0300 Subject: [PATCH 12/13] ModelMapper code refactor using java generic --- .../service/Impl/FaqServiceImpl.java | 9 ++--- .../service/MapperService.java | 9 +++++ .../service/MapperServiceImpl.java | 36 +++++++++++++++++++ 3 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/manir/springbootecommercerestapi/service/MapperService.java create mode 100644 src/main/java/com/manir/springbootecommercerestapi/service/MapperServiceImpl.java diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/Impl/FaqServiceImpl.java b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/FaqServiceImpl.java index 6ea6cb8..567dc11 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/service/Impl/FaqServiceImpl.java +++ b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/FaqServiceImpl.java @@ -6,6 +6,7 @@ import com.manir.springbootecommercerestapi.repository.FaqRepository; import com.manir.springbootecommercerestapi.service.CommonService; import com.manir.springbootecommercerestapi.service.FaqService; +import com.manir.springbootecommercerestapi.service.MapperService; import lombok.AllArgsConstructor; import org.modelmapper.ModelMapper; import org.springframework.stereotype.Service; @@ -21,15 +22,15 @@ public class FaqServiceImpl implements FaqService { private final FaqRepository faqRepository; @Resource(name = "modelMapper") private final ModelMapper modelMapper; - @Resource(name = "commonService") - private final CommonService commonService; + @Resource(name = "mapperService") + private final MapperService mapperService; @Override public FaqDto addFaq(FaqDto faqDto) { - Faq faq = mapToEntity(faqDto); + Faq faq = mapperService.mapToEntity(faqDto); Faq addedFaq = faqRepository.save(faq); - return mapToDto(addedFaq); + return mapperService.mapToDto(addedFaq); } @Override diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/MapperService.java b/src/main/java/com/manir/springbootecommercerestapi/service/MapperService.java new file mode 100644 index 0000000..33a4150 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/service/MapperService.java @@ -0,0 +1,9 @@ +package com.manir.springbootecommercerestapi.service; + +public interface MapperService{ + //entity mapper + E mapToEntity(D type); + + //dto mapper + D mapToDto(E type); +} diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/MapperServiceImpl.java b/src/main/java/com/manir/springbootecommercerestapi/service/MapperServiceImpl.java new file mode 100644 index 0000000..2eb67f5 --- /dev/null +++ b/src/main/java/com/manir/springbootecommercerestapi/service/MapperServiceImpl.java @@ -0,0 +1,36 @@ +package com.manir.springbootecommercerestapi.service; + +import lombok.AllArgsConstructor; +import org.modelmapper.ModelMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +@AllArgsConstructor +@Service +@Component("mapperService") +public class MapperServiceImpl implements MapperService { + + + @Resource(name = "modelMapper") + private final ModelMapper modelMapper; + @Resource + private final Class entityClass; + @Resource + private final Class dtoClass; + + + @Override + public E mapToEntity(D type) { + E model = modelMapper.map(type, entityClass); + return model; + } + + @Override + public D mapToDto(E type) { + D dto = modelMapper.map(type, dtoClass); + return dto; + } +} From 3b990a9004305917bb42b2b6d378357ffe87079c Mon Sep 17 00:00:00 2001 From: manirDev Date: Mon, 21 Nov 2022 14:06:53 +0300 Subject: [PATCH 13/13] model mapper refactor --- .../service/Impl/FaqServiceImpl.java | 2 +- .../service/MapperServiceImpl.java | 22 +++++++++++-------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/Impl/FaqServiceImpl.java b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/FaqServiceImpl.java index 567dc11..1732722 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/service/Impl/FaqServiceImpl.java +++ b/src/main/java/com/manir/springbootecommercerestapi/service/Impl/FaqServiceImpl.java @@ -36,7 +36,7 @@ public FaqDto addFaq(FaqDto faqDto) { @Override public List listAllFaqs() { List faqs = faqRepository.findAll(); - return faqs.stream().map(faq -> mapToDto(faq)).collect(Collectors.toList()); + return faqs.stream().map(faq -> mapperService.mapToDto(faq)).collect(Collectors.toList()); } @Override diff --git a/src/main/java/com/manir/springbootecommercerestapi/service/MapperServiceImpl.java b/src/main/java/com/manir/springbootecommercerestapi/service/MapperServiceImpl.java index 2eb67f5..9857292 100644 --- a/src/main/java/com/manir/springbootecommercerestapi/service/MapperServiceImpl.java +++ b/src/main/java/com/manir/springbootecommercerestapi/service/MapperServiceImpl.java @@ -1,36 +1,40 @@ package com.manir.springbootecommercerestapi.service; -import lombok.AllArgsConstructor; + +import lombok.Data; import org.modelmapper.ModelMapper; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; import javax.annotation.Resource; -@AllArgsConstructor + @Service @Component("mapperService") +@Data public class MapperServiceImpl implements MapperService { @Resource(name = "modelMapper") private final ModelMapper modelMapper; - @Resource - private final Class entityClass; - @Resource - private final Class dtoClass; + private Class entityClass; + + private Class dtoClass; + + public MapperServiceImpl(ModelMapper modelMapper) { + this.modelMapper = modelMapper; + } @Override public E mapToEntity(D type) { - E model = modelMapper.map(type, entityClass); + E model = modelMapper.map(type, getEntityClass()); return model; } @Override public D mapToDto(E type) { - D dto = modelMapper.map(type, dtoClass); + D dto = modelMapper.map(type, getDtoClass()); return dto; } }