Apply service logic

This commit is contained in:
2026-04-01 16:57:27 -06:00
parent 3b31ef4020
commit e1f6d8cae2
3 changed files with 81 additions and 6 deletions

1
.gitignore vendored
View File

@@ -1 +1,2 @@
*.zip *.zip
.local/

View File

@@ -4,23 +4,34 @@ import com.petshop.backend.dto.common.BulkDeleteRequest;
import com.petshop.backend.dto.customer.CustomerRequest; import com.petshop.backend.dto.customer.CustomerRequest;
import com.petshop.backend.dto.customer.CustomerResponse; import com.petshop.backend.dto.customer.CustomerResponse;
import com.petshop.backend.entity.Customer; import com.petshop.backend.entity.Customer;
import com.petshop.backend.entity.User;
import com.petshop.backend.exception.ResourceNotFoundException; import com.petshop.backend.exception.ResourceNotFoundException;
import com.petshop.backend.repository.CustomerRepository; import com.petshop.backend.repository.CustomerRepository;
import com.petshop.backend.repository.UserRepository; import com.petshop.backend.repository.UserRepository;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.server.ResponseStatusException;
import static org.springframework.http.HttpStatus.CONFLICT;
@Service @Service
public class CustomerService { public class CustomerService {
private static final String TEMP_PASSWORD = "TempPass123!";
private final CustomerRepository customerRepository; private final CustomerRepository customerRepository;
private final UserRepository userRepository; 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.customerRepository = customerRepository;
this.userRepository = userRepository; this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder;
this.userBusinessLinkageService = userBusinessLinkageService;
} }
public Page<CustomerResponse> getAllCustomers(String query, Pageable pageable) { public Page<CustomerResponse> getAllCustomers(String query, Pageable pageable) {
@@ -41,14 +52,19 @@ public class CustomerService {
@Transactional @Transactional
public CustomerResponse createCustomer(CustomerRequest request) { public CustomerResponse createCustomer(CustomerRequest request) {
ensureEmailAvailable(request.getEmail(), null);
Customer customer = new Customer(); Customer customer = new Customer();
customer.setFirstName(request.getFirstName()); customer.setFirstName(request.getFirstName());
customer.setLastName(request.getLastName()); customer.setLastName(request.getLastName());
customer.setEmail(request.getEmail()); customer.setEmail(request.getEmail());
customer = customerRepository.save(customer); customer = customerRepository.save(customer);
syncLinkedUser(customer); User user = createLinkedUser(customer);
return mapToResponse(customer);
Customer linkedCustomer = userBusinessLinkageService.ensureLinkedCustomer(user);
syncLinkedUser(linkedCustomer);
return mapToResponse(linkedCustomer);
} }
@Transactional @Transactional
@@ -56,6 +72,8 @@ public class CustomerService {
Customer customer = customerRepository.findById(id) Customer customer = customerRepository.findById(id)
.orElseThrow(() -> new ResourceNotFoundException("Customer not found with id: " + id)); .orElseThrow(() -> new ResourceNotFoundException("Customer not found with id: " + id));
ensureEmailAvailable(request.getEmail(), customer.getUserId());
customer.setFirstName(request.getFirstName()); customer.setFirstName(request.getFirstName());
customer.setLastName(request.getLastName()); customer.setLastName(request.getLastName());
customer.setEmail(request.getEmail()); customer.setEmail(request.getEmail());
@@ -67,9 +85,14 @@ public class CustomerService {
@Transactional @Transactional
public void deleteCustomer(Long id) { public void deleteCustomer(Long id) {
if (!customerRepository.existsById(id)) { Customer customer = customerRepository.findById(id)
throw new ResourceNotFoundException("Customer not found with id: " + 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); customerRepository.deleteById(id);
} }
@@ -99,4 +122,37 @@ public class CustomerService {
userRepository.save(user); 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");
}
});
}
} }

View File

@@ -78,7 +78,7 @@ public class SaleService {
sale.setSaleDate(LocalDateTime.now()); sale.setSaleDate(LocalDateTime.now());
sale.setEmployee(employee); sale.setEmployee(employee);
sale.setStore(store); sale.setStore(store);
sale.setPaymentMethod(request.getPaymentMethod()); sale.setPaymentMethod(normalizePaymentMethod(request.getPaymentMethod()));
sale.setIsRefund(request.getIsRefund() != null ? request.getIsRefund() : false); sale.setIsRefund(request.getIsRefund() != null ? request.getIsRefund() : false);
if (request.getCustomerId() != null) { if (request.getCustomerId() != null) {
@@ -215,4 +215,22 @@ public class SaleService {
return response; 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;
}
} }