Ver código fonte

add currency param for portfolio history (#11)

Daniel Bohry 2 meses atrás
pai
commit
b59a4c21c9

+ 5 - 2
src/main/java/com/danielbohry/stocks/api/portfolio/PortfolioHistoryController.java

@@ -9,6 +9,8 @@ import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
 
+import static com.danielbohry.stocks.service.portfolio.PortfolioHistoryService.DEFAULT_CURRENCY;
+
 @RestController
 @RequestMapping("api/portfolios/{portfolioId}")
 @AllArgsConstructor
@@ -18,8 +20,9 @@ public class PortfolioHistoryController {
     private final PortfolioHistoryService service;
 
     @GetMapping("history")
-    public ResponseEntity<?> getPortfolioHistory(@PathVariable String portfolioId) {
-        List<PortfolioHistory> response = service.getSnapshots(portfolioId);
+    public ResponseEntity<?> getPortfolioHistory(@PathVariable String portfolioId,
+                                                 @RequestParam(value = "currency", defaultValue = DEFAULT_CURRENCY) String currency) {
+        List<PortfolioHistory> response = service.getSnapshots(portfolioId, currency);
         return ResponseEntity.ok(response);
     }
 

+ 1 - 1
src/main/java/com/danielbohry/stocks/domain/PortfolioHistory.java

@@ -19,7 +19,7 @@ public class PortfolioHistory {
     private List<PortfolioStock> stocks;
     private Instant createdAt;
 
-    public BigDecimal getTotalValue() {
+    public BigDecimal getTotalValueInUSD() {
         return stocks.stream()
             .map(PortfolioStock::getTotal)
             .reduce(BigDecimal.ZERO, BigDecimal::add);

+ 33 - 2
src/main/java/com/danielbohry/stocks/service/portfolio/PortfolioHistoryService.java

@@ -4,6 +4,7 @@ import com.danielbohry.stocks.domain.Portfolio;
 import com.danielbohry.stocks.domain.PortfolioHistory;
 import com.danielbohry.stocks.repository.portfolio.PortfolioHistoryEntity;
 import com.danielbohry.stocks.repository.portfolio.PortfolioHistoryRepository;
+import com.danielbohry.stocks.service.ExchangeService;
 import com.danielbohry.stocks.service.stock.StockEncryptService;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -11,8 +12,12 @@ import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 
+import java.math.BigDecimal;
 import java.util.List;
+import java.util.Map;
 
+import static java.math.BigDecimal.ONE;
+import static java.math.RoundingMode.HALF_UP;
 import static java.time.Instant.now;
 
 @Slf4j
@@ -23,6 +28,7 @@ public class PortfolioHistoryService {
     private final PortfolioService service;
     private final PortfolioHistoryRepository repository;
     private final StockEncryptService encryptService;
+    private final ExchangeService exchangeService;
 
     public static final String ONCE_PER_MONTH = "0 0 0 1 * *";
     public static final String DEFAULT_CURRENCY = "USD";
@@ -37,14 +43,39 @@ public class PortfolioHistoryService {
         saveSnapshots(portfolios);
     }
 
-    public List<PortfolioHistory> getSnapshots(String portfolioId) {
-        return repository.findAllByPortfolioId(portfolioId).stream()
+    public List<PortfolioHistory> getSnapshots(String portfolioId, String currency) {
+        List<PortfolioHistory> history = repository.findAllByPortfolioId(portfolioId).stream()
             .map(entity -> PortfolioHistory.builder()
                 .portfolioId(entity.getPortfolioId())
                 .stocks(encryptService.decryptStocks(entity.getEncryptedStocks()))
                 .createdAt(entity.getCreatedAt())
                 .build()
             ).toList();
+
+        ExchangeService.ExchangeRateResponse exchangeRate = exchangeService.getCurrentRate(currency);
+        Map<String, BigDecimal> rates = exchangeRate.getConversionRates();
+        BigDecimal targetRate = rates.getOrDefault(currency, ONE);
+
+        history.forEach(h -> {
+            BigDecimal quoteRate = rates.getOrDefault(DEFAULT_CURRENCY, ONE);
+            BigDecimal convertedPriceTotalValue = h.getTotalValueInUSD()
+                .divide(quoteRate, 2, HALF_UP)
+                .multiply(targetRate);
+
+            h.setTotalValue(convertedPriceTotalValue);
+
+            h.getStocks().forEach(s -> {
+                BigDecimal convertedStockPrice = s.getPrice()
+                    .divide(quoteRate, 2, HALF_UP)
+                    .multiply(targetRate);
+
+                s.setPrice(convertedStockPrice);
+                s.setTotal(convertedStockPrice.multiply(BigDecimal.valueOf(s.getQuantity())));
+            });
+
+        });
+
+        return history;
     }
 
     public void createSnapshot(String portfolioId) {

+ 5 - 3
src/main/java/com/danielbohry/stocks/service/portfolio/PortfolioService.java

@@ -25,6 +25,8 @@ import java.util.Objects;
 import java.util.UUID;
 
 import static com.danielbohry.stocks.domain.Portfolio.convert;
+import static java.math.BigDecimal.ONE;
+import static java.math.RoundingMode.HALF_UP;
 import static java.time.Instant.now;
 import static java.util.Collections.emptyList;
 
@@ -60,7 +62,7 @@ public class PortfolioService {
         Portfolio portfolio = convert(entity);
         ExchangeRateResponse exchangeRate = exchangeService.getCurrentRate(currency);
         Map<String, BigDecimal> rates = exchangeRate.getConversionRates();
-        BigDecimal targetRate = rates.getOrDefault(currency, BigDecimal.ONE);
+        BigDecimal targetRate = rates.getOrDefault(currency, ONE);
 
         log.info("Getting portfolio [{}] and converting to [{}]", id, currency);
         List<PortfolioStock> updatedStocks = portfolio.getStocks().stream()
@@ -68,10 +70,10 @@ public class PortfolioService {
                 Stock quote = stockService.getStockQuote(stock.getCode());
                 stock.setName(quote.getName());
 
-                BigDecimal quoteRate = rates.getOrDefault(quote.getCurrency(), BigDecimal.ONE);
+                BigDecimal quoteRate = rates.getOrDefault(quote.getCurrency(), ONE);
 
                 BigDecimal convertedPrice = quote.getPrice()
-                    .divide(quoteRate, 2, RoundingMode.HALF_UP)
+                    .divide(quoteRate, 2, HALF_UP)
                     .multiply(targetRate);
 
                 stock.setPrice(convertedPrice);