Skip to content
Snippets Groups Projects
IncomeExpenseController.java 10.6 KiB
Newer Older
package no.ntnu.idatt1002.demo.controller;

import java.awt.event.ActionEvent;
import java.io.IOException;
import java.util.Optional;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Side;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.chart.PieChart;
import javafx.scene.chart.PieChart.Data;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.ComboBox;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.text.Text;
import no.ntnu.idatt1002.demo.data.Budget.FileHandlingBudget;
import no.ntnu.idatt1002.demo.data.Budget.GeneralBudget;
import no.ntnu.idatt1002.demo.data.Economics.Expense;
import no.ntnu.idatt1002.demo.data.Economics.ExpenseCategory;
import no.ntnu.idatt1002.demo.data.Economics.ExpenseRegister;
import no.ntnu.idatt1002.demo.data.Economics.FileHandling;
import no.ntnu.idatt1002.demo.data.Economics.Income;
import no.ntnu.idatt1002.demo.data.Economics.IncomeCategory;
import no.ntnu.idatt1002.demo.data.Economics.IncomeRegister;

public class IncomeExpenseController implements FinanceController {

  @FXML
  private TableColumn<Expense, Double> expAmountCol;

  @FXML
  private TableColumn<Expense, ExpenseCategory> expCategoryCol;

  @FXML
  private TableColumn<Expense, String> expDateCol;

  @FXML
  private TableColumn<Expense, String> expDescriptionCol;

  @FXML
  private TableColumn<Expense, Boolean> expRecurringCol;

  @FXML
  private TableColumn<Income, Double> inAmountCol;

  @FXML
  private TableColumn<Income, IncomeCategory>  inCategoryCol;

  @FXML
  private TableColumn<Income, String>  inDateCol;

  @FXML
  private TableColumn<Income, String>  inDescriptionCol;

  @FXML
  private TableColumn<Income, Boolean> inRecurringCol;

  @FXML
  private TableView<Expense> expenseTableView;

  @FXML
  private TableView<Income> incomeTableView;

  @FXML
  private Text inSum;

  @FXML
  private Text expSum;

  @FXML
  private Button addBtn;

  @FXML
  private Button deleteBtn;

  @FXML
  private Button editBtn;

  @FXML
  private ProgressBar budgetProgress;

  @FXML
  private DatePicker date;

  @FXML
  private Label daysLeftLbl;

  @FXML
  private ComboBox<?> filter;

  @FXML
  private Button returnBtn;

  @FXML
  private Label title;

  private FinanceMode financeMode;
  private IncomeRegister incomeRegister;

  private ExpenseRegister expenseRegister;

  private GeneralBudget generalBudget;

  private ObservableList<Income> income;

  private ObservableList<Expense> expenses;

  @FXML
  private PieChart expensePieChart;

  @FXML
  private PieChart incomePieChart;

  FileHandling fileHandling;

  @FXML
  public void initialize() throws IOException {
    setColumns();

    //Initialize registers and tableview
    incomeRegister = loadIncomeDataFromFile("Income");
    income = FXCollections.observableArrayList(incomeRegister.getItems());
    incomeTableView.setItems(income);

    expenseRegister = loadExpenseDataFromFile("Expense");
    expenses = FXCollections.observableArrayList(expenseRegister.getItems());
    expenseTableView.setItems(expenses);

    incomePieChart.getData().addAll(createIncomePyChart());
    incomePieChart.setTitle("Income");
    incomePieChart.setLegendSide(Side.RIGHT);
    expensePieChart.setData(createExpensePyChart());
    expensePieChart.setLabelLineLength(10);

    //Initialize sum field under the tableview
   // inSum.setText(String.valueOf(incomeRegister.getTotalSum()));
    //expSum.setText(String.valueOf(expenseRegister.getTotalSum()));
  }

  private void setColumns() {
    inDateCol.setCellValueFactory(new PropertyValueFactory<Income, String>("date"));
    inAmountCol.setCellValueFactory(new PropertyValueFactory<Income, Double>("amount"));
    inCategoryCol.setCellValueFactory(new PropertyValueFactory<Income, IncomeCategory>("category"));
    inDescriptionCol.setCellValueFactory(new PropertyValueFactory<Income, String>("description"));
    inRecurringCol.setCellValueFactory(new PropertyValueFactory<Income, Boolean>("recurring"));

    expDateCol.setCellValueFactory(new PropertyValueFactory<Expense, String>("date"));
    expAmountCol.setCellValueFactory(new PropertyValueFactory<Expense, Double>("amount"));
    expCategoryCol.setCellValueFactory(new PropertyValueFactory<Expense, ExpenseCategory>("category"));
    expDescriptionCol.setCellValueFactory(new PropertyValueFactory<Expense, String>("description"));
    expRecurringCol.setCellValueFactory(new PropertyValueFactory<Expense, Boolean>("recurring"));
  private ObservableList<PieChart.Data> createExpensePyChart() {
    return FXCollections.observableArrayList(
        new Data("Food", expenseRegister.getExpenseByCategory(ExpenseCategory.FOOD).getTotalSum()),
        new Data("Books", expenseRegister.getExpenseByCategory(ExpenseCategory.BOOKS).getTotalSum()),
        new Data("Clothes", expenseRegister.getExpenseByCategory(ExpenseCategory.CLOTHES).getTotalSum()),
        new Data("Other", expenseRegister.getExpenseByCategory(ExpenseCategory.OTHER).getTotalSum())
    );
  private ObservableList<PieChart.Data> createIncomePyChart() {
    return FXCollections.observableArrayList(
        new Data("Food", incomeRegister.getIncomeByCategory(IncomeCategory.STUDENT_LOAN).getTotalSum()),
        new Data("Books", incomeRegister.getIncomeByCategory(IncomeCategory.SALARY).getTotalSum())
    );
  }

  /**
   * Method for handling the adding of new entries in the tableview.
   * @param event A button click on the add button.
   */
  @Override
  public void handleAddBtn(ActionEvent event) {
    handleEditBtn(event);
  }

  /**
   * Method for handling the editing of a chosen entry in the tableview.
   *
   * @param event A button click on the edit button.
   */
  @Override
  public void handleEditBtn(ActionEvent event) {

  }

  /**
   * Deletes an entry from the tableview, if an entry has been selected. The method brings up a
   * popup window, asking for confirmation for deleting the entry.
   *
   * @param event A button click on the delete button
   */
  @Override
  public void handleDeleteBtn(ActionEvent event) {
  }

  /**
   * Method for synching the register with the tableview. The observable list to which the tableview
   * is set, is being refilled with all the entries in the register, keeping it updated with new
   * changes.
   */
  @Override
  public void refreshTableView() {
    this.income.setAll(incomeRegister.getItems());
    //this.sum.setText(String.valueOf(incomeRegister.getTotalSum()));
    this.expenses.setAll(expenseRegister.getItems());
    //this.sum.setText(String.valueOf(incomeRegister.getTotalSum()));
  }

  /**
   * Returns an optional, which is a popup alert box, asking for confirmation for deleting an
   * entry.
   *
   * @return An alert box, asking for confirmation for deleting the selected entry of the tableview.
   */
  @Override
  public Optional<ButtonType> showConfirmationDialog() {
    return Optional.empty();
  }

  /**
   * Saves the changes made to the tableview by writing the information to a file.
   * @throws IOException If an error occurs while writing to the file.
   */
  @Override
  public void saveDataToFile() throws IOException {
    fileHandling.writeItemRegisterToFile(incomeRegister, "Income");
    fileHandling.writeItemRegisterToFile(expenseRegister, "Expense");
  }

  /**
   * Method that either reads data from a file with which it fills an income register, if older changes exist, or instantiates an income register if the file is empty.
   * @param fileName The name of the file that is being read from.
   * @return An object of type IncomeRegister.
   * @throws IOException If an error occurs while reading from the file.
   */
  public IncomeRegister loadIncomeDataFromFile(String fileName) throws IOException {
    //Instantiate new incomeRegister
    if (fileHandling.isEmpty(fileName)) {
      incomeRegister = new IncomeRegister();
    } else { //Load previous income register
      try {
        incomeRegister = fileHandling.readIncomeRegisterFromFile(fileName);
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    return incomeRegister;
  }

  /**
   * Method that either reads data from a file with which it fills an expense register, if older changes exist, or instantiates an expense register if the file is empty.
   * @param fileName The name of the file that is being read from.
   * @return An object of type IncomeRegister.
   * @throws IOException If an error occurs while reading from the file.
   */
  public ExpenseRegister loadExpenseDataFromFile(String fileName) throws IOException {
    //ItemRegister<T extends Item>
    if (fileHandling.isEmpty(fileName)) {
      expenseRegister = new ExpenseRegister();
    } else {
      try {
        expenseRegister = fileHandling.readExpenseRegisterFromFile(fileName);
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    return expenseRegister;
  }

  /**
   * Method that either reads data from a file with which it fills a budget register, if this is an old budget, or instantiates a budget register if this is a new budget.
   * @param fileName The name of the file that is being read from.
   * @return An object of type GeneralBudget.
   * @throws IOException If an error occurs while reading from the file.
   */
  public GeneralBudget loadBudgetDataFromFile(String fileName) throws IOException {
    FileHandlingBudget fileHandlingBudget = new FileHandlingBudget();
    //Instantiate new budget
    if (fileHandlingBudget.isEmpty(fileName)) {
      generalBudget = new GeneralBudget(31, 1000);
    } else { //Load previous budget
      try {
        generalBudget = fileHandlingBudget.readGeneralBudgetFromFile(fileName);
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    return generalBudget;
  }

  /**
   * Switches the scene to the Main Menu scene.
   */
  @FXML
  private void returnToMainMenu(javafx.event.ActionEvent event) throws IOException {
    FXMLLoader loader = new FXMLLoader();
    loader.setLocation(getClass().getResource("/view/MainMenuNew.fxml"));

    Parent root = loader.load();
    Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
    Scene scene = new Scene(root);
    stage.setScene(scene);
    stage.show();