diff --git a/src/main/java/com/connect/accountApp/domain/expense/adapter/in/web/controller/GetDailyTotalExpensesController.java b/src/main/java/com/connect/accountApp/domain/expense/adapter/in/web/controller/GetDailyTotalExpensesController.java index faba2cb..f155abc 100644 --- a/src/main/java/com/connect/accountApp/domain/expense/adapter/in/web/controller/GetDailyTotalExpensesController.java +++ b/src/main/java/com/connect/accountApp/domain/expense/adapter/in/web/controller/GetDailyTotalExpensesController.java @@ -18,7 +18,7 @@ @RestController @RequestMapping("/api/v1/expense") @RequiredArgsConstructor -public class GetDailyTotalExpensesController { +public class GetDailyTotalExpensesController { // 월별 지출 캘린더 private final GetDailyTotalExpensesOfHouseholdUseCase getDailyTotalExpensesOfHouseholdUseCase; diff --git a/src/main/java/com/connect/accountApp/domain/expense/adapter/in/web/controller/GetExpenseController.java b/src/main/java/com/connect/accountApp/domain/expense/adapter/in/web/controller/GetExpenseController.java index c4d1a21..459ef86 100644 --- a/src/main/java/com/connect/accountApp/domain/expense/adapter/in/web/controller/GetExpenseController.java +++ b/src/main/java/com/connect/accountApp/domain/expense/adapter/in/web/controller/GetExpenseController.java @@ -1,15 +1,9 @@ package com.connect.accountApp.domain.expense.adapter.in.web.controller; -import com.connect.accountApp.domain.expense.adapter.in.web.controller.response.DailyExpenseResponse; import com.connect.accountApp.domain.expense.adapter.in.web.controller.response.GetExpenseResponse; import com.connect.accountApp.domain.expense.application.port.in.GetExpenseUseCase; -import com.connect.accountApp.domain.expense.application.port.in.command.DailyExpenseCommand; import com.connect.accountApp.domain.expense.domain.model.Expense; import com.connect.accountApp.global.common.adapter.in.web.response.SuccessResponse; -import jakarta.validation.constraints.Min; -import jakarta.validation.constraints.Size; -import java.time.LocalDate; -import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; diff --git a/src/main/java/com/connect/accountApp/domain/expense/adapter/in/web/controller/RegisterExpenseController.java b/src/main/java/com/connect/accountApp/domain/expense/adapter/in/web/controller/RegisterExpenseController.java index 287aabc..2765a55 100644 --- a/src/main/java/com/connect/accountApp/domain/expense/adapter/in/web/controller/RegisterExpenseController.java +++ b/src/main/java/com/connect/accountApp/domain/expense/adapter/in/web/controller/RegisterExpenseController.java @@ -4,6 +4,7 @@ import com.connect.accountApp.domain.expense.application.port.in.RegisterExpenseUseCase; import com.connect.accountApp.global.common.adapter.in.web.response.SuccessResponse; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.security.core.userdetails.UserDetails; @@ -15,15 +16,17 @@ @RestController @RequestMapping("/api/v1/expense") @RequiredArgsConstructor +@Slf4j public class RegisterExpenseController { private final RegisterExpenseUseCase registerExpenseUseCase; - @PostMapping("") public ResponseEntity registerExpense(@AuthenticationPrincipal UserDetails userDetails, @RequestBody RegisterExpenseRequest request) { + log.info("[controller] : {}", "RegisterExpenseController"); + String userEmail = userDetails.getUsername(); Long expenseId = registerExpenseUseCase.registerExpense(userEmail, request); return ResponseEntity.ok(SuccessResponse.create201CreatedResponse(expenseId)); diff --git a/src/main/java/com/connect/accountApp/domain/expense/adapter/in/web/controller/response/DailyExpenseResponse.java b/src/main/java/com/connect/accountApp/domain/expense/adapter/in/web/controller/response/DailyExpenseResponse.java index 4b6aac3..1a2eb17 100644 --- a/src/main/java/com/connect/accountApp/domain/expense/adapter/in/web/controller/response/DailyExpenseResponse.java +++ b/src/main/java/com/connect/accountApp/domain/expense/adapter/in/web/controller/response/DailyExpenseResponse.java @@ -1,9 +1,9 @@ package com.connect.accountApp.domain.expense.adapter.in.web.controller.response; import com.connect.accountApp.domain.expense.application.port.in.command.DailyExpenseCommand; -import com.connect.accountApp.domain.expense.application.port.in.command.DailyExpenseCommand.SettlementSubjectCommand; import java.math.BigDecimal; import java.math.RoundingMode; +import java.util.Collections; import java.util.List; import lombok.AccessLevel; import lombok.Getter; @@ -13,51 +13,31 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) public class DailyExpenseResponse { - private List expenses; + private List expenses; - public DailyExpenseResponse(List commands) { - this.expenses = commands.stream().map(DailyExpense::new).toList(); - } - - @Getter - @NoArgsConstructor(access = AccessLevel.PROTECTED) - public class DailyExpense { - - private Long expenseId; - private BigDecimal expenseAmount; - private String expenseStore; - private String expenseCategoryName; - private String expenseCategoryImage; - private List settlementSubjects; - - public DailyExpense(DailyExpenseCommand command ) { - this.expenseId = command.getExpenseId(); - this.expenseAmount = command.getExpenseAmount().setScale(0, RoundingMode.FLOOR); - this.expenseStore = command.getExpenseStore(); - this.expenseCategoryName = command.getExpenseCategory().getTitle(); - this.expenseCategoryImage = command.getExpenseCategory().getImgUrl(); - - this.settlementSubjects = command.getSettlementSubjects().stream().map(SettlementSubject::new).toList(); + public DailyExpenseResponse(List commands) { + this.expenses = commands.stream().map(DailyExpense::new).toList(); } @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) - public class SettlementSubject { - - private Long userId; - private String userName; - private Boolean isExpenseConsumer; - private String userProfileImage; - - public SettlementSubject(SettlementSubjectCommand command) { - this.userId = command.getUserId(); - this.userName = command.getUserNickname(); - this.isExpenseConsumer = command.getIsExpenseConsumer(); - this.userProfileImage = command.getUserProfileImage(); - } + public class DailyExpense { + + private Long expenseId; + private BigDecimal expenseAmount; + private String expenseStore; + private String expenseCategoryName; + private String expenseCategoryImage; + private List settlementSubjects; + + public DailyExpense(DailyExpenseCommand command) { + this.expenseId = command.getExpenseId(); + this.expenseAmount = command.getExpenseAmount().setScale(0, RoundingMode.FLOOR); + this.expenseStore = command.getExpenseStore(); + this.expenseCategoryName = command.getExpenseCategory().getTitle(); + this.expenseCategoryImage = command.getExpenseCategory().getImgUrl(); + this.settlementSubjects = Collections.EMPTY_LIST; + } } - } - - } diff --git a/src/main/java/com/connect/accountApp/domain/expense/adapter/out/persistence/ExpenseMapper.java b/src/main/java/com/connect/accountApp/domain/expense/adapter/out/persistence/ExpenseMapper.java index ebe3e84..ebf5862 100644 --- a/src/main/java/com/connect/accountApp/domain/expense/adapter/out/persistence/ExpenseMapper.java +++ b/src/main/java/com/connect/accountApp/domain/expense/adapter/out/persistence/ExpenseMapper.java @@ -2,35 +2,85 @@ import com.connect.accountApp.domain.expense.adapter.out.persistence.jpa.model.ExpenseJpaEntity; import com.connect.accountApp.domain.expense.domain.model.Expense; +import com.connect.accountApp.domain.household.adapter.out.persistence.HouseholdMapper; +import com.connect.accountApp.domain.household.adapter.out.persistence.jpa.model.HouseHoldJpaEntity; +import com.connect.accountApp.domain.household.domain.model.Household; import com.connect.accountApp.domain.user.adapter.out.persistence.UserMapper; +import com.connect.accountApp.domain.user.adapter.out.persistence.jpa.model.UserJpaEntity; +import com.connect.accountApp.domain.user.domain.model.User; import lombok.RequiredArgsConstructor; +import org.hibernate.proxy.HibernateProxy; import org.springframework.stereotype.Component; @Component @RequiredArgsConstructor public class ExpenseMapper { + private final UserMapper userMapper; + private final HouseholdMapper householdMapper; + public Expense mapToDomainEntity(ExpenseJpaEntity expenseJpaEntity) { return Expense.builder() - .expenseId(expenseJpaEntity.getExpenseId()) - .expenseAmount(expenseJpaEntity.getExpenseAmount()) - .expenseDate(expenseJpaEntity.getExpenseDate()) - .expenseStore(expenseJpaEntity.getExpenseStore()) - .expenseMemo(expenseJpaEntity.getExpenseMemo()) - .expenseCategory(expenseJpaEntity.getExpenseCategory()) - .build(); + .expenseId(expenseJpaEntity.getExpenseId()) + .expenseAmount(expenseJpaEntity.getExpenseAmount()) + .expenseDate(expenseJpaEntity.getExpenseDate()) + .expenseStore(expenseJpaEntity.getExpenseStore()) + .expenseMemo(expenseJpaEntity.getExpenseMemo()) + .expenseCategory(expenseJpaEntity.getExpenseCategory()) + .spender(getUserOfExpenseJpaEntity(expenseJpaEntity.getSpender())) + .household(getHouseHoldOfExpenseJpaEntity(expenseJpaEntity.getHouseHoldJpaEntity())) + .build(); } public ExpenseJpaEntity mapToJpaEntity(Expense expense) { return ExpenseJpaEntity.builder() - .expenseId(expense.getExpenseId()) - .expenseAmount(expense.getExpenseAmount()) - .expenseDate(expense.getExpenseDate()) - .expenseStore(expense.getExpenseStore()) - .expenseMemo(expense.getExpenseMemo()) - .expenseCategory(expense.getExpenseCategory()) - .build(); + .expenseId(expense.getExpenseId()) + .expenseAmount(expense.getExpenseAmount()) + .expenseDate(expense.getExpenseDate()) + .expenseStore(expense.getExpenseStore()) + .expenseMemo(expense.getExpenseMemo()) + .expenseCategory(expense.getExpenseCategory()) + .spender(getUserJpaEntityOfExpense(expense.getSpender())) + .houseHoldJpaEntity(getHouseHoldJpaEntityOfExpense(expense.getHousehold())) + .build(); + + } + + + private HouseHoldJpaEntity getHouseHoldJpaEntityOfExpense(Household household) { + if (household == null) { + return null; + }else { + return householdMapper.mapToJpaEntity(household); + } + } + + private Household getHouseHoldOfExpenseJpaEntity(HouseHoldJpaEntity houseHoldJpaEntity) { + if (houseHoldJpaEntity == null || houseHoldJpaEntity instanceof HibernateProxy) { + return null; + }else { + return householdMapper.mapToDomainEntity(houseHoldJpaEntity); + } } + + private UserJpaEntity getUserJpaEntityOfExpense(User user) { + if (user == null) { + return null; + }else { + return userMapper.mapToJpaEntity(user); + } + } + + private User getUserOfExpenseJpaEntity(UserJpaEntity userJpaEntity) { + + if (userJpaEntity == null || userJpaEntity instanceof HibernateProxy) { + return null; + }else { + return userMapper.mapToDomainEntity(userJpaEntity); + } + } + + } diff --git a/src/main/java/com/connect/accountApp/domain/expense/adapter/out/persistence/ExpensePersistenceAdapter.java b/src/main/java/com/connect/accountApp/domain/expense/adapter/out/persistence/ExpensePersistenceAdapter.java index ec5690b..e4c9a7b 100644 --- a/src/main/java/com/connect/accountApp/domain/expense/adapter/out/persistence/ExpensePersistenceAdapter.java +++ b/src/main/java/com/connect/accountApp/domain/expense/adapter/out/persistence/ExpensePersistenceAdapter.java @@ -36,7 +36,7 @@ public List getTotalExpense(Long householdId, LocalDateTime LocalDateTime endTime) { List totalExpenseQuery = expenseQueryRepository.getTotalExpenseQuery( - householdId, startTime, endTime); + householdId, startTime.toLocalDate(), endTime.toLocalDate()); return totalExpenseQuery; } @@ -54,12 +54,14 @@ public TotalExpenseCommand getUserSendMoney(Long userId, LocalDate date) { @Override public int getHouseholdTotalExpense(Long householdId, LocalDateTime startTime, LocalDateTime endTime) { - return expenseQueryRepository.getHouseholdTotalExpense(householdId, startTime, endTime); + return 1; +// return expenseQueryRepository.getHouseholdTotalExpense(householdId, startTime.toLocalDate(), endTime.toLocalDate()); } @Override public BigDecimal getHouseholdTotalExpenseByDate(Long householdId, LocalDateTime startTime, LocalDateTime endTime) { - return expenseQueryRepository.getHouseholdTotalExpenseBetweenDate(householdId, startTime, endTime); + return expenseQueryRepository.getHouseholdTotalExpenseBetweenDate(householdId, startTime, + endTime.plusDays(1).minusSeconds(1)); } @Override @@ -97,4 +99,9 @@ public List findSearchedExpenses(Long householdId, Searched return expenseQueryRepository.findSearchedExpenses(householdId, condition); } + @Override + public BigDecimal findHouseholdTotalExpenses(Long householdId, LocalDate startDate, LocalDate endDate) { + return expenseQueryRepository.getHouseholdTotalExpense(householdId, startDate, endDate); + } + } diff --git a/src/main/java/com/connect/accountApp/domain/expense/adapter/out/persistence/ExpenseQueryRepository.java b/src/main/java/com/connect/accountApp/domain/expense/adapter/out/persistence/ExpenseQueryRepository.java index 733d6b0..b7ac7af 100644 --- a/src/main/java/com/connect/accountApp/domain/expense/adapter/out/persistence/ExpenseQueryRepository.java +++ b/src/main/java/com/connect/accountApp/domain/expense/adapter/out/persistence/ExpenseQueryRepository.java @@ -2,7 +2,6 @@ import static com.connect.accountApp.domain.expense.adapter.out.persistence.jpa.model.QExpenseJpaEntity.expenseJpaEntity; import static com.connect.accountApp.domain.household.adapter.out.persistence.jpa.model.QHouseHoldJpaEntity.houseHoldJpaEntity; -import static com.connect.accountApp.domain.settlement.adapter.out.persistence.jpa.model.QSettlementJpaEntity.settlementJpaEntity; import static com.connect.accountApp.domain.user.adapter.out.persistence.jpa.model.QUserJpaEntity.userJpaEntity; import com.connect.accountApp.domain.expense.application.port.in.command.DailyExpenseCommand; @@ -29,245 +28,230 @@ @Slf4j public class ExpenseQueryRepository { - private final JPAQueryFactory queryFactory; + private final JPAQueryFactory queryFactory; - public List getTotalExpenseQuery(Long householdId, LocalDateTime startTime, - LocalDateTime endTime) { + public List getTotalExpenseQuery(Long householdId, LocalDate startTime, + LocalDate endTime) { - return queryFactory - .select(Projections.constructor(TotalExpenseCommand.class, - userJpaEntity.userId, - userJpaEntity.userNickname.as("userName"), - expenseJpaEntity.expenseAmount.sum().as("userTotalExpense"), - userJpaEntity.userRatio - )) - .from(expenseJpaEntity) + return queryFactory + .select(Projections.constructor(TotalExpenseCommand.class, + userJpaEntity.userId, + userJpaEntity.userNickname.as("userName"), + expenseJpaEntity.expenseAmount.sum().as("userTotalExpense"), + userJpaEntity.userRatio + )) + .from(expenseJpaEntity) // .join(expenseJpaEntity., userJpaEntity) - .where( - eqHouseholdId(householdId), - betweenDate(startTime, endTime) - ) - .groupBy(userJpaEntity.userId) - .fetch(); - } + .where( + eqHouseholdId(householdId), + betweenDate(startTime, endTime) + ) + .groupBy(userJpaEntity.userId) + .fetch(); + } - public TotalExpenseCommand getUserTotalExpenseQuery(Long userId, LocalDate date) { + public TotalExpenseCommand getUserTotalExpenseQuery(Long userId, LocalDate date) { - return queryFactory - .select(Projections.constructor(TotalExpenseCommand.class, - userJpaEntity.userId, - userJpaEntity.userNickname.as("userName"), - expenseJpaEntity.expenseAmount.sum().as("userTotalExpense"), - userJpaEntity.userRatio - )) - .from(expenseJpaEntity) + return queryFactory + .select(Projections.constructor(TotalExpenseCommand.class, + userJpaEntity.userId, + userJpaEntity.userNickname.as("userName"), + expenseJpaEntity.expenseAmount.sum().as("userTotalExpense"), + userJpaEntity.userRatio + )) + .from(expenseJpaEntity) // .join(expenseJpaEntity.userJpaEntity, userJpaEntity) - .where( - userJpaEntity.userId.eq(userId), - betweenDate(date.atStartOfDay()) - ) - .fetchOne(); - } + .where( + userJpaEntity.userId.eq(userId), + betweenDate(date.atStartOfDay()) + ) + .fetchOne(); + } - public List findDailyExpenses(Long householdId, LocalDate date) { + public List findDailyExpenses(Long householdId, LocalDate date) { - return queryFactory - .from(settlementJpaEntity) - .join(settlementJpaEntity.expenseJpaEntity, expenseJpaEntity) - .join(settlementJpaEntity.userJpaEntity, userJpaEntity) - .where( - userJpaEntity.houseHoldJpaEntity.householdId.eq(householdId), - settlementJpaEntity.expenseJpaEntity.expenseDate.eq(date) - ) - .transform(GroupBy.groupBy(settlementJpaEntity.expenseJpaEntity.expenseId).list( - Projections.constructor(DailyExpenseCommand.class, - settlementJpaEntity.expenseJpaEntity.expenseId, - settlementJpaEntity.expenseJpaEntity.expenseAmount, - settlementJpaEntity.expenseJpaEntity.expenseStore, - settlementJpaEntity.expenseJpaEntity.expenseCategory, - GroupBy.list( - Projections.constructor( - DailyExpenseCommand.SettlementSubjectCommand.class, - userJpaEntity.userId, - userJpaEntity.userNickname, - settlementJpaEntity.isSettlementDelegate.as("isExpenseConsumer"), - userJpaEntity.userImgUrl.as("userProfileImage") - ).as("settlementSubjects") - ) + return queryFactory + .selectFrom(expenseJpaEntity) + .where( + expenseJpaEntity.houseHoldJpaEntity.householdId.eq(householdId), + expenseJpaEntity.expenseDate.eq(date) ) - ) - ); - } + .transform(GroupBy.groupBy(expenseJpaEntity.expenseId).list( + Projections.constructor(DailyExpenseCommand.class, + expenseJpaEntity.expenseId, + expenseJpaEntity.expenseAmount, + expenseJpaEntity.expenseStore, + expenseJpaEntity.expenseCategory + ) + ) + ); + } public List findSearchedExpenses(Long householdId, SearchedCondition condition) { OrderSpecifier sorted = sorted(condition); return queryFactory - .from(settlementJpaEntity) - .join(settlementJpaEntity.expenseJpaEntity, expenseJpaEntity) - .join(settlementJpaEntity.userJpaEntity, userJpaEntity) + .from(expenseJpaEntity) + .join(expenseJpaEntity.spender, userJpaEntity) .where( - userJpaEntity.houseHoldJpaEntity.householdId.eq(householdId), - settlementJpaEntity.expenseJpaEntity.expenseDate.between(condition.getExpenseDateMin(), condition.getExpenseDateMax()), + expenseJpaEntity.houseHoldJpaEntity.householdId.eq(householdId), + expenseJpaEntity.expenseDate.between(condition.getExpenseDateMin(), condition.getExpenseDateMax()), eqCategory(condition.getExpenseCategory().orElse(null)), - settlementJpaEntity.expenseJpaEntity.expenseAmount.between(condition.getExpenseAmountMin(), + expenseJpaEntity.expenseAmount.between(condition.getExpenseAmountMin(), condition.getExpenseAmountMax()) ) .orderBy(sorted) - .transform(GroupBy.groupBy(settlementJpaEntity.expenseJpaEntity.expenseId).list( + .transform(GroupBy.groupBy(expenseJpaEntity.expenseId).list( Projections.constructor(DailyExpenseCommand.class, - settlementJpaEntity.expenseJpaEntity.expenseId, - settlementJpaEntity.expenseJpaEntity.expenseAmount, - settlementJpaEntity.expenseJpaEntity.expenseStore, - settlementJpaEntity.expenseJpaEntity.expenseCategory, - GroupBy.list( - Projections.constructor( - DailyExpenseCommand.SettlementSubjectCommand.class, - userJpaEntity.userId, - userJpaEntity.userNickname, - settlementJpaEntity.isSettlementDelegate.as("isExpenseConsumer"), - userJpaEntity.userImgUrl.as("userProfileImage") - ).as("settlementSubjects") - ) + expenseJpaEntity.expenseId, + expenseJpaEntity.expenseAmount, + expenseJpaEntity.expenseStore, + expenseJpaEntity.expenseCategory ) ) ); } private OrderSpecifier sorted(SearchedCondition condition) { - OrderSpecifier sorted = settlementJpaEntity.expenseJpaEntity.expenseDate.asc(); - if (condition.getSortedByNewest()) { - sorted = settlementJpaEntity.expenseJpaEntity.expenseDate.desc(); - } - return sorted; +// OrderSpecifier sorted = settlementJpaEntity.expenseJpaEntity.expenseDate.asc(); +// if (condition.getSortedByNewest()) { +// sorted = settlementJpaEntity.expenseJpaEntity.expenseDate.desc(); +// } +// return sorted; + return null; } public BigDecimal getHouseholdTotalExpenseBetweenDate(Long householdId, LocalDateTime startTime, LocalDateTime endTime) { - System.out.println("householdId = " + householdId); - System.out.println("startTime = " + startTime); - System.out.println("endTime = " + endTime); - return queryFactory .select( expenseJpaEntity.expenseAmount.sum().as("householdTotalExpense") ) - .from(settlementJpaEntity) - .join(settlementJpaEntity.expenseJpaEntity) - .join(settlementJpaEntity.userJpaEntity) - .join(settlementJpaEntity.userJpaEntity.houseHoldJpaEntity) + .from(expenseJpaEntity) + .join(expenseJpaEntity.houseHoldJpaEntity, houseHoldJpaEntity) .where( - eqHouseholdId(householdId), - betweenDate(startTime, endTime.plusDays(1).minusSeconds(1)) + expenseJpaEntity.houseHoldJpaEntity.householdId.eq(householdId), + betweenDate(startTime.toLocalDate(), endTime.toLocalDate()) ) - .groupBy(settlementJpaEntity.userJpaEntity.houseHoldJpaEntity.householdId) + .groupBy(expenseJpaEntity.houseHoldJpaEntity.householdId) .fetchOne(); - } + } public BigDecimal getUserTotalExpense(Long userId, LocalDateTime startTime, LocalDateTime endTime) { + return null; +// return queryFactory +// .select( +// expenseJpaEntity.expenseAmount.sum().as("userTotalExpense") +// ) +// .from(expenseJpaEntity) +// .join(expenseJpaEntity.spender, userJpaEntity) +// .where( +// +// settlementJpaEntity.userJpaEntity.userId.eq(userId), +// betweenDate(startTime, endTime.plusDays(1).minusSeconds(1)) +// ) +// .groupBy(settlementJpaEntity.userJpaEntity.houseHoldJpaEntity.householdId) +// .fetchOne(); + } + + public BigDecimal getHouseholdTotalExpense(Long householdId, LocalDate startTime, LocalDate endTime) { return queryFactory - .select( - expenseJpaEntity.expenseAmount.sum().as("userTotalExpense") - ) - .from(settlementJpaEntity) - .join(settlementJpaEntity.expenseJpaEntity) - .join(settlementJpaEntity.userJpaEntity) - .join(settlementJpaEntity.userJpaEntity.houseHoldJpaEntity) + .select(expenseJpaEntity.expenseAmount.sum().as("householdTotalExpense")) + .from(expenseJpaEntity) + .join(expenseJpaEntity.houseHoldJpaEntity, houseHoldJpaEntity) .where( - settlementJpaEntity.isSettlementDelegate.isTrue(), - settlementJpaEntity.userJpaEntity.userId.eq(userId), - betweenDate(startTime, endTime.plusDays(1).minusSeconds(1)) + expenseJpaEntity.houseHoldJpaEntity.householdId.eq(householdId), + betweenDate(startTime, endTime) //todo: 여기 포함? ) - .groupBy(settlementJpaEntity.userJpaEntity.houseHoldJpaEntity.householdId) + .groupBy(expenseJpaEntity.houseHoldJpaEntity.householdId) .fetchOne(); } - public Integer getHouseholdTotalExpense(Long householdId, LocalDateTime startTime, LocalDateTime endTime) { + public List getDailyTotalExpenseOfHousehold(Long householdId, LocalDate date) { // 월별 조회 -// Integer householdTotalExpense = queryFactory -// .select( -// expenseJpaEntity.expenseAmount.sum().as("householdTotalExpense") -// ) -// .from(expenseJpaEntity) -// .join(expenseJpaEntity.userJpaEntity, userJpaEntity) -// .where( -// eqHouseholdId(householdId), -// betweenDate(startTime, endTime.plusDays(1).minusSeconds(1)) -// ) -// .groupBy(userJpaEntity.houseHoldJpaEntity.householdId) -// .fetchOne(); - return 1; - } + System.out.println("date = " + date.getMonth()); + System.out.println("date = " + date.getYear()); - public List getDailyTotalExpenseOfHousehold(Long householdId, LocalDate date) { - - System.out.println("date = " + date.getMonth()); - System.out.println("date = " + date.getYear()); - - return queryFactory - .select( - Projections.constructor(DailyTotalExpensesCommand.class, - expenseJpaEntity.expenseDate.dayOfMonth().as("expenseDayOfMonth"), - expenseJpaEntity.expenseAmount.sum().as("dailyTotalExpense") - ) - - ) - .from(settlementJpaEntity) - .join(settlementJpaEntity.userJpaEntity, userJpaEntity) - .join(settlementJpaEntity.expenseJpaEntity, expenseJpaEntity) - .join(userJpaEntity.houseHoldJpaEntity, houseHoldJpaEntity) - .where( - eqHouseholdId(householdId), - settlementJpaEntity.isSettlementDelegate.eq(true), - expenseJpaEntity.expenseDate.year().eq(date.getYear()), - expenseJpaEntity.expenseDate.month().eq(date.getMonthValue()) - ) - .groupBy(expenseJpaEntity.expenseDate.dayOfMonth()) - .fetch(); - } - - public List getTotalExpenseGroupByCategory(Long householdId, LocalDate from, LocalDate to) { + /* + private Integer expenseDayOfMonth; + private BigDecimal dailyTotalExpense; + */ + return queryFactory + .select( + Projections.constructor(DailyTotalExpensesCommand.class, + expenseJpaEntity.expenseDate.dayOfMonth().as("expenseDayOfMonth"), + expenseJpaEntity.expenseAmount.sum().as("dailyTotalExpense") + ) + ) + .from(expenseJpaEntity) + .join(expenseJpaEntity.houseHoldJpaEntity, houseHoldJpaEntity) + .where( + expenseJpaEntity.houseHoldJpaEntity.householdId.eq(householdId), + expenseJpaEntity.expenseDate.year().eq(date.getYear()), + expenseJpaEntity.expenseDate.month().eq(date.getMonthValue()) + ) + .groupBy(expenseJpaEntity.expenseDate.dayOfMonth()) + .fetch(); +// return queryFactory +// .select( +// Projections.constructor(DailyTotalExpensesCommand.class, +// expenseJpaEntity.expenseDate.dayOfMonth().as("expenseDayOfMonth"), +// expenseJpaEntity.expenseAmount.sum().as("dailyTotalExpense") +// ) +// ) +// .from(expenseJpaEntity) +// .join(expenseJpaEntity.spender, userJpaEntity) +// .join(userJpaEntity.houseHoldJpaEntity, houseHoldJpaEntity) +// .where( +// eqHouseholdId(householdId), +// expenseJpaEntity.expenseDate.year().eq(date.getYear()), +// expenseJpaEntity.expenseDate.month().eq(date.getMonthValue()) +// ) +// .groupBy(expenseJpaEntity.expenseDate.dayOfMonth()) +// .fetch(); + } + public List getTotalExpenseGroupByCategory(Long householdId, LocalDate from, + LocalDate to) { return queryFactory .select(Projections.constructor(TotalExpenseByCategoryCommand.class, - settlementJpaEntity.expenseJpaEntity.expenseCategory.as("expenseCategory"), - settlementJpaEntity.expenseJpaEntity.expenseAmount.sum().as("totalExpenseAmount")) + expenseJpaEntity.expenseCategory.as("expenseCategory"), + expenseJpaEntity.expenseAmount.sum().as("totalExpenseAmount")) ) - .from(settlementJpaEntity) - .join(settlementJpaEntity.userJpaEntity) - .join(settlementJpaEntity.expenseJpaEntity) + .from(expenseJpaEntity) + .join(expenseJpaEntity.houseHoldJpaEntity) .where( - settlementJpaEntity.userJpaEntity.houseHoldJpaEntity.householdId.eq(householdId), - settlementJpaEntity.expenseJpaEntity.expenseDate.between(from, to) + expenseJpaEntity.houseHoldJpaEntity.householdId.eq(householdId), + expenseJpaEntity.expenseDate.between(from, to) ) .groupBy(expenseJpaEntity.expenseCategory) .fetch(); - } + } - private BooleanExpression eqHouseholdId(Long householdId) { - log.info("householdId : {}", householdId); - return householdId != null ? userJpaEntity.houseHoldJpaEntity.householdId.eq(householdId) : null; - } + private BooleanExpression eqHouseholdId(Long householdId) { + log.info("householdId : {}", householdId); + return householdId != null ? userJpaEntity.houseHoldJpaEntity.householdId.eq(householdId) : null; + } - private BooleanExpression betweenDate(LocalDateTime date) { - log.info("startDate : {}, endDate : {}",date.plusDays(1).minusSeconds(1), date); - return date != null ? expenseJpaEntity.expenseDate - .between(date.toLocalDate(), date.toLocalDate()) : null; - } + private BooleanExpression betweenDate(LocalDateTime date) { + log.info("startDate : {}, endDate : {}", date.plusDays(1).minusSeconds(1), date); + return date != null ? expenseJpaEntity.expenseDate + .between(date.toLocalDate(), date.toLocalDate()) : null; + } - private BooleanExpression betweenDate(LocalDateTime startDate, LocalDateTime endDate) { - log.info("startDate : {}, endDate : {}",startDate, endDate); + private BooleanExpression betweenDate(LocalDate startDate, LocalDate endDate) { + log.info("startDate : {}, endDate : {}", startDate, endDate); - return (startDate != null) && (endDate != null) ? expenseJpaEntity.expenseDate.between(startDate.toLocalDate(), endDate.toLocalDate()) : null; - } + return (startDate != null) && (endDate != null) ? expenseJpaEntity.expenseDate.between(startDate, endDate) : null; + } private BooleanExpression eqCategory(ExpenseCategory category) { - return (category != null) ? settlementJpaEntity.expenseJpaEntity.expenseCategory.eq(category) : null; + return (category != null) ? expenseJpaEntity.expenseCategory.eq(category) : null; } } diff --git a/src/main/java/com/connect/accountApp/domain/expense/adapter/out/persistence/jpa/model/ExpenseJpaEntity.java b/src/main/java/com/connect/accountApp/domain/expense/adapter/out/persistence/jpa/model/ExpenseJpaEntity.java index 3280acb..a9b28e6 100644 --- a/src/main/java/com/connect/accountApp/domain/expense/adapter/out/persistence/jpa/model/ExpenseJpaEntity.java +++ b/src/main/java/com/connect/accountApp/domain/expense/adapter/out/persistence/jpa/model/ExpenseJpaEntity.java @@ -3,14 +3,18 @@ import com.connect.accountApp.domain.expense.domain.model.ExpenseCategory; import com.connect.accountApp.domain.household.adapter.out.persistence.jpa.model.HouseHoldJpaEntity; import com.connect.accountApp.domain.user.adapter.out.persistence.jpa.model.UserJpaEntity; +import com.connect.accountApp.domain.user.domain.model.User; +import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; +import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToOne; import jakarta.persistence.Table; import java.math.BigDecimal; import java.time.LocalDate; @@ -36,16 +40,27 @@ public class ExpenseJpaEntity { @Enumerated(EnumType.STRING) private ExpenseCategory expenseCategory; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "household_id") + private HouseHoldJpaEntity houseHoldJpaEntity; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id") + private UserJpaEntity spender; + @Builder - public ExpenseJpaEntity(Long expenseId, BigDecimal expenseAmount, LocalDate expenseDate, - String expenseStore, String expenseMemo, - UserJpaEntity userJpaEntity, - ExpenseCategory expenseCategory) { + public ExpenseJpaEntity(Long expenseId, BigDecimal expenseAmount, LocalDate expenseDate, String expenseStore, + String expenseMemo, + ExpenseCategory expenseCategory, + HouseHoldJpaEntity houseHoldJpaEntity, + UserJpaEntity spender) { this.expenseId = expenseId; this.expenseAmount = expenseAmount; this.expenseDate = expenseDate; this.expenseStore = expenseStore; this.expenseMemo = expenseMemo; this.expenseCategory = expenseCategory; + this.houseHoldJpaEntity = houseHoldJpaEntity; + this.spender = spender; } } diff --git a/src/main/java/com/connect/accountApp/domain/expense/application/port/in/SearchExpenseUseCase.java b/src/main/java/com/connect/accountApp/domain/expense/application/port/in/SearchExpenseUseCase.java index bdbde1e..185b7b8 100644 --- a/src/main/java/com/connect/accountApp/domain/expense/application/port/in/SearchExpenseUseCase.java +++ b/src/main/java/com/connect/accountApp/domain/expense/application/port/in/SearchExpenseUseCase.java @@ -1,9 +1,7 @@ package com.connect.accountApp.domain.expense.application.port.in; -import com.connect.accountApp.domain.expense.adapter.in.web.controller.request.SearchConditionRequest; import com.connect.accountApp.domain.expense.application.port.in.command.DailyExpenseCommand; import com.connect.accountApp.domain.expense.application.port.in.command.SearchedCondition; -import com.connect.accountApp.domain.expense.application.port.out.command.DailyTotalExpensesCommand; import java.util.List; public interface SearchExpenseUseCase { diff --git a/src/main/java/com/connect/accountApp/domain/expense/application/port/in/command/DailyExpenseCommand.java b/src/main/java/com/connect/accountApp/domain/expense/application/port/in/command/DailyExpenseCommand.java index 3b8dcc8..290fe99 100644 --- a/src/main/java/com/connect/accountApp/domain/expense/application/port/in/command/DailyExpenseCommand.java +++ b/src/main/java/com/connect/accountApp/domain/expense/application/port/in/command/DailyExpenseCommand.java @@ -15,34 +15,13 @@ public class DailyExpenseCommand { private BigDecimal expenseAmount; private String expenseStore; private ExpenseCategory expenseCategory; - private List settlementSubjects; public DailyExpenseCommand(Long expenseId, BigDecimal expenseAmount, String expenseStore, - ExpenseCategory expenseCategory, - List settlementSubjects) { + ExpenseCategory expenseCategory) { this.expenseId = expenseId; this.expenseAmount = expenseAmount; this.expenseStore = expenseStore; this.expenseCategory = expenseCategory; - this.settlementSubjects = settlementSubjects; - } - - @Getter - @NoArgsConstructor(access = AccessLevel.PROTECTED) - public static class SettlementSubjectCommand { - - private Long userId; - private String userNickname; - private Boolean isExpenseConsumer; - private String userProfileImage; - - public SettlementSubjectCommand(Long userId, String userNickname, Boolean isExpenseConsumer, - String userProfileImage) { - this.userId = userId; - this.userNickname = userNickname; - this.isExpenseConsumer = isExpenseConsumer; - this.userProfileImage = userProfileImage; - } } } diff --git a/src/main/java/com/connect/accountApp/domain/expense/application/port/out/FindExpensePort.java b/src/main/java/com/connect/accountApp/domain/expense/application/port/out/FindExpensePort.java index 6225bb9..c327899 100644 --- a/src/main/java/com/connect/accountApp/domain/expense/application/port/out/FindExpensePort.java +++ b/src/main/java/com/connect/accountApp/domain/expense/application/port/out/FindExpensePort.java @@ -3,6 +3,7 @@ import com.connect.accountApp.domain.expense.application.port.in.command.DailyExpenseCommand; import com.connect.accountApp.domain.expense.application.port.in.command.SearchedCondition; import com.connect.accountApp.domain.expense.domain.model.Expense; +import java.math.BigDecimal; import java.time.LocalDate; import java.util.List; @@ -14,4 +15,5 @@ public interface FindExpensePort { List findSearchedExpenses(Long householdId, SearchedCondition condition); + BigDecimal findHouseholdTotalExpenses(Long householdId, LocalDate startDate, LocalDate endDate); } diff --git a/src/main/java/com/connect/accountApp/domain/expense/application/service/RegisterExpenseService.java b/src/main/java/com/connect/accountApp/domain/expense/application/service/RegisterExpenseService.java index 8ef4c40..ab3714e 100644 --- a/src/main/java/com/connect/accountApp/domain/expense/application/service/RegisterExpenseService.java +++ b/src/main/java/com/connect/accountApp/domain/expense/application/service/RegisterExpenseService.java @@ -5,13 +5,14 @@ import com.connect.accountApp.domain.expense.application.port.out.FindExpensePort; import com.connect.accountApp.domain.expense.application.port.out.SaveExpensePort; import com.connect.accountApp.domain.expense.domain.model.Expense; +import com.connect.accountApp.domain.expensenotification.application.port.out.SaveExpenseNotificationPort; +import com.connect.accountApp.domain.expensenotification.domain.model.ExpenseNotification; +import com.connect.accountApp.domain.household.domain.model.Household; +import com.connect.accountApp.domain.user.application.port.out.FindHouseholdUserListPort; import com.connect.accountApp.domain.user.application.port.out.GetUserPort; import com.connect.accountApp.domain.user.domain.model.User; -import com.connect.accountApp.domain.settlement.application.port.out.SaveSettlementPort; -import com.connect.accountApp.domain.settlement.domain.model.Settlement; -import com.connect.accountApp.domain.settlement.exception.ExpenseDelegateNotFound; import java.util.List; -import java.util.Objects; +import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -19,67 +20,63 @@ @RequiredArgsConstructor public class RegisterExpenseService implements RegisterExpenseUseCase { - private final GetUserPort getUserPort; - private final SaveExpensePort saveExpensePort; - private final FindExpensePort findExpensePort; - private final SaveSettlementPort saveSettlementPort; - - - @Override - - public Long registerExpense(String expenseDelegateUserEmail, RegisterExpenseRequest request) { - - User expenseDelegate = getUserPort.findUser(expenseDelegateUserEmail); - List settlementSubjects = request.getSettlementSubjectIds().stream().map(getUserPort::getUser).toList(); - - validateDelegateExistInSubjects(expenseDelegate, settlementSubjects); - - Expense expense = createAndSaveExpense(request); - createAndSaveSettlementsOfSubjects(settlementSubjects, expense, expenseDelegate); - - return expense.getExpenseId(); - } - - - private void validateDelegateExistInSubjects(User expenseDelegate, List settlementSubjects) { - boolean existExistSubjects = settlementSubjects.stream() - .anyMatch(user -> Objects.equals(user.getUserId(), expenseDelegate.getUserId())); - - if (!existExistSubjects) - throw new ExpenseDelegateNotFound("실제 지출 등록한 사람의 id : " + expenseDelegate.getUserId() + - "가 settlementSubjects : " + settlementSubjects + "에 존재하지 않습니다."); - } - - private void createAndSaveSettlementsOfSubjects(List settlementSubjects, Expense expense, User expenseDelegate) { - settlementSubjects.forEach(settlementSubject -> - { - Settlement settlement = createSettlement(expense, expenseDelegate, settlementSubject); - saveSettlementPort.saveSettlement(settlement); - } - ); - } - - private Expense createAndSaveExpense(RegisterExpenseRequest request) { - Expense newExpense = createExpense(request); - Long savedExpenseId = saveExpensePort.saveExpensePort(newExpense); - return findExpensePort.findExpense(savedExpenseId); - } - - private Expense createExpense(RegisterExpenseRequest request) { - return Expense.builder() - .expenseAmount(request.getExpenseAmount()) - .expenseDate(request.getExpenseDate()) - .expenseStore(request.getExpenseStore()) - .expenseMemo(request.getExpenseMemo()) - .expenseCategory(request.getExpenseCategory()) - .build(); - } - - private Settlement createSettlement(Expense expense, User expenseDelegate, User settlementSubject) { - return Settlement.builder() - .expense(expense) - .user(settlementSubject) - .isSettlementDelegate(Objects.equals(settlementSubject.getUserId(), expenseDelegate.getUserId())) - .build(); - } + private final GetUserPort getUserPort; + private final SaveExpensePort saveExpensePort; + private final FindExpensePort findExpensePort; + private final SaveExpenseNotificationPort saveExpenseNotificationPort; + private final FindHouseholdUserListPort findHouseholdUserListPort; + + + @Override + public Long registerExpense(String expenseDelegateUserEmail, RegisterExpenseRequest request) { + User userWithHousehold = getUserPort.findUserWithHousehold(expenseDelegateUserEmail); + Household household = userWithHousehold.getHousehold(); + + Expense expense = createAndSaveExpense(request, household, userWithHousehold); + saveExpenseNotifications(expense, household); + + return expense.getExpenseId(); + } + + + private Expense createAndSaveExpense(RegisterExpenseRequest request, Household household, User spender) { + Expense newExpense = createExpense(request, household, spender); + Long savedExpenseId = saveExpensePort.saveExpensePort(newExpense); + return findExpensePort.findExpense(savedExpenseId); + } + + + private Expense createExpense(RegisterExpenseRequest request, Household household, User spender) { + + return Expense.builder() + .expenseAmount(request.getExpenseAmount()) + .expenseDate(request.getExpenseDate()) + .expenseStore(request.getExpenseStore()) + .expenseMemo(request.getExpenseMemo()) + .expenseCategory(request.getExpenseCategory()) + .household(household) + .spender(spender) + .build(); + } + + + private void saveExpenseNotifications(Expense expense, Household household) { + List expenseNotification = createExpenseNotificationOfMembers(expense, household); + saveExpenseNotificationPort.saveAll(expenseNotification); + } + + private List createExpenseNotificationOfMembers(Expense expense, Household household) { + List householdMembers = findHouseholdUserListPort.findHouseholdMembers(household.getHouseholdId()); + return householdMembers.stream() + .map(member -> createExpenseNotification(expense, member)) + .collect(Collectors.toList()); + } + + private ExpenseNotification createExpenseNotification(Expense expense, User member) { + return ExpenseNotification.builder() + .isRead(false) + .expense(expense) + .user(member).build(); + } + } diff --git a/src/main/java/com/connect/accountApp/domain/expense/domain/model/Expense.java b/src/main/java/com/connect/accountApp/domain/expense/domain/model/Expense.java index 5fc4550..59af592 100644 --- a/src/main/java/com/connect/accountApp/domain/expense/domain/model/Expense.java +++ b/src/main/java/com/connect/accountApp/domain/expense/domain/model/Expense.java @@ -1,5 +1,6 @@ package com.connect.accountApp.domain.expense.domain.model; +import com.connect.accountApp.domain.household.domain.model.Household; import com.connect.accountApp.domain.user.domain.model.User; import java.math.BigDecimal; import java.time.LocalDate; @@ -20,15 +21,20 @@ public class Expense { private String expenseMemo; private ExpenseCategory expenseCategory; + private Household household; + private User spender; + @Builder - public Expense(Long expenseId, BigDecimal expenseAmount, LocalDate expenseDate, - String expenseStore, String expenseMemo, - User user, ExpenseCategory expenseCategory) { + public Expense(Long expenseId, BigDecimal expenseAmount, LocalDate expenseDate, String expenseStore, + String expenseMemo, ExpenseCategory expenseCategory, + Household household, User spender) { this.expenseId = expenseId; this.expenseAmount = expenseAmount; this.expenseDate = expenseDate; this.expenseStore = expenseStore; this.expenseMemo = expenseMemo; this.expenseCategory = expenseCategory; + this.household = household; + this.spender = spender; } } diff --git a/src/main/java/com/connect/accountApp/domain/expensenotification/adapter/port/out/persistence/ExpenseNotificationQueryRepository.java b/src/main/java/com/connect/accountApp/domain/expensenotification/adapter/port/out/persistence/ExpenseNotificationQueryRepository.java index a8ec0e7..a38e9c9 100644 --- a/src/main/java/com/connect/accountApp/domain/expensenotification/adapter/port/out/persistence/ExpenseNotificationQueryRepository.java +++ b/src/main/java/com/connect/accountApp/domain/expensenotification/adapter/port/out/persistence/ExpenseNotificationQueryRepository.java @@ -2,7 +2,7 @@ import static com.connect.accountApp.domain.expense.adapter.out.persistence.jpa.model.QExpenseJpaEntity.expenseJpaEntity; import static com.connect.accountApp.domain.expensenotification.adapter.port.out.persistence.jpa.model.QExpenseNotificationJpaEntity.expenseNotificationJpaEntity; -import static com.connect.accountApp.domain.settlement.adapter.out.persistence.jpa.model.QSettlementJpaEntity.settlementJpaEntity; +import static com.connect.accountApp.domain.user.adapter.out.persistence.jpa.model.QUserJpaEntity.userJpaEntity; import com.connect.accountApp.domain.expensenotification.adapter.port.out.persistence.jpa.model.ExpenseNotificationJpaEntity; import com.connect.accountApp.domain.expensenotification.application.port.in.command.ExpenseNotificationCommand; @@ -19,58 +19,64 @@ @Slf4j public class ExpenseNotificationQueryRepository { - private final JPAQueryFactory jpaQueryFactory; + private final JPAQueryFactory jpaQueryFactory; - public List findExpenseNotificationsInHousehold(String userEmail) { + public List findExpenseNotificationsInHousehold(String userEmail) { + /* + (Long expenseNotificationId, Long expenseId, + ExpenseCategory expenseCategory, LocalDateTime createdAt, Boolean isRead, + BigDecimal expenseAmount, String spenderName) + */ - System.out.println("userEmail = " + userEmail); - return jpaQueryFactory - .select(Projections.constructor(ExpenseNotificationCommand.class, - expenseNotificationJpaEntity.id.as("expenseNotificationId"), - expenseNotificationJpaEntity.expenseJpaEntity.expenseId.as("expenseId"), - expenseNotificationJpaEntity.expenseJpaEntity.expenseCategory.as("expenseCategory"), - expenseNotificationJpaEntity.createdAt, - expenseNotificationJpaEntity.isRead, - expenseNotificationJpaEntity.expenseJpaEntity.expenseAmount - )) - .from(expenseNotificationJpaEntity) - .join(expenseNotificationJpaEntity.userJpaEntity) - .join(expenseNotificationJpaEntity.expenseJpaEntity) - .where( - expenseNotificationJpaEntity.userJpaEntity.userEmail.eq(userEmail) - ) - .orderBy(expenseNotificationJpaEntity.id.asc()) - .fetch(); - } + return jpaQueryFactory + .select(Projections.constructor(ExpenseNotificationCommand.class, + expenseNotificationJpaEntity.id.as("expenseNotificationId"), + expenseNotificationJpaEntity.expenseJpaEntity.expenseId.as("expenseId"), + expenseNotificationJpaEntity.expenseJpaEntity.expenseCategory.as("expenseCategory"), + expenseNotificationJpaEntity.expenseJpaEntity.expenseDate.as("createdAt"), + expenseNotificationJpaEntity.isRead, + expenseNotificationJpaEntity.expenseJpaEntity.expenseAmount, + expenseNotificationJpaEntity.expenseJpaEntity.spender.userNickname.as("spenderName") + )) + .from(expenseNotificationJpaEntity) + .join(expenseNotificationJpaEntity.expenseJpaEntity, expenseJpaEntity) + .join(expenseNotificationJpaEntity.expenseJpaEntity.spender, userJpaEntity) + .where( + expenseNotificationJpaEntity.userJpaEntity.userEmail.eq(userEmail) + ) + .orderBy(expenseNotificationJpaEntity.expenseJpaEntity.expenseDate.desc()) + .fetch(); + } - public List findSpender(List expenseIds) { + public List findSpender(List expenseIds) { + return null; +// +// return jpaQueryFactory +// .select( +// Projections.constructor(FindSpenderCommand.class, +// settlementJpaEntity.expenseJpaEntity.expenseId, +// settlementJpaEntity.userJpaEntity.userNickname.as("spenderName") +// ) +// ) +// .from(settlementJpaEntity) +// .join(settlementJpaEntity.expenseJpaEntity, expenseJpaEntity) +// .where( +// settlementJpaEntity.expenseJpaEntity.expenseId.in(expenseIds), +// settlementJpaEntity.isSettlementDelegate.isTrue() +// ) +// .orderBy() +// .fetch(); + } - return jpaQueryFactory - .select( - Projections.constructor(FindSpenderCommand.class, - settlementJpaEntity.expenseJpaEntity.expenseId, - settlementJpaEntity.userJpaEntity.userNickname.as("spenderName") - ) - ) - .from(settlementJpaEntity) - .join(settlementJpaEntity.expenseJpaEntity, expenseJpaEntity) - .where( - settlementJpaEntity.expenseJpaEntity.expenseId.in(expenseIds), - settlementJpaEntity.isSettlementDelegate.isTrue() - ) - .orderBy() - .fetch(); - } + public List findExpenseNotifications(List expenseNotificationIds) { - public List findExpenseNotifications(List expenseNotificationIds) { - - return jpaQueryFactory - .select(expenseNotificationJpaEntity) - .from(expenseNotificationJpaEntity) - .where( - expenseNotificationJpaEntity.id.in(expenseNotificationIds) - ) - .fetch(); - } + return jpaQueryFactory + .select(expenseNotificationJpaEntity) + .from(expenseNotificationJpaEntity) + .where( + expenseNotificationJpaEntity.id.in(expenseNotificationIds) + ) + .fetch(); + } } diff --git a/src/main/java/com/connect/accountApp/domain/expensenotification/application/port/in/command/ExpenseNotificationCommand.java b/src/main/java/com/connect/accountApp/domain/expensenotification/application/port/in/command/ExpenseNotificationCommand.java index c54a2bb..167ac68 100644 --- a/src/main/java/com/connect/accountApp/domain/expensenotification/application/port/in/command/ExpenseNotificationCommand.java +++ b/src/main/java/com/connect/accountApp/domain/expensenotification/application/port/in/command/ExpenseNotificationCommand.java @@ -2,6 +2,7 @@ import com.connect.accountApp.domain.expense.domain.model.ExpenseCategory; import java.math.BigDecimal; +import java.time.LocalDate; import java.time.LocalDateTime; import lombok.AccessLevel; import lombok.Getter; @@ -11,29 +12,29 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) public class ExpenseNotificationCommand { - private Long expenseNotificationId; - private Long expenseId; - private String expenseCategoryImageUrl; - private String expenseCategoryTitle; - private LocalDateTime createdAt; - private Boolean isRead; - private BigDecimal expenseAmount; - private String spenderName; + private Long expenseNotificationId; + private Long expenseId; + private String expenseCategoryImageUrl; + private String expenseCategoryTitle; + private LocalDateTime createdAt; + private Boolean isRead; + private BigDecimal expenseAmount; + private String spenderName; - public ExpenseNotificationCommand(Long expenseNotificationId, Long expenseId, - ExpenseCategory expenseCategory, LocalDateTime createdAt, Boolean isRead, - BigDecimal expenseAmount) { - this.expenseNotificationId = expenseNotificationId; - this.expenseId = expenseId; - this.expenseCategoryImageUrl = expenseCategory.getImgUrl(); - this.expenseCategoryTitle = expenseCategory.getTitle(); - this.createdAt = createdAt; - this.isRead = isRead; - this.expenseAmount = expenseAmount; -// this.spenderName = spenderName; - } + public ExpenseNotificationCommand(Long expenseNotificationId, Long expenseId, + ExpenseCategory expenseCategory, LocalDate createdAt, Boolean isRead, + BigDecimal expenseAmount, String spenderName) { + this.expenseNotificationId = expenseNotificationId; + this.expenseId = expenseId; + this.expenseCategoryImageUrl = expenseCategory.getImgUrl(); + this.expenseCategoryTitle = expenseCategory.getTitle(); + this.createdAt = createdAt.atStartOfDay(); + this.isRead = isRead; + this.expenseAmount = expenseAmount; + this.spenderName = spenderName; + } - public void setSpenderName(String spenderName) { - this.spenderName = spenderName; - } + public void setSpenderName(String spenderName) { + this.spenderName = spenderName; + } } diff --git a/src/main/java/com/connect/accountApp/domain/expensenotification/application/service/GetExpenseNotificationsService.java b/src/main/java/com/connect/accountApp/domain/expensenotification/application/service/GetExpenseNotificationsService.java index 4b70c51..2781dbf 100644 --- a/src/main/java/com/connect/accountApp/domain/expensenotification/application/service/GetExpenseNotificationsService.java +++ b/src/main/java/com/connect/accountApp/domain/expensenotification/application/service/GetExpenseNotificationsService.java @@ -20,24 +20,24 @@ public class GetExpenseNotificationsService implements GetExpenseNotificationsUs @Override public List getExpenseNotifications(String userEmail) { List commands = findExpenseNotificationPort.findExpenseNotifications(userEmail); - - List spenderCommands = FindSpenderByExpenseNotificationCommands(commands); - settingSpenderInCommands(commands, spenderCommands); +// +// List spenderCommands = FindSpenderByExpenseNotificationCommands(commands); +// settingSpenderInCommands(commands, spenderCommands); return commands; } - private List FindSpenderByExpenseNotificationCommands(List commands) { - List expenseId = commands.stream().map(ExpenseNotificationCommand::getExpenseId).toList(); - return findExpenseNotificationPort.findExpenseSpenders(expenseId); - } - - private void settingSpenderInCommands(List commands, List spenderCommands) { - Map spenderMap = convertToMap(spenderCommands); - commands.forEach(command -> command.setSpenderName(spenderMap.get(command.getExpenseId()))); - } - - private Map convertToMap(List spenderCommands) { - return spenderCommands.stream().collect( - Collectors.toMap(FindSpenderCommand::getExpenseId, FindSpenderCommand::getSpenderName)); - } +// private List FindSpenderByExpenseNotificationCommands(List commands) { +// List expenseId = commands.stream().map(ExpenseNotificationCommand::getExpenseId).toList(); +// return findExpenseNotificationPort.findExpenseSpenders(expenseId); +// } +// +// private void settingSpenderInCommands(List commands, List spenderCommands) { +// Map spenderMap = convertToMap(spenderCommands); +// commands.forEach(command -> command.setSpenderName(spenderMap.get(command.getExpenseId()))); +// } + +// private Map convertToMap(List spenderCommands) { +// return spenderCommands.stream().collect( +// Collectors.toMap(FindSpenderCommand::getExpenseId, FindSpenderCommand::getSpenderName)); +// } } diff --git a/src/main/java/com/connect/accountApp/domain/household/application/port/in/command/GetHouseholdHomeCommand.java b/src/main/java/com/connect/accountApp/domain/household/application/port/in/command/GetHouseholdHomeCommand.java index 5eadad3..0fecf58 100644 --- a/src/main/java/com/connect/accountApp/domain/household/application/port/in/command/GetHouseholdHomeCommand.java +++ b/src/main/java/com/connect/accountApp/domain/household/application/port/in/command/GetHouseholdHomeCommand.java @@ -35,7 +35,7 @@ public GetHouseholdHomeCommand(Household household, BigDecimal byNowExpense, Big this.settlementDDay = dDay; this.nowExpenseDiff = byPreviousExpense.subtract(byNowExpense); this.isHouseholdBudgetOverWarn = isHouseholdBudgetOverWarn(household.getHouseholdBudget(), pastNearSettlementDate, byNowExpense); - this.expenseDuration = Period.between(pastNearSettlementDate, LocalDate.now()).getDays(); + this.expenseDuration = Period.between(pastNearSettlementDate, LocalDate.of(2023, 11, 23)).getDays(); } private boolean isHouseholdBudgetOverWarn(BigDecimal budget, LocalDate pastNearSettlementDate, BigDecimal householdByNowExpense) { diff --git a/src/main/java/com/connect/accountApp/domain/household/application/service/GetHomeService.java b/src/main/java/com/connect/accountApp/domain/household/application/service/GetHomeService.java index d061341..d91ce52 100644 --- a/src/main/java/com/connect/accountApp/domain/household/application/service/GetHomeService.java +++ b/src/main/java/com/connect/accountApp/domain/household/application/service/GetHomeService.java @@ -4,8 +4,8 @@ import com.connect.accountApp.domain.household.application.port.in.GetHouseholdHomeUseCase; import com.connect.accountApp.domain.household.application.port.in.command.GetHouseholdHomeCommand; import com.connect.accountApp.domain.household.application.port.in.command.GetUserHomeCommand; -import com.connect.accountApp.domain.household.application.port.out.GetHouseholdPort; import com.connect.accountApp.domain.household.domain.model.Household; +import com.connect.accountApp.domain.settlement.application.port.out.FindSettlementPort; import com.connect.accountApp.domain.user.application.port.out.FindHouseholdUserListPort; import com.connect.accountApp.domain.user.application.port.out.GetUserPort; import com.connect.accountApp.domain.user.domain.model.User; @@ -22,9 +22,9 @@ public class GetHomeService implements GetHouseholdHomeUseCase { private final GetUserPort getUserPort; - private final GetHouseholdPort getHouseholdPort; private final FindHouseholdUserListPort findHouseholdUserListPort; private final GetHouseholdTotalExpensePort getHouseholdTotalExpensePort; + private final FindSettlementPort findSettlementPort; @Override public GetHouseholdHomeCommand getHouseholdHome(String userEmail) { @@ -32,16 +32,27 @@ public GetHouseholdHomeCommand getHouseholdHome(String userEmail) { User userWithHousehold = getUserPort.findUserWithHousehold(userEmail); Household household = userWithHousehold.getHousehold(); - List householdMembers = findHouseholdUserListPort.findHouseholdMembers(household.getHouseholdId()); + // 현재 날짜에서 가장 가까운 정산일을 가져온다. // 10 24 + LocalDateTime pastNearSettlementDate = getPastNearSettlementDate(LocalDate.of(2023, 11, 23), + household.getHouseholdSettlementDayOfMonth()); - // 현재 날짜에서 가장 가까운 정산일을 가져온다. - LocalDateTime pastNearSettlementDate = getPastNearSettlementDate(LocalDate.now(), household.getHouseholdSettlementDayOfMonth()); - BigDecimal householdPreviousTotalExpense = getHouseholdPreviousTotalExpense(pastNearSettlementDate, household.getHouseholdId()); + BigDecimal householdPreviousTotalExpense = getHouseholdPreviousTotalExpense(pastNearSettlementDate, + household.getHouseholdId()); // 이전 몇일간 사용한 금액 - BigDecimal householdNowTotalExpense = getHouseholdTotalExpensePort.getHouseholdTotalExpenseByDate( - household.getHouseholdId(), pastNearSettlementDate, LocalDateTime.now()).divide(BigDecimal.valueOf(householdMembers.size())); + System.out.println("householdPreviousTotalExpense = " + householdPreviousTotalExpense); - int dDay = Period.between(LocalDate.now(), pastNearSettlementDate.toLocalDate().plusMonths(1)).getDays(); +// BigDecimal householdNowTotalExpense = // 지금 몇일간 사용한 금액 +// getHouseholdTotalExpensePort.getHouseholdTotalExpenseByDate(household.getHouseholdId(), +// pastNearSettlementDate, LocalDateTime.now()); + BigDecimal householdNowTotalExpense = // 지금 몇일간 사용한 금액 + getHouseholdTotalExpensePort.getHouseholdTotalExpenseByDate(household.getHouseholdId(), + pastNearSettlementDate, pastNearSettlementDate.toLocalDate().plusMonths(1).atStartOfDay()); + + System.out.println("householdNowTotalExpense = " + householdNowTotalExpense); + +// int dDay = Period.between(LocalDate.now(), pastNearSettlementDate.toLocalDate().plusMonths(1)).getDays(); + int dDay = Period.between(pastNearSettlementDate.toLocalDate().plusMonths(1), + LocalDate.of(2023, 11, 23)).getDays() + 1; return new GetHouseholdHomeCommand(household, householdNowTotalExpense, householdPreviousTotalExpense, dDay, pastNearSettlementDate.toLocalDate()); @@ -57,51 +68,68 @@ public GetUserHomeCommand getUserHome(String userEmail) { BigDecimal userRatio = BigDecimal.valueOf(userWithHousehold.getUserRatio()); BigDecimal userTotalBudget = householdBudget.multiply(userRatio.divide(BigDecimal.valueOf(100))); - - LocalDateTime pastNearSettlementDate = getPastNearSettlementDate(LocalDate.now(), household.getHouseholdSettlementDayOfMonth()); - - BigDecimal userByNowTotalExpense = - getHouseholdTotalExpensePort.getUserTotalExpenseByDate(userWithHousehold.getUserId(), pastNearSettlementDate, LocalDateTime.now()); +// +// LocalDateTime pastNearSettlementDate = getPastNearSettlementDate(LocalDate.now(), +// household.getHouseholdSettlementDayOfMonth()); + LocalDateTime pastNearSettlementDate = getPastNearSettlementDate(LocalDate.of(2023, 11, 23), + household.getHouseholdSettlementDayOfMonth()); + +// BigDecimal userByNowTotalExpense = findSettlementPort.findUserRealExpense(userWithHousehold.getUserId(), +// pastNearSettlementDate.toLocalDate(), LocalDate.now()); + BigDecimal userByNowTotalExpense = findSettlementPort.findUserRealExpense(userWithHousehold.getUserId(), + pastNearSettlementDate.toLocalDate(), LocalDate.of(2023, 11, 23)); +// BigDecimal userByNowTotalExpense = +// getHouseholdTotalExpensePort.getUserTotalExpenseByDate(userWithHousehold.getUserId(), +// pastNearSettlementDate, LocalDateTime.now()); return new GetUserHomeCommand(userWithHousehold.getUserId(), userTotalBudget, userByNowTotalExpense); } - /** * 저번달 정산일 부터 지금으로부터 한달 전까지의 쓴 돈을 반환하는 함수 + * * @param pastNearSettlementDate : 가까운 정산일 - * @param householdId : 가구 아이디 + * @param householdId : 가구 아이디 * @return int 저번달 정산일 부터 지금으로부터 한달 전까지의 쓴 돈 */ - private BigDecimal getHouseholdPreviousTotalExpense(LocalDateTime pastNearSettlementDate, Long householdId) { - List householdMembers = findHouseholdUserListPort.findHouseholdMembers(householdId); + private BigDecimal getHouseholdPreviousTotalExpense(LocalDateTime pastNearSettlementDate, + Long householdId) { // 10월 23일 -> 9월 24일부터 10월 23일까지 + System.out.println("pastNearSettlementDate = " + pastNearSettlementDate); LocalDateTime previousStartTime = pastNearSettlementDate.toLocalDate().atStartOfDay().minusMonths(1); - LocalDateTime previousEndTime = LocalDate.now().atStartOfDay().plusDays(1).minusSeconds(1).minusMonths(1); - - BigDecimal householdTotalExpenseByDate = getHouseholdTotalExpensePort.getHouseholdTotalExpenseByDate( - householdId, previousStartTime, previousEndTime); - - return householdTotalExpenseByDate.divide(BigDecimal.valueOf(householdMembers.size())); + System.out.println("previousStartTime = " + previousStartTime); + LocalDateTime previousEndTime = LocalDate.of(2023, 11, 22).atStartOfDay().plusDays(1).minusSeconds(1) + .minusMonths(1); + System.out.println("previousEndTime = " + previousEndTime); + return getHouseholdTotalExpensePort.getHouseholdTotalExpenseByDate(householdId, previousStartTime, + previousEndTime); } /** * 현재 날짜에서 가장 가까운 정산일을 가져오는 함수 + * * @param date * @param householdSettlementDate * @return LocalDateTime : 현재와 가장 가까운 정산일 */ private LocalDateTime getPastNearSettlementDate(LocalDate date, Integer householdSettlementDate) { - if (date.getDayOfMonth() >= householdSettlementDate) { + //23 >= 23 + if (date.getDayOfMonth() > householdSettlementDate) { return LocalDate.of(date.getYear(), date.getMonth(), householdSettlementDate).atStartOfDay(); + } else if (date.getDayOfMonth() == householdSettlementDate) { + return LocalDate.of(date.getYear(), date.minusMonths(1).getMonth(), householdSettlementDate + 1) + .atStartOfDay(); } else { + // TODO : 30, 31 고려 - if(householdSettlementDate==31) { - return LocalDate.of(date.minusMonths(1).getYear(), date.minusMonths(1).getMonth(), householdSettlementDate-1).atStartOfDay(); + if (householdSettlementDate == 31) { + return LocalDate.of(date.minusMonths(1).getYear(), date.minusMonths(1).getMonth(), + householdSettlementDate - 1).atStartOfDay(); } - return LocalDate.of(date.minusMonths(1).getYear(), date.minusMonths(1).getMonth(), householdSettlementDate).atStartOfDay(); + return LocalDate.of(date.minusMonths(1).getYear(), date.minusMonths(1).getMonth(), householdSettlementDate) + .atStartOfDay(); } } diff --git a/src/main/java/com/connect/accountApp/domain/settlement/adapter/in/web/controller/GetHouseholdSettlementController.java b/src/main/java/com/connect/accountApp/domain/settlement/adapter/in/web/controller/GetHouseholdSettlementController.java index 765db64..fc81b51 100644 --- a/src/main/java/com/connect/accountApp/domain/settlement/adapter/in/web/controller/GetHouseholdSettlementController.java +++ b/src/main/java/com/connect/accountApp/domain/settlement/adapter/in/web/controller/GetHouseholdSettlementController.java @@ -34,8 +34,8 @@ public ResponseEntity getRoommateSettlement(@AuthenticationPrincipal UserDetails String userEmail = userDetails.getUsername(); - HouseholdSettlementCommand command = getHouseholdSettlementUseCase.getRoommateSettlement( - userEmail, startDate, endDate); + HouseholdSettlementCommand command = + getHouseholdSettlementUseCase.getRoommateSettlement(userEmail, startDate, endDate); System.out.println( "command.getRoommateSettlementCommands().size() = " + command.getRoommateSettlementCommands().size()); diff --git a/src/main/java/com/connect/accountApp/domain/settlement/adapter/in/web/response/HouseholdSettlementResponse.java b/src/main/java/com/connect/accountApp/domain/settlement/adapter/in/web/response/HouseholdSettlementResponse.java index db9a075..e750358 100644 --- a/src/main/java/com/connect/accountApp/domain/settlement/adapter/in/web/response/HouseholdSettlementResponse.java +++ b/src/main/java/com/connect/accountApp/domain/settlement/adapter/in/web/response/HouseholdSettlementResponse.java @@ -48,8 +48,8 @@ public class UserSettlementResponse { public UserSettlementResponse(UserSettlementCommand command) { this.id = command.getId(); this.name = command.getName(); -// this.isSettlementSender = command.getIsSettlementSender(); - this.isSettlementSender = false; + this.isSettlementSender = command.getIsSettlementSender(); +// this.isSettlementSender = false; this.settlementAmount = command.getSettlementAmount().setScale(0, RoundingMode.FLOOR); } } diff --git a/src/main/java/com/connect/accountApp/domain/settlement/adapter/out/persistence/SettlementMapper.java b/src/main/java/com/connect/accountApp/domain/settlement/adapter/out/persistence/SettlementMapper.java deleted file mode 100644 index f0f7d10..0000000 --- a/src/main/java/com/connect/accountApp/domain/settlement/adapter/out/persistence/SettlementMapper.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.connect.accountApp.domain.settlement.adapter.out.persistence; - -import com.connect.accountApp.domain.expense.adapter.out.persistence.ExpenseMapper; -import com.connect.accountApp.domain.user.adapter.out.persistence.UserMapper; -import com.connect.accountApp.domain.settlement.adapter.out.persistence.jpa.model.SettlementJpaEntity; -import com.connect.accountApp.domain.settlement.domain.model.Settlement; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Component; - -@Component -@RequiredArgsConstructor -public class SettlementMapper { - - private final ExpenseMapper expenseMapper; - private final UserMapper userMapper; - - public Settlement mapToDomainEntity(SettlementJpaEntity settlementJpaEntity) { - - return Settlement.builder() - .settlementId(settlementJpaEntity.getSettlementId()) - .expense(expenseMapper.mapToDomainEntity(settlementJpaEntity.getExpenseJpaEntity())) - .user(userMapper.mapToDomainEntity(settlementJpaEntity.getUserJpaEntity())) - .isSettlementDelegate(settlementJpaEntity.getIsSettlementDelegate()) - .build(); - } - - public SettlementJpaEntity mapToJpaEntity(Settlement settlement) { - - return SettlementJpaEntity.builder() - .settlementId(settlement.getSettlementId()) - .expenseJpaEntity(expenseMapper.mapToJpaEntity(settlement.getExpense())) - .userJpaEntity(userMapper.mapToJpaEntity(settlement.getUser())) - .isSettlementDelegate(settlement.getIsSettlementDelegate()) - .build(); - } - -} diff --git a/src/main/java/com/connect/accountApp/domain/settlement/adapter/out/persistence/SettlementPersistenceAdapter.java b/src/main/java/com/connect/accountApp/domain/settlement/adapter/out/persistence/SettlementPersistenceAdapter.java index 9cc596d..9091a00 100644 --- a/src/main/java/com/connect/accountApp/domain/settlement/adapter/out/persistence/SettlementPersistenceAdapter.java +++ b/src/main/java/com/connect/accountApp/domain/settlement/adapter/out/persistence/SettlementPersistenceAdapter.java @@ -1,11 +1,8 @@ package com.connect.accountApp.domain.settlement.adapter.out.persistence; -import com.connect.accountApp.domain.settlement.adapter.out.persistence.jpa.SettlementJpaRepository; import com.connect.accountApp.domain.settlement.application.port.out.FindSettlementPort; import com.connect.accountApp.domain.settlement.application.port.out.SaveSettlementPort; import com.connect.accountApp.domain.settlement.application.port.out.command.ExpenseOfHouseholdCommand; -import com.connect.accountApp.domain.settlement.adapter.out.persistence.jpa.model.SettlementJpaEntity; -import com.connect.accountApp.domain.settlement.domain.model.Settlement; import java.math.BigDecimal; import java.time.LocalDate; import java.util.List; @@ -16,27 +13,27 @@ @Component public class SettlementPersistenceAdapter implements SaveSettlementPort, FindSettlementPort { - private final SettlementJpaRepository settlementJpaRepository; +// private final SettlementJpaRepository settlementJpaRepository; private final SettlementQueryRepository settlementQueryRepository; - private final SettlementMapper settlementMapper; +// private final SettlementMapper settlementMapper; - @Override - public Long saveSettlement(Settlement settlement) { - SettlementJpaEntity settlementJpaEntity = settlementMapper.mapToJpaEntity(settlement); - return settlementJpaRepository.save(settlementJpaEntity).getSettlementId(); - } +// @Override +// public Long saveSettlement(Settlement settlement) { +// SettlementJpaEntity settlementJpaEntity = settlementMapper.mapToJpaEntity(settlement); +// return settlementJpaRepository.save(settlementJpaEntity).getSettlementId(); +// } @Override - public List findUserRealExpense(String userEmail, LocalDate startDate, - LocalDate endDate) { + public BigDecimal findUserRealExpense(Long userId, LocalDate startDate, LocalDate endDate) { - return settlementQueryRepository.findUserRealExpense(userEmail, startDate, endDate); + return settlementQueryRepository.findUserRealExpense(userId, startDate, endDate); } @Override public List findHouseholdExpenses(Long householdId, LocalDate startDate, LocalDate endDate) { - return settlementQueryRepository.findExpenseOfHousehold(householdId, startDate, endDate); +// return settlementQueryRepository.findExpenseOfHousehold(householdId, startDate, endDate); + return null; } } diff --git a/src/main/java/com/connect/accountApp/domain/settlement/adapter/out/persistence/SettlementQueryRepository.java b/src/main/java/com/connect/accountApp/domain/settlement/adapter/out/persistence/SettlementQueryRepository.java index d6bb9fe..7b74ae1 100644 --- a/src/main/java/com/connect/accountApp/domain/settlement/adapter/out/persistence/SettlementQueryRepository.java +++ b/src/main/java/com/connect/accountApp/domain/settlement/adapter/out/persistence/SettlementQueryRepository.java @@ -1,7 +1,6 @@ package com.connect.accountApp.domain.settlement.adapter.out.persistence; import static com.connect.accountApp.domain.expense.adapter.out.persistence.jpa.model.QExpenseJpaEntity.expenseJpaEntity; -import static com.connect.accountApp.domain.settlement.adapter.out.persistence.jpa.model.QSettlementJpaEntity.settlementJpaEntity; import static com.connect.accountApp.domain.user.adapter.out.persistence.jpa.model.QUserJpaEntity.userJpaEntity; import static com.querydsl.core.group.GroupBy.groupBy; import static com.querydsl.core.group.GroupBy.list; @@ -22,47 +21,48 @@ @Slf4j public class SettlementQueryRepository { - private final JPAQueryFactory queryFactory; + private final JPAQueryFactory queryFactory; - public List findUserRealExpense(String userEmail, LocalDate startDate, - LocalDate endDate) { + public BigDecimal findUserRealExpense(Long userId, LocalDate startDate, LocalDate endDate) { - return queryFactory - .select(settlementJpaEntity.expenseJpaEntity.expenseAmount) - .from(settlementJpaEntity) - .join(settlementJpaEntity.expenseJpaEntity, expenseJpaEntity) - .join(settlementJpaEntity.userJpaEntity, userJpaEntity) - .where( - settlementJpaEntity.expenseJpaEntity.expenseDate.between(startDate, endDate), - settlementJpaEntity.isSettlementDelegate.isTrue(), - settlementJpaEntity.userJpaEntity.userEmail.eq(userEmail) - ) - .fetch(); - } + System.out.println("userId = " + userId); + System.out.println("startDate = " + startDate); + System.out.println("endDate = " + endDate); + return queryFactory + .select(expenseJpaEntity.expenseAmount.sum()) + .from(expenseJpaEntity) + .join(expenseJpaEntity.spender, userJpaEntity) + .where( + expenseJpaEntity.expenseDate.between(startDate, endDate), + expenseJpaEntity.spender.userId.eq(userId)) + .fetchOne(); + } - public List findExpenseOfHousehold(Long householdId, LocalDate startDate, LocalDate endDate) { + public List findExpenseOfHousehold(Long householdId, LocalDate startDate, + LocalDate endDate) { - return queryFactory - .from(settlementJpaEntity) - .join(settlementJpaEntity.expenseJpaEntity, expenseJpaEntity) - .join(settlementJpaEntity.userJpaEntity, userJpaEntity) - .where( - settlementJpaEntity.expenseJpaEntity.expenseDate.between(startDate, endDate), - settlementJpaEntity.userJpaEntity.houseHoldJpaEntity.householdId.eq(householdId) - ) - .transform( - groupBy(settlementJpaEntity.expenseJpaEntity).list( - Projections.fields(ExpenseOfHouseholdCommand.class, - settlementJpaEntity.expenseJpaEntity.expenseId.as("expenseId"), - settlementJpaEntity.expenseJpaEntity.expenseAmount.as("expenseAmount"), - list( - Projections.fields(ExpenseOfHouseholdCommand.ExpenseRatioOfUser.class, - settlementJpaEntity.userJpaEntity.userId.as("userId"), - settlementJpaEntity.userJpaEntity.userRatio.as("userExpenseRatio") - ) - ).as("expenseRatioOfUsers") - ) - )); - } + return null; +// return queryFactory +// .from(settlementJpaEntity) +// .join(settlementJpaEntity.expenseJpaEntity, expenseJpaEntity) +// .join(settlementJpaEntity.userJpaEntity, userJpaEntity) +// .where( +// settlementJpaEntity.expenseJpaEntity.expenseDate.between(startDate, endDate), +// settlementJpaEntity.userJpaEntity.houseHoldJpaEntity.householdId.eq(householdId) +// ) +// .transform( +// groupBy(settlementJpaEntity.expenseJpaEntity).list( +// Projections.fields(ExpenseOfHouseholdCommand.class, +// settlementJpaEntity.expenseJpaEntity.expenseId.as("expenseId"), +// settlementJpaEntity.expenseJpaEntity.expenseAmount.as("expenseAmount"), +// list( +// Projections.fields(ExpenseOfHouseholdCommand.ExpenseRatioOfUser.class, +// settlementJpaEntity.userJpaEntity.userId.as("userId"), +// settlementJpaEntity.userJpaEntity.userRatio.as("userExpenseRatio") +// ) +// ).as("expenseRatioOfUsers") +// ) +// )); + } } diff --git a/src/main/java/com/connect/accountApp/domain/settlement/adapter/out/persistence/jpa/SettlementJpaRepository.java b/src/main/java/com/connect/accountApp/domain/settlement/adapter/out/persistence/jpa/SettlementJpaRepository.java deleted file mode 100644 index 0488999..0000000 --- a/src/main/java/com/connect/accountApp/domain/settlement/adapter/out/persistence/jpa/SettlementJpaRepository.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.connect.accountApp.domain.settlement.adapter.out.persistence.jpa; - -import com.connect.accountApp.domain.settlement.adapter.out.persistence.jpa.model.SettlementJpaEntity; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface SettlementJpaRepository extends JpaRepository { - -} diff --git a/src/main/java/com/connect/accountApp/domain/settlement/adapter/out/persistence/jpa/model/SettlementJpaEntity.java b/src/main/java/com/connect/accountApp/domain/settlement/adapter/out/persistence/jpa/model/SettlementJpaEntity.java deleted file mode 100644 index 265072a..0000000 --- a/src/main/java/com/connect/accountApp/domain/settlement/adapter/out/persistence/jpa/model/SettlementJpaEntity.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.connect.accountApp.domain.settlement.adapter.out.persistence.jpa.model; - -import com.connect.accountApp.domain.expense.adapter.out.persistence.jpa.model.ExpenseJpaEntity; -import com.connect.accountApp.domain.user.adapter.out.persistence.jpa.model.UserJpaEntity; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.Table; -import lombok.AccessLevel; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Entity -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Table(name = "settlement") -public class SettlementJpaEntity { - - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long settlementId; - - @ManyToOne - @JoinColumn(name = "expense_id") - private ExpenseJpaEntity expenseJpaEntity; - - @ManyToOne - @JoinColumn(name = "user_id") - private UserJpaEntity userJpaEntity; - - private Boolean isSettlementDelegate; - - @Builder - public SettlementJpaEntity(Long settlementId, - ExpenseJpaEntity expenseJpaEntity, - UserJpaEntity userJpaEntity, Boolean isSettlementDelegate) { - this.settlementId = settlementId; - this.expenseJpaEntity = expenseJpaEntity; - this.userJpaEntity = userJpaEntity; - this.isSettlementDelegate = isSettlementDelegate; - } -} diff --git a/src/main/java/com/connect/accountApp/domain/settlement/application/port/in/command/ReceiverCommand.java b/src/main/java/com/connect/accountApp/domain/settlement/application/port/in/command/ReceiverCommand.java new file mode 100644 index 0000000..16d4336 --- /dev/null +++ b/src/main/java/com/connect/accountApp/domain/settlement/application/port/in/command/ReceiverCommand.java @@ -0,0 +1,25 @@ +package com.connect.accountApp.domain.settlement.application.port.in.command; + +import java.math.BigDecimal; + +public class ReceiverCommand { + private Long receiverId; + private BigDecimal receiverAmount; + + public ReceiverCommand(Long receiverId, BigDecimal receiverAmount) { + this.receiverId = receiverId; + this.receiverAmount = receiverAmount; + } + + public BigDecimal getReceiverAmount() { + return receiverAmount; + } + + public void setReceiverAmount(BigDecimal receiverAmount) { + this.receiverAmount = receiverAmount; + } + + public Long getReceiverId() { + return receiverId; + } +} diff --git a/src/main/java/com/connect/accountApp/domain/settlement/application/port/in/command/SenderCommand.java b/src/main/java/com/connect/accountApp/domain/settlement/application/port/in/command/SenderCommand.java new file mode 100644 index 0000000..6225201 --- /dev/null +++ b/src/main/java/com/connect/accountApp/domain/settlement/application/port/in/command/SenderCommand.java @@ -0,0 +1,25 @@ +package com.connect.accountApp.domain.settlement.application.port.in.command; + +import java.math.BigDecimal; + +public class SenderCommand { + private Long senderId; + private BigDecimal SenderAmount; + + public SenderCommand(Long senderId, BigDecimal senderAmount) { + this.senderId = senderId; + SenderAmount = senderAmount; + } + + public BigDecimal getSenderAmount() { + return SenderAmount; + } + + public void setSenderAmount(BigDecimal senderAmount) { + SenderAmount = senderAmount; + } + + public Long getSenderId() { + return senderId; + } +} diff --git a/src/main/java/com/connect/accountApp/domain/settlement/application/port/in/command/SettlementCommand.java b/src/main/java/com/connect/accountApp/domain/settlement/application/port/in/command/SettlementCommand.java index c30a4f0..e00a5c2 100644 --- a/src/main/java/com/connect/accountApp/domain/settlement/application/port/in/command/SettlementCommand.java +++ b/src/main/java/com/connect/accountApp/domain/settlement/application/port/in/command/SettlementCommand.java @@ -6,13 +6,41 @@ @Getter public class SettlementCommand { - private Long giverId; - private Long senderId; - private BigDecimal settlementAmount; - - public SettlementCommand(Long giverId, Long senderId, BigDecimal settlementAmount) { - this.giverId = giverId; - this.senderId = senderId; - this.settlementAmount = settlementAmount; - } + private Long giverId; + private Long senderId; + private BigDecimal settlementAmount; + + public SettlementCommand(Long giverId, Long senderId, BigDecimal settlementAmount) { + this.giverId = giverId; + this.senderId = senderId; + this.settlementAmount = settlementAmount; + } + + @Override + public String toString() { + return "SettlementCommand{" + + "giverId=" + giverId + + ", senderId=" + senderId + + ", settlementAmount=" + settlementAmount + + '}'; + } + +// // 내가 sender면 command에서 sender인 애들을 가져와 +// // 그 다음 sender가 같으면 filetering 된다. +// public Boolean isSettlement(Long userId) { +// if (this.giverId == userId) { +// +// } +// } } + +// 지출 등록 +// 달별 지출 조회 +// 일별 지출 조회 +// 지출 1건 조회 +// 지출 검색 + +// 정산 +// 사용자 정산 +// 멤버별 정산 +// 홈 정산 \ No newline at end of file diff --git a/src/main/java/com/connect/accountApp/domain/settlement/application/port/in/command/UserSettlementCommand.java b/src/main/java/com/connect/accountApp/domain/settlement/application/port/in/command/UserSettlementCommand.java index dd4530c..2e580d2 100644 --- a/src/main/java/com/connect/accountApp/domain/settlement/application/port/in/command/UserSettlementCommand.java +++ b/src/main/java/com/connect/accountApp/domain/settlement/application/port/in/command/UserSettlementCommand.java @@ -20,12 +20,9 @@ public class UserSettlementCommand { public UserSettlementCommand(Long id, String name, BigDecimal realExpense, BigDecimal ratioExpense) { this.id = id; this.name = name; -// this.realExpense = realExpense; - this.realExpense = BigDecimal.valueOf(255875); -// this.ratioExpense = ratioExpense; - this.ratioExpense = BigDecimal.valueOf(222500); -// this.isSettlementSender = realExpense.compareTo(ratioExpense) < 0; // realExpense < ratioExpense : 보내는 사람 - this.isSettlementSender = false; // realExpense < ratioExpense : 보내는 사람 + this.realExpense = realExpense; + this.ratioExpense = ratioExpense; + this.isSettlementSender = isSender(realExpense, ratioExpense); this.settlementAmount = realExpense.subtract(ratioExpense).abs(); } @@ -36,4 +33,14 @@ public UserSettlementCommand(Long id, String name, Boolean isSettlementSender, this.isSettlementSender = isSettlementSender; this.settlementAmount = settlementAmount; } + + private Boolean isSender(BigDecimal realExpense, BigDecimal ratioExpense) { + BigDecimal userSettlement = realExpense.subtract(ratioExpense); + if (userSettlement.compareTo(BigDecimal.ZERO) > 0) { // userSettlement가 양수임 -> 실제 지출 금액이 크니까 받아야지 + return false; + } + return true; + } + + } diff --git a/src/main/java/com/connect/accountApp/domain/settlement/application/port/out/FindSettlementPort.java b/src/main/java/com/connect/accountApp/domain/settlement/application/port/out/FindSettlementPort.java index ead3075..4b4505b 100644 --- a/src/main/java/com/connect/accountApp/domain/settlement/application/port/out/FindSettlementPort.java +++ b/src/main/java/com/connect/accountApp/domain/settlement/application/port/out/FindSettlementPort.java @@ -7,7 +7,7 @@ public interface FindSettlementPort { - List findUserRealExpense(String userEmail, LocalDate startDate, LocalDate endDate); + BigDecimal findUserRealExpense(Long userId, LocalDate startDate, LocalDate endDate); List findHouseholdExpenses(Long householdId, LocalDate startDate, LocalDate endDate); diff --git a/src/main/java/com/connect/accountApp/domain/settlement/application/port/out/SaveSettlementPort.java b/src/main/java/com/connect/accountApp/domain/settlement/application/port/out/SaveSettlementPort.java index 2dbf2c5..b570785 100644 --- a/src/main/java/com/connect/accountApp/domain/settlement/application/port/out/SaveSettlementPort.java +++ b/src/main/java/com/connect/accountApp/domain/settlement/application/port/out/SaveSettlementPort.java @@ -1,9 +1,7 @@ package com.connect.accountApp.domain.settlement.application.port.out; -import com.connect.accountApp.domain.settlement.domain.model.Settlement; - public interface SaveSettlementPort { - Long saveSettlement(Settlement settlement); +// Long saveSettlement(Settlement settlement); } diff --git a/src/main/java/com/connect/accountApp/domain/settlement/application/service/GetHouseholdSettlementService.java b/src/main/java/com/connect/accountApp/domain/settlement/application/service/GetHouseholdSettlementService.java index a34d702..f2a183b 100644 --- a/src/main/java/com/connect/accountApp/domain/settlement/application/service/GetHouseholdSettlementService.java +++ b/src/main/java/com/connect/accountApp/domain/settlement/application/service/GetHouseholdSettlementService.java @@ -1,23 +1,26 @@ package com.connect.accountApp.domain.settlement.application.service; +import com.connect.accountApp.domain.expense.application.port.out.FindExpensePort; import com.connect.accountApp.domain.settlement.application.port.in.GetHouseholdSettlementUseCase; import com.connect.accountApp.domain.settlement.application.port.in.command.HouseholdSettlementCommand; +import com.connect.accountApp.domain.settlement.application.port.in.command.ReceiverCommand; +import com.connect.accountApp.domain.settlement.application.port.in.command.RoommateSettlementCommand; +import com.connect.accountApp.domain.settlement.application.port.in.command.SenderCommand; import com.connect.accountApp.domain.settlement.application.port.in.command.SettlementCommand; import com.connect.accountApp.domain.settlement.application.port.in.command.UserSettlementCommand; import com.connect.accountApp.domain.settlement.application.port.out.FindSettlementPort; -import com.connect.accountApp.domain.settlement.application.port.out.command.ExpenseOfHouseholdCommand; -import com.connect.accountApp.domain.settlement.application.port.out.command.ExpenseOfHouseholdCommand.ExpenseRatioOfUser; import com.connect.accountApp.domain.user.application.port.out.FindHouseholdUserListPort; import com.connect.accountApp.domain.user.application.port.out.GetUserPort; import com.connect.accountApp.domain.user.domain.model.User; -import com.connect.accountApp.domain.settlement.application.port.in.command.RoommateSettlementCommand; import java.math.BigDecimal; import java.time.LocalDate; import java.util.ArrayList; +import java.util.Collections; import java.util.Comparator; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.TreeMap; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -25,263 +28,191 @@ @RequiredArgsConstructor public class GetHouseholdSettlementService implements GetHouseholdSettlementUseCase { - private final GetUserPort getUserPort; - private final FindHouseholdUserListPort findHouseholdUserListPort; - private final FindSettlementPort findSettlementPort; - -// private Map creditorMap = new LinkedHashMap<>(); -// private Map debtorMap = new LinkedHashMap<>(); -// -// private List settlements = new ArrayList<>(); - - - - @Override - public HouseholdSettlementCommand getRoommateSettlement(String userEmail, LocalDate startDate, LocalDate endDate) { - - Map creditorMap = new LinkedHashMap<>(); - Map debtorMap = new LinkedHashMap<>(); - List settlements = new ArrayList<>(); - - User user = getUserPort.findUserWithHousehold(userEmail); - BigDecimal userSettlement = getUserSettlement(user, startDate, endDate); - + private final GetUserPort getUserPort; + private final FindHouseholdUserListPort findHouseholdUserListPort; + private final FindSettlementPort findSettlementPort; + private final FindExpensePort findExpensePort; + + + @Override + public HouseholdSettlementCommand getRoommateSettlement(String userEmail, LocalDate startDate, LocalDate endDate) { + + User user = getUserPort.findUserWithHousehold(userEmail); + BigDecimal householdTotalExpenses = + findExpensePort.findHouseholdTotalExpenses(user.getHousehold().getHouseholdId(), startDate, + endDate); // 가구에서 전체 사용한 돈 + BigDecimal userRealExpense = findSettlementPort.findUserRealExpense(user.getUserId(), startDate, + endDate); // 실제 지출한 돈 + + BigDecimal userRatioExpense = householdTotalExpenses.multiply( + BigDecimal.valueOf(user.getUserRatio() / 100.0)); // 지출해야 하는 돈(실제 가구가 사용한 돈에서) + + // 실제 지출한 돈 - 지출 해야하는 돈 -> 실제 지출한 돈이 더 크면, 즉 양수면 받아야지 => sender : false + BigDecimal userSettlement = userRealExpense.subtract(userRatioExpense).abs(); + + UserSettlementCommand userSettlementCommand = new UserSettlementCommand(user.getUserId(), + user.getUserNickname(), + userRealExpense, userRatioExpense); + + List allMembers = findHouseholdUserListPort.findHouseholdUserList(user.getHousehold()); + List members = allMembers.stream().filter(member -> !Objects.equals(member.getUserId(), user.getUserId())) + .toList(); + + int ratioSum = members.stream() + .mapToInt(User::getUserRatio) + .sum(); + + System.out.println("ratioSum = " + ratioSum); + + List roommateSettlementCommands = members.stream() + .map(member -> new RoommateSettlementCommand(member.getUserNickname(), member.getUserId(), + userSettlement.multiply(BigDecimal.valueOf(member.getUserRatio() / (double) ratioSum)), + member.getUserAccountBank().getBankName(), member.getUserAccount())).toList(); + + List commands = test(user, startDate, endDate); + //(String name, Long id, BigDecimal settlementAmount, String accountBank, String accountNumber) + List senderCommands = commands.stream() + .filter(command -> command.getSenderId() == user.getUserId() || command.getGiverId() == user.getUserId()).toList(); + + /* + private Long giverId; + private Long senderId; + private BigDecimal settlementAmount; + */ + + /* + private String name; + private Long id; + private BigDecimal settlementAmount; + private String accountBank; + private String accountNumber; + */ + List roommateSettlementCommands1; + if (!userSettlementCommand.getIsSettlementSender()) { + // 만약 user가 sender면 + roommateSettlementCommands1 = senderCommands.stream().map(command -> { + User user1 = getUserPort.getUser(command.getGiverId()); + return new RoommateSettlementCommand(user1.getUserNickname(), user1.getUserId(), + command.getSettlementAmount(), user1.getUserAccountBank().getBankName(), + user1.getUserAccount()); + }).toList(); + } else { + //giver라면 + roommateSettlementCommands1 = senderCommands.stream().map(command -> { + User user1 = getUserPort.getUser(command.getSenderId()); + return new RoommateSettlementCommand(user1.getUserNickname(), user1.getUserId(), + command.getSettlementAmount(), user1.getUserAccountBank().getBankName(), user1.getUserAccount()); + }).toList(); + } - addSettlementToMap(userSettlement, user, creditorMap, debtorMap); - List householdMembers = findHouseholdUserListPort.findHouseholdMembers(user.getHousehold().getHouseholdId()); - List householdMembersWithoutUser = householdMembers.stream().filter( - householdMember -> !user.getUserId().equals(householdMember.getUserId())).toList(); - householdMembersWithoutUser.forEach( - householdMember -> { - BigDecimal settlement = getUserSettlement(householdMember, startDate, endDate); - addSettlementToMap(settlement, householdMember, creditorMap, debtorMap); - } - ); - List keySetDesc = sortMap(creditorMap); - List keySetAsc = sortMap(debtorMap); - for (Long hi : keySetDesc) { - System.out.println("hi = " + hi); - } - for (Long hi : keySetAsc) { - System.out.println("hi = " + hi); + return new HouseholdSettlementCommand(userSettlementCommand, roommateSettlementCommands1); } - // 1. 먼저 같은 얘들은 빼기 - findEqualSettlement(keySetDesc, keySetAsc, creditorMap, debtorMap, settlements); + private List test(User user, LocalDate startDate, LocalDate endDate) { - for (Long hi : creditorMap.keySet()) { - System.out.println("creditor " + creditorMap.get(hi)); - } - - for (Long hi : debtorMap.keySet()) { - System.out.println("debtor " + debtorMap.get(hi)); - } + Map sender = new TreeMap<>(); + Map receiver = new TreeMap<>(); - //2. 제일 큰 얘들부터 비교해가며 빼주기 + List allMembers = findHouseholdUserListPort.findHouseholdUserList(user.getHousehold()); - for (int i = 0; i < keySetDesc.size(); i++) { - Long key = keySetDesc.get(i); - BigDecimal creditorSettlement = creditorMap.get(key); + List users = allMembers.stream().map(member -> getUserPort.findUserWithHousehold(member.getUserEmail())) + .toList(); + List userSettlementCommands = users.stream() + .map(member -> getUserSettlementCommand(member, startDate, endDate)) + .toList(); + userSettlementCommands.forEach( + userSettlementCommand -> addSettlementMap(userSettlementCommand, sender, receiver)); - for (int j = 0; j < keySetAsc.size(); j++) { - Long key2 = keySetAsc.get(j); - BigDecimal debtorSettlement = debtorMap.get(key2); - if (creditorSettlement.compareTo(debtorSettlement) < 0) { // 채권자가 받을 돈이 채무자가 줄 돈보다 작다면 - settlements.add(new SettlementCommand(key2, key, creditorSettlement)); - debtorMap.replace(key2 ,debtorMap.get(key2).subtract(creditorSettlement)); - creditorMap.remove(key); - keySetDesc.remove(key); - i--; - break; + List senderCommands = new ArrayList<>(); + List receiverCommands = new ArrayList<>(); - } else { // // 채권자가 받을 돈이 채무자가 줄 돈보다 크다면 - settlements.add(new SettlementCommand(key2, key, debtorSettlement)); - creditorMap.replace(key ,creditorMap.get(key).subtract(debtorSettlement)); - debtorMap.remove(key2); - keySetAsc.remove(key2); - j--; + for (Long senderId : sender.keySet()) { + BigDecimal settlementAmount = sender.get(senderId); + senderCommands.add(new SenderCommand(senderId, settlementAmount)); } - } - } + for (Long receiverId : receiver.keySet()) { + BigDecimal settlementAmount = receiver.get(receiverId); + receiverCommands.add(new ReceiverCommand(receiverId, settlementAmount)); + } - System.out.println("settlements.size() = " + settlements.size()); // 여기에 값이 없음. - List filteredSettlements = settlements.stream() - .filter(settlement -> { - System.out.println("settlement.getSenderId() = " + settlement.getSenderId()); - System.out.println("settlement.getGiverId() = " + settlement.getGiverId()); - System.out.println("settlement.getSettlementAmount() = " + settlement.getSettlementAmount()); - return (settlement.getGiverId().equals(user.getUserId()) || settlement.getSenderId().equals(user.getUserId())); - }).toList(); + Collections.sort(senderCommands, Comparator.comparing(SenderCommand::getSenderAmount).reversed()); + Collections.sort(receiverCommands, Comparator.comparing(ReceiverCommand::getReceiverAmount).reversed()); - System.out.println("size " + filteredSettlements.size()); + // 위까지 정렬 끝! - boolean isSender; + List settlementCommands = new ArrayList<>(); - System.out.println(" ========="); - if (filteredSettlements.isEmpty()) { - isSender = false; - } else if (filteredSettlements.get(0).getSenderId().equals(user.getUserId())) { - isSender = true; - } else { - isSender = false; - } + // 보내는 사람 입장이 제일 클 때 - System.out.println(" ========="); + int i = 0; + int j = 0; + while (i < senderCommands.size() && j < receiverCommands.size()) { - List RoommateSettlementCommands; - BigDecimal totalAmount = filteredSettlements.stream().map(SettlementCommand::getSettlementAmount) - .reduce(BigDecimal.ZERO, BigDecimal::add); + SenderCommand senderCommand = senderCommands.get(i); + BigDecimal senderAmount = senderCommand.getSenderAmount(); - UserSettlementCommand userSettlementCommand = new UserSettlementCommand(user.getUserId(), - user.getUserNickname(), true, totalAmount); + ReceiverCommand receiverCommand = receiverCommands.get(j); + BigDecimal receiverAmount = receiverCommand.getReceiverAmount(); - RoommateSettlementCommands = getRoommateSettlementCommands(filteredSettlements, isSender); - return new HouseholdSettlementCommand(userSettlementCommand, RoommateSettlementCommands); - } - - private List getRoommateSettlementCommands( - List filteredSettlements, boolean isSender) { - List commands; - if (isSender) { - commands = filteredSettlements.stream().map( - filteredSettlement -> { - User giver = getUserPort.getUser(filteredSettlement.getGiverId()); - return new RoommateSettlementCommand( - giver.getUserNickname(), - giver.getUserId(), - filteredSettlement.getSettlementAmount(), - giver.getUserAccountBank().name(), - giver.getUserAccount()); + if (senderAmount.compareTo(receiverAmount) <= 0) { + receiverCommand.setReceiverAmount(receiverAmount.subtract(senderAmount));// reciever는 빼준다. + senderCommand.setSenderAmount(BigDecimal.ZERO); + settlementCommands.add( + new SettlementCommand(senderCommand.getSenderId(), receiverCommand.getReceiverId(), + senderAmount)); + } else { + senderCommand.setSenderAmount(senderAmount.subtract(receiverAmount));// sender에서 빼준다. + receiverCommand.setReceiverAmount(BigDecimal.ZERO); + settlementCommands.add( + new SettlementCommand(senderCommand.getSenderId(), receiverCommand.getReceiverId(), + receiverAmount)); + } + if (senderCommand.getSenderAmount().equals(BigDecimal.ZERO)) { + i++; + } - } + if (receiverCommand.getReceiverAmount().equals(BigDecimal.ZERO)) { + j++; + } - ).toList(); + } - } else { - commands = filteredSettlements.stream().map( - filteredSettlement -> { - User giver = getUserPort.getUser(filteredSettlement.getSenderId()); - return new RoommateSettlementCommand( - giver.getUserNickname(), - giver.getUserId(), - filteredSettlement.getSettlementAmount(), - giver.getUserAccountBank().name(), - giver.getUserAccount()); - } + for (SettlementCommand command : settlementCommands) { + System.out.println("command = " + command); + } - ).toList(); + return settlementCommands; } - return commands; - } - - - private void payBackSettlement() { - - } - - private void findEqualSettlement(List keySetDesc, List keySetAsc, - Map creditorMap, Map debtorMap, - List settlements) { - for (Long key : keySetDesc) { - BigDecimal bigDecimal = creditorMap.get(key); - for (Long key2 : keySetAsc) { - if(debtorMap.get(key2).equals(bigDecimal)) { // - 주는 것, + 받는 것 - settlements.add(new SettlementCommand(key2, key, bigDecimal)); - creditorMap.remove(key); - debtorMap.remove(key2); - keySetDesc.remove(key); - keySetAsc.remove(key2); + + private void addSettlementMap(UserSettlementCommand userSettlementCommand, + Map sender, + Map receiver) { + if (userSettlementCommand.getIsSettlementSender()) { + sender.put(userSettlementCommand.getId(), userSettlementCommand.getSettlementAmount()); + } else { + receiver.put(userSettlementCommand.getId(), userSettlementCommand.getSettlementAmount()); } - } } - } - private void addSettlementToMap(BigDecimal userSettlement, User user, Map creditorMap, Map debtorMap) { - if (userSettlement.compareTo(BigDecimal.ZERO) < 0) { - debtorMap.put(user.getUserId(), userSettlement.abs()); - } else if (userSettlement.compareTo(BigDecimal.ZERO) > 0) { - creditorMap.put(user.getUserId(), userSettlement); + private UserSettlementCommand getUserSettlementCommand(User user, LocalDate startDate, LocalDate endDate) { + BigDecimal householdTotalExpenses = + findExpensePort.findHouseholdTotalExpenses(user.getHousehold().getHouseholdId(), startDate, endDate); + BigDecimal userRatioExpense = householdTotalExpenses.multiply(BigDecimal.valueOf(user.getUserRatio() / 100.0)); + BigDecimal userRealExpense = findSettlementPort.findUserRealExpense(user.getUserId(), startDate, + endDate); // 실제 지출한 돈 + return new UserSettlementCommand(user.getUserId(), user.getUserNickname(), + userRealExpense, userRatioExpense); } - } - - private List sortMap(Map map) { - - List keySetDesc = new ArrayList<>(map.keySet()); - - keySetDesc.sort(new Comparator() { // 내림차순 정렬 - @Override - public int compare(Long o1, Long o2) { - return map.get(o2).compareTo(map.get(o1)); //todo : bigdecimal compareTo 정리 - } - }); - - return keySetDesc; - } - // 이 아래부터 userSettlement 와 중복임 - - - private BigDecimal getUserSettlement(User user, LocalDate from, LocalDate to) { - BigDecimal userTotalRealExpense = getUserTotalRealExpense(user.getUserEmail(), from, to); - BigDecimal userRatioExpense = getUserRatioExpense(user, from, to); - return userTotalRealExpense.subtract(userRatioExpense); // 실제 지출 - 정산 비율 : (-) 주어야 하는 입장 : 채무자, (+) 받아야하는 입장 : 채권자 - } - - private BigDecimal getUserTotalRealExpense(String userEmail, LocalDate from, LocalDate to) { - List userRealExpenses = findSettlementPort.findUserRealExpense(userEmail, from, to); - return userRealExpenses.stream().reduce(BigDecimal.ZERO, BigDecimal::add); - } - - private BigDecimal getUserRatioExpense(User user, LocalDate from, LocalDate to) { - List expenseOfHouseholdCommands = findSettlementPort.findHouseholdExpenses(user.getHousehold().getHouseholdId(), from, to); - List filteredExpenseOfHouseholdCommands = filterExpenseOfHouseholdCommandIncludingUser(expenseOfHouseholdCommands, user); - - return getUserRatioExpense(filteredExpenseOfHouseholdCommands, user); - } - - - private List filterExpenseOfHouseholdCommandIncludingUser(List commands, User user) { - - return commands.stream() - .filter(expenseOfHouseholdCommand -> expenseOfHouseholdCommand - .getExpenseRatioOfUsers() - .stream().anyMatch( - expenseRatioOfUser -> expenseRatioOfUser.getUserId().equals(user.getUserId()))) - .toList(); - } - - private BigDecimal getUserRatioExpense( - List filteredExpenseOfHouseholdCommands, User user) { - - return filteredExpenseOfHouseholdCommands.stream() - .map( - expenseOfHouseholdCommand -> { - BigDecimal userRealRatio = getUserRealRatio(expenseOfHouseholdCommand, user); - - return expenseOfHouseholdCommand.getExpenseAmount().multiply(userRealRatio); - } - ).reduce(BigDecimal.ZERO, BigDecimal::add); - - } - - private BigDecimal getUserRealRatio(ExpenseOfHouseholdCommand expenseOfHouseholdCommand, User user) { - - List expenseRatioOfUsers = expenseOfHouseholdCommand.getExpenseRatioOfUsers(); - - int ratioSumOfUsers = expenseRatioOfUsers.stream() - .mapToInt(ExpenseRatioOfUser::getUserExpenseRatio) - .sum(); - return BigDecimal.valueOf(user.getUserRatio() / (double) ratioSumOfUsers); - } } diff --git a/src/main/java/com/connect/accountApp/domain/settlement/application/service/GetUserSettlementService.java b/src/main/java/com/connect/accountApp/domain/settlement/application/service/GetUserSettlementService.java index f615035..e1b3702 100644 --- a/src/main/java/com/connect/accountApp/domain/settlement/application/service/GetUserSettlementService.java +++ b/src/main/java/com/connect/accountApp/domain/settlement/application/service/GetUserSettlementService.java @@ -1,15 +1,14 @@ package com.connect.accountApp.domain.settlement.application.service; +import com.connect.accountApp.domain.expense.application.port.out.FindExpensePort; +import com.connect.accountApp.domain.expense.application.port.out.GetHouseholdTotalExpensePort; import com.connect.accountApp.domain.settlement.application.port.in.GetUserSettlementUseCase; +import com.connect.accountApp.domain.settlement.application.port.in.command.UserSettlementWithHouseholdTotalExpenseCommand; import com.connect.accountApp.domain.settlement.application.port.out.FindSettlementPort; -import com.connect.accountApp.domain.settlement.application.port.out.command.ExpenseOfHouseholdCommand; -import com.connect.accountApp.domain.settlement.application.port.out.command.ExpenseOfHouseholdCommand.ExpenseRatioOfUser; import com.connect.accountApp.domain.user.application.port.out.GetUserPort; import com.connect.accountApp.domain.user.domain.model.User; -import com.connect.accountApp.domain.settlement.application.port.in.command.UserSettlementWithHouseholdTotalExpenseCommand; import java.math.BigDecimal; import java.time.LocalDate; -import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -19,97 +18,29 @@ public class GetUserSettlementService implements GetUserSettlementUseCase { private final GetUserPort getUserPort; private final FindSettlementPort findSettlementPort; + private final GetHouseholdTotalExpensePort getHouseholdTotalExpensePort; @Override public UserSettlementWithHouseholdTotalExpenseCommand getUserSettlement(String userEmail, LocalDate startDate, LocalDate endDate) { User user = getUserPort.findUserWithHousehold(userEmail); + BigDecimal userRealTotalExpense = getUserTotalRealExpense(user.getUserId(), startDate, endDate); - BigDecimal userRealTotalExpense = getUserTotalRealExpense(userEmail, startDate, endDate); - - List expenseOfHouseholdCommands = findSettlementPort.findHouseholdExpenses(user.getHousehold().getHouseholdId(), startDate, endDate); - - List filteredExpenseOfHouseholdCommands = filterExpenseOfHouseholdCommandIncludingUser(expenseOfHouseholdCommands, user); - - BigDecimal userRatioExpense = getUserRatioExpense(filteredExpenseOfHouseholdCommands, user); - - BigDecimal householdTotalExpense = getHouseholdTotalExpense(expenseOfHouseholdCommands); + BigDecimal householdTotalExpense = + getHouseholdTotalExpensePort.getHouseholdTotalExpenseByDate(user.getHousehold().getHouseholdId(), startDate.atStartOfDay(), endDate.atStartOfDay()); + BigDecimal userRatioExpense = householdTotalExpense.multiply(BigDecimal.valueOf(user.getUserRatio() / 100.0)); return new UserSettlementWithHouseholdTotalExpenseCommand(householdTotalExpense, userRealTotalExpense, userRatioExpense, user); } /** * 사용자의 실제 지출의 총 합을 반환하는 함수 - * @param userEmail user의 이메일 값 + * @param userId user의 아이디 값 * @param from 지출 소비 시작 날짜 * @param to 지출 소비 마지막 날짜 * @return user의 from에서 to까지 실제 지출의 총 합을 반환 */ - private BigDecimal getUserTotalRealExpense(String userEmail, LocalDate from, LocalDate to) { - List userRealExpenses = findSettlementPort.findUserRealExpense(userEmail, from, to); - return userRealExpenses.stream().reduce(BigDecimal.ZERO, BigDecimal::add); - } - - /** - * 사용자가 지출한 소비 내역만 반환 - * @param commands ExpenseOfHouseholdCommand 리스트 객체 - * @param user 포함되어야하는 사용자 - * @return user를 포함하는 ExpenseOfHouseholdCommand 객체 리스트 - */ - private List filterExpenseOfHouseholdCommandIncludingUser(List commands, User user) { - - return commands.stream() - .filter(expenseOfHouseholdCommand -> expenseOfHouseholdCommand - .getExpenseRatioOfUsers() - .stream().anyMatch( - expenseRatioOfUser -> expenseRatioOfUser.getUserId().equals(user.getUserId()))) - .toList(); - } - - /** - * 가구 전체의 총 지출 반환 - * @param expenseOfHouseholdCommands (어떤 일자 범위 내의) 지출 내역 리스트 - * @return expenseOfHouseholdCommands 내의 모든 지출(expenseAmount)을 더하여 반환 - */ - private BigDecimal getHouseholdTotalExpense(List expenseOfHouseholdCommands) { - return expenseOfHouseholdCommands.stream() - .map(ExpenseOfHouseholdCommand::getExpenseAmount) - .reduce(BigDecimal.ZERO, BigDecimal::add); + private BigDecimal getUserTotalRealExpense(Long userId, LocalDate from, LocalDate to) { + return findSettlementPort.findUserRealExpense(userId, from, to); } - - /** - * 주어진 사용자의 비율에 따른 정산 값 계산 - * @param filteredExpenseOfHouseholdCommands 각 지출에 대한 소비 비율이 들어있는 객체 - * @param user 사용자 - * @return 주어진 사용자의 비율에 따른 정산 값의 총합 반환 - */ - private BigDecimal getUserRatioExpense( - List filteredExpenseOfHouseholdCommands, User user) { - - return filteredExpenseOfHouseholdCommands.stream() - .map( - expenseOfHouseholdCommand -> { - BigDecimal userRealRatio = getUserRealRatio(expenseOfHouseholdCommand, user); - - return expenseOfHouseholdCommand.getExpenseAmount().multiply(userRealRatio); - } - ).reduce(BigDecimal.ZERO, BigDecimal::add); - - } - - /** - * 지출한 가구원들 사이에서 사용자가 실제 담당해야할 비율 계산 - * @return 사용자가 실제 담당해야할 비율 반환 - */ - private BigDecimal getUserRealRatio(ExpenseOfHouseholdCommand expenseOfHouseholdCommand, User user) { - - List expenseRatioOfUsers = expenseOfHouseholdCommand.getExpenseRatioOfUsers(); - - int ratioSumOfUsers = expenseRatioOfUsers.stream() - .mapToInt(ExpenseRatioOfUser::getUserExpenseRatio) - .sum(); - - return BigDecimal.valueOf(user.getUserRatio() / (double) ratioSumOfUsers); - } - } diff --git a/src/main/java/com/connect/accountApp/domain/settlement/domain/model/Settlement.java b/src/main/java/com/connect/accountApp/domain/settlement/domain/model/Settlement.java deleted file mode 100644 index 50e72d9..0000000 --- a/src/main/java/com/connect/accountApp/domain/settlement/domain/model/Settlement.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.connect.accountApp.domain.settlement.domain.model; - -import com.connect.accountApp.domain.expense.domain.model.Expense; -import com.connect.accountApp.domain.user.domain.model.User; -import lombok.AccessLevel; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -public class Settlement { - - private Long settlementId; - private Expense expense; - private User user; - private Boolean isSettlementDelegate; - - @Builder - public Settlement(Long settlementId, Expense expense, User user, Boolean isSettlementDelegate) { - this.settlementId = settlementId; - this.expense = expense; - this.user = user; - this.isSettlementDelegate = isSettlementDelegate; - } -} diff --git a/src/main/java/com/connect/accountApp/domain/user/application/service/GetSettlementRoommatesService.java b/src/main/java/com/connect/accountApp/domain/user/application/service/GetSettlementRoommatesService.java index 7e8b6f5..b349400 100644 --- a/src/main/java/com/connect/accountApp/domain/user/application/service/GetSettlementRoommatesService.java +++ b/src/main/java/com/connect/accountApp/domain/user/application/service/GetSettlementRoommatesService.java @@ -33,7 +33,9 @@ public SendMoneyCommand getSendMoney(Long userId) { User user = getUserPort.getUser(userId); Household household = getHouseholdPort.getHousehold(user.getHousehold().getHouseholdId()); - LocalDate householdSettlementDate = household.getHouseholdSettlementDate(); + + + LocalDate householdSettlementDate = household.getHouseholdSettlementDate();// 이부분 정리 //TODO : 날짜에 맞추기 LocalDate pastNearSettlementDate = getPastNearSettlementDate(LocalDate.now(), householdSettlementDate);