Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;


@Slf4j
Expand Down Expand Up @@ -105,4 +109,31 @@ public IncentiveListOutDto getIncentiveList(IncentiveListInDto inDto) {
.build();
}

// 파트너 UUID 목록별 총 인센티브 합계 조회 (EARN/REVERSAL 포함, 순합)
public Map<UUID, BigDecimal> getTotalIncentiveByPartnerUuids(List<UUID> partnerUuids) {
if (partnerUuids == null || partnerUuids.isEmpty()) {
return Map.of();
}

var totalIncentiveSum = qIncentive.totalIncentive.sum();

List<Tuple> tuples = queryFactory
.select(qIncentive.partnerUuid, totalIncentiveSum)
.from(qIncentive)
.where(qIncentive.partnerUuid.in(partnerUuids))
.groupBy(qIncentive.partnerUuid)
.fetch();

Map<UUID, BigDecimal> result = new HashMap<>();
for (Tuple tuple : tuples) {
UUID partnerUuid = tuple.get(qIncentive.partnerUuid);
BigDecimal totalIncentive = tuple.get(totalIncentiveSum);
if (partnerUuid != null) {
result.put(partnerUuid, totalIncentive == null ? BigDecimal.ZERO : totalIncentive);
}
}

return result;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Repository;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;

Expand Down Expand Up @@ -94,6 +96,13 @@ public List<Incentive> findByPartnerUuidAndIncentiveKind(UUID partnerUuid, Incen
}


// 파트너 UUID 목록별 총 인센티브 합계 조회 (EARN/REVERSAL 포함, 순합)
@Override
public Map<UUID, BigDecimal> getTotalIncentiveByPartnerUuids(List<UUID> partnerUuids) {
return incentiveQuerydslRepository.getTotalIncentiveByPartnerUuids(partnerUuids);
}


// 이미 REVERSAL이 존재하는지 확인 (idempotency)
@Override
public boolean existsByReversalOfIncentiveId(Long originalIncentiveId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
import greenfirst.be.incentive.domain.enums.IncentiveKind;
import greenfirst.be.incentive.domain.model.Incentive;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;

Expand Down Expand Up @@ -34,6 +36,9 @@ public interface IncentiveQueryRepository {
// 파트너 UUID + 인센티브 종류로 조회
List<Incentive> findByPartnerUuidAndIncentiveKind(UUID partnerUuid, IncentiveKind incentiveKind);

// 파트너 UUID 목록별 총 인센티브 합계 조회 (EARN/REVERSAL 포함, 순합)
Map<UUID, BigDecimal> getTotalIncentiveByPartnerUuids(List<UUID> partnerUuids);

// 이미 REVERSAL이 존재하는지 확인 (idempotency)
boolean existsByReversalOfIncentiveId(Long originalIncentiveId);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.modelmapper.ModelMapper;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
Expand All @@ -27,8 +26,6 @@ public class GetRelationshipDataController {

// facade
private final PartnerRelationshipFacade partnerRelationshipFacade;
// util
private final ModelMapper modelMapper;


/**
Expand All @@ -47,7 +44,7 @@ public BaseResponse<PartnerRelationshipResponse> getPartnerRelationshipData(@Pat
PartnerRelationshipOutDto outDto = partnerRelationshipFacade.getPartnerRelationshipData(partnerUuid);

// result
PartnerRelationshipResponse response = modelMapper.map(outDto, PartnerRelationshipResponse.class);
PartnerRelationshipResponse response = PartnerRelationshipResponse.from(outDto);
return new BaseResponse<>(response);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@


import greenfirst.be.user.application.dto.out.Level1DownlineData;
import greenfirst.be.user.application.dto.out.PartnerRelationshipOutDto;
import greenfirst.be.user.application.dto.out.ReferrerData;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.List;
import java.util.Objects;


@Getter
@NoArgsConstructor
public class PartnerRelationshipResponse {

/**
Expand All @@ -21,4 +26,18 @@ public class PartnerRelationshipResponse {
private ReferrerData referrerData;
private List<Level1DownlineData> level1Downlines;

@Builder(toBuilder = true)
public PartnerRelationshipResponse(ReferrerData referrerData, List<Level1DownlineData> level1Downlines) {
this.referrerData = referrerData;
this.level1Downlines = level1Downlines;
}

public static PartnerRelationshipResponse from(PartnerRelationshipOutDto outDto) {
Objects.requireNonNull(outDto, "partnerRelationshipOutDto must not be null");
return PartnerRelationshipResponse.builder()
.referrerData(outDto.getReferrerData())
.level1Downlines(outDto.getLevel1Downlines())
.build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package greenfirst.be.user.adapter.out.persistence.repository.incentive;


import greenfirst.be.incentive.application.port.out.IncentiveQueryRepository;
import greenfirst.be.user.application.port.out.incentive.IncentiveTotalQueryPort;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.UUID;


@Repository
@RequiredArgsConstructor
public class IncentiveTotalQueryPortImpl implements IncentiveTotalQueryPort {

private final IncentiveQueryRepository incentiveQueryRepository;

@Override
public Map<UUID, BigDecimal> getTotalIncentiveByPartnerUuids(List<UUID> partnerUuids) {
return incentiveQueryRepository.getTotalIncentiveByPartnerUuids(partnerUuids);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.math.BigDecimal;
import java.util.UUID;


Expand All @@ -18,5 +19,6 @@ public class PartnerData {
private UUID partnerUuid;
private String partnerName;
private String partnerPhoneNumber;
private BigDecimal totalIncentive;

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import greenfirst.be.user.application.dto.out.PartnerData;
import greenfirst.be.user.application.dto.out.PartnerRelationshipOutDto;
import greenfirst.be.user.application.dto.out.ReferrerData;
import greenfirst.be.user.application.port.out.incentive.IncentiveTotalQueryPort;
import greenfirst.be.user.application.service.GetPartnerRelationshipDataService;
import greenfirst.be.user.application.service.GetUserDataService;
import greenfirst.be.user.domain.model.PartnerRelationship;
Expand All @@ -16,10 +17,12 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Stream;


@Slf4j
Expand All @@ -30,6 +33,7 @@ public class PartnerRelationshipFacade {
// service
private final GetUserDataService getUserDataService;
private final GetPartnerRelationshipDataService getPartnerRelationshipDataService;
private final IncentiveTotalQueryPort incentiveTotalQueryPort;
// domain service
private final PartnerRelationshipAssembler partnerRelationshipAssembler;

Expand Down Expand Up @@ -107,16 +111,28 @@ private List<Level1DownlineData> getDownlinesData(UUID partnerUuid) {
List<UUID> level2Uuids = partnerRelationshipAssembler.extractAllLevel2DownlineUuids(level2RelationshipMap);
List<Users> level2Partners = getUserDataService.getUsersByUuidInList(level2Uuids);

// 1차 + 2차 파트너 UUID 목록 합치기
List<UUID> allDownlineUuids = Stream.concat(
level1Partners.stream().map(Users::getUserUuid),
level2Partners.stream().map(Users::getUserUuid)
)
.distinct()
.toList();

// 파트너별 총 인센티브 합계 조회 (EARN/REVERSAL 포함, 순합)
Map<UUID, BigDecimal> totalIncentiveByPartnerUuid = incentiveTotalQueryPort.getTotalIncentiveByPartnerUuids(allDownlineUuids);

// 1차, 2차 하위 파트너 매핑
return this.mappingDownlinesData(level1Partners, level2Partners, level2RelationshipMap);
return this.mappingDownlinesData(level1Partners, level2Partners, level2RelationshipMap, totalIncentiveByPartnerUuid);
}


// Level1DownlineData 매핑
private List<Level1DownlineData> mappingDownlinesData(
List<Users> level1Partners,
List<Users> level2Partners,
Map<UUID, List<PartnerRelationship>> level2RelationshipMap
Map<UUID, List<PartnerRelationship>> level2RelationshipMap,
Map<UUID, BigDecimal> totalIncentiveByPartnerUuid
) {
// 2차 파트너 UUID -> Users 맵 생성
Map<UUID, Users> level2PartnerMap = partnerRelationshipAssembler.buildPartnerMap(level2Partners);
Expand All @@ -130,13 +146,15 @@ private List<Level1DownlineData> mappingDownlinesData(
.partnerUuid(level1Partner.getUserUuid())
.partnerName(level1Partner.getUserName())
.partnerPhoneNumber(level1Partner.getUserPhoneNumber())
.totalIncentive(totalIncentiveByPartnerUuid.getOrDefault(level1Partner.getUserUuid(), BigDecimal.ZERO))
.build();

// 1차 파트너의 2차 하위 파트너 목록 조회
List<PartnerData> level2Downlines = this.mapLevel2Downlines(
level1Partner.getUserUuid(),
level2RelationshipMap,
level2PartnerMap
level2PartnerMap,
totalIncentiveByPartnerUuid
);

// Level1DownlineData 생성
Expand All @@ -150,7 +168,8 @@ private List<Level1DownlineData> mappingDownlinesData(
private List<PartnerData> mapLevel2Downlines(
UUID level1PartnerUuid,
Map<UUID, List<PartnerRelationship>> level2RelationshipMap,
Map<UUID, Users> level2PartnerMap
Map<UUID, Users> level2PartnerMap,
Map<UUID, BigDecimal> totalIncentiveByPartnerUuid
) {
return level2RelationshipMap
.getOrDefault(level1PartnerUuid, List.of()) // 1차 파트너 UUID에 해당하는 2차 관계 목록 조회
Expand All @@ -163,6 +182,7 @@ private List<PartnerData> mapLevel2Downlines(
.partnerUuid(user.getUserUuid())
.partnerName(user.getUserName())
.partnerPhoneNumber(user.getUserPhoneNumber())
.totalIncentive(totalIncentiveByPartnerUuid.getOrDefault(user.getUserUuid(), BigDecimal.ZERO))
.build();
})
.toList();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package greenfirst.be.user.application.port.out.incentive;


import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.UUID;


public interface IncentiveTotalQueryPort {

// 파트너 UUID 목록별 총 인센티브 합계 조회 (EARN/REVERSAL 포함, 순합)
Map<UUID, BigDecimal> getTotalIncentiveByPartnerUuids(List<UUID> partnerUuids);

}
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,11 @@ public List<Incentive> findByPartnerUuidAndIncentiveKind(UUID partnerUuid, Incen
.toList();
}

@Override
public Map<UUID, BigDecimal> getTotalIncentiveByPartnerUuids(List<UUID> partnerUuids) {
return Map.of();
}

@Override
public boolean existsByReversalOfIncentiveId(Long originalIncentiveId) {
return storage.values().stream()
Expand Down
Loading