SalesTargetQueryServiceImpl.java
package com.deveagles.be15_deveagles_be.features.staffsales.query.service.impl;
import com.deveagles.be15_deveagles_be.features.staffsales.command.application.dto.StaffSalesTargetInfo;
import com.deveagles.be15_deveagles_be.features.staffsales.command.application.dto.request.GetSalesTargetRequest;
import com.deveagles.be15_deveagles_be.features.staffsales.command.application.dto.response.SalesTargetListResult;
import com.deveagles.be15_deveagles_be.features.staffsales.command.application.dto.response.StaffSimpleInfo;
import com.deveagles.be15_deveagles_be.features.staffsales.command.domain.aggregate.SalesTarget;
import com.deveagles.be15_deveagles_be.features.staffsales.command.domain.aggregate.StaffSalesSettingType;
import com.deveagles.be15_deveagles_be.features.staffsales.query.repository.SalesTargetQueryRepository;
import com.deveagles.be15_deveagles_be.features.staffsales.query.service.SalesTargetQueryService;
import com.deveagles.be15_deveagles_be.features.users.command.domain.aggregate.Staff;
import com.deveagles.be15_deveagles_be.features.users.command.repository.UserRepository;
import java.time.Month;
import java.time.Year;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Slf4j
@Service
@RequiredArgsConstructor
public class SalesTargetQueryServiceImpl implements SalesTargetQueryService {
private final UserRepository userRepository;
private final SalesTargetQueryRepository salesTargetQueryRepository;
@Override
public SalesTargetListResult getSalesTarget(Long shopId, GetSalesTargetRequest request) {
Year year = Year.of(request.targetDate().getYear());
Month month = request.targetDate().getMonth();
// 1. 직원 목록
List<Staff> staffList = userRepository.findByShopIdAndLeftDateIsNull(shopId);
List<StaffSimpleInfo> staffInfos =
staffList.stream()
.map(
staff ->
StaffSimpleInfo.builder()
.staffId(staff.getStaffId())
.staffName(staff.getStaffName())
.build())
.toList();
// 2. 해당 년월의 목표 매출 조회
List<SalesTarget> targetList =
salesTargetQueryRepository.findAppliedTargets(shopId, year, month);
// 3. 일괄 설정 확인
boolean hasOnlyBulk = targetList.stream().allMatch(t -> t.getStaffId() == null);
StaffSalesSettingType settingType =
hasOnlyBulk ? StaffSalesSettingType.BULK : StaffSalesSettingType.STAFF;
// 4. 일괄 설정 Target 추출
Map<String, Integer> defaultTargets = new HashMap<>();
targetList.stream()
.filter(t -> t.getStaffId() == null)
.forEach(
t -> {
if (Boolean.TRUE.equals(t.isItems())) defaultTargets.put("items", t.getSales());
if (Boolean.TRUE.equals(t.isMembership()))
defaultTargets.put("membership", t.getSales());
});
// 5. 개별 설정 Target 추출
Map<Long, Map<String, Integer>> personalTargets = new HashMap<>();
targetList.stream()
.filter(t -> t.getStaffId() != null)
.forEach(
t -> {
Long staffId = t.getStaffId();
personalTargets.putIfAbsent(staffId, new HashMap<>());
if (Boolean.TRUE.equals(t.isItems()))
personalTargets.get(staffId).put("items", t.getSales());
if (Boolean.TRUE.equals(t.isMembership()))
personalTargets.get(staffId).put("membership", t.getSales());
});
// 6. 직원별 targetAmount
List<StaffSalesTargetInfo> salesTargetInfos =
staffList.stream()
.map(
staff -> {
Map<String, Integer> targetAmounts = new HashMap<>();
// 우선순위 적용
if (personalTargets.containsKey(staff.getStaffId())) {
targetAmounts = personalTargets.get(staff.getStaffId());
} else {
targetAmounts.put("items", defaultTargets.getOrDefault("items", 0));
targetAmounts.put("membership", defaultTargets.getOrDefault("membership", 0));
}
return StaffSalesTargetInfo.builder()
.staffId(staff.getStaffId())
.targetAmounts(targetAmounts)
.build();
})
.toList();
return SalesTargetListResult.builder()
.targetYear(year)
.targetMonth(month)
.type(settingType)
.staffList(staffInfos)
.salesTargetInfos(salesTargetInfos)
.build();
}
}