From e8e80fabf40d9d85770124689b374539b916672c Mon Sep 17 00:00:00 2001 From: pawelsa Date: Sat, 16 May 2026 19:57:17 +0200 Subject: [PATCH] feat(PortfolioController): Implement Portfolio logic --- .../primary/exchange/ExchangeController.java | 1 + .../portfolio/PortfolioController.java | 140 ++++++++++++++++-- 2 files changed, 130 insertions(+), 11 deletions(-) diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeController.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeController.java index eece896..8528815 100644 --- a/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeController.java +++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/exchange/ExchangeController.java @@ -67,6 +67,7 @@ public void sortStocksBy(SortAction action) { case LOSERS: { stocksSorted.addAll(session.getExchange().getLosers(Integer.MAX_VALUE)); + break; } } diff --git a/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioController.java b/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioController.java index e3ba06a..051228f 100644 --- a/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioController.java +++ b/src/main/java/edu/ntnu/idi/idatt/view/primary/portfolio/PortfolioController.java @@ -1,22 +1,140 @@ package edu.ntnu.idi.idatt.view.primary.portfolio; +import edu.ntnu.idi.idatt.model.portfolio.Portfolio; import edu.ntnu.idi.idatt.model.portfolio.Share; +import edu.ntnu.idi.idatt.service.transaction.SaleCalculator; import edu.ntnu.idi.idatt.session.UserSession; import edu.ntnu.idi.idatt.view.components.AbstractController; import edu.ntnu.idi.idatt.view.components.elements.ShareComponent; +import edu.ntnu.idi.idatt.view.components.ui.UIAlert; +import edu.ntnu.idi.idatt.view.util.CssUtils; +import java.math.BigDecimal; import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; public class PortfolioController extends AbstractController { - private final ArrayList loadedShareComponents = new ArrayList<>(); - private UserSession session = UserSession.getInstance(); - - public PortfolioController(PortfolioModel model){ - super(model); - for(Share share: session.getPlayer().getPortfolio().getShares()){ - ShareComponent shareComponent = new ShareComponent(share); - loadedShareComponents.add(shareComponent); - } - model.getSharesList().setAll(loadedShareComponents); + + public enum SortAction { + OLDEST, + NEWEST, + PROFIT, + LOSS + } + + private final ArrayList sharesSorted = new ArrayList<>(); + private UserSession session = UserSession.getInstance(); + + public PortfolioController(PortfolioModel model) { + super(model); + List initialSharesLoad = session.getPlayer().getPortfolio().getShares(); + sharesSorted.addAll(initialSharesLoad); + setShareModel(initialSharesLoad); + + initController(); + } + + public void setShareModel(List shareList) { + model.getShareList().clear(); + for (Share share : shareList) { + ShareComponent shareComponent = new ShareComponent(share); + shareComponent.onShareSellButton((sellShare) -> holdingSale(sellShare)); + model.getShareList().add(shareComponent); + } + } + + public void initController() { + + setupPlayerInfo(); + + } + + public void holdingSale(Share share) { + + UIAlert sellConfirmation = new UIAlert("Confirmation required", + "Do you wish to sell this holding?", + String.format("Selling %.2f [%s] for %.2f $", + share.getQuantity(), share.getStock().getSymbol(), new SaleCalculator(share).calculateTotal())); + + boolean result = sellConfirmation.displayAwaitResponse(); + + if (!result) { + return; + } + + session.getExchange().sell(share, session.getPlayer()); + session.updateGameState(); + setupPlayerInfo(); // Reload player information section + sortSharesBy(SortAction.OLDEST); // Reset loaded shares. + + } + + public void setupPlayerInfo() { + Portfolio portfolio = session.getPlayer().getPortfolio(); + + String title = String.format("%s's Portfolio", session.getPlayer().getName()); + model.playerInfoModel().getTitle().set(title); + + String netWorth = String.format("Portfolio net worth: %.2f $", portfolio.getNetWorth()); + model.playerInfoModel().getNetWorth().set(netWorth); + + BigDecimal totalNetWorthChangeValue = portfolio.getChangeFromStock(); + model.playerInfoModel().getNetWorthTotalChange().set(totalNetWorthChangeValue.toPlainString() + " %"); + model.playerInfoModel().getNetWorthTotalChangeColor().set(CssUtils.generateValueColors(totalNetWorthChangeValue)); + + String playerStatus = String.format("Player status: %s", session.getPlayer().getStatus()); + model.playerInfoModel().getPlayerStatus().set(playerStatus); + + String ownedShares = String.format("Total shares owned: %.2f", portfolio.getOwnedAmount()); + model.playerInfoModel().getTotalSharesOwned().set(ownedShares); + } + + public void handleSearchQuery(String query) { + if (query == null || query.isBlank()) { + setShareModel(sharesSorted); // Get back to "no search" + return; } -} \ No newline at end of file + + List sharesFound = sharesSorted.stream() + .filter(share -> share.getStock().toString().contains(query)).toList(); + + setShareModel(sharesFound); + + } + + public void sortSharesBy(SortAction action) { + sharesSorted.clear(); + sharesSorted.addAll(session.getPlayer().getPortfolio().getShares()); + + switch (action) { + + case OLDEST: { + break; + } + + case NEWEST: { + List reversed = new ArrayList<>(sharesSorted.reversed()); + sharesSorted.clear(); + sharesSorted.addAll(reversed); + break; + } + + case PROFIT: { + sharesSorted.sort(Comparator.comparing(Share::getProfit).reversed()); + break; + } + + case LOSS: { + + sharesSorted.sort(Comparator.comparing(Share::getProfit)); + break; + } + + } + + setShareModel(sharesSorted); + + } + +}