Files
SR-SYSTEM/backend/src/main/java/com/srsystem/service/EmployeeService.java
T

233 lines
9.1 KiB
Java

package com.srsystem.service;
import com.srsystem.dto.ChangePasswordRequest;
import com.srsystem.dto.EmployeeSearchResult;
import com.srsystem.dto.EmployeeSummary;
import com.srsystem.entity.Employee;
import com.srsystem.entity.EmployeeEmergencyContact;
import com.srsystem.entity.enums.DispatchStatus;
import com.srsystem.entity.enums.EmpStatus;
import com.srsystem.entity.enums.RoleCode;
import com.srsystem.exception.BusinessException;
import com.srsystem.exception.ErrorCode;
import org.springframework.dao.DataIntegrityViolationException;
import com.srsystem.repository.DispatchHistoryRepository;
import com.srsystem.repository.EmployeeEmergencyContactRepository;
import com.srsystem.repository.EmployeeRepository;
import lombok.RequiredArgsConstructor;
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 java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class EmployeeService {
private final EmployeeRepository employeeRepository;
private final DispatchHistoryRepository dispatchHistoryRepository;
private final EmployeeEmergencyContactRepository emergencyContactRepository;
private final PasswordEncoder passwordEncoder;
public Page<Employee> findAll(EmpStatus status, Pageable pageable) {
if (status != null) {
return employeeRepository.findByEmpStatus(status, pageable);
}
return employeeRepository.findAll(pageable);
}
public Employee findById(Long empId) {
return employeeRepository.findById(empId)
.orElseThrow(() -> new BusinessException(ErrorCode.EMPLOYEE_NOT_FOUND));
}
public Employee findByLoginId(String loginId) {
return employeeRepository.findByLoginId(loginId)
.orElseThrow(() -> new BusinessException(ErrorCode.EMPLOYEE_NOT_FOUND));
}
public List<EmployeeSearchResult> searchByName(String keyword) {
List<Employee> byName = employeeRepository.findByNameContainingIgnoreCase(keyword);
List<EmployeeSearchResult> results = new ArrayList<>();
Set<Long> seen = new HashSet<>();
for (Employee e : byName) {
if (seen.add(e.getEmpId())) {
results.add(toSearchResult(e));
}
}
return results;
}
public List<EmployeeSearchResult> getApprovers() {
return employeeRepository.findByRoleCodeIn(List.of(RoleCode.MANAGER, RoleCode.ADMIN))
.stream().map(this::toSearchResult).toList();
}
private EmployeeSearchResult toSearchResult(Employee e) {
return new EmployeeSearchResult(
e.getEmpId(),
e.getName(),
e.getEmail(),
e.getRoleCode() != null ? e.getRoleCode().name() : null,
e.getDispatchStatus() != null ? e.getDispatchStatus().name() : null
);
}
@Transactional
public Employee create(Employee employee) {
if (employee.getLoginId() == null || employee.getLoginId().isBlank()) {
throw new BusinessException(ErrorCode.INVALID_INPUT_VALUE);
}
if (employeeRepository.findByLoginId(employee.getLoginId()).isPresent()) {
throw new BusinessException(ErrorCode.DUPLICATE_LOGIN_ID);
}
if (employee.getEmail() != null && !employee.getEmail().isBlank() && employeeRepository.findByEmail(employee.getEmail()).isPresent()) {
throw new BusinessException(ErrorCode.DUPLICATE_LOGIN_ID);
}
if (employee.getRoleCode() == null) employee.setRoleCode(RoleCode.EMPLOYEE);
if (employee.getEmpStatus() == null) employee.setEmpStatus(EmpStatus.ACTIVE);
if (employee.getDispatchStatus() == null) employee.setDispatchStatus(DispatchStatus.WAITING);
String rawPassword = employee.getPassword();
if (rawPassword == null || rawPassword.isBlank()) {
rawPassword = "admin123";
}
employee.setPassword(passwordEncoder.encode(rawPassword));
try {
return employeeRepository.save(employee);
} catch (DataIntegrityViolationException e) {
throw new BusinessException(ErrorCode.DUPLICATE_LOGIN_ID);
}
}
@Transactional
public Employee update(Long empId, Employee updateRequest) {
Employee employee = findById(empId);
if (employee.getEmpStatus() == EmpStatus.RESIGNED) {
throw new BusinessException(ErrorCode.RESIGNED_EMPLOYEE);
}
employee.setName(updateRequest.getName());
employee.setEmail(updateRequest.getEmail());
employee.setPhone(updateRequest.getPhone());
employee.setJoinedDate(updateRequest.getJoinedDate());
employee.setProfileImage(updateRequest.getProfileImage());
employee.setPosition(updateRequest.getPosition());
employee.setManagerId(updateRequest.getManagerId());
employee.setBackupManagerId(updateRequest.getBackupManagerId());
return employee;
}
@Transactional
public Employee updateStatus(Long empId, EmpStatus status, String leftDate) {
Employee employee = findById(empId);
employee.setEmpStatus(status);
if (leftDate != null && !leftDate.isBlank()) {
employee.setLeftDate(LocalDate.parse(leftDate));
}
if (status == EmpStatus.RESIGNED && leftDate != null) {
employee.setLeftDate(LocalDate.parse(leftDate));
}
return employeeRepository.save(employee);
}
@Transactional
public Employee updateRole(Long empId, RoleCode role) {
Employee employee = findById(empId);
employee.setRoleCode(role);
return employeeRepository.save(employee);
}
@Transactional
public Employee updateDispatchStatus(Long empId, DispatchStatus status) {
Employee employee = findById(empId);
employee.setDispatchStatus(status);
return employeeRepository.save(employee);
}
@Transactional
public void resetPassword(Long empId, String newPassword) {
Employee employee = findById(empId);
employee.setPassword(passwordEncoder.encode(newPassword));
employeeRepository.save(employee);
}
@Transactional
public void delete(Long empId) {
Employee employee = findById(empId);
if (employee.getEmpStatus() == EmpStatus.RESIGNED) {
throw new BusinessException(ErrorCode.RESIGNED_EMPLOYEE);
}
employeeRepository.delete(employee);
}
public EmployeeSummary toSummary(Employee employee) {
return new EmployeeSummary(
employee.getEmpId(),
employee.getName(),
employee.getEmail(),
employee.getRoleCode(),
employee.getEmpStatus(),
employee.getDispatchStatus(),
employee.getJoinedDate(),
employee.getLeftDate(),
employee.getProfileImage()
);
}
// ---- Emergency Contact CRUD ----
public List<EmployeeEmergencyContact> getEmergencyContacts(Long empId) {
return emergencyContactRepository.findByEmployeeEmpIdOrderBySortOrderAsc(empId);
}
@Transactional
public EmployeeEmergencyContact createEmergencyContact(Long empId, EmployeeEmergencyContact contact) {
Employee employee = findById(empId);
contact.setEmployee(employee);
if (contact.getSortOrder() == null) contact.setSortOrder(0);
return emergencyContactRepository.save(contact);
}
@Transactional
public EmployeeEmergencyContact updateEmergencyContact(Long contactId, EmployeeEmergencyContact update) {
EmployeeEmergencyContact contact = emergencyContactRepository.findById(contactId)
.orElseThrow(() -> new BusinessException(ErrorCode.CODE_NOT_FOUND));
if (update.getName() != null) contact.setName(update.getName());
if (update.getRelation() != null) contact.setRelation(update.getRelation());
if (update.getPhone() != null) contact.setPhone(update.getPhone());
if (update.getSortOrder() != null) contact.setSortOrder(update.getSortOrder());
return emergencyContactRepository.save(contact);
}
@Transactional
public void deleteEmergencyContact(Long contactId) {
EmployeeEmergencyContact contact = emergencyContactRepository.findById(contactId)
.orElseThrow(() -> new BusinessException(ErrorCode.CODE_NOT_FOUND));
contact.setIsDeleted('Y');
emergencyContactRepository.save(contact);
}
@Transactional
public void changePassword(Long empId, ChangePasswordRequest request) {
Employee employee = findById(empId);
if (!passwordEncoder.matches(request.currentPassword(), employee.getPassword())) {
throw new BusinessException(ErrorCode.AUTH_INVALID_CREDENTIALS);
}
employee.setPassword(passwordEncoder.encode(request.newPassword()));
employeeRepository.save(employee);
}
}