From e1f6d8cae25cf898329821459117d164e1fb96da Mon Sep 17 00:00:00 2001 From: Harkamal Randhawa Date: Wed, 1 Apr 2026 16:57:27 -0600 Subject: [PATCH] Apply service logic --- .gitignore | 1 + .../backend/service/CustomerService.java | 66 +++++++++++++++++-- .../petshop/backend/service/SaleService.java | 20 +++++- 3 files changed, 81 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index c4c4ffc6..733370d6 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ *.zip +.local/ diff --git a/backend/src/main/java/com/petshop/backend/service/CustomerService.java b/backend/src/main/java/com/petshop/backend/service/CustomerService.java index 040be22a..33c731d1 100644 --- a/backend/src/main/java/com/petshop/backend/service/CustomerService.java +++ b/backend/src/main/java/com/petshop/backend/service/CustomerService.java @@ -4,23 +4,34 @@ import com.petshop.backend.dto.common.BulkDeleteRequest; import com.petshop.backend.dto.customer.CustomerRequest; import com.petshop.backend.dto.customer.CustomerResponse; import com.petshop.backend.entity.Customer; +import com.petshop.backend.entity.User; import com.petshop.backend.exception.ResourceNotFoundException; import com.petshop.backend.repository.CustomerRepository; import com.petshop.backend.repository.UserRepository; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.server.ResponseStatusException; + +import static org.springframework.http.HttpStatus.CONFLICT; @Service public class CustomerService { + private static final String TEMP_PASSWORD = "TempPass123!"; + private final CustomerRepository customerRepository; private final UserRepository userRepository; + private final PasswordEncoder passwordEncoder; + private final UserBusinessLinkageService userBusinessLinkageService; - public CustomerService(CustomerRepository customerRepository, UserRepository userRepository) { + public CustomerService(CustomerRepository customerRepository, UserRepository userRepository, PasswordEncoder passwordEncoder, UserBusinessLinkageService userBusinessLinkageService) { this.customerRepository = customerRepository; this.userRepository = userRepository; + this.passwordEncoder = passwordEncoder; + this.userBusinessLinkageService = userBusinessLinkageService; } public Page getAllCustomers(String query, Pageable pageable) { @@ -41,14 +52,19 @@ public class CustomerService { @Transactional public CustomerResponse createCustomer(CustomerRequest request) { + ensureEmailAvailable(request.getEmail(), null); + Customer customer = new Customer(); customer.setFirstName(request.getFirstName()); customer.setLastName(request.getLastName()); customer.setEmail(request.getEmail()); customer = customerRepository.save(customer); - syncLinkedUser(customer); - return mapToResponse(customer); + User user = createLinkedUser(customer); + + Customer linkedCustomer = userBusinessLinkageService.ensureLinkedCustomer(user); + syncLinkedUser(linkedCustomer); + return mapToResponse(linkedCustomer); } @Transactional @@ -56,6 +72,8 @@ public class CustomerService { Customer customer = customerRepository.findById(id) .orElseThrow(() -> new ResourceNotFoundException("Customer not found with id: " + id)); + ensureEmailAvailable(request.getEmail(), customer.getUserId()); + customer.setFirstName(request.getFirstName()); customer.setLastName(request.getLastName()); customer.setEmail(request.getEmail()); @@ -67,9 +85,14 @@ public class CustomerService { @Transactional public void deleteCustomer(Long id) { - if (!customerRepository.existsById(id)) { - throw new ResourceNotFoundException("Customer not found with id: " + id); + Customer customer = customerRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException("Customer not found with id: " + id)); + + if (customer.getUserId() != null && userRepository.existsById(customer.getUserId())) { + userRepository.deleteById(customer.getUserId()); + return; } + customerRepository.deleteById(id); } @@ -99,4 +122,37 @@ public class CustomerService { userRepository.save(user); }); } + + private User createLinkedUser(Customer customer) { + User user = new User(); + user.setUsername(generateUsername(customer)); + user.setPassword(passwordEncoder.encode(TEMP_PASSWORD)); + user.setEmail(customer.getEmail()); + user.setFullName((customer.getFirstName() + " " + customer.getLastName()).trim()); + user.setPhone(generatePhone(customer)); + user.setRole(User.Role.CUSTOMER); + user.setActive(false); + user.setTokenVersion(0); + return userRepository.save(user); + } + + private String generateUsername(Customer customer) { + return "customer_" + customer.getCustomerId(); + } + + private String generatePhone(Customer customer) { + return String.format("200-000-%04d", customer.getCustomerId()); + } + + private void ensureEmailAvailable(String email, Long currentUserId) { + if (email == null || email.isBlank()) { + return; + } + + userRepository.findByEmail(email).ifPresent(existing -> { + if (currentUserId == null || !existing.getId().equals(currentUserId)) { + throw new ResponseStatusException(CONFLICT, "Email already exists"); + } + }); + } } diff --git a/backend/src/main/java/com/petshop/backend/service/SaleService.java b/backend/src/main/java/com/petshop/backend/service/SaleService.java index b426dc38..b8d5861e 100644 --- a/backend/src/main/java/com/petshop/backend/service/SaleService.java +++ b/backend/src/main/java/com/petshop/backend/service/SaleService.java @@ -78,7 +78,7 @@ public class SaleService { sale.setSaleDate(LocalDateTime.now()); sale.setEmployee(employee); sale.setStore(store); - sale.setPaymentMethod(request.getPaymentMethod()); + sale.setPaymentMethod(normalizePaymentMethod(request.getPaymentMethod())); sale.setIsRefund(request.getIsRefund() != null ? request.getIsRefund() : false); if (request.getCustomerId() != null) { @@ -215,4 +215,22 @@ public class SaleService { return response; } + + String normalizePaymentMethod(String paymentMethod) { + if (paymentMethod == null) { + return null; + } + + String normalized = paymentMethod.trim(); + if (normalized.equalsIgnoreCase("Debit")) { + return "Card"; + } + if (normalized.equalsIgnoreCase("Cash")) { + return "Cash"; + } + if (normalized.equalsIgnoreCase("Card")) { + return "Card"; + } + return normalized; + } }