LeaveCommandService.java
package com.deveagles.be15_deveagles_be.features.schedules.command.application.service;
import com.deveagles.be15_deveagles_be.common.exception.BusinessException;
import com.deveagles.be15_deveagles_be.common.exception.ErrorCode;
import com.deveagles.be15_deveagles_be.features.schedules.command.application.dto.request.*;
import com.deveagles.be15_deveagles_be.features.schedules.command.domain.aggregate.Leave;
import com.deveagles.be15_deveagles_be.features.schedules.command.domain.aggregate.RegularLeave;
import com.deveagles.be15_deveagles_be.features.schedules.command.domain.aggregate.ScheduleType;
import com.deveagles.be15_deveagles_be.features.schedules.command.domain.repository.LeaveRepository;
import com.deveagles.be15_deveagles_be.features.schedules.command.domain.repository.RegularLeaveRepository;
import java.util.*;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@RequiredArgsConstructor
public class LeaveCommandService {
private final LeaveRepository leaveRepository;
private final RegularLeaveRepository regularLeaveRepository;
@Transactional
public Long createLeave(Long shopId, CreateLeaveRequest request) {
Leave leave =
Leave.builder()
.staffId(request.staffId())
.shopId(shopId)
.leaveTitle(request.leaveTitle())
.leaveAt(request.leaveAt())
.leaveMemo(request.leaveMemo())
.build();
return leaveRepository.save(leave).getLeaveId();
}
@Transactional
public void updateLeave(Long shopId, Long leaveId, UpdateLeaveRequest request) {
Leave leave =
leaveRepository
.findById(leaveId)
.orElseThrow(() -> new BusinessException(ErrorCode.LEAVE_NOT_FOUND));
leave.update(request.leaveTitle(), request.leaveAt(), request.leaveMemo());
}
@Transactional
public Long createRegularLeave(Long shopId, CreateRegularLeaveRequest request) {
boolean hasMonthly = request.monthlyLeave() != null;
boolean hasWeekly = request.weeklyLeave() != null;
if (hasMonthly == hasWeekly) {
throw new BusinessException(ErrorCode.INVALID_SCHEDULE_REPEAT_TYPE);
}
RegularLeave regularLeave =
RegularLeave.builder()
.staffId(request.staffId())
.shopId(shopId)
.regularLeaveTitle(request.regularLeaveTitle())
.monthlyLeave(request.monthlyLeave())
.weeklyLeave(request.weeklyLeave())
.regularLeaveMemo(request.regularLeaveMemo())
.build();
return regularLeaveRepository.save(regularLeave).getRegularLeaveId();
}
@Transactional
public void updateRegularLeave(
Long shopId, Long regularLeaveId, UpdateRegularLeaveRequest request) {
RegularLeave regularLeave =
regularLeaveRepository
.findById(regularLeaveId)
.orElseThrow(() -> new BusinessException(ErrorCode.REGULAR_LEAVE_NOT_FOUND));
regularLeave.update(
request.regularLeaveTitle(),
request.monthlyLeave(),
request.weeklyLeave(),
request.regularLeaveMemo());
}
@Transactional
public void deleteMixedLeaves(Long shopId, List<DeleteScheduleRequest> requests) {
if (requests == null || requests.isEmpty()) return;
List<Long> leaveIds = new ArrayList<>();
List<Long> regularLeaveIds = new ArrayList<>();
for (DeleteScheduleRequest req : requests) {
String type = req.type().toLowerCase(Locale.ROOT);
if ("leave".equals(type)) {
leaveIds.add(req.id());
} else if ("regular_leave".equals(type)) {
regularLeaveIds.add(req.id());
} else {
throw new BusinessException(ErrorCode.INVALID_SCHEDULE_TYPE);
}
}
if (!leaveIds.isEmpty()) {
List<Leave> leaves = leaveRepository.findAllById(leaveIds);
if (leaves.size() != leaveIds.size()) {
throw new BusinessException(ErrorCode.LEAVE_NOT_FOUND);
}
leaveRepository.deleteAllInBatch(leaves);
}
if (!regularLeaveIds.isEmpty()) {
List<RegularLeave> regularLeaves = regularLeaveRepository.findAllById(regularLeaveIds);
if (regularLeaves.size() != regularLeaveIds.size()) {
throw new BusinessException(ErrorCode.REGULAR_LEAVE_NOT_FOUND);
}
regularLeaveRepository.deleteAllInBatch(regularLeaves);
}
}
@Transactional
public void switchSchedule(Long shopId, UpdateLeaveScheduleRequest request) {
ScheduleType fromType = request.fromType();
ScheduleType toType = request.toType();
if (fromType == toType) {
switch (fromType) {
case LEAVE ->
updateLeave(shopId, request.fromId(), request.leaveRequest().toUpdateRequest());
case REGULAR_LEAVE ->
updateRegularLeave(
shopId, request.fromId(), request.regularLeaveRequest().toUpdateRequest());
default -> throw new BusinessException(ErrorCode.INVALID_SCHEDULE_TYPE);
}
return;
}
switch (fromType) {
case LEAVE -> {
if (!leaveRepository.existsById(request.fromId())) {
throw new BusinessException(ErrorCode.LEAVE_NOT_FOUND);
}
leaveRepository.deleteById(request.fromId());
}
case REGULAR_LEAVE -> {
if (!regularLeaveRepository.existsById(request.fromId())) {
throw new BusinessException(ErrorCode.REGULAR_LEAVE_NOT_FOUND);
}
regularLeaveRepository.deleteById(request.fromId());
}
default -> throw new BusinessException(ErrorCode.INVALID_SCHEDULE_TYPE);
}
switch (toType) {
case LEAVE -> createLeave(shopId, request.leaveRequest());
case REGULAR_LEAVE -> createRegularLeave(shopId, request.regularLeaveRequest());
default -> throw new BusinessException(ErrorCode.INVALID_SCHEDULE_TYPE);
}
}
}