cut over employee phones
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
package com.petshop.backend.controller;
|
||||
|
||||
import com.petshop.backend.dto.employee.EmployeeRequest;
|
||||
import com.petshop.backend.dto.employee.EmployeeResponse;
|
||||
import com.petshop.backend.service.EmployeeService;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/employees")
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
public class EmployeeController {
|
||||
private final EmployeeService employeeService;
|
||||
|
||||
public EmployeeController(EmployeeService employeeService) {
|
||||
this.employeeService = employeeService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public ResponseEntity<Page<EmployeeResponse>> getAllEmployees(@RequestParam(required = false) String q, Pageable pageable) {
|
||||
return ResponseEntity.ok(employeeService.getAllEmployees(q, pageable));
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public ResponseEntity<EmployeeResponse> getEmployeeById(@PathVariable Long id) {
|
||||
return ResponseEntity.ok(employeeService.getEmployeeById(id));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public ResponseEntity<EmployeeResponse> createEmployee(@Valid @RequestBody EmployeeRequest request) {
|
||||
return ResponseEntity.status(HttpStatus.CREATED).body(employeeService.createEmployee(request));
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public ResponseEntity<EmployeeResponse> updateEmployee(@PathVariable Long id, @Valid @RequestBody EmployeeRequest request) {
|
||||
return ResponseEntity.ok(employeeService.updateEmployee(id, request));
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public ResponseEntity<Void> deleteEmployee(@PathVariable Long id) {
|
||||
employeeService.deleteEmployee(id);
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
}
|
||||
@@ -14,8 +14,6 @@ public class CustomerRequest {
|
||||
@Email(message = "Invalid email format")
|
||||
private String email;
|
||||
|
||||
private String phone;
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
@@ -40,14 +38,6 @@ public class CustomerRequest {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getPhone() {
|
||||
return phone;
|
||||
}
|
||||
|
||||
public void setPhone(String phone) {
|
||||
this.phone = phone;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
@@ -55,13 +45,12 @@ public class CustomerRequest {
|
||||
CustomerRequest that = (CustomerRequest) o;
|
||||
return Objects.equals(firstName, that.firstName) &&
|
||||
Objects.equals(lastName, that.lastName) &&
|
||||
Objects.equals(email, that.email) &&
|
||||
Objects.equals(phone, that.phone);
|
||||
Objects.equals(email, that.email);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(firstName, lastName, email, phone);
|
||||
return Objects.hash(firstName, lastName, email);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -70,7 +59,6 @@ public class CustomerRequest {
|
||||
"firstName='" + firstName + '\'' +
|
||||
", lastName='" + lastName + '\'' +
|
||||
", email='" + email + '\'' +
|
||||
", phone='" + phone + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,19 +8,17 @@ public class CustomerResponse {
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
private String email;
|
||||
private String phone;
|
||||
private LocalDateTime createdAt;
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
public CustomerResponse() {
|
||||
}
|
||||
|
||||
public CustomerResponse(Long customerId, String firstName, String lastName, String email, String phone, LocalDateTime createdAt, LocalDateTime updatedAt) {
|
||||
public CustomerResponse(Long customerId, String firstName, String lastName, String email, LocalDateTime createdAt, LocalDateTime updatedAt) {
|
||||
this.customerId = customerId;
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
this.email = email;
|
||||
this.phone = phone;
|
||||
this.createdAt = createdAt;
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
@@ -57,14 +55,6 @@ public class CustomerResponse {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getPhone() {
|
||||
return phone;
|
||||
}
|
||||
|
||||
public void setPhone(String phone) {
|
||||
this.phone = phone;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
@@ -86,12 +76,12 @@ public class CustomerResponse {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
CustomerResponse that = (CustomerResponse) o;
|
||||
return Objects.equals(customerId, that.customerId) && Objects.equals(firstName, that.firstName) && Objects.equals(lastName, that.lastName) && Objects.equals(email, that.email) && Objects.equals(phone, that.phone) && Objects.equals(createdAt, that.createdAt) && Objects.equals(updatedAt, that.updatedAt);
|
||||
return Objects.equals(customerId, that.customerId) && Objects.equals(firstName, that.firstName) && Objects.equals(lastName, that.lastName) && Objects.equals(email, that.email) && Objects.equals(createdAt, that.createdAt) && Objects.equals(updatedAt, that.updatedAt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(customerId, firstName, lastName, email, phone, createdAt, updatedAt);
|
||||
return Objects.hash(customerId, firstName, lastName, email, createdAt, updatedAt);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -101,7 +91,6 @@ public class CustomerResponse {
|
||||
", firstName='" + firstName + '\'' +
|
||||
", lastName='" + lastName + '\'' +
|
||||
", email='" + email + '\'' +
|
||||
", phone='" + phone + '\'' +
|
||||
", createdAt=" + createdAt +
|
||||
", updatedAt=" + updatedAt +
|
||||
'}';
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.petshop.backend.dto.employee;
|
||||
|
||||
import com.petshop.backend.entity.User;
|
||||
import jakarta.validation.constraints.Email;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
|
||||
public class EmployeeRequest {
|
||||
@NotBlank(message = "Username is required")
|
||||
@Size(min = 3, max = 50, message = "Username must be between 3 and 50 characters")
|
||||
private String username;
|
||||
|
||||
@Size(min = 6, message = "Password must be at least 6 characters")
|
||||
private String password;
|
||||
|
||||
@NotBlank(message = "First name is required")
|
||||
private String firstName;
|
||||
|
||||
@NotBlank(message = "Last name is required")
|
||||
private String lastName;
|
||||
|
||||
@Email(message = "Invalid email format")
|
||||
private String email;
|
||||
|
||||
@Size(max = 20, message = "Phone must not exceed 20 characters")
|
||||
private String phone;
|
||||
|
||||
@NotNull(message = "Role is required")
|
||||
private User.Role role;
|
||||
|
||||
private Boolean active = true;
|
||||
|
||||
public String getUsername() { return username; }
|
||||
public void setUsername(String username) { this.username = username; }
|
||||
public String getPassword() { return password; }
|
||||
public void setPassword(String password) { this.password = password; }
|
||||
public String getFirstName() { return firstName; }
|
||||
public void setFirstName(String firstName) { this.firstName = firstName; }
|
||||
public String getLastName() { return lastName; }
|
||||
public void setLastName(String lastName) { this.lastName = lastName; }
|
||||
public String getEmail() { return email; }
|
||||
public void setEmail(String email) { this.email = email; }
|
||||
public String getPhone() { return phone; }
|
||||
public void setPhone(String phone) { this.phone = phone; }
|
||||
public User.Role getRole() { return role; }
|
||||
public void setRole(User.Role role) { this.role = role; }
|
||||
public Boolean getActive() { return active; }
|
||||
public void setActive(Boolean active) { this.active = active; }
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.petshop.backend.dto.employee;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public class EmployeeResponse {
|
||||
private Long employeeId;
|
||||
private Long userId;
|
||||
private String username;
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
private String fullName;
|
||||
private String email;
|
||||
private String phone;
|
||||
private String role;
|
||||
private Boolean active;
|
||||
private LocalDateTime createdAt;
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
public Long getEmployeeId() { return employeeId; }
|
||||
public void setEmployeeId(Long employeeId) { this.employeeId = employeeId; }
|
||||
public Long getUserId() { return userId; }
|
||||
public void setUserId(Long userId) { this.userId = userId; }
|
||||
public String getUsername() { return username; }
|
||||
public void setUsername(String username) { this.username = username; }
|
||||
public String getFirstName() { return firstName; }
|
||||
public void setFirstName(String firstName) { this.firstName = firstName; }
|
||||
public String getLastName() { return lastName; }
|
||||
public void setLastName(String lastName) { this.lastName = lastName; }
|
||||
public String getFullName() { return fullName; }
|
||||
public void setFullName(String fullName) { this.fullName = fullName; }
|
||||
public String getEmail() { return email; }
|
||||
public void setEmail(String email) { this.email = email; }
|
||||
public String getPhone() { return phone; }
|
||||
public void setPhone(String phone) { this.phone = phone; }
|
||||
public String getRole() { return role; }
|
||||
public void setRole(String role) { this.role = role; }
|
||||
public Boolean getActive() { return active; }
|
||||
public void setActive(Boolean active) { this.active = active; }
|
||||
public LocalDateTime getCreatedAt() { return createdAt; }
|
||||
public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
|
||||
public LocalDateTime getUpdatedAt() { return updatedAt; }
|
||||
public void setUpdatedAt(LocalDateTime updatedAt) { this.updatedAt = updatedAt; }
|
||||
}
|
||||
@@ -27,9 +27,6 @@ public class Customer {
|
||||
@Column(nullable = false, length = 100)
|
||||
private String email;
|
||||
|
||||
@Column(nullable = false, length = 20)
|
||||
private String phone;
|
||||
|
||||
@CreationTimestamp
|
||||
@Column(name = "created_at", updatable = false)
|
||||
private LocalDateTime createdAt;
|
||||
@@ -41,13 +38,12 @@ public class Customer {
|
||||
public Customer() {
|
||||
}
|
||||
|
||||
public Customer(Long customerId, Long userId, String firstName, String lastName, String email, String phone, LocalDateTime createdAt, LocalDateTime updatedAt) {
|
||||
public Customer(Long customerId, Long userId, String firstName, String lastName, String email, LocalDateTime createdAt, LocalDateTime updatedAt) {
|
||||
this.customerId = customerId;
|
||||
this.userId = userId;
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
this.email = email;
|
||||
this.phone = phone;
|
||||
this.createdAt = createdAt;
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
@@ -92,14 +88,6 @@ public class Customer {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getPhone() {
|
||||
return phone;
|
||||
}
|
||||
|
||||
public void setPhone(String phone) {
|
||||
this.phone = phone;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
@@ -137,7 +125,6 @@ public class Customer {
|
||||
", firstName='" + firstName + '\'' +
|
||||
", lastName='" + lastName + '\'' +
|
||||
", email='" + email + '\'' +
|
||||
", phone='" + phone + '\'' +
|
||||
", createdAt=" + createdAt +
|
||||
", updatedAt=" + updatedAt +
|
||||
'}';
|
||||
|
||||
@@ -27,9 +27,6 @@ public class Employee {
|
||||
@Column(nullable = false, length = 100)
|
||||
private String email;
|
||||
|
||||
@Column(nullable = false, length = 20)
|
||||
private String phone;
|
||||
|
||||
@Column(nullable = false, length = 50)
|
||||
private String role;
|
||||
|
||||
@@ -47,13 +44,12 @@ public class Employee {
|
||||
public Employee() {
|
||||
}
|
||||
|
||||
public Employee(Long employeeId, Long userId, String firstName, String lastName, String email, String phone, String role, Boolean isActive, LocalDateTime createdAt, LocalDateTime updatedAt) {
|
||||
public Employee(Long employeeId, Long userId, String firstName, String lastName, String email, String role, Boolean isActive, LocalDateTime createdAt, LocalDateTime updatedAt) {
|
||||
this.employeeId = employeeId;
|
||||
this.userId = userId;
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
this.email = email;
|
||||
this.phone = phone;
|
||||
this.role = role;
|
||||
this.isActive = isActive;
|
||||
this.createdAt = createdAt;
|
||||
@@ -100,14 +96,6 @@ public class Employee {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getPhone() {
|
||||
return phone;
|
||||
}
|
||||
|
||||
public void setPhone(String phone) {
|
||||
this.phone = phone;
|
||||
}
|
||||
|
||||
public String getRole() {
|
||||
return role;
|
||||
}
|
||||
@@ -161,7 +149,6 @@ public class Employee {
|
||||
", firstName='" + firstName + '\'' +
|
||||
", lastName='" + lastName + '\'' +
|
||||
", email='" + email + '\'' +
|
||||
", phone='" + phone + '\'' +
|
||||
", role='" + role + '\'' +
|
||||
", isActive=" + isActive +
|
||||
", createdAt=" + createdAt +
|
||||
|
||||
@@ -21,6 +21,6 @@ public interface CustomerRepository extends JpaRepository<Customer, Long> {
|
||||
"LOWER(c.firstName) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
|
||||
"LOWER(c.lastName) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
|
||||
"LOWER(c.email) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
|
||||
"LOWER(c.phone) LIKE LOWER(CONCAT('%', :q, '%'))")
|
||||
"EXISTS (SELECT u FROM User u WHERE u.id = c.userId AND LOWER(COALESCE(u.phone, '')) LIKE LOWER(CONCAT('%', :q, '%')))")
|
||||
Page<Customer> searchCustomers(@Param("q") String query, Pageable pageable);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
package com.petshop.backend.repository;
|
||||
|
||||
import com.petshop.backend.entity.Employee;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
@@ -11,4 +15,14 @@ import java.util.Optional;
|
||||
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
|
||||
Optional<Employee> findByUserId(Long userId);
|
||||
List<Employee> findAllByEmail(String email);
|
||||
|
||||
@Query("SELECT e FROM Employee e WHERE " +
|
||||
"LOWER(e.firstName) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
|
||||
"LOWER(e.lastName) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
|
||||
"LOWER(e.email) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
|
||||
"LOWER(e.role) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
|
||||
"EXISTS (SELECT u FROM User u WHERE u.id = e.userId AND (" +
|
||||
"LOWER(u.username) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
|
||||
"LOWER(COALESCE(u.phone, '')) LIKE LOWER(CONCAT('%', :q, '%'))))")
|
||||
Page<Employee> searchEmployees(@Param("q") String query, Pageable pageable);
|
||||
}
|
||||
|
||||
@@ -45,7 +45,6 @@ public class CustomerService {
|
||||
customer.setFirstName(request.getFirstName());
|
||||
customer.setLastName(request.getLastName());
|
||||
customer.setEmail(request.getEmail());
|
||||
customer.setPhone(request.getPhone());
|
||||
|
||||
customer = customerRepository.save(customer);
|
||||
syncLinkedUser(customer);
|
||||
@@ -60,7 +59,6 @@ public class CustomerService {
|
||||
customer.setFirstName(request.getFirstName());
|
||||
customer.setLastName(request.getLastName());
|
||||
customer.setEmail(request.getEmail());
|
||||
customer.setPhone(request.getPhone());
|
||||
|
||||
customer = customerRepository.save(customer);
|
||||
syncLinkedUser(customer);
|
||||
@@ -86,7 +84,6 @@ public class CustomerService {
|
||||
customer.getFirstName(),
|
||||
customer.getLastName(),
|
||||
customer.getEmail(),
|
||||
customer.getPhone(),
|
||||
customer.getCreatedAt(),
|
||||
customer.getUpdatedAt()
|
||||
);
|
||||
@@ -98,7 +95,6 @@ public class CustomerService {
|
||||
}
|
||||
userRepository.findById(customer.getUserId()).ifPresent(user -> {
|
||||
user.setEmail(customer.getEmail());
|
||||
user.setPhone(customer.getPhone());
|
||||
user.setFullName((customer.getFirstName() + " " + customer.getLastName()).trim());
|
||||
userRepository.save(user);
|
||||
});
|
||||
|
||||
175
src/main/java/com/petshop/backend/service/EmployeeService.java
Normal file
175
src/main/java/com/petshop/backend/service/EmployeeService.java
Normal file
@@ -0,0 +1,175 @@
|
||||
package com.petshop.backend.service;
|
||||
|
||||
import com.petshop.backend.dto.employee.EmployeeRequest;
|
||||
import com.petshop.backend.dto.employee.EmployeeResponse;
|
||||
import com.petshop.backend.entity.Employee;
|
||||
import com.petshop.backend.entity.User;
|
||||
import com.petshop.backend.exception.ResourceNotFoundException;
|
||||
import com.petshop.backend.repository.EmployeeRepository;
|
||||
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 EmployeeService {
|
||||
private final EmployeeRepository employeeRepository;
|
||||
private final UserRepository userRepository;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
private final UserBusinessLinkageService userBusinessLinkageService;
|
||||
|
||||
public EmployeeService(EmployeeRepository employeeRepository, UserRepository userRepository, PasswordEncoder passwordEncoder, UserBusinessLinkageService userBusinessLinkageService) {
|
||||
this.employeeRepository = employeeRepository;
|
||||
this.userRepository = userRepository;
|
||||
this.passwordEncoder = passwordEncoder;
|
||||
this.userBusinessLinkageService = userBusinessLinkageService;
|
||||
}
|
||||
|
||||
public Page<EmployeeResponse> getAllEmployees(String query, Pageable pageable) {
|
||||
Page<Employee> employees;
|
||||
if (query != null && !query.trim().isEmpty()) {
|
||||
employees = employeeRepository.searchEmployees(query, pageable);
|
||||
} else {
|
||||
employees = employeeRepository.findAll(pageable);
|
||||
}
|
||||
return employees.map(this::mapToResponse);
|
||||
}
|
||||
|
||||
public EmployeeResponse getEmployeeById(Long id) {
|
||||
Employee employee = employeeRepository.findById(id)
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Employee not found with id: " + id));
|
||||
return mapToResponse(employee);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public EmployeeResponse createEmployee(EmployeeRequest request) {
|
||||
validateRole(request.getRole());
|
||||
if (request.getPassword() == null || request.getPassword().trim().length() < 6) {
|
||||
throw new IllegalArgumentException("Password must be at least 6 characters");
|
||||
}
|
||||
if (userRepository.findByUsername(request.getUsername()).isPresent()) {
|
||||
throw new ResponseStatusException(CONFLICT, "Username already exists");
|
||||
}
|
||||
if (request.getEmail() != null && userRepository.findByEmail(request.getEmail()).isPresent()) {
|
||||
throw new ResponseStatusException(CONFLICT, "Email already exists");
|
||||
}
|
||||
String phone = trimToNull(request.getPhone());
|
||||
if (phone != null && userRepository.findByPhone(phone).isPresent()) {
|
||||
throw new ResponseStatusException(CONFLICT, "Phone already exists");
|
||||
}
|
||||
|
||||
User user = new User();
|
||||
user.setUsername(request.getUsername());
|
||||
user.setPassword(passwordEncoder.encode(request.getPassword()));
|
||||
user.setFullName(fullName(request));
|
||||
user.setEmail(request.getEmail());
|
||||
user.setPhone(phone);
|
||||
user.setRole(request.getRole());
|
||||
user.setActive(request.getActive() != null ? request.getActive() : true);
|
||||
user = userRepository.save(user);
|
||||
|
||||
Employee employee = userBusinessLinkageService.ensureLinkedEmployee(user);
|
||||
return mapToResponse(employee, user);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public EmployeeResponse updateEmployee(Long id, EmployeeRequest request) {
|
||||
Employee employee = employeeRepository.findById(id)
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Employee not found with id: " + id));
|
||||
User user = requireLinkedUser(employee);
|
||||
|
||||
validateRole(request.getRole());
|
||||
if (!user.getUsername().equals(request.getUsername()) && userRepository.findByUsername(request.getUsername()).isPresent()) {
|
||||
throw new ResponseStatusException(CONFLICT, "Username already exists");
|
||||
}
|
||||
if (!java.util.Objects.equals(user.getEmail(), request.getEmail()) && request.getEmail() != null && userRepository.findByEmail(request.getEmail()).isPresent()) {
|
||||
throw new ResponseStatusException(CONFLICT, "Email already exists");
|
||||
}
|
||||
String phone = trimToNull(request.getPhone());
|
||||
Long currentUserId = user.getId();
|
||||
if (!java.util.Objects.equals(user.getPhone(), phone)) {
|
||||
userRepository.findByPhone(phone)
|
||||
.filter(existing -> !existing.getId().equals(currentUserId))
|
||||
.ifPresent(existing -> { throw new ResponseStatusException(CONFLICT, "Phone already exists"); });
|
||||
}
|
||||
|
||||
user.setUsername(request.getUsername());
|
||||
if (request.getPassword() != null && !request.getPassword().trim().isEmpty()) {
|
||||
user.setPassword(passwordEncoder.encode(request.getPassword()));
|
||||
user.setTokenVersion(user.getTokenVersion() + 1);
|
||||
}
|
||||
user.setEmail(request.getEmail());
|
||||
user.setPhone(phone);
|
||||
user.setFullName(fullName(request));
|
||||
user.setRole(request.getRole());
|
||||
user.setActive(request.getActive() != null ? request.getActive() : true);
|
||||
user = userRepository.save(user);
|
||||
|
||||
employee = userBusinessLinkageService.ensureLinkedEmployee(user);
|
||||
return mapToResponse(employee, user);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteEmployee(Long id) {
|
||||
Employee employee = employeeRepository.findById(id)
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Employee not found with id: " + id));
|
||||
if (employee.getUserId() != null && userRepository.existsById(employee.getUserId())) {
|
||||
userRepository.deleteById(employee.getUserId());
|
||||
return;
|
||||
}
|
||||
employeeRepository.deleteById(id);
|
||||
}
|
||||
|
||||
private EmployeeResponse mapToResponse(Employee employee) {
|
||||
User user = requireLinkedUser(employee);
|
||||
return mapToResponse(employee, user);
|
||||
}
|
||||
|
||||
private EmployeeResponse mapToResponse(Employee employee, User user) {
|
||||
EmployeeResponse response = new EmployeeResponse();
|
||||
response.setEmployeeId(employee.getEmployeeId());
|
||||
response.setUserId(user.getId());
|
||||
response.setUsername(user.getUsername());
|
||||
response.setFirstName(employee.getFirstName());
|
||||
response.setLastName(employee.getLastName());
|
||||
response.setFullName(user.getFullName());
|
||||
response.setEmail(user.getEmail());
|
||||
response.setPhone(user.getPhone());
|
||||
response.setRole(user.getRole().name());
|
||||
response.setActive(user.getActive());
|
||||
response.setCreatedAt(employee.getCreatedAt());
|
||||
response.setUpdatedAt(employee.getUpdatedAt());
|
||||
return response;
|
||||
}
|
||||
|
||||
private User requireLinkedUser(Employee employee) {
|
||||
if (employee.getUserId() == null) {
|
||||
throw new ResourceNotFoundException("Employee user account not found");
|
||||
}
|
||||
return userRepository.findById(employee.getUserId())
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Employee user account not found"));
|
||||
}
|
||||
|
||||
private void validateRole(User.Role role) {
|
||||
if (role != User.Role.STAFF && role != User.Role.ADMIN) {
|
||||
throw new IllegalArgumentException("Employee role must be STAFF or ADMIN");
|
||||
}
|
||||
}
|
||||
|
||||
private String fullName(EmployeeRequest request) {
|
||||
return (request.getFirstName().trim() + " " + request.getLastName().trim()).trim();
|
||||
}
|
||||
|
||||
private String trimToNull(String value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
String trimmed = value.trim();
|
||||
return trimmed.isEmpty() ? null : trimmed;
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,6 @@ public class UserBusinessLinkageService {
|
||||
newEmployee.setFirstName(nameParts[0]);
|
||||
newEmployee.setLastName(nameParts[1]);
|
||||
|
||||
newEmployee.setPhone(normalizePhone(user.getPhone(), "000-000-0000"));
|
||||
newEmployee.setIsActive(true);
|
||||
|
||||
if (user.getRole() == User.Role.ADMIN) {
|
||||
@@ -91,8 +90,6 @@ public class UserBusinessLinkageService {
|
||||
newCustomer.setFirstName(nameParts[0]);
|
||||
newCustomer.setLastName(nameParts[1]);
|
||||
|
||||
newCustomer.setPhone(normalizePhone(user.getPhone(), "000-000-0001"));
|
||||
|
||||
return syncCustomer(newCustomer, user);
|
||||
}
|
||||
|
||||
@@ -111,7 +108,6 @@ public class UserBusinessLinkageService {
|
||||
String[] nameParts = splitFullName(user.getFullName());
|
||||
employee.setFirstName(nameParts[0]);
|
||||
employee.setLastName(nameParts[1]);
|
||||
employee.setPhone(normalizePhone(user.getPhone(), employee.getPhone()));
|
||||
if (user.getRole() == User.Role.ADMIN) {
|
||||
employee.setRole("Manager");
|
||||
} else {
|
||||
@@ -126,17 +122,9 @@ public class UserBusinessLinkageService {
|
||||
String[] nameParts = splitFullName(user.getFullName());
|
||||
customer.setFirstName(nameParts[0]);
|
||||
customer.setLastName(nameParts[1]);
|
||||
customer.setPhone(normalizePhone(user.getPhone(), customer.getPhone()));
|
||||
return customerRepository.save(customer);
|
||||
}
|
||||
|
||||
private String normalizePhone(String phone, String fallback) {
|
||||
if (phone == null || phone.trim().isEmpty()) {
|
||||
return fallback;
|
||||
}
|
||||
return phone.trim();
|
||||
}
|
||||
|
||||
private String[] splitFullName(String fullName) {
|
||||
if (fullName == null || fullName.trim().isEmpty()) {
|
||||
return new String[]{"System", "User"};
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
UPDATE users u
|
||||
LEFT JOIN customer c ON c.user_id = u.id
|
||||
LEFT JOIN employee e ON e.user_id = u.id
|
||||
SET u.phone = COALESCE(NULLIF(u.phone, ''), NULLIF(c.phone, ''), NULLIF(e.phone, ''))
|
||||
WHERE u.phone IS NULL OR u.phone = '';
|
||||
|
||||
ALTER TABLE customer
|
||||
DROP COLUMN phone;
|
||||
|
||||
ALTER TABLE employee
|
||||
DROP COLUMN phone;
|
||||
Reference in New Issue
Block a user