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")
|
@Email(message = "Invalid email format")
|
||||||
private String email;
|
private String email;
|
||||||
|
|
||||||
private String phone;
|
|
||||||
|
|
||||||
public String getFirstName() {
|
public String getFirstName() {
|
||||||
return firstName;
|
return firstName;
|
||||||
}
|
}
|
||||||
@@ -40,14 +38,6 @@ public class CustomerRequest {
|
|||||||
this.email = email;
|
this.email = email;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPhone() {
|
|
||||||
return phone;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPhone(String phone) {
|
|
||||||
this.phone = phone;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
@@ -55,13 +45,12 @@ public class CustomerRequest {
|
|||||||
CustomerRequest that = (CustomerRequest) o;
|
CustomerRequest that = (CustomerRequest) o;
|
||||||
return Objects.equals(firstName, that.firstName) &&
|
return Objects.equals(firstName, that.firstName) &&
|
||||||
Objects.equals(lastName, that.lastName) &&
|
Objects.equals(lastName, that.lastName) &&
|
||||||
Objects.equals(email, that.email) &&
|
Objects.equals(email, that.email);
|
||||||
Objects.equals(phone, that.phone);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(firstName, lastName, email, phone);
|
return Objects.hash(firstName, lastName, email);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -70,7 +59,6 @@ public class CustomerRequest {
|
|||||||
"firstName='" + firstName + '\'' +
|
"firstName='" + firstName + '\'' +
|
||||||
", lastName='" + lastName + '\'' +
|
", lastName='" + lastName + '\'' +
|
||||||
", email='" + email + '\'' +
|
", email='" + email + '\'' +
|
||||||
", phone='" + phone + '\'' +
|
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,19 +8,17 @@ public class CustomerResponse {
|
|||||||
private String firstName;
|
private String firstName;
|
||||||
private String lastName;
|
private String lastName;
|
||||||
private String email;
|
private String email;
|
||||||
private String phone;
|
|
||||||
private LocalDateTime createdAt;
|
private LocalDateTime createdAt;
|
||||||
private LocalDateTime updatedAt;
|
private LocalDateTime updatedAt;
|
||||||
|
|
||||||
public CustomerResponse() {
|
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.customerId = customerId;
|
||||||
this.firstName = firstName;
|
this.firstName = firstName;
|
||||||
this.lastName = lastName;
|
this.lastName = lastName;
|
||||||
this.email = email;
|
this.email = email;
|
||||||
this.phone = phone;
|
|
||||||
this.createdAt = createdAt;
|
this.createdAt = createdAt;
|
||||||
this.updatedAt = updatedAt;
|
this.updatedAt = updatedAt;
|
||||||
}
|
}
|
||||||
@@ -57,14 +55,6 @@ public class CustomerResponse {
|
|||||||
this.email = email;
|
this.email = email;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPhone() {
|
|
||||||
return phone;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPhone(String phone) {
|
|
||||||
this.phone = phone;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDateTime getCreatedAt() {
|
public LocalDateTime getCreatedAt() {
|
||||||
return createdAt;
|
return createdAt;
|
||||||
}
|
}
|
||||||
@@ -86,12 +76,12 @@ public class CustomerResponse {
|
|||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
CustomerResponse that = (CustomerResponse) o;
|
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
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(customerId, firstName, lastName, email, phone, createdAt, updatedAt);
|
return Objects.hash(customerId, firstName, lastName, email, createdAt, updatedAt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -101,7 +91,6 @@ public class CustomerResponse {
|
|||||||
", firstName='" + firstName + '\'' +
|
", firstName='" + firstName + '\'' +
|
||||||
", lastName='" + lastName + '\'' +
|
", lastName='" + lastName + '\'' +
|
||||||
", email='" + email + '\'' +
|
", email='" + email + '\'' +
|
||||||
", phone='" + phone + '\'' +
|
|
||||||
", createdAt=" + createdAt +
|
", createdAt=" + createdAt +
|
||||||
", updatedAt=" + updatedAt +
|
", 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)
|
@Column(nullable = false, length = 100)
|
||||||
private String email;
|
private String email;
|
||||||
|
|
||||||
@Column(nullable = false, length = 20)
|
|
||||||
private String phone;
|
|
||||||
|
|
||||||
@CreationTimestamp
|
@CreationTimestamp
|
||||||
@Column(name = "created_at", updatable = false)
|
@Column(name = "created_at", updatable = false)
|
||||||
private LocalDateTime createdAt;
|
private LocalDateTime createdAt;
|
||||||
@@ -41,13 +38,12 @@ public class Customer {
|
|||||||
public 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.customerId = customerId;
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
this.firstName = firstName;
|
this.firstName = firstName;
|
||||||
this.lastName = lastName;
|
this.lastName = lastName;
|
||||||
this.email = email;
|
this.email = email;
|
||||||
this.phone = phone;
|
|
||||||
this.createdAt = createdAt;
|
this.createdAt = createdAt;
|
||||||
this.updatedAt = updatedAt;
|
this.updatedAt = updatedAt;
|
||||||
}
|
}
|
||||||
@@ -92,14 +88,6 @@ public class Customer {
|
|||||||
this.email = email;
|
this.email = email;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPhone() {
|
|
||||||
return phone;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPhone(String phone) {
|
|
||||||
this.phone = phone;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDateTime getCreatedAt() {
|
public LocalDateTime getCreatedAt() {
|
||||||
return createdAt;
|
return createdAt;
|
||||||
}
|
}
|
||||||
@@ -137,7 +125,6 @@ public class Customer {
|
|||||||
", firstName='" + firstName + '\'' +
|
", firstName='" + firstName + '\'' +
|
||||||
", lastName='" + lastName + '\'' +
|
", lastName='" + lastName + '\'' +
|
||||||
", email='" + email + '\'' +
|
", email='" + email + '\'' +
|
||||||
", phone='" + phone + '\'' +
|
|
||||||
", createdAt=" + createdAt +
|
", createdAt=" + createdAt +
|
||||||
", updatedAt=" + updatedAt +
|
", updatedAt=" + updatedAt +
|
||||||
'}';
|
'}';
|
||||||
|
|||||||
@@ -27,9 +27,6 @@ public class Employee {
|
|||||||
@Column(nullable = false, length = 100)
|
@Column(nullable = false, length = 100)
|
||||||
private String email;
|
private String email;
|
||||||
|
|
||||||
@Column(nullable = false, length = 20)
|
|
||||||
private String phone;
|
|
||||||
|
|
||||||
@Column(nullable = false, length = 50)
|
@Column(nullable = false, length = 50)
|
||||||
private String role;
|
private String role;
|
||||||
|
|
||||||
@@ -47,13 +44,12 @@ public class Employee {
|
|||||||
public 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.employeeId = employeeId;
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
this.firstName = firstName;
|
this.firstName = firstName;
|
||||||
this.lastName = lastName;
|
this.lastName = lastName;
|
||||||
this.email = email;
|
this.email = email;
|
||||||
this.phone = phone;
|
|
||||||
this.role = role;
|
this.role = role;
|
||||||
this.isActive = isActive;
|
this.isActive = isActive;
|
||||||
this.createdAt = createdAt;
|
this.createdAt = createdAt;
|
||||||
@@ -100,14 +96,6 @@ public class Employee {
|
|||||||
this.email = email;
|
this.email = email;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPhone() {
|
|
||||||
return phone;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPhone(String phone) {
|
|
||||||
this.phone = phone;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRole() {
|
public String getRole() {
|
||||||
return role;
|
return role;
|
||||||
}
|
}
|
||||||
@@ -161,7 +149,6 @@ public class Employee {
|
|||||||
", firstName='" + firstName + '\'' +
|
", firstName='" + firstName + '\'' +
|
||||||
", lastName='" + lastName + '\'' +
|
", lastName='" + lastName + '\'' +
|
||||||
", email='" + email + '\'' +
|
", email='" + email + '\'' +
|
||||||
", phone='" + phone + '\'' +
|
|
||||||
", role='" + role + '\'' +
|
", role='" + role + '\'' +
|
||||||
", isActive=" + isActive +
|
", isActive=" + isActive +
|
||||||
", createdAt=" + createdAt +
|
", createdAt=" + createdAt +
|
||||||
|
|||||||
@@ -21,6 +21,6 @@ public interface CustomerRepository extends JpaRepository<Customer, Long> {
|
|||||||
"LOWER(c.firstName) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
|
"LOWER(c.firstName) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
|
||||||
"LOWER(c.lastName) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
|
"LOWER(c.lastName) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
|
||||||
"LOWER(c.email) 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);
|
Page<Customer> searchCustomers(@Param("q") String query, Pageable pageable);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
package com.petshop.backend.repository;
|
package com.petshop.backend.repository;
|
||||||
|
|
||||||
import com.petshop.backend.entity.Employee;
|
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.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.Query;
|
||||||
|
import org.springframework.data.repository.query.Param;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -11,4 +15,14 @@ import java.util.Optional;
|
|||||||
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
|
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
|
||||||
Optional<Employee> findByUserId(Long userId);
|
Optional<Employee> findByUserId(Long userId);
|
||||||
List<Employee> findAllByEmail(String email);
|
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.setFirstName(request.getFirstName());
|
||||||
customer.setLastName(request.getLastName());
|
customer.setLastName(request.getLastName());
|
||||||
customer.setEmail(request.getEmail());
|
customer.setEmail(request.getEmail());
|
||||||
customer.setPhone(request.getPhone());
|
|
||||||
|
|
||||||
customer = customerRepository.save(customer);
|
customer = customerRepository.save(customer);
|
||||||
syncLinkedUser(customer);
|
syncLinkedUser(customer);
|
||||||
@@ -60,7 +59,6 @@ public class CustomerService {
|
|||||||
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.setPhone(request.getPhone());
|
|
||||||
|
|
||||||
customer = customerRepository.save(customer);
|
customer = customerRepository.save(customer);
|
||||||
syncLinkedUser(customer);
|
syncLinkedUser(customer);
|
||||||
@@ -86,7 +84,6 @@ public class CustomerService {
|
|||||||
customer.getFirstName(),
|
customer.getFirstName(),
|
||||||
customer.getLastName(),
|
customer.getLastName(),
|
||||||
customer.getEmail(),
|
customer.getEmail(),
|
||||||
customer.getPhone(),
|
|
||||||
customer.getCreatedAt(),
|
customer.getCreatedAt(),
|
||||||
customer.getUpdatedAt()
|
customer.getUpdatedAt()
|
||||||
);
|
);
|
||||||
@@ -98,7 +95,6 @@ public class CustomerService {
|
|||||||
}
|
}
|
||||||
userRepository.findById(customer.getUserId()).ifPresent(user -> {
|
userRepository.findById(customer.getUserId()).ifPresent(user -> {
|
||||||
user.setEmail(customer.getEmail());
|
user.setEmail(customer.getEmail());
|
||||||
user.setPhone(customer.getPhone());
|
|
||||||
user.setFullName((customer.getFirstName() + " " + customer.getLastName()).trim());
|
user.setFullName((customer.getFirstName() + " " + customer.getLastName()).trim());
|
||||||
userRepository.save(user);
|
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.setFirstName(nameParts[0]);
|
||||||
newEmployee.setLastName(nameParts[1]);
|
newEmployee.setLastName(nameParts[1]);
|
||||||
|
|
||||||
newEmployee.setPhone(normalizePhone(user.getPhone(), "000-000-0000"));
|
|
||||||
newEmployee.setIsActive(true);
|
newEmployee.setIsActive(true);
|
||||||
|
|
||||||
if (user.getRole() == User.Role.ADMIN) {
|
if (user.getRole() == User.Role.ADMIN) {
|
||||||
@@ -91,8 +90,6 @@ public class UserBusinessLinkageService {
|
|||||||
newCustomer.setFirstName(nameParts[0]);
|
newCustomer.setFirstName(nameParts[0]);
|
||||||
newCustomer.setLastName(nameParts[1]);
|
newCustomer.setLastName(nameParts[1]);
|
||||||
|
|
||||||
newCustomer.setPhone(normalizePhone(user.getPhone(), "000-000-0001"));
|
|
||||||
|
|
||||||
return syncCustomer(newCustomer, user);
|
return syncCustomer(newCustomer, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,7 +108,6 @@ public class UserBusinessLinkageService {
|
|||||||
String[] nameParts = splitFullName(user.getFullName());
|
String[] nameParts = splitFullName(user.getFullName());
|
||||||
employee.setFirstName(nameParts[0]);
|
employee.setFirstName(nameParts[0]);
|
||||||
employee.setLastName(nameParts[1]);
|
employee.setLastName(nameParts[1]);
|
||||||
employee.setPhone(normalizePhone(user.getPhone(), employee.getPhone()));
|
|
||||||
if (user.getRole() == User.Role.ADMIN) {
|
if (user.getRole() == User.Role.ADMIN) {
|
||||||
employee.setRole("Manager");
|
employee.setRole("Manager");
|
||||||
} else {
|
} else {
|
||||||
@@ -126,17 +122,9 @@ public class UserBusinessLinkageService {
|
|||||||
String[] nameParts = splitFullName(user.getFullName());
|
String[] nameParts = splitFullName(user.getFullName());
|
||||||
customer.setFirstName(nameParts[0]);
|
customer.setFirstName(nameParts[0]);
|
||||||
customer.setLastName(nameParts[1]);
|
customer.setLastName(nameParts[1]);
|
||||||
customer.setPhone(normalizePhone(user.getPhone(), customer.getPhone()));
|
|
||||||
return customerRepository.save(customer);
|
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) {
|
private String[] splitFullName(String fullName) {
|
||||||
if (fullName == null || fullName.trim().isEmpty()) {
|
if (fullName == null || fullName.trim().isEmpty()) {
|
||||||
return new String[]{"System", "User"};
|
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