From b534a6488295bc51c258866bf246121e7ce510be Mon Sep 17 00:00:00 2001 From: vedasole Date: Thu, 26 Dec 2024 23:32:15 +0530 Subject: [PATCH] feat(customer/addCustomer): update the add customer functionality to use NewCustomerDto while adding new customers --- .../controller/CustomerController.java | 17 ++-- .../payload/NewCustomerDto.java | 84 +++++++++++++++++++ .../service_impl/CustomerServiceImpl.java | 29 +++++-- .../service_interface/CustomerService.java | 3 +- .../utility/ApplicationInitializer.java | 4 +- .../payload/CustomerDtoTest.java | 12 +-- .../utility/TestApplicationInitializer.java | 6 +- 7 files changed, 128 insertions(+), 27 deletions(-) create mode 100644 src/main/java/com/vedasole/ekartecommercebackend/payload/NewCustomerDto.java diff --git a/src/main/java/com/vedasole/ekartecommercebackend/controller/CustomerController.java b/src/main/java/com/vedasole/ekartecommercebackend/controller/CustomerController.java index afb2bbf..ab9d8a9 100644 --- a/src/main/java/com/vedasole/ekartecommercebackend/controller/CustomerController.java +++ b/src/main/java/com/vedasole/ekartecommercebackend/controller/CustomerController.java @@ -4,6 +4,7 @@ import com.vedasole.ekartecommercebackend.exception.ResourceNotFoundException; import com.vedasole.ekartecommercebackend.payload.ApiResponse; import com.vedasole.ekartecommercebackend.payload.CustomerDto; +import com.vedasole.ekartecommercebackend.payload.NewCustomerDto; import com.vedasole.ekartecommercebackend.security.JwtService; import com.vedasole.ekartecommercebackend.service.service_interface.CustomerService; import com.vedasole.ekartecommercebackend.service.service_interface.UserService; @@ -50,27 +51,27 @@ public class CustomerController { /** * Creates a new customer. * - * @param customerDto the customer data to create + * @param newCustomerDto the customer data to create * @return a response with the created customer data and links to itself and the list of customers */ @PostMapping public ResponseEntity> createCustomer( - @Valid @RequestBody CustomerDto customerDto + @Valid @RequestBody NewCustomerDto newCustomerDto ) { - log.debug("New Customer request received with email : {}", customerDto.getEmail()); - log.debug("New Customer request received : {}", customerDto); + log.debug("New Customer request received with email : {}", newCustomerDto.getEmail()); + log.debug("New Customer request received : {}", newCustomerDto); try { - this.customerService.getCustomerByEmail(customerDto.getEmail()); - this.userService.getUserByEmail(customerDto.getEmail()); + this.customerService.getCustomerByEmail(newCustomerDto.getEmail()); + this.userService.getUserByEmail(newCustomerDto.getEmail()); }catch(ResourceNotFoundException re) { log.debug("No customer with this email found"); } catch (Exception e) { throw new APIException("A customer with this email already exists"); } - CustomerDto createdCustomer = this.customerService.createCustomer(customerDto); + CustomerDto createdCustomer = this.customerService.createCustomer(newCustomerDto); log.debug("New Customer created : {}", createdCustomer.getEmail()); - String jwt = this.jwtService.generateToken(this.userService.getUserByEmail(customerDto.getEmail())); + String jwt = this.jwtService.generateToken(this.userService.getUserByEmail(newCustomerDto.getEmail())); Link selfLink = linkTo(methodOn(CustomerController.class).getCustomer(createdCustomer.getCustomerId())).withSelfRel(); Link customersLink = linkTo(methodOn(CustomerController.class).getAllCustomers()).withRel(CUSTOMERS.getValue()); return ResponseEntity diff --git a/src/main/java/com/vedasole/ekartecommercebackend/payload/NewCustomerDto.java b/src/main/java/com/vedasole/ekartecommercebackend/payload/NewCustomerDto.java new file mode 100644 index 0000000..30afd02 --- /dev/null +++ b/src/main/java/com/vedasole/ekartecommercebackend/payload/NewCustomerDto.java @@ -0,0 +1,84 @@ +package com.vedasole.ekartecommercebackend.payload; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonIncludeProperties; +import com.vedasole.ekartecommercebackend.entity.Customer; +import com.vedasole.ekartecommercebackend.utility.AppConstant.Role; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.hateoas.server.core.Relation; + +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.validation.constraints.*; +import java.io.Serial; +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * DTO for new {@link Customer} + */ +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Data +@Relation(itemRelation = "customer", collectionRelation = "customers") +public class NewCustomerDto implements Serializable { + + @Serial + private static final long serialVersionUID = -4970632778733952870L; + + private long customerId; + + @NotBlank(message = "First name is required") + @Size( + min = 3, + max = 20, + message = "First name must be between minimum of 3 characters and maximum of 20 characters" + ) + private String firstName; + + @NotBlank(message = "Last name is required") + @Size( + min = 3, + max = 20, + message = "Last name must be between minimum of 3 characters " + + "and maximum of 20 characters" + ) + private String lastName; + + @NotBlank(message = "Email address is required") + @Email(message = "Email address is not valid", + regexp = "^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+$" + ) + private String email; + + @NotBlank(message = "Password cannot be blank") + @Size( + min = 3, + max = 20, + message = "Password must be between minimum of 3 characters " + + "and maximum of 20 characters" + ) + private String password; + + @NotNull(message = "Phone number is required") + @Pattern( + regexp = "^(\\+\\d{1,3}[- ]?)?\\d{10}$", + message = "Phone number must be a valid 10-digit number" + ) + private String phoneNumber; + + @NotNull(message = "Role is required") + @Enumerated(EnumType.STRING) + private Role role; + + @JsonIncludeProperties({"cartId"}) + private ShoppingCartDto shoppingCart; + + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime createdAt; + +} \ No newline at end of file diff --git a/src/main/java/com/vedasole/ekartecommercebackend/service/service_impl/CustomerServiceImpl.java b/src/main/java/com/vedasole/ekartecommercebackend/service/service_impl/CustomerServiceImpl.java index c2cfefc..eb12cb8 100644 --- a/src/main/java/com/vedasole/ekartecommercebackend/service/service_impl/CustomerServiceImpl.java +++ b/src/main/java/com/vedasole/ekartecommercebackend/service/service_impl/CustomerServiceImpl.java @@ -6,6 +6,7 @@ import com.vedasole.ekartecommercebackend.exception.APIException; import com.vedasole.ekartecommercebackend.exception.ResourceNotFoundException; import com.vedasole.ekartecommercebackend.payload.CustomerDto; +import com.vedasole.ekartecommercebackend.payload.NewCustomerDto; import com.vedasole.ekartecommercebackend.repository.CustomerRepo; import com.vedasole.ekartecommercebackend.repository.ShoppingCartRepo; import com.vedasole.ekartecommercebackend.repository.UserRepo; @@ -26,6 +27,7 @@ import org.thymeleaf.context.Context; import javax.mail.MessagingException; +import javax.validation.Valid; import java.util.List; import java.util.Optional; @@ -52,7 +54,7 @@ public class CustomerServiceImpl implements CustomerService { /** * Creates a new customer and saves it to the database. * - * @param customerDto the customer data to be saved + * @param newCustomerDto the new customer data to be saved * @return the created customer with its ID and other details * @throws APIException if an error occurs while saving the customer */ @@ -62,12 +64,12 @@ public class CustomerServiceImpl implements CustomerService { @CacheEvict(value = "allCustomers", allEntries = true), @CacheEvict(value = "allCustomersPage", allEntries = true) }) - public CustomerDto createCustomer(CustomerDto customerDto) { + public CustomerDto createCustomer(@Valid NewCustomerDto newCustomerDto) { // Create a new user with the role of USER User user = new User( - customerDto.getEmail(), - passwordEncoder.encode(customerDto.getPassword()), - customerDto.getRole() != null ? customerDto.getRole() : AppConstant.Role.USER + newCustomerDto.getEmail(), + passwordEncoder.encode(newCustomerDto.getPassword()), + newCustomerDto.getRole() != null ? newCustomerDto.getRole() : AppConstant.Role.USER ); // Save the user to the database User newUser; @@ -79,7 +81,7 @@ public CustomerDto createCustomer(CustomerDto customerDto) { } // Create a new customer and set the user to the newly created user - Customer customer = dtoToCustomer(customerDto); + Customer customer = newCustomerDtoToCustomer(newCustomerDto); customer.setUser(newUser); // Save the customer to the database @@ -93,7 +95,7 @@ public CustomerDto createCustomer(CustomerDto customerDto) { newCustomer = this.customerRepo.save(newCustomer); log.debug("Customer saved with id : {}", newCustomer.getEmail()); } catch (Exception e) { - log.error("Failed to save customer: {}", customerDto.getEmail()); + log.error("Failed to save customer: {}", newCustomerDto.getEmail()); throw new APIException("Failed to save customer"); } @@ -309,6 +311,19 @@ private Customer dtoToCustomer(CustomerDto customerDto){ return customer; } + /** + * Maps a NewCustomerDto to a Customer. + * + * @param newCustomerDto the NewCustomerDto to be mapped + * @return the mapped Customer + */ + private Customer newCustomerDtoToCustomer(NewCustomerDto newCustomerDto){ + User user = new User(newCustomerDto.getEmail(), passwordEncoder.encode(newCustomerDto.getPassword()), newCustomerDto.getRole()); + Customer customer = this.modelMapper.map(newCustomerDto, Customer.class); + customer.setUser(user); + return customer; + } + /** * Maps a Customer to a CustomerDto. * diff --git a/src/main/java/com/vedasole/ekartecommercebackend/service/service_interface/CustomerService.java b/src/main/java/com/vedasole/ekartecommercebackend/service/service_interface/CustomerService.java index 9096000..f93e12d 100644 --- a/src/main/java/com/vedasole/ekartecommercebackend/service/service_interface/CustomerService.java +++ b/src/main/java/com/vedasole/ekartecommercebackend/service/service_interface/CustomerService.java @@ -3,13 +3,14 @@ import com.vedasole.ekartecommercebackend.entity.Customer; import com.vedasole.ekartecommercebackend.entity.User; import com.vedasole.ekartecommercebackend.payload.CustomerDto; +import com.vedasole.ekartecommercebackend.payload.NewCustomerDto; import org.springframework.data.domain.Page; import java.util.List; public interface CustomerService { - CustomerDto createCustomer(CustomerDto customerDto); + CustomerDto createCustomer(NewCustomerDto newCustomerDto); CustomerDto updateCustomer(CustomerDto customerDto , Long customerId); List getAllCustomers(); Page getAllCustomersByPage(int page, int size, String sortBy, String sortOrder); diff --git a/src/main/java/com/vedasole/ekartecommercebackend/utility/ApplicationInitializer.java b/src/main/java/com/vedasole/ekartecommercebackend/utility/ApplicationInitializer.java index 5c6ebb9..cd8ac43 100644 --- a/src/main/java/com/vedasole/ekartecommercebackend/utility/ApplicationInitializer.java +++ b/src/main/java/com/vedasole/ekartecommercebackend/utility/ApplicationInitializer.java @@ -1,7 +1,7 @@ package com.vedasole.ekartecommercebackend.utility; import com.vedasole.ekartecommercebackend.exception.ResourceNotFoundException; -import com.vedasole.ekartecommercebackend.payload.CustomerDto; +import com.vedasole.ekartecommercebackend.payload.NewCustomerDto; import com.vedasole.ekartecommercebackend.service.service_interface.CustomerService; import lombok.NonNull; import org.springframework.beans.factory.annotation.Value; @@ -33,7 +33,7 @@ private void insertAdminUser() { try { customerService.getCustomerByEmail(adminEmail); } catch (ResourceNotFoundException e) { - CustomerDto adminUser = CustomerDto.builder() + NewCustomerDto adminUser = NewCustomerDto.builder() .customerId(1) .email(adminEmail) .firstName("Admin") diff --git a/src/test/java/com/vedasole/ekartecommercebackend/payload/CustomerDtoTest.java b/src/test/java/com/vedasole/ekartecommercebackend/payload/CustomerDtoTest.java index cc7b9bd..a4bcc6d 100644 --- a/src/test/java/com/vedasole/ekartecommercebackend/payload/CustomerDtoTest.java +++ b/src/test/java/com/vedasole/ekartecommercebackend/payload/CustomerDtoTest.java @@ -134,7 +134,7 @@ void shouldValidateEmailFormatWhenNotValid() { @Test void shouldValidatePasswordLengthWhenLessThanMinimum() { // Given - CustomerDto customerDto = CustomerDto.builder() + NewCustomerDto newCustomerDto = NewCustomerDto.builder() .customerId(1) .firstName("John") .lastName("Doe") @@ -145,7 +145,7 @@ void shouldValidatePasswordLengthWhenLessThanMinimum() { .build(); // When - Set> violations = validator.validate(customerDto); + Set> violations = validator.validate(newCustomerDto); // Then assertEquals(1, violations.size()); @@ -156,7 +156,7 @@ void shouldValidatePasswordLengthWhenLessThanMinimum() { @Test void shouldValidatePasswordLengthWhenMoreThanMaximum() { // Given - CustomerDto customerDto = CustomerDto.builder() + NewCustomerDto newCustomerDto = NewCustomerDto.builder() .customerId(1) .firstName("John") .lastName("Doe") @@ -167,7 +167,7 @@ void shouldValidatePasswordLengthWhenMoreThanMaximum() { .build(); // When - Set> violations = validator.validate(customerDto); + Set> violations = validator.validate(newCustomerDto); // Then assertEquals(1, violations.size()); @@ -267,7 +267,7 @@ void shouldValidatePhoneNumberWhenNotValid() { @Test void shouldValidateRoleWhenNull() { // Given - CustomerDto customerDto = CustomerDto.builder() + NewCustomerDto newCustomerDto = NewCustomerDto.builder() .customerId(1) .firstName("John") .lastName("Doe") @@ -278,7 +278,7 @@ void shouldValidateRoleWhenNull() { .build(); // When - Set> violations = validator.validate(customerDto); + Set> violations = validator.validate(newCustomerDto); // Then assertEquals(1, violations.size()); diff --git a/src/test/java/com/vedasole/ekartecommercebackend/utility/TestApplicationInitializer.java b/src/test/java/com/vedasole/ekartecommercebackend/utility/TestApplicationInitializer.java index 5352b29..1fe2269 100644 --- a/src/test/java/com/vedasole/ekartecommercebackend/utility/TestApplicationInitializer.java +++ b/src/test/java/com/vedasole/ekartecommercebackend/utility/TestApplicationInitializer.java @@ -1,7 +1,7 @@ package com.vedasole.ekartecommercebackend.utility; import com.vedasole.ekartecommercebackend.entity.User; -import com.vedasole.ekartecommercebackend.payload.CustomerDto; +import com.vedasole.ekartecommercebackend.payload.NewCustomerDto; import com.vedasole.ekartecommercebackend.security.JwtService; import com.vedasole.ekartecommercebackend.service.service_interface.CustomerService; import lombok.Getter; @@ -64,7 +64,7 @@ private void generateUserToken() { } private void insertNormalUser() { - CustomerDto adminUser = CustomerDto.builder() + NewCustomerDto normalUser = NewCustomerDto.builder() .customerId(2) .email(normalUserEmail) .firstName("Normal") @@ -73,7 +73,7 @@ private void insertNormalUser() { .password(normalUserPassword) .role(AppConstant.Role.USER) .build(); - customerService.createCustomer(adminUser); + customerService.createCustomer(normalUser); } } \ No newline at end of file