diff --git a/src/main/java/no/ntnu/idatt1002/demo/controller/BudgetController.java b/src/main/java/no/ntnu/idatt1002/demo/controller/BudgetController.java deleted file mode 100644 index 1325d2968e40ab23d687559dc589f1b6a60d8a79..0000000000000000000000000000000000000000 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/BudgetController.java +++ /dev/null @@ -1,296 +0,0 @@ -package no.ntnu.idatt1002.demo.controller; - -import java.time.LocalDate; -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; -import javafx.event.ActionEvent; -import javafx.fxml.FXML; -import javafx.fxml.FXMLLoader; -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.*; -import javafx.scene.control.Alert.AlertType; -import javafx.scene.control.cell.PropertyValueFactory; -import javafx.scene.text.Text; -import javafx.stage.Modality; -import javafx.stage.Stage; -import no.ntnu.idatt1002.demo.data.Budget.BudgetItem; -import no.ntnu.idatt1002.demo.data.Budget.FileHandlingBudget; -import no.ntnu.idatt1002.demo.data.Budget.GeneralBudget; -import no.ntnu.idatt1002.demo.data.Economics.ExpenseCategory; - - -import java.io.IOException; -import java.util.Optional; -import no.ntnu.idatt1002.demo.data.Economics.IncomeCategory; - -/** - * Controller for budget scene in the application. This controller manages all actions that relates to the budget tableview (add, edit and delete), the switching - * of scenes from the budget scene to another scene, and the saving of the table, whenever the user switches to another scene. - * - * @author Anders Emil Bergan - * @since 24.3.2023 - */ -public class BudgetController implements FinanceController { - - private GeneralBudget general; - - @FXML - private Button addBtn; - - @FXML - private Button editBtn; - - @FXML - private Button returnBtn; - @FXML - private TableColumn<BudgetItem, Double> amountCol; - - @FXML - private TableView<BudgetItem> budgetTableView = new TableView<>(); - - @FXML - private TableColumn<BudgetItem, ExpenseCategory> categoryCol; - - @FXML - private TableColumn<BudgetItem, String> descriptionCol; - - @FXML - private Text sum; - - @FXML - private DatePicker date; - - @FXML - private TableColumn<BudgetItem, Double> percentageColumn; - - @FXML - private ObservableList<BudgetItem> budgetList; - - - /** - * Initializes the budget register, the observable budget list and the tableview, along with the values of the dropbox used for filtering the tableview. - * @throws IOException If there occurs any exception when loading the budget register from a file. - */ - - @FXML - public void initialize() throws IOException { - //TODO if budget is not empty (HAS VALUES) -> make uneditable -> EVENT FILTER TO CONTEXT MENU - //TODO disable return to main menu when creating budget because this is the same view as when you create budeget - //TODO make budget item throw exception with negative amount - //TODO specify error messgage for when amount is exceeded / duplicate exists - //todo properly close screen so things are saved - //Initialize table columns - categoryCol.setCellValueFactory(new PropertyValueFactory<BudgetItem, ExpenseCategory>("budgetCategory")); - amountCol.setCellValueFactory(new PropertyValueFactory<BudgetItem, Double>("budgetAmount")); - descriptionCol.setCellValueFactory(new PropertyValueFactory<BudgetItem, String>("budgetDescription")); - - //Initialize registers and tableview - general = loadBudgetDataFromFile("Budget"); - budgetList = FXCollections.observableArrayList(general.getBudgetItems()); - budgetTableView.setItems(budgetList); - - formatDatePicker(); - //createBudgetPieChart(); - //Initialize sum field under the tableview - //sum.setText(String.valueOf(general.totalSum())); - } - - private ObservableList<PieChart.Data> createBudgetPieChart() throws IllegalArgumentException { //TODO DOESNT WORK IF BUDGETITEM HAS NO BUDGET - try { - return FXCollections.observableArrayList( - new Data("Food", general.getBudgetItem(ExpenseCategory.FOOD).getBudgetAmount()), - new Data("Books", general.getBudgetItem(ExpenseCategory.BOOKS).getBudgetAmount()), - new Data("Clothes", - general.getBudgetItem(ExpenseCategory.CLOTHES).getBudgetAmount()), - new Data("Other", general.getBudgetItem(ExpenseCategory.OTHER).getBudgetAmount()) - ); - } catch(IllegalArgumentException iae) { - return FXCollections.observableArrayList(); - } - } - - /** - * Method for disabling the date picker, yet having its opacity at max. - */ - private void formatDatePicker() { - date.setValue(LocalDate.now()); - date.setDisable(true); - date.setStyle("-fx-opacity: 1"); - date.getEditor().setStyle("-fx-opacity: 1"); - } - - @Override - public void handleAddBtn(ActionEvent event) { - handleEditBtn(event); - } - /** - * Adds or edits a budget item, depending on what mode the DialogMode enum is at. The method brings up a dialog box popup in which the user can fill and choose - * values that the budget item will have. Open exiting the popup, the changes the saved to the tableview. - * @param event A button click on either the add or delete button. - */ - @Override - public void handleEditBtn(ActionEvent event) { - BudgetItem item = null; - String dialogTitle = ""; - DialogMode dialogMode; - - FXMLLoader loader = new FXMLLoader(SceneController.class.getResource("/view/AddBudgetNew.fxml")); - Dialog<BudgetItem> dialog = new Dialog<>(); - dialog.initModality(Modality.APPLICATION_MODAL); - - //Try to load the FXML file onto another dialogPane - try{ - dialog.getDialogPane().setContent(loader.load()); - } catch(IOException e) { - e.printStackTrace(); - } - - //Loads the controller for the dialog box that appears whenever one adds or edits a budget item - AddBudgetController budgetController = loader.getController(); - - //Sets the title of the dialog box - if(event.getSource().equals(addBtn)){ - dialogMode = DialogMode.ADD; - dialogTitle = "New Budget"; - } - else if (event.getSource().equals(editBtn) && budgetTableView.getSelectionModel().getSelectedItem() != null) { - dialogMode = DialogMode.EDIT; - dialogTitle = "Edit expense"; - //Gets the selected item from the table - item = budgetTableView.getSelectionModel().getSelectedItem(); - //Binds the selected item to another item which is defined in the budgetcontroller - budgetController.setBudget(item); - } else { - return; - } - - dialog.setTitle(dialogTitle); - // Show the Dialog and wait for the user to close it - dialog.showAndWait(); - - //Adds the new item to the register - item = budgetController.getNewBudgetItem(); - if(item != null && dialogMode == DialogMode.ADD){ - try { - general.addToBudgetBudgetItem(item); - } catch(IllegalArgumentException e) { - showIllegalBudgetItemDialog(); - } - } - //Updates the tableview using the register - refreshTableView(); - } - - - /** - * 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 - */ - @FXML - public void handleDeleteBtn(ActionEvent event) { - //Gets the selected item from the tableview - BudgetItem item = budgetTableView.getSelectionModel().getSelectedItem(); - //Exits the method if nothing is selected - if (item == null) { - return; - } - //Brings up a confirmation popup - Optional<ButtonType> isConfirmed = showConfirmationDialog(); - if (isConfirmed.isPresent() && isConfirmed.get() == ButtonType.OK) { - general.deleteItemFromBudget(item.getBudgetCategory()); - refreshTableView(); - } - } - - /** - * 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. - */ - public void refreshTableView(){ - this.budgetList.setAll(general.getBudgetItems()); - //Refreshing the sum of the amounts of the budget - //this.sum.setText(String.valueOf(general.totalSum())); - } - - /** - * 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() { - Alert alert = new Alert(Alert.AlertType.CONFIRMATION); - alert.setTitle("Confirm Delete"); - alert.setHeaderText("Delete Confirmation"); - alert.setContentText("Are you sure you would like to delete the selected entry?"); - - return alert.showAndWait(); - } - - /** - * 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 { - FileHandlingBudget fileHandlingBudget = new FileHandlingBudget(); - fileHandlingBudget.writeGeneralBudgetToFile("Budget", general); - } - - /** - * Returns an optional, which is a popup alert box, informing that either the budget amount has - * been exceeded or that the same category has been entered twice in the budget tableview. - */ - private void showIllegalBudgetItemDialog() { - Alert alert = new Alert(AlertType.ERROR); - alert.setTitle("Budget amount exceeded/Category already exists"); - alert.setHeaderText("Your budget exceeds the max limit OR a budget item of the same category already exists in the table"); - alert.setContentText("The total budget sum must be below " + general.getMaxAmount() + " OR Each category can only have one entry in the budget table"); - alert.showAndWait(); - } - - /** - * 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)) { - general = new GeneralBudget(31, 1000); - //throws new IOException("Not valid budget") - } else { //Load previous budget - try { - general = fileHandlingBudget.readGeneralBudgetFromFile(fileName); - } catch (IOException e) { - e.printStackTrace(); - } - } - return general; - } - - /** - * Switches scenes back to main menu, by loading a new FXML file and setting the scene to this location. - * @param event A button click on the return to main menu button - * @throws IOException If an error occurs with loading any of the FXML files. - */ - @FXML - public void returnToMainMenu(ActionEvent event) throws IOException { - //Always saving the data when switching scenes - saveDataToFile(); - 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(); - } -} diff --git a/src/main/java/no/ntnu/idatt1002/demo/controller/budgetController.java b/src/main/java/no/ntnu/idatt1002/demo/controller/budgetController.java deleted file mode 100644 index 569710ce0e59feb2101553fd4365e398359314f0..0000000000000000000000000000000000000000 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/budgetController.java +++ /dev/null @@ -1,4 +0,0 @@ -package no.ntnu.idatt1002.demo.controller; - -public class budgetController { -} diff --git a/src/main/java/no/ntnu/idatt1002/demo/data/Budget/GeneralBudget.java b/src/main/java/no/ntnu/idatt1002/demo/data/Budget/GeneralBudget.java index 6a4e46adbe1b2ba8f282341931c8dae900e6c59c..bfedeea23f1ab618b7149d89d6ce54ab8feb481d 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/data/Budget/GeneralBudget.java +++ b/src/main/java/no/ntnu/idatt1002/demo/data/Budget/GeneralBudget.java @@ -5,6 +5,7 @@ import no.ntnu.idatt1002.demo.data.Economics.ExpenseCategory; import java.sql.Date; import java.time.Duration; import java.time.LocalDate; +import java.time.Month; import java.time.ZoneId; import java.time.temporal.ChronoUnit; import java.time.temporal.Temporal; @@ -110,22 +111,16 @@ public class GeneralBudget { } /** - * This method returns the amount of days left in the budget period as a string. + * This method returns the amount of days left in the budget period as a long. * * @return the amount of days left in the budget period * */ public long getDaysLeftOfBudgetPeriod() { - LocalDate today = LocalDate.now(); - LocalDate end = today.plus(Duration.ofDays(getBudgetPeriod())); + Month thisMonth = LocalDate.now().getMonth(); + int dayOfTheMonth = LocalDate.now().getDayOfMonth(); - Date todaysDate = (Date) Date.from(today.atStartOfDay(ZoneId.systemDefault()).toInstant()); - Date endDate = (Date) Date.from(end.atStartOfDay(ZoneId.systemDefault()).toInstant()); - - Calendar cStart = Calendar.getInstance(); cStart.setTime(todaysDate); - Calendar cEnd = Calendar.getInstance(); cEnd.setTime(endDate); - - return ChronoUnit.DAYS.between((Temporal) cStart, (Temporal) cEnd); + return thisMonth.maxLength() - dayOfTheMonth; } /** diff --git a/src/test/java/no/ntnu/idatt1002/demo/data/Budget/GeneralBudgetTest.java b/src/test/java/no/ntnu/idatt1002/demo/data/Budget/GeneralBudgetTest.java index d4ee06433f68d8e3b85eae037f72237ecb3c70b2..ff7d0636bb2b487a0178bcda77ef5c353cff5d8a 100644 --- a/src/test/java/no/ntnu/idatt1002/demo/data/Budget/GeneralBudgetTest.java +++ b/src/test/java/no/ntnu/idatt1002/demo/data/Budget/GeneralBudgetTest.java @@ -104,4 +104,13 @@ class GeneralBudgetTest { assertTrue(list.isEmpty()); } + + @Test + @DisplayName("Gets the number of days left in the month. 17 has to be changed to the actual number of days left in the month.") + void get_days_left_of_the_month(){ + List<BudgetItem> list = new ArrayList<>(); + GeneralBudget budget1 = new GeneralBudget(12, list, 1200); + + assertEquals(17, budget1.getDaysLeftOfBudgetPeriod()); + } } \ No newline at end of file