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

Restructure sell to remove dependency on dashboard state #136

Merged
merged 1 commit into from
Nov 27, 2023
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
9 changes: 9 additions & 0 deletions src/main/java/interface_adapters/Sell/SellController.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import use_cases.Sell.SellInputBoundary;
import use_cases.Sell.SellInputData;

import java.util.List;

public class SellController {
final private SellInputBoundary sellInteractor;

Expand All @@ -19,4 +21,11 @@ public void execute(String amount, String ticker) {
sellInteractor.execute(sellInputData);
}
}

public void execute() {
SellInputData sellInputData = new SellInputData();
sellInteractor.execute(sellInputData);
}


}
19 changes: 12 additions & 7 deletions src/main/java/interface_adapters/Sell/SellPresenter.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,23 @@ public SellPresenter(ViewManagerModel viewManagerModel,
@Override
public void prepareSuccessView(SellOutputData response) {
SellState sellState = sellViewModel.getState();
String sellSuccess = String.format("Congratulations! Sold %.2f stocks of ", response.getAmount()) + response.getTicker();
sellState.setSellSuccess(sellSuccess);
dashboardViewModel.firePropertyChanged();
sellViewModel.firePropertyChanged();
viewManagerModel.setActiveView(sellViewModel.getViewName());
viewManagerModel.firePropertyChanged();
if (response.isExecuteTypeSell()) {
String sellSuccess = String.format("Congratulations! Sold %.2f stocks of ", response.getAmount()) + response.getTicker();
sellState.setSellSuccess(sellSuccess);
} else {
sellState.setBalance(response.getBalance());
sellState.setOwnedStocks(response.getOwnedStocks());
sellState.setOwnedAmounts(response.getOwnedAmounts());
sellState.setSellAmounts(response.getSellAmounts());
}
sellViewModel.setState(sellState);
// sellViewModel.firePropertyChanged();
}

@Override
public void prepareFailView(String error) {
SellState sellState = sellViewModel.getState();
sellState.setAmountError(error);
sellViewModel.firePropertyChanged();
// sellViewModel.firePropertyChanged();
}
}
43 changes: 41 additions & 2 deletions src/main/java/interface_adapters/Sell/SellState.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,28 @@ public class SellState {
private String amount = null;
private String sellSuccess = null;
private List<String> ownedStocks = null;

public SellState(String stockSelected, String amount, String amountError, List<String> ownedStocks, String sellSuccess) {
private List<Double> ownedAmounts = null;
private List<Double> sellAmounts = null;
private Double balance = null;

public SellState(
String stockSelected,
String amount,
String amountError,
List<String> ownedStocks,
String sellSuccess,
List<Double> ownedAmounts,
Double balance,
List<Double> sellAmounts
) {
this.amountError = amountError;
this.amount = amount;
this.stockSelected = stockSelected;
this.ownedStocks = ownedStocks;
this.sellSuccess = sellSuccess;
this.ownedAmounts = ownedAmounts;
this.balance = balance;
this.sellAmounts = sellAmounts;
}

public String getAmountError() {
Expand Down Expand Up @@ -57,6 +72,30 @@ public String getSellSuccess() {
return sellSuccess;
}

public void setBalance(Double balance) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Your whole PR is an excellent example of good naming conventions, with attributes and methods being named using camelCase and classes named using PascalCase.
  • The changes you made to SellState were very crucial, as without them the view would have been much less functional.
  • The code's correctness is undeniable, as it is so neat that I could understand every addition it will make, but also it passes all of our Maven tests which would detect compile errors and failures of other pre-built tests we have made.
  • The test coverage of the Sell use case and interface adapters is not extensive, however this is not a problem specific to this use case but a general problem for our app. I just wanted to mention that we will need significantly more testing, including on the files that are modified here.
  • As with every class in our app, these changes reflect very good SOLID design principles and CA setup.
  • Another thing to note with the Sell use case here is that Javadoc is missing. Every constructor is public and many of the methods, including this one, SellState.setBalance are also public, meaning all of these require Javadoc.
  • Your explanation/description of this PR was exemplary, as it laid out the changes you made and the reasons for making them.

Overall, this is a high-quality PR, and thus merits approval.

this.balance = balance;
}

public Double getBalance() {
return balance;
}

public void setOwnedAmounts(List<Double> ownedAmounts) {
this.ownedAmounts = ownedAmounts;
}

public List<Double> getSellAmounts() {
return sellAmounts;
}

public void setSellAmounts(List<Double> sellAmounts) {
this.sellAmounts = sellAmounts;
}

public List<Double> getOwnedAmounts() {
return ownedAmounts;
}

// Because of the previous copy constructor, the default constructor must be explicit. Hence overloading.
public SellState() {

Expand Down
11 changes: 11 additions & 0 deletions src/main/java/use_cases/Sell/SellInputData.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
package use_cases.Sell;

import java.util.List;

public class SellInputData {
public Double amount;
public String ticker;
public boolean executeTypeSell;

public SellInputData(Double amount, String ticker) {
this.amount = amount;
this.ticker = ticker;
this.executeTypeSell = true;
}

public SellInputData() {
this.executeTypeSell = false;
}

public Double getAmount() {
Expand All @@ -17,4 +25,7 @@ public String getTicker() {
return ticker;
}

public boolean isExecuteTypeSell() {
return executeTypeSell;
}
}
68 changes: 46 additions & 22 deletions src/main/java/use_cases/Sell/SellInteractor.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
import use_cases.BaseStockInteractor;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class SellInteractor extends BaseStockInteractor implements SellInputBoundary {
final SellDataAccessInterface userDataAccessObject;
Expand All @@ -23,33 +25,55 @@ public SellInteractor(SellDataAccessInterface userDataAccessInterface,

@Override
public void execute(SellInputData sellInputData) {
String ticker = sellInputData.getTicker();
Double amount = sellInputData.getAmount();
if (sellInputData.isExecuteTypeSell()) {
String ticker = sellInputData.getTicker();
Double amount = sellInputData.getAmount();

User user = userDataAccessObject.get();
User user = userDataAccessObject.get();

if (amount <= 0.0) {
sellPresenter.prepareFailView("Please enter a decimal value greater than 0");
return;
}
if (!user.hasStock(ticker) || user.getStockOwned(ticker) < amount) {
sellPresenter.prepareFailView("You can't sell more than you have.");
return;
}

Double currentPrice = driverAPI.getCurrentPrice(ticker).getPrice();
Double currentlyOwned = user.getStockOwned(ticker);
if (amount <= 0.0) {
sellPresenter.prepareFailView("Please enter a decimal value greater than 0");
return;
}
if (!user.hasStock(ticker) || user.getStockOwned(ticker) < amount) {
sellPresenter.prepareFailView("You can't sell more than you have.");
return;
}

Double currentPrice = driverAPI.getCurrentPrice(ticker).getPrice();
Double currentlyOwned = user.getStockOwned(ticker);

user.addBalance(currentPrice * amount);
HashMap<String, TransactionHistory> userHistory = user.getHistory();

Transaction transaction = new SellTransaction(amount, new PricePoint(LocalDate.now(), currentPrice));

user.addBalance(currentPrice * amount);
HashMap<String, TransactionHistory> userHistory = user.getHistory();
super.updatePortfolio(user, ticker, currentlyOwned - amount);
super.addToHistory(userHistory, ticker, user, amount, currentPrice, transaction);
userDataAccessObject.save();

Transaction transaction = new SellTransaction(amount, new PricePoint(LocalDate.now(), currentPrice));
SellOutputData result = new SellOutputData(sellInputData.getAmount(), sellInputData.getTicker());
sellPresenter.prepareSuccessView(result);

super.updatePortfolio(user, ticker, currentlyOwned - amount);
super.addToHistory(userHistory, ticker, user, amount, currentPrice, transaction);
userDataAccessObject.save();
} else {
User user = userDataAccessObject.get();
HashMap<String, Double> portfolio = user.getPortfolio();
Double balance = user.getBalance();

SellOutputData result = new SellOutputData(sellInputData.getAmount(), sellInputData.getTicker());
sellPresenter.prepareSuccessView(result);
List<String> ownedStocks = new ArrayList<String>();
ownedStocks.addAll(portfolio.keySet());

List<Double> ownedAmounts = new ArrayList<Double>();
ownedAmounts.addAll(portfolio.values());

List<Double> sellAmounts = new ArrayList<Double>();
for (String ownedStock : ownedStocks) {
Double stockPrice = driverAPI.getCurrentPrice(ownedStock).getPrice();
sellAmounts.add(stockPrice);
}

SellOutputData result = new SellOutputData(ownedStocks, ownedAmounts, sellAmounts, balance);
sellPresenter.prepareSuccessView(result);
}
}
}
41 changes: 41 additions & 0 deletions src/main/java/use_cases/Sell/SellOutputData.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,33 @@
package use_cases.Sell;

import java.util.List;

public class SellOutputData {
public Double amount;
public String ticker;
public boolean executeTypeSell;
public List<String> ownedStocks;
public List<Double> ownedAmounts;
public List<Double> sellAmounts;
public Double balance;

public SellOutputData(Double amount, String ticker) {
this.amount = amount;
this.ticker = ticker;
this.executeTypeSell = true;
}

public SellOutputData(
List<String> ownedStocks,
List<Double> ownedAmounts,
List<Double> sellAmounts,
Double balance
) {
this.ownedStocks = ownedStocks;
this.ownedAmounts = ownedAmounts;
this.sellAmounts = sellAmounts;
this.balance = balance;
this.executeTypeSell = false;
}

public Double getAmount() {
Expand All @@ -16,4 +37,24 @@ public Double getAmount() {
public String getTicker() {
return ticker;
}

public boolean isExecuteTypeSell() {
return executeTypeSell;
}

public List<Double> getOwnedAmounts() {
return ownedAmounts;
}

public Double getBalance() {
return balance;
}

public List<String> getOwnedStocks() {
return ownedStocks;
}

public List<Double> getSellAmounts() {
return sellAmounts;
}
}
Loading
Loading