Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: change dependency direction #87

Merged
merged 6 commits into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,4 @@ out/

**/logs
**/db/data
domain/src/main/generated/nexters/payout/domain/stock/domain/QStock.java
**/src/main/generated/**
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package nexters.payout.apiserver.dividend.application;

import lombok.RequiredArgsConstructor;
import nexters.payout.apiserver.stock.application.StockDividendQueryService;
import nexters.payout.apiserver.stock.application.dto.response.DividendResponse;
import nexters.payout.apiserver.stock.application.dto.response.StockDetailResponse;
import nexters.payout.core.time.InstantProvider;
import nexters.payout.domain.dividend.domain.Dividend;
import nexters.payout.domain.dividend.domain.repository.DividendRepository;
import nexters.payout.domain.stock.domain.Stock;
import nexters.payout.domain.stock.domain.exception.TickerNotFoundException;
import nexters.payout.domain.stock.domain.repository.StockRepository;
import nexters.payout.domain.stock.domain.service.StockDividendAnalysisService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Month;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class StockDividendQueryServiceImpl implements StockDividendQueryService {

private final StockDividendAnalysisService dividendAnalysisService;
private final StockRepository stockRepository;
private final DividendRepository dividendRepository;

public StockDetailResponse getStockByTicker(final String ticker) {
Stock stock = getStock(ticker);

List<Dividend> lastYearDividends = getLastYearDividends(stock);
List<Dividend> thisYearDividends = getThisYearDividends(stock);

if (lastYearDividends.isEmpty() && thisYearDividends.isEmpty()) {
return StockDetailResponse.of(stock, DividendResponse.noDividend());
}

List<Month> dividendMonths = dividendAnalysisService.calculateDividendMonths(stock, lastYearDividends);
Double dividendYield = dividendAnalysisService.calculateDividendYield(stock, lastYearDividends);
Double dividendPerShare = dividendAnalysisService.calculateAverageDividend(
combinedDividends(lastYearDividends, thisYearDividends)
);

return dividendAnalysisService.findUpcomingDividend(lastYearDividends, thisYearDividends)
.map(upcomingDividend -> StockDetailResponse.of(
stock,
DividendResponse.fullDividendInfo(upcomingDividend, dividendYield, dividendMonths)
))
.orElse(StockDetailResponse.of(
stock,
DividendResponse.withoutDividendDates(dividendPerShare, dividendYield, dividendMonths)
));
}

private List<Dividend> combinedDividends(final List<Dividend> lastYearDividends, final List<Dividend> thisYearDividends) {
return Stream.of(lastYearDividends, thisYearDividends)
.flatMap(List::stream)
.collect(Collectors.toList());
}

private Stock getStock(final String ticker) {
return stockRepository.findByTicker(ticker)
.orElseThrow(() -> new TickerNotFoundException(ticker));
}

private List<Dividend> getLastYearDividends(final Stock stock) {
int lastYear = InstantProvider.getLastYear();

return dividendRepository.findAllByStockId(stock.getId())
.stream()
.filter(dividend -> InstantProvider.toLocalDate(dividend.getExDividendDate()).getYear() == lastYear)
.collect(Collectors.toList());
}

private List<Dividend> getThisYearDividends(final Stock stock) {
int thisYear = InstantProvider.getThisYear();

return dividendRepository.findAllByStockId(stock.getId())
.stream()
.filter(dividend -> InstantProvider.toLocalDate(dividend.getExDividendDate()).getYear() == thisYear)
.collect(Collectors.toList());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package nexters.payout.apiserver.stock.application;

import nexters.payout.apiserver.stock.application.dto.response.StockDetailResponse;

public interface StockDividendQueryService {
StockDetailResponse getStockByTicker(final String ticker);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,27 @@
import nexters.payout.apiserver.stock.application.dto.request.TickerShare;
import nexters.payout.apiserver.stock.application.dto.response.*;
import nexters.payout.core.time.InstantProvider;
import nexters.payout.domain.dividend.domain.Dividend;
import nexters.payout.domain.dividend.domain.repository.DividendRepository;
import nexters.payout.domain.stock.domain.Sector;
import nexters.payout.domain.stock.domain.Stock;
import nexters.payout.domain.stock.domain.exception.TickerNotFoundException;
import nexters.payout.domain.stock.domain.repository.StockRepository;
import nexters.payout.domain.stock.domain.service.SectorAnalysisService;
import nexters.payout.domain.stock.domain.service.SectorAnalysisService.SectorInfo;
import nexters.payout.domain.stock.domain.service.SectorAnalysisService.StockShare;
import nexters.payout.domain.stock.domain.service.StockDividendAnalysisService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Month;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class StockQueryService {

private final StockRepository stockRepository;
private final DividendRepository dividendRepository;
private final SectorAnalysisService sectorAnalysisService;
private final StockDividendAnalysisService dividendAnalysisService;
private final StockDividendQueryService stockDividendQueryService;

public List<StockResponse> searchStock(final String keyword, final Integer pageNumber, final Integer pageSize) {
return stockRepository.findStocksByTickerOrNameWithPriority(keyword, pageNumber, pageSize)
Expand All @@ -42,59 +35,7 @@ public List<StockResponse> searchStock(final String keyword, final Integer pageN
}

public StockDetailResponse getStockByTicker(final String ticker) {
Stock stock = getStock(ticker);

List<Dividend> lastYearDividends = getLastYearDividends(stock);
List<Dividend> thisYearDividends = getThisYearDividends(stock);

if (lastYearDividends.isEmpty() && thisYearDividends.isEmpty()) {
return StockDetailResponse.of(stock, DividendResponse.noDividend());
}

List<Month> dividendMonths = dividendAnalysisService.calculateDividendMonths(stock, lastYearDividends);
Double dividendYield = dividendAnalysisService.calculateDividendYield(stock, lastYearDividends);
Double dividendPerShare = dividendAnalysisService.calculateAverageDividend(
combinedDividends(lastYearDividends, thisYearDividends)
);

return dividendAnalysisService.findUpcomingDividend(lastYearDividends, thisYearDividends)
.map(upcomingDividend -> StockDetailResponse.of(
stock,
DividendResponse.fullDividendInfo(upcomingDividend, dividendYield, dividendMonths)
))
.orElse(StockDetailResponse.of(
stock,
DividendResponse.withoutDividendDates(dividendPerShare, dividendYield, dividendMonths)
));
}

private List<Dividend> combinedDividends(final List<Dividend> lastYearDividends, final List<Dividend> thisYearDividends) {
return Stream.of(lastYearDividends, thisYearDividends)
.flatMap(List::stream)
.collect(Collectors.toList());
}

private Stock getStock(final String ticker) {
return stockRepository.findByTicker(ticker)
.orElseThrow(() -> new TickerNotFoundException(ticker));
}

private List<Dividend> getLastYearDividends(final Stock stock) {
int lastYear = InstantProvider.getLastYear();

return dividendRepository.findAllByStockId(stock.getId())
.stream()
.filter(dividend -> InstantProvider.toLocalDate(dividend.getExDividendDate()).getYear() == lastYear)
.collect(Collectors.toList());
}

private List<Dividend> getThisYearDividends(final Stock stock) {
int thisYear = InstantProvider.getThisYear();

return dividendRepository.findAllByStockId(stock.getId())
.stream()
.filter(dividend -> InstantProvider.toLocalDate(dividend.getExDividendDate()).getYear() == thisYear)
.collect(Collectors.toList());
return stockDividendQueryService.getStockByTicker(ticker);
}

public List<SectorRatioResponse> analyzeSectorRatio(final SectorRatioRequest request) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package nexters.payout.apiserver.stock.application;

import nexters.payout.apiserver.dividend.application.StockDividendQueryServiceImpl;
import nexters.payout.apiserver.stock.application.dto.request.SectorRatioRequest;
import nexters.payout.apiserver.stock.application.dto.request.TickerShare;
import nexters.payout.apiserver.stock.application.dto.response.*;
Expand All @@ -19,9 +20,9 @@
import nexters.payout.domain.stock.domain.service.StockDividendAnalysisService;
import nexters.payout.domain.stock.domain.service.SectorAnalysisService;
import nexters.payout.domain.stock.infra.dto.StockDividendYieldDto;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;
Expand All @@ -45,9 +46,7 @@
@ExtendWith(MockitoExtension.class)
class StockQueryServiceTest {

@InjectMocks
private StockQueryService stockQueryService;

@Mock
private StockRepository stockRepository;
@Mock
Expand All @@ -57,6 +56,12 @@ class StockQueryServiceTest {
@Spy
private StockDividendAnalysisService stockDividendAnalysisService;

@BeforeEach
void setUp() {
StockDividendQueryServiceImpl stockDividendQuery = new StockDividendQueryServiceImpl(stockDividendAnalysisService, stockRepository, dividendRepository);
stockQueryService = new StockQueryService(stockRepository, sectorAnalysisService, stockDividendQuery);
}

@Test
void 검색된_종목_정보를_정상적으로_반환한다() {
// given
Expand Down
41 changes: 0 additions & 41 deletions domain/src/main/generated/nexters/payout/domain/QBaseEntity.java

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package nexters.payout.domain.stock.service;

import nexters.payout.core.time.InstantProvider;
import nexters.payout.domain.DividendFixture;
import nexters.payout.domain.StockFixture;
import nexters.payout.domain.dividend.domain.Dividend;
Expand Down Expand Up @@ -76,18 +77,17 @@ class StockDividendAnalysisServiceTest {
@Test
void 공시된_현재_배당금_지급일이_없는_경우_과거데이터를_기반으로_가까운_지급일을_계산한다() {
// given
LocalDate now = LocalDate.now();
LocalDate now = LocalDate.ofInstant(Instant.now(), UTC);

Dividend pastDividend = DividendFixture.createDividendWithExDividendDate(
UUID.randomUUID(),
LocalDate.of(now.getYear() - 1, 1, 10)
LocalDate.of(now.getYear(), now.getMonth().minus(1), now.getDayOfMonth())
.atStartOfDay(ZoneId.systemDefault()).toInstant()
);

Dividend earlistDividend = DividendFixture.createDividendWithExDividendDate(
UUID.randomUUID(),
LocalDate.of(now.getYear() - 1, 3, 10)
.atStartOfDay(ZoneId.systemDefault()).toInstant()
LocalDate.of(now.getYear(), now.getMonth(), now.getDayOfMonth()).atStartOfDay().toInstant(UTC)
);
List<Dividend> lastYearDividends = List.of(pastDividend, earlistDividend);

Expand All @@ -107,7 +107,7 @@ class StockDividendAnalysisServiceTest {
Dividend lastYearDividend = DividendFixture.createDividend(
UUID.randomUUID(),
1.0,
LocalDate.now().plusDays(10)
LocalDate.now().minusDays(10)
.atStartOfDay(ZoneId.systemDefault()).toInstant()
);

Expand Down
Loading