From 00e6b6401325a390550b66d48d9328ca5c7e2bbe Mon Sep 17 00:00:00 2001 From: ryan <94791461+ryan1604@users.noreply.github.com> Date: Thu, 5 Oct 2023 17:21:05 +0800 Subject: [PATCH 001/518] Create _config.yml --- docs/_config.yml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 docs/_config.yml diff --git a/docs/_config.yml b/docs/_config.yml new file mode 100644 index 0000000000..2934f0e3a3 --- /dev/null +++ b/docs/_config.yml @@ -0,0 +1,3 @@ +remote_theme: pages-themes/hacker@v0.2.0 +plugins: +- jekyll-remote-theme # add this line to the plugins list if you already have one From 491c9238e3c2b52f8ddaa10ba332e9566a8b7e9e Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Thu, 5 Oct 2023 17:59:02 +0800 Subject: [PATCH 002/518] Add aboutus links and add my my own md file --- docs/AboutUs.md | 14 +++++++------- docs/team/frederick.md | 5 +++++ 2 files changed, 12 insertions(+), 7 deletions(-) create mode 100644 docs/team/frederick.md diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 0f072953ea..a4136dfefd 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,9 +1,9 @@ # About us -Display | Name | Github Profile | Portfolio ---------|:----:|:--------------:|:---------: -![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +Display | Name | Github Profile | Portfolio +--------|:---------:|:---------------------------------------:|:---------: +![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://via.placeholder.com/100.png?text=Photo) | Frederick | [Github](https://github.com/wwweert123) | [Portfolio](docs/team/frederick.md) diff --git a/docs/team/frederick.md b/docs/team/frederick.md new file mode 100644 index 0000000000..6ddbda5256 --- /dev/null +++ b/docs/team/frederick.md @@ -0,0 +1,5 @@ +I am Frederick + +Hello + +I am from this team! \ No newline at end of file From eab7be4bcbb2bd13648ec4f347d0278a5b33b3b1 Mon Sep 17 00:00:00 2001 From: "LAPTOP-29R7UPMN\\Ryones" Date: Thu, 5 Oct 2023 18:02:16 +0800 Subject: [PATCH 003/518] Update AboutUs --- docs/AboutUs.md | 14 +++++++------- docs/team/ryanchua.md | 0 2 files changed, 7 insertions(+), 7 deletions(-) create mode 100644 docs/team/ryanchua.md diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 0f072953ea..e6078ca3c2 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,9 +1,9 @@ # About us -Display | Name | Github Profile | Portfolio ---------|:----:|:--------------:|:---------: -![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +Display | Name | Github Profile | Portfolio +--------|:---------:|:-------------------------------------:|:---------: +![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://via.placeholder.com/100.png?text=Photo) | Ryan Chua | [Github](https://github.com/ryan1604) | [Portfolio](docs/team/ryanchua.md) +![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) diff --git a/docs/team/ryanchua.md b/docs/team/ryanchua.md new file mode 100644 index 0000000000..e69de29bb2 From 4f47ae40234b912a4c5b7dc60382509629d101a3 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Thu, 5 Oct 2023 18:04:13 +0800 Subject: [PATCH 004/518] Add name to AboutUs --- docs/AboutUs.md | 14 +++++++------- docs/team/{johndoe.md => NeoMinWei.md} | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) rename docs/team/{johndoe.md => NeoMinWei.md} (53%) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 0f072953ea..1a9e5d76f9 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,9 +1,9 @@ # About us -Display | Name | Github Profile | Portfolio ---------|:----:|:--------------:|:---------: -![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +Display | Name | Github Profile | Portfolio +--------|:-----------:|:--------------:|:---------: +![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://via.placeholder.com/100.png?text=Photo) | Neo Min Wei | [Github](https://github.com/NeoMinWei) | [Portfolio](docs/team/NeoMinWei.md) +![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) diff --git a/docs/team/johndoe.md b/docs/team/NeoMinWei.md similarity index 53% rename from docs/team/johndoe.md rename to docs/team/NeoMinWei.md index ab75b391b8..d23055a4b1 100644 --- a/docs/team/johndoe.md +++ b/docs/team/NeoMinWei.md @@ -1,4 +1,4 @@ -# John Doe - Project Portfolio Page +# Neo Min Wei - Project Portfolio Page ## Overview From f4e110ae257a2d4b5945b76e92c4f67b53a9b9c9 Mon Sep 17 00:00:00 2001 From: hshiah Date: Thu, 5 Oct 2023 18:24:14 +0800 Subject: [PATCH 005/518] Test --- src/main/java/seedu/duke/Duke.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java index 5c74e68d59..ec44021b45 100644 --- a/src/main/java/seedu/duke/Duke.java +++ b/src/main/java/seedu/duke/Duke.java @@ -14,8 +14,9 @@ public static void main(String[] args) { + "|____/ \\__,_|_|\\_\\___|\n"; System.out.println("Hello from\n" + logo); System.out.println("What is your name?"); - Scanner in = new Scanner(System.in); + + System.out.println("Hello " + in.nextLine()); } } From e8da8d09f6900bdcf1299dabba13d3177794676f Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Sat, 7 Oct 2023 14:43:51 +0800 Subject: [PATCH 006/518] Setup Ui and rename Duke to FinancialPlanner Fixes #5 --- build.gradle | 2 +- src/main/java/seedu/duke/Duke.java | 22 ---------------- .../financialplanner/FinancialPlanner.java | 20 +++++++++++++++ .../java/seedu/financialplanner/ui/Ui.java | 25 +++++++++++++++++++ .../FinancialPlannerTest.java} | 4 +-- 5 files changed, 48 insertions(+), 25 deletions(-) delete mode 100644 src/main/java/seedu/duke/Duke.java create mode 100644 src/main/java/seedu/financialplanner/FinancialPlanner.java create mode 100644 src/main/java/seedu/financialplanner/ui/Ui.java rename src/test/java/seedu/{duke/DukeTest.java => financialplanner/FinancialPlannerTest.java} (73%) diff --git a/build.gradle b/build.gradle index ea82051fab..477d6f4399 100644 --- a/build.gradle +++ b/build.gradle @@ -29,7 +29,7 @@ test { } application { - mainClass.set("seedu.duke.Duke") + mainClass.set("seedu.financialplanner.FinancialPlanner") } shadowJar { diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java deleted file mode 100644 index ec44021b45..0000000000 --- a/src/main/java/seedu/duke/Duke.java +++ /dev/null @@ -1,22 +0,0 @@ -package seedu.duke; - -import java.util.Scanner; - -public class Duke { - /** - * Main entry-point for the java.duke.Duke application. - */ - public static void main(String[] args) { - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; - System.out.println("Hello from\n" + logo); - System.out.println("What is your name?"); - Scanner in = new Scanner(System.in); - - - System.out.println("Hello " + in.nextLine()); - } -} diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java new file mode 100644 index 0000000000..ab8c7c56e2 --- /dev/null +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -0,0 +1,20 @@ +package seedu.financialplanner; + +import seedu.financialplanner.ui.Ui; + +public class FinancialPlanner { + private Ui ui; + + public FinancialPlanner() { + ui = new Ui(); + } + + public void run() { + ui.welcomeMessage(); + ui.exitMessage(); + } + + public static void main(String[] args) { + new FinancialPlanner().run(); + } +} diff --git a/src/main/java/seedu/financialplanner/ui/Ui.java b/src/main/java/seedu/financialplanner/ui/Ui.java new file mode 100644 index 0000000000..308044430f --- /dev/null +++ b/src/main/java/seedu/financialplanner/ui/Ui.java @@ -0,0 +1,25 @@ +package seedu.financialplanner.ui; + +import java.util.Scanner; + +public class Ui { + public Ui() { + } + + public void showMessage(String message) { + System.out.println(message); + } + + public void welcomeMessage() { + showMessage("\tWelcome to your Financial Planner. Type something to get started."); + } + + public void exitMessage() { + showMessage("\tExiting Financial Planner. Goodbye."); + } + + public String input() { + Scanner in = new Scanner(System.in); + return in.nextLine().trim(); + } +} diff --git a/src/test/java/seedu/duke/DukeTest.java b/src/test/java/seedu/financialplanner/FinancialPlannerTest.java similarity index 73% rename from src/test/java/seedu/duke/DukeTest.java rename to src/test/java/seedu/financialplanner/FinancialPlannerTest.java index 2dda5fd651..22f624b2d5 100644 --- a/src/test/java/seedu/duke/DukeTest.java +++ b/src/test/java/seedu/financialplanner/FinancialPlannerTest.java @@ -1,10 +1,10 @@ -package seedu.duke; +package seedu.financialplanner; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; -class DukeTest { +class FinancialPlannerTest { @Test public void sampleTest() { assertTrue(true); From d5be6d4bae825dbb2ba49c20588e7d1ecfaa8f7e Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Sat, 7 Oct 2023 14:47:13 +0800 Subject: [PATCH 007/518] Add FinancialPlannerException Fixes #8 --- .../exceptions/FinancialPlannerException.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/main/java/seedu/financialplanner/exceptions/FinancialPlannerException.java diff --git a/src/main/java/seedu/financialplanner/exceptions/FinancialPlannerException.java b/src/main/java/seedu/financialplanner/exceptions/FinancialPlannerException.java new file mode 100644 index 0000000000..387c7ddd06 --- /dev/null +++ b/src/main/java/seedu/financialplanner/exceptions/FinancialPlannerException.java @@ -0,0 +1,7 @@ +package seedu.financialplanner.exceptions; + +public class FinancialPlannerException extends Exception { + public FinancialPlannerException(String message) { + super(message); + } +} From 41909a10cf9d822fabd58091788fa8d898615517 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Sat, 7 Oct 2023 14:59:33 +0800 Subject: [PATCH 008/518] Add Parser, add 'exit' and 'invalid' command to Parser --- .../financialplanner/FinancialPlanner.java | 13 ++++++++++- .../financialplanner/commands/Command.java | 8 +++++++ .../seedu/financialplanner/commands/Exit.java | 12 ++++++++++ .../financialplanner/commands/Invalid.java | 13 +++++++++++ .../seedu/financialplanner/utils/Parser.java | 22 +++++++++++++++++++ .../financialplanner/{ui => utils}/Ui.java | 2 +- 6 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 src/main/java/seedu/financialplanner/commands/Command.java create mode 100644 src/main/java/seedu/financialplanner/commands/Exit.java create mode 100644 src/main/java/seedu/financialplanner/commands/Invalid.java create mode 100644 src/main/java/seedu/financialplanner/utils/Parser.java rename src/main/java/seedu/financialplanner/{ui => utils}/Ui.java (93%) diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index ab8c7c56e2..c39bdfa954 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -1,6 +1,9 @@ package seedu.financialplanner; -import seedu.financialplanner.ui.Ui; +import seedu.financialplanner.commands.Command; +import seedu.financialplanner.commands.Exit; +import seedu.financialplanner.utils.Parser; +import seedu.financialplanner.utils.Ui; public class FinancialPlanner { private Ui ui; @@ -11,6 +14,14 @@ public FinancialPlanner() { public void run() { ui.welcomeMessage(); + String input; + Command command = null; + + while (!(command instanceof Exit)) { + input = ui.input(); + command = Parser.parse(input); + command.execute(ui); + } ui.exitMessage(); } diff --git a/src/main/java/seedu/financialplanner/commands/Command.java b/src/main/java/seedu/financialplanner/commands/Command.java new file mode 100644 index 0000000000..cc938892ec --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/Command.java @@ -0,0 +1,8 @@ +package seedu.financialplanner.commands; + +import seedu.financialplanner.utils.Ui; + +public class Command { + public void execute(Ui ui) { + } +} diff --git a/src/main/java/seedu/financialplanner/commands/Exit.java b/src/main/java/seedu/financialplanner/commands/Exit.java new file mode 100644 index 0000000000..1f00847423 --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/Exit.java @@ -0,0 +1,12 @@ +package seedu.financialplanner.commands; + +import seedu.financialplanner.utils.Ui; + +public class Exit extends Command { + public Exit() { + } + + @Override + public void execute(Ui ui) { + } +} diff --git a/src/main/java/seedu/financialplanner/commands/Invalid.java b/src/main/java/seedu/financialplanner/commands/Invalid.java new file mode 100644 index 0000000000..6b9a3a2720 --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/Invalid.java @@ -0,0 +1,13 @@ +package seedu.financialplanner.commands; + +import seedu.financialplanner.utils.Ui; + +public class Invalid extends Command { + public Invalid() { + } + + @Override + public void execute(Ui ui) { + ui.showMessage("\tUnknown command. Please try again."); + } +} diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java new file mode 100644 index 0000000000..21d1f90458 --- /dev/null +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -0,0 +1,22 @@ +package seedu.financialplanner.utils; + +import seedu.financialplanner.commands.Command; +import seedu.financialplanner.commands.Exit; +import seedu.financialplanner.commands.Invalid; + +public class Parser { + private static final String EXIT_COMMAND = "exit"; + + public static Command parse(String input) { + String[] split = input.split(" ", 2); + String command = split[0].toLowerCase(); + String restOfInput = split.length > 1 ? split[1] : ""; // checks if rest of input is empty + + switch (command) { + case EXIT_COMMAND: + return new Exit(); + default: + return new Invalid(); + } + } +} diff --git a/src/main/java/seedu/financialplanner/ui/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java similarity index 93% rename from src/main/java/seedu/financialplanner/ui/Ui.java rename to src/main/java/seedu/financialplanner/utils/Ui.java index 308044430f..5057c70f48 100644 --- a/src/main/java/seedu/financialplanner/ui/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -1,4 +1,4 @@ -package seedu.financialplanner.ui; +package seedu.financialplanner.utils; import java.util.Scanner; From a988c38622239d85bf60a543816798ede11f1d0d Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Sat, 7 Oct 2023 19:19:35 +0800 Subject: [PATCH 009/518] Update test file --- text-ui-test/EXPECTED.TXT | 11 ++--------- text-ui-test/input.txt | 2 +- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 892cb6cae7..e39b240f0c 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,9 +1,2 @@ -Hello from - ____ _ -| _ \ _ _| | _____ -| | | | | | | |/ / _ \ -| |_| | |_| | < __/ -|____/ \__,_|_|\_\___| - -What is your name? -Hello James Gosling + Welcome to your Financial Planner. Type something to get started. + Exiting Financial Planner. Goodbye. diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index f6ec2e9f95..ae3bc0a936 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -1 +1 @@ -James Gosling \ No newline at end of file +exit \ No newline at end of file From 2d7049b261c1db9ee9b2fd302da80eac4f32b989 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 8 Oct 2023 12:35:18 +0800 Subject: [PATCH 010/518] Create cashflow and income classes --- .../seedu/financialplanner/list/Cashflow.java | 21 +++++++++++++++++++ .../seedu/financialplanner/list/Income.java | 12 +++++++++++ 2 files changed, 33 insertions(+) create mode 100644 src/main/java/seedu/financialplanner/list/Cashflow.java create mode 100644 src/main/java/seedu/financialplanner/list/Income.java diff --git a/src/main/java/seedu/financialplanner/list/Cashflow.java b/src/main/java/seedu/financialplanner/list/Cashflow.java new file mode 100644 index 0000000000..e63a74d257 --- /dev/null +++ b/src/main/java/seedu/financialplanner/list/Cashflow.java @@ -0,0 +1,21 @@ +package seedu.financialplanner.list; + +public class Cashflow { + + protected static double balance = 0; + protected double value; + protected String type; + protected int recur; + + public Cashflow(double value, String type, int recur) { + this.value = value; + this.type = type; + this.recur = recur; + } + + public Cashflow() { + this.value = 0; + this.type = null; + this.recur = 0; + } +} diff --git a/src/main/java/seedu/financialplanner/list/Income.java b/src/main/java/seedu/financialplanner/list/Income.java new file mode 100644 index 0000000000..e6cec70c51 --- /dev/null +++ b/src/main/java/seedu/financialplanner/list/Income.java @@ -0,0 +1,12 @@ +package seedu.financialplanner.list; + +public class Income extends Cashflow{ + public Income(double value, String type, int recur) { + super(value, type, recur); + addIncome(value); + } + + private void addIncome(double value) { + balance += value; + } +} From f8e310a44b9827b00635f829dd8d1fd8a11224e9 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 8 Oct 2023 12:35:33 +0800 Subject: [PATCH 011/518] Create ArrayList to store entries --- .../seedu/financialplanner/list/FinancialList.java | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/main/java/seedu/financialplanner/list/FinancialList.java diff --git a/src/main/java/seedu/financialplanner/list/FinancialList.java b/src/main/java/seedu/financialplanner/list/FinancialList.java new file mode 100644 index 0000000000..73c699be03 --- /dev/null +++ b/src/main/java/seedu/financialplanner/list/FinancialList.java @@ -0,0 +1,11 @@ +package seedu.financialplanner.list; + +import java.util.ArrayList; + +public class FinancialList { + protected ArrayList list = new ArrayList<>(); + + public ArrayList getList() { + return list; + } +} From ae8527bbe3908a49eee3eeba95bb39a9778f275b Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 8 Oct 2023 12:41:44 +0800 Subject: [PATCH 012/518] Add ability to add income to the ArrayList --- .../java/seedu/financialplanner/list/FinancialList.java | 8 ++++++++ src/main/java/seedu/financialplanner/list/Income.java | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/list/FinancialList.java b/src/main/java/seedu/financialplanner/list/FinancialList.java index 73c699be03..652bf5be1e 100644 --- a/src/main/java/seedu/financialplanner/list/FinancialList.java +++ b/src/main/java/seedu/financialplanner/list/FinancialList.java @@ -8,4 +8,12 @@ public class FinancialList { public ArrayList getList() { return list; } + private void printAddedCashflow(String line) { + System.out.println("Added " + line + "to the list."); + } + public void addIncome(double value, String type, int recur) { + Income toAdd = new Income(value, type, recur); + list.add(toAdd); + printAddedCashflow("income"); + } } diff --git a/src/main/java/seedu/financialplanner/list/Income.java b/src/main/java/seedu/financialplanner/list/Income.java index e6cec70c51..31ddbf8310 100644 --- a/src/main/java/seedu/financialplanner/list/Income.java +++ b/src/main/java/seedu/financialplanner/list/Income.java @@ -3,10 +3,10 @@ public class Income extends Cashflow{ public Income(double value, String type, int recur) { super(value, type, recur); - addIncome(value); + addIncomeValue(value); } - private void addIncome(double value) { + private void addIncomeValue(double value) { balance += value; } } From c09c55e2fbf921cb8794c0eac6512dbc9b291f2a Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 8 Oct 2023 13:49:31 +0800 Subject: [PATCH 013/518] Add ability to add income through user input --- .../financialplanner/FinancialPlanner.java | 8 +++- .../financialplanner/commands/Entry.java | 41 +++++++++++++++++++ .../financialplanner/list/FinancialList.java | 4 +- .../seedu/financialplanner/utils/Parser.java | 12 +++++- 4 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 src/main/java/seedu/financialplanner/commands/Entry.java diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index c39bdfa954..ae84df18ab 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -2,14 +2,20 @@ import seedu.financialplanner.commands.Command; import seedu.financialplanner.commands.Exit; +import seedu.financialplanner.list.Cashflow; +import seedu.financialplanner.list.FinancialList; import seedu.financialplanner.utils.Parser; import seedu.financialplanner.utils.Ui; +import java.util.ArrayList; + public class FinancialPlanner { private Ui ui; + private FinancialList financialList; public FinancialPlanner() { ui = new Ui(); + financialList = new FinancialList(); } public void run() { @@ -19,7 +25,7 @@ public void run() { while (!(command instanceof Exit)) { input = ui.input(); - command = Parser.parse(input); + command = Parser.parse(input, financialList); command.execute(ui); } ui.exitMessage(); diff --git a/src/main/java/seedu/financialplanner/commands/Entry.java b/src/main/java/seedu/financialplanner/commands/Entry.java new file mode 100644 index 0000000000..f43947f715 --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/Entry.java @@ -0,0 +1,41 @@ +package seedu.financialplanner.commands; + +import seedu.financialplanner.list.FinancialList; + +public class Entry extends Command{ + private static final String INCOME = "income"; + protected String entryType; + protected String[] parameters; + protected FinancialList list; + + public Entry(String entryParameters, FinancialList list) { + String[] split = entryParameters.split(" ", 2); + this.entryType = split[0]; + String restOfInput = split[1]; + this.parameters = restOfInput.split(" "); + this.list = list; + addEntry(); + } + + private int determineRecur() { + if (parameters.length == 3) { + String recur = parameters[2].substring(2); + return Integer.parseInt(recur); + } + return 0; + } + + private void addEntry() { + switch (entryType) { + case INCOME: + double value = Double.parseDouble(parameters[0].substring(2)); + String type = parameters[1].substring(2); + int recur = determineRecur(); + list.addIncome(value, type, recur); + break; + default: + System.out.println("Unidentified entry."); + break; + } + } +} diff --git a/src/main/java/seedu/financialplanner/list/FinancialList.java b/src/main/java/seedu/financialplanner/list/FinancialList.java index 652bf5be1e..f135841ba4 100644 --- a/src/main/java/seedu/financialplanner/list/FinancialList.java +++ b/src/main/java/seedu/financialplanner/list/FinancialList.java @@ -5,9 +5,7 @@ public class FinancialList { protected ArrayList list = new ArrayList<>(); - public ArrayList getList() { - return list; - } + private void printAddedCashflow(String line) { System.out.println("Added " + line + "to the list."); } diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index 21d1f90458..2359c5af0c 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -1,13 +1,21 @@ package seedu.financialplanner.utils; +import seedu.financialplanner.commands.Entry; import seedu.financialplanner.commands.Command; import seedu.financialplanner.commands.Exit; import seedu.financialplanner.commands.Invalid; +import seedu.financialplanner.list.Cashflow; +import seedu.financialplanner.list.FinancialList; + +import java.util.ArrayList; public class Parser { private static final String EXIT_COMMAND = "exit"; + private static final String ADD_ENTRY = "add"; + + - public static Command parse(String input) { + public static Command parse(String input, FinancialList list) { String[] split = input.split(" ", 2); String command = split[0].toLowerCase(); String restOfInput = split.length > 1 ? split[1] : ""; // checks if rest of input is empty @@ -15,6 +23,8 @@ public static Command parse(String input) { switch (command) { case EXIT_COMMAND: return new Exit(); + case ADD_ENTRY: + return new Entry(restOfInput, list); default: return new Invalid(); } From 68d635974b5493f20ba1ffaa1b953cf0b798a5ae Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 8 Oct 2023 14:36:28 +0800 Subject: [PATCH 014/518] Add new watchlist command and pull from FMP api for stock data --- .../financialplanner/commands/WatchList.java | 32 +++++++++++++++++++ .../seedu/financialplanner/utils/Parser.java | 4 +++ 2 files changed, 36 insertions(+) create mode 100644 src/main/java/seedu/financialplanner/commands/WatchList.java diff --git a/src/main/java/seedu/financialplanner/commands/WatchList.java b/src/main/java/seedu/financialplanner/commands/WatchList.java new file mode 100644 index 0000000000..18812cd11b --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/WatchList.java @@ -0,0 +1,32 @@ +package seedu.financialplanner.commands; + +import seedu.financialplanner.utils.Ui; + +import java.io.IOException; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; + +public class WatchList extends Command { + @Override + public void execute(Ui ui) { + + HttpClient client = HttpClient.newHttpClient(); + + HttpRequest request = HttpRequest.newBuilder(URI.create("https://financialmodelingprep.com/api/v3/quote/META,AAPL?apikey=rNCNMmSLUR3BAyeKFHwN69QGzE8fmig1")) + .header("accept", "application/json") + .build(); + + try { + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + System.out.println(response.body()); + } catch (IOException e) { + throw new RuntimeException(e); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + } +} diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index 21d1f90458..06ccac904c 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -3,9 +3,11 @@ import seedu.financialplanner.commands.Command; import seedu.financialplanner.commands.Exit; import seedu.financialplanner.commands.Invalid; +import seedu.financialplanner.commands.WatchList; public class Parser { private static final String EXIT_COMMAND = "exit"; + private static final String WATCHLIST_COMMAND = "watchlist"; public static Command parse(String input) { String[] split = input.split(" ", 2); @@ -15,6 +17,8 @@ public static Command parse(String input) { switch (command) { case EXIT_COMMAND: return new Exit(); + case WATCHLIST_COMMAND: + return new WatchList(); default: return new Invalid(); } From 17fea1ee0b01d0acd6fa797bca86c66770974214 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 8 Oct 2023 14:57:40 +0800 Subject: [PATCH 015/518] Remove unused imports --- src/main/java/seedu/financialplanner/FinancialPlanner.java | 3 --- src/main/java/seedu/financialplanner/utils/Parser.java | 2 -- 2 files changed, 5 deletions(-) diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index ae84df18ab..f934646a2a 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -2,13 +2,10 @@ import seedu.financialplanner.commands.Command; import seedu.financialplanner.commands.Exit; -import seedu.financialplanner.list.Cashflow; import seedu.financialplanner.list.FinancialList; import seedu.financialplanner.utils.Parser; import seedu.financialplanner.utils.Ui; -import java.util.ArrayList; - public class FinancialPlanner { private Ui ui; private FinancialList financialList; diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index 2359c5af0c..7e43529fe1 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -4,10 +4,8 @@ import seedu.financialplanner.commands.Command; import seedu.financialplanner.commands.Exit; import seedu.financialplanner.commands.Invalid; -import seedu.financialplanner.list.Cashflow; import seedu.financialplanner.list.FinancialList; -import java.util.ArrayList; public class Parser { private static final String EXIT_COMMAND = "exit"; From d5200ef10bf45e451d5057995598577e58195500 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 8 Oct 2023 14:58:14 +0800 Subject: [PATCH 016/518] Add rounding of double values to 2 decimal places --- .../financialplanner/list/FinancialList.java | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/list/FinancialList.java b/src/main/java/seedu/financialplanner/list/FinancialList.java index f135841ba4..1cb3085b10 100644 --- a/src/main/java/seedu/financialplanner/list/FinancialList.java +++ b/src/main/java/seedu/financialplanner/list/FinancialList.java @@ -1,14 +1,39 @@ package seedu.financialplanner.list; +import java.text.DecimalFormat; import java.util.ArrayList; +import java.math.BigDecimal; +import java.math.RoundingMode; public class FinancialList { protected ArrayList list = new ArrayList<>(); - private void printAddedCashflow(String line) { - System.out.println("Added " + line + "to the list."); + DecimalFormat decimalFormat = new DecimalFormat("####0.00"); + + Cashflow cashflow = list.get(list.size() - 1); + System.out.print("Added " + line + " of value: "); + System.out.println(decimalFormat.format(round(cashflow.value, 2)) + " to the list."); + System.out.println("type: " + cashflow.type); + if (cashflow.recur != 0) { + System.out.println("recurring every: " + cashflow.recur + " days"); + } + System.out.println("balance: " + decimalFormat.format(round(Cashflow.balance, 2))); + } + + //@author mhadidg-reused + //Reused from https://stackoverflow.com/questions/2808535/round-a-double-to-2-decimal-places + public static double round(double value, int places) { + if (places < 0) { + throw new IllegalArgumentException(); + } + + BigDecimal bd = BigDecimal.valueOf(value); + bd = bd.setScale(places, RoundingMode.HALF_UP); + return bd.doubleValue(); } + //@author mhadidg + public void addIncome(double value, String type, int recur) { Income toAdd = new Income(value, type, recur); list.add(toAdd); From e12ed8368ad3bee02c11466fc8e5c0a8162baeb5 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 8 Oct 2023 14:59:01 +0800 Subject: [PATCH 017/518] Update test file --- text-ui-test/EXPECTED.TXT | 8 ++++++++ text-ui-test/input.txt | 1 + 2 files changed, 9 insertions(+) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index e39b240f0c..60db00030c 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,2 +1,10 @@ Welcome to your Financial Planner. Type something to get started. + Added income of value: 5000.00 to the list. + type: work + recurring every: 30 days + balance: 5000.00 + Added income of value: 123.12 to the list. + type: work + recurring every: 30 days + balance: 5123.12 Exiting Financial Planner. Goodbye. diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index ae3bc0a936..d0a44eed5c 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -1 +1,2 @@ +add income a/5000 t/work r/30 exit \ No newline at end of file From 5f7d5ba1fafae93224d2ae0559edae789e3747bd Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 8 Oct 2023 15:07:24 +0800 Subject: [PATCH 018/518] Add simple JSON library to parse response body and print to UI --- build.gradle | 1 + .../financialplanner/commands/WatchList.java | 25 ++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 477d6f4399..dc4fbc121d 100644 --- a/build.gradle +++ b/build.gradle @@ -12,6 +12,7 @@ repositories { dependencies { testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.10.0' testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.10.0' + implementation group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1' } test { diff --git a/src/main/java/seedu/financialplanner/commands/WatchList.java b/src/main/java/seedu/financialplanner/commands/WatchList.java index 18812cd11b..66f50dd144 100644 --- a/src/main/java/seedu/financialplanner/commands/WatchList.java +++ b/src/main/java/seedu/financialplanner/commands/WatchList.java @@ -8,6 +8,7 @@ import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.time.Duration; +import java.util.Iterator; public class WatchList extends Command { @Override @@ -21,11 +22,33 @@ public void execute(Ui ui) { try { HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); - System.out.println(response.body()); + // System.out.println(response.body()); + Object obj = new JSONParser().parse(response.body()); + + JSONArray ja = (JSONArray) obj; + // System.out.println(ja.toJSONString()); + Iterator itr = ja.iterator(); + System.out.print("Symbol"); + System.out.print(" "); + System.out.print("Price"); + System.out.print(" "); + System.out.print("Company Name"); + System.out.println(); + while (itr.hasNext()) { + JSONObject stock = (JSONObject) itr.next(); + System.out.print(stock.get("symbol")); + System.out.print(" "); + System.out.print(stock.get("price")); + System.out.print(" "); + System.out.print(stock.get("name")); + System.out.println(); + } } catch (IOException e) { throw new RuntimeException(e); } catch (InterruptedException e) { throw new RuntimeException(e); + } catch (ParseException e) { + throw new RuntimeException(e); } } From c9daed435f0538014db06c642d487427e73b1ac8 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 8 Oct 2023 15:11:23 +0800 Subject: [PATCH 019/518] Add expense class and ability to add expense through user input --- .../java/seedu/financialplanner/commands/Entry.java | 11 ++++++++--- .../java/seedu/financialplanner/list/Expense.java | 12 ++++++++++++ .../seedu/financialplanner/list/FinancialList.java | 6 ++++++ 3 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 src/main/java/seedu/financialplanner/list/Expense.java diff --git a/src/main/java/seedu/financialplanner/commands/Entry.java b/src/main/java/seedu/financialplanner/commands/Entry.java index f43947f715..9499ddfdaf 100644 --- a/src/main/java/seedu/financialplanner/commands/Entry.java +++ b/src/main/java/seedu/financialplanner/commands/Entry.java @@ -4,6 +4,7 @@ public class Entry extends Command{ private static final String INCOME = "income"; + private static final String EXPENSE = "expense"; protected String entryType; protected String[] parameters; protected FinancialList list; @@ -26,13 +27,17 @@ private int determineRecur() { } private void addEntry() { + double value = Double.parseDouble(parameters[0].substring(2)); + String type = parameters[1].substring(2); + int recur = determineRecur(); + switch (entryType) { case INCOME: - double value = Double.parseDouble(parameters[0].substring(2)); - String type = parameters[1].substring(2); - int recur = determineRecur(); list.addIncome(value, type, recur); break; + case EXPENSE: + list.addExpense(value, type, recur); + break; default: System.out.println("Unidentified entry."); break; diff --git a/src/main/java/seedu/financialplanner/list/Expense.java b/src/main/java/seedu/financialplanner/list/Expense.java new file mode 100644 index 0000000000..6aae39d6c4 --- /dev/null +++ b/src/main/java/seedu/financialplanner/list/Expense.java @@ -0,0 +1,12 @@ +package seedu.financialplanner.list; + +public class Expense extends Cashflow { + public Expense(double value, String type, int recur) { + super(value, type, recur); + addIncomeValue(value); + } + + private void addIncomeValue(double value) { + balance -= value; + } +} diff --git a/src/main/java/seedu/financialplanner/list/FinancialList.java b/src/main/java/seedu/financialplanner/list/FinancialList.java index 1cb3085b10..0b461b1f60 100644 --- a/src/main/java/seedu/financialplanner/list/FinancialList.java +++ b/src/main/java/seedu/financialplanner/list/FinancialList.java @@ -39,4 +39,10 @@ public void addIncome(double value, String type, int recur) { list.add(toAdd); printAddedCashflow("income"); } + + public void addExpense(double value, String type, int recur) { + Expense toAdd = new Expense(value, type, recur); + list.add(toAdd); + printAddedCashflow("expense"); + } } From bfa75c44ff77cc7824fb4a072c8d4a8e94a19e09 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 8 Oct 2023 15:15:11 +0800 Subject: [PATCH 020/518] Use string format to create request URI --- .../seedu/financialplanner/commands/WatchList.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/WatchList.java b/src/main/java/seedu/financialplanner/commands/WatchList.java index 66f50dd144..2e3567d9e1 100644 --- a/src/main/java/seedu/financialplanner/commands/WatchList.java +++ b/src/main/java/seedu/financialplanner/commands/WatchList.java @@ -1,5 +1,9 @@ package seedu.financialplanner.commands; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; import seedu.financialplanner.utils.Ui; import java.io.IOException; @@ -7,16 +11,20 @@ import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; -import java.time.Duration; import java.util.Iterator; public class WatchList extends Command { + + private final String API_ENDPOINT = "https://financialmodelingprep.com/api/v3/quote/"; + private final String API_KEY = "rNCNMmSLUR3BAyeKFHwN69QGzE8fmig1"; @Override public void execute(Ui ui) { HttpClient client = HttpClient.newHttpClient(); + String stocks = "META,AAPL"; + String requestURI = String.format("%s%s?apikey=%s", API_ENDPOINT,stocks,API_KEY); - HttpRequest request = HttpRequest.newBuilder(URI.create("https://financialmodelingprep.com/api/v3/quote/META,AAPL?apikey=rNCNMmSLUR3BAyeKFHwN69QGzE8fmig1")) + HttpRequest request = HttpRequest.newBuilder(URI.create(requestURI)) .header("accept", "application/json") .build(); From 26b06f9c92c6a293c902d83d8de8f4fa7434c443 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 8 Oct 2023 15:35:33 +0800 Subject: [PATCH 021/518] Fix bug of not recognising description of parameters --- .../financialplanner/commands/Entry.java | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/Entry.java b/src/main/java/seedu/financialplanner/commands/Entry.java index 9499ddfdaf..7a8b0e2d11 100644 --- a/src/main/java/seedu/financialplanner/commands/Entry.java +++ b/src/main/java/seedu/financialplanner/commands/Entry.java @@ -6,30 +6,38 @@ public class Entry extends Command{ private static final String INCOME = "income"; private static final String EXPENSE = "expense"; protected String entryType; - protected String[] parameters; + protected String parameters; protected FinancialList list; public Entry(String entryParameters, FinancialList list) { String[] split = entryParameters.split(" ", 2); this.entryType = split[0]; - String restOfInput = split[1]; - this.parameters = restOfInput.split(" "); + this.parameters = split[1]; this.list = list; addEntry(); } private int determineRecur() { - if (parameters.length == 3) { - String recur = parameters[2].substring(2); + if (parameters.contains("r/")) { + int indexOfRecur = parameters.indexOf("r/"); + String recur = parameters.substring(indexOfRecur + 2).trim(); return Integer.parseInt(recur); } return 0; } private void addEntry() { - double value = Double.parseDouble(parameters[0].substring(2)); - String type = parameters[1].substring(2); int recur = determineRecur(); + int indexOfAmount = parameters.indexOf("a/"); + int indexOfType = parameters.indexOf("t/"); + double value = Double.parseDouble(parameters.substring(indexOfAmount + 2, indexOfType).trim()); + String type; + if (recur == 0) { + type = parameters.substring(indexOfType + 2).trim(); + } else { + int indexOfRecur = parameters.indexOf("r/"); + type = parameters.substring(indexOfType + 2, indexOfRecur).trim(); + } switch (entryType) { case INCOME: From 4b08a122b8a53c349226c377cd63e01cd2fbe5b1 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 8 Oct 2023 15:35:55 +0800 Subject: [PATCH 022/518] Update test file to include expenses input --- text-ui-test/EXPECTED.TXT | 22 ++++++++++++++-------- text-ui-test/input.txt | 3 +++ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 60db00030c..07d5a93dc3 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,10 +1,16 @@ Welcome to your Financial Planner. Type something to get started. - Added income of value: 5000.00 to the list. - type: work - recurring every: 30 days - balance: 5000.00 - Added income of value: 123.12 to the list. - type: work - recurring every: 30 days - balance: 5123.12 +Added income of value: 5000.00 to the list. +type: work +recurring every: 30 days +balance: 5000.00 +Added income of value: 123.12 to the list. +type: allowance +balance: 5123.12 +Added expense of value: 100.00 to the list. +type: daily necessities +recurring every: 30 days +balance: 5023.12 +Added expense of value: 123.21 to the list. +type: books +balance: 4899.91 Exiting Financial Planner. Goodbye. diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index d0a44eed5c..fc3780332a 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -1,2 +1,5 @@ add income a/5000 t/work r/30 +add income a/123.12 t/allowance +add expense a/100 t/daily necessities r/30 +add expense a/123.21 t/books exit \ No newline at end of file From d5ac9fceb7e20c02055b08cff4c73c88830bb993 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 8 Oct 2023 16:05:16 +0800 Subject: [PATCH 023/518] Add a stock class and have the watchlist query API endpoint using stock classes created --- .../financialplanner/commands/WatchList.java | 17 ++++- .../financialplanner/investments/Stock.java | 72 +++++++++++++++++++ 2 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 src/main/java/seedu/financialplanner/investments/Stock.java diff --git a/src/main/java/seedu/financialplanner/commands/WatchList.java b/src/main/java/seedu/financialplanner/commands/WatchList.java index 2e3567d9e1..c97a5e3ecf 100644 --- a/src/main/java/seedu/financialplanner/commands/WatchList.java +++ b/src/main/java/seedu/financialplanner/commands/WatchList.java @@ -4,6 +4,7 @@ import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; +import seedu.financialplanner.investments.Stock; import seedu.financialplanner.utils.Ui; import java.io.IOException; @@ -11,6 +12,8 @@ import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; +import java.time.Duration; +import java.util.ArrayList; import java.util.Iterator; public class WatchList extends Command { @@ -21,11 +24,21 @@ public class WatchList extends Command { public void execute(Ui ui) { HttpClient client = HttpClient.newHttpClient(); - String stocks = "META,AAPL"; - String requestURI = String.format("%s%s?apikey=%s", API_ENDPOINT,stocks,API_KEY); + ArrayList stocks = new ArrayList<>(); + stocks.add(new Stock("AAPL", "NASDAQ")); + stocks.add(new Stock("META", "NASDAQ")); + stocks.add(new Stock("GOOGL", "NASDAQ")); + // String stocks = "META,AAPL,VOO"; + StringBuilder queryStocks = new StringBuilder(); + for (Stock stock : stocks) { + queryStocks.append(stock.toString()); + } + String requestURI = String.format("%s%s?apikey=%s", API_ENDPOINT, queryStocks,API_KEY); HttpRequest request = HttpRequest.newBuilder(URI.create(requestURI)) .header("accept", "application/json") + .GET() + .timeout(Duration.ofSeconds(10)) .build(); try { diff --git a/src/main/java/seedu/financialplanner/investments/Stock.java b/src/main/java/seedu/financialplanner/investments/Stock.java new file mode 100644 index 0000000000..4d13478bb6 --- /dev/null +++ b/src/main/java/seedu/financialplanner/investments/Stock.java @@ -0,0 +1,72 @@ +package seedu.financialplanner.investments; + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import seedu.financialplanner.exceptions.FinancialPlannerException; + +import java.io.IOException; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; + +public class Stock { + private String symbol; + private String market; + private String stockName; + + public Stock(String symbol, String market) { + this.symbol = symbol; + this.market = market; + this.stockName = getStockName(symbol,market); + } + + public String getStockName(String symbol, String market) { + final String API_ENDPOINT = "https://financialmodelingprep.com/api/v3/search-ticker?query="; + final String API_KEY = "rNCNMmSLUR3BAyeKFHwN69QGzE8fmig1"; + String requestURI = String.format("%s%s&exchange=%s&apikey=%s", API_ENDPOINT,symbol,market,API_KEY); + HttpClient client = HttpClient.newHttpClient(); + HttpRequest request = HttpRequest.newBuilder(URI.create(requestURI)) + .header("accept", "application/json") + .GET() + .timeout(Duration.ofSeconds(10)) + .build(); + try { + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + Object obj = new JSONParser().parse(response.body()); + + JSONArray ja = (JSONArray) obj; + if (ja.size() != 1) { + throw new FinancialPlannerException("stock not found"); + } else { + JSONObject stock = (JSONObject) ja.get(0); + System.out.println(stock.get("name")); + return (String) stock.get("name"); + } + } catch (IOException e) { + throw new RuntimeException(e); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } catch (ParseException e) { + throw new RuntimeException(e); + } catch (FinancialPlannerException e) { + throw new RuntimeException(e); + } + } + + public String getSymbol() { + return symbol; + } + + public void setSymbol(String symbol) { + this.symbol = symbol; + } + + @Override + public String toString() { + return symbol + ","; + } +} From 66c6dc6ad21cbde9abe158bb32b30160a572021d Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 8 Oct 2023 16:18:07 +0800 Subject: [PATCH 024/518] Add commons lang library to allow for padding of string when printing --- build.gradle | 1 + .../financialplanner/commands/WatchList.java | 17 ++++++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/build.gradle b/build.gradle index dc4fbc121d..4bd48aac5b 100644 --- a/build.gradle +++ b/build.gradle @@ -13,6 +13,7 @@ dependencies { testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.10.0' testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.10.0' implementation group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1' + implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.0' } test { diff --git a/src/main/java/seedu/financialplanner/commands/WatchList.java b/src/main/java/seedu/financialplanner/commands/WatchList.java index c97a5e3ecf..5d6be78966 100644 --- a/src/main/java/seedu/financialplanner/commands/WatchList.java +++ b/src/main/java/seedu/financialplanner/commands/WatchList.java @@ -1,5 +1,6 @@ package seedu.financialplanner.commands; +import org.apache.commons.lang3.StringUtils; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; @@ -50,19 +51,14 @@ public void execute(Ui ui) { // System.out.println(ja.toJSONString()); Iterator itr = ja.iterator(); System.out.print("Symbol"); - System.out.print(" "); + System.out.print(" "); System.out.print("Price"); System.out.print(" "); System.out.print("Company Name"); System.out.println(); while (itr.hasNext()) { JSONObject stock = (JSONObject) itr.next(); - System.out.print(stock.get("symbol")); - System.out.print(" "); - System.out.print(stock.get("price")); - System.out.print(" "); - System.out.print(stock.get("name")); - System.out.println(); + printStockInfo(stock); } } catch (IOException e) { throw new RuntimeException(e); @@ -73,4 +69,11 @@ public void execute(Ui ui) { } } + + public void printStockInfo(JSONObject stock) { + String symbol = StringUtils.rightPad((String) stock.get("symbol"), 10); + String price = StringUtils.rightPad(stock.get("price").toString(), 10); + String name = StringUtils.rightPad((String) stock.get("name"), 10); + System.out.println(symbol + price + name); + } } From c0e43ac6456c816b00caf8ff6e6299f7026fabf1 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 8 Oct 2023 23:11:15 +0800 Subject: [PATCH 025/518] Edit test file --- text-ui-test/EXPECTED.TXT | 14 -------------- text-ui-test/input.txt | 4 ---- 2 files changed, 18 deletions(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 07d5a93dc3..e39b240f0c 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,16 +1,2 @@ Welcome to your Financial Planner. Type something to get started. -Added income of value: 5000.00 to the list. -type: work -recurring every: 30 days -balance: 5000.00 -Added income of value: 123.12 to the list. -type: allowance -balance: 5123.12 -Added expense of value: 100.00 to the list. -type: daily necessities -recurring every: 30 days -balance: 5023.12 -Added expense of value: 123.21 to the list. -type: books -balance: 4899.91 Exiting Financial Planner. Goodbye. diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index fc3780332a..ae3bc0a936 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -1,5 +1 @@ -add income a/5000 t/work r/30 -add income a/123.12 t/allowance -add expense a/100 t/daily necessities r/30 -add expense a/123.21 t/books exit \ No newline at end of file From 4b7aa80bfe1c46aac6581012cfe57fe4efd37ab2 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Mon, 9 Oct 2023 11:21:43 +0800 Subject: [PATCH 026/518] Update test file and multiple code refactorings Fixes #34 --- .../financialplanner/FinancialPlanner.java | 4 +-- .../financialplanner/commands/Command.java | 3 ++- .../financialplanner/commands/Entry.java | 25 +++++++++---------- .../seedu/financialplanner/commands/Exit.java | 3 ++- .../financialplanner/commands/Invalid.java | 5 ++-- .../seedu/financialplanner/utils/Parser.java | 8 +++--- .../java/seedu/financialplanner/utils/Ui.java | 6 ++--- text-ui-test/EXPECTED.TXT | 19 ++++++++++++-- text-ui-test/input.txt | 5 ++++ 9 files changed, 50 insertions(+), 28 deletions(-) diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index f934646a2a..869e610653 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -22,8 +22,8 @@ public void run() { while (!(command instanceof Exit)) { input = ui.input(); - command = Parser.parse(input, financialList); - command.execute(ui); + command = Parser.parse(input); + command.execute(ui, financialList); } ui.exitMessage(); } diff --git a/src/main/java/seedu/financialplanner/commands/Command.java b/src/main/java/seedu/financialplanner/commands/Command.java index cc938892ec..78a3e60fd2 100644 --- a/src/main/java/seedu/financialplanner/commands/Command.java +++ b/src/main/java/seedu/financialplanner/commands/Command.java @@ -1,8 +1,9 @@ package seedu.financialplanner.commands; +import seedu.financialplanner.list.FinancialList; import seedu.financialplanner.utils.Ui; public class Command { - public void execute(Ui ui) { + public void execute(Ui ui, FinancialList financialList) { } } diff --git a/src/main/java/seedu/financialplanner/commands/Entry.java b/src/main/java/seedu/financialplanner/commands/Entry.java index 7a8b0e2d11..af74c0a958 100644 --- a/src/main/java/seedu/financialplanner/commands/Entry.java +++ b/src/main/java/seedu/financialplanner/commands/Entry.java @@ -1,23 +1,18 @@ package seedu.financialplanner.commands; import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.utils.Ui; public class Entry extends Command{ private static final String INCOME = "income"; private static final String EXPENSE = "expense"; - protected String entryType; - protected String parameters; - protected FinancialList list; + protected String input; - public Entry(String entryParameters, FinancialList list) { - String[] split = entryParameters.split(" ", 2); - this.entryType = split[0]; - this.parameters = split[1]; - this.list = list; - addEntry(); + public Entry(String input) { + this.input = input; } - private int determineRecur() { + private int determineRecur(String parameters) { if (parameters.contains("r/")) { int indexOfRecur = parameters.indexOf("r/"); String recur = parameters.substring(indexOfRecur + 2).trim(); @@ -26,8 +21,12 @@ private int determineRecur() { return 0; } - private void addEntry() { - int recur = determineRecur(); + @Override + public void execute(Ui ui, FinancialList list) { + String[] split = input.split(" ", 2); + String entryType = split[0]; + String parameters = split[1]; + int recur = determineRecur(parameters); int indexOfAmount = parameters.indexOf("a/"); int indexOfType = parameters.indexOf("t/"); double value = Double.parseDouble(parameters.substring(indexOfAmount + 2, indexOfType).trim()); @@ -47,7 +46,7 @@ private void addEntry() { list.addExpense(value, type, recur); break; default: - System.out.println("Unidentified entry."); + ui.showMessage("Unidentified entry."); break; } } diff --git a/src/main/java/seedu/financialplanner/commands/Exit.java b/src/main/java/seedu/financialplanner/commands/Exit.java index 1f00847423..029fb8f75b 100644 --- a/src/main/java/seedu/financialplanner/commands/Exit.java +++ b/src/main/java/seedu/financialplanner/commands/Exit.java @@ -1,5 +1,6 @@ package seedu.financialplanner.commands; +import seedu.financialplanner.list.FinancialList; import seedu.financialplanner.utils.Ui; public class Exit extends Command { @@ -7,6 +8,6 @@ public Exit() { } @Override - public void execute(Ui ui) { + public void execute(Ui ui, FinancialList financialList) { } } diff --git a/src/main/java/seedu/financialplanner/commands/Invalid.java b/src/main/java/seedu/financialplanner/commands/Invalid.java index 6b9a3a2720..8d1784a075 100644 --- a/src/main/java/seedu/financialplanner/commands/Invalid.java +++ b/src/main/java/seedu/financialplanner/commands/Invalid.java @@ -1,5 +1,6 @@ package seedu.financialplanner.commands; +import seedu.financialplanner.list.FinancialList; import seedu.financialplanner.utils.Ui; public class Invalid extends Command { @@ -7,7 +8,7 @@ public Invalid() { } @Override - public void execute(Ui ui) { - ui.showMessage("\tUnknown command. Please try again."); + public void execute(Ui ui, FinancialList financialList) { + ui.showMessage("Unknown command. Please try again."); } } diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index 7e43529fe1..4949d1de59 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -9,11 +9,11 @@ public class Parser { private static final String EXIT_COMMAND = "exit"; - private static final String ADD_ENTRY = "add"; + private static final String ADD_ENTRY_COMMAND = "add"; - public static Command parse(String input, FinancialList list) { + public static Command parse(String input) { String[] split = input.split(" ", 2); String command = split[0].toLowerCase(); String restOfInput = split.length > 1 ? split[1] : ""; // checks if rest of input is empty @@ -21,8 +21,8 @@ public static Command parse(String input, FinancialList list) { switch (command) { case EXIT_COMMAND: return new Exit(); - case ADD_ENTRY: - return new Entry(restOfInput, list); + case ADD_ENTRY_COMMAND: + return new Entry(restOfInput); default: return new Invalid(); } diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 5057c70f48..af08da3509 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -3,6 +3,7 @@ import java.util.Scanner; public class Ui { + private Scanner in = new Scanner(System.in); public Ui() { } @@ -11,15 +12,14 @@ public void showMessage(String message) { } public void welcomeMessage() { - showMessage("\tWelcome to your Financial Planner. Type something to get started."); + showMessage("Welcome to your Financial Planner. Type something to get started."); } public void exitMessage() { - showMessage("\tExiting Financial Planner. Goodbye."); + showMessage("Exiting Financial Planner. Goodbye."); } public String input() { - Scanner in = new Scanner(System.in); return in.nextLine().trim(); } } diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index e39b240f0c..e9110ab378 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,2 +1,17 @@ - Welcome to your Financial Planner. Type something to get started. - Exiting Financial Planner. Goodbye. +Welcome to your Financial Planner. Type something to get started. +Added income of value: 5000.00 to the list. +type: work +recurring every: 30 days +balance: 5000.00 +Added income of value: 123.12 to the list. +type: allowance +balance: 5123.12 +Added expense of value: 100.00 to the list. +type: daily necessities +recurring every: 30 days +balance: 5023.12 +Added expense of value: 123.21 to the list. +type: books +balance: 4899.91 +Unknown command. Please try again. +Exiting Financial Planner. Goodbye. diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index ae3bc0a936..1274e7d7b0 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -1 +1,6 @@ +add income a/5000 t/work r/30 +add income a/123.12 t/allowance +add expense a/100 t/daily necessities r/30 +add expense a/123.21 t/books +sdf exit \ No newline at end of file From 91c6f28655a8d39e1d9b3067075e1ef6c6b3f2c0 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Mon, 9 Oct 2023 11:25:06 +0800 Subject: [PATCH 027/518] Remove unused import in Parser --- src/main/java/seedu/financialplanner/utils/Parser.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index 4949d1de59..4c2628140c 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -4,8 +4,6 @@ import seedu.financialplanner.commands.Command; import seedu.financialplanner.commands.Exit; import seedu.financialplanner.commands.Invalid; -import seedu.financialplanner.list.FinancialList; - public class Parser { private static final String EXIT_COMMAND = "exit"; From 9a32030207906b044fd774d1afcc8768c2f52b51 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 9 Oct 2023 14:31:50 +0800 Subject: [PATCH 028/518] Create a watchlist class to reference stocks --- .../commands/WatchListCommand.java | 31 ++++++++++++ .../{commands => investments}/WatchList.java | 47 +++++-------------- 2 files changed, 43 insertions(+), 35 deletions(-) create mode 100644 src/main/java/seedu/financialplanner/commands/WatchListCommand.java rename src/main/java/seedu/financialplanner/{commands => investments}/WatchList.java (57%) diff --git a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java new file mode 100644 index 0000000000..3d512f8f7a --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java @@ -0,0 +1,31 @@ +package seedu.financialplanner.commands; + +import org.apache.commons.lang3.StringUtils; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import seedu.financialplanner.investments.Stock; +import seedu.financialplanner.investments.WatchList; +import seedu.financialplanner.utils.Ui; + +import java.io.IOException; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; +import java.util.ArrayList; +import java.util.Iterator; + +public class WatchListCommand extends Command { + @Override + public void execute(Ui ui, WatchList watchList) { + JSONArray stocks = watchList.fetchFMPStockPrices(); + ui.printWatchListHeader(); + for (Object o : stocks) { + JSONObject stock = (JSONObject) o; + ui.printStockInfo(stock); + } + } +} diff --git a/src/main/java/seedu/financialplanner/commands/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java similarity index 57% rename from src/main/java/seedu/financialplanner/commands/WatchList.java rename to src/main/java/seedu/financialplanner/investments/WatchList.java index 5d6be78966..8ceeefbfc2 100644 --- a/src/main/java/seedu/financialplanner/commands/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -1,12 +1,10 @@ -package seedu.financialplanner.commands; +package seedu.financialplanner.investments; import org.apache.commons.lang3.StringUtils; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; -import seedu.financialplanner.investments.Stock; -import seedu.financialplanner.utils.Ui; import java.io.IOException; import java.net.URI; @@ -17,49 +15,35 @@ import java.util.ArrayList; import java.util.Iterator; -public class WatchList extends Command { - +public class WatchList { + private ArrayList stocks; private final String API_ENDPOINT = "https://financialmodelingprep.com/api/v3/quote/"; private final String API_KEY = "rNCNMmSLUR3BAyeKFHwN69QGzE8fmig1"; - @Override - public void execute(Ui ui) { - HttpClient client = HttpClient.newHttpClient(); - ArrayList stocks = new ArrayList<>(); + public WatchList() { + stocks = new ArrayList<>(); stocks.add(new Stock("AAPL", "NASDAQ")); stocks.add(new Stock("META", "NASDAQ")); stocks.add(new Stock("GOOGL", "NASDAQ")); - // String stocks = "META,AAPL,VOO"; + } + + public JSONArray fetchFMPStockPrices() { + HttpClient client = HttpClient.newHttpClient(); StringBuilder queryStocks = new StringBuilder(); for (Stock stock : stocks) { queryStocks.append(stock.toString()); } String requestURI = String.format("%s%s?apikey=%s", API_ENDPOINT, queryStocks,API_KEY); - HttpRequest request = HttpRequest.newBuilder(URI.create(requestURI)) .header("accept", "application/json") .GET() .timeout(Duration.ofSeconds(10)) .build(); - + Object obj; try { HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); // System.out.println(response.body()); - Object obj = new JSONParser().parse(response.body()); - - JSONArray ja = (JSONArray) obj; - // System.out.println(ja.toJSONString()); - Iterator itr = ja.iterator(); - System.out.print("Symbol"); - System.out.print(" "); - System.out.print("Price"); - System.out.print(" "); - System.out.print("Company Name"); - System.out.println(); - while (itr.hasNext()) { - JSONObject stock = (JSONObject) itr.next(); - printStockInfo(stock); - } + obj = new JSONParser().parse(response.body()); } catch (IOException e) { throw new RuntimeException(e); } catch (InterruptedException e) { @@ -67,13 +51,6 @@ public void execute(Ui ui) { } catch (ParseException e) { throw new RuntimeException(e); } - - } - - public void printStockInfo(JSONObject stock) { - String symbol = StringUtils.rightPad((String) stock.get("symbol"), 10); - String price = StringUtils.rightPad(stock.get("price").toString(), 10); - String name = StringUtils.rightPad((String) stock.get("name"), 10); - System.out.println(symbol + price + name); + return (JSONArray) obj; } } From a311199b47d9c35e55f5509eaba762545283cd61 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 9 Oct 2023 14:32:21 +0800 Subject: [PATCH 029/518] Create method in UI to print stock prices --- .../java/seedu/financialplanner/utils/Ui.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 5057c70f48..1415a41b02 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -1,5 +1,8 @@ package seedu.financialplanner.utils; +import org.apache.commons.lang3.StringUtils; +import org.json.simple.JSONObject; + import java.util.Scanner; public class Ui { @@ -22,4 +25,20 @@ public String input() { Scanner in = new Scanner(System.in); return in.nextLine().trim(); } + + public void printWatchListHeader() { + System.out.print("Symbol"); + System.out.print(" "); + System.out.print("Price"); + System.out.print(" "); + System.out.print("Company Name"); + System.out.println(); + } + + public void printStockInfo(JSONObject stock) { + String symbol = StringUtils.rightPad((String) stock.get("symbol"), 10); + String price = StringUtils.rightPad(stock.get("price").toString(), 10); + String name = StringUtils.rightPad((String) stock.get("name"), 10); + System.out.println(symbol + price + name); + } } From 84fb7092fb5158ab4e8aeb7b0e00b521bdd981df Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 9 Oct 2023 14:33:27 +0800 Subject: [PATCH 030/518] Add watchlist parameter to execute --- src/main/java/seedu/financialplanner/commands/Command.java | 3 ++- src/main/java/seedu/financialplanner/commands/Exit.java | 3 ++- src/main/java/seedu/financialplanner/commands/Invalid.java | 3 ++- src/main/java/seedu/financialplanner/investments/Stock.java | 1 - src/main/java/seedu/financialplanner/utils/Parser.java | 4 ++-- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/Command.java b/src/main/java/seedu/financialplanner/commands/Command.java index cc938892ec..7595a9a802 100644 --- a/src/main/java/seedu/financialplanner/commands/Command.java +++ b/src/main/java/seedu/financialplanner/commands/Command.java @@ -1,8 +1,9 @@ package seedu.financialplanner.commands; +import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.utils.Ui; public class Command { - public void execute(Ui ui) { + public void execute(Ui ui, WatchList watchList) { } } diff --git a/src/main/java/seedu/financialplanner/commands/Exit.java b/src/main/java/seedu/financialplanner/commands/Exit.java index 1f00847423..b4c4c19da4 100644 --- a/src/main/java/seedu/financialplanner/commands/Exit.java +++ b/src/main/java/seedu/financialplanner/commands/Exit.java @@ -1,5 +1,6 @@ package seedu.financialplanner.commands; +import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.utils.Ui; public class Exit extends Command { @@ -7,6 +8,6 @@ public Exit() { } @Override - public void execute(Ui ui) { + public void execute(Ui ui, WatchList watchList) { } } diff --git a/src/main/java/seedu/financialplanner/commands/Invalid.java b/src/main/java/seedu/financialplanner/commands/Invalid.java index 6b9a3a2720..9d34b86b11 100644 --- a/src/main/java/seedu/financialplanner/commands/Invalid.java +++ b/src/main/java/seedu/financialplanner/commands/Invalid.java @@ -1,5 +1,6 @@ package seedu.financialplanner.commands; +import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.utils.Ui; public class Invalid extends Command { @@ -7,7 +8,7 @@ public Invalid() { } @Override - public void execute(Ui ui) { + public void execute(Ui ui, WatchList watchList) { ui.showMessage("\tUnknown command. Please try again."); } } diff --git a/src/main/java/seedu/financialplanner/investments/Stock.java b/src/main/java/seedu/financialplanner/investments/Stock.java index 4d13478bb6..137c8091b0 100644 --- a/src/main/java/seedu/financialplanner/investments/Stock.java +++ b/src/main/java/seedu/financialplanner/investments/Stock.java @@ -43,7 +43,6 @@ public String getStockName(String symbol, String market) { throw new FinancialPlannerException("stock not found"); } else { JSONObject stock = (JSONObject) ja.get(0); - System.out.println(stock.get("name")); return (String) stock.get("name"); } } catch (IOException e) { diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index 06ccac904c..5f8e1a5700 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -3,7 +3,7 @@ import seedu.financialplanner.commands.Command; import seedu.financialplanner.commands.Exit; import seedu.financialplanner.commands.Invalid; -import seedu.financialplanner.commands.WatchList; +import seedu.financialplanner.commands.WatchListCommand; public class Parser { private static final String EXIT_COMMAND = "exit"; @@ -18,7 +18,7 @@ public static Command parse(String input) { case EXIT_COMMAND: return new Exit(); case WATCHLIST_COMMAND: - return new WatchList(); + return new WatchListCommand(); default: return new Invalid(); } From 2977b5bb71d186cf5ba1d7e15eb4c59e029f88c3 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 9 Oct 2023 14:33:51 +0800 Subject: [PATCH 031/518] Initialize watchlist on startup --- src/main/java/seedu/financialplanner/FinancialPlanner.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index c39bdfa954..d3bbee40b4 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -2,14 +2,17 @@ import seedu.financialplanner.commands.Command; import seedu.financialplanner.commands.Exit; +import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.utils.Parser; import seedu.financialplanner.utils.Ui; public class FinancialPlanner { private Ui ui; + private WatchList watchList; public FinancialPlanner() { ui = new Ui(); + watchList = new WatchList(); } public void run() { @@ -20,7 +23,7 @@ public void run() { while (!(command instanceof Exit)) { input = ui.input(); command = Parser.parse(input); - command.execute(ui); + command.execute(ui, watchList); } ui.exitMessage(); } From 74e0b77d800eb36b21b1534bb75611548d2b2164 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 9 Oct 2023 14:49:46 +0800 Subject: [PATCH 032/518] Remove unused imports --- .../financialplanner/commands/WatchListCommand.java | 13 ------------- .../financialplanner/investments/WatchList.java | 3 --- 2 files changed, 16 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java index 5bb2c940ac..0b6d427938 100644 --- a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java @@ -1,24 +1,11 @@ package seedu.financialplanner.commands; -import org.apache.commons.lang3.StringUtils; import org.json.simple.JSONArray; import org.json.simple.JSONObject; -import org.json.simple.parser.JSONParser; -import org.json.simple.parser.ParseException; -import seedu.financialplanner.investments.Stock; import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.list.FinancialList; import seedu.financialplanner.utils.Ui; -import java.io.IOException; -import java.net.URI; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.time.Duration; -import java.util.ArrayList; -import java.util.Iterator; - public class WatchListCommand extends Command { @Override public void execute(Ui ui, FinancialList financialList, WatchList watchList) { diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index 8ceeefbfc2..d1e3a14cf3 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -1,8 +1,6 @@ package seedu.financialplanner.investments; -import org.apache.commons.lang3.StringUtils; import org.json.simple.JSONArray; -import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; @@ -13,7 +11,6 @@ import java.net.http.HttpResponse; import java.time.Duration; import java.util.ArrayList; -import java.util.Iterator; public class WatchList { private ArrayList stocks; From a778bb54cf3c686fc074b019c292a87b7beeb3dd Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 9 Oct 2023 17:04:52 +0800 Subject: [PATCH 033/518] Add command for adding stock to watchlist --- .../commands/AddStockCommand.java | 27 +++++++++++++++++++ .../investments/WatchList.java | 21 ++++++++++++--- .../seedu/financialplanner/utils/Parser.java | 18 +++++++++++-- .../java/seedu/financialplanner/utils/Ui.java | 6 +++++ 4 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 src/main/java/seedu/financialplanner/commands/AddStockCommand.java diff --git a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java new file mode 100644 index 0000000000..c4f45972f4 --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java @@ -0,0 +1,27 @@ +package seedu.financialplanner.commands; + +import seedu.financialplanner.exceptions.FinancialPlannerException; +import seedu.financialplanner.investments.WatchList; +import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.utils.Ui; + +public class AddStockCommand extends Command { + private final String market; + private final String stockCode; + + public AddStockCommand(String market, String stockCode) { + this.market = market; + this.stockCode = stockCode; + } + + @Override + public void execute(Ui ui, FinancialList financialList, WatchList watchList) { + String stockName = null; + try { + stockName = watchList.addStock(market, stockCode); + ui.printAddStock(stockName); + } catch (FinancialPlannerException e) { + System.out.println(e.getMessage()); + } + } +} diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index d1e3a14cf3..9726c0c64f 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -3,6 +3,7 @@ import org.json.simple.JSONArray; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; +import seedu.financialplanner.exceptions.FinancialPlannerException; import java.io.IOException; import java.net.URI; @@ -19,9 +20,16 @@ public class WatchList { public WatchList() { stocks = new ArrayList<>(); - stocks.add(new Stock("AAPL", "NASDAQ")); - stocks.add(new Stock("META", "NASDAQ")); - stocks.add(new Stock("GOOGL", "NASDAQ")); + try { + Stock apple = new Stock("AAPL", "NASDAQ"); + stocks.add(apple); + Stock meta = new Stock("META", "NASDAQ"); + stocks.add(meta); + Stock google = new Stock("GOOGL", "NASDAQ"); + stocks.add(google); + } catch (FinancialPlannerException e) { + System.out.println(e.getMessage()); + } } public JSONArray fetchFMPStockPrices() { @@ -50,4 +58,11 @@ public JSONArray fetchFMPStockPrices() { } return (JSONArray) obj; } + + public String addStock(String market, String stockCode) throws FinancialPlannerException { + Stock newStock = null; + newStock = new Stock(stockCode, market); + stocks.add(newStock); + return newStock.getStockName(); + } } diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index d4f730ce0f..e1a1ea1070 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -1,10 +1,12 @@ package seedu.financialplanner.utils; -import seedu.financialplanner.commands.Entry; + import seedu.financialplanner.commands.Command; +import seedu.financialplanner.commands.Entry; import seedu.financialplanner.commands.Exit; -import seedu.financialplanner.commands.Invalid; import seedu.financialplanner.commands.WatchListCommand; +import seedu.financialplanner.commands.Invalid; +import seedu.financialplanner.commands.AddStockCommand; public class Parser { private static final String EXIT_COMMAND = "exit"; @@ -13,6 +15,8 @@ public class Parser { private static final String ADD_ENTRY_COMMAND = "add"; + private static final String ADD_STOCK_COMMAND = "addstock"; + public static Command parse(String input) { String[] split = input.split(" ", 2); String command = split[0].toLowerCase(); @@ -25,8 +29,18 @@ public static Command parse(String input) { return new WatchListCommand(); case ADD_ENTRY_COMMAND: return new Entry(restOfInput); + case ADD_STOCK_COMMAND: + return parseAddStock(restOfInput); default: return new Invalid(); } } + + private static Command parseAddStock(String restOfInput) { + String[] split = restOfInput.trim().split("m/|s/"); + // TODO: check error here + String exchange = split[1].trim(); + String stockCode = split[2].trim(); + return new AddStockCommand(exchange, stockCode); + } } diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 0bcd6fd67e..604ae79429 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -41,4 +41,10 @@ public void printStockInfo(JSONObject stock) { String name = StringUtils.rightPad((String) stock.get("name"), 10); System.out.println(symbol + price + name); } + + public void printAddStock(String stockName) { + System.out.println("You have successfully added:"); + System.out.println(stockName); + System.out.println("Use Watchlist to view it!"); + } } From bece3c1c0e553317e4fa0715467f3a782b274f1c Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 9 Oct 2023 17:05:31 +0800 Subject: [PATCH 034/518] Add some minor error handling for response from API endpoint --- .../financialplanner/investments/Stock.java | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/main/java/seedu/financialplanner/investments/Stock.java b/src/main/java/seedu/financialplanner/investments/Stock.java index 137c8091b0..ceb0f4234c 100644 --- a/src/main/java/seedu/financialplanner/investments/Stock.java +++ b/src/main/java/seedu/financialplanner/investments/Stock.java @@ -18,13 +18,16 @@ public class Stock { private String market; private String stockName; - public Stock(String symbol, String market) { + public Stock(String symbol, String market) throws FinancialPlannerException { this.symbol = symbol; this.market = market; - this.stockName = getStockName(symbol,market); + this.stockName = getStockNameFromAPI(symbol,market); } - public String getStockName(String symbol, String market) { + public String getStockName() { + return stockName; + } + public String getStockNameFromAPI(String symbol, String market) throws FinancialPlannerException { final String API_ENDPOINT = "https://financialmodelingprep.com/api/v3/search-ticker?query="; final String API_KEY = "rNCNMmSLUR3BAyeKFHwN69QGzE8fmig1"; String requestURI = String.format("%s%s&exchange=%s&apikey=%s", API_ENDPOINT,symbol,market,API_KEY); @@ -39,20 +42,27 @@ public String getStockName(String symbol, String market) { Object obj = new JSONParser().parse(response.body()); JSONArray ja = (JSONArray) obj; - if (ja.size() != 1) { + if (ja.isEmpty()) { throw new FinancialPlannerException("stock not found"); - } else { - JSONObject stock = (JSONObject) ja.get(0); - return (String) stock.get("name"); } + JSONObject stock = (JSONObject) ja.get(0); + String symbolFound = (String) stock.get("symbol"); + // TODO: Might need to use AMEX when NYSE is used + // TODO: Need to check if it is added already + // TODO: add a cap to adding + // TODO: Separate based on market + // TODO: add other info + // TODO: testing + if (!symbolFound.equals(symbol)) { + throw new FinancialPlannerException("Stock not found"); + } + return (String) stock.get("name"); } catch (IOException e) { throw new RuntimeException(e); } catch (InterruptedException e) { throw new RuntimeException(e); } catch (ParseException e) { throw new RuntimeException(e); - } catch (FinancialPlannerException e) { - throw new RuntimeException(e); } } From 433adcbd1c91a7e38b09aaaf96c4a738235f4d52 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 9 Oct 2023 17:06:03 +0800 Subject: [PATCH 035/518] Add to I/O redirection input and expected output file for test on adding stocks --- text-ui-test/EXPECTED.TXT | 6 ++++++ text-ui-test/input.txt | 2 ++ 2 files changed, 8 insertions(+) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index e9110ab378..e9c713997a 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -13,5 +13,11 @@ balance: 5023.12 Added expense of value: 123.21 to the list. type: books balance: 4899.91 +You have successfully added: +Microsoft Corporation +Use Watchlist to view it! +You have successfully added: +GameStop Corp. +Use Watchlist to view it! Unknown command. Please try again. Exiting Financial Planner. Goodbye. diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index 1274e7d7b0..025ea01d28 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -2,5 +2,7 @@ add income a/5000 t/work r/30 add income a/123.12 t/allowance add expense a/100 t/daily necessities r/30 add expense a/123.21 t/books +addstock m/NASDAQ s/MSFT +addstock m/NYSE s/GME sdf exit \ No newline at end of file From dfffa4ac58a33413fbc45a1fa59b2d4faed0bcac Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 10 Oct 2023 12:00:10 +0800 Subject: [PATCH 036/518] Setup storage Fixes #7 --- .../financialplanner/FinancialPlanner.java | 16 ++++++++++ .../financialplanner/storage/Storage.java | 32 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 src/main/java/seedu/financialplanner/storage/Storage.java diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index 8144645481..1a10a9fa8c 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -2,8 +2,10 @@ import seedu.financialplanner.commands.Command; import seedu.financialplanner.commands.Exit; +import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.storage.Storage; import seedu.financialplanner.utils.Parser; import seedu.financialplanner.utils.Ui; @@ -11,10 +13,14 @@ public class FinancialPlanner { private Ui ui; private WatchList watchList; private FinancialList financialList; + private Storage storage; + public FinancialPlanner() { ui = new Ui(); financialList = new FinancialList(); watchList = new WatchList(); + storage = new Storage(); + storage.load(financialList); } public void run() { @@ -27,9 +33,19 @@ public void run() { command = Parser.parse(input); command.execute(ui, financialList, watchList); } + + save(); ui.exitMessage(); } + public void save() { + try { + storage.save(financialList); + } catch (FinancialPlannerException e) { + ui.showMessage(e.getMessage()); + } + } + public static void main(String[] args) { new FinancialPlanner().run(); } diff --git a/src/main/java/seedu/financialplanner/storage/Storage.java b/src/main/java/seedu/financialplanner/storage/Storage.java new file mode 100644 index 0000000000..32b0b8261d --- /dev/null +++ b/src/main/java/seedu/financialplanner/storage/Storage.java @@ -0,0 +1,32 @@ +package seedu.financialplanner.storage; + +import seedu.financialplanner.exceptions.FinancialPlannerException; +import seedu.financialplanner.list.FinancialList; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.Path; + +public class Storage { + private final Path path = Paths.get("data"); + + public Storage() { + if (!Files.exists(path)) { + try { + System.out.println("Directory doesn't exist. Creating directory..."); + Files.createDirectory(path); + } catch (IOException e) { + System.out.println("Error creating directory: " + e.getMessage()); + } + } + } + + public void load(FinancialList list) { + + } + + public void save(FinancialList list) throws FinancialPlannerException { + SaveData.save(list); + } +} From 8c328c6af2a61181bc07c1bcf8677e49b31630e8 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 10 Oct 2023 12:00:51 +0800 Subject: [PATCH 037/518] Add save functionality for income and expense --- .../seedu/financialplanner/list/Cashflow.java | 4 ++++ .../seedu/financialplanner/list/Expense.java | 5 ++++ .../financialplanner/list/FinancialList.java | 2 +- .../seedu/financialplanner/list/Income.java | 5 ++++ .../financialplanner/storage/SaveData.java | 24 +++++++++++++++++++ 5 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 src/main/java/seedu/financialplanner/storage/SaveData.java diff --git a/src/main/java/seedu/financialplanner/list/Cashflow.java b/src/main/java/seedu/financialplanner/list/Cashflow.java index e63a74d257..67a7ab2a9f 100644 --- a/src/main/java/seedu/financialplanner/list/Cashflow.java +++ b/src/main/java/seedu/financialplanner/list/Cashflow.java @@ -18,4 +18,8 @@ public Cashflow() { this.type = null; this.recur = 0; } + + public String formatString() { + return this.value + " | " + this.type + " | " + this.recur; + } } diff --git a/src/main/java/seedu/financialplanner/list/Expense.java b/src/main/java/seedu/financialplanner/list/Expense.java index 6aae39d6c4..2299bd8105 100644 --- a/src/main/java/seedu/financialplanner/list/Expense.java +++ b/src/main/java/seedu/financialplanner/list/Expense.java @@ -9,4 +9,9 @@ public Expense(double value, String type, int recur) { private void addIncomeValue(double value) { balance -= value; } + + @Override + public String formatString() { + return "E | " + super.formatString(); + } } diff --git a/src/main/java/seedu/financialplanner/list/FinancialList.java b/src/main/java/seedu/financialplanner/list/FinancialList.java index 0b461b1f60..3b80abaf2e 100644 --- a/src/main/java/seedu/financialplanner/list/FinancialList.java +++ b/src/main/java/seedu/financialplanner/list/FinancialList.java @@ -6,7 +6,7 @@ import java.math.RoundingMode; public class FinancialList { - protected ArrayList list = new ArrayList<>(); + public ArrayList list = new ArrayList<>(); private void printAddedCashflow(String line) { DecimalFormat decimalFormat = new DecimalFormat("####0.00"); diff --git a/src/main/java/seedu/financialplanner/list/Income.java b/src/main/java/seedu/financialplanner/list/Income.java index 31ddbf8310..8b21dc1efb 100644 --- a/src/main/java/seedu/financialplanner/list/Income.java +++ b/src/main/java/seedu/financialplanner/list/Income.java @@ -9,4 +9,9 @@ public Income(double value, String type, int recur) { private void addIncomeValue(double value) { balance += value; } + + @Override + public String formatString() { + return "I | " + super.formatString(); + } } diff --git a/src/main/java/seedu/financialplanner/storage/SaveData.java b/src/main/java/seedu/financialplanner/storage/SaveData.java new file mode 100644 index 0000000000..4c81779cab --- /dev/null +++ b/src/main/java/seedu/financialplanner/storage/SaveData.java @@ -0,0 +1,24 @@ +package seedu.financialplanner.storage; + +import seedu.financialplanner.exceptions.FinancialPlannerException; +import seedu.financialplanner.list.Cashflow; +import seedu.financialplanner.list.FinancialList; + +import java.io.FileWriter; +import java.io.IOException; + +public abstract class SaveData { + private static final String FILE_PATH = "data/data.txt"; + + public static void save(FinancialList financialList) throws FinancialPlannerException { + try { + FileWriter fw = new FileWriter(FILE_PATH); + for (Cashflow entry : financialList.list) { + fw.write(entry.formatString() + "\n"); + } + fw.close(); + } catch (IOException e) { + throw new FinancialPlannerException("Error saving file."); + } + } +} From 75847cd1846bd27dab82dbc0dab5da96cf596d33 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 10 Oct 2023 13:49:04 +0800 Subject: [PATCH 038/518] Add load functionality and edit EXPECTED.TXT Fixes #38 --- .../financialplanner/FinancialPlanner.java | 8 ++- .../financialplanner/list/FinancialList.java | 4 ++ .../financialplanner/storage/LoadData.java | 58 +++++++++++++++++++ .../financialplanner/storage/Storage.java | 4 +- text-ui-test/EXPECTED.TXT | 2 + 5 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 src/main/java/seedu/financialplanner/storage/LoadData.java diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index 1a10a9fa8c..4f4b597fbf 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -15,7 +15,7 @@ public class FinancialPlanner { private FinancialList financialList; private Storage storage; - public FinancialPlanner() { + public FinancialPlanner() throws FinancialPlannerException { ui = new Ui(); financialList = new FinancialList(); watchList = new WatchList(); @@ -47,6 +47,10 @@ public void save() { } public static void main(String[] args) { - new FinancialPlanner().run(); + try { + new FinancialPlanner().run(); + } catch (FinancialPlannerException e) { + System.out.println(e.getMessage()); + } } } diff --git a/src/main/java/seedu/financialplanner/list/FinancialList.java b/src/main/java/seedu/financialplanner/list/FinancialList.java index 3b80abaf2e..70710489d2 100644 --- a/src/main/java/seedu/financialplanner/list/FinancialList.java +++ b/src/main/java/seedu/financialplanner/list/FinancialList.java @@ -45,4 +45,8 @@ public void addExpense(double value, String type, int recur) { list.add(toAdd); printAddedCashflow("expense"); } + + public void load(Cashflow entry) { + list.add(entry); + } } diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java new file mode 100644 index 0000000000..0a098a4faf --- /dev/null +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -0,0 +1,58 @@ +package seedu.financialplanner.storage; + +import seedu.financialplanner.exceptions.FinancialPlannerException; +import seedu.financialplanner.list.Cashflow; +import seedu.financialplanner.list.Expense; +import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.list.Income; + +import java.io.FileReader; +import java.io.IOException; +import java.util.Scanner; + +public abstract class LoadData { + private static final String FILE_PATH = "data/data.txt"; + + public static void load(FinancialList financialList) throws FinancialPlannerException { + try { + Scanner inputFile = new Scanner(new FileReader(FILE_PATH)); + String line; + System.out.println("Loading existing file..."); + + while(inputFile.hasNext()) { + line = inputFile.nextLine(); + final Cashflow entry = getEntry(line); + + financialList.load(entry); + } + inputFile.close(); + } catch (IOException e) { + System.out.println("File not found. Creating new file..."); + } + } + + private static Cashflow getEntry(String line) throws FinancialPlannerException { + String[] split = line.split("\\|"); + String type = split[0].trim(); + double value; + int recur; + Cashflow entry; + + switch (type) { + case "I": + value = Double.parseDouble(split[1].trim()); + recur = Integer.parseInt(split[3].trim()); + entry = new Income(value, split[2].trim(), recur); + break; + case "E": + value = Double.parseDouble(split[1].trim()); + recur = Integer.parseInt(split[3].trim()); + entry = new Expense(value, split[2].trim(), recur); + break; + default: + throw new FinancialPlannerException("Error loading file"); + } + + return entry; + } +} diff --git a/src/main/java/seedu/financialplanner/storage/Storage.java b/src/main/java/seedu/financialplanner/storage/Storage.java index 32b0b8261d..f5f8d20e46 100644 --- a/src/main/java/seedu/financialplanner/storage/Storage.java +++ b/src/main/java/seedu/financialplanner/storage/Storage.java @@ -22,8 +22,8 @@ public Storage() { } } - public void load(FinancialList list) { - + public void load(FinancialList list) throws FinancialPlannerException { + LoadData.load(list); } public void save(FinancialList list) throws FinancialPlannerException { diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index e9110ab378..2a727698ab 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,3 +1,5 @@ +Directory doesn't exist. Creating directory... +File not found. Creating new file... Welcome to your Financial Planner. Type something to get started. Added income of value: 5000.00 to the list. type: work From 95cd96179ef5466fadecdc7027762af2af1e1c43 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 10 Oct 2023 14:41:34 +0800 Subject: [PATCH 039/518] Add error handling for storage Fixes #39 --- .../financialplanner/FinancialPlanner.java | 5 ++-- .../financialplanner/list/FinancialList.java | 6 ++++- .../financialplanner/storage/LoadData.java | 26 ++++++++++++++++--- .../financialplanner/storage/Storage.java | 5 ++-- 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index 4f4b597fbf..fd74c3c47e 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -20,7 +20,7 @@ public FinancialPlanner() throws FinancialPlannerException { financialList = new FinancialList(); watchList = new WatchList(); storage = new Storage(); - storage.load(financialList); + storage.load(financialList, ui); } public void run() { @@ -49,8 +49,7 @@ public void save() { public static void main(String[] args) { try { new FinancialPlanner().run(); - } catch (FinancialPlannerException e) { - System.out.println(e.getMessage()); + } catch (FinancialPlannerException ignored) { } } } diff --git a/src/main/java/seedu/financialplanner/list/FinancialList.java b/src/main/java/seedu/financialplanner/list/FinancialList.java index 70710489d2..243c4cfb91 100644 --- a/src/main/java/seedu/financialplanner/list/FinancialList.java +++ b/src/main/java/seedu/financialplanner/list/FinancialList.java @@ -6,7 +6,11 @@ import java.math.RoundingMode; public class FinancialList { - public ArrayList list = new ArrayList<>(); + public ArrayList list; + + public FinancialList() { + this.list = new ArrayList<>(); + } private void printAddedCashflow(String line) { DecimalFormat decimalFormat = new DecimalFormat("####0.00"); diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 0a098a4faf..650ae43260 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -5,6 +5,7 @@ import seedu.financialplanner.list.Expense; import seedu.financialplanner.list.FinancialList; import seedu.financialplanner.list.Income; +import seedu.financialplanner.utils.Ui; import java.io.FileReader; import java.io.IOException; @@ -13,11 +14,11 @@ public abstract class LoadData { private static final String FILE_PATH = "data/data.txt"; - public static void load(FinancialList financialList) throws FinancialPlannerException { + public static void load(FinancialList financialList, Ui ui) throws FinancialPlannerException { try { Scanner inputFile = new Scanner(new FileReader(FILE_PATH)); String line; - System.out.println("Loading existing file..."); + ui.showMessage("Loading existing file..."); while(inputFile.hasNext()) { line = inputFile.nextLine(); @@ -27,10 +28,29 @@ public static void load(FinancialList financialList) throws FinancialPlannerExce } inputFile.close(); } catch (IOException e) { - System.out.println("File not found. Creating new file..."); + ui.showMessage("File not found. Creating new file..."); + } catch (NumberFormatException | ArrayIndexOutOfBoundsException | FinancialPlannerException e) { + ui.showMessage("File appears to be corrupted. Do you want to create a new file? (Y/N)"); + if (createNewFile(ui)) { + financialList.list.clear(); + } else { + String message = "Please fix the corrupted file, which can be found in data/data.txt."; + ui.showMessage(message); + throw new FinancialPlannerException(message); + } } } + private static boolean createNewFile(Ui ui) { + String line = ui.input(); + while (!line.equalsIgnoreCase("y") && !line.equalsIgnoreCase("n")) { + ui.showMessage("Unknown input. Please enter Y or N only."); + line = ui.input(); + } + + return line.equalsIgnoreCase("y"); + } + private static Cashflow getEntry(String line) throws FinancialPlannerException { String[] split = line.split("\\|"); String type = split[0].trim(); diff --git a/src/main/java/seedu/financialplanner/storage/Storage.java b/src/main/java/seedu/financialplanner/storage/Storage.java index f5f8d20e46..5ccc701b35 100644 --- a/src/main/java/seedu/financialplanner/storage/Storage.java +++ b/src/main/java/seedu/financialplanner/storage/Storage.java @@ -2,6 +2,7 @@ import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.utils.Ui; import java.io.IOException; import java.nio.file.Files; @@ -22,8 +23,8 @@ public Storage() { } } - public void load(FinancialList list) throws FinancialPlannerException { - LoadData.load(list); + public void load(FinancialList list, Ui ui) throws FinancialPlannerException { + LoadData.load(list, ui); } public void save(FinancialList list) throws FinancialPlannerException { From e25b510b6db7b5de800c52341e5835ced25d683f Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 10 Oct 2023 14:41:51 +0800 Subject: [PATCH 040/518] Add /data/ to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 2873e189e1..ebcd74ed30 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ bin/ /text-ui-test/ACTUAL.TXT text-ui-test/EXPECTED-UNIX.TXT +data/ From b8b88c5b065e937a31978ae306c56d41a2b75706 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 10 Oct 2023 14:50:09 +0800 Subject: [PATCH 041/518] Update catch block in main --- src/main/java/seedu/financialplanner/FinancialPlanner.java | 3 ++- src/main/java/seedu/financialplanner/storage/LoadData.java | 5 ++--- src/main/java/seedu/financialplanner/utils/Ui.java | 4 ++++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index fd74c3c47e..f524494a77 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -49,7 +49,8 @@ public void save() { public static void main(String[] args) { try { new FinancialPlanner().run(); - } catch (FinancialPlannerException ignored) { + } catch (FinancialPlannerException e) { + Ui.printCorruptedFileError(e.getMessage()); } } } diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 650ae43260..b6c4c6c1b8 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -34,9 +34,8 @@ public static void load(FinancialList financialList, Ui ui) throws FinancialPlan if (createNewFile(ui)) { financialList.list.clear(); } else { - String message = "Please fix the corrupted file, which can be found in data/data.txt."; - ui.showMessage(message); - throw new FinancialPlannerException(message); + throw new FinancialPlannerException("Please fix the corrupted file, " + + "which can be found in data/data.txt."); } } } diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 0bcd6fd67e..e635988fbe 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -41,4 +41,8 @@ public void printStockInfo(JSONObject stock) { String name = StringUtils.rightPad((String) stock.get("name"), 10); System.out.println(symbol + price + name); } + + public static void printCorruptedFileError(String message) { + System.out.println(message); + } } From 0eca8f566599608a2dd256f9aef4a8147595722f Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 10 Oct 2023 14:58:54 +0800 Subject: [PATCH 042/518] Add in 'run' method --- .../java/seedu/financialplanner/FinancialPlanner.java | 8 ++++++-- .../java/seedu/financialplanner/commands/Command.java | 3 ++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index f524494a77..372d99be4f 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -30,8 +30,12 @@ public void run() { while (!(command instanceof Exit)) { input = ui.input(); - command = Parser.parse(input); - command.execute(ui, financialList, watchList); + try { + command = Parser.parse(input); + command.execute(ui, financialList, watchList); + } catch (FinancialPlannerException e) { + ui.showMessage(e.getMessage()); + } } save(); diff --git a/src/main/java/seedu/financialplanner/commands/Command.java b/src/main/java/seedu/financialplanner/commands/Command.java index c3885fa4a6..cfa92f08d7 100644 --- a/src/main/java/seedu/financialplanner/commands/Command.java +++ b/src/main/java/seedu/financialplanner/commands/Command.java @@ -1,10 +1,11 @@ package seedu.financialplanner.commands; +import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.utils.Ui; import seedu.financialplanner.list.FinancialList; public class Command { - public void execute(Ui ui, FinancialList financialList, WatchList watchList) { + public void execute(Ui ui, FinancialList financialList, WatchList watchList) throws FinancialPlannerException { } } From bef5bea11ba3f9ee327b12830092670706eb6c8c Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Thu, 12 Oct 2023 13:39:13 +0800 Subject: [PATCH 043/518] Add testcases for addstock and fetchFMPStockPrices --- .../investments/WatchListTest.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/test/java/seedu/financialplanner/investments/WatchListTest.java diff --git a/src/test/java/seedu/financialplanner/investments/WatchListTest.java b/src/test/java/seedu/financialplanner/investments/WatchListTest.java new file mode 100644 index 0000000000..afbab4ed37 --- /dev/null +++ b/src/test/java/seedu/financialplanner/investments/WatchListTest.java @@ -0,0 +1,31 @@ +package seedu.financialplanner.investments; + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.junit.jupiter.api.Test; +import seedu.financialplanner.exceptions.FinancialPlannerException; + +import static org.junit.jupiter.api.Assertions.*; + +class WatchListTest { + + @Test + void fetchFMPStockPrices() { + WatchList wl = new WatchList(); + JSONArray obj = wl.fetchFMPStockPrices(); + JSONObject apple = (JSONObject) obj.get(0); + assertNotNull(apple.get("price")); + JSONObject meta = (JSONObject) obj.get(1); + assertNotNull(meta.get("price")); + JSONObject google = (JSONObject) obj.get(2); + assertNotNull(google.get("price")); + } + + @Test + void addStock() throws Exception { + WatchList wl = new WatchList(); + String market = "NYSE"; + String stockCode = "GME"; + assertEquals("GameStop Corp.", wl.addStock(market, stockCode)); + } +} \ No newline at end of file From 92df6fe7a3c18bfd7283694eafeee6fb0e82f070 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Thu, 12 Oct 2023 13:43:22 +0800 Subject: [PATCH 044/518] Fix Code styles --- .../seedu/financialplanner/investments/WatchListTest.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/test/java/seedu/financialplanner/investments/WatchListTest.java b/src/test/java/seedu/financialplanner/investments/WatchListTest.java index afbab4ed37..11c5ac3d2c 100644 --- a/src/test/java/seedu/financialplanner/investments/WatchListTest.java +++ b/src/test/java/seedu/financialplanner/investments/WatchListTest.java @@ -3,9 +3,8 @@ import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.junit.jupiter.api.Test; -import seedu.financialplanner.exceptions.FinancialPlannerException; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertNotNull; class WatchListTest { @@ -28,4 +27,4 @@ void addStock() throws Exception { String stockCode = "GME"; assertEquals("GameStop Corp.", wl.addStock(market, stockCode)); } -} \ No newline at end of file +} From 1afcc973197329792f60e23295c485d963590453 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Thu, 12 Oct 2023 13:46:48 +0800 Subject: [PATCH 045/518] Fix imports --- .../java/seedu/financialplanner/investments/WatchListTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/java/seedu/financialplanner/investments/WatchListTest.java b/src/test/java/seedu/financialplanner/investments/WatchListTest.java index 11c5ac3d2c..e36b4f643e 100644 --- a/src/test/java/seedu/financialplanner/investments/WatchListTest.java +++ b/src/test/java/seedu/financialplanner/investments/WatchListTest.java @@ -5,6 +5,7 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertEquals; class WatchListTest { From 22508414ff64c714b8c24237a8ab30432ade3775 Mon Sep 17 00:00:00 2001 From: hshiah Date: Thu, 12 Oct 2023 14:30:25 +0800 Subject: [PATCH 046/518] implement function find --- .../seedu/financialplanner/commands/Find.java | 48 +++++++++++++++++++ .../investments/WatchList.java | 8 ++++ .../financialplanner/list/FinancialList.java | 6 +++ .../seedu/financialplanner/utils/Parser.java | 4 ++ 4 files changed, 66 insertions(+) create mode 100644 src/main/java/seedu/financialplanner/commands/Find.java diff --git a/src/main/java/seedu/financialplanner/commands/Find.java b/src/main/java/seedu/financialplanner/commands/Find.java new file mode 100644 index 0000000000..32ee443c87 --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/Find.java @@ -0,0 +1,48 @@ +package seedu.financialplanner.commands; + +import seedu.financialplanner.investments.WatchList; +import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.utils.Ui; + +import java.util.ArrayList; + +public class Find extends Command{ + private final String description; + + public Find(String description) { + this.description = description; + } + + @Override + public void execute(Ui ui, FinancialList financialList, WatchList watchList) { + ArrayList foundedFinancialList = new ArrayList<>(); + ArrayList foundedWatchList = new ArrayList<>(); + for(int i = 0; i < financialList.size(); i++) { + if(financialList.get(i).formatString().contains(description)) { + foundedFinancialList.add(financialList.get(i).formatString()); + } + } + if(!foundedFinancialList.isEmpty()){ + ui.showMessage("Here are the matching financial records in your financial list:"); + }else{ + ui.showMessage("There is no matching financial record in your financial list."); + } + for(String foundedFinancialRecord : foundedFinancialList) { + ui.showMessage(foundedFinancialRecord); + } + + for(int i = 0; i < watchList.size(); i++) { + if(watchList.get(i).toString().contains(description)) { + foundedWatchList.add(watchList.get(i).toString()); + } + } + if(!foundedWatchList.isEmpty()) { + ui.showMessage("Here are the matching stock records in your stock list:"); + }else{ + ui.showMessage("There is no matching stock record in your stock list."); + } + for(String foundedStockRecord : foundedWatchList) { + ui.showMessage(foundedStockRecord); + } + } +} diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index 9726c0c64f..7717c1f2db 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -65,4 +65,12 @@ public String addStock(String market, String stockCode) throws FinancialPlannerE stocks.add(newStock); return newStock.getStockName(); } + + public int size(){ + return stocks.size(); + } + + public Stock get(int index){ + return stocks.get(index); + } } diff --git a/src/main/java/seedu/financialplanner/list/FinancialList.java b/src/main/java/seedu/financialplanner/list/FinancialList.java index 243c4cfb91..060e715d97 100644 --- a/src/main/java/seedu/financialplanner/list/FinancialList.java +++ b/src/main/java/seedu/financialplanner/list/FinancialList.java @@ -53,4 +53,10 @@ public void addExpense(double value, String type, int recur) { public void load(Cashflow entry) { list.add(entry); } + public Cashflow get(int index) { + return list.get(index); + } + public int size() { + return list.size(); + } } diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index e1a1ea1070..c2b8b2d911 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -7,6 +7,7 @@ import seedu.financialplanner.commands.WatchListCommand; import seedu.financialplanner.commands.Invalid; import seedu.financialplanner.commands.AddStockCommand; +import seedu.financialplanner.commands.Find; public class Parser { private static final String EXIT_COMMAND = "exit"; @@ -16,6 +17,7 @@ public class Parser { private static final String ADD_ENTRY_COMMAND = "add"; private static final String ADD_STOCK_COMMAND = "addstock"; + private static final String FIND_COMMAND = "find"; public static Command parse(String input) { String[] split = input.split(" ", 2); @@ -31,6 +33,8 @@ public static Command parse(String input) { return new Entry(restOfInput); case ADD_STOCK_COMMAND: return parseAddStock(restOfInput); + case FIND_COMMAND: + return new Find(restOfInput); default: return new Invalid(); } From 3501ede398172c065fabdf26f4e4706df23686c9 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Thu, 12 Oct 2023 23:34:06 +0800 Subject: [PATCH 047/518] Add storage test for loading valid data --- .../financialplanner/FinancialPlanner.java | 5 ++-- .../seedu/financialplanner/list/Cashflow.java | 6 ++++ .../seedu/financialplanner/list/Expense.java | 6 ++++ .../financialplanner/list/FinancialList.java | 11 +++++++ .../seedu/financialplanner/list/Income.java | 6 ++++ .../financialplanner/storage/LoadData.java | 6 ++-- .../financialplanner/storage/SaveData.java | 6 ++-- .../financialplanner/storage/Storage.java | 8 ++--- .../seedu/financialplanner/utils/Parser.java | 3 -- .../financialplanner/storage/StorageTest.java | 29 +++++++++++++++++++ 10 files changed, 69 insertions(+), 17 deletions(-) create mode 100644 src/test/java/seedu/financialplanner/storage/StorageTest.java diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index 372d99be4f..b7e21dbbdd 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -14,13 +14,14 @@ public class FinancialPlanner { private WatchList watchList; private FinancialList financialList; private Storage storage; + private static final String FILE_PATH = "data/data.txt"; public FinancialPlanner() throws FinancialPlannerException { ui = new Ui(); financialList = new FinancialList(); watchList = new WatchList(); storage = new Storage(); - storage.load(financialList, ui); + storage.load(financialList, ui, FILE_PATH); } public void run() { @@ -44,7 +45,7 @@ public void run() { public void save() { try { - storage.save(financialList); + storage.save(financialList, FILE_PATH); } catch (FinancialPlannerException e) { ui.showMessage(e.getMessage()); } diff --git a/src/main/java/seedu/financialplanner/list/Cashflow.java b/src/main/java/seedu/financialplanner/list/Cashflow.java index 67a7ab2a9f..fc4219bd61 100644 --- a/src/main/java/seedu/financialplanner/list/Cashflow.java +++ b/src/main/java/seedu/financialplanner/list/Cashflow.java @@ -22,4 +22,10 @@ public Cashflow() { public String formatString() { return this.value + " | " + this.type + " | " + this.recur; } + + // temp + @Override + public String toString() { + return this.value + " " + this.type + " " + this.recur; + } } diff --git a/src/main/java/seedu/financialplanner/list/Expense.java b/src/main/java/seedu/financialplanner/list/Expense.java index 2299bd8105..61c5e0ef7b 100644 --- a/src/main/java/seedu/financialplanner/list/Expense.java +++ b/src/main/java/seedu/financialplanner/list/Expense.java @@ -14,4 +14,10 @@ private void addIncomeValue(double value) { public String formatString() { return "E | " + super.formatString(); } + + //temp + @Override + public String toString() { + return "Expense: " + super.toString(); + } } diff --git a/src/main/java/seedu/financialplanner/list/FinancialList.java b/src/main/java/seedu/financialplanner/list/FinancialList.java index 060e715d97..d9767cfca7 100644 --- a/src/main/java/seedu/financialplanner/list/FinancialList.java +++ b/src/main/java/seedu/financialplanner/list/FinancialList.java @@ -53,9 +53,20 @@ public void addExpense(double value, String type, int recur) { public void load(Cashflow entry) { list.add(entry); } + + //temp method + public String getList() { + String output = ""; + for (Cashflow entry : list) { + output += entry.toString() + "\n"; + } + return output; + } + public Cashflow get(int index) { return list.get(index); } + public int size() { return list.size(); } diff --git a/src/main/java/seedu/financialplanner/list/Income.java b/src/main/java/seedu/financialplanner/list/Income.java index 8b21dc1efb..775fd84873 100644 --- a/src/main/java/seedu/financialplanner/list/Income.java +++ b/src/main/java/seedu/financialplanner/list/Income.java @@ -14,4 +14,10 @@ private void addIncomeValue(double value) { public String formatString() { return "I | " + super.formatString(); } + + //temp + @Override + public String toString() { + return "Income: " + super.toString(); + } } diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index b6c4c6c1b8..26449059f2 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -12,11 +12,9 @@ import java.util.Scanner; public abstract class LoadData { - private static final String FILE_PATH = "data/data.txt"; - - public static void load(FinancialList financialList, Ui ui) throws FinancialPlannerException { + public static void load(FinancialList financialList, Ui ui, String filePath) throws FinancialPlannerException { try { - Scanner inputFile = new Scanner(new FileReader(FILE_PATH)); + Scanner inputFile = new Scanner(new FileReader(filePath)); String line; ui.showMessage("Loading existing file..."); diff --git a/src/main/java/seedu/financialplanner/storage/SaveData.java b/src/main/java/seedu/financialplanner/storage/SaveData.java index 4c81779cab..d36380c0d6 100644 --- a/src/main/java/seedu/financialplanner/storage/SaveData.java +++ b/src/main/java/seedu/financialplanner/storage/SaveData.java @@ -8,11 +8,9 @@ import java.io.IOException; public abstract class SaveData { - private static final String FILE_PATH = "data/data.txt"; - - public static void save(FinancialList financialList) throws FinancialPlannerException { + public static void save(FinancialList financialList, String filePath) throws FinancialPlannerException { try { - FileWriter fw = new FileWriter(FILE_PATH); + FileWriter fw = new FileWriter(filePath); for (Cashflow entry : financialList.list) { fw.write(entry.formatString() + "\n"); } diff --git a/src/main/java/seedu/financialplanner/storage/Storage.java b/src/main/java/seedu/financialplanner/storage/Storage.java index 5ccc701b35..d8eb733b67 100644 --- a/src/main/java/seedu/financialplanner/storage/Storage.java +++ b/src/main/java/seedu/financialplanner/storage/Storage.java @@ -23,11 +23,11 @@ public Storage() { } } - public void load(FinancialList list, Ui ui) throws FinancialPlannerException { - LoadData.load(list, ui); + public void load(FinancialList list, Ui ui, String filePath) throws FinancialPlannerException { + LoadData.load(list, ui, filePath); } - public void save(FinancialList list) throws FinancialPlannerException { - SaveData.save(list); + public void save(FinancialList list, String filePath) throws FinancialPlannerException { + SaveData.save(list, filePath); } } diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index c2b8b2d911..5a1d86fa1a 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -11,11 +11,8 @@ public class Parser { private static final String EXIT_COMMAND = "exit"; - private static final String WATCHLIST_COMMAND = "watchlist"; - private static final String ADD_ENTRY_COMMAND = "add"; - private static final String ADD_STOCK_COMMAND = "addstock"; private static final String FIND_COMMAND = "find"; diff --git a/src/test/java/seedu/financialplanner/storage/StorageTest.java b/src/test/java/seedu/financialplanner/storage/StorageTest.java new file mode 100644 index 0000000000..61ed332d88 --- /dev/null +++ b/src/test/java/seedu/financialplanner/storage/StorageTest.java @@ -0,0 +1,29 @@ +package seedu.financialplanner.storage; + +import org.junit.jupiter.api.Test; +import seedu.financialplanner.exceptions.FinancialPlannerException; +import seedu.financialplanner.list.Expense; +import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.list.Income; +import seedu.financialplanner.utils.Ui; + + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class StorageTest { + @Test + void loadValidData() throws FinancialPlannerException { + Storage storage = new Storage(); + FinancialList test = new FinancialList(); + storage.load(test, new Ui(), "src/test/data/ValidData.txt"); + FinancialList expected = getTestData(); + assertEquals(expected.getList(), test.getList()); + } + + private FinancialList getTestData() { + FinancialList list = new FinancialList(); + list.load(new Income(123.12, "allowance", 0)); + list.load(new Expense(100, "daily necessities", 30)); + return list; + } +} From 62d46f719a6d2b1a8b804ac1a54b3ef6cc03b943 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Thu, 12 Oct 2023 23:53:21 +0800 Subject: [PATCH 048/518] Add JUnit tests for addIncome() and addExpense() --- .../financialplanner/list/FinancialList.java | 2 +- .../list/FinancialListTest.java | 56 +++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 src/test/java/seedu/financialplanner/list/FinancialListTest.java diff --git a/src/main/java/seedu/financialplanner/list/FinancialList.java b/src/main/java/seedu/financialplanner/list/FinancialList.java index 243c4cfb91..a77b03cd01 100644 --- a/src/main/java/seedu/financialplanner/list/FinancialList.java +++ b/src/main/java/seedu/financialplanner/list/FinancialList.java @@ -27,7 +27,7 @@ private void printAddedCashflow(String line) { //@author mhadidg-reused //Reused from https://stackoverflow.com/questions/2808535/round-a-double-to-2-decimal-places - public static double round(double value, int places) { + public double round(double value, int places) { if (places < 0) { throw new IllegalArgumentException(); } diff --git a/src/test/java/seedu/financialplanner/list/FinancialListTest.java b/src/test/java/seedu/financialplanner/list/FinancialListTest.java new file mode 100644 index 0000000000..c559ab255e --- /dev/null +++ b/src/test/java/seedu/financialplanner/list/FinancialListTest.java @@ -0,0 +1,56 @@ +package seedu.financialplanner.list; + +import org.junit.jupiter.api.Test; +import java.text.DecimalFormat; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class FinancialListTest { + FinancialList testList = new FinancialList(); + DecimalFormat decimalFormat = new DecimalFormat("####0.00"); + + @Test + void testAddIncomeAndExpense() { + + testList.addIncome(15, "work", 30); + Cashflow testIncome = testList.list.get(0); + double roundedValue = testList.round(testIncome.value, 2); + double roundedBalance = testList.round(Cashflow.balance, 2); + assertTrue(testIncome instanceof Income); + assertEquals("15.00", decimalFormat.format(roundedValue)); + assertEquals("work", testIncome.type); + assertEquals(30, testIncome.recur); + assertEquals("15.00", decimalFormat.format(roundedBalance)); + + testList.addIncome(15.999, "rate of returns", 0); + testIncome = testList.list.get(1); + roundedValue = testList.round(testIncome.value, 2); + roundedBalance = testList.round(Cashflow.balance, 2); + assertTrue(testIncome instanceof Income); + assertEquals("16.00", decimalFormat.format(roundedValue)); + assertEquals("rate of returns", testIncome.type); + assertEquals(0, testIncome.recur); + assertEquals("31.00", decimalFormat.format(roundedBalance)); + + testList.addExpense(10, "lunch", 0); + Cashflow testExpense = testList.list.get(2); + roundedValue = testList.round(testExpense.value, 2); + roundedBalance = testList.round(Cashflow.balance, 2); + assertTrue(testExpense instanceof Expense); + assertEquals("10.00", decimalFormat.format(roundedValue)); + assertEquals("lunch", testExpense.type); + assertEquals(0, testExpense.recur); + assertEquals("21.00", decimalFormat.format(roundedBalance)); + + testList.addExpense(19.999, "Apple Music", 30); + testExpense = testList.list.get(3); + roundedValue = testList.round(testExpense.value, 2); + roundedBalance = testList.round(Cashflow.balance, 2); + assertTrue(testExpense instanceof Expense); + assertEquals("20.00", decimalFormat.format(roundedValue)); + assertEquals("Apple Music", testExpense.type); + assertEquals(30, testExpense.recur); + assertEquals("1.00", decimalFormat.format(roundedBalance)); + } +} From c9fa29cd6aa140362bfaacdf93ae5c98b7ddf5b0 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Fri, 13 Oct 2023 00:33:12 +0800 Subject: [PATCH 049/518] Add JUnit test for execute() in Entry --- .../financialplanner/commands/Entry.java | 12 ++++---- .../financialplanner/commands/EntryTest.java | 29 +++++++++++++++++++ 2 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 src/test/java/seedu/financialplanner/commands/EntryTest.java diff --git a/src/main/java/seedu/financialplanner/commands/Entry.java b/src/main/java/seedu/financialplanner/commands/Entry.java index cecf104bd4..8d6feee45e 100644 --- a/src/main/java/seedu/financialplanner/commands/Entry.java +++ b/src/main/java/seedu/financialplanner/commands/Entry.java @@ -8,6 +8,9 @@ public class Entry extends Command{ private static final String INCOME = "income"; private static final String EXPENSE = "expense"; protected String input; + protected double value; + protected String type; + protected int recur; public Entry(String input) { this.input = input; @@ -27,16 +30,15 @@ public void execute(Ui ui, FinancialList list, WatchList watchList) { String[] split = input.split(" ", 2); String entryType = split[0]; String parameters = split[1]; - int recur = determineRecur(parameters); + this.recur = determineRecur(parameters); int indexOfAmount = parameters.indexOf("a/"); int indexOfType = parameters.indexOf("t/"); - double value = Double.parseDouble(parameters.substring(indexOfAmount + 2, indexOfType).trim()); - String type; + this.value = Double.parseDouble(parameters.substring(indexOfAmount + 2, indexOfType).trim()); if (recur == 0) { - type = parameters.substring(indexOfType + 2).trim(); + this.type = parameters.substring(indexOfType + 2).trim(); } else { int indexOfRecur = parameters.indexOf("r/"); - type = parameters.substring(indexOfType + 2, indexOfRecur).trim(); + this.type = parameters.substring(indexOfType + 2, indexOfRecur).trim(); } switch (entryType) { diff --git a/src/test/java/seedu/financialplanner/commands/EntryTest.java b/src/test/java/seedu/financialplanner/commands/EntryTest.java new file mode 100644 index 0000000000..0fe063613e --- /dev/null +++ b/src/test/java/seedu/financialplanner/commands/EntryTest.java @@ -0,0 +1,29 @@ +package seedu.financialplanner.commands; + +import org.junit.jupiter.api.Test; +import seedu.financialplanner.investments.WatchList; +import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.utils.Ui; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class EntryTest { + Ui ui = new Ui(); + FinancialList financialList = new FinancialList(); + WatchList watchList = new WatchList(); + + @Test + void testExecute() { + Entry testEntry = new Entry("income a/300 t/work r/30"); + testEntry.execute(ui, financialList, watchList); + assertEquals(300, testEntry.value); + assertEquals("work", testEntry.type); + assertEquals(30, testEntry.recur); + + testEntry = new Entry("expense a/15 t/double mcspicy"); + testEntry.execute(ui, financialList, watchList); + assertEquals(15, testEntry.value); + assertEquals("double mcspicy", testEntry.type); + assertEquals(0, testEntry.recur); + } +} From a61e59da1fb118eb86fdedbbafcb124bfef873a5 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Fri, 13 Oct 2023 11:49:53 +0800 Subject: [PATCH 050/518] Add storage test for: - load invalid data - save valid data - save non-existent file Fixes #46 --- .../seedu/financialplanner/list/Cashflow.java | 6 --- .../seedu/financialplanner/list/Expense.java | 6 --- .../financialplanner/list/FinancialList.java | 2 +- .../seedu/financialplanner/list/Income.java | 6 --- .../financialplanner/storage/StorageTest.java | 38 ++++++++++++++++++- 5 files changed, 38 insertions(+), 20 deletions(-) diff --git a/src/main/java/seedu/financialplanner/list/Cashflow.java b/src/main/java/seedu/financialplanner/list/Cashflow.java index fc4219bd61..67a7ab2a9f 100644 --- a/src/main/java/seedu/financialplanner/list/Cashflow.java +++ b/src/main/java/seedu/financialplanner/list/Cashflow.java @@ -22,10 +22,4 @@ public Cashflow() { public String formatString() { return this.value + " | " + this.type + " | " + this.recur; } - - // temp - @Override - public String toString() { - return this.value + " " + this.type + " " + this.recur; - } } diff --git a/src/main/java/seedu/financialplanner/list/Expense.java b/src/main/java/seedu/financialplanner/list/Expense.java index 61c5e0ef7b..2299bd8105 100644 --- a/src/main/java/seedu/financialplanner/list/Expense.java +++ b/src/main/java/seedu/financialplanner/list/Expense.java @@ -14,10 +14,4 @@ private void addIncomeValue(double value) { public String formatString() { return "E | " + super.formatString(); } - - //temp - @Override - public String toString() { - return "Expense: " + super.toString(); - } } diff --git a/src/main/java/seedu/financialplanner/list/FinancialList.java b/src/main/java/seedu/financialplanner/list/FinancialList.java index d9767cfca7..d20b120a6e 100644 --- a/src/main/java/seedu/financialplanner/list/FinancialList.java +++ b/src/main/java/seedu/financialplanner/list/FinancialList.java @@ -58,7 +58,7 @@ public void load(Cashflow entry) { public String getList() { String output = ""; for (Cashflow entry : list) { - output += entry.toString() + "\n"; + output += entry.formatString() + "\n"; } return output; } diff --git a/src/main/java/seedu/financialplanner/list/Income.java b/src/main/java/seedu/financialplanner/list/Income.java index 775fd84873..8b21dc1efb 100644 --- a/src/main/java/seedu/financialplanner/list/Income.java +++ b/src/main/java/seedu/financialplanner/list/Income.java @@ -14,10 +14,4 @@ private void addIncomeValue(double value) { public String formatString() { return "I | " + super.formatString(); } - - //temp - @Override - public String toString() { - return "Income: " + super.toString(); - } } diff --git a/src/test/java/seedu/financialplanner/storage/StorageTest.java b/src/test/java/seedu/financialplanner/storage/StorageTest.java index 61ed332d88..c8e13d5dbf 100644 --- a/src/test/java/seedu/financialplanner/storage/StorageTest.java +++ b/src/test/java/seedu/financialplanner/storage/StorageTest.java @@ -1,6 +1,7 @@ package seedu.financialplanner.storage; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.list.Expense; import seedu.financialplanner.list.FinancialList; @@ -8,11 +9,20 @@ import seedu.financialplanner.utils.Ui; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; public class StorageTest { + @TempDir + public static Path testFolder; + @Test - void loadValidData() throws FinancialPlannerException { + public void loadValidData() throws FinancialPlannerException { Storage storage = new Storage(); FinancialList test = new FinancialList(); storage.load(test, new Ui(), "src/test/data/ValidData.txt"); @@ -20,6 +30,32 @@ void loadValidData() throws FinancialPlannerException { assertEquals(expected.getList(), test.getList()); } + @Test + public void loadInvalidData_UserInputNo() { + Storage storage = new Storage(); + FinancialList test = new FinancialList(); + ByteArrayInputStream in = new ByteArrayInputStream("n".getBytes()); + System.setIn(in); + assertThrows(FinancialPlannerException.class, + () -> storage.load(test, new Ui(), "src/test/data/InvalidData.txt")); + } + + @Test + public void saveValidData() throws FinancialPlannerException, IOException { + FinancialList expected = getTestData(); + Storage storage = new Storage(); + storage.save(expected, String.valueOf(testFolder.resolve("temp.txt"))); + assertEquals(Files.readAllLines(Path.of("src/test/data/ValidData.txt")), + Files.readAllLines(testFolder.resolve("temp.txt"))); + } + + @Test + public void saveNonExistentFile() { + FinancialList expected = getTestData(); + Storage storage = new Storage(); + assertThrows(FinancialPlannerException.class, () -> storage.save(expected, "")); + } + private FinancialList getTestData() { FinancialList list = new FinancialList(); list.load(new Income(123.12, "allowance", 0)); From d048f440dbb5e3fe9617dda4c50edab3904307c3 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Fri, 13 Oct 2023 11:55:54 +0800 Subject: [PATCH 051/518] Follow coding standards --- src/main/java/seedu/financialplanner/FinancialPlanner.java | 2 +- src/test/java/seedu/financialplanner/storage/StorageTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index b7e21dbbdd..c77c4b2791 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -10,11 +10,11 @@ import seedu.financialplanner.utils.Ui; public class FinancialPlanner { + private static final String FILE_PATH = "data/data.txt"; private Ui ui; private WatchList watchList; private FinancialList financialList; private Storage storage; - private static final String FILE_PATH = "data/data.txt"; public FinancialPlanner() throws FinancialPlannerException { ui = new Ui(); diff --git a/src/test/java/seedu/financialplanner/storage/StorageTest.java b/src/test/java/seedu/financialplanner/storage/StorageTest.java index c8e13d5dbf..6848429d9a 100644 --- a/src/test/java/seedu/financialplanner/storage/StorageTest.java +++ b/src/test/java/seedu/financialplanner/storage/StorageTest.java @@ -31,7 +31,7 @@ public void loadValidData() throws FinancialPlannerException { } @Test - public void loadInvalidData_UserInputNo() { + public void loadInvalidData_userInputNo() { Storage storage = new Storage(); FinancialList test = new FinancialList(); ByteArrayInputStream in = new ByteArrayInputStream("n".getBytes()); From 6bdf7e453019f8b40fb962822b1db0652308ce57 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Fri, 13 Oct 2023 12:02:09 +0800 Subject: [PATCH 052/518] Rename data to testData folder --- .../java/seedu/financialplanner/storage/StorageTest.java | 6 +++--- src/test/testData/InvalidData.txt | 1 + src/test/testData/ValidData.txt | 2 ++ 3 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 src/test/testData/InvalidData.txt create mode 100644 src/test/testData/ValidData.txt diff --git a/src/test/java/seedu/financialplanner/storage/StorageTest.java b/src/test/java/seedu/financialplanner/storage/StorageTest.java index 6848429d9a..d4a7e601da 100644 --- a/src/test/java/seedu/financialplanner/storage/StorageTest.java +++ b/src/test/java/seedu/financialplanner/storage/StorageTest.java @@ -25,7 +25,7 @@ public class StorageTest { public void loadValidData() throws FinancialPlannerException { Storage storage = new Storage(); FinancialList test = new FinancialList(); - storage.load(test, new Ui(), "src/test/data/ValidData.txt"); + storage.load(test, new Ui(), "src/test/testData/ValidData.txt"); FinancialList expected = getTestData(); assertEquals(expected.getList(), test.getList()); } @@ -37,7 +37,7 @@ public void loadInvalidData_userInputNo() { ByteArrayInputStream in = new ByteArrayInputStream("n".getBytes()); System.setIn(in); assertThrows(FinancialPlannerException.class, - () -> storage.load(test, new Ui(), "src/test/data/InvalidData.txt")); + () -> storage.load(test, new Ui(), "src/test/testData/InvalidData.txt")); } @Test @@ -45,7 +45,7 @@ public void saveValidData() throws FinancialPlannerException, IOException { FinancialList expected = getTestData(); Storage storage = new Storage(); storage.save(expected, String.valueOf(testFolder.resolve("temp.txt"))); - assertEquals(Files.readAllLines(Path.of("src/test/data/ValidData.txt")), + assertEquals(Files.readAllLines(Path.of("src/test/testData/ValidData.txt")), Files.readAllLines(testFolder.resolve("temp.txt"))); } diff --git a/src/test/testData/InvalidData.txt b/src/test/testData/InvalidData.txt new file mode 100644 index 0000000000..30d74d2584 --- /dev/null +++ b/src/test/testData/InvalidData.txt @@ -0,0 +1 @@ +test \ No newline at end of file diff --git a/src/test/testData/ValidData.txt b/src/test/testData/ValidData.txt new file mode 100644 index 0000000000..948450ef20 --- /dev/null +++ b/src/test/testData/ValidData.txt @@ -0,0 +1,2 @@ +I | 123.12 | allowance | 0 +E | 100.0 | daily necessities | 30 \ No newline at end of file From 1c81748388c8834d4ad2125d39dbb70a8e192d51 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Fri, 13 Oct 2023 12:22:29 +0800 Subject: [PATCH 053/518] Make objects private in test classes --- .../java/seedu/financialplanner/commands/EntryTest.java | 6 +++--- .../java/seedu/financialplanner/list/FinancialListTest.java | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/test/java/seedu/financialplanner/commands/EntryTest.java b/src/test/java/seedu/financialplanner/commands/EntryTest.java index 0fe063613e..057511a501 100644 --- a/src/test/java/seedu/financialplanner/commands/EntryTest.java +++ b/src/test/java/seedu/financialplanner/commands/EntryTest.java @@ -8,9 +8,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals; class EntryTest { - Ui ui = new Ui(); - FinancialList financialList = new FinancialList(); - WatchList watchList = new WatchList(); + private Ui ui = new Ui(); + private FinancialList financialList = new FinancialList(); + private WatchList watchList = new WatchList(); @Test void testExecute() { diff --git a/src/test/java/seedu/financialplanner/list/FinancialListTest.java b/src/test/java/seedu/financialplanner/list/FinancialListTest.java index c559ab255e..f04993c457 100644 --- a/src/test/java/seedu/financialplanner/list/FinancialListTest.java +++ b/src/test/java/seedu/financialplanner/list/FinancialListTest.java @@ -7,8 +7,8 @@ import static org.junit.jupiter.api.Assertions.assertTrue; class FinancialListTest { - FinancialList testList = new FinancialList(); - DecimalFormat decimalFormat = new DecimalFormat("####0.00"); + private FinancialList testList = new FinancialList(); + private DecimalFormat decimalFormat = new DecimalFormat("####0.00"); @Test void testAddIncomeAndExpense() { From 09c4f10ef1b93b7d4006e4e9ee8e7530db81438c Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Fri, 13 Oct 2023 12:34:38 +0800 Subject: [PATCH 054/518] Clears list at the end of method --- src/test/java/seedu/financialplanner/commands/EntryTest.java | 1 + src/test/java/seedu/financialplanner/list/FinancialListTest.java | 1 + 2 files changed, 2 insertions(+) diff --git a/src/test/java/seedu/financialplanner/commands/EntryTest.java b/src/test/java/seedu/financialplanner/commands/EntryTest.java index 057511a501..c7f24245dd 100644 --- a/src/test/java/seedu/financialplanner/commands/EntryTest.java +++ b/src/test/java/seedu/financialplanner/commands/EntryTest.java @@ -25,5 +25,6 @@ void testExecute() { assertEquals(15, testEntry.value); assertEquals("double mcspicy", testEntry.type); assertEquals(0, testEntry.recur); + financialList.list.clear(); } } diff --git a/src/test/java/seedu/financialplanner/list/FinancialListTest.java b/src/test/java/seedu/financialplanner/list/FinancialListTest.java index f04993c457..d8290f1be4 100644 --- a/src/test/java/seedu/financialplanner/list/FinancialListTest.java +++ b/src/test/java/seedu/financialplanner/list/FinancialListTest.java @@ -52,5 +52,6 @@ void testAddIncomeAndExpense() { assertEquals("Apple Music", testExpense.type); assertEquals(30, testExpense.recur); assertEquals("1.00", decimalFormat.format(roundedBalance)); + testList.list.clear(); } } From b6f7a7cbb9a8fd3b9830aa4aebd3d360bbf5f6d3 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Fri, 13 Oct 2023 12:42:03 +0800 Subject: [PATCH 055/518] Undo clearing of list and set cashflow balance to 0 in testAddIncomeAndExpense --- src/test/java/seedu/financialplanner/commands/EntryTest.java | 2 +- .../java/seedu/financialplanner/list/FinancialListTest.java | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/test/java/seedu/financialplanner/commands/EntryTest.java b/src/test/java/seedu/financialplanner/commands/EntryTest.java index c7f24245dd..00a6fbc7a1 100644 --- a/src/test/java/seedu/financialplanner/commands/EntryTest.java +++ b/src/test/java/seedu/financialplanner/commands/EntryTest.java @@ -2,6 +2,7 @@ import org.junit.jupiter.api.Test; import seedu.financialplanner.investments.WatchList; +import seedu.financialplanner.list.Cashflow; import seedu.financialplanner.list.FinancialList; import seedu.financialplanner.utils.Ui; @@ -25,6 +26,5 @@ void testExecute() { assertEquals(15, testEntry.value); assertEquals("double mcspicy", testEntry.type); assertEquals(0, testEntry.recur); - financialList.list.clear(); } } diff --git a/src/test/java/seedu/financialplanner/list/FinancialListTest.java b/src/test/java/seedu/financialplanner/list/FinancialListTest.java index d8290f1be4..47bd69ec95 100644 --- a/src/test/java/seedu/financialplanner/list/FinancialListTest.java +++ b/src/test/java/seedu/financialplanner/list/FinancialListTest.java @@ -12,7 +12,7 @@ class FinancialListTest { @Test void testAddIncomeAndExpense() { - + Cashflow.balance = 0; testList.addIncome(15, "work", 30); Cashflow testIncome = testList.list.get(0); double roundedValue = testList.round(testIncome.value, 2); @@ -52,6 +52,5 @@ void testAddIncomeAndExpense() { assertEquals("Apple Music", testExpense.type); assertEquals(30, testExpense.recur); assertEquals("1.00", decimalFormat.format(roundedBalance)); - testList.list.clear(); } } From 1437d9a753198822b0f8c0881ee6858194829c66 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Fri, 13 Oct 2023 12:43:36 +0800 Subject: [PATCH 056/518] Remove unused imports --- src/test/java/seedu/financialplanner/commands/EntryTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/seedu/financialplanner/commands/EntryTest.java b/src/test/java/seedu/financialplanner/commands/EntryTest.java index 00a6fbc7a1..057511a501 100644 --- a/src/test/java/seedu/financialplanner/commands/EntryTest.java +++ b/src/test/java/seedu/financialplanner/commands/EntryTest.java @@ -2,7 +2,6 @@ import org.junit.jupiter.api.Test; import seedu.financialplanner.investments.WatchList; -import seedu.financialplanner.list.Cashflow; import seedu.financialplanner.list.FinancialList; import seedu.financialplanner.utils.Ui; From 7828ae3395aae5d90d22f6743b43b03445b289a9 Mon Sep 17 00:00:00 2001 From: YFshadaow Date: Fri, 13 Oct 2023 12:48:57 +0800 Subject: [PATCH 057/518] Refactor code: Use singleton instead --- .../financialplanner/FinancialPlanner.java | 36 +++++++++---------- .../investments/WatchList.java | 12 +++---- .../financialplanner/list/FinancialList.java | 11 +++--- .../financialplanner/storage/Storage.java | 5 +-- .../java/seedu/financialplanner/utils/Ui.java | 14 ++++---- .../financialplanner/commands/EntryTest.java | 6 ++-- .../investments/WatchListTest.java | 4 +-- .../list/FinancialListTest.java | 2 +- .../financialplanner/storage/StorageTest.java | 18 +++++----- 9 files changed, 55 insertions(+), 53 deletions(-) diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index c77c4b2791..4123c0eccb 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -10,21 +10,27 @@ import seedu.financialplanner.utils.Ui; public class FinancialPlanner { + private static final String FILE_PATH = "data/data.txt"; - private Ui ui; - private WatchList watchList; - private FinancialList financialList; - private Storage storage; - - public FinancialPlanner() throws FinancialPlannerException { - ui = new Ui(); - financialList = new FinancialList(); - watchList = new WatchList(); - storage = new Storage(); - storage.load(financialList, ui, FILE_PATH); + private final Storage storage = Storage.INSTANCE; + private final Ui ui = Ui.INSTANCE; + private final WatchList watchList = WatchList.INSTANCE; + private final FinancialList financialList = FinancialList.INSTANCE; + + private FinancialPlanner() { + } + + public static void main(String[] args) { + new FinancialPlanner().run(); } public void run() { + try { + storage.load(financialList, ui, FILE_PATH); + } catch (FinancialPlannerException e) { + ui.showMessage(e.getMessage()); + } + ui.welcomeMessage(); String input; Command command = null; @@ -50,12 +56,4 @@ public void save() { ui.showMessage(e.getMessage()); } } - - public static void main(String[] args) { - try { - new FinancialPlanner().run(); - } catch (FinancialPlannerException e) { - Ui.printCorruptedFileError(e.getMessage()); - } - } } diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index 7717c1f2db..578fcc6b93 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -14,11 +14,11 @@ import java.util.ArrayList; public class WatchList { - private ArrayList stocks; + public static final WatchList INSTANCE = new WatchList(); + private final ArrayList stocks; private final String API_ENDPOINT = "https://financialmodelingprep.com/api/v3/quote/"; private final String API_KEY = "rNCNMmSLUR3BAyeKFHwN69QGzE8fmig1"; - - public WatchList() { + private WatchList() { stocks = new ArrayList<>(); try { Stock apple = new Stock("AAPL", "NASDAQ"); @@ -38,7 +38,7 @@ public JSONArray fetchFMPStockPrices() { for (Stock stock : stocks) { queryStocks.append(stock.toString()); } - String requestURI = String.format("%s%s?apikey=%s", API_ENDPOINT, queryStocks,API_KEY); + String requestURI = String.format("%s%s?apikey=%s", API_ENDPOINT, queryStocks, API_KEY); HttpRequest request = HttpRequest.newBuilder(URI.create(requestURI)) .header("accept", "application/json") .GET() @@ -66,11 +66,11 @@ public String addStock(String market, String stockCode) throws FinancialPlannerE return newStock.getStockName(); } - public int size(){ + public int size() { return stocks.size(); } - public Stock get(int index){ + public Stock get(int index) { return stocks.get(index); } } diff --git a/src/main/java/seedu/financialplanner/list/FinancialList.java b/src/main/java/seedu/financialplanner/list/FinancialList.java index 5d6ac48fb8..3d5558e1be 100644 --- a/src/main/java/seedu/financialplanner/list/FinancialList.java +++ b/src/main/java/seedu/financialplanner/list/FinancialList.java @@ -1,15 +1,16 @@ package seedu.financialplanner.list; -import java.text.DecimalFormat; -import java.util.ArrayList; import java.math.BigDecimal; import java.math.RoundingMode; +import java.text.DecimalFormat; +import java.util.ArrayList; public class FinancialList { - public ArrayList list; + public static final FinancialList INSTANCE = new FinancialList(); + + public final ArrayList list = new ArrayList<>(); - public FinancialList() { - this.list = new ArrayList<>(); + private FinancialList() { } private void printAddedCashflow(String line) { diff --git a/src/main/java/seedu/financialplanner/storage/Storage.java b/src/main/java/seedu/financialplanner/storage/Storage.java index d8eb733b67..741e0eb7ed 100644 --- a/src/main/java/seedu/financialplanner/storage/Storage.java +++ b/src/main/java/seedu/financialplanner/storage/Storage.java @@ -6,13 +6,14 @@ import java.io.IOException; import java.nio.file.Files; -import java.nio.file.Paths; import java.nio.file.Path; +import java.nio.file.Paths; public class Storage { + public static final Storage INSTANCE = new Storage(); private final Path path = Paths.get("data"); - public Storage() { + private Storage() { if (!Files.exists(path)) { try { System.out.println("Directory doesn't exist. Creating directory..."); diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 5c9b0b9b41..ace28c998c 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -6,8 +6,14 @@ import java.util.Scanner; public class Ui { - private Scanner in = new Scanner(System.in); - public Ui() { + public static final Ui INSTANCE = new Ui(); + private final Scanner in = new Scanner(System.in); + + private Ui() { + } + + public static void printCorruptedFileError(String message) { + System.out.println(message); } public void showMessage(String message) { @@ -41,10 +47,6 @@ public void printStockInfo(JSONObject stock) { String name = StringUtils.rightPad((String) stock.get("name"), 10); System.out.println(symbol + price + name); } - - public static void printCorruptedFileError(String message) { - System.out.println(message); - } public void printAddStock(String stockName) { System.out.println("You have successfully added:"); diff --git a/src/test/java/seedu/financialplanner/commands/EntryTest.java b/src/test/java/seedu/financialplanner/commands/EntryTest.java index 0fe063613e..dfda98ea5f 100644 --- a/src/test/java/seedu/financialplanner/commands/EntryTest.java +++ b/src/test/java/seedu/financialplanner/commands/EntryTest.java @@ -8,9 +8,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals; class EntryTest { - Ui ui = new Ui(); - FinancialList financialList = new FinancialList(); - WatchList watchList = new WatchList(); + Ui ui = Ui.INSTANCE; + FinancialList financialList = FinancialList.INSTANCE; + WatchList watchList = WatchList.INSTANCE; @Test void testExecute() { diff --git a/src/test/java/seedu/financialplanner/investments/WatchListTest.java b/src/test/java/seedu/financialplanner/investments/WatchListTest.java index e36b4f643e..1086af73e2 100644 --- a/src/test/java/seedu/financialplanner/investments/WatchListTest.java +++ b/src/test/java/seedu/financialplanner/investments/WatchListTest.java @@ -11,7 +11,7 @@ class WatchListTest { @Test void fetchFMPStockPrices() { - WatchList wl = new WatchList(); + WatchList wl = WatchList.INSTANCE; JSONArray obj = wl.fetchFMPStockPrices(); JSONObject apple = (JSONObject) obj.get(0); assertNotNull(apple.get("price")); @@ -23,7 +23,7 @@ void fetchFMPStockPrices() { @Test void addStock() throws Exception { - WatchList wl = new WatchList(); + WatchList wl = WatchList.INSTANCE; String market = "NYSE"; String stockCode = "GME"; assertEquals("GameStop Corp.", wl.addStock(market, stockCode)); diff --git a/src/test/java/seedu/financialplanner/list/FinancialListTest.java b/src/test/java/seedu/financialplanner/list/FinancialListTest.java index c559ab255e..2f0adb0041 100644 --- a/src/test/java/seedu/financialplanner/list/FinancialListTest.java +++ b/src/test/java/seedu/financialplanner/list/FinancialListTest.java @@ -7,7 +7,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; class FinancialListTest { - FinancialList testList = new FinancialList(); + FinancialList testList = FinancialList.INSTANCE; DecimalFormat decimalFormat = new DecimalFormat("####0.00"); @Test diff --git a/src/test/java/seedu/financialplanner/storage/StorageTest.java b/src/test/java/seedu/financialplanner/storage/StorageTest.java index d4a7e601da..342752e726 100644 --- a/src/test/java/seedu/financialplanner/storage/StorageTest.java +++ b/src/test/java/seedu/financialplanner/storage/StorageTest.java @@ -23,27 +23,27 @@ public class StorageTest { @Test public void loadValidData() throws FinancialPlannerException { - Storage storage = new Storage(); - FinancialList test = new FinancialList(); - storage.load(test, new Ui(), "src/test/testData/ValidData.txt"); + Storage storage = Storage.INSTANCE; + FinancialList test = FinancialList.INSTANCE; + storage.load(test, Ui.INSTANCE, "src/test/testData/ValidData.txt"); FinancialList expected = getTestData(); assertEquals(expected.getList(), test.getList()); } @Test public void loadInvalidData_userInputNo() { - Storage storage = new Storage(); - FinancialList test = new FinancialList(); + Storage storage = Storage.INSTANCE; + FinancialList test = FinancialList.INSTANCE; ByteArrayInputStream in = new ByteArrayInputStream("n".getBytes()); System.setIn(in); assertThrows(FinancialPlannerException.class, - () -> storage.load(test, new Ui(), "src/test/testData/InvalidData.txt")); + () -> storage.load(test, Ui.INSTANCE, "src/test/testData/InvalidData.txt")); } @Test public void saveValidData() throws FinancialPlannerException, IOException { FinancialList expected = getTestData(); - Storage storage = new Storage(); + Storage storage = Storage.INSTANCE; storage.save(expected, String.valueOf(testFolder.resolve("temp.txt"))); assertEquals(Files.readAllLines(Path.of("src/test/testData/ValidData.txt")), Files.readAllLines(testFolder.resolve("temp.txt"))); @@ -52,12 +52,12 @@ public void saveValidData() throws FinancialPlannerException, IOException { @Test public void saveNonExistentFile() { FinancialList expected = getTestData(); - Storage storage = new Storage(); + Storage storage = Storage.INSTANCE; assertThrows(FinancialPlannerException.class, () -> storage.save(expected, "")); } private FinancialList getTestData() { - FinancialList list = new FinancialList(); + FinancialList list = FinancialList.INSTANCE; list.load(new Income(123.12, "allowance", 0)); list.load(new Expense(100, "daily necessities", 30)); return list; From 00f4c3f960e81461c36262c92bbd2dfa2a9d8541 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Fri, 13 Oct 2023 15:21:01 +0800 Subject: [PATCH 058/518] Fix bug by changing api endpoint and changing api key --- .../commands/AddStockCommand.java | 6 ++--- .../financialplanner/investments/Stock.java | 22 ++++++++++--------- .../investments/WatchList.java | 12 +++++----- .../seedu/financialplanner/utils/Parser.java | 2 +- .../investments/WatchListTest.java | 2 +- 5 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java index c4f45972f4..94278ba62c 100644 --- a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java @@ -6,11 +6,9 @@ import seedu.financialplanner.utils.Ui; public class AddStockCommand extends Command { - private final String market; private final String stockCode; - public AddStockCommand(String market, String stockCode) { - this.market = market; + public AddStockCommand(String stockCode) { this.stockCode = stockCode; } @@ -18,7 +16,7 @@ public AddStockCommand(String market, String stockCode) { public void execute(Ui ui, FinancialList financialList, WatchList watchList) { String stockName = null; try { - stockName = watchList.addStock(market, stockCode); + stockName = watchList.addStock(stockCode); ui.printAddStock(stockName); } catch (FinancialPlannerException e) { System.out.println(e.getMessage()); diff --git a/src/main/java/seedu/financialplanner/investments/Stock.java b/src/main/java/seedu/financialplanner/investments/Stock.java index ceb0f4234c..3c65f9e61e 100644 --- a/src/main/java/seedu/financialplanner/investments/Stock.java +++ b/src/main/java/seedu/financialplanner/investments/Stock.java @@ -18,19 +18,18 @@ public class Stock { private String market; private String stockName; - public Stock(String symbol, String market) throws FinancialPlannerException { + public Stock(String symbol) throws FinancialPlannerException { this.symbol = symbol; - this.market = market; - this.stockName = getStockNameFromAPI(symbol,market); + this.stockName = getStockNameFromAPI(symbol); } public String getStockName() { return stockName; } - public String getStockNameFromAPI(String symbol, String market) throws FinancialPlannerException { - final String API_ENDPOINT = "https://financialmodelingprep.com/api/v3/search-ticker?query="; - final String API_KEY = "rNCNMmSLUR3BAyeKFHwN69QGzE8fmig1"; - String requestURI = String.format("%s%s&exchange=%s&apikey=%s", API_ENDPOINT,symbol,market,API_KEY); + public String getStockNameFromAPI(String symbol) throws FinancialPlannerException { + final String API_ENDPOINT = "https://www.alphavantage.co/query?function=SYMBOL_SEARCH&keywords="; + final String API_KEY = "LNKL0548PHY2F0QU"; + String requestURI = String.format("%s%s&apikey=%s", API_ENDPOINT,symbol,API_KEY); HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder(URI.create(requestURI)) .header("accept", "application/json") @@ -41,12 +40,13 @@ public String getStockNameFromAPI(String symbol, String market) throws Financial HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); Object obj = new JSONParser().parse(response.body()); - JSONArray ja = (JSONArray) obj; + JSONObject jsonObject = (JSONObject) obj; + JSONArray ja = (JSONArray) jsonObject.get("bestMatches"); if (ja.isEmpty()) { throw new FinancialPlannerException("stock not found"); } JSONObject stock = (JSONObject) ja.get(0); - String symbolFound = (String) stock.get("symbol"); + String symbolFound = (String) stock.get("1. symbol"); // TODO: Might need to use AMEX when NYSE is used // TODO: Need to check if it is added already // TODO: add a cap to adding @@ -56,7 +56,9 @@ public String getStockNameFromAPI(String symbol, String market) throws Financial if (!symbolFound.equals(symbol)) { throw new FinancialPlannerException("Stock not found"); } - return (String) stock.get("name"); + System.out.println(stock.get("2. name")); + market = (String) stock.get("4. region"); + return (String) stock.get("2. name"); } catch (IOException e) { throw new RuntimeException(e); } catch (InterruptedException e) { diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index 578fcc6b93..02396168f8 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -17,15 +17,15 @@ public class WatchList { public static final WatchList INSTANCE = new WatchList(); private final ArrayList stocks; private final String API_ENDPOINT = "https://financialmodelingprep.com/api/v3/quote/"; - private final String API_KEY = "rNCNMmSLUR3BAyeKFHwN69QGzE8fmig1"; + private final String API_KEY = "iFumtYryBCbHpS3sDqLdVKi2SdP63vSV"; private WatchList() { stocks = new ArrayList<>(); try { - Stock apple = new Stock("AAPL", "NASDAQ"); + Stock apple = new Stock("AAPL"); stocks.add(apple); - Stock meta = new Stock("META", "NASDAQ"); + Stock meta = new Stock("META"); stocks.add(meta); - Stock google = new Stock("GOOGL", "NASDAQ"); + Stock google = new Stock("GOOGL"); stocks.add(google); } catch (FinancialPlannerException e) { System.out.println(e.getMessage()); @@ -59,9 +59,9 @@ public JSONArray fetchFMPStockPrices() { return (JSONArray) obj; } - public String addStock(String market, String stockCode) throws FinancialPlannerException { + public String addStock(String stockCode) throws FinancialPlannerException { Stock newStock = null; - newStock = new Stock(stockCode, market); + newStock = new Stock(stockCode); stocks.add(newStock); return newStock.getStockName(); } diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index 5a1d86fa1a..8d36437914 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -42,6 +42,6 @@ private static Command parseAddStock(String restOfInput) { // TODO: check error here String exchange = split[1].trim(); String stockCode = split[2].trim(); - return new AddStockCommand(exchange, stockCode); + return new AddStockCommand(stockCode); } } diff --git a/src/test/java/seedu/financialplanner/investments/WatchListTest.java b/src/test/java/seedu/financialplanner/investments/WatchListTest.java index 1086af73e2..7a2ffe8f64 100644 --- a/src/test/java/seedu/financialplanner/investments/WatchListTest.java +++ b/src/test/java/seedu/financialplanner/investments/WatchListTest.java @@ -26,6 +26,6 @@ void addStock() throws Exception { WatchList wl = WatchList.INSTANCE; String market = "NYSE"; String stockCode = "GME"; - assertEquals("GameStop Corp.", wl.addStock(market, stockCode)); + assertEquals("GameStop Corp.", wl.addStock(stockCode)); } } From f4935d893db62558f2c75ebdddd419e7b39f15b6 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Fri, 13 Oct 2023 15:29:16 +0800 Subject: [PATCH 059/518] Fix test and remove market from add stock --- src/main/java/seedu/financialplanner/utils/Parser.java | 5 ++--- text-ui-test/EXPECTED.TXT | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index 8d36437914..c571f38a72 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -38,10 +38,9 @@ public static Command parse(String input) { } private static Command parseAddStock(String restOfInput) { - String[] split = restOfInput.trim().split("m/|s/"); + String[] split = restOfInput.trim().split("s/"); // TODO: check error here - String exchange = split[1].trim(); - String stockCode = split[2].trim(); + String stockCode = split[1].trim(); return new AddStockCommand(stockCode); } } diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 050dd930f8..0797b3fd0a 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -19,7 +19,7 @@ You have successfully added: Microsoft Corporation Use Watchlist to view it! You have successfully added: -GameStop Corp. +Gamestop Corporation - Class A Use Watchlist to view it! Unknown command. Please try again. Exiting Financial Planner. Goodbye. From acb5bdbfd096302f98eea97c01f4a6e360c1395b Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Fri, 13 Oct 2023 15:38:07 +0800 Subject: [PATCH 060/518] Fix bug --- src/main/java/seedu/financialplanner/investments/Stock.java | 1 - .../java/seedu/financialplanner/investments/WatchListTest.java | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/investments/Stock.java b/src/main/java/seedu/financialplanner/investments/Stock.java index 3c65f9e61e..f39275877a 100644 --- a/src/main/java/seedu/financialplanner/investments/Stock.java +++ b/src/main/java/seedu/financialplanner/investments/Stock.java @@ -56,7 +56,6 @@ public String getStockNameFromAPI(String symbol) throws FinancialPlannerExceptio if (!symbolFound.equals(symbol)) { throw new FinancialPlannerException("Stock not found"); } - System.out.println(stock.get("2. name")); market = (String) stock.get("4. region"); return (String) stock.get("2. name"); } catch (IOException e) { diff --git a/src/test/java/seedu/financialplanner/investments/WatchListTest.java b/src/test/java/seedu/financialplanner/investments/WatchListTest.java index 7a2ffe8f64..cd7b9b9a66 100644 --- a/src/test/java/seedu/financialplanner/investments/WatchListTest.java +++ b/src/test/java/seedu/financialplanner/investments/WatchListTest.java @@ -26,6 +26,6 @@ void addStock() throws Exception { WatchList wl = WatchList.INSTANCE; String market = "NYSE"; String stockCode = "GME"; - assertEquals("GameStop Corp.", wl.addStock(stockCode)); + assertEquals("Gamestop Corporation - Class A", wl.addStock(stockCode)); } } From 28cfe5345285e27661812b3a3a21ff1dafebf0af Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Sun, 15 Oct 2023 12:14:56 +0800 Subject: [PATCH 061/518] Add Budget class --- src/main/java/seedu/financialplanner/list/Budget.java | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/main/java/seedu/financialplanner/list/Budget.java diff --git a/src/main/java/seedu/financialplanner/list/Budget.java b/src/main/java/seedu/financialplanner/list/Budget.java new file mode 100644 index 0000000000..f162c02f13 --- /dev/null +++ b/src/main/java/seedu/financialplanner/list/Budget.java @@ -0,0 +1,10 @@ +package seedu.financialplanner.list; + +public class Budget extends Cashflow { + private static final int MONTH = 30; + public Budget(double value) { + super(value, null, MONTH); + } + + //add storage for budget +} From f166d899d4192414e397be9695f7ab466ed91ceb Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Sun, 15 Oct 2023 12:17:06 +0800 Subject: [PATCH 062/518] Add BudgetCommand --- .../commands/BudgetCommand.java | 28 +++++++++++++++++++ .../seedu/financialplanner/utils/Parser.java | 4 +++ 2 files changed, 32 insertions(+) create mode 100644 src/main/java/seedu/financialplanner/commands/BudgetCommand.java diff --git a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java new file mode 100644 index 0000000000..cb51d653d9 --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java @@ -0,0 +1,28 @@ +package seedu.financialplanner.commands; + +import seedu.financialplanner.exceptions.FinancialPlannerException; +import seedu.financialplanner.investments.WatchList; +import seedu.financialplanner.list.Budget; +import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.utils.Ui; + +public class BudgetCommand extends Command { + private static final String BUDGET_DELIMITTER = "b/"; + private String input; + + public BudgetCommand(String input) { + this.input = input; + } + + @Override + public void execute(Ui ui, FinancialList financialList, WatchList watchList) throws FinancialPlannerException { + int budgetIndex = input.indexOf(BUDGET_DELIMITTER); + if (budgetIndex == -1) { + throw new FinancialPlannerException("Please ensure b/ is included in the command."); + } + String budgetString = input.substring(budgetIndex + BUDGET_DELIMITTER.length()).trim(); + double budget = Double.parseDouble(budgetString); //add error handling here + + financialList.setBudget(new Budget(budget)); + } +} diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index c571f38a72..57d5ddacf3 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -8,6 +8,7 @@ import seedu.financialplanner.commands.Invalid; import seedu.financialplanner.commands.AddStockCommand; import seedu.financialplanner.commands.Find; +import seedu.financialplanner.commands.BudgetCommand; public class Parser { private static final String EXIT_COMMAND = "exit"; @@ -15,6 +16,7 @@ public class Parser { private static final String ADD_ENTRY_COMMAND = "add"; private static final String ADD_STOCK_COMMAND = "addstock"; private static final String FIND_COMMAND = "find"; + private static final String SET_BUDGET_COMMAND = "setbudget"; public static Command parse(String input) { String[] split = input.split(" ", 2); @@ -32,6 +34,8 @@ public static Command parse(String input) { return parseAddStock(restOfInput); case FIND_COMMAND: return new Find(restOfInput); + case SET_BUDGET_COMMAND: + return new BudgetCommand(restOfInput); default: return new Invalid(); } From 5acc2f839e4007ad39ee4fbb069e023c00456cfc Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Sun, 15 Oct 2023 12:18:39 +0800 Subject: [PATCH 063/518] Add setBudget to FinancialList and update test files --- .../java/seedu/financialplanner/list/FinancialList.java | 8 ++++++++ text-ui-test/EXPECTED.TXT | 1 + text-ui-test/input.txt | 1 + 3 files changed, 10 insertions(+) diff --git a/src/main/java/seedu/financialplanner/list/FinancialList.java b/src/main/java/seedu/financialplanner/list/FinancialList.java index 3d5558e1be..96b803f52f 100644 --- a/src/main/java/seedu/financialplanner/list/FinancialList.java +++ b/src/main/java/seedu/financialplanner/list/FinancialList.java @@ -51,6 +51,14 @@ public void addExpense(double value, String type, int recur) { printAddedCashflow("expense"); } + public void setBudget(Budget budget) { + list.add(budget); + + DecimalFormat decimalFormat = new DecimalFormat("####0.00"); + System.out.println("A monthly budget of " + decimalFormat.format(round(budget.value, 2)) + + " has been set."); + } + public void load(Cashflow entry) { list.add(entry); } diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 0797b3fd0a..086723a98e 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -21,5 +21,6 @@ Use Watchlist to view it! You have successfully added: Gamestop Corporation - Class A Use Watchlist to view it! +A monthly budget of 5000.00 has been set. Unknown command. Please try again. Exiting Financial Planner. Goodbye. diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index 025ea01d28..c70bc82617 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -4,5 +4,6 @@ add expense a/100 t/daily necessities r/30 add expense a/123.21 t/books addstock m/NASDAQ s/MSFT addstock m/NYSE s/GME +setbudget b/5000 sdf exit \ No newline at end of file From 0ca7eeac266bc0a105ef37e9c58e1834f5d25850 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Sun, 15 Oct 2023 12:25:10 +0800 Subject: [PATCH 064/518] Add overview command --- .../financialplanner/commands/OverviewCommand.java | 12 ++++++++++++ .../java/seedu/financialplanner/utils/Parser.java | 4 ++++ 2 files changed, 16 insertions(+) create mode 100644 src/main/java/seedu/financialplanner/commands/OverviewCommand.java diff --git a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java new file mode 100644 index 0000000000..a3e4a56814 --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java @@ -0,0 +1,12 @@ +package seedu.financialplanner.commands; + +import seedu.financialplanner.investments.WatchList; +import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.utils.Ui; + +public class OverviewCommand extends Command { + @Override + public void execute(Ui ui, FinancialList financialList, WatchList watchList) { + ui.showMessage("Here is an overview of your financials:"); + } +} diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index c571f38a72..d54a69dc26 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -8,6 +8,7 @@ import seedu.financialplanner.commands.Invalid; import seedu.financialplanner.commands.AddStockCommand; import seedu.financialplanner.commands.Find; +import seedu.financialplanner.commands.OverviewCommand; public class Parser { private static final String EXIT_COMMAND = "exit"; @@ -15,6 +16,7 @@ public class Parser { private static final String ADD_ENTRY_COMMAND = "add"; private static final String ADD_STOCK_COMMAND = "addstock"; private static final String FIND_COMMAND = "find"; + private static final String OVERVIEW_COMMAND = "overview"; public static Command parse(String input) { String[] split = input.split(" ", 2); @@ -32,6 +34,8 @@ public static Command parse(String input) { return parseAddStock(restOfInput); case FIND_COMMAND: return new Find(restOfInput); + case OVERVIEW_COMMAND: + return new OverviewCommand(); default: return new Invalid(); } From ff40a9b9b08d48c6dbcb89fb637fa403e8f9f89c Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Sun, 15 Oct 2023 13:05:04 +0800 Subject: [PATCH 065/518] Update overview to show: - Total balance - Highest income - Highest expense - Watchlist Fixes #29 --- .../commands/OverviewCommand.java | 40 ++++++++++++++++++- .../seedu/financialplanner/list/Cashflow.java | 8 ++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java index a3e4a56814..406b53c086 100644 --- a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java +++ b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java @@ -1,12 +1,48 @@ package seedu.financialplanner.commands; +import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.investments.WatchList; +import seedu.financialplanner.list.Cashflow; +import seedu.financialplanner.list.Expense; import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.list.Income; import seedu.financialplanner.utils.Ui; public class OverviewCommand extends Command { @Override - public void execute(Ui ui, FinancialList financialList, WatchList watchList) { - ui.showMessage("Here is an overview of your financials:"); + public void execute(Ui ui, FinancialList financialList, WatchList watchList) throws FinancialPlannerException { + Command watchlist = new WatchListCommand(); + ui.showMessage("Here is an overview of your financials:\n" + + "Total balance: " + String.format("%.2f", Cashflow.getBalance()) + "\n" + + "Highest income: " + String.format("%.2f", getHighestIncome(financialList)) + "\n" + + "Highest expense: " + String.format("%.2f", getHighestExpense(financialList)) + "\n" + + "Watchlist: "); //todo: maybe indicate if income/expense is recurring + //todo: add budget and goal disparity + watchlist.execute(ui, financialList, watchList); + //todo: add visualisation + } + + private double getHighestIncome(FinancialList list) { + double maxIncome = 0; + for (Cashflow entry : list.list) { + if (entry instanceof Income) { + if (entry.getValue() > maxIncome) { + maxIncome = entry.getValue(); + } + } + } + return maxIncome; + } + + private double getHighestExpense(FinancialList list) { + double maxExpense = 0; + for (Cashflow entry : list.list) { + if (entry instanceof Expense) { + if (entry.getValue() > maxExpense) { + maxExpense = entry.getValue(); + } + } + } + return maxExpense; } } diff --git a/src/main/java/seedu/financialplanner/list/Cashflow.java b/src/main/java/seedu/financialplanner/list/Cashflow.java index 67a7ab2a9f..5a29d1184f 100644 --- a/src/main/java/seedu/financialplanner/list/Cashflow.java +++ b/src/main/java/seedu/financialplanner/list/Cashflow.java @@ -19,6 +19,14 @@ public Cashflow() { this.recur = 0; } + public static double getBalance() { + return balance; + } + + public double getValue() { + return value; + } + public String formatString() { return this.value + " | " + this.type + " | " + this.recur; } From 1c099725de56ae0fe7476dd7294229998340ed16 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Sun, 15 Oct 2023 13:30:05 +0800 Subject: [PATCH 066/518] Edit setBudget method in FinancialList --- .../java/seedu/financialplanner/commands/BudgetCommand.java | 2 +- src/main/java/seedu/financialplanner/list/Budget.java | 2 +- src/main/java/seedu/financialplanner/list/FinancialList.java | 4 +--- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java index cb51d653d9..3c479e5c9f 100644 --- a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java +++ b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java @@ -21,7 +21,7 @@ public void execute(Ui ui, FinancialList financialList, WatchList watchList) thr throw new FinancialPlannerException("Please ensure b/ is included in the command."); } String budgetString = input.substring(budgetIndex + BUDGET_DELIMITTER.length()).trim(); - double budget = Double.parseDouble(budgetString); //add error handling here + double budget = Double.parseDouble(budgetString); //todo: add error handling here financialList.setBudget(new Budget(budget)); } diff --git a/src/main/java/seedu/financialplanner/list/Budget.java b/src/main/java/seedu/financialplanner/list/Budget.java index f162c02f13..adae6863b7 100644 --- a/src/main/java/seedu/financialplanner/list/Budget.java +++ b/src/main/java/seedu/financialplanner/list/Budget.java @@ -6,5 +6,5 @@ public Budget(double value) { super(value, null, MONTH); } - //add storage for budget + //todo: add storage for budget } diff --git a/src/main/java/seedu/financialplanner/list/FinancialList.java b/src/main/java/seedu/financialplanner/list/FinancialList.java index 96b803f52f..06cbe66aad 100644 --- a/src/main/java/seedu/financialplanner/list/FinancialList.java +++ b/src/main/java/seedu/financialplanner/list/FinancialList.java @@ -54,9 +54,7 @@ public void addExpense(double value, String type, int recur) { public void setBudget(Budget budget) { list.add(budget); - DecimalFormat decimalFormat = new DecimalFormat("####0.00"); - System.out.println("A monthly budget of " + decimalFormat.format(round(budget.value, 2)) - + " has been set."); + System.out.println("A monthly budget of " + String.format("%.2f", budget.value) + " has been set."); } public void load(Cashflow entry) { From 7d495e4009402389b717de162fc78f288ba88fc1 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 15 Oct 2023 17:00:31 +0800 Subject: [PATCH 067/518] Add new dependency for creating data plots and test it --- build.gradle | 1 + .../financialplanner/FinancialPlanner.java | 4 ++- .../visualisations/PieChartVisual.java | 26 +++++++++++++++++++ .../visualisations/Visual.java | 5 ++++ .../visualisations/VisualType.java | 5 ++++ 5 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 src/main/java/seedu/financialplanner/visualisations/PieChartVisual.java create mode 100644 src/main/java/seedu/financialplanner/visualisations/Visual.java create mode 100644 src/main/java/seedu/financialplanner/visualisations/VisualType.java diff --git a/build.gradle b/build.gradle index 4bd48aac5b..d9b62e0a3b 100644 --- a/build.gradle +++ b/build.gradle @@ -14,6 +14,7 @@ dependencies { testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.10.0' implementation group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1' implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.0' + implementation group: 'org.knowm.xchart', name: 'xchart', version: '3.2.2' } test { diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index 4123c0eccb..950611a486 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -8,6 +8,7 @@ import seedu.financialplanner.storage.Storage; import seedu.financialplanner.utils.Parser; import seedu.financialplanner.utils.Ui; +import seedu.financialplanner.visualisations.PieChartVisual; public class FinancialPlanner { @@ -44,7 +45,8 @@ public void run() { ui.showMessage(e.getMessage()); } } - + PieChartVisual test = new PieChartVisual(); + test.displayPieChart(); save(); ui.exitMessage(); } diff --git a/src/main/java/seedu/financialplanner/visualisations/PieChartVisual.java b/src/main/java/seedu/financialplanner/visualisations/PieChartVisual.java new file mode 100644 index 0000000000..3175bc3850 --- /dev/null +++ b/src/main/java/seedu/financialplanner/visualisations/PieChartVisual.java @@ -0,0 +1,26 @@ +package seedu.financialplanner.visualisations; + +import org.knowm.xchart.*; + +import java.awt.*; + +public class PieChartVisual extends Visual { + public void displayPieChart () { + PieChart chart = new PieChartBuilder().width(800).height(600).title("Test").build(); + + // Customize Chart + Color[] sliceColors = new Color[] { new Color(224, 68, 14), new Color(230, 105, 62), new Color(236, 143, 110), new Color(243, 180, 159), new Color(246, 199, 182) }; + chart.getStyler().setSeriesColors(sliceColors); + + // Series + chart.addSeries("Gold", 24); + chart.addSeries("Silver", 21); + chart.addSeries("Platinum", 39); + chart.addSeries("Copper", 17); + chart.addSeries("Zinc", 40); + + // Show it + new SwingWrapper<>(chart).displayChart(); + } + +} diff --git a/src/main/java/seedu/financialplanner/visualisations/Visual.java b/src/main/java/seedu/financialplanner/visualisations/Visual.java new file mode 100644 index 0000000000..3fab8f35c3 --- /dev/null +++ b/src/main/java/seedu/financialplanner/visualisations/Visual.java @@ -0,0 +1,5 @@ +package seedu.financialplanner.visualisations; + + +public abstract class Visual { +} diff --git a/src/main/java/seedu/financialplanner/visualisations/VisualType.java b/src/main/java/seedu/financialplanner/visualisations/VisualType.java new file mode 100644 index 0000000000..57ec86bbf8 --- /dev/null +++ b/src/main/java/seedu/financialplanner/visualisations/VisualType.java @@ -0,0 +1,5 @@ +package seedu.financialplanner.visualisations; + +public enum VisualType { + PIECHART, BARGRAPH +} From fe1b5953d0fd0d3767e5ed5a5ce7f748651598ba Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 15 Oct 2023 19:33:20 +0800 Subject: [PATCH 068/518] Rename FinancialList to CashflowList --- .../financialplanner/FinancialPlanner.java | 10 +++---- .../commands/AddStockCommand.java | 4 +-- .../financialplanner/commands/Command.java | 4 +-- .../financialplanner/commands/Entry.java | 4 +-- .../seedu/financialplanner/commands/Exit.java | 4 +-- .../seedu/financialplanner/commands/Find.java | 10 +++---- .../financialplanner/commands/Invalid.java | 4 +-- .../commands/WatchListCommand.java | 4 +-- .../{FinancialList.java => CashflowList.java} | 26 ++++++++++++++++--- .../financialplanner/storage/LoadData.java | 8 +++--- .../financialplanner/storage/SaveData.java | 6 ++--- .../financialplanner/storage/Storage.java | 6 ++--- .../java/seedu/financialplanner/utils/Ui.java | 5 ++++ .../financialplanner/commands/EntryTest.java | 8 +++--- ...ialListTest.java => CashflowListTest.java} | 4 +-- .../financialplanner/storage/StorageTest.java | 16 ++++++------ 16 files changed, 73 insertions(+), 50 deletions(-) rename src/main/java/seedu/financialplanner/list/{FinancialList.java => CashflowList.java} (76%) rename src/test/java/seedu/financialplanner/list/{FinancialListTest.java => CashflowListTest.java} (96%) diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index 4123c0eccb..c952f51cff 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -4,7 +4,7 @@ import seedu.financialplanner.commands.Exit; import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.investments.WatchList; -import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.list.CashflowList; import seedu.financialplanner.storage.Storage; import seedu.financialplanner.utils.Parser; import seedu.financialplanner.utils.Ui; @@ -15,7 +15,7 @@ public class FinancialPlanner { private final Storage storage = Storage.INSTANCE; private final Ui ui = Ui.INSTANCE; private final WatchList watchList = WatchList.INSTANCE; - private final FinancialList financialList = FinancialList.INSTANCE; + private final CashflowList cashflowList = CashflowList.INSTANCE; private FinancialPlanner() { } @@ -26,7 +26,7 @@ public static void main(String[] args) { public void run() { try { - storage.load(financialList, ui, FILE_PATH); + storage.load(cashflowList, ui, FILE_PATH); } catch (FinancialPlannerException e) { ui.showMessage(e.getMessage()); } @@ -39,7 +39,7 @@ public void run() { input = ui.input(); try { command = Parser.parse(input); - command.execute(ui, financialList, watchList); + command.execute(ui, cashflowList, watchList); } catch (FinancialPlannerException e) { ui.showMessage(e.getMessage()); } @@ -51,7 +51,7 @@ public void run() { public void save() { try { - storage.save(financialList, FILE_PATH); + storage.save(cashflowList, FILE_PATH); } catch (FinancialPlannerException e) { ui.showMessage(e.getMessage()); } diff --git a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java index 94278ba62c..a1c9bdad35 100644 --- a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java @@ -2,7 +2,7 @@ import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.investments.WatchList; -import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.list.CashflowList; import seedu.financialplanner.utils.Ui; public class AddStockCommand extends Command { @@ -13,7 +13,7 @@ public AddStockCommand(String stockCode) { } @Override - public void execute(Ui ui, FinancialList financialList, WatchList watchList) { + public void execute(Ui ui, CashflowList cashflowList, WatchList watchList) { String stockName = null; try { stockName = watchList.addStock(stockCode); diff --git a/src/main/java/seedu/financialplanner/commands/Command.java b/src/main/java/seedu/financialplanner/commands/Command.java index cfa92f08d7..7bd135b541 100644 --- a/src/main/java/seedu/financialplanner/commands/Command.java +++ b/src/main/java/seedu/financialplanner/commands/Command.java @@ -3,9 +3,9 @@ import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.utils.Ui; -import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.list.CashflowList; public class Command { - public void execute(Ui ui, FinancialList financialList, WatchList watchList) throws FinancialPlannerException { + public void execute(Ui ui, CashflowList cashflowList, WatchList watchList) throws FinancialPlannerException { } } diff --git a/src/main/java/seedu/financialplanner/commands/Entry.java b/src/main/java/seedu/financialplanner/commands/Entry.java index 8d6feee45e..8ac20214d7 100644 --- a/src/main/java/seedu/financialplanner/commands/Entry.java +++ b/src/main/java/seedu/financialplanner/commands/Entry.java @@ -1,7 +1,7 @@ package seedu.financialplanner.commands; import seedu.financialplanner.investments.WatchList; -import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.list.CashflowList; import seedu.financialplanner.utils.Ui; public class Entry extends Command{ @@ -26,7 +26,7 @@ private int determineRecur(String parameters) { } @Override - public void execute(Ui ui, FinancialList list, WatchList watchList) { + public void execute(Ui ui, CashflowList list, WatchList watchList) { String[] split = input.split(" ", 2); String entryType = split[0]; String parameters = split[1]; diff --git a/src/main/java/seedu/financialplanner/commands/Exit.java b/src/main/java/seedu/financialplanner/commands/Exit.java index fe214ca1fb..39b732db41 100644 --- a/src/main/java/seedu/financialplanner/commands/Exit.java +++ b/src/main/java/seedu/financialplanner/commands/Exit.java @@ -1,7 +1,7 @@ package seedu.financialplanner.commands; import seedu.financialplanner.investments.WatchList; -import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.list.CashflowList; import seedu.financialplanner.utils.Ui; public class Exit extends Command { @@ -9,6 +9,6 @@ public Exit() { } @Override - public void execute(Ui ui, FinancialList financialList, WatchList watchList) { + public void execute(Ui ui, CashflowList cashflowList, WatchList watchList) { } } diff --git a/src/main/java/seedu/financialplanner/commands/Find.java b/src/main/java/seedu/financialplanner/commands/Find.java index 32ee443c87..2c45c3f100 100644 --- a/src/main/java/seedu/financialplanner/commands/Find.java +++ b/src/main/java/seedu/financialplanner/commands/Find.java @@ -1,7 +1,7 @@ package seedu.financialplanner.commands; import seedu.financialplanner.investments.WatchList; -import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.list.CashflowList; import seedu.financialplanner.utils.Ui; import java.util.ArrayList; @@ -14,12 +14,12 @@ public Find(String description) { } @Override - public void execute(Ui ui, FinancialList financialList, WatchList watchList) { + public void execute(Ui ui, CashflowList cashflowList, WatchList watchList) { ArrayList foundedFinancialList = new ArrayList<>(); ArrayList foundedWatchList = new ArrayList<>(); - for(int i = 0; i < financialList.size(); i++) { - if(financialList.get(i).formatString().contains(description)) { - foundedFinancialList.add(financialList.get(i).formatString()); + for(int i = 0; i < cashflowList.size(); i++) { + if(cashflowList.get(i).formatString().contains(description)) { + foundedFinancialList.add(cashflowList.get(i).formatString()); } } if(!foundedFinancialList.isEmpty()){ diff --git a/src/main/java/seedu/financialplanner/commands/Invalid.java b/src/main/java/seedu/financialplanner/commands/Invalid.java index 5a081a375b..d182028772 100644 --- a/src/main/java/seedu/financialplanner/commands/Invalid.java +++ b/src/main/java/seedu/financialplanner/commands/Invalid.java @@ -1,7 +1,7 @@ package seedu.financialplanner.commands; import seedu.financialplanner.investments.WatchList; -import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.list.CashflowList; import seedu.financialplanner.utils.Ui; public class Invalid extends Command { @@ -9,7 +9,7 @@ public Invalid() { } @Override - public void execute(Ui ui, FinancialList financialList, WatchList watchList) { + public void execute(Ui ui, CashflowList cashflowList, WatchList watchList) { ui.showMessage("Unknown command. Please try again."); } } diff --git a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java index 0b6d427938..4550eb48b1 100644 --- a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java @@ -3,12 +3,12 @@ import org.json.simple.JSONArray; import org.json.simple.JSONObject; import seedu.financialplanner.investments.WatchList; -import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.list.CashflowList; import seedu.financialplanner.utils.Ui; public class WatchListCommand extends Command { @Override - public void execute(Ui ui, FinancialList financialList, WatchList watchList) { + public void execute(Ui ui, CashflowList cashflowList, WatchList watchList) { JSONArray stocks = watchList.fetchFMPStockPrices(); ui.printWatchListHeader(); for (Object o : stocks) { diff --git a/src/main/java/seedu/financialplanner/list/FinancialList.java b/src/main/java/seedu/financialplanner/list/CashflowList.java similarity index 76% rename from src/main/java/seedu/financialplanner/list/FinancialList.java rename to src/main/java/seedu/financialplanner/list/CashflowList.java index 3d5558e1be..f6e7c462ae 100644 --- a/src/main/java/seedu/financialplanner/list/FinancialList.java +++ b/src/main/java/seedu/financialplanner/list/CashflowList.java @@ -1,22 +1,24 @@ package seedu.financialplanner.list; +import seedu.financialplanner.utils.Ui; + import java.math.BigDecimal; import java.math.RoundingMode; import java.text.DecimalFormat; import java.util.ArrayList; -public class FinancialList { - public static final FinancialList INSTANCE = new FinancialList(); +public class CashflowList { + public static final CashflowList INSTANCE = new CashflowList(); public final ArrayList list = new ArrayList<>(); - private FinancialList() { + private CashflowList() { } private void printAddedCashflow(String line) { DecimalFormat decimalFormat = new DecimalFormat("####0.00"); - Cashflow cashflow = list.get(list.size() - 1); + Cashflow cashflow = get(list.size() - 1); System.out.print("Added " + line + " of value: "); System.out.println(decimalFormat.format(round(cashflow.value, 2)) + " to the list."); System.out.println("type: " + cashflow.type); @@ -51,6 +53,22 @@ public void addExpense(double value, String type, int recur) { printAddedCashflow("expense"); } + public void delete(int index) { + int listIndex = index - 1; + + Cashflow toRemove = get(listIndex); + list.remove(listIndex); + Ui.INSTANCE.printDeletedCashflow(toRemove); + } + + public void deleteIncome(int index) { + int listIndex = index - 1; + + Cashflow toRemove = get(listIndex); + list.remove(listIndex); + Ui.INSTANCE.printDeletedCashflow(toRemove); + } + public void load(Cashflow entry) { list.add(entry); } diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 26449059f2..8198c8785b 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -3,7 +3,7 @@ import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.list.Cashflow; import seedu.financialplanner.list.Expense; -import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.list.CashflowList; import seedu.financialplanner.list.Income; import seedu.financialplanner.utils.Ui; @@ -12,7 +12,7 @@ import java.util.Scanner; public abstract class LoadData { - public static void load(FinancialList financialList, Ui ui, String filePath) throws FinancialPlannerException { + public static void load(CashflowList cashflowList, Ui ui, String filePath) throws FinancialPlannerException { try { Scanner inputFile = new Scanner(new FileReader(filePath)); String line; @@ -22,7 +22,7 @@ public static void load(FinancialList financialList, Ui ui, String filePath) thr line = inputFile.nextLine(); final Cashflow entry = getEntry(line); - financialList.load(entry); + cashflowList.load(entry); } inputFile.close(); } catch (IOException e) { @@ -30,7 +30,7 @@ public static void load(FinancialList financialList, Ui ui, String filePath) thr } catch (NumberFormatException | ArrayIndexOutOfBoundsException | FinancialPlannerException e) { ui.showMessage("File appears to be corrupted. Do you want to create a new file? (Y/N)"); if (createNewFile(ui)) { - financialList.list.clear(); + cashflowList.list.clear(); } else { throw new FinancialPlannerException("Please fix the corrupted file, " + "which can be found in data/data.txt."); diff --git a/src/main/java/seedu/financialplanner/storage/SaveData.java b/src/main/java/seedu/financialplanner/storage/SaveData.java index d36380c0d6..b5fa6bc2f6 100644 --- a/src/main/java/seedu/financialplanner/storage/SaveData.java +++ b/src/main/java/seedu/financialplanner/storage/SaveData.java @@ -2,16 +2,16 @@ import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.list.Cashflow; -import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.list.CashflowList; import java.io.FileWriter; import java.io.IOException; public abstract class SaveData { - public static void save(FinancialList financialList, String filePath) throws FinancialPlannerException { + public static void save(CashflowList cashflowList, String filePath) throws FinancialPlannerException { try { FileWriter fw = new FileWriter(filePath); - for (Cashflow entry : financialList.list) { + for (Cashflow entry : cashflowList.list) { fw.write(entry.formatString() + "\n"); } fw.close(); diff --git a/src/main/java/seedu/financialplanner/storage/Storage.java b/src/main/java/seedu/financialplanner/storage/Storage.java index 741e0eb7ed..ef340a2d3e 100644 --- a/src/main/java/seedu/financialplanner/storage/Storage.java +++ b/src/main/java/seedu/financialplanner/storage/Storage.java @@ -1,7 +1,7 @@ package seedu.financialplanner.storage; import seedu.financialplanner.exceptions.FinancialPlannerException; -import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.list.CashflowList; import seedu.financialplanner.utils.Ui; import java.io.IOException; @@ -24,11 +24,11 @@ private Storage() { } } - public void load(FinancialList list, Ui ui, String filePath) throws FinancialPlannerException { + public void load(CashflowList list, Ui ui, String filePath) throws FinancialPlannerException { LoadData.load(list, ui, filePath); } - public void save(FinancialList list, String filePath) throws FinancialPlannerException { + public void save(CashflowList list, String filePath) throws FinancialPlannerException { SaveData.save(list, filePath); } } diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index ace28c998c..ee157893ab 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -2,6 +2,7 @@ import org.apache.commons.lang3.StringUtils; import org.json.simple.JSONObject; +import seedu.financialplanner.list.Cashflow; import java.util.Scanner; @@ -54,4 +55,8 @@ public void printAddStock(String stockName) { System.out.println("Use Watchlist to view it!"); } + + public void printDeletedCashflow(Cashflow type) { + + } } diff --git a/src/test/java/seedu/financialplanner/commands/EntryTest.java b/src/test/java/seedu/financialplanner/commands/EntryTest.java index 682880db27..6b8bfff11b 100644 --- a/src/test/java/seedu/financialplanner/commands/EntryTest.java +++ b/src/test/java/seedu/financialplanner/commands/EntryTest.java @@ -2,26 +2,26 @@ import org.junit.jupiter.api.Test; import seedu.financialplanner.investments.WatchList; -import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.list.CashflowList; import seedu.financialplanner.utils.Ui; import static org.junit.jupiter.api.Assertions.assertEquals; class EntryTest { private Ui ui = Ui.INSTANCE; - private FinancialList financialList = FinancialList.INSTANCE; + private CashflowList cashflowList = CashflowList.INSTANCE; private WatchList watchList = WatchList.INSTANCE; @Test void testExecute() { Entry testEntry = new Entry("income a/300 t/work r/30"); - testEntry.execute(ui, financialList, watchList); + testEntry.execute(ui, cashflowList, watchList); assertEquals(300, testEntry.value); assertEquals("work", testEntry.type); assertEquals(30, testEntry.recur); testEntry = new Entry("expense a/15 t/double mcspicy"); - testEntry.execute(ui, financialList, watchList); + testEntry.execute(ui, cashflowList, watchList); assertEquals(15, testEntry.value); assertEquals("double mcspicy", testEntry.type); assertEquals(0, testEntry.recur); diff --git a/src/test/java/seedu/financialplanner/list/FinancialListTest.java b/src/test/java/seedu/financialplanner/list/CashflowListTest.java similarity index 96% rename from src/test/java/seedu/financialplanner/list/FinancialListTest.java rename to src/test/java/seedu/financialplanner/list/CashflowListTest.java index 3a4e07fef9..84b6cac8e7 100644 --- a/src/test/java/seedu/financialplanner/list/FinancialListTest.java +++ b/src/test/java/seedu/financialplanner/list/CashflowListTest.java @@ -6,8 +6,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -class FinancialListTest { - private FinancialList testList = FinancialList.INSTANCE; +class CashflowListTest { + private CashflowList testList = CashflowList.INSTANCE; private DecimalFormat decimalFormat = new DecimalFormat("####0.00"); @Test diff --git a/src/test/java/seedu/financialplanner/storage/StorageTest.java b/src/test/java/seedu/financialplanner/storage/StorageTest.java index 342752e726..3ddcfe5be0 100644 --- a/src/test/java/seedu/financialplanner/storage/StorageTest.java +++ b/src/test/java/seedu/financialplanner/storage/StorageTest.java @@ -4,7 +4,7 @@ import org.junit.jupiter.api.io.TempDir; import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.list.Expense; -import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.list.CashflowList; import seedu.financialplanner.list.Income; import seedu.financialplanner.utils.Ui; @@ -24,16 +24,16 @@ public class StorageTest { @Test public void loadValidData() throws FinancialPlannerException { Storage storage = Storage.INSTANCE; - FinancialList test = FinancialList.INSTANCE; + CashflowList test = CashflowList.INSTANCE; storage.load(test, Ui.INSTANCE, "src/test/testData/ValidData.txt"); - FinancialList expected = getTestData(); + CashflowList expected = getTestData(); assertEquals(expected.getList(), test.getList()); } @Test public void loadInvalidData_userInputNo() { Storage storage = Storage.INSTANCE; - FinancialList test = FinancialList.INSTANCE; + CashflowList test = CashflowList.INSTANCE; ByteArrayInputStream in = new ByteArrayInputStream("n".getBytes()); System.setIn(in); assertThrows(FinancialPlannerException.class, @@ -42,7 +42,7 @@ public void loadInvalidData_userInputNo() { @Test public void saveValidData() throws FinancialPlannerException, IOException { - FinancialList expected = getTestData(); + CashflowList expected = getTestData(); Storage storage = Storage.INSTANCE; storage.save(expected, String.valueOf(testFolder.resolve("temp.txt"))); assertEquals(Files.readAllLines(Path.of("src/test/testData/ValidData.txt")), @@ -51,13 +51,13 @@ public void saveValidData() throws FinancialPlannerException, IOException { @Test public void saveNonExistentFile() { - FinancialList expected = getTestData(); + CashflowList expected = getTestData(); Storage storage = Storage.INSTANCE; assertThrows(FinancialPlannerException.class, () -> storage.save(expected, "")); } - private FinancialList getTestData() { - FinancialList list = FinancialList.INSTANCE; + private CashflowList getTestData() { + CashflowList list = CashflowList.INSTANCE; list.load(new Income(123.12, "allowance", 0)); list.load(new Expense(100, "daily necessities", 30)); return list; From 2be22452273938923c4666e0b1af0c17acfca335 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 15 Oct 2023 21:45:03 +0800 Subject: [PATCH 069/518] Add toString method in Cashflow --- .../seedu/financialplanner/list/Cashflow.java | 44 ++++++++++++++++--- .../seedu/financialplanner/list/Expense.java | 11 +++-- .../seedu/financialplanner/list/Income.java | 11 +++-- .../list/CashflowListTest.java | 16 +++---- 4 files changed, 62 insertions(+), 20 deletions(-) diff --git a/src/main/java/seedu/financialplanner/list/Cashflow.java b/src/main/java/seedu/financialplanner/list/Cashflow.java index 67a7ab2a9f..2df5dccc89 100644 --- a/src/main/java/seedu/financialplanner/list/Cashflow.java +++ b/src/main/java/seedu/financialplanner/list/Cashflow.java @@ -1,25 +1,59 @@ package seedu.financialplanner.list; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.text.DecimalFormat; + public class Cashflow { protected static double balance = 0; - protected double value; + protected double amount; protected String type; protected int recur; - public Cashflow(double value, String type, int recur) { - this.value = value; + public Cashflow(double amount, String type, int recur) { + this.amount = amount; this.type = type; this.recur = recur; } public Cashflow() { - this.value = 0; + this.amount = 0; this.type = null; this.recur = 0; } + //@author mhadidg-reused + //Reused from https://stackoverflow.com/questions/2808535/round-a-double-to-2-decimal-places + public double round(double value, int places) { + if (places < 0) { + throw new IllegalArgumentException(); + } + + BigDecimal bd = BigDecimal.valueOf(value); + bd = bd.setScale(places, RoundingMode.HALF_UP); + return bd.doubleValue(); + } + //@author mhadidg + public String toString() { + DecimalFormat decimalFormat = new DecimalFormat("####0.00"); + + String string = "Type: " + type + System.lineSeparator() + + "Amount:" + decimalFormat.format(round(amount, 2)); + + if (recur != 0) { + string += System.lineSeparator() + "Recurring every: " + recur + "days."; + } + + return string; + } + + public String formatBalance() { + DecimalFormat decimalFormat = new DecimalFormat("####0.00"); + + return decimalFormat.format(round(Cashflow.balance, 2)); + } public String formatString() { - return this.value + " | " + this.type + " | " + this.recur; + return this.amount + " | " + this.type + " | " + this.recur; } } diff --git a/src/main/java/seedu/financialplanner/list/Expense.java b/src/main/java/seedu/financialplanner/list/Expense.java index 2299bd8105..7230fcac13 100644 --- a/src/main/java/seedu/financialplanner/list/Expense.java +++ b/src/main/java/seedu/financialplanner/list/Expense.java @@ -1,15 +1,20 @@ package seedu.financialplanner.list; public class Expense extends Cashflow { - public Expense(double value, String type, int recur) { - super(value, type, recur); - addIncomeValue(value); + public Expense(double amount, String type, int recur) { + super(amount, type, recur); + addIncomeValue(amount); } private void addIncomeValue(double value) { balance -= value; } + @Override + public String toString() { + return "Expense" + System.lineSeparator() + super.toString(); + } + @Override public String formatString() { return "E | " + super.formatString(); diff --git a/src/main/java/seedu/financialplanner/list/Income.java b/src/main/java/seedu/financialplanner/list/Income.java index 8b21dc1efb..ac86d6162c 100644 --- a/src/main/java/seedu/financialplanner/list/Income.java +++ b/src/main/java/seedu/financialplanner/list/Income.java @@ -1,15 +1,18 @@ package seedu.financialplanner.list; public class Income extends Cashflow{ - public Income(double value, String type, int recur) { - super(value, type, recur); - addIncomeValue(value); + public Income(double amount, String type, int recur) { + super(amount, type, recur); + addIncomeValue(amount); } private void addIncomeValue(double value) { balance += value; } - + @Override + public String toString() { + return "Income" + System.lineSeparator() + super.toString(); + } @Override public String formatString() { return "I | " + super.formatString(); diff --git a/src/test/java/seedu/financialplanner/list/CashflowListTest.java b/src/test/java/seedu/financialplanner/list/CashflowListTest.java index 84b6cac8e7..e8bfc52f15 100644 --- a/src/test/java/seedu/financialplanner/list/CashflowListTest.java +++ b/src/test/java/seedu/financialplanner/list/CashflowListTest.java @@ -15,8 +15,8 @@ void testAddIncomeAndExpense() { Cashflow.balance = 0; testList.addIncome(15, "work", 30); Cashflow testIncome = testList.list.get(0); - double roundedValue = testList.round(testIncome.value, 2); - double roundedBalance = testList.round(Cashflow.balance, 2); + double roundedValue = testIncome.round(testIncome.amount, 2); + double roundedBalance = testIncome.round(Cashflow.balance, 2); assertTrue(testIncome instanceof Income); assertEquals("15.00", decimalFormat.format(roundedValue)); assertEquals("work", testIncome.type); @@ -25,8 +25,8 @@ void testAddIncomeAndExpense() { testList.addIncome(15.999, "rate of returns", 0); testIncome = testList.list.get(1); - roundedValue = testList.round(testIncome.value, 2); - roundedBalance = testList.round(Cashflow.balance, 2); + roundedValue = testIncome.round(testIncome.amount, 2); + roundedBalance = testIncome.round(Cashflow.balance, 2); assertTrue(testIncome instanceof Income); assertEquals("16.00", decimalFormat.format(roundedValue)); assertEquals("rate of returns", testIncome.type); @@ -35,8 +35,8 @@ void testAddIncomeAndExpense() { testList.addExpense(10, "lunch", 0); Cashflow testExpense = testList.list.get(2); - roundedValue = testList.round(testExpense.value, 2); - roundedBalance = testList.round(Cashflow.balance, 2); + roundedValue = testExpense.round(testExpense.amount, 2); + roundedBalance = testExpense.round(Cashflow.balance, 2); assertTrue(testExpense instanceof Expense); assertEquals("10.00", decimalFormat.format(roundedValue)); assertEquals("lunch", testExpense.type); @@ -45,8 +45,8 @@ void testAddIncomeAndExpense() { testList.addExpense(19.999, "Apple Music", 30); testExpense = testList.list.get(3); - roundedValue = testList.round(testExpense.value, 2); - roundedBalance = testList.round(Cashflow.balance, 2); + roundedValue = testExpense.round(testExpense.amount, 2); + roundedBalance = testExpense.round(Cashflow.balance, 2); assertTrue(testExpense instanceof Expense); assertEquals("20.00", decimalFormat.format(roundedValue)); assertEquals("Apple Music", testExpense.type); From 73b1c64059a1ea52fcd4bac81d45be61ce1c621e Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 15 Oct 2023 21:46:44 +0800 Subject: [PATCH 070/518] Add printAddedCashflow and printDeletedCashflow methods to Ui --- src/main/java/seedu/financialplanner/utils/Ui.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index ee157893ab..4b5890a2a0 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -55,8 +55,16 @@ public void printAddStock(String stockName) { System.out.println("Use Watchlist to view it!"); } + public void printAddedCashflow(Cashflow entry) { + System.out.println("You have added:"); + System.out.println(entry); + System.out.println("to the Financial Planner."); + System.out.println("Balance: " + entry.formatBalance()); + } - public void printDeletedCashflow(Cashflow type) { - + public void printDeletedCashflow(Cashflow entry) { + System.out.println("You have removed:"); + System.out.println(entry); + System.out.println("from the Financial Planner."); } } From 7f0ff6575178c82185acd34370ed280d0ff9c9bb Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 15 Oct 2023 21:49:57 +0800 Subject: [PATCH 071/518] Rename Entry class to AddCashflowCommand class --- .../commands/{Entry.java => AddCashflowCommand.java} | 12 ++++++------ .../java/seedu/financialplanner/utils/Parser.java | 5 ++++- 2 files changed, 10 insertions(+), 7 deletions(-) rename src/main/java/seedu/financialplanner/commands/{Entry.java => AddCashflowCommand.java} (82%) diff --git a/src/main/java/seedu/financialplanner/commands/Entry.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java similarity index 82% rename from src/main/java/seedu/financialplanner/commands/Entry.java rename to src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index 8ac20214d7..c6c9fba51d 100644 --- a/src/main/java/seedu/financialplanner/commands/Entry.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -4,15 +4,15 @@ import seedu.financialplanner.list.CashflowList; import seedu.financialplanner.utils.Ui; -public class Entry extends Command{ +public class AddCashflowCommand extends Command{ private static final String INCOME = "income"; private static final String EXPENSE = "expense"; protected String input; - protected double value; + protected double amount; protected String type; protected int recur; - public Entry(String input) { + public AddCashflowCommand(String input) { this.input = input; } @@ -33,7 +33,7 @@ public void execute(Ui ui, CashflowList list, WatchList watchList) { this.recur = determineRecur(parameters); int indexOfAmount = parameters.indexOf("a/"); int indexOfType = parameters.indexOf("t/"); - this.value = Double.parseDouble(parameters.substring(indexOfAmount + 2, indexOfType).trim()); + this.amount = Double.parseDouble(parameters.substring(indexOfAmount + 2, indexOfType).trim()); if (recur == 0) { this.type = parameters.substring(indexOfType + 2).trim(); } else { @@ -43,10 +43,10 @@ public void execute(Ui ui, CashflowList list, WatchList watchList) { switch (entryType) { case INCOME: - list.addIncome(value, type, recur); + list.addIncome(amount, type, recur); break; case EXPENSE: - list.addExpense(value, type, recur); + list.addExpense(amount, type, recur); break; default: ui.showMessage("Unidentified entry."); diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index c571f38a72..8e87214dea 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -2,17 +2,20 @@ import seedu.financialplanner.commands.Command; -import seedu.financialplanner.commands.Entry; +import seedu.financialplanner.commands.AddCashflowCommand; +import seedu.financialplanner.commands.DeleteCashflowCommand; import seedu.financialplanner.commands.Exit; import seedu.financialplanner.commands.WatchListCommand; import seedu.financialplanner.commands.Invalid; import seedu.financialplanner.commands.AddStockCommand; import seedu.financialplanner.commands.Find; + public class Parser { private static final String EXIT_COMMAND = "exit"; private static final String WATCHLIST_COMMAND = "watchlist"; private static final String ADD_ENTRY_COMMAND = "add"; + private static final String DELETE_ENTRY_COMMAND = "delete"; private static final String ADD_STOCK_COMMAND = "addstock"; private static final String FIND_COMMAND = "find"; From 93058ea23bd016c655986c6368673c965819d4e8 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 15 Oct 2023 21:51:26 +0800 Subject: [PATCH 072/518] Rename Entry class to AddCashflowCommand class --- .../java/seedu/financialplanner/commands/EntryTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/java/seedu/financialplanner/commands/EntryTest.java b/src/test/java/seedu/financialplanner/commands/EntryTest.java index 6b8bfff11b..9ff558b9bd 100644 --- a/src/test/java/seedu/financialplanner/commands/EntryTest.java +++ b/src/test/java/seedu/financialplanner/commands/EntryTest.java @@ -14,15 +14,15 @@ class EntryTest { @Test void testExecute() { - Entry testEntry = new Entry("income a/300 t/work r/30"); + AddCashflowCommand testEntry = new AddCashflowCommand("income a/300 t/work r/30"); testEntry.execute(ui, cashflowList, watchList); - assertEquals(300, testEntry.value); + assertEquals(300, testEntry.amount); assertEquals("work", testEntry.type); assertEquals(30, testEntry.recur); - testEntry = new Entry("expense a/15 t/double mcspicy"); + testEntry = new AddCashflowCommand("expense a/15 t/double mcspicy"); testEntry.execute(ui, cashflowList, watchList); - assertEquals(15, testEntry.value); + assertEquals(15, testEntry.amount); assertEquals("double mcspicy", testEntry.type); assertEquals(0, testEntry.recur); } From b8d5f995f6592fbb2e9a0f5f9525bf27f82b527c Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 15 Oct 2023 22:25:11 +0800 Subject: [PATCH 073/518] Extract parsing method from AddCashflowCommand class to Parser class --- .../commands/AddCashflowCommand.java | 34 ++++--------------- .../seedu/financialplanner/utils/Parser.java | 33 +++++++++++++++++- .../financialplanner/commands/EntryTest.java | 29 ---------------- 3 files changed, 39 insertions(+), 57 deletions(-) delete mode 100644 src/test/java/seedu/financialplanner/commands/EntryTest.java diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index c6c9fba51d..ebef1ab45d 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -7,41 +7,21 @@ public class AddCashflowCommand extends Command{ private static final String INCOME = "income"; private static final String EXPENSE = "expense"; - protected String input; + protected String cashflowType; protected double amount; protected String type; protected int recur; - public AddCashflowCommand(String input) { - this.input = input; - } - - private int determineRecur(String parameters) { - if (parameters.contains("r/")) { - int indexOfRecur = parameters.indexOf("r/"); - String recur = parameters.substring(indexOfRecur + 2).trim(); - return Integer.parseInt(recur); - } - return 0; + public AddCashflowCommand(String cashflowType, double amount, String type, int recur) { + this.cashflowType = cashflowType; + this.amount = amount; + this.type = type; + this.recur = recur; } @Override public void execute(Ui ui, CashflowList list, WatchList watchList) { - String[] split = input.split(" ", 2); - String entryType = split[0]; - String parameters = split[1]; - this.recur = determineRecur(parameters); - int indexOfAmount = parameters.indexOf("a/"); - int indexOfType = parameters.indexOf("t/"); - this.amount = Double.parseDouble(parameters.substring(indexOfAmount + 2, indexOfType).trim()); - if (recur == 0) { - this.type = parameters.substring(indexOfType + 2).trim(); - } else { - int indexOfRecur = parameters.indexOf("r/"); - this.type = parameters.substring(indexOfType + 2, indexOfRecur).trim(); - } - - switch (entryType) { + switch (cashflowType) { case INCOME: list.addIncome(amount, type, recur); break; diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index 8e87214dea..6c96f18dfd 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -30,7 +30,9 @@ public static Command parse(String input) { case WATCHLIST_COMMAND: return new WatchListCommand(); case ADD_ENTRY_COMMAND: - return new Entry(restOfInput); + return parseAddCashflow(restOfInput); + case DELETE_ENTRY_COMMAND: + return new DeleteCashflowCommand(restOfInput); case ADD_STOCK_COMMAND: return parseAddStock(restOfInput); case FIND_COMMAND: @@ -46,4 +48,33 @@ private static Command parseAddStock(String restOfInput) { String stockCode = split[1].trim(); return new AddStockCommand(stockCode); } + private static int determineRecur(String parameters) { + if (parameters.contains("r/")) { + int indexOfRecur = parameters.indexOf("r/"); + String recur = parameters.substring(indexOfRecur + 2).trim(); + return Integer.parseInt(recur); + } + return 0; + } + public static Command parseAddCashflow(String restOfInput) { + String type; + double amount; + int recur; + + String[] split = restOfInput.split(" ", 2); + String cashflowType = split[0]; + String parameters = split[1]; + recur = determineRecur(parameters); + int indexOfAmount = parameters.indexOf("a/"); + int indexOfType = parameters.indexOf("t/"); + amount = Double.parseDouble(parameters.substring(indexOfAmount + 2, indexOfType).trim()); + if (recur == 0) { + type = parameters.substring(indexOfType + 2).trim(); + } else { + int indexOfRecur = parameters.indexOf("r/"); + type = parameters.substring(indexOfType + 2, indexOfRecur).trim(); + } + + return new AddCashflowCommand(cashflowType, amount, type, recur); + } } diff --git a/src/test/java/seedu/financialplanner/commands/EntryTest.java b/src/test/java/seedu/financialplanner/commands/EntryTest.java deleted file mode 100644 index 9ff558b9bd..0000000000 --- a/src/test/java/seedu/financialplanner/commands/EntryTest.java +++ /dev/null @@ -1,29 +0,0 @@ -package seedu.financialplanner.commands; - -import org.junit.jupiter.api.Test; -import seedu.financialplanner.investments.WatchList; -import seedu.financialplanner.list.CashflowList; -import seedu.financialplanner.utils.Ui; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -class EntryTest { - private Ui ui = Ui.INSTANCE; - private CashflowList cashflowList = CashflowList.INSTANCE; - private WatchList watchList = WatchList.INSTANCE; - - @Test - void testExecute() { - AddCashflowCommand testEntry = new AddCashflowCommand("income a/300 t/work r/30"); - testEntry.execute(ui, cashflowList, watchList); - assertEquals(300, testEntry.amount); - assertEquals("work", testEntry.type); - assertEquals(30, testEntry.recur); - - testEntry = new AddCashflowCommand("expense a/15 t/double mcspicy"); - testEntry.execute(ui, cashflowList, watchList); - assertEquals(15, testEntry.amount); - assertEquals("double mcspicy", testEntry.type); - assertEquals(0, testEntry.recur); - } -} From ef33866779c2999ab88f18d234af45c1ae46cf1c Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 15 Oct 2023 22:35:18 +0800 Subject: [PATCH 074/518] Rename list to cashflowList --- .../seedu/financialplanner/commands/AddCashflowCommand.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index ebef1ab45d..8dd18c9181 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -20,13 +20,13 @@ public AddCashflowCommand(String cashflowType, double amount, String type, int r } @Override - public void execute(Ui ui, CashflowList list, WatchList watchList) { + public void execute(Ui ui, CashflowList cashflowList, WatchList watchList) { switch (cashflowType) { case INCOME: - list.addIncome(amount, type, recur); + cashflowList.addIncome(amount, type, recur); break; case EXPENSE: - list.addExpense(amount, type, recur); + cashflowList.addExpense(amount, type, recur); break; default: ui.showMessage("Unidentified entry."); From a7b5722ca73a4b15a5c0e25b783a9fb827b30f28 Mon Sep 17 00:00:00 2001 From: YFshadaow Date: Sun, 15 Oct 2023 23:28:40 +0800 Subject: [PATCH 075/518] Refactor code: Restructure command parse logic --- .../financialplanner/FinancialPlanner.java | 14 +-- .../commands/AbstractCommand.java | 5 + .../commands/AddStockCommand.java | 23 +++- .../financialplanner/commands/Command.java | 11 -- .../financialplanner/commands/Entry.java | 56 --------- .../commands/EntryCommand.java | 67 ++++++++++ .../seedu/financialplanner/commands/Exit.java | 14 --- .../commands/ExitCommand.java | 16 +++ .../commands/{Find.java => FindCommand.java} | 35 +++--- .../financialplanner/commands/Invalid.java | 15 --- .../commands/InvalidCommand.java | 13 ++ .../financialplanner/commands/RawCommand.java | 28 +++++ .../commands/WatchListCommand.java | 19 ++- .../enumerations/EntryCategory.java | 5 + .../seedu/financialplanner/utils/Parser.java | 119 ++++++++++++------ .../financialplanner/commands/EntryTest.java | 17 +-- .../financialplanner/storage/StorageTest.java | 1 - 17 files changed, 284 insertions(+), 174 deletions(-) create mode 100644 src/main/java/seedu/financialplanner/commands/AbstractCommand.java delete mode 100644 src/main/java/seedu/financialplanner/commands/Command.java delete mode 100644 src/main/java/seedu/financialplanner/commands/Entry.java create mode 100644 src/main/java/seedu/financialplanner/commands/EntryCommand.java delete mode 100644 src/main/java/seedu/financialplanner/commands/Exit.java create mode 100644 src/main/java/seedu/financialplanner/commands/ExitCommand.java rename src/main/java/seedu/financialplanner/commands/{Find.java => FindCommand.java} (50%) delete mode 100644 src/main/java/seedu/financialplanner/commands/Invalid.java create mode 100644 src/main/java/seedu/financialplanner/commands/InvalidCommand.java create mode 100644 src/main/java/seedu/financialplanner/commands/RawCommand.java create mode 100644 src/main/java/seedu/financialplanner/enumerations/EntryCategory.java diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index 4123c0eccb..eff9c8ae17 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -1,7 +1,7 @@ package seedu.financialplanner; -import seedu.financialplanner.commands.Command; -import seedu.financialplanner.commands.Exit; +import seedu.financialplanner.commands.AbstractCommand; +import seedu.financialplanner.commands.ExitCommand; import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.list.FinancialList; @@ -33,14 +33,14 @@ public void run() { ui.welcomeMessage(); String input; - Command command = null; + AbstractCommand command = null; - while (!(command instanceof Exit)) { + while (!(command instanceof ExitCommand)) { input = ui.input(); try { - command = Parser.parse(input); - command.execute(ui, financialList, watchList); - } catch (FinancialPlannerException e) { + command = Parser.parseCommand(input); + command.execute(); + } catch (Exception e) { ui.showMessage(e.getMessage()); } } diff --git a/src/main/java/seedu/financialplanner/commands/AbstractCommand.java b/src/main/java/seedu/financialplanner/commands/AbstractCommand.java new file mode 100644 index 0000000000..83a9a0f624 --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/AbstractCommand.java @@ -0,0 +1,5 @@ +package seedu.financialplanner.commands; + +public abstract class AbstractCommand { + public abstract void execute() throws Exception; +} diff --git a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java index 94278ba62c..aa7559480e 100644 --- a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java @@ -2,19 +2,30 @@ import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.investments.WatchList; -import seedu.financialplanner.list.FinancialList; import seedu.financialplanner.utils.Ui; -public class AddStockCommand extends Command { +import java.util.ArrayList; + +public class AddStockCommand extends AbstractCommand { private final String stockCode; - public AddStockCommand(String stockCode) { - this.stockCode = stockCode; + public AddStockCommand(RawCommand rawCommand) throws IllegalArgumentException { + if (!rawCommand.extraArgs.containsKey("s")) { + throw new IllegalArgumentException("Stock code cannot be empty"); + } + stockCode = rawCommand.extraArgs.get("s"); + rawCommand.extraArgs.remove("s"); + if (!rawCommand.extraArgs.isEmpty()) { + String unknownExtraArgument = new ArrayList<>(rawCommand.extraArgs.keySet()).get(0); + throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); + } } @Override - public void execute(Ui ui, FinancialList financialList, WatchList watchList) { - String stockName = null; + public void execute() { + Ui ui = Ui.INSTANCE; + WatchList watchList = WatchList.INSTANCE; + String stockName; try { stockName = watchList.addStock(stockCode); ui.printAddStock(stockName); diff --git a/src/main/java/seedu/financialplanner/commands/Command.java b/src/main/java/seedu/financialplanner/commands/Command.java deleted file mode 100644 index cfa92f08d7..0000000000 --- a/src/main/java/seedu/financialplanner/commands/Command.java +++ /dev/null @@ -1,11 +0,0 @@ -package seedu.financialplanner.commands; - -import seedu.financialplanner.exceptions.FinancialPlannerException; -import seedu.financialplanner.investments.WatchList; -import seedu.financialplanner.utils.Ui; -import seedu.financialplanner.list.FinancialList; - -public class Command { - public void execute(Ui ui, FinancialList financialList, WatchList watchList) throws FinancialPlannerException { - } -} diff --git a/src/main/java/seedu/financialplanner/commands/Entry.java b/src/main/java/seedu/financialplanner/commands/Entry.java deleted file mode 100644 index 8d6feee45e..0000000000 --- a/src/main/java/seedu/financialplanner/commands/Entry.java +++ /dev/null @@ -1,56 +0,0 @@ -package seedu.financialplanner.commands; - -import seedu.financialplanner.investments.WatchList; -import seedu.financialplanner.list.FinancialList; -import seedu.financialplanner.utils.Ui; - -public class Entry extends Command{ - private static final String INCOME = "income"; - private static final String EXPENSE = "expense"; - protected String input; - protected double value; - protected String type; - protected int recur; - - public Entry(String input) { - this.input = input; - } - - private int determineRecur(String parameters) { - if (parameters.contains("r/")) { - int indexOfRecur = parameters.indexOf("r/"); - String recur = parameters.substring(indexOfRecur + 2).trim(); - return Integer.parseInt(recur); - } - return 0; - } - - @Override - public void execute(Ui ui, FinancialList list, WatchList watchList) { - String[] split = input.split(" ", 2); - String entryType = split[0]; - String parameters = split[1]; - this.recur = determineRecur(parameters); - int indexOfAmount = parameters.indexOf("a/"); - int indexOfType = parameters.indexOf("t/"); - this.value = Double.parseDouble(parameters.substring(indexOfAmount + 2, indexOfType).trim()); - if (recur == 0) { - this.type = parameters.substring(indexOfType + 2).trim(); - } else { - int indexOfRecur = parameters.indexOf("r/"); - this.type = parameters.substring(indexOfType + 2, indexOfRecur).trim(); - } - - switch (entryType) { - case INCOME: - list.addIncome(value, type, recur); - break; - case EXPENSE: - list.addExpense(value, type, recur); - break; - default: - ui.showMessage("Unidentified entry."); - break; - } - } -} diff --git a/src/main/java/seedu/financialplanner/commands/EntryCommand.java b/src/main/java/seedu/financialplanner/commands/EntryCommand.java new file mode 100644 index 0000000000..10eeb04206 --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/EntryCommand.java @@ -0,0 +1,67 @@ +package seedu.financialplanner.commands; + +import seedu.financialplanner.enumerations.EntryCategory; +import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.utils.Ui; + +import java.util.ArrayList; + +public class EntryCommand extends AbstractCommand { + protected double amount; + protected EntryCategory category; + protected String type; + protected int recur = 0; + + public EntryCommand(RawCommand rawCommand) throws IllegalArgumentException { + String typeString = String.join(" ", rawCommand.args); + try { + category = EntryCategory.valueOf(typeString.toUpperCase()); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Entry must be either income or expense"); + } + + if (!rawCommand.extraArgs.containsKey("a")) { + throw new IllegalArgumentException("Entry must have an amount"); + } + try { + amount = Double.parseDouble(rawCommand.extraArgs.get("a")); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Amount must be a number"); + } + rawCommand.extraArgs.remove("a"); + + if (!rawCommand.extraArgs.containsKey("t")) { + throw new IllegalArgumentException("Entry must have a type"); + } + type = rawCommand.extraArgs.get("t"); + rawCommand.extraArgs.remove("t"); + + if (rawCommand.extraArgs.containsKey("r")) { + try { + recur = Integer.parseInt(rawCommand.extraArgs.get("r")); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Recurrence must be an integer"); + } + rawCommand.extraArgs.remove("r"); + } + if (!rawCommand.extraArgs.isEmpty()) { + String unknownExtraArgument = new ArrayList<>(rawCommand.extraArgs.keySet()).get(0); + throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); + } + } + + @Override + public void execute() { + switch (category) { + case INCOME: + FinancialList.INSTANCE.addIncome(amount, type, recur); + break; + case EXPENSE: + FinancialList.INSTANCE.addExpense(amount, type, recur); + break; + default: + Ui.INSTANCE.showMessage("Unidentified entry."); + break; + } + } +} diff --git a/src/main/java/seedu/financialplanner/commands/Exit.java b/src/main/java/seedu/financialplanner/commands/Exit.java deleted file mode 100644 index fe214ca1fb..0000000000 --- a/src/main/java/seedu/financialplanner/commands/Exit.java +++ /dev/null @@ -1,14 +0,0 @@ -package seedu.financialplanner.commands; - -import seedu.financialplanner.investments.WatchList; -import seedu.financialplanner.list.FinancialList; -import seedu.financialplanner.utils.Ui; - -public class Exit extends Command { - public Exit() { - } - - @Override - public void execute(Ui ui, FinancialList financialList, WatchList watchList) { - } -} diff --git a/src/main/java/seedu/financialplanner/commands/ExitCommand.java b/src/main/java/seedu/financialplanner/commands/ExitCommand.java new file mode 100644 index 0000000000..1dbfd24cf5 --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/ExitCommand.java @@ -0,0 +1,16 @@ +package seedu.financialplanner.commands; + +import java.util.ArrayList; + +public class ExitCommand extends AbstractCommand { + public ExitCommand(RawCommand rawCommand) { + if (!rawCommand.extraArgs.isEmpty()) { + String unknownExtraArgument = new ArrayList<>(rawCommand.extraArgs.keySet()).get(0); + throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); + } + } + + @Override + public void execute() { + } +} diff --git a/src/main/java/seedu/financialplanner/commands/Find.java b/src/main/java/seedu/financialplanner/commands/FindCommand.java similarity index 50% rename from src/main/java/seedu/financialplanner/commands/Find.java rename to src/main/java/seedu/financialplanner/commands/FindCommand.java index 32ee443c87..9225704a20 100644 --- a/src/main/java/seedu/financialplanner/commands/Find.java +++ b/src/main/java/seedu/financialplanner/commands/FindCommand.java @@ -6,42 +6,49 @@ import java.util.ArrayList; -public class Find extends Command{ +public class FindCommand extends AbstractCommand { private final String description; - public Find(String description) { - this.description = description; + public FindCommand(RawCommand rawCommand) { + this.description = String.join(" ", rawCommand.args); + if (!rawCommand.extraArgs.isEmpty()) { + String unknownExtraArgument = new ArrayList<>(rawCommand.extraArgs.keySet()).get(0); + throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); + } } @Override - public void execute(Ui ui, FinancialList financialList, WatchList watchList) { + public void execute() { + FinancialList financialList = FinancialList.INSTANCE; + Ui ui = Ui.INSTANCE; + WatchList watchList = WatchList.INSTANCE; ArrayList foundedFinancialList = new ArrayList<>(); ArrayList foundedWatchList = new ArrayList<>(); - for(int i = 0; i < financialList.size(); i++) { - if(financialList.get(i).formatString().contains(description)) { + for (int i = 0; i < financialList.size(); i++) { + if (financialList.get(i).formatString().contains(description)) { foundedFinancialList.add(financialList.get(i).formatString()); } } - if(!foundedFinancialList.isEmpty()){ + if (!foundedFinancialList.isEmpty()) { ui.showMessage("Here are the matching financial records in your financial list:"); - }else{ + } else { ui.showMessage("There is no matching financial record in your financial list."); } - for(String foundedFinancialRecord : foundedFinancialList) { + for (String foundedFinancialRecord : foundedFinancialList) { ui.showMessage(foundedFinancialRecord); } - for(int i = 0; i < watchList.size(); i++) { - if(watchList.get(i).toString().contains(description)) { + for (int i = 0; i < watchList.size(); i++) { + if (watchList.get(i).toString().contains(description)) { foundedWatchList.add(watchList.get(i).toString()); } } - if(!foundedWatchList.isEmpty()) { + if (!foundedWatchList.isEmpty()) { ui.showMessage("Here are the matching stock records in your stock list:"); - }else{ + } else { ui.showMessage("There is no matching stock record in your stock list."); } - for(String foundedStockRecord : foundedWatchList) { + for (String foundedStockRecord : foundedWatchList) { ui.showMessage(foundedStockRecord); } } diff --git a/src/main/java/seedu/financialplanner/commands/Invalid.java b/src/main/java/seedu/financialplanner/commands/Invalid.java deleted file mode 100644 index 5a081a375b..0000000000 --- a/src/main/java/seedu/financialplanner/commands/Invalid.java +++ /dev/null @@ -1,15 +0,0 @@ -package seedu.financialplanner.commands; - -import seedu.financialplanner.investments.WatchList; -import seedu.financialplanner.list.FinancialList; -import seedu.financialplanner.utils.Ui; - -public class Invalid extends Command { - public Invalid() { - } - - @Override - public void execute(Ui ui, FinancialList financialList, WatchList watchList) { - ui.showMessage("Unknown command. Please try again."); - } -} diff --git a/src/main/java/seedu/financialplanner/commands/InvalidCommand.java b/src/main/java/seedu/financialplanner/commands/InvalidCommand.java new file mode 100644 index 0000000000..07902d8da4 --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/InvalidCommand.java @@ -0,0 +1,13 @@ +package seedu.financialplanner.commands; + +import seedu.financialplanner.utils.Ui; + +public class InvalidCommand extends AbstractCommand { + public InvalidCommand() { + } + + @Override + public void execute() { + Ui.INSTANCE.showMessage("Unknown command. Please try again."); + } +} diff --git a/src/main/java/seedu/financialplanner/commands/RawCommand.java b/src/main/java/seedu/financialplanner/commands/RawCommand.java new file mode 100644 index 0000000000..ac6e3800be --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/RawCommand.java @@ -0,0 +1,28 @@ +package seedu.financialplanner.commands; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class RawCommand { + public final List args = new ArrayList<>(); + public final Map extraArgs = new HashMap<>(); + protected String commandName; + + public RawCommand(String name, List args, Map extraArgs) { + this.commandName = name; + this.args.addAll(args); + this.extraArgs.putAll(extraArgs); + } + + @SuppressWarnings("unused") + public String getCommandName() { + return commandName; + } + + @SuppressWarnings("unused") + public void setCommandName(String commandName) { + this.commandName = commandName; + } +} diff --git a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java index 0b6d427938..b549e560e9 100644 --- a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java @@ -3,17 +3,24 @@ import org.json.simple.JSONArray; import org.json.simple.JSONObject; import seedu.financialplanner.investments.WatchList; -import seedu.financialplanner.list.FinancialList; import seedu.financialplanner.utils.Ui; -public class WatchListCommand extends Command { +import java.util.ArrayList; + +public class WatchListCommand extends AbstractCommand { + public WatchListCommand(RawCommand rawCommand) throws IllegalArgumentException{ + if (!rawCommand.extraArgs.isEmpty()) { + String unknownExtraArgument = new ArrayList<>(rawCommand.extraArgs.keySet()).get(0); + throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); + } + } @Override - public void execute(Ui ui, FinancialList financialList, WatchList watchList) { - JSONArray stocks = watchList.fetchFMPStockPrices(); - ui.printWatchListHeader(); + public void execute() { + JSONArray stocks = WatchList.INSTANCE.fetchFMPStockPrices(); + Ui.INSTANCE.printWatchListHeader(); for (Object o : stocks) { JSONObject stock = (JSONObject) o; - ui.printStockInfo(stock); + Ui.INSTANCE.printStockInfo(stock); } } } diff --git a/src/main/java/seedu/financialplanner/enumerations/EntryCategory.java b/src/main/java/seedu/financialplanner/enumerations/EntryCategory.java new file mode 100644 index 0000000000..14bcbcb2b9 --- /dev/null +++ b/src/main/java/seedu/financialplanner/enumerations/EntryCategory.java @@ -0,0 +1,5 @@ +package seedu.financialplanner.enumerations; + +public enum EntryCategory { + INCOME, EXPENSE +} diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index c571f38a72..62fec2994c 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -1,46 +1,93 @@ package seedu.financialplanner.utils; +import seedu.financialplanner.commands.*; -import seedu.financialplanner.commands.Command; -import seedu.financialplanner.commands.Entry; -import seedu.financialplanner.commands.Exit; -import seedu.financialplanner.commands.WatchListCommand; -import seedu.financialplanner.commands.Invalid; -import seedu.financialplanner.commands.AddStockCommand; -import seedu.financialplanner.commands.Find; +import java.util.*; public class Parser { - private static final String EXIT_COMMAND = "exit"; - private static final String WATCHLIST_COMMAND = "watchlist"; - private static final String ADD_ENTRY_COMMAND = "add"; - private static final String ADD_STOCK_COMMAND = "addstock"; - private static final String FIND_COMMAND = "find"; - - public static Command parse(String input) { - String[] split = input.split(" ", 2); - String command = split[0].toLowerCase(); - String restOfInput = split.length > 1 ? split[1] : ""; // checks if rest of input is empty - - switch (command) { - case EXIT_COMMAND: - return new Exit(); - case WATCHLIST_COMMAND: - return new WatchListCommand(); - case ADD_ENTRY_COMMAND: - return new Entry(restOfInput); - case ADD_STOCK_COMMAND: - return parseAddStock(restOfInput); - case FIND_COMMAND: - return new Find(restOfInput); - default: - return new Invalid(); + private static final String EXIT_COMMAND_NAME = "exit"; + private static final String WATCHLIST_COMMAND_NAME = "watchlist"; + private static final String ADD_ENTRY_COMMAND_NAME = "add"; + private static final String ADD_STOCK_COMMAND_NAME = "addstock"; + private static final String FIND_COMMAND_NAME = "find"; + + public static AbstractCommand parseCommand(String input) throws IllegalArgumentException { + RawCommand rawCommand = parseRawCommand(input); + return parseCommand(rawCommand); + } + + public static RawCommand parseRawCommand(String input) throws IllegalArgumentException{ + Iterator iterator = Arrays.stream(input.split(" ")).iterator(); + if (!iterator.hasNext()) { + throw new IllegalArgumentException("Command cannot be empty"); + } + String commandName = iterator.next(); + List args = new ArrayList<>(); + Map extraArgs = new HashMap<>(); + + List extraArgumentContentBuffer = new ArrayList<>(); + String currentExtraArgumentName = null; + + while (iterator.hasNext()) { + String next = iterator.next(); + if (next.startsWith("/")) { + // Save previous extra argument when next extra argument is found + if (currentExtraArgumentName != null) { + if (extraArgs.containsKey(currentExtraArgumentName)) { + throw new IllegalArgumentException(String.format("Duplicate extra argument name: %s", currentExtraArgumentName)); + } else { + extraArgs.put(currentExtraArgumentName, String.join(" ", extraArgumentContentBuffer)); + extraArgumentContentBuffer.clear(); + } + } + + if (next.length() == 1) { + throw new IllegalArgumentException("Extra argument name cannot be empty"); + } + + currentExtraArgumentName =next.substring(1); + + } else { + if (currentExtraArgumentName == null) { + args.add(next); + } else { + extraArgumentContentBuffer.add(next); + } + } } + // Save previous extra argument at the very end + if (currentExtraArgumentName != null) { + if (extraArgs.containsKey(currentExtraArgumentName)) { + throw new IllegalArgumentException(String.format("Duplicate extra argument name: %s", currentExtraArgumentName)); + } else { + extraArgs.put(currentExtraArgumentName, String.join(" ", extraArgumentContentBuffer)); + extraArgumentContentBuffer.clear(); + } + } + + return new RawCommand(commandName, args, extraArgs); } - private static Command parseAddStock(String restOfInput) { - String[] split = restOfInput.trim().split("s/"); - // TODO: check error here - String stockCode = split[1].trim(); - return new AddStockCommand(stockCode); + public static AbstractCommand parseCommand(RawCommand rawCommand) throws IllegalArgumentException{ + switch (rawCommand.getCommandName()) { + case EXIT_COMMAND_NAME: { + return new ExitCommand(rawCommand); + } + case WATCHLIST_COMMAND_NAME: { + return new WatchListCommand(rawCommand); + } + case ADD_ENTRY_COMMAND_NAME: { + return new EntryCommand(rawCommand); + } + case ADD_STOCK_COMMAND_NAME: { + return new AddStockCommand(rawCommand); + } + case FIND_COMMAND_NAME: { + return new FindCommand(rawCommand); + } + default: { + return new InvalidCommand(); + } + } } } diff --git a/src/test/java/seedu/financialplanner/commands/EntryTest.java b/src/test/java/seedu/financialplanner/commands/EntryTest.java index 682880db27..ed174a41a4 100644 --- a/src/test/java/seedu/financialplanner/commands/EntryTest.java +++ b/src/test/java/seedu/financialplanner/commands/EntryTest.java @@ -3,6 +3,7 @@ import org.junit.jupiter.api.Test; import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.utils.Parser; import seedu.financialplanner.utils.Ui; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -14,16 +15,16 @@ class EntryTest { @Test void testExecute() { - Entry testEntry = new Entry("income a/300 t/work r/30"); - testEntry.execute(ui, financialList, watchList); - assertEquals(300, testEntry.value); - assertEquals("work", testEntry.type); + EntryCommand testEntry = new EntryCommand(Parser.parseRawCommand("add income /a 300 /t work /r 30")); + testEntry.execute(); + assertEquals(300, testEntry.amount); + assertEquals("work", testEntry.category); assertEquals(30, testEntry.recur); - testEntry = new Entry("expense a/15 t/double mcspicy"); - testEntry.execute(ui, financialList, watchList); - assertEquals(15, testEntry.value); - assertEquals("double mcspicy", testEntry.type); + testEntry = new EntryCommand(Parser.parseRawCommand("add expense /a 15 /t double_mcspicy")); + testEntry.execute(); + assertEquals(15, testEntry.amount); + assertEquals("double_mcspicy", testEntry.category); assertEquals(0, testEntry.recur); } } diff --git a/src/test/java/seedu/financialplanner/storage/StorageTest.java b/src/test/java/seedu/financialplanner/storage/StorageTest.java index 342752e726..2342e3d32f 100644 --- a/src/test/java/seedu/financialplanner/storage/StorageTest.java +++ b/src/test/java/seedu/financialplanner/storage/StorageTest.java @@ -8,7 +8,6 @@ import seedu.financialplanner.list.Income; import seedu.financialplanner.utils.Ui; - import java.io.ByteArrayInputStream; import java.io.IOException; import java.nio.file.Files; From 6b30cdad90948467b5fe2cd12651aa04467304a5 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 15 Oct 2023 23:30:02 +0800 Subject: [PATCH 076/518] Add delete income/expense functionality --- .../commands/DeleteCashflowCommand.java | 29 +++++++ .../seedu/financialplanner/list/Cashflow.java | 9 +- .../financialplanner/list/CashflowList.java | 84 ++++++++++++------- .../seedu/financialplanner/list/Expense.java | 11 ++- .../seedu/financialplanner/list/Income.java | 12 ++- .../seedu/financialplanner/utils/Parser.java | 27 ++++-- .../java/seedu/financialplanner/utils/Ui.java | 5 +- 7 files changed, 128 insertions(+), 49 deletions(-) create mode 100644 src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java diff --git a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java new file mode 100644 index 0000000000..21fa0c7b38 --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java @@ -0,0 +1,29 @@ +package seedu.financialplanner.commands; + +import seedu.financialplanner.investments.WatchList; +import seedu.financialplanner.list.CashflowList; +import seedu.financialplanner.utils.Ui; + +public class DeleteCashflowCommand extends Command{ + protected String cashflowType; + protected int index; + + public DeleteCashflowCommand(String cashflowType, int index) { + this.cashflowType = cashflowType; + this.index = index; + } + + public DeleteCashflowCommand(int index) { + this.cashflowType = "empty"; + this.index = index; + } + + @Override + public void execute(Ui ui, CashflowList cashflowList, WatchList watchList) { + if (cashflowType.contains("empty")) { + cashflowList.delete(index); + } else { + cashflowList.deleteCashflow(cashflowType, index); + } + } +} diff --git a/src/main/java/seedu/financialplanner/list/Cashflow.java b/src/main/java/seedu/financialplanner/list/Cashflow.java index 2df5dccc89..1f135bb351 100644 --- a/src/main/java/seedu/financialplanner/list/Cashflow.java +++ b/src/main/java/seedu/financialplanner/list/Cashflow.java @@ -16,7 +16,8 @@ public Cashflow(double amount, String type, int recur) { this.type = type; this.recur = recur; } - + public void deleteCashflowvalue() { + } public Cashflow() { this.amount = 0; this.type = null; @@ -37,11 +38,11 @@ public double round(double value, int places) { public String toString() { DecimalFormat decimalFormat = new DecimalFormat("####0.00"); - String string = "Type: " + type + System.lineSeparator() - + "Amount:" + decimalFormat.format(round(amount, 2)); + String string = " Type: " + type + System.lineSeparator() + + " Amount: " + decimalFormat.format(round(amount, 2)); if (recur != 0) { - string += System.lineSeparator() + "Recurring every: " + recur + "days."; + string += System.lineSeparator() + " Recurring every: " + recur + " days"; } return string; diff --git a/src/main/java/seedu/financialplanner/list/CashflowList.java b/src/main/java/seedu/financialplanner/list/CashflowList.java index f6e7c462ae..9eabac8cba 100644 --- a/src/main/java/seedu/financialplanner/list/CashflowList.java +++ b/src/main/java/seedu/financialplanner/list/CashflowList.java @@ -2,9 +2,6 @@ import seedu.financialplanner.utils.Ui; -import java.math.BigDecimal; -import java.math.RoundingMode; -import java.text.DecimalFormat; import java.util.ArrayList; public class CashflowList { @@ -15,42 +12,17 @@ public class CashflowList { private CashflowList() { } - private void printAddedCashflow(String line) { - DecimalFormat decimalFormat = new DecimalFormat("####0.00"); - - Cashflow cashflow = get(list.size() - 1); - System.out.print("Added " + line + " of value: "); - System.out.println(decimalFormat.format(round(cashflow.value, 2)) + " to the list."); - System.out.println("type: " + cashflow.type); - if (cashflow.recur != 0) { - System.out.println("recurring every: " + cashflow.recur + " days"); - } - System.out.println("balance: " + decimalFormat.format(round(Cashflow.balance, 2))); - } - - //@author mhadidg-reused - //Reused from https://stackoverflow.com/questions/2808535/round-a-double-to-2-decimal-places - public double round(double value, int places) { - if (places < 0) { - throw new IllegalArgumentException(); - } - - BigDecimal bd = BigDecimal.valueOf(value); - bd = bd.setScale(places, RoundingMode.HALF_UP); - return bd.doubleValue(); - } - //@author mhadidg public void addIncome(double value, String type, int recur) { Income toAdd = new Income(value, type, recur); list.add(toAdd); - printAddedCashflow("income"); + Ui.INSTANCE.printAddedCashflow(toAdd); } public void addExpense(double value, String type, int recur) { Expense toAdd = new Expense(value, type, recur); list.add(toAdd); - printAddedCashflow("expense"); + Ui.INSTANCE.printAddedCashflow(toAdd); } public void delete(int index) { @@ -58,14 +30,62 @@ public void delete(int index) { Cashflow toRemove = get(listIndex); list.remove(listIndex); + Cashflow.balance -= toRemove.amount; Ui.INSTANCE.printDeletedCashflow(toRemove); } + //helper method to find the index of a given cashflow in the overall list + //given its index in its respective list. e.g. "income 3" is the third income + //in the overall list + private int cashflowIndexFinder(String type, int cashflowIndex) { + + switch (type) { + case "income": + return findCashflowIndexFromIncomeIndex(cashflowIndex); + case "expense": + return findCashflowIndexFromExpenseIndex(cashflowIndex); + default: + return -1; + } + } - public void deleteIncome(int index) { - int listIndex = index - 1; + private int findCashflowIndexFromIncomeIndex(int cashflowIndex) { + int cashflowCounter = 0; + int overallCashflowIndex = 0; + + for (Cashflow entry : list) { + if (entry instanceof Income) { + cashflowCounter += 1; + } + if (cashflowCounter == cashflowIndex) { + break; + } + overallCashflowIndex += 1; + } + return overallCashflowIndex; + } + + private int findCashflowIndexFromExpenseIndex(int cashflowIndex) { + int cashflowCounter = 0; + int overallCashflowIndex = 0; + + for (Cashflow entry : list) { + if (entry instanceof Expense) { + cashflowCounter += 1; + } + if (cashflowCounter == cashflowIndex) { + break; + } + overallCashflowIndex += 1; + } + return overallCashflowIndex; + } + + public void deleteCashflow(String cashflowType, int index) { + int listIndex = cashflowIndexFinder(cashflowType, index); Cashflow toRemove = get(listIndex); list.remove(listIndex); + Cashflow.balance -= toRemove.amount; Ui.INSTANCE.printDeletedCashflow(toRemove); } diff --git a/src/main/java/seedu/financialplanner/list/Expense.java b/src/main/java/seedu/financialplanner/list/Expense.java index 7230fcac13..aaa30375c1 100644 --- a/src/main/java/seedu/financialplanner/list/Expense.java +++ b/src/main/java/seedu/financialplanner/list/Expense.java @@ -3,11 +3,16 @@ public class Expense extends Cashflow { public Expense(double amount, String type, int recur) { super(amount, type, recur); - addIncomeValue(amount); + addExpenseValue(); } - private void addIncomeValue(double value) { - balance -= value; + private void addExpenseValue() { + balance -= this.amount; + } + + @Override + public void deleteCashflowvalue() { + balance += this.amount; } @Override diff --git a/src/main/java/seedu/financialplanner/list/Income.java b/src/main/java/seedu/financialplanner/list/Income.java index ac86d6162c..41f6888998 100644 --- a/src/main/java/seedu/financialplanner/list/Income.java +++ b/src/main/java/seedu/financialplanner/list/Income.java @@ -3,12 +3,18 @@ public class Income extends Cashflow{ public Income(double amount, String type, int recur) { super(amount, type, recur); - addIncomeValue(amount); + addIncomeValue(); } - private void addIncomeValue(double value) { - balance += value; + private void addIncomeValue() { + balance += this.amount; } + + @Override + public void deleteCashflowvalue() { + balance -= this.amount; + } + @Override public String toString() { return "Income" + System.lineSeparator() + super.toString(); diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index 6c96f18dfd..dc53cc119a 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -14,8 +14,8 @@ public class Parser { private static final String EXIT_COMMAND = "exit"; private static final String WATCHLIST_COMMAND = "watchlist"; - private static final String ADD_ENTRY_COMMAND = "add"; - private static final String DELETE_ENTRY_COMMAND = "delete"; + private static final String ADD_CASHFLOW_COMMAND = "add"; + private static final String DELETE_CASHFLOW_COMMAND = "delete"; private static final String ADD_STOCK_COMMAND = "addstock"; private static final String FIND_COMMAND = "find"; @@ -29,10 +29,10 @@ public static Command parse(String input) { return new Exit(); case WATCHLIST_COMMAND: return new WatchListCommand(); - case ADD_ENTRY_COMMAND: + case ADD_CASHFLOW_COMMAND: return parseAddCashflow(restOfInput); - case DELETE_ENTRY_COMMAND: - return new DeleteCashflowCommand(restOfInput); + case DELETE_CASHFLOW_COMMAND: + return parseDeleteCashflow(restOfInput); case ADD_STOCK_COMMAND: return parseAddStock(restOfInput); case FIND_COMMAND: @@ -77,4 +77,21 @@ public static Command parseAddCashflow(String restOfInput) { return new AddCashflowCommand(cashflowType, amount, type, recur); } + + public static Command parseDeleteCashflow(String restOfInput) { + String[] split = restOfInput.split(" ", 2); + + if (split.length == 1) { + String stringIndex = split[0].trim(); + int index = Integer.parseInt(stringIndex); + + return new DeleteCashflowCommand(index); + } + + String cashflowType = split[0]; + String stringIndex = split[1].trim(); + int index = Integer.parseInt(stringIndex); + + return new DeleteCashflowCommand(cashflowType, index); + } } diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 4b5890a2a0..8105471972 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -56,15 +56,16 @@ public void printAddStock(String stockName) { } public void printAddedCashflow(Cashflow entry) { - System.out.println("You have added:"); + System.out.print("You have added an "); System.out.println(entry); System.out.println("to the Financial Planner."); System.out.println("Balance: " + entry.formatBalance()); } public void printDeletedCashflow(Cashflow entry) { - System.out.println("You have removed:"); + System.out.print("You have removed an "); System.out.println(entry); System.out.println("from the Financial Planner."); + System.out.println("Balance: " + entry.formatBalance()); } } From 38dbc030b566522fd0f329ba247221284b2ed4af Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 15 Oct 2023 23:37:23 +0800 Subject: [PATCH 077/518] Add JUnit testing --- .../seedu/financialplanner/list/Cashflow.java | 2 +- .../financialplanner/list/CashflowList.java | 4 +- .../list/CashflowListTest.java | 39 +++++++++++++++---- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/main/java/seedu/financialplanner/list/Cashflow.java b/src/main/java/seedu/financialplanner/list/Cashflow.java index 1f135bb351..bf1d2c398d 100644 --- a/src/main/java/seedu/financialplanner/list/Cashflow.java +++ b/src/main/java/seedu/financialplanner/list/Cashflow.java @@ -25,7 +25,7 @@ public Cashflow() { } //@author mhadidg-reused //Reused from https://stackoverflow.com/questions/2808535/round-a-double-to-2-decimal-places - public double round(double value, int places) { + public static double round(double value, int places) { if (places < 0) { throw new IllegalArgumentException(); } diff --git a/src/main/java/seedu/financialplanner/list/CashflowList.java b/src/main/java/seedu/financialplanner/list/CashflowList.java index 9eabac8cba..add574b575 100644 --- a/src/main/java/seedu/financialplanner/list/CashflowList.java +++ b/src/main/java/seedu/financialplanner/list/CashflowList.java @@ -30,7 +30,7 @@ public void delete(int index) { Cashflow toRemove = get(listIndex); list.remove(listIndex); - Cashflow.balance -= toRemove.amount; + toRemove.deleteCashflowvalue(); Ui.INSTANCE.printDeletedCashflow(toRemove); } //helper method to find the index of a given cashflow in the overall list @@ -85,7 +85,7 @@ public void deleteCashflow(String cashflowType, int index) { Cashflow toRemove = get(listIndex); list.remove(listIndex); - Cashflow.balance -= toRemove.amount; + toRemove.deleteCashflowvalue(); Ui.INSTANCE.printDeletedCashflow(toRemove); } diff --git a/src/test/java/seedu/financialplanner/list/CashflowListTest.java b/src/test/java/seedu/financialplanner/list/CashflowListTest.java index e8bfc52f15..015cfc821c 100644 --- a/src/test/java/seedu/financialplanner/list/CashflowListTest.java +++ b/src/test/java/seedu/financialplanner/list/CashflowListTest.java @@ -15,8 +15,8 @@ void testAddIncomeAndExpense() { Cashflow.balance = 0; testList.addIncome(15, "work", 30); Cashflow testIncome = testList.list.get(0); - double roundedValue = testIncome.round(testIncome.amount, 2); - double roundedBalance = testIncome.round(Cashflow.balance, 2); + double roundedValue = Cashflow.round(testIncome.amount, 2); + double roundedBalance = Cashflow.round(Cashflow.balance, 2); assertTrue(testIncome instanceof Income); assertEquals("15.00", decimalFormat.format(roundedValue)); assertEquals("work", testIncome.type); @@ -25,8 +25,8 @@ void testAddIncomeAndExpense() { testList.addIncome(15.999, "rate of returns", 0); testIncome = testList.list.get(1); - roundedValue = testIncome.round(testIncome.amount, 2); - roundedBalance = testIncome.round(Cashflow.balance, 2); + roundedValue = Cashflow.round(testIncome.amount, 2); + roundedBalance = Cashflow.round(Cashflow.balance, 2); assertTrue(testIncome instanceof Income); assertEquals("16.00", decimalFormat.format(roundedValue)); assertEquals("rate of returns", testIncome.type); @@ -35,8 +35,8 @@ void testAddIncomeAndExpense() { testList.addExpense(10, "lunch", 0); Cashflow testExpense = testList.list.get(2); - roundedValue = testExpense.round(testExpense.amount, 2); - roundedBalance = testExpense.round(Cashflow.balance, 2); + roundedValue = Cashflow.round(testExpense.amount, 2); + roundedBalance = Cashflow.round(Cashflow.balance, 2); assertTrue(testExpense instanceof Expense); assertEquals("10.00", decimalFormat.format(roundedValue)); assertEquals("lunch", testExpense.type); @@ -45,12 +45,35 @@ void testAddIncomeAndExpense() { testList.addExpense(19.999, "Apple Music", 30); testExpense = testList.list.get(3); - roundedValue = testExpense.round(testExpense.amount, 2); - roundedBalance = testExpense.round(Cashflow.balance, 2); + roundedValue = Cashflow.round(testExpense.amount, 2); + roundedBalance = Cashflow.round(Cashflow.balance, 2); assertTrue(testExpense instanceof Expense); assertEquals("20.00", decimalFormat.format(roundedValue)); assertEquals("Apple Music", testExpense.type); assertEquals(30, testExpense.recur); assertEquals("1.00", decimalFormat.format(roundedBalance)); } + + @Test + void testDeleteIncomeAndExpense() { + testList.deleteCashflow("income", 2); + assertEquals(3, testList.size()); + double roundedBalance = Cashflow.round(Cashflow.balance, 2); + assertEquals("-15.00", decimalFormat.format(roundedBalance)); + + testList.delete(1); + assertEquals(2, testList.size()); + roundedBalance = Cashflow.round(Cashflow.balance, 2); + assertEquals("-30.00", decimalFormat.format(roundedBalance)); + + testList.deleteCashflow("expense", 2); + assertEquals(1, testList.size()); + roundedBalance = Cashflow.round(Cashflow.balance, 2); + assertEquals("-10.00", decimalFormat.format(roundedBalance)); + + testList.delete(1); + assertEquals(0, testList.size()); + roundedBalance = Cashflow.round(Cashflow.balance, 2); + assertEquals("0.00", decimalFormat.format(roundedBalance)); + } } From 763e137a04d856abc406e8795f0bf5f91d904d1e Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 15 Oct 2023 23:41:39 +0800 Subject: [PATCH 078/518] Remove unnecessary classes --- .../visualisations/PieChartVisual.java | 26 ------------------- .../visualisations/Visual.java | 5 ---- 2 files changed, 31 deletions(-) delete mode 100644 src/main/java/seedu/financialplanner/visualisations/PieChartVisual.java delete mode 100644 src/main/java/seedu/financialplanner/visualisations/Visual.java diff --git a/src/main/java/seedu/financialplanner/visualisations/PieChartVisual.java b/src/main/java/seedu/financialplanner/visualisations/PieChartVisual.java deleted file mode 100644 index 3175bc3850..0000000000 --- a/src/main/java/seedu/financialplanner/visualisations/PieChartVisual.java +++ /dev/null @@ -1,26 +0,0 @@ -package seedu.financialplanner.visualisations; - -import org.knowm.xchart.*; - -import java.awt.*; - -public class PieChartVisual extends Visual { - public void displayPieChart () { - PieChart chart = new PieChartBuilder().width(800).height(600).title("Test").build(); - - // Customize Chart - Color[] sliceColors = new Color[] { new Color(224, 68, 14), new Color(230, 105, 62), new Color(236, 143, 110), new Color(243, 180, 159), new Color(246, 199, 182) }; - chart.getStyler().setSeriesColors(sliceColors); - - // Series - chart.addSeries("Gold", 24); - chart.addSeries("Silver", 21); - chart.addSeries("Platinum", 39); - chart.addSeries("Copper", 17); - chart.addSeries("Zinc", 40); - - // Show it - new SwingWrapper<>(chart).displayChart(); - } - -} diff --git a/src/main/java/seedu/financialplanner/visualisations/Visual.java b/src/main/java/seedu/financialplanner/visualisations/Visual.java deleted file mode 100644 index 3fab8f35c3..0000000000 --- a/src/main/java/seedu/financialplanner/visualisations/Visual.java +++ /dev/null @@ -1,5 +0,0 @@ -package seedu.financialplanner.visualisations; - - -public abstract class Visual { -} From d03b9438f621db15a83610c3ce199c6ee840675c Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 15 Oct 2023 23:42:10 +0800 Subject: [PATCH 079/518] Add getters for cashflow type and value --- .../java/seedu/financialplanner/FinancialPlanner.java | 3 --- src/main/java/seedu/financialplanner/list/Cashflow.java | 8 ++++++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index 950611a486..74451cb8d3 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -8,7 +8,6 @@ import seedu.financialplanner.storage.Storage; import seedu.financialplanner.utils.Parser; import seedu.financialplanner.utils.Ui; -import seedu.financialplanner.visualisations.PieChartVisual; public class FinancialPlanner { @@ -45,8 +44,6 @@ public void run() { ui.showMessage(e.getMessage()); } } - PieChartVisual test = new PieChartVisual(); - test.displayPieChart(); save(); ui.exitMessage(); } diff --git a/src/main/java/seedu/financialplanner/list/Cashflow.java b/src/main/java/seedu/financialplanner/list/Cashflow.java index 67a7ab2a9f..61cb1edbac 100644 --- a/src/main/java/seedu/financialplanner/list/Cashflow.java +++ b/src/main/java/seedu/financialplanner/list/Cashflow.java @@ -22,4 +22,12 @@ public Cashflow() { public String formatString() { return this.value + " | " + this.type + " | " + this.recur; } + + public String getType() { + return type; + } + + public double getValue() { + return value; + } } From 4fc4df2db821fb4d8cdd5f3eb3093400f5e0d297 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 15 Oct 2023 23:43:15 +0800 Subject: [PATCH 080/518] Add vis command to the parser class --- .../financialplanner/commands/VisCommand.java | 23 +++++++++++++++++++ .../financialplanner/list/FinancialList.java | 3 --- .../seedu/financialplanner/utils/Parser.java | 18 +++++++++------ 3 files changed, 34 insertions(+), 10 deletions(-) create mode 100644 src/main/java/seedu/financialplanner/commands/VisCommand.java diff --git a/src/main/java/seedu/financialplanner/commands/VisCommand.java b/src/main/java/seedu/financialplanner/commands/VisCommand.java new file mode 100644 index 0000000000..82ef9b4879 --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/VisCommand.java @@ -0,0 +1,23 @@ +package seedu.financialplanner.commands; + +import seedu.financialplanner.exceptions.FinancialPlannerException; +import seedu.financialplanner.investments.WatchList; +import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.utils.Ui; +import seedu.financialplanner.visualisations.Categorizer; +import seedu.financialplanner.visualisations.Visualizer; + +public class VisCommand extends Command { + + private String type; + private String chart; + + public VisCommand(String type, String chart) { + this.type = type; + this.chart = chart; + } + @Override + public void execute(Ui ui, FinancialList financialList, WatchList watchList) throws FinancialPlannerException { + Visualizer.displayChart(chart, Categorizer.SortExpenses(financialList)); + } +} diff --git a/src/main/java/seedu/financialplanner/list/FinancialList.java b/src/main/java/seedu/financialplanner/list/FinancialList.java index 3d5558e1be..9d33571381 100644 --- a/src/main/java/seedu/financialplanner/list/FinancialList.java +++ b/src/main/java/seedu/financialplanner/list/FinancialList.java @@ -10,9 +10,6 @@ public class FinancialList { public final ArrayList list = new ArrayList<>(); - private FinancialList() { - } - private void printAddedCashflow(String line) { DecimalFormat decimalFormat = new DecimalFormat("####0.00"); diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index c571f38a72..e5878425cb 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -1,13 +1,7 @@ package seedu.financialplanner.utils; -import seedu.financialplanner.commands.Command; -import seedu.financialplanner.commands.Entry; -import seedu.financialplanner.commands.Exit; -import seedu.financialplanner.commands.WatchListCommand; -import seedu.financialplanner.commands.Invalid; -import seedu.financialplanner.commands.AddStockCommand; -import seedu.financialplanner.commands.Find; +import seedu.financialplanner.commands.*; public class Parser { private static final String EXIT_COMMAND = "exit"; @@ -15,6 +9,7 @@ public class Parser { private static final String ADD_ENTRY_COMMAND = "add"; private static final String ADD_STOCK_COMMAND = "addstock"; private static final String FIND_COMMAND = "find"; + private static final String VISUALIZATION_COMMAND = "vis"; public static Command parse(String input) { String[] split = input.split(" ", 2); @@ -32,6 +27,8 @@ public static Command parse(String input) { return parseAddStock(restOfInput); case FIND_COMMAND: return new Find(restOfInput); + case VISUALIZATION_COMMAND: + return parseVis(restOfInput); default: return new Invalid(); } @@ -43,4 +40,11 @@ private static Command parseAddStock(String restOfInput) { String stockCode = split[1].trim(); return new AddStockCommand(stockCode); } + + private static Command parseVis(String restOfInput) { + String[] split = restOfInput.trim().split("t/|c/"); + String type = split[1].trim(); + String chart = split[2].trim(); + return new VisCommand(type, chart); + } } From 7f31985cd4ae39b8944d2df5d424aad1616742c0 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 15 Oct 2023 23:44:05 +0800 Subject: [PATCH 081/518] Add categorizer utility class to sort expenses or income entry based on type --- .../visualisations/Categorizer.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/main/java/seedu/financialplanner/visualisations/Categorizer.java diff --git a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java new file mode 100644 index 0000000000..f0357c3188 --- /dev/null +++ b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java @@ -0,0 +1,24 @@ +package seedu.financialplanner.visualisations; + +import com.sun.source.tree.Tree; +import seedu.financialplanner.list.Cashflow; +import seedu.financialplanner.list.Expense; +import seedu.financialplanner.list.FinancialList; + +import java.util.HashMap; +import java.util.Map; +import java.util.TreeMap; + +public class Categorizer { + public static Map SortExpenses(FinancialList financialList) { + Map expensesByCat = new HashMap<>(); + for (Cashflow e: financialList.list) { + if (e instanceof Expense) { + String key = e.getType(); + double value = expensesByCat.getOrDefault(key, 0.0) + e.getValue(); + expensesByCat.put(key, value); + } + } + return expensesByCat; + } +} From afc246440d8eca06ede599770fa363a0a5549f3e Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 15 Oct 2023 23:44:36 +0800 Subject: [PATCH 082/518] Add visualizer class to visualize data in bar graph or pie chart --- .../visualisations/Visualizer.java | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 src/main/java/seedu/financialplanner/visualisations/Visualizer.java diff --git a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java new file mode 100644 index 0000000000..1f54ba1bce --- /dev/null +++ b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java @@ -0,0 +1,69 @@ +package seedu.financialplanner.visualisations; + + +import org.knowm.xchart.CategoryChart; +import org.knowm.xchart.CategoryChartBuilder; +import org.knowm.xchart.PieChart; +import org.knowm.xchart.PieChartBuilder; +import org.knowm.xchart.SwingWrapper; +import org.knowm.xchart.internal.chartpart.Chart; +import org.knowm.xchart.style.Styler; +import seedu.financialplanner.exceptions.FinancialPlannerException; + +import javax.swing.*; +import java.awt.Color; +import java.sql.Array; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class Visualizer { + public static void displayChart(String chartType, Map expensesByCat) throws FinancialPlannerException { + switch (chartType) { + case "pie": + displayPieChart(expensesByCat); + break; + case "bar": + displayBarChart(expensesByCat); + break; + default: + throw new FinancialPlannerException("Chart Type Not Found"); + } + + + } + public static void displayPieChart (Map expensesByCat) { + PieChart chart = new PieChartBuilder().width(800).height(600).title("Test").build(); + + // Customize Chart + Color[] sliceColors = new Color[] { new Color(224, 68, 14), new Color(230, 105, 62), + new Color(236, 143, 110), new Color(243, 180, 159), new Color(246, 199, 182) }; + chart.getStyler().setSeriesColors(sliceColors); + + for (Map.Entry set: expensesByCat.entrySet()) { + chart.addSeries(set.getKey(), set.getValue()); + } + // Show it + JFrame swHR = new SwingWrapper<>(chart).displayChart(); + javax.swing.SwingUtilities.invokeLater( + ()->swHR.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE) + ); + } + + public static void displayBarChart (Map expensesByCat) { + CategoryChart chart = new CategoryChartBuilder().width(800).height(600) + .title("Expenses").xAxisTitle("Type").yAxisTitle("Value").build(); + // Customize Chart + chart.getStyler().setLegendPosition(Styler.LegendPosition.InsideNW); + chart.getStyler().setHasAnnotations(true); + + // Series + List values = new ArrayList(expensesByCat.values()); + List keys = new ArrayList(expensesByCat.keySet()); + chart.addSeries("Expense", keys, values); + JFrame swHR = new SwingWrapper<>(chart).displayChart(); + javax.swing.SwingUtilities.invokeLater( + ()->swHR.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE) + ); + } +} From 8631e18975c8beabae651b826d9c0a6a6a798aeb Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 15 Oct 2023 23:49:43 +0800 Subject: [PATCH 083/518] Fix Import --- src/main/java/seedu/financialplanner/utils/Parser.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index e5878425cb..915fa2ffec 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -1,7 +1,14 @@ package seedu.financialplanner.utils; -import seedu.financialplanner.commands.*; +import seedu.financialplanner.commands.Command; +import seedu.financialplanner.commands.Entry; +import seedu.financialplanner.commands.Exit; +import seedu.financialplanner.commands.WatchListCommand; +import seedu.financialplanner.commands.Invalid; +import seedu.financialplanner.commands.AddStockCommand; +import seedu.financialplanner.commands.Find; +import seedu.financialplanner.commands.VisCommand; public class Parser { private static final String EXIT_COMMAND = "exit"; From e7adc46ce9780ed73bde9a9394d449fb1dc98eed Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 15 Oct 2023 23:51:03 +0800 Subject: [PATCH 084/518] Update text ui test files --- text-ui-test/EXPECTED.TXT | 58 +++++++++++++++++++++++++++++---------- text-ui-test/input.txt | 4 +++ 2 files changed, 48 insertions(+), 14 deletions(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 0797b3fd0a..f9bb80dd7b 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,20 +1,50 @@ Directory doesn't exist. Creating directory... File not found. Creating new file... Welcome to your Financial Planner. Type something to get started. -Added income of value: 5000.00 to the list. -type: work -recurring every: 30 days -balance: 5000.00 -Added income of value: 123.12 to the list. -type: allowance -balance: 5123.12 -Added expense of value: 100.00 to the list. -type: daily necessities -recurring every: 30 days -balance: 5023.12 -Added expense of value: 123.21 to the list. -type: books -balance: 4899.91 +You have added an Income + Type: work + Amount: 5000.00 + Recurring every: 30 days +to the Financial Planner. +Balance: 5000.00 +You have added an Income + Type: allowance + Amount: 123.12 +to the Financial Planner. +Balance: 5123.12 +You have added an Expense + Type: daily necessities + Amount: 100.00 + Recurring every: 30 days +to the Financial Planner. +Balance: 5023.12 +You have added an Expense + Type: books + Amount: 123.21 +to the Financial Planner. +Balance: 4899.91 +You have removed an Income + Type: allowance + Amount: 123.12 +from the Financial Planner. +Balance: 4776.79 +You have removed an Income + Type: work + Amount: 5000.00 + Recurring every: 30 days +from the Financial Planner. +Balance: -223.21 +You have removed an Expense + Type: books + Amount: 123.21 +from the Financial Planner. +Balance: -100.00 +You have removed an Expense + Type: daily necessities + Amount: 100.00 + Recurring every: 30 days +from the Financial Planner. +Balance: 0.00 You have successfully added: Microsoft Corporation Use Watchlist to view it! diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index 025ea01d28..cfde7a9100 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -2,6 +2,10 @@ add income a/5000 t/work r/30 add income a/123.12 t/allowance add expense a/100 t/daily necessities r/30 add expense a/123.21 t/books +delete income 2 +delete 1 +delete expense 2 +delete 1 addstock m/NASDAQ s/MSFT addstock m/NYSE s/GME sdf From 781779dca09f480fe69d15dcdfcbd955af8c56d6 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 16 Oct 2023 00:03:42 +0800 Subject: [PATCH 085/518] Delete unused constructor --- src/main/java/seedu/financialplanner/list/Cashflow.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/seedu/financialplanner/list/Cashflow.java b/src/main/java/seedu/financialplanner/list/Cashflow.java index bf1d2c398d..4e03f873c2 100644 --- a/src/main/java/seedu/financialplanner/list/Cashflow.java +++ b/src/main/java/seedu/financialplanner/list/Cashflow.java @@ -18,11 +18,7 @@ public Cashflow(double amount, String type, int recur) { } public void deleteCashflowvalue() { } - public Cashflow() { - this.amount = 0; - this.type = null; - this.recur = 0; - } + //@author mhadidg-reused //Reused from https://stackoverflow.com/questions/2808535/round-a-double-to-2-decimal-places public static double round(double value, int places) { From 7ed9cafa3c7bd26a4641c1ec66c018e371c42434 Mon Sep 17 00:00:00 2001 From: YFshadaow Date: Mon, 16 Oct 2023 00:05:23 +0800 Subject: [PATCH 086/518] Update code to pass style checks --- .../seedu/financialplanner/utils/Parser.java | 69 ++++++++++++------- 1 file changed, 43 insertions(+), 26 deletions(-) diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index 62fec2994c..79dd9e1927 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -1,8 +1,23 @@ package seedu.financialplanner.utils; -import seedu.financialplanner.commands.*; -import java.util.*; + +import seedu.financialplanner.commands.AbstractCommand; +import seedu.financialplanner.commands.AddStockCommand; +import seedu.financialplanner.commands.EntryCommand; +import seedu.financialplanner.commands.ExitCommand; +import seedu.financialplanner.commands.FindCommand; +import seedu.financialplanner.commands.InvalidCommand; +import seedu.financialplanner.commands.RawCommand; +import seedu.financialplanner.commands.WatchListCommand; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + public class Parser { private static final String EXIT_COMMAND_NAME = "exit"; @@ -16,6 +31,28 @@ public static AbstractCommand parseCommand(String input) throws IllegalArgumentE return parseCommand(rawCommand); } + public static AbstractCommand parseCommand(RawCommand rawCommand) throws IllegalArgumentException{ + switch (rawCommand.getCommandName()) { + case EXIT_COMMAND_NAME: { + return new ExitCommand(rawCommand); + } + case WATCHLIST_COMMAND_NAME: { + return new WatchListCommand(rawCommand); + } + case ADD_ENTRY_COMMAND_NAME: { + return new EntryCommand(rawCommand); + } + case ADD_STOCK_COMMAND_NAME: { + return new AddStockCommand(rawCommand); + } + case FIND_COMMAND_NAME: { + return new FindCommand(rawCommand); + } + default: { + return new InvalidCommand(); + } + } + } public static RawCommand parseRawCommand(String input) throws IllegalArgumentException{ Iterator iterator = Arrays.stream(input.split(" ")).iterator(); if (!iterator.hasNext()) { @@ -34,7 +71,8 @@ public static RawCommand parseRawCommand(String input) throws IllegalArgumentExc // Save previous extra argument when next extra argument is found if (currentExtraArgumentName != null) { if (extraArgs.containsKey(currentExtraArgumentName)) { - throw new IllegalArgumentException(String.format("Duplicate extra argument name: %s", currentExtraArgumentName)); + throw new IllegalArgumentException( + String.format("Duplicate extra argument name: %s", currentExtraArgumentName)); } else { extraArgs.put(currentExtraArgumentName, String.join(" ", extraArgumentContentBuffer)); extraArgumentContentBuffer.clear(); @@ -58,7 +96,8 @@ public static RawCommand parseRawCommand(String input) throws IllegalArgumentExc // Save previous extra argument at the very end if (currentExtraArgumentName != null) { if (extraArgs.containsKey(currentExtraArgumentName)) { - throw new IllegalArgumentException(String.format("Duplicate extra argument name: %s", currentExtraArgumentName)); + throw new IllegalArgumentException( + String.format("Duplicate extra argument name: %s", currentExtraArgumentName)); } else { extraArgs.put(currentExtraArgumentName, String.join(" ", extraArgumentContentBuffer)); extraArgumentContentBuffer.clear(); @@ -68,26 +107,4 @@ public static RawCommand parseRawCommand(String input) throws IllegalArgumentExc return new RawCommand(commandName, args, extraArgs); } - public static AbstractCommand parseCommand(RawCommand rawCommand) throws IllegalArgumentException{ - switch (rawCommand.getCommandName()) { - case EXIT_COMMAND_NAME: { - return new ExitCommand(rawCommand); - } - case WATCHLIST_COMMAND_NAME: { - return new WatchListCommand(rawCommand); - } - case ADD_ENTRY_COMMAND_NAME: { - return new EntryCommand(rawCommand); - } - case ADD_STOCK_COMMAND_NAME: { - return new AddStockCommand(rawCommand); - } - case FIND_COMMAND_NAME: { - return new FindCommand(rawCommand); - } - default: { - return new InvalidCommand(); - } - } - } } From 7fe6dc007f9a4c50dd6d6e431834641688608bd3 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 16 Oct 2023 00:23:56 +0800 Subject: [PATCH 087/518] Fix code style issues --- .../financialplanner/commands/VisCommand.java | 2 +- .../visualisations/Categorizer.java | 4 +--- .../visualisations/Visualizer.java | 16 ++++++++++------ 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/VisCommand.java b/src/main/java/seedu/financialplanner/commands/VisCommand.java index 82ef9b4879..07e636ccd5 100644 --- a/src/main/java/seedu/financialplanner/commands/VisCommand.java +++ b/src/main/java/seedu/financialplanner/commands/VisCommand.java @@ -18,6 +18,6 @@ public VisCommand(String type, String chart) { } @Override public void execute(Ui ui, FinancialList financialList, WatchList watchList) throws FinancialPlannerException { - Visualizer.displayChart(chart, Categorizer.SortExpenses(financialList)); + Visualizer.displayChart(chart, Categorizer.sortExpenses(financialList)); } } diff --git a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java index f0357c3188..e24dd0b965 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java @@ -1,16 +1,14 @@ package seedu.financialplanner.visualisations; -import com.sun.source.tree.Tree; import seedu.financialplanner.list.Cashflow; import seedu.financialplanner.list.Expense; import seedu.financialplanner.list.FinancialList; import java.util.HashMap; import java.util.Map; -import java.util.TreeMap; public class Categorizer { - public static Map SortExpenses(FinancialList financialList) { + public static Map sortExpenses(FinancialList financialList) { Map expensesByCat = new HashMap<>(); for (Cashflow e: financialList.list) { if (e instanceof Expense) { diff --git a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java index 1f54ba1bce..a5abc520c9 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java @@ -6,19 +6,18 @@ import org.knowm.xchart.PieChart; import org.knowm.xchart.PieChartBuilder; import org.knowm.xchart.SwingWrapper; -import org.knowm.xchart.internal.chartpart.Chart; import org.knowm.xchart.style.Styler; import seedu.financialplanner.exceptions.FinancialPlannerException; -import javax.swing.*; +import javax.swing.JFrame; import java.awt.Color; -import java.sql.Array; import java.util.ArrayList; import java.util.List; import java.util.Map; public class Visualizer { - public static void displayChart(String chartType, Map expensesByCat) throws FinancialPlannerException { + public static void displayChart(String chartType, Map expensesByCat) + throws FinancialPlannerException { switch (chartType) { case "pie": displayPieChart(expensesByCat); @@ -36,8 +35,13 @@ public static void displayPieChart (Map expensesByCat) { PieChart chart = new PieChartBuilder().width(800).height(600).title("Test").build(); // Customize Chart - Color[] sliceColors = new Color[] { new Color(224, 68, 14), new Color(230, 105, 62), - new Color(236, 143, 110), new Color(243, 180, 159), new Color(246, 199, 182) }; + Color[] sliceColors = new Color[] { + new Color(224, 68, 14), + new Color(230, 105, 62), + new Color(236, 143, 110), + new Color(243, 180, 159), + new Color(246, 199, 182) + }; chart.getStyler().setSeriesColors(sliceColors); for (Map.Entry set: expensesByCat.entrySet()) { From 28dd7ef23c898f7c9a91969a499e1463e6f12b2e Mon Sep 17 00:00:00 2001 From: YFshadaow Date: Mon, 16 Oct 2023 01:33:36 +0800 Subject: [PATCH 088/518] Update test files --- .../financialplanner/FinancialPlanner.java | 8 ++-- .../commands/EntryCommand.java | 6 +-- .../commands/FindCommand.java | 10 ++--- .../{FinancialList.java => CashflowList.java} | 6 +-- .../financialplanner/storage/LoadData.java | 8 ++-- .../financialplanner/storage/SaveData.java | 6 +-- .../financialplanner/storage/Storage.java | 6 +-- .../java/seedu/financialplanner/utils/Ui.java | 12 +++++- .../financialplanner/commands/EntryTest.java | 12 +++--- ...ialListTest.java => CashflowListTest.java} | 6 ++- .../financialplanner/storage/StorageTest.java | 38 +++++++++++-------- text-ui-test/input.txt | 12 +++--- 12 files changed, 74 insertions(+), 56 deletions(-) rename src/main/java/seedu/financialplanner/list/{FinancialList.java => CashflowList.java} (94%) rename src/test/java/seedu/financialplanner/list/{FinancialListTest.java => CashflowListTest.java} (94%) diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index eff9c8ae17..af8456a6bc 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -4,7 +4,7 @@ import seedu.financialplanner.commands.ExitCommand; import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.investments.WatchList; -import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.list.CashflowList; import seedu.financialplanner.storage.Storage; import seedu.financialplanner.utils.Parser; import seedu.financialplanner.utils.Ui; @@ -15,7 +15,7 @@ public class FinancialPlanner { private final Storage storage = Storage.INSTANCE; private final Ui ui = Ui.INSTANCE; private final WatchList watchList = WatchList.INSTANCE; - private final FinancialList financialList = FinancialList.INSTANCE; + private final CashflowList cashflowList = CashflowList.INSTANCE; private FinancialPlanner() { } @@ -26,7 +26,7 @@ public static void main(String[] args) { public void run() { try { - storage.load(financialList, ui, FILE_PATH); + storage.load(cashflowList, ui, FILE_PATH); } catch (FinancialPlannerException e) { ui.showMessage(e.getMessage()); } @@ -51,7 +51,7 @@ public void run() { public void save() { try { - storage.save(financialList, FILE_PATH); + storage.save(cashflowList, FILE_PATH); } catch (FinancialPlannerException e) { ui.showMessage(e.getMessage()); } diff --git a/src/main/java/seedu/financialplanner/commands/EntryCommand.java b/src/main/java/seedu/financialplanner/commands/EntryCommand.java index 10eeb04206..f10ebe4207 100644 --- a/src/main/java/seedu/financialplanner/commands/EntryCommand.java +++ b/src/main/java/seedu/financialplanner/commands/EntryCommand.java @@ -1,7 +1,7 @@ package seedu.financialplanner.commands; import seedu.financialplanner.enumerations.EntryCategory; -import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.list.CashflowList; import seedu.financialplanner.utils.Ui; import java.util.ArrayList; @@ -54,10 +54,10 @@ public EntryCommand(RawCommand rawCommand) throws IllegalArgumentException { public void execute() { switch (category) { case INCOME: - FinancialList.INSTANCE.addIncome(amount, type, recur); + CashflowList.INSTANCE.addIncome(amount, type, recur); break; case EXPENSE: - FinancialList.INSTANCE.addExpense(amount, type, recur); + CashflowList.INSTANCE.addExpense(amount, type, recur); break; default: Ui.INSTANCE.showMessage("Unidentified entry."); diff --git a/src/main/java/seedu/financialplanner/commands/FindCommand.java b/src/main/java/seedu/financialplanner/commands/FindCommand.java index 9225704a20..6aabcdf7ee 100644 --- a/src/main/java/seedu/financialplanner/commands/FindCommand.java +++ b/src/main/java/seedu/financialplanner/commands/FindCommand.java @@ -1,7 +1,7 @@ package seedu.financialplanner.commands; import seedu.financialplanner.investments.WatchList; -import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.list.CashflowList; import seedu.financialplanner.utils.Ui; import java.util.ArrayList; @@ -19,14 +19,14 @@ public FindCommand(RawCommand rawCommand) { @Override public void execute() { - FinancialList financialList = FinancialList.INSTANCE; + CashflowList cashflowList = CashflowList.INSTANCE; Ui ui = Ui.INSTANCE; WatchList watchList = WatchList.INSTANCE; ArrayList foundedFinancialList = new ArrayList<>(); ArrayList foundedWatchList = new ArrayList<>(); - for (int i = 0; i < financialList.size(); i++) { - if (financialList.get(i).formatString().contains(description)) { - foundedFinancialList.add(financialList.get(i).formatString()); + for (int i = 0; i < cashflowList.size(); i++) { + if (cashflowList.get(i).formatString().contains(description)) { + foundedFinancialList.add(cashflowList.get(i).formatString()); } } if (!foundedFinancialList.isEmpty()) { diff --git a/src/main/java/seedu/financialplanner/list/FinancialList.java b/src/main/java/seedu/financialplanner/list/CashflowList.java similarity index 94% rename from src/main/java/seedu/financialplanner/list/FinancialList.java rename to src/main/java/seedu/financialplanner/list/CashflowList.java index 3d5558e1be..435927c694 100644 --- a/src/main/java/seedu/financialplanner/list/FinancialList.java +++ b/src/main/java/seedu/financialplanner/list/CashflowList.java @@ -5,12 +5,12 @@ import java.text.DecimalFormat; import java.util.ArrayList; -public class FinancialList { - public static final FinancialList INSTANCE = new FinancialList(); +public class CashflowList { + public static final CashflowList INSTANCE = new CashflowList(); public final ArrayList list = new ArrayList<>(); - private FinancialList() { + private CashflowList() { } private void printAddedCashflow(String line) { diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 26449059f2..8198c8785b 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -3,7 +3,7 @@ import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.list.Cashflow; import seedu.financialplanner.list.Expense; -import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.list.CashflowList; import seedu.financialplanner.list.Income; import seedu.financialplanner.utils.Ui; @@ -12,7 +12,7 @@ import java.util.Scanner; public abstract class LoadData { - public static void load(FinancialList financialList, Ui ui, String filePath) throws FinancialPlannerException { + public static void load(CashflowList cashflowList, Ui ui, String filePath) throws FinancialPlannerException { try { Scanner inputFile = new Scanner(new FileReader(filePath)); String line; @@ -22,7 +22,7 @@ public static void load(FinancialList financialList, Ui ui, String filePath) thr line = inputFile.nextLine(); final Cashflow entry = getEntry(line); - financialList.load(entry); + cashflowList.load(entry); } inputFile.close(); } catch (IOException e) { @@ -30,7 +30,7 @@ public static void load(FinancialList financialList, Ui ui, String filePath) thr } catch (NumberFormatException | ArrayIndexOutOfBoundsException | FinancialPlannerException e) { ui.showMessage("File appears to be corrupted. Do you want to create a new file? (Y/N)"); if (createNewFile(ui)) { - financialList.list.clear(); + cashflowList.list.clear(); } else { throw new FinancialPlannerException("Please fix the corrupted file, " + "which can be found in data/data.txt."); diff --git a/src/main/java/seedu/financialplanner/storage/SaveData.java b/src/main/java/seedu/financialplanner/storage/SaveData.java index d36380c0d6..b5fa6bc2f6 100644 --- a/src/main/java/seedu/financialplanner/storage/SaveData.java +++ b/src/main/java/seedu/financialplanner/storage/SaveData.java @@ -2,16 +2,16 @@ import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.list.Cashflow; -import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.list.CashflowList; import java.io.FileWriter; import java.io.IOException; public abstract class SaveData { - public static void save(FinancialList financialList, String filePath) throws FinancialPlannerException { + public static void save(CashflowList cashflowList, String filePath) throws FinancialPlannerException { try { FileWriter fw = new FileWriter(filePath); - for (Cashflow entry : financialList.list) { + for (Cashflow entry : cashflowList.list) { fw.write(entry.formatString() + "\n"); } fw.close(); diff --git a/src/main/java/seedu/financialplanner/storage/Storage.java b/src/main/java/seedu/financialplanner/storage/Storage.java index 741e0eb7ed..ef340a2d3e 100644 --- a/src/main/java/seedu/financialplanner/storage/Storage.java +++ b/src/main/java/seedu/financialplanner/storage/Storage.java @@ -1,7 +1,7 @@ package seedu.financialplanner.storage; import seedu.financialplanner.exceptions.FinancialPlannerException; -import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.list.CashflowList; import seedu.financialplanner.utils.Ui; import java.io.IOException; @@ -24,11 +24,11 @@ private Storage() { } } - public void load(FinancialList list, Ui ui, String filePath) throws FinancialPlannerException { + public void load(CashflowList list, Ui ui, String filePath) throws FinancialPlannerException { LoadData.load(list, ui, filePath); } - public void save(FinancialList list, String filePath) throws FinancialPlannerException { + public void save(CashflowList list, String filePath) throws FinancialPlannerException { SaveData.save(list, filePath); } } diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index ace28c998c..0fd3c8349c 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -7,7 +7,7 @@ public class Ui { public static final Ui INSTANCE = new Ui(); - private final Scanner in = new Scanner(System.in); + private Scanner Scanner = new Scanner(System.in); private Ui() { } @@ -16,6 +16,14 @@ public static void printCorruptedFileError(String message) { System.out.println(message); } + public Scanner getScanner() { + return Scanner; + } + + public void setScanner(Scanner scanner) { + this.Scanner = scanner; + } + public void showMessage(String message) { System.out.println(message); } @@ -29,7 +37,7 @@ public void exitMessage() { } public String input() { - return in.nextLine().trim(); + return Scanner.nextLine().trim(); } public void printWatchListHeader() { diff --git a/src/test/java/seedu/financialplanner/commands/EntryTest.java b/src/test/java/seedu/financialplanner/commands/EntryTest.java index ed174a41a4..c500dde9c7 100644 --- a/src/test/java/seedu/financialplanner/commands/EntryTest.java +++ b/src/test/java/seedu/financialplanner/commands/EntryTest.java @@ -2,7 +2,7 @@ import org.junit.jupiter.api.Test; import seedu.financialplanner.investments.WatchList; -import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.list.CashflowList; import seedu.financialplanner.utils.Parser; import seedu.financialplanner.utils.Ui; @@ -10,21 +10,23 @@ class EntryTest { private Ui ui = Ui.INSTANCE; - private FinancialList financialList = FinancialList.INSTANCE; + private CashflowList cashflowList = CashflowList.INSTANCE; private WatchList watchList = WatchList.INSTANCE; @Test void testExecute() { + CashflowList.INSTANCE.list.clear(); + EntryCommand testEntry = new EntryCommand(Parser.parseRawCommand("add income /a 300 /t work /r 30")); testEntry.execute(); assertEquals(300, testEntry.amount); - assertEquals("work", testEntry.category); + assertEquals("work", testEntry.type); assertEquals(30, testEntry.recur); - testEntry = new EntryCommand(Parser.parseRawCommand("add expense /a 15 /t double_mcspicy")); + testEntry = new EntryCommand(Parser.parseRawCommand("add expense /a 15 /t double mcspicy")); testEntry.execute(); assertEquals(15, testEntry.amount); - assertEquals("double_mcspicy", testEntry.category); + assertEquals("double mcspicy", testEntry.type); assertEquals(0, testEntry.recur); } } diff --git a/src/test/java/seedu/financialplanner/list/FinancialListTest.java b/src/test/java/seedu/financialplanner/list/CashflowListTest.java similarity index 94% rename from src/test/java/seedu/financialplanner/list/FinancialListTest.java rename to src/test/java/seedu/financialplanner/list/CashflowListTest.java index 3a4e07fef9..4526810b67 100644 --- a/src/test/java/seedu/financialplanner/list/FinancialListTest.java +++ b/src/test/java/seedu/financialplanner/list/CashflowListTest.java @@ -6,12 +6,14 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -class FinancialListTest { - private FinancialList testList = FinancialList.INSTANCE; +class CashflowListTest { + private CashflowList testList = CashflowList.INSTANCE; private DecimalFormat decimalFormat = new DecimalFormat("####0.00"); @Test void testAddIncomeAndExpense() { + CashflowList.INSTANCE.list.clear(); + Cashflow.balance = 0; testList.addIncome(15, "work", 30); Cashflow testIncome = testList.list.get(0); diff --git a/src/test/java/seedu/financialplanner/storage/StorageTest.java b/src/test/java/seedu/financialplanner/storage/StorageTest.java index 2342e3d32f..bec28f1863 100644 --- a/src/test/java/seedu/financialplanner/storage/StorageTest.java +++ b/src/test/java/seedu/financialplanner/storage/StorageTest.java @@ -4,7 +4,7 @@ import org.junit.jupiter.api.io.TempDir; import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.list.Expense; -import seedu.financialplanner.list.FinancialList; +import seedu.financialplanner.list.CashflowList; import seedu.financialplanner.list.Income; import seedu.financialplanner.utils.Ui; @@ -12,6 +12,7 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Scanner; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -23,42 +24,47 @@ public class StorageTest { @Test public void loadValidData() throws FinancialPlannerException { Storage storage = Storage.INSTANCE; - FinancialList test = FinancialList.INSTANCE; - storage.load(test, Ui.INSTANCE, "src/test/testData/ValidData.txt"); - FinancialList expected = getTestData(); - assertEquals(expected.getList(), test.getList()); + CashflowList cashflowList = CashflowList.INSTANCE; + cashflowList.list.clear(); + storage.load(cashflowList, Ui.INSTANCE, "src/test/testData/ValidData.txt"); + String actual = cashflowList.getList(); + cashflowList.list.clear(); + getTestData(); + String expected = cashflowList.getList(); + assertEquals(expected, actual); } @Test public void loadInvalidData_userInputNo() { Storage storage = Storage.INSTANCE; - FinancialList test = FinancialList.INSTANCE; + CashflowList test = CashflowList.INSTANCE; + test.list.clear(); ByteArrayInputStream in = new ByteArrayInputStream("n".getBytes()); - System.setIn(in); + Ui.INSTANCE.setScanner(new Scanner(in)); assertThrows(FinancialPlannerException.class, () -> storage.load(test, Ui.INSTANCE, "src/test/testData/InvalidData.txt")); } @Test public void saveValidData() throws FinancialPlannerException, IOException { - FinancialList expected = getTestData(); + CashflowList.INSTANCE.list.clear(); + getTestData(); Storage storage = Storage.INSTANCE; - storage.save(expected, String.valueOf(testFolder.resolve("temp.txt"))); + storage.save(CashflowList.INSTANCE, String.valueOf(testFolder.resolve("temp.txt"))); assertEquals(Files.readAllLines(Path.of("src/test/testData/ValidData.txt")), Files.readAllLines(testFolder.resolve("temp.txt"))); } @Test public void saveNonExistentFile() { - FinancialList expected = getTestData(); + getTestData(); Storage storage = Storage.INSTANCE; - assertThrows(FinancialPlannerException.class, () -> storage.save(expected, "")); + assertThrows(FinancialPlannerException.class, () -> storage.save(CashflowList.INSTANCE, "")); } - private FinancialList getTestData() { - FinancialList list = FinancialList.INSTANCE; - list.load(new Income(123.12, "allowance", 0)); - list.load(new Expense(100, "daily necessities", 30)); - return list; + private void getTestData() { + CashflowList cashflowList = CashflowList.INSTANCE; + cashflowList.load(new Income(123.12, "allowance", 0)); + cashflowList.load(new Expense(100, "daily necessities", 30)); } } diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index 025ea01d28..0322817fe7 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -1,8 +1,8 @@ -add income a/5000 t/work r/30 -add income a/123.12 t/allowance -add expense a/100 t/daily necessities r/30 -add expense a/123.21 t/books -addstock m/NASDAQ s/MSFT -addstock m/NYSE s/GME +add income /a 5000 /t work /r 30 +add income /a 123.12 /t allowance +add expense /a 100 /t daily necessities /r 30 +add expense /a 123.21 /t books +addstock /s MSFT +addstock /s GME sdf exit \ No newline at end of file From 9790808efd401a0add9b17e445f73e792823dbca Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Mon, 16 Oct 2023 10:01:26 +0800 Subject: [PATCH 089/518] Add storage and exceptions for budget --- .../commands/BudgetCommand.java | 33 +++++++++---------- .../seedu/financialplanner/list/Budget.java | 6 +++- .../financialplanner/storage/LoadData.java | 9 ++--- .../seedu/financialplanner/utils/Parser.java | 5 ++- 4 files changed, 29 insertions(+), 24 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java index 3c479e5c9f..9c4e4ffc53 100644 --- a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java +++ b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java @@ -1,28 +1,25 @@ package seedu.financialplanner.commands; -import seedu.financialplanner.exceptions.FinancialPlannerException; -import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.list.Budget; -import seedu.financialplanner.list.FinancialList; -import seedu.financialplanner.utils.Ui; +import seedu.financialplanner.list.CashflowList; -public class BudgetCommand extends Command { - private static final String BUDGET_DELIMITTER = "b/"; - private String input; +public class BudgetCommand extends AbstractCommand { + private double budget; - public BudgetCommand(String input) { - this.input = input; + public BudgetCommand(RawCommand rawCommand) throws IllegalArgumentException { + if (!rawCommand.extraArgs.containsKey("b")) { + throw new IllegalArgumentException("Missing /b argument."); + } + try { + budget = Double.parseDouble(rawCommand.extraArgs.get("b")); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Budget must be a number."); + } + rawCommand.extraArgs.remove("b"); } @Override - public void execute(Ui ui, FinancialList financialList, WatchList watchList) throws FinancialPlannerException { - int budgetIndex = input.indexOf(BUDGET_DELIMITTER); - if (budgetIndex == -1) { - throw new FinancialPlannerException("Please ensure b/ is included in the command."); - } - String budgetString = input.substring(budgetIndex + BUDGET_DELIMITTER.length()).trim(); - double budget = Double.parseDouble(budgetString); //todo: add error handling here - - financialList.setBudget(new Budget(budget)); + public void execute() throws Exception { + CashflowList.INSTANCE.setBudget(new Budget(budget)); } } diff --git a/src/main/java/seedu/financialplanner/list/Budget.java b/src/main/java/seedu/financialplanner/list/Budget.java index adae6863b7..e39de3ecda 100644 --- a/src/main/java/seedu/financialplanner/list/Budget.java +++ b/src/main/java/seedu/financialplanner/list/Budget.java @@ -2,9 +2,13 @@ public class Budget extends Cashflow { private static final int MONTH = 30; + private static double currentBudget = 0; public Budget(double value) { super(value, null, MONTH); } - //todo: add storage for budget + @Override + public String formatString() { + return "B | " + this.value; + } } diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 8198c8785b..e2fae4961c 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -1,10 +1,7 @@ package seedu.financialplanner.storage; import seedu.financialplanner.exceptions.FinancialPlannerException; -import seedu.financialplanner.list.Cashflow; -import seedu.financialplanner.list.Expense; -import seedu.financialplanner.list.CashflowList; -import seedu.financialplanner.list.Income; +import seedu.financialplanner.list.*; import seedu.financialplanner.utils.Ui; import java.io.FileReader; @@ -66,6 +63,10 @@ private static Cashflow getEntry(String line) throws FinancialPlannerException { recur = Integer.parseInt(split[3].trim()); entry = new Expense(value, split[2].trim(), recur); break; + case "B": + value = Double.parseDouble(split[1].trim()); + entry = new Budget(value); + break; default: throw new FinancialPlannerException("Error loading file"); } diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index 105f5f75d0..406ea00255 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -11,6 +11,7 @@ import seedu.financialplanner.commands.RawCommand; import seedu.financialplanner.commands.WatchListCommand; import seedu.financialplanner.commands.BudgetCommand; +import seedu.financialplanner.exceptions.FinancialPlannerException; import java.util.ArrayList; import java.util.Arrays; @@ -32,7 +33,7 @@ public static AbstractCommand parseCommand(String input) throws IllegalArgumentE return parseCommand(rawCommand); } - public static AbstractCommand parseCommand(RawCommand rawCommand) throws IllegalArgumentException{ + public static AbstractCommand parseCommand(RawCommand rawCommand) throws IllegalArgumentException { switch (rawCommand.getCommandName()) { case EXIT_COMMAND: { return new ExitCommand(rawCommand); @@ -49,6 +50,8 @@ public static AbstractCommand parseCommand(RawCommand rawCommand) throws Illegal case FIND_COMMAND: { return new FindCommand(rawCommand); } + case SET_BUDGET_COMMAND: + return new BudgetCommand(rawCommand); default: { return new InvalidCommand(); } From b6a93fdf77d18006ed5b8af749def38bc5b1a6b1 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Mon, 16 Oct 2023 11:44:55 +0800 Subject: [PATCH 090/518] Update Budget Fixes #59 --- .../commands/BudgetCommand.java | 25 ------------- .../commands/SetBudgetCommand.java | 32 +++++++++++++++++ .../seedu/financialplanner/list/Budget.java | 35 +++++++++++++++---- .../financialplanner/list/CashflowList.java | 5 --- .../financialplanner/storage/LoadData.java | 30 +++++++++++----- .../financialplanner/storage/SaveData.java | 2 ++ .../seedu/financialplanner/utils/Parser.java | 11 +++--- 7 files changed, 90 insertions(+), 50 deletions(-) delete mode 100644 src/main/java/seedu/financialplanner/commands/BudgetCommand.java create mode 100644 src/main/java/seedu/financialplanner/commands/SetBudgetCommand.java diff --git a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java deleted file mode 100644 index 9c4e4ffc53..0000000000 --- a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java +++ /dev/null @@ -1,25 +0,0 @@ -package seedu.financialplanner.commands; - -import seedu.financialplanner.list.Budget; -import seedu.financialplanner.list.CashflowList; - -public class BudgetCommand extends AbstractCommand { - private double budget; - - public BudgetCommand(RawCommand rawCommand) throws IllegalArgumentException { - if (!rawCommand.extraArgs.containsKey("b")) { - throw new IllegalArgumentException("Missing /b argument."); - } - try { - budget = Double.parseDouble(rawCommand.extraArgs.get("b")); - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException("Budget must be a number."); - } - rawCommand.extraArgs.remove("b"); - } - - @Override - public void execute() throws Exception { - CashflowList.INSTANCE.setBudget(new Budget(budget)); - } -} diff --git a/src/main/java/seedu/financialplanner/commands/SetBudgetCommand.java b/src/main/java/seedu/financialplanner/commands/SetBudgetCommand.java new file mode 100644 index 0000000000..729ba203a0 --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/SetBudgetCommand.java @@ -0,0 +1,32 @@ +package seedu.financialplanner.commands; + +import seedu.financialplanner.exceptions.FinancialPlannerException; +import seedu.financialplanner.list.Budget; +import seedu.financialplanner.utils.Ui; + +public class SetBudgetCommand extends AbstractCommand { + private double budget; + + public SetBudgetCommand(RawCommand rawCommand) throws FinancialPlannerException { + if (!rawCommand.extraArgs.containsKey("b")) { + throw new IllegalArgumentException("Missing /b argument."); + } + try { + budget = Double.parseDouble(rawCommand.extraArgs.get("b")); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Budget must be a number."); + } + rawCommand.extraArgs.remove("b"); + + if (Budget.getInitialBudget() != 0) { + throw new FinancialPlannerException("There is an existing budget, did you mean updatebudget?"); + } + } + + @Override + public void execute() { + Budget.setBudget(budget); + + Ui.INSTANCE.showMessage("A monthly budget of " + String.format("%.2f", Budget.getInitialBudget()) + " has been set."); + } +} diff --git a/src/main/java/seedu/financialplanner/list/Budget.java b/src/main/java/seedu/financialplanner/list/Budget.java index e39de3ecda..4892da0eea 100644 --- a/src/main/java/seedu/financialplanner/list/Budget.java +++ b/src/main/java/seedu/financialplanner/list/Budget.java @@ -1,14 +1,37 @@ package seedu.financialplanner.list; -public class Budget extends Cashflow { +public abstract class Budget { private static final int MONTH = 30; + private static double initialBudget = 0; private static double currentBudget = 0; - public Budget(double value) { - super(value, null, MONTH); + + public static void setBudget(double amount) { + initialBudget = amount; + currentBudget = amount; + } + + public static double getInitialBudget() { + return initialBudget; + } + + public static void setInitialBudget(double initialBudget) { + Budget.initialBudget = initialBudget; + } + + public static double getCurrentBudget() { + return currentBudget; + } + + public static void setCurrentBudget(double currentBudget) { + Budget.currentBudget = currentBudget; + } + + public static void load(double initial, double current) { + initialBudget = initial; + currentBudget = current; } - @Override - public String formatString() { - return "B | " + this.value; + public static String formatString() { + return "B | " + initialBudget + " | " + currentBudget; } } diff --git a/src/main/java/seedu/financialplanner/list/CashflowList.java b/src/main/java/seedu/financialplanner/list/CashflowList.java index a2b7d4e348..cef3eafc17 100644 --- a/src/main/java/seedu/financialplanner/list/CashflowList.java +++ b/src/main/java/seedu/financialplanner/list/CashflowList.java @@ -51,11 +51,6 @@ public void addExpense(double value, String type, int recur) { printAddedCashflow("expense"); } - public void setBudget(Budget budget) { - list.add(budget); - - System.out.println("A monthly budget of " + String.format("%.2f", budget.value) + " has been set."); - } public void load(Cashflow entry) { list.add(entry); diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index e2fae4961c..32947a64ee 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -17,9 +17,21 @@ public static void load(CashflowList cashflowList, Ui ui, String filePath) throw while(inputFile.hasNext()) { line = inputFile.nextLine(); - final Cashflow entry = getEntry(line); + String[] split = line.split("\\|"); + String type = split[0].trim(); + switch (type) { + case "I": + case "E": + final Cashflow entry = getEntry(type, split); + cashflowList.load(entry); + break; + case "B": + loadBudget(split); + break; + default: + throw new FinancialPlannerException("Error loading file"); + } - cashflowList.load(entry); } inputFile.close(); } catch (IOException e) { @@ -35,6 +47,12 @@ public static void load(CashflowList cashflowList, Ui ui, String filePath) throw } } + private static void loadBudget(String[] split) { + double initial = Double.parseDouble(split[1].trim()); + double current = Double.parseDouble(split[2].trim()); + Budget.load(initial, current); + } + private static boolean createNewFile(Ui ui) { String line = ui.input(); while (!line.equalsIgnoreCase("y") && !line.equalsIgnoreCase("n")) { @@ -45,9 +63,7 @@ private static boolean createNewFile(Ui ui) { return line.equalsIgnoreCase("y"); } - private static Cashflow getEntry(String line) throws FinancialPlannerException { - String[] split = line.split("\\|"); - String type = split[0].trim(); + private static Cashflow getEntry(String type, String[] split) throws FinancialPlannerException { double value; int recur; Cashflow entry; @@ -63,10 +79,6 @@ private static Cashflow getEntry(String line) throws FinancialPlannerException { recur = Integer.parseInt(split[3].trim()); entry = new Expense(value, split[2].trim(), recur); break; - case "B": - value = Double.parseDouble(split[1].trim()); - entry = new Budget(value); - break; default: throw new FinancialPlannerException("Error loading file"); } diff --git a/src/main/java/seedu/financialplanner/storage/SaveData.java b/src/main/java/seedu/financialplanner/storage/SaveData.java index b5fa6bc2f6..d87f449bc1 100644 --- a/src/main/java/seedu/financialplanner/storage/SaveData.java +++ b/src/main/java/seedu/financialplanner/storage/SaveData.java @@ -1,6 +1,7 @@ package seedu.financialplanner.storage; import seedu.financialplanner.exceptions.FinancialPlannerException; +import seedu.financialplanner.list.Budget; import seedu.financialplanner.list.Cashflow; import seedu.financialplanner.list.CashflowList; @@ -14,6 +15,7 @@ public static void save(CashflowList cashflowList, String filePath) throws Finan for (Cashflow entry : cashflowList.list) { fw.write(entry.formatString() + "\n"); } + fw.write(Budget.formatString() + "\n"); fw.close(); } catch (IOException e) { throw new FinancialPlannerException("Error saving file."); diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index 406ea00255..624fc387aa 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -10,7 +10,7 @@ import seedu.financialplanner.commands.InvalidCommand; import seedu.financialplanner.commands.RawCommand; import seedu.financialplanner.commands.WatchListCommand; -import seedu.financialplanner.commands.BudgetCommand; +import seedu.financialplanner.commands.SetBudgetCommand; import seedu.financialplanner.exceptions.FinancialPlannerException; import java.util.ArrayList; @@ -28,12 +28,12 @@ public class Parser { private static final String FIND_COMMAND = "find"; private static final String SET_BUDGET_COMMAND = "setbudget"; - public static AbstractCommand parseCommand(String input) throws IllegalArgumentException { + public static AbstractCommand parseCommand(String input) throws FinancialPlannerException { RawCommand rawCommand = parseRawCommand(input); return parseCommand(rawCommand); } - public static AbstractCommand parseCommand(RawCommand rawCommand) throws IllegalArgumentException { + public static AbstractCommand parseCommand(RawCommand rawCommand) throws FinancialPlannerException { switch (rawCommand.getCommandName()) { case EXIT_COMMAND: { return new ExitCommand(rawCommand); @@ -50,8 +50,9 @@ public static AbstractCommand parseCommand(RawCommand rawCommand) throws Illegal case FIND_COMMAND: { return new FindCommand(rawCommand); } - case SET_BUDGET_COMMAND: - return new BudgetCommand(rawCommand); + case SET_BUDGET_COMMAND: { + return new SetBudgetCommand(rawCommand); + } default: { return new InvalidCommand(); } From 7dc589fac79d029a9161b1e73f9dd6c09b230cff Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Mon, 16 Oct 2023 12:01:48 +0800 Subject: [PATCH 091/518] Update budget when new expense is added Fixes #60 --- .../commands/EntryCommand.java | 20 ++++++++++++++++++- .../commands/SetBudgetCommand.java | 2 +- .../seedu/financialplanner/list/Budget.java | 8 ++++++-- .../seedu/financialplanner/list/Cashflow.java | 4 ++++ 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/EntryCommand.java b/src/main/java/seedu/financialplanner/commands/EntryCommand.java index f10ebe4207..6307713a25 100644 --- a/src/main/java/seedu/financialplanner/commands/EntryCommand.java +++ b/src/main/java/seedu/financialplanner/commands/EntryCommand.java @@ -1,11 +1,15 @@ package seedu.financialplanner.commands; import seedu.financialplanner.enumerations.EntryCategory; +import seedu.financialplanner.list.Budget; +import seedu.financialplanner.list.Cashflow; import seedu.financialplanner.list.CashflowList; import seedu.financialplanner.utils.Ui; import java.util.ArrayList; +import static java.lang.Math.abs; + public class EntryCommand extends AbstractCommand { protected double amount; protected EntryCategory category; @@ -57,11 +61,25 @@ public void execute() { CashflowList.INSTANCE.addIncome(amount, type, recur); break; case EXPENSE: - CashflowList.INSTANCE.addExpense(amount, type, recur); + CashflowList list = CashflowList.INSTANCE; + list.addExpense(amount, type, recur); + if (Budget.hasBudget()) { + deductFromBudget(list.list.get(list.list.size() - 1)); + } break; default: Ui.INSTANCE.showMessage("Unidentified entry."); break; } } + + private static void deductFromBudget(Cashflow entry) { + double expenseAmount = entry.getValue(); + Budget.deduct(expenseAmount); + if (Budget.getCurrentBudget() <= 0) { + Ui.INSTANCE.showMessage("You have exceeded your current budget by: " + abs(Budget.getCurrentBudget())); + } else if (Budget.getCurrentBudget() > 0) { + Ui.INSTANCE.showMessage("Your remaining budget is: " + Budget.getCurrentBudget()); + } + } } diff --git a/src/main/java/seedu/financialplanner/commands/SetBudgetCommand.java b/src/main/java/seedu/financialplanner/commands/SetBudgetCommand.java index 729ba203a0..213411b90b 100644 --- a/src/main/java/seedu/financialplanner/commands/SetBudgetCommand.java +++ b/src/main/java/seedu/financialplanner/commands/SetBudgetCommand.java @@ -18,7 +18,7 @@ public SetBudgetCommand(RawCommand rawCommand) throws FinancialPlannerException } rawCommand.extraArgs.remove("b"); - if (Budget.getInitialBudget() != 0) { + if (Budget.hasBudget()) { throw new FinancialPlannerException("There is an existing budget, did you mean updatebudget?"); } } diff --git a/src/main/java/seedu/financialplanner/list/Budget.java b/src/main/java/seedu/financialplanner/list/Budget.java index 4892da0eea..08bec3d21a 100644 --- a/src/main/java/seedu/financialplanner/list/Budget.java +++ b/src/main/java/seedu/financialplanner/list/Budget.java @@ -22,8 +22,8 @@ public static double getCurrentBudget() { return currentBudget; } - public static void setCurrentBudget(double currentBudget) { - Budget.currentBudget = currentBudget; + public static void deduct(double amount) { + Budget.currentBudget -= amount; } public static void load(double initial, double current) { @@ -31,6 +31,10 @@ public static void load(double initial, double current) { currentBudget = current; } + public static boolean hasBudget() { + return initialBudget != 0; + } + public static String formatString() { return "B | " + initialBudget + " | " + currentBudget; } diff --git a/src/main/java/seedu/financialplanner/list/Cashflow.java b/src/main/java/seedu/financialplanner/list/Cashflow.java index 67a7ab2a9f..8aac4b139c 100644 --- a/src/main/java/seedu/financialplanner/list/Cashflow.java +++ b/src/main/java/seedu/financialplanner/list/Cashflow.java @@ -19,6 +19,10 @@ public Cashflow() { this.recur = 0; } + public double getValue() { + return value; + } + public String formatString() { return this.value + " | " + this.type + " | " + this.recur; } From aa68bb059f3bf8201c0830bd13a714577428adbd Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Mon, 16 Oct 2023 13:08:41 +0800 Subject: [PATCH 092/518] Add ability to update budget --- .../commands/BudgetCommand.java | 56 +++++++++++++++++++ .../commands/EntryCommand.java | 2 +- .../commands/SetBudgetCommand.java | 32 ----------- .../seedu/financialplanner/list/Budget.java | 13 ++++- .../seedu/financialplanner/utils/Parser.java | 8 +-- 5 files changed, 72 insertions(+), 39 deletions(-) create mode 100644 src/main/java/seedu/financialplanner/commands/BudgetCommand.java delete mode 100644 src/main/java/seedu/financialplanner/commands/SetBudgetCommand.java diff --git a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java new file mode 100644 index 0000000000..8b68bdca2e --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java @@ -0,0 +1,56 @@ +package seedu.financialplanner.commands; + +import seedu.financialplanner.exceptions.FinancialPlannerException; +import seedu.financialplanner.list.Budget; +import seedu.financialplanner.utils.Ui; + +public class BudgetCommand extends AbstractCommand { + private double budget; + private String command; + + public BudgetCommand(RawCommand rawCommand) throws FinancialPlannerException { + command = String.join(" ", rawCommand.args); + if (!command.equals("set") && !command.equals("update")) { + throw new FinancialPlannerException("Please indicate whether budget is to be set or update."); + } + + if (command.equals("set") && Budget.hasBudget()) { + throw new FinancialPlannerException("There is an existing budget, did you mean update?"); + } + + if (!rawCommand.extraArgs.containsKey("b")) { + throw new IllegalArgumentException("Missing /b argument."); + } + + try { + budget = Double.parseDouble(rawCommand.extraArgs.get("b")); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Budget must be a number."); + } + rawCommand.extraArgs.remove("b"); + } + + @Override + public void execute() { + switch (command) { + case "set": + Budget.setBudget(budget); + Ui.INSTANCE.showMessage("A monthly budget of " + String.format("%.2f", Budget.getInitialBudget()) + + " has been set."); + break; + case "update": + Ui.INSTANCE.showMessage("Budget has been updated:\nOld initial budget: " + Budget.getInitialBudget() + + "\nOld current budget: " + Budget.getCurrentBudget()); + Budget.updateBudget(budget); + Ui.INSTANCE.showMessage("New initial budget: " + Budget.getInitialBudget() + "\nNew current budget: " + + Budget.getCurrentBudget()); + if (Budget.getCurrentBudget() <= 0) { + Ui.INSTANCE.showMessage("You have exceeded your budget, please update to a larger budget or " + + "reset the current budget to initial budget."); + } + break; + default: + Ui.INSTANCE.showMessage("Unknown command."); + } + } +} diff --git a/src/main/java/seedu/financialplanner/commands/EntryCommand.java b/src/main/java/seedu/financialplanner/commands/EntryCommand.java index 6307713a25..9de069de74 100644 --- a/src/main/java/seedu/financialplanner/commands/EntryCommand.java +++ b/src/main/java/seedu/financialplanner/commands/EntryCommand.java @@ -79,7 +79,7 @@ private static void deductFromBudget(Cashflow entry) { if (Budget.getCurrentBudget() <= 0) { Ui.INSTANCE.showMessage("You have exceeded your current budget by: " + abs(Budget.getCurrentBudget())); } else if (Budget.getCurrentBudget() > 0) { - Ui.INSTANCE.showMessage("Your remaining budget is: " + Budget.getCurrentBudget()); + Ui.INSTANCE.showMessage("Your remaining budget for the month is: " + Budget.getCurrentBudget()); } } } diff --git a/src/main/java/seedu/financialplanner/commands/SetBudgetCommand.java b/src/main/java/seedu/financialplanner/commands/SetBudgetCommand.java deleted file mode 100644 index 213411b90b..0000000000 --- a/src/main/java/seedu/financialplanner/commands/SetBudgetCommand.java +++ /dev/null @@ -1,32 +0,0 @@ -package seedu.financialplanner.commands; - -import seedu.financialplanner.exceptions.FinancialPlannerException; -import seedu.financialplanner.list.Budget; -import seedu.financialplanner.utils.Ui; - -public class SetBudgetCommand extends AbstractCommand { - private double budget; - - public SetBudgetCommand(RawCommand rawCommand) throws FinancialPlannerException { - if (!rawCommand.extraArgs.containsKey("b")) { - throw new IllegalArgumentException("Missing /b argument."); - } - try { - budget = Double.parseDouble(rawCommand.extraArgs.get("b")); - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException("Budget must be a number."); - } - rawCommand.extraArgs.remove("b"); - - if (Budget.hasBudget()) { - throw new FinancialPlannerException("There is an existing budget, did you mean updatebudget?"); - } - } - - @Override - public void execute() { - Budget.setBudget(budget); - - Ui.INSTANCE.showMessage("A monthly budget of " + String.format("%.2f", Budget.getInitialBudget()) + " has been set."); - } -} diff --git a/src/main/java/seedu/financialplanner/list/Budget.java b/src/main/java/seedu/financialplanner/list/Budget.java index 08bec3d21a..e3eaafac75 100644 --- a/src/main/java/seedu/financialplanner/list/Budget.java +++ b/src/main/java/seedu/financialplanner/list/Budget.java @@ -14,8 +14,17 @@ public static double getInitialBudget() { return initialBudget; } - public static void setInitialBudget(double initialBudget) { - Budget.initialBudget = initialBudget; + public static void updateBudget(double budget) { + double diff; + if (budget > initialBudget) { + diff = budget - initialBudget; + initialBudget = budget; + currentBudget += diff; + } else if (budget < initialBudget) { + diff = initialBudget - budget; + initialBudget = budget; + currentBudget -= diff; + } } public static double getCurrentBudget() { diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index 624fc387aa..78a098c3a0 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -10,7 +10,7 @@ import seedu.financialplanner.commands.InvalidCommand; import seedu.financialplanner.commands.RawCommand; import seedu.financialplanner.commands.WatchListCommand; -import seedu.financialplanner.commands.SetBudgetCommand; +import seedu.financialplanner.commands.BudgetCommand; import seedu.financialplanner.exceptions.FinancialPlannerException; import java.util.ArrayList; @@ -26,7 +26,7 @@ public class Parser { private static final String ADD_ENTRY_COMMAND = "add"; private static final String ADD_STOCK_COMMAND = "addstock"; private static final String FIND_COMMAND = "find"; - private static final String SET_BUDGET_COMMAND = "setbudget"; + private static final String BUDGET_COMMAND = "budget"; public static AbstractCommand parseCommand(String input) throws FinancialPlannerException { RawCommand rawCommand = parseRawCommand(input); @@ -50,8 +50,8 @@ public static AbstractCommand parseCommand(RawCommand rawCommand) throws Financi case FIND_COMMAND: { return new FindCommand(rawCommand); } - case SET_BUDGET_COMMAND: { - return new SetBudgetCommand(rawCommand); + case BUDGET_COMMAND: { + return new BudgetCommand(rawCommand); } default: { return new InvalidCommand(); From 4a25982c9f7dea52d0d5b50b0b9ed4c6da622a22 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Mon, 16 Oct 2023 13:18:49 +0800 Subject: [PATCH 093/518] Update test files and format printing of double to 2d.p --- .../seedu/financialplanner/commands/BudgetCommand.java | 9 +++++---- .../seedu/financialplanner/commands/EntryCommand.java | 6 ++++-- text-ui-test/EXPECTED.TXT | 9 +++++++++ text-ui-test/input.txt | 4 +++- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java index 8b68bdca2e..c9f589fc4d 100644 --- a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java +++ b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java @@ -39,11 +39,12 @@ public void execute() { + " has been set."); break; case "update": - Ui.INSTANCE.showMessage("Budget has been updated:\nOld initial budget: " + Budget.getInitialBudget() + - "\nOld current budget: " + Budget.getCurrentBudget()); + Ui.INSTANCE.showMessage("Budget has been updated:\nOld initial budget: " + + String.format("%.2f", Budget.getInitialBudget()) + "\nOld current budget: " + + String.format("%.2f", Budget.getCurrentBudget())); Budget.updateBudget(budget); - Ui.INSTANCE.showMessage("New initial budget: " + Budget.getInitialBudget() + "\nNew current budget: " + - Budget.getCurrentBudget()); + Ui.INSTANCE.showMessage("New initial budget: " + String.format("%.2f", Budget.getInitialBudget()) + + "\nNew current budget: " + String.format("%.2f", Budget.getCurrentBudget())); if (Budget.getCurrentBudget() <= 0) { Ui.INSTANCE.showMessage("You have exceeded your budget, please update to a larger budget or " + "reset the current budget to initial budget."); diff --git a/src/main/java/seedu/financialplanner/commands/EntryCommand.java b/src/main/java/seedu/financialplanner/commands/EntryCommand.java index 9de069de74..074c64c757 100644 --- a/src/main/java/seedu/financialplanner/commands/EntryCommand.java +++ b/src/main/java/seedu/financialplanner/commands/EntryCommand.java @@ -77,9 +77,11 @@ private static void deductFromBudget(Cashflow entry) { double expenseAmount = entry.getValue(); Budget.deduct(expenseAmount); if (Budget.getCurrentBudget() <= 0) { - Ui.INSTANCE.showMessage("You have exceeded your current budget by: " + abs(Budget.getCurrentBudget())); + Ui.INSTANCE.showMessage("You have exceeded your current budget by: " + + String.format("%.2f", abs(Budget.getCurrentBudget()))); } else if (Budget.getCurrentBudget() > 0) { - Ui.INSTANCE.showMessage("Your remaining budget for the month is: " + Budget.getCurrentBudget()); + Ui.INSTANCE.showMessage("Your remaining budget for the month is: " + + String.format("%.2f", Budget.getCurrentBudget())); } } } diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 086723a98e..b05687d50f 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -22,5 +22,14 @@ You have successfully added: Gamestop Corporation - Class A Use Watchlist to view it! A monthly budget of 5000.00 has been set. +Budget has been updated: +Old initial budget: 5000.00 +Old current budget: 5000.00 +New initial budget: 3000.00 +New current budget: 3000.00 +Added expense of value: 200.00 to the list. +type: airpods +balance: 4699.91 +Your remaining budget for the month is: 2800.00 Unknown command. Please try again. Exiting Financial Planner. Goodbye. diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index a5ed00c639..36e9912655 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -4,6 +4,8 @@ add expense /a 100 /t daily necessities /r 30 add expense /a 123.21 /t books addstock /s MSFT addstock /s GME -setbudget /b 5000 +budget set /b 5000 +budget update /b 3000 +add expense /a 200 /t airpods sdf exit \ No newline at end of file From 8ff7b412958e60cf34968d32ce1d8b2e0a17d58c Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Mon, 16 Oct 2023 14:01:57 +0800 Subject: [PATCH 094/518] Add JUnit tests for Budget and update ValidData.txt Fixes #73 --- .../financialplanner/list/BudgetTest.java | 42 +++++++++++++++++++ src/test/testData/ValidData.txt | 3 +- 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 src/test/java/seedu/financialplanner/list/BudgetTest.java diff --git a/src/test/java/seedu/financialplanner/list/BudgetTest.java b/src/test/java/seedu/financialplanner/list/BudgetTest.java new file mode 100644 index 0000000000..5ad0846fd3 --- /dev/null +++ b/src/test/java/seedu/financialplanner/list/BudgetTest.java @@ -0,0 +1,42 @@ +package seedu.financialplanner.list; + +import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import seedu.financialplanner.commands.BudgetCommand; +import seedu.financialplanner.commands.EntryCommand; +import seedu.financialplanner.utils.Parser; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertFalse; + +@TestMethodOrder(OrderAnnotation.class) +public class BudgetTest { + @Test + @Order(1) + public void testSetBudget() { + assertFalse(Budget.hasBudget()); + Budget.setBudget(500); + assertTrue(Budget.hasBudget()); + assertEquals(500, Budget.getInitialBudget()); + assertEquals(500, Budget.getCurrentBudget()); + } + + @Test + @Order(2) + public void testNewExpense() { + EntryCommand testExpense = new EntryCommand(Parser.parseRawCommand("add expense /a 50 /t food")); + testExpense.execute(); + assertEquals(450, Budget.getCurrentBudget()); + } + + @Test + @Order(3) + public void testUpdateBudget() { + Budget.updateBudget(1000); + assertEquals(1000, Budget.getInitialBudget()); + assertEquals(950, Budget.getCurrentBudget()); + } +} diff --git a/src/test/testData/ValidData.txt b/src/test/testData/ValidData.txt index 948450ef20..915220c562 100644 --- a/src/test/testData/ValidData.txt +++ b/src/test/testData/ValidData.txt @@ -1,2 +1,3 @@ I | 123.12 | allowance | 0 -E | 100.0 | daily necessities | 30 \ No newline at end of file +E | 100.0 | daily necessities | 30 +B | 0.0 | 0.0 \ No newline at end of file From 6bfd86e9bf988f2b31c9683606facdc1550f2475 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Mon, 16 Oct 2023 14:05:11 +0800 Subject: [PATCH 095/518] Update code to follow coding standards --- src/main/java/seedu/financialplanner/storage/LoadData.java | 6 +++++- src/test/java/seedu/financialplanner/list/BudgetTest.java | 1 - 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 32947a64ee..829e1a9bfb 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -1,7 +1,11 @@ package seedu.financialplanner.storage; import seedu.financialplanner.exceptions.FinancialPlannerException; -import seedu.financialplanner.list.*; +import seedu.financialplanner.list.Budget; +import seedu.financialplanner.list.Cashflow; +import seedu.financialplanner.list.CashflowList; +import seedu.financialplanner.list.Income; +import seedu.financialplanner.list.Expense; import seedu.financialplanner.utils.Ui; import java.io.FileReader; diff --git a/src/test/java/seedu/financialplanner/list/BudgetTest.java b/src/test/java/seedu/financialplanner/list/BudgetTest.java index 5ad0846fd3..b30dcbbe26 100644 --- a/src/test/java/seedu/financialplanner/list/BudgetTest.java +++ b/src/test/java/seedu/financialplanner/list/BudgetTest.java @@ -4,7 +4,6 @@ import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestMethodOrder; -import seedu.financialplanner.commands.BudgetCommand; import seedu.financialplanner.commands.EntryCommand; import seedu.financialplanner.utils.Parser; From c45bba6e16e98a3ca9c500a5ec64c598ec444c49 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Mon, 16 Oct 2023 14:08:12 +0800 Subject: [PATCH 096/518] Remove redundant get() and size() methods in cashFlowList --- .../java/seedu/financialplanner/commands/FindCommand.java | 6 +++--- .../java/seedu/financialplanner/list/CashflowList.java | 8 -------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/FindCommand.java b/src/main/java/seedu/financialplanner/commands/FindCommand.java index 6aabcdf7ee..56b7eff564 100644 --- a/src/main/java/seedu/financialplanner/commands/FindCommand.java +++ b/src/main/java/seedu/financialplanner/commands/FindCommand.java @@ -24,9 +24,9 @@ public void execute() { WatchList watchList = WatchList.INSTANCE; ArrayList foundedFinancialList = new ArrayList<>(); ArrayList foundedWatchList = new ArrayList<>(); - for (int i = 0; i < cashflowList.size(); i++) { - if (cashflowList.get(i).formatString().contains(description)) { - foundedFinancialList.add(cashflowList.get(i).formatString()); + for (int i = 0; i < cashflowList.list.size(); i++) { + if (cashflowList.list.get(i).formatString().contains(description)) { + foundedFinancialList.add(cashflowList.list.get(i).formatString()); } } if (!foundedFinancialList.isEmpty()) { diff --git a/src/main/java/seedu/financialplanner/list/CashflowList.java b/src/main/java/seedu/financialplanner/list/CashflowList.java index cef3eafc17..af63077c65 100644 --- a/src/main/java/seedu/financialplanner/list/CashflowList.java +++ b/src/main/java/seedu/financialplanner/list/CashflowList.java @@ -64,12 +64,4 @@ public String getList() { } return output; } - - public Cashflow get(int index) { - return list.get(index); - } - - public int size() { - return list.size(); - } } From e417fcac442470226432184427bd86a06da278f7 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Mon, 16 Oct 2023 14:15:40 +0800 Subject: [PATCH 097/518] Update error handling for update budget --- .../java/seedu/financialplanner/commands/BudgetCommand.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java index c9f589fc4d..1dfed2528f 100644 --- a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java +++ b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java @@ -18,6 +18,10 @@ public BudgetCommand(RawCommand rawCommand) throws FinancialPlannerException { throw new FinancialPlannerException("There is an existing budget, did you mean update?"); } + if (command.equals("update") && !Budget.hasBudget()) { + throw new FinancialPlannerException("There is no budget set yet, did you mean set?"); + } + if (!rawCommand.extraArgs.containsKey("b")) { throw new IllegalArgumentException("Missing /b argument."); } From 68fc9ae55171009c217fc93e846fa88e4c0b913a Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 16 Oct 2023 14:44:34 +0800 Subject: [PATCH 098/518] Fix identation in visualizer --- .../financialplanner/visualisations/Visualizer.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java index a5abc520c9..7371b39129 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java @@ -36,11 +36,11 @@ public static void displayPieChart (Map expensesByCat) { // Customize Chart Color[] sliceColors = new Color[] { - new Color(224, 68, 14), - new Color(230, 105, 62), - new Color(236, 143, 110), - new Color(243, 180, 159), - new Color(246, 199, 182) + new Color(224, 68, 14), + new Color(230, 105, 62), + new Color(236, 143, 110), + new Color(243, 180, 159), + new Color(246, 199, 182) }; chart.getStyler().setSeriesColors(sliceColors); From c689389905882a16a1e1aa27a4fbfd4936ba22a3 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 16 Oct 2023 15:12:47 +0800 Subject: [PATCH 099/518] Remove dead code --- src/main/java/seedu/financialplanner/utils/Parser.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index 6dbc359e88..66d656df1c 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -105,11 +105,4 @@ public static RawCommand parseRawCommand(String input) throws IllegalArgumentExc return new RawCommand(commandName, args, extraArgs); } - -// private static Command parseVis(String restOfInput) { -// String[] split = restOfInput.trim().split("t/|c/"); -// String type = split[1].trim(); -// String chart = split[2].trim(); -// return new VisCommand(type, chart); -// } } From 7084894811134dccb133b5b495c4bc0c0c96c9ea Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 16 Oct 2023 15:33:26 +0800 Subject: [PATCH 100/518] Wrap line to reduce line length --- .../commands/{EntryTest.java => AddCashflowCommandTest.java} | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) rename src/test/java/seedu/financialplanner/commands/{EntryTest.java => AddCashflowCommandTest.java} (90%) diff --git a/src/test/java/seedu/financialplanner/commands/EntryTest.java b/src/test/java/seedu/financialplanner/commands/AddCashflowCommandTest.java similarity index 90% rename from src/test/java/seedu/financialplanner/commands/EntryTest.java rename to src/test/java/seedu/financialplanner/commands/AddCashflowCommandTest.java index 0d4db8e67e..d9a4a2b4d4 100644 --- a/src/test/java/seedu/financialplanner/commands/EntryTest.java +++ b/src/test/java/seedu/financialplanner/commands/AddCashflowCommandTest.java @@ -8,7 +8,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -class EntryTest { +class AddCashflowCommandTest { private Ui ui = Ui.INSTANCE; private CashflowList cashflowList = CashflowList.INSTANCE; private WatchList watchList = WatchList.INSTANCE; @@ -17,7 +17,8 @@ class EntryTest { void testExecute() { CashflowList.INSTANCE.list.clear(); - AddCashflowCommand testEntry = new AddCashflowCommand(Parser.parseRawCommand("add income /a 300 /t work /r 30")); + AddCashflowCommand testEntry = new AddCashflowCommand(Parser + .parseRawCommand("add income /a 300 /t work /r 30")); testEntry.execute(); assertEquals(300, testEntry.amount); assertEquals("work", testEntry.type); From 89d5babd83af99396efcc453995b7002edf6f988 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Mon, 16 Oct 2023 15:34:23 +0800 Subject: [PATCH 101/518] Standardise case statements --- .../seedu/financialplanner/utils/Parser.java | 23 ++++++------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index 78a098c3a0..06c0069007 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -1,7 +1,5 @@ package seedu.financialplanner.utils; - - import seedu.financialplanner.commands.AbstractCommand; import seedu.financialplanner.commands.AddStockCommand; import seedu.financialplanner.commands.EntryCommand; @@ -35,28 +33,21 @@ public static AbstractCommand parseCommand(String input) throws FinancialPlanner public static AbstractCommand parseCommand(RawCommand rawCommand) throws FinancialPlannerException { switch (rawCommand.getCommandName()) { - case EXIT_COMMAND: { + case EXIT_COMMAND: return new ExitCommand(rawCommand); - } - case WATCHLIST_COMMAND: { + case WATCHLIST_COMMAND: return new WatchListCommand(rawCommand); - } - case ADD_ENTRY_COMMAND: { + case ADD_ENTRY_COMMAND: return new EntryCommand(rawCommand); - } - case ADD_STOCK_COMMAND: { + case ADD_STOCK_COMMAND: return new AddStockCommand(rawCommand); - } - case FIND_COMMAND: { + case FIND_COMMAND: return new FindCommand(rawCommand); - } - case BUDGET_COMMAND: { + case BUDGET_COMMAND: return new BudgetCommand(rawCommand); - } - default: { + default: return new InvalidCommand(); } - } } public static RawCommand parseRawCommand(String input) throws IllegalArgumentException{ Iterator iterator = Arrays.stream(input.split(" ")).iterator(); From f97b44048a9b7b92fcb0abbd4ca91161a7d965f5 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 16 Oct 2023 15:43:30 +0800 Subject: [PATCH 102/518] Add functionality to do visualization for both income and expense --- .../financialplanner/commands/VisCommand.java | 2 +- .../visualisations/Categorizer.java | 30 +++++++++++++++++-- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/VisCommand.java b/src/main/java/seedu/financialplanner/commands/VisCommand.java index 85b259f576..dd5cfe51f0 100644 --- a/src/main/java/seedu/financialplanner/commands/VisCommand.java +++ b/src/main/java/seedu/financialplanner/commands/VisCommand.java @@ -30,6 +30,6 @@ public VisCommand(RawCommand rawCommand) throws IllegalArgumentException { } @Override public void execute() throws FinancialPlannerException { - Visualizer.displayChart(chart, Categorizer.sortExpenses(CashflowList.INSTANCE)); + Visualizer.displayChart(chart, Categorizer.sortType(CashflowList.INSTANCE, type)); } } diff --git a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java index 338a570a08..0258709492 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java @@ -1,16 +1,30 @@ package seedu.financialplanner.visualisations; +import seedu.financialplanner.FinancialPlanner; +import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.list.Cashflow; import seedu.financialplanner.list.CashflowList; import seedu.financialplanner.list.Expense; +import seedu.financialplanner.list.Income; import java.util.HashMap; import java.util.Map; public class Categorizer { - public static Map sortExpenses(CashflowList financialList) { + + public static Map sortType(CashflowList cashflowList, String type) throws FinancialPlannerException { + switch (type) { + case "expense": + return sortExpenses(cashflowList); + case "income": + return sortIncome(cashflowList); + default: + throw new FinancialPlannerException("Type not found"); + } + } + public static Map sortExpenses(CashflowList cashflowList) { Map expensesByCat = new HashMap<>(); - for (Cashflow e: financialList.list) { + for (Cashflow e: cashflowList.list) { if (e instanceof Expense) { String key = e.getType(); double value = expensesByCat.getOrDefault(key, 0.0) + e.getValue(); @@ -19,4 +33,16 @@ public static Map sortExpenses(CashflowList financialList) { } return expensesByCat; } + + public static Map sortIncome(CashflowList cashflowList) { + Map incomeByCat = new HashMap<>(); + for (Cashflow e: cashflowList.list) { + if (e instanceof Income) { + String key = e.getType(); + double value = incomeByCat.getOrDefault(key, 0.0) + e.getValue(); + incomeByCat.put(key, value); + } + } + return incomeByCat; + } } From 1f0dd2ff73b0f8937c646a97b15280bbf1a4962f Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 16 Oct 2023 15:54:42 +0800 Subject: [PATCH 103/518] Resolve renaming issues --- src/test/java/seedu/financialplanner/list/BudgetTest.java | 4 ++-- .../seedu/financialplanner/list/CashflowListTest.java | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/java/seedu/financialplanner/list/BudgetTest.java b/src/test/java/seedu/financialplanner/list/BudgetTest.java index b30dcbbe26..b7b133d9e2 100644 --- a/src/test/java/seedu/financialplanner/list/BudgetTest.java +++ b/src/test/java/seedu/financialplanner/list/BudgetTest.java @@ -4,7 +4,7 @@ import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestMethodOrder; -import seedu.financialplanner.commands.EntryCommand; +import seedu.financialplanner.commands.AddCashflowCommand; import seedu.financialplanner.utils.Parser; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -26,7 +26,7 @@ public void testSetBudget() { @Test @Order(2) public void testNewExpense() { - EntryCommand testExpense = new EntryCommand(Parser.parseRawCommand("add expense /a 50 /t food")); + AddCashflowCommand testExpense = new AddCashflowCommand(Parser.parseRawCommand("add expense /a 50 /t food")); testExpense.execute(); assertEquals(450, Budget.getCurrentBudget()); } diff --git a/src/test/java/seedu/financialplanner/list/CashflowListTest.java b/src/test/java/seedu/financialplanner/list/CashflowListTest.java index 0edf99ef7a..6648ccbe5b 100644 --- a/src/test/java/seedu/financialplanner/list/CashflowListTest.java +++ b/src/test/java/seedu/financialplanner/list/CashflowListTest.java @@ -61,22 +61,22 @@ void testAddIncomeAndExpense() { @Test void testDeleteIncomeAndExpense() { testList.deleteCashflow(CashflowCategory.INCOME, 2); - assertEquals(3, testList.size()); + assertEquals(3, testList.list.size()); double roundedBalance = Cashflow.round(Cashflow.balance, 2); assertEquals("-15.00", decimalFormat.format(roundedBalance)); testList.delete(1); - assertEquals(2, testList.size()); + assertEquals(2, testList.list.size()); roundedBalance = Cashflow.round(Cashflow.balance, 2); assertEquals("-30.00", decimalFormat.format(roundedBalance)); testList.deleteCashflow(CashflowCategory.EXPENSE, 2); - assertEquals(1, testList.size()); + assertEquals(1, testList.list.size()); roundedBalance = Cashflow.round(Cashflow.balance, 2); assertEquals("-10.00", decimalFormat.format(roundedBalance)); testList.delete(1); - assertEquals(0, testList.size()); + assertEquals(0, testList.list.size()); roundedBalance = Cashflow.round(Cashflow.balance, 2); assertEquals("0.00", decimalFormat.format(roundedBalance)); } From 2a0a2fb3bf353c2ec7d9faf9f4b26be38addb9cb Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 16 Oct 2023 15:59:40 +0800 Subject: [PATCH 104/518] Fix code style --- .../seedu/financialplanner/visualisations/Categorizer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java index 0258709492..91d3fbc23f 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java @@ -1,6 +1,5 @@ package seedu.financialplanner.visualisations; -import seedu.financialplanner.FinancialPlanner; import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.list.Cashflow; import seedu.financialplanner.list.CashflowList; @@ -12,7 +11,8 @@ public class Categorizer { - public static Map sortType(CashflowList cashflowList, String type) throws FinancialPlannerException { + public static Map sortType(CashflowList cashflowList, String type) + throws FinancialPlannerException { switch (type) { case "expense": return sortExpenses(cashflowList); From a52b60c16680aa993e79f500e36270336a33aa29 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 16 Oct 2023 16:24:20 +0800 Subject: [PATCH 105/518] Update text ui test --- text-ui-test/EXPECTED.TXT | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 377f938270..1f82a4c0e4 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -57,9 +57,11 @@ Old initial budget: 5000.00 Old current budget: 5000.00 New initial budget: 3000.00 New current budget: 3000.00 -Added expense of value: 200.00 to the list. -type: airpods -balance: 4699.91 +You have added an Expense + Type: airpods + Amount: 200.00 +to the Financial Planner. +Balance: -200.00 Your remaining budget for the month is: 2800.00 Unknown command. Please try again. -Exiting Financial Planner. Goodbye. +Exiting Financial Planner. Goodbye. \ No newline at end of file From db2e3b0c317e22cb6b1361ad35b76a83f9323a52 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 16 Oct 2023 16:26:58 +0800 Subject: [PATCH 106/518] Add newline to end of expected.txt file --- text-ui-test/EXPECTED.TXT | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 1f82a4c0e4..964ec748b9 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -64,4 +64,4 @@ to the Financial Planner. Balance: -200.00 Your remaining budget for the month is: 2800.00 Unknown command. Please try again. -Exiting Financial Planner. Goodbye. \ No newline at end of file +Exiting Financial Planner. Goodbye. From 2c4321ec694fab448316d4670acb2409d60896d6 Mon Sep 17 00:00:00 2001 From: hshiah Date: Mon, 16 Oct 2023 16:35:55 +0800 Subject: [PATCH 107/518] Add reminder --- .../commands/AddReminderCommand.java | 31 +++++++++++++++++++ .../financialplanner/reminder/Reminder.java | 29 +++++++++++++++++ .../reminder/ReminderList.java | 24 ++++++++++++++ .../seedu/financialplanner/utils/Parser.java | 5 ++- 4 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 src/main/java/seedu/financialplanner/commands/AddReminderCommand.java create mode 100644 src/main/java/seedu/financialplanner/reminder/Reminder.java create mode 100644 src/main/java/seedu/financialplanner/reminder/ReminderList.java diff --git a/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java b/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java new file mode 100644 index 0000000000..bbc8cb1ce3 --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java @@ -0,0 +1,31 @@ +package seedu.financialplanner.commands; +import seedu.financialplanner.reminder.ReminderList; +import seedu.financialplanner.utils.Ui; +public class AddReminderCommand extends AbstractCommand{ + private final String type; + private final String date; + + public AddReminderCommand(RawCommand rawCommand) throws IllegalArgumentException { + String typeString = String.join(" ", rawCommand.args); + if(!rawCommand.extraArgs.containsKey("t")){ + throw new IllegalArgumentException("Reminder must have a type"); + } + type = rawCommand.extraArgs.get("t"); + rawCommand.extraArgs.remove("t"); + if(!rawCommand.extraArgs.containsKey("d")){ + throw new IllegalArgumentException("Reminder must have a date"); + } + date = rawCommand.extraArgs.get("d"); + rawCommand.extraArgs.remove("d"); + if(!rawCommand.extraArgs.isEmpty()){ + String unknownExtraArgument = new java.util.ArrayList<>(rawCommand.extraArgs.keySet()).get(0); + throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); + } + } + + @Override + public void execute() { + ReminderList.INSTANCE.addReminder(type, date); + Ui.INSTANCE.showMessage("Reminder added!"); + } +} diff --git a/src/main/java/seedu/financialplanner/reminder/Reminder.java b/src/main/java/seedu/financialplanner/reminder/Reminder.java new file mode 100644 index 0000000000..b43b16b5ad --- /dev/null +++ b/src/main/java/seedu/financialplanner/reminder/Reminder.java @@ -0,0 +1,29 @@ +package seedu.financialplanner.reminder; + +public class Reminder { + private String type; + private String date; + private boolean isDone = false; + public Reminder(String type, String date) { + this.type = type; + this.date = date; + } + + public String toString() { + String status = isDone ? "Done" : "Not Done"; + return "Reminder: "+this.type + " | " + this.date + " | " + status; + } + public void markAsDone() { + this.isDone = true; + } + + /* + * Returns a string that can be saved to a file. + * Format: type | date | isDone + * Example: "Reminder: Birthday | 2020-10-10 | false" + */ + public String formatString() { + String status = isDone ? "Done" : "Not Done"; + return this.type + " | " + this.date + " | " + this.isDone; + } +} diff --git a/src/main/java/seedu/financialplanner/reminder/ReminderList.java b/src/main/java/seedu/financialplanner/reminder/ReminderList.java new file mode 100644 index 0000000000..f3a4208640 --- /dev/null +++ b/src/main/java/seedu/financialplanner/reminder/ReminderList.java @@ -0,0 +1,24 @@ +package seedu.financialplanner.reminder; +import java.util.ArrayList; +public class ReminderList { + public static final ReminderList INSTANCE = new ReminderList(); + private ArrayList list = new ArrayList<>(); + private ReminderList() { + } + + public void addReminder(String type, String date) { + list.add(new Reminder(type, date)); + } + + public int size() { + return list.size(); + } + + public Reminder get(int index) { + return list.get(index); + } + public void load(Reminder reminder) { + list.add(reminder); + } + //TODO deleteReminder +} diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index 4359d37246..cfc8d3f588 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -10,6 +10,7 @@ import seedu.financialplanner.commands.WatchListCommand; import seedu.financialplanner.commands.VisCommand; import seedu.financialplanner.commands.BudgetCommand; +import seedu.financialplanner.commands.AddReminderCommand; import seedu.financialplanner.exceptions.FinancialPlannerException; import java.util.ArrayList; @@ -27,7 +28,7 @@ public class Parser { private static final String FIND_COMMAND = "find"; private static final String BUDGET_COMMAND = "budget"; private static final String VISUALIZATION_COMMAND = "vis"; - + private static final String ADD_REMINDER_COMMAND = "addreminder"; public static AbstractCommand parseCommand(String input) throws FinancialPlannerException { RawCommand rawCommand = parseRawCommand(input); return parseCommand(rawCommand); @@ -49,6 +50,8 @@ public static AbstractCommand parseCommand(RawCommand rawCommand) throws Financi return new BudgetCommand(rawCommand); case VISUALIZATION_COMMAND: return new VisCommand(rawCommand); + case ADD_REMINDER_COMMAND: + return new AddReminderCommand(rawCommand); default: return new InvalidCommand(); } From 4c12a33358390c7833882cb4ff8856c639a0e0d9 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 16 Oct 2023 17:29:11 +0800 Subject: [PATCH 108/518] Add logger for visualizer and categorizer class --- .../seedu/financialplanner/visualisations/Categorizer.java | 6 +++++- .../seedu/financialplanner/visualisations/Visualizer.java | 7 +++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java index 9880dbe097..f2a41671f4 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java @@ -8,15 +8,19 @@ import java.util.HashMap; import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; public class Categorizer { - + private static final Logger logger = Logger.getLogger("Financial Planner Logger"); public static Map sortType(CashflowList cashflowList, String type) throws FinancialPlannerException { switch (type) { case "expense": + logger.log(Level.INFO, "categorizing expenses"); return sortExpenses(cashflowList); case "income": + logger.log(Level.INFO, "categorizing income"); return sortIncome(cashflowList); default: throw new FinancialPlannerException("Type not found"); diff --git a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java index 7371b39129..8171713852 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java @@ -14,8 +14,12 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; public class Visualizer { + + private static final Logger logger = Logger.getLogger("Financial Planner Logger"); public static void displayChart(String chartType, Map expensesByCat) throws FinancialPlannerException { switch (chartType) { @@ -47,6 +51,7 @@ public static void displayPieChart (Map expensesByCat) { for (Map.Entry set: expensesByCat.entrySet()) { chart.addSeries(set.getKey(), set.getValue()); } + logger.log(Level.INFO, "Showing Pie Chart"); // Show it JFrame swHR = new SwingWrapper<>(chart).displayChart(); javax.swing.SwingUtilities.invokeLater( @@ -65,6 +70,8 @@ public static void displayBarChart (Map expensesByCat) { List values = new ArrayList(expensesByCat.values()); List keys = new ArrayList(expensesByCat.keySet()); chart.addSeries("Expense", keys, values); + + logger.log(Level.INFO, "Showing Bar Chart"); JFrame swHR = new SwingWrapper<>(chart).displayChart(); javax.swing.SwingUtilities.invokeLater( ()->swHR.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE) From 5e6072c3cfd8377d6401e4aa8656c4abf71508fe Mon Sep 17 00:00:00 2001 From: hshiah Date: Mon, 16 Oct 2023 18:03:28 +0800 Subject: [PATCH 109/518] Finish setting goals Fix bugs of find command --- .../commands/FindCommand.java | 4 +-- .../commands/SetGoalCommand.java | 35 +++++++++++++++++++ .../seedu/financialplanner/goal/Goal.java | 24 +++++++++++++ .../seedu/financialplanner/goal/GoalList.java | 22 ++++++++++++ .../seedu/financialplanner/utils/Parser.java | 4 +++ 5 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 src/main/java/seedu/financialplanner/commands/SetGoalCommand.java create mode 100644 src/main/java/seedu/financialplanner/goal/Goal.java create mode 100644 src/main/java/seedu/financialplanner/goal/GoalList.java diff --git a/src/main/java/seedu/financialplanner/commands/FindCommand.java b/src/main/java/seedu/financialplanner/commands/FindCommand.java index 56b7eff564..ec287761c3 100644 --- a/src/main/java/seedu/financialplanner/commands/FindCommand.java +++ b/src/main/java/seedu/financialplanner/commands/FindCommand.java @@ -26,7 +26,7 @@ public void execute() { ArrayList foundedWatchList = new ArrayList<>(); for (int i = 0; i < cashflowList.list.size(); i++) { if (cashflowList.list.get(i).formatString().contains(description)) { - foundedFinancialList.add(cashflowList.list.get(i).formatString()); + foundedFinancialList.add(cashflowList.list.get(i).formatString()+"\tCorresponding index is: "+(i+1)); } } if (!foundedFinancialList.isEmpty()) { @@ -40,7 +40,7 @@ public void execute() { for (int i = 0; i < watchList.size(); i++) { if (watchList.get(i).toString().contains(description)) { - foundedWatchList.add(watchList.get(i).toString()); + foundedWatchList.add(watchList.get(i).toString()+"\tCorresponding index is: "+(i+1)); } } if (!foundedWatchList.isEmpty()) { diff --git a/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java b/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java new file mode 100644 index 0000000000..d41f8440cf --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java @@ -0,0 +1,35 @@ +package seedu.financialplanner.commands; +import seedu.financialplanner.goal.GoalList; +import seedu.financialplanner.utils.Ui; + +public class SetGoalCommand extends AbstractCommand{ + private final String goal; + private int amount; + public SetGoalCommand(RawCommand rawCommand) throws IllegalArgumentException { + String labelString = String.join(" ", rawCommand.args); + if(!rawCommand.extraArgs.containsKey("g")){ + throw new IllegalArgumentException("Goal must have an amount"); + } + try{ + amount = Integer.parseInt(rawCommand.extraArgs.get("g")); + } catch (IllegalArgumentException e){ + throw new IllegalArgumentException("Amount must be a number"); + } + rawCommand.extraArgs.remove("g"); + if(!rawCommand.extraArgs.containsKey("l")){ + throw new IllegalArgumentException("Please specify the content of the goal"); + } + goal = rawCommand.extraArgs.get("l"); + rawCommand.extraArgs.remove("l"); + if(!rawCommand.extraArgs.isEmpty()){ + String unknownExtraArgument = new java.util.ArrayList<>(rawCommand.extraArgs.keySet()).get(0); + throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); + } + } + + @Override + public void execute() { + GoalList.INSTANCE.addGoal(goal, amount); + Ui.INSTANCE.showMessage("Set Goal Successfully!"); + } +} diff --git a/src/main/java/seedu/financialplanner/goal/Goal.java b/src/main/java/seedu/financialplanner/goal/Goal.java new file mode 100644 index 0000000000..0c9c6024a2 --- /dev/null +++ b/src/main/java/seedu/financialplanner/goal/Goal.java @@ -0,0 +1,24 @@ +package seedu.financialplanner.goal; + +public class Goal { + private String label; + private int amount; + private boolean isDone = false; + public Goal(String label, int amount) { + this.label = label; + this.amount = amount; + } + public String toString() { + String status = isDone ? "Done" : "Not Done"; + return "Goal: "+this.label + " | " + this.amount + " | " + status; + } + public void markAsDone() { + //TODO edit the expense to mark the goal as done + this.isDone = true; + } + //TODO delete the Reminde + public String formatString() { + String status = isDone ? "Done" : "Not Done"; + return this.label + " | " + this.amount + " | " + this.isDone; + } +} diff --git a/src/main/java/seedu/financialplanner/goal/GoalList.java b/src/main/java/seedu/financialplanner/goal/GoalList.java new file mode 100644 index 0000000000..2120439cc1 --- /dev/null +++ b/src/main/java/seedu/financialplanner/goal/GoalList.java @@ -0,0 +1,22 @@ +package seedu.financialplanner.goal; +import java.util.ArrayList; +public class GoalList { + public static final GoalList INSTANCE = new GoalList(); + private ArrayList list = new ArrayList<>(); + + private GoalList() { + } + public void addGoal(String label, int amount) { + list.add(new Goal(label, amount)); + } + public int size() { + return list.size(); + } + public Goal get(int index) { + return list.get(index); + } + public void load(Goal goal) { + list.add(goal); + } + //TODO deleteGoal +} diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index cfc8d3f588..467936993c 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -11,6 +11,7 @@ import seedu.financialplanner.commands.VisCommand; import seedu.financialplanner.commands.BudgetCommand; import seedu.financialplanner.commands.AddReminderCommand; +import seedu.financialplanner.commands.SetGoalCommand; import seedu.financialplanner.exceptions.FinancialPlannerException; import java.util.ArrayList; @@ -29,6 +30,7 @@ public class Parser { private static final String BUDGET_COMMAND = "budget"; private static final String VISUALIZATION_COMMAND = "vis"; private static final String ADD_REMINDER_COMMAND = "addreminder"; + private static final String SET_GOAL_COMMAND = "set"; public static AbstractCommand parseCommand(String input) throws FinancialPlannerException { RawCommand rawCommand = parseRawCommand(input); return parseCommand(rawCommand); @@ -52,6 +54,8 @@ public static AbstractCommand parseCommand(RawCommand rawCommand) throws Financi return new VisCommand(rawCommand); case ADD_REMINDER_COMMAND: return new AddReminderCommand(rawCommand); + case SET_GOAL_COMMAND: + return new SetGoalCommand(rawCommand); default: return new InvalidCommand(); } From ab2f4ada4e7927c3e547ff23c80429d5fa018a85 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Mon, 16 Oct 2023 18:26:06 +0800 Subject: [PATCH 110/518] Update overview command --- .../commands/OverviewCommand.java | 60 +++++++++++-------- 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java index 406b53c086..207638be4b 100644 --- a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java +++ b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java @@ -1,48 +1,60 @@ package seedu.financialplanner.commands; -import seedu.financialplanner.exceptions.FinancialPlannerException; -import seedu.financialplanner.investments.WatchList; -import seedu.financialplanner.list.Cashflow; -import seedu.financialplanner.list.Expense; -import seedu.financialplanner.list.FinancialList; -import seedu.financialplanner.list.Income; +import seedu.financialplanner.list.*; +import seedu.financialplanner.utils.Parser; import seedu.financialplanner.utils.Ui; -public class OverviewCommand extends Command { +import java.util.ArrayList; + +public class OverviewCommand extends AbstractCommand { + public OverviewCommand(RawCommand rawCommand) { + if (!rawCommand.extraArgs.isEmpty()) { + String unknownExtraArgument = new ArrayList<>(rawCommand.extraArgs.keySet()).get(0); + throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); + } + } + @Override - public void execute(Ui ui, FinancialList financialList, WatchList watchList) throws FinancialPlannerException { - Command watchlist = new WatchListCommand(); - ui.showMessage("Here is an overview of your financials:\n" + + public void execute() throws Exception { + CashflowList list = CashflowList.INSTANCE; + AbstractCommand watchlist = new WatchListCommand(Parser.parseRawCommand("watchlist")); + Ui.INSTANCE.showMessage("Here is an overview of your financials:\n" + "Total balance: " + String.format("%.2f", Cashflow.getBalance()) + "\n" + - "Highest income: " + String.format("%.2f", getHighestIncome(financialList)) + "\n" + - "Highest expense: " + String.format("%.2f", getHighestExpense(financialList)) + "\n" + - "Watchlist: "); //todo: maybe indicate if income/expense is recurring - //todo: add budget and goal disparity - watchlist.execute(ui, financialList, watchList); - //todo: add visualisation + "Highest income: " + getHighestIncome(list) + "\n" + + "Highest expense: " + getHighestExpense(list) + "\n" + + "Remaining budget for the month: " + getBudgetDesc() + "\n" + + "Watchlist: "); + //todo: maybe indicate if income/expense is recurring + //todo: goal disparity + watchlist.execute(); + //todo: add educational tip + } + + private static String getBudgetDesc() { + return String.format("%.2f", Budget.getCurrentBudget()); } - private double getHighestIncome(FinancialList list) { + private static String getHighestIncome(CashflowList list) { double maxIncome = 0; for (Cashflow entry : list.list) { if (entry instanceof Income) { - if (entry.getValue() > maxIncome) { - maxIncome = entry.getValue(); + if (entry.getAmount() > maxIncome) { + maxIncome = entry.getAmount(); } } } - return maxIncome; + return String.format("%.2f", maxIncome); } - private double getHighestExpense(FinancialList list) { + private static String getHighestExpense(CashflowList list) { double maxExpense = 0; for (Cashflow entry : list.list) { if (entry instanceof Expense) { - if (entry.getValue() > maxExpense) { - maxExpense = entry.getValue(); + if (entry.getAmount() > maxExpense) { + maxExpense = entry.getAmount(); } } } - return maxExpense; + return String.format("%.2f", maxExpense); } } From 75d7c453aa561d32dc04f507920e91866cd3cd42 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Mon, 16 Oct 2023 18:35:53 +0800 Subject: [PATCH 111/518] Refactor code in budget and overview Fixes #29 --- .../financialplanner/commands/BudgetCommand.java | 8 +++----- .../financialplanner/commands/OverviewCommand.java | 14 +++++++------- .../java/seedu/financialplanner/list/Cashflow.java | 4 ---- src/main/java/seedu/financialplanner/utils/Ui.java | 12 ++++++++++++ 4 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java index 1dfed2528f..59bcf5e918 100644 --- a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java +++ b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java @@ -43,12 +43,10 @@ public void execute() { + " has been set."); break; case "update": - Ui.INSTANCE.showMessage("Budget has been updated:\nOld initial budget: " + - String.format("%.2f", Budget.getInitialBudget()) + "\nOld current budget: " + - String.format("%.2f", Budget.getCurrentBudget())); + Ui.INSTANCE.printBudgetBeforeUpdate(); Budget.updateBudget(budget); - Ui.INSTANCE.showMessage("New initial budget: " + String.format("%.2f", Budget.getInitialBudget()) + - "\nNew current budget: " + String.format("%.2f", Budget.getCurrentBudget())); + Ui.INSTANCE.printBudgetAfterUpdate(); + if (Budget.getCurrentBudget() <= 0) { Ui.INSTANCE.showMessage("You have exceeded your budget, please update to a larger budget or " + "reset the current budget to initial budget."); diff --git a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java index 207638be4b..9c97a5edc5 100644 --- a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java +++ b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java @@ -1,7 +1,10 @@ package seedu.financialplanner.commands; -import seedu.financialplanner.list.*; -import seedu.financialplanner.utils.Parser; +import seedu.financialplanner.list.Budget; +import seedu.financialplanner.list.Cashflow; +import seedu.financialplanner.list.CashflowList; +import seedu.financialplanner.list.Income; +import seedu.financialplanner.list.Expense; import seedu.financialplanner.utils.Ui; import java.util.ArrayList; @@ -17,16 +20,13 @@ public OverviewCommand(RawCommand rawCommand) { @Override public void execute() throws Exception { CashflowList list = CashflowList.INSTANCE; - AbstractCommand watchlist = new WatchListCommand(Parser.parseRawCommand("watchlist")); Ui.INSTANCE.showMessage("Here is an overview of your financials:\n" + "Total balance: " + String.format("%.2f", Cashflow.getBalance()) + "\n" + "Highest income: " + getHighestIncome(list) + "\n" + "Highest expense: " + getHighestExpense(list) + "\n" + - "Remaining budget for the month: " + getBudgetDesc() + "\n" + - "Watchlist: "); - //todo: maybe indicate if income/expense is recurring + "Remaining budget for the month: " + getBudgetDesc()); + //todo: indicate description of income/expense //todo: goal disparity - watchlist.execute(); //todo: add educational tip } diff --git a/src/main/java/seedu/financialplanner/list/Cashflow.java b/src/main/java/seedu/financialplanner/list/Cashflow.java index c6146647c6..1dba38000c 100644 --- a/src/main/java/seedu/financialplanner/list/Cashflow.java +++ b/src/main/java/seedu/financialplanner/list/Cashflow.java @@ -58,10 +58,6 @@ public static double getBalance() { return balance; } - public double getValue() { - return value; - } - public String formatString() { return this.amount + " | " + this.type + " | " + this.recur; } diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 1072a89e5b..374666eb41 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -2,6 +2,7 @@ import org.apache.commons.lang3.StringUtils; import org.json.simple.JSONObject; +import seedu.financialplanner.list.Budget; import seedu.financialplanner.list.Cashflow; import java.util.Scanner; @@ -76,4 +77,15 @@ public void printDeletedCashflow(Cashflow entry) { System.out.println("from the Financial Planner."); System.out.println("Balance: " + entry.formatBalance()); } + + public void printBudgetBeforeUpdate() { + showMessage("Budget has been updated:\nOld initial budget: " + + String.format("%.2f", Budget.getInitialBudget()) + "\nOld current budget: " + + String.format("%.2f", Budget.getCurrentBudget())); + } + + public void printBudgetAfterUpdate() { + showMessage("New initial budget: " + String.format("%.2f", Budget.getInitialBudget()) + + "\nNew current budget: " + String.format("%.2f", Budget.getCurrentBudget())); + } } From 8e970f586211c98a67104e2e5e60c1467290283f Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Mon, 16 Oct 2023 18:54:49 +0800 Subject: [PATCH 112/518] Fix bug in loading storage --- .../financialplanner/FinancialPlanner.java | 1 + .../financialplanner/storage/LoadData.java | 18 +++++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index 6596453764..5ad0eded60 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -29,6 +29,7 @@ public void run() { storage.load(cashflowList, ui, FILE_PATH); } catch (FinancialPlannerException e) { ui.showMessage(e.getMessage()); + return; } ui.welcomeMessage(); diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 829e1a9bfb..9fd2e2c7d6 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -41,13 +41,17 @@ public static void load(CashflowList cashflowList, Ui ui, String filePath) throw } catch (IOException e) { ui.showMessage("File not found. Creating new file..."); } catch (NumberFormatException | ArrayIndexOutOfBoundsException | FinancialPlannerException e) { - ui.showMessage("File appears to be corrupted. Do you want to create a new file? (Y/N)"); - if (createNewFile(ui)) { - cashflowList.list.clear(); - } else { - throw new FinancialPlannerException("Please fix the corrupted file, " + - "which can be found in data/data.txt."); - } + handleCorruptedFile(cashflowList, ui); + } + } + + private static void handleCorruptedFile(CashflowList cashflowList, Ui ui) throws FinancialPlannerException { + ui.showMessage("File appears to be corrupted. Do you want to create a new file? (Y/N)"); + if (createNewFile(ui)) { + cashflowList.list.clear(); + } else { + throw new FinancialPlannerException("Please fix the corrupted file, " + + "which can be found in data/data.txt."); } } From 01fbdd18f50dc01d6273bb8ae0f716d76658c798 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Mon, 16 Oct 2023 19:18:53 +0800 Subject: [PATCH 113/518] Update error handling for budget --- .../seedu/financialplanner/commands/BudgetCommand.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java index 59bcf5e918..228e549f70 100644 --- a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java +++ b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java @@ -4,6 +4,8 @@ import seedu.financialplanner.list.Budget; import seedu.financialplanner.utils.Ui; +import java.util.ArrayList; + public class BudgetCommand extends AbstractCommand { private double budget; private String command; @@ -32,6 +34,11 @@ public BudgetCommand(RawCommand rawCommand) throws FinancialPlannerException { throw new IllegalArgumentException("Budget must be a number."); } rawCommand.extraArgs.remove("b"); + + if (!rawCommand.extraArgs.isEmpty()) { + String unknownExtraArgument = new ArrayList<>(rawCommand.extraArgs.keySet()).get(0); + throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); + } } @Override From b33a0c71e3a82cedd3deac14b53ee8c881b63934 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Mon, 16 Oct 2023 20:29:38 +0800 Subject: [PATCH 114/518] Refactor code: - Refactor formatting of double to string - Reduce nesting in overviewcommand - Clean up code --- .../commands/AddCashflowCommand.java | 10 +++---- .../commands/BudgetCommand.java | 2 +- .../commands/OverviewCommand.java | 27 ++++++++++--------- .../investments/WatchList.java | 6 +---- .../seedu/financialplanner/list/Budget.java | 12 +++++++++ .../java/seedu/financialplanner/utils/Ui.java | 8 +++--- 6 files changed, 38 insertions(+), 27 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index 211ba3609f..a63a030e28 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -7,7 +7,6 @@ import seedu.financialplanner.utils.Ui; import java.util.ArrayList; -import static java.lang.Math.abs; public class AddCashflowCommand extends AbstractCommand { @@ -76,12 +75,13 @@ public void execute() { private static void deductFromBudget(Cashflow entry) { double expenseAmount = entry.getAmount(); Budget.deduct(expenseAmount); + String message = ""; if (Budget.getCurrentBudget() <= 0) { - Ui.INSTANCE.showMessage("You have exceeded your current budget by: " + - String.format("%.2f", abs(Budget.getCurrentBudget()))); + message += "You have exceeded your current budget by: "; } else if (Budget.getCurrentBudget() > 0) { - Ui.INSTANCE.showMessage("Your remaining budget for the month is: " + - String.format("%.2f", Budget.getCurrentBudget())); + message += "Your remaining budget for the month is: "; } + message += Budget.getCurrentBudgetString(); + Ui.INSTANCE.showMessage(message); } } diff --git a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java index 228e549f70..187dfde1a1 100644 --- a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java +++ b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java @@ -46,7 +46,7 @@ public void execute() { switch (command) { case "set": Budget.setBudget(budget); - Ui.INSTANCE.showMessage("A monthly budget of " + String.format("%.2f", Budget.getInitialBudget()) + Ui.INSTANCE.showMessage("A monthly budget of " + Budget.getInitialBudgetString() + " has been set."); break; case "update": diff --git a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java index 9c97a5edc5..fdb1c1df13 100644 --- a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java +++ b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java @@ -7,6 +7,7 @@ import seedu.financialplanner.list.Expense; import seedu.financialplanner.utils.Ui; +import java.text.DecimalFormat; import java.util.ArrayList; public class OverviewCommand extends AbstractCommand { @@ -21,7 +22,7 @@ public OverviewCommand(RawCommand rawCommand) { public void execute() throws Exception { CashflowList list = CashflowList.INSTANCE; Ui.INSTANCE.showMessage("Here is an overview of your financials:\n" + - "Total balance: " + String.format("%.2f", Cashflow.getBalance()) + "\n" + + "Total balance: " + formatDoubleToString(Cashflow.getBalance()) + "\n" + "Highest income: " + getHighestIncome(list) + "\n" + "Highest expense: " + getHighestExpense(list) + "\n" + "Remaining budget for the month: " + getBudgetDesc()); @@ -31,30 +32,32 @@ public void execute() throws Exception { } private static String getBudgetDesc() { - return String.format("%.2f", Budget.getCurrentBudget()); + return Budget.getCurrentBudgetString(); } private static String getHighestIncome(CashflowList list) { double maxIncome = 0; for (Cashflow entry : list.list) { - if (entry instanceof Income) { - if (entry.getAmount() > maxIncome) { - maxIncome = entry.getAmount(); - } + if (entry instanceof Income && entry.getAmount() > maxIncome) { + maxIncome = entry.getAmount(); } } - return String.format("%.2f", maxIncome); + return formatDoubleToString(maxIncome); } private static String getHighestExpense(CashflowList list) { double maxExpense = 0; for (Cashflow entry : list.list) { - if (entry instanceof Expense) { - if (entry.getAmount() > maxExpense) { - maxExpense = entry.getAmount(); - } + if (entry instanceof Expense && entry.getAmount() > maxExpense) { + maxExpense = entry.getAmount(); } } - return String.format("%.2f", maxExpense); + return formatDoubleToString(maxExpense); + } + + private static String formatDoubleToString(double amount) { + DecimalFormat decimalFormat = new DecimalFormat("####0.00"); + + return decimalFormat.format(Cashflow.round(amount, 2)); } } diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index 02396168f8..0ba661e10d 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -49,11 +49,7 @@ public JSONArray fetchFMPStockPrices() { HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); // System.out.println(response.body()); obj = new JSONParser().parse(response.body()); - } catch (IOException e) { - throw new RuntimeException(e); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } catch (ParseException e) { + } catch (IOException | InterruptedException | ParseException e) { throw new RuntimeException(e); } return (JSONArray) obj; diff --git a/src/main/java/seedu/financialplanner/list/Budget.java b/src/main/java/seedu/financialplanner/list/Budget.java index e3eaafac75..892d155446 100644 --- a/src/main/java/seedu/financialplanner/list/Budget.java +++ b/src/main/java/seedu/financialplanner/list/Budget.java @@ -1,5 +1,7 @@ package seedu.financialplanner.list; +import java.text.DecimalFormat; + public abstract class Budget { private static final int MONTH = 30; private static double initialBudget = 0; @@ -31,6 +33,16 @@ public static double getCurrentBudget() { return currentBudget; } + public static String getCurrentBudgetString() { + DecimalFormat decimalFormat = new DecimalFormat("####0.00"); + return decimalFormat.format(Cashflow.round(currentBudget, 2)); + } + + public static String getInitialBudgetString() { + DecimalFormat decimalFormat = new DecimalFormat("####0.00"); + return decimalFormat.format(Cashflow.round(initialBudget, 2)); + } + public static void deduct(double amount) { Budget.currentBudget -= amount; } diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 374666eb41..c9226b21d3 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -80,12 +80,12 @@ public void printDeletedCashflow(Cashflow entry) { public void printBudgetBeforeUpdate() { showMessage("Budget has been updated:\nOld initial budget: " + - String.format("%.2f", Budget.getInitialBudget()) + "\nOld current budget: " + - String.format("%.2f", Budget.getCurrentBudget())); + Budget.getInitialBudgetString() + "\nOld current budget: " + + Budget.getCurrentBudgetString()); } public void printBudgetAfterUpdate() { - showMessage("New initial budget: " + String.format("%.2f", Budget.getInitialBudget()) + - "\nNew current budget: " + String.format("%.2f", Budget.getCurrentBudget())); + showMessage("New initial budget: " + Budget.getInitialBudgetString() + + "\nNew current budget: " + Budget.getCurrentBudgetString()); } } From 989068feb2dd79c2e54c25b3b6d3965507ea1cef Mon Sep 17 00:00:00 2001 From: YFshadaow Date: Mon, 16 Oct 2023 21:40:19 +0800 Subject: [PATCH 115/518] Add list commands. Minor changes include: - Remove EMPTY cash flow category - Refactor delete command --- .../commands/DeleteCashflowCommand.java | 30 ++++---- .../commands/ListCommand.java | 70 +++++++++++++++++++ .../enumerations/CashflowCategory.java | 2 +- .../seedu/financialplanner/utils/Parser.java | 4 ++ 4 files changed, 90 insertions(+), 16 deletions(-) create mode 100644 src/main/java/seedu/financialplanner/commands/ListCommand.java diff --git a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java index e338448d0a..6417b6f183 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java @@ -6,21 +6,20 @@ public class DeleteCashflowCommand extends AbstractCommand{ - protected CashflowCategory category = CashflowCategory.EMPTY; + protected CashflowCategory category = null; protected int index; public DeleteCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException { String stringIndex; - String stringCategory; + String stringCategory = null; if (rawCommand.args.size() == 1) { stringIndex = rawCommand.args.get(0); - } else { + } else if (rawCommand.args.size() == 2) { stringCategory = rawCommand.args.get(0); - - handleInvalidCategory(stringCategory); - stringIndex = rawCommand.args.get(1); + } else { + throw new IllegalArgumentException("Incorrect arguments."); } try { @@ -28,26 +27,27 @@ public DeleteCashflowCommand(RawCommand rawCommand) throws IllegalArgumentExcept } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Index must be an integer"); } - } - private void handleInvalidCategory(String stringCategory) { - try { - category = CashflowCategory.valueOf(stringCategory.toUpperCase()); - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException("Entry must be either income or expense"); + if (stringCategory != null) { + try { + category = CashflowCategory.valueOf(stringCategory.toUpperCase()); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Entry must be either income or expense"); + } } } @Override public void execute() { + if (category == null) { + handleDeleteCashflowWithoutCategory(); + return; + } switch (category) { case INCOME: case EXPENSE: handleDeleteCashflowWithCategory(); break; - case EMPTY: - handleDeleteCashflowWithoutCategory(); - break; default: Ui.INSTANCE.showMessage("Unidentified entry."); break; diff --git a/src/main/java/seedu/financialplanner/commands/ListCommand.java b/src/main/java/seedu/financialplanner/commands/ListCommand.java new file mode 100644 index 0000000000..37011c08bd --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/ListCommand.java @@ -0,0 +1,70 @@ +package seedu.financialplanner.commands; + +import seedu.financialplanner.enumerations.CashflowCategory; +import seedu.financialplanner.list.Cashflow; +import seedu.financialplanner.list.CashflowList; +import seedu.financialplanner.list.Expense; +import seedu.financialplanner.list.Income; +import seedu.financialplanner.utils.Ui; + +import java.util.ArrayList; +import java.util.List; + +public class ListCommand extends AbstractCommand{ + protected CashflowCategory category = null; + public ListCommand(RawCommand rawCommand) throws IllegalArgumentException{ + String stringCategory = null; + + if (rawCommand.args.size() == 1) { + stringCategory = rawCommand.args.get(0); + } else if (rawCommand.args.size() > 1) { + throw new IllegalArgumentException("Incorrect arguments."); + } + + if (stringCategory != null) { + try { + category = CashflowCategory.valueOf(stringCategory.toUpperCase()); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Entry must be either income or expense"); + } + } else { + + } + } + + private boolean shouldPrintCashFlow(Cashflow cashflow) { + if (category == null) { + return true; + } + if (cashflow instanceof Income) { + return category.equals(CashflowCategory.INCOME); + } + if (cashflow instanceof Expense) { + return category.equals(CashflowCategory.EXPENSE); + } + return false; + } + + @Override + public void execute() throws Exception { + + List cashflowList = CashflowList.INSTANCE.list; + List cashflowToBePrinted = new ArrayList<>(); + for (Cashflow flow : cashflowList) { + if (!shouldPrintCashFlow(flow)) { + continue; + } + cashflowToBePrinted.add(flow); + } + + if (cashflowToBePrinted.isEmpty()) { + Ui.INSTANCE.showMessage("No matching cash flow"); + return; + } + + Ui.INSTANCE.showMessage(String.format("You have %d matching cash flow:", cashflowToBePrinted.size())); + for (int i = 0; i < cashflowToBePrinted.size(); i += 1) { + Ui.INSTANCE.showMessage((i+ 1) + ": " + cashflowToBePrinted.get(i).toString()); + } + } +} diff --git a/src/main/java/seedu/financialplanner/enumerations/CashflowCategory.java b/src/main/java/seedu/financialplanner/enumerations/CashflowCategory.java index 57fd1445d2..0c394fee70 100644 --- a/src/main/java/seedu/financialplanner/enumerations/CashflowCategory.java +++ b/src/main/java/seedu/financialplanner/enumerations/CashflowCategory.java @@ -1,5 +1,5 @@ package seedu.financialplanner.enumerations; public enum CashflowCategory { - INCOME, EXPENSE, EMPTY + INCOME, EXPENSE } diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index fdc2755346..554a62b316 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -7,6 +7,7 @@ import seedu.financialplanner.commands.ExitCommand; import seedu.financialplanner.commands.FindCommand; import seedu.financialplanner.commands.InvalidCommand; +import seedu.financialplanner.commands.ListCommand; import seedu.financialplanner.commands.RawCommand; import seedu.financialplanner.commands.WatchListCommand; import seedu.financialplanner.commands.VisCommand; @@ -31,6 +32,7 @@ public class Parser { private static final String BUDGET_COMMAND = "budget"; private static final String VISUALIZATION_COMMAND = "vis"; private static final String ADD_REMINDER_COMMAND = "addreminder"; + private static final String LIST_COMMAND = "list"; public static AbstractCommand parseCommand(String input) throws FinancialPlannerException { RawCommand rawCommand = parseRawCommand(input); return parseCommand(rawCommand); @@ -56,6 +58,8 @@ public static AbstractCommand parseCommand(RawCommand rawCommand) throws Financi return new VisCommand(rawCommand); case ADD_REMINDER_COMMAND: return new AddReminderCommand(rawCommand); + case LIST_COMMAND: + return new ListCommand(rawCommand); default: return new InvalidCommand(); } From 76ef2f72103f0f0e994d3cb8440b4bd9775feaf0 Mon Sep 17 00:00:00 2001 From: YFshadaow Date: Mon, 16 Oct 2023 21:41:41 +0800 Subject: [PATCH 116/518] Minor change: Remove redundant else block --- src/main/java/seedu/financialplanner/commands/ListCommand.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/ListCommand.java b/src/main/java/seedu/financialplanner/commands/ListCommand.java index 37011c08bd..ab4699ef78 100644 --- a/src/main/java/seedu/financialplanner/commands/ListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/ListCommand.java @@ -27,8 +27,6 @@ public ListCommand(RawCommand rawCommand) throws IllegalArgumentException{ } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Entry must be either income or expense"); } - } else { - } } From c39094ff72f2ff8fa468ec804cd3dfb3016fe480 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 16 Oct 2023 22:38:27 +0800 Subject: [PATCH 117/518] Fix bug where wrong message is showing for error handling and when user inputs delete 0 --- .../commands/DeleteCashflowCommand.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java index e338448d0a..898e648614 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java @@ -28,6 +28,10 @@ public DeleteCashflowCommand(RawCommand rawCommand) throws IllegalArgumentExcept } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Index must be an integer"); } + + if (index == 0) { + throw new IllegalArgumentException("Index must be within the list"); + } } private void handleInvalidCategory(String stringCategory) { @@ -57,16 +61,16 @@ public void execute() { private void handleDeleteCashflowWithoutCategory() { try { CashflowList.INSTANCE.delete(index); - } catch (ArrayIndexOutOfBoundsException e) { - throw new IllegalArgumentException("Index must be within the list."); + } catch (IndexOutOfBoundsException e) { + throw new IllegalArgumentException("Index must be within the list"); } } private void handleDeleteCashflowWithCategory() { try { CashflowList.INSTANCE.deleteCashflow(category, index); - } catch (ArrayIndexOutOfBoundsException e) { - throw new IllegalArgumentException("Index must be within the list."); + } catch (IndexOutOfBoundsException e) { + throw new IllegalArgumentException("Index must be within the list"); } } } From 169a0adc623031468978ad883a41a8862150d138 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 16 Oct 2023 23:19:35 +0800 Subject: [PATCH 118/518] Add assertions for AddCashflowCommand --- .../seedu/financialplanner/commands/AddCashflowCommand.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index 211ba3609f..7da7e00c5a 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -6,6 +6,7 @@ import seedu.financialplanner.list.CashflowList; import seedu.financialplanner.utils.Ui; +import java.awt.geom.Arc2D; import java.util.ArrayList; import static java.lang.Math.abs; @@ -56,6 +57,10 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException @Override public void execute() { + assert category.equals(CashflowCategory.INCOME) || category.equals(CashflowCategory.EXPENSE); + assert recur >= 0; + assert amount >= 0; + switch (category) { case INCOME: CashflowList.INSTANCE.addIncome(amount, type, recur); From c32e4c62168dba8284fb862f1bdcebd8ceaad008 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 16 Oct 2023 23:34:42 +0800 Subject: [PATCH 119/518] Add error handling for empty type string --- .../commands/AddCashflowCommand.java | 13 +++++++++++-- .../commands/DeleteCashflowCommand.java | 3 +++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index 7da7e00c5a..26b88559e4 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -6,7 +6,6 @@ import seedu.financialplanner.list.CashflowList; import seedu.financialplanner.utils.Ui; -import java.awt.geom.Arc2D; import java.util.ArrayList; import static java.lang.Math.abs; @@ -14,7 +13,7 @@ public class AddCashflowCommand extends AbstractCommand { protected double amount; protected CashflowCategory category; - protected String type; + protected String type = null; protected int recur = 0; public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException { @@ -33,12 +32,18 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Amount must be a number"); } + if (amount < 0) { + throw new IllegalArgumentException("Amount cannot be negative"); + } rawCommand.extraArgs.remove("a"); if (!rawCommand.extraArgs.containsKey("t")) { throw new IllegalArgumentException("Entry must have a type"); } type = rawCommand.extraArgs.get("t"); + if (type.isBlank()) { + throw new IllegalArgumentException("Type cannot be left empty"); + } rawCommand.extraArgs.remove("t"); if (rawCommand.extraArgs.containsKey("r")) { @@ -49,6 +54,9 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException } rawCommand.extraArgs.remove("r"); } + if (recur < 0) { + throw new IllegalArgumentException("Amount cannot be negative"); + } if (!rawCommand.extraArgs.isEmpty()) { String unknownExtraArgument = new ArrayList<>(rawCommand.extraArgs.keySet()).get(0); throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); @@ -60,6 +68,7 @@ public void execute() { assert category.equals(CashflowCategory.INCOME) || category.equals(CashflowCategory.EXPENSE); assert recur >= 0; assert amount >= 0; + assert type != null; switch (category) { case INCOME: diff --git a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java index e338448d0a..5a099dbcef 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java @@ -40,6 +40,9 @@ private void handleInvalidCategory(String stringCategory) { @Override public void execute() { + assert category.equals(CashflowCategory.INCOME) || category.equals(CashflowCategory.EXPENSE); + assert index != 0; + switch (category) { case INCOME: case EXPENSE: From ffe8271a4dc18b4c8b4490697931915343ac4c08 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 16 Oct 2023 23:36:55 +0800 Subject: [PATCH 120/518] Revert "Add error handling for empty type string" This reverts commit c32e4c62168dba8284fb862f1bdcebd8ceaad008. --- .../commands/AddCashflowCommand.java | 13 ++----------- .../commands/DeleteCashflowCommand.java | 3 --- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index 26b88559e4..7da7e00c5a 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -6,6 +6,7 @@ import seedu.financialplanner.list.CashflowList; import seedu.financialplanner.utils.Ui; +import java.awt.geom.Arc2D; import java.util.ArrayList; import static java.lang.Math.abs; @@ -13,7 +14,7 @@ public class AddCashflowCommand extends AbstractCommand { protected double amount; protected CashflowCategory category; - protected String type = null; + protected String type; protected int recur = 0; public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException { @@ -32,18 +33,12 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Amount must be a number"); } - if (amount < 0) { - throw new IllegalArgumentException("Amount cannot be negative"); - } rawCommand.extraArgs.remove("a"); if (!rawCommand.extraArgs.containsKey("t")) { throw new IllegalArgumentException("Entry must have a type"); } type = rawCommand.extraArgs.get("t"); - if (type.isBlank()) { - throw new IllegalArgumentException("Type cannot be left empty"); - } rawCommand.extraArgs.remove("t"); if (rawCommand.extraArgs.containsKey("r")) { @@ -54,9 +49,6 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException } rawCommand.extraArgs.remove("r"); } - if (recur < 0) { - throw new IllegalArgumentException("Amount cannot be negative"); - } if (!rawCommand.extraArgs.isEmpty()) { String unknownExtraArgument = new ArrayList<>(rawCommand.extraArgs.keySet()).get(0); throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); @@ -68,7 +60,6 @@ public void execute() { assert category.equals(CashflowCategory.INCOME) || category.equals(CashflowCategory.EXPENSE); assert recur >= 0; assert amount >= 0; - assert type != null; switch (category) { case INCOME: diff --git a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java index 5a099dbcef..e338448d0a 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java @@ -40,9 +40,6 @@ private void handleInvalidCategory(String stringCategory) { @Override public void execute() { - assert category.equals(CashflowCategory.INCOME) || category.equals(CashflowCategory.EXPENSE); - assert index != 0; - switch (category) { case INCOME: case EXPENSE: From 6bcfea610b1d4ff267638f51777a3095c2f4686b Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 16 Oct 2023 23:40:10 +0800 Subject: [PATCH 121/518] Add error handling of negative amount and recur value and empty type string --- .../commands/AddCashflowCommand.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index 7da7e00c5a..b292de47ef 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -6,7 +6,6 @@ import seedu.financialplanner.list.CashflowList; import seedu.financialplanner.utils.Ui; -import java.awt.geom.Arc2D; import java.util.ArrayList; import static java.lang.Math.abs; @@ -14,7 +13,7 @@ public class AddCashflowCommand extends AbstractCommand { protected double amount; protected CashflowCategory category; - protected String type; + protected String type = null; protected int recur = 0; public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException { @@ -33,12 +32,18 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Amount must be a number"); } + if (amount < 0) { + throw new IllegalArgumentException("Amount cannot be negative"); + } rawCommand.extraArgs.remove("a"); if (!rawCommand.extraArgs.containsKey("t")) { throw new IllegalArgumentException("Entry must have a type"); } type = rawCommand.extraArgs.get("t"); + if (type.isBlank()) { + throw new IllegalArgumentException("Type cannot be left empty"); + } rawCommand.extraArgs.remove("t"); if (rawCommand.extraArgs.containsKey("r")) { @@ -49,6 +54,10 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException } rawCommand.extraArgs.remove("r"); } + if (recur < 0) { + throw new IllegalArgumentException("Amount cannot be negative"); + } + if (!rawCommand.extraArgs.isEmpty()) { String unknownExtraArgument = new ArrayList<>(rawCommand.extraArgs.keySet()).get(0); throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); @@ -60,6 +69,7 @@ public void execute() { assert category.equals(CashflowCategory.INCOME) || category.equals(CashflowCategory.EXPENSE); assert recur >= 0; assert amount >= 0; + assert type != null; switch (category) { case INCOME: From 6124a059151ca2174be69affe593633855519e0e Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 16 Oct 2023 23:40:55 +0800 Subject: [PATCH 122/518] Add assertions for DeleteCashflowCommand --- .../seedu/financialplanner/commands/DeleteCashflowCommand.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java index e338448d0a..d51d41a313 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java @@ -40,6 +40,9 @@ private void handleInvalidCategory(String stringCategory) { @Override public void execute() { + assert category.equals(CashflowCategory.INCOME) || category.equals(CashflowCategory.EXPENSE); + assert index != 0; + switch (category) { case INCOME: case EXPENSE: From 6ddac1f153c6f64db63f72da8612452b2573fbec Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 16 Oct 2023 23:47:36 +0800 Subject: [PATCH 123/518] Add assertions to CashflowList --- .../commands/DeleteCashflowCommand.java | 2 +- .../financialplanner/list/CashflowList.java | 21 ++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java index d51d41a313..5a099dbcef 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java @@ -42,7 +42,7 @@ private void handleInvalidCategory(String stringCategory) { public void execute() { assert category.equals(CashflowCategory.INCOME) || category.equals(CashflowCategory.EXPENSE); assert index != 0; - + switch (category) { case INCOME: case EXPENSE: diff --git a/src/main/java/seedu/financialplanner/list/CashflowList.java b/src/main/java/seedu/financialplanner/list/CashflowList.java index 85ec6f5375..13ccb2900a 100644 --- a/src/main/java/seedu/financialplanner/list/CashflowList.java +++ b/src/main/java/seedu/financialplanner/list/CashflowList.java @@ -13,30 +13,45 @@ private CashflowList() { } public void addIncome(double value, String type, int recur) { + int existingListSize = list.size(); + Income toAdd = new Income(value, type, recur); list.add(toAdd); Ui.INSTANCE.printAddedCashflow(toAdd); + + int newListSize = list.size(); + assert newListSize == existingListSize + 1; } public void addExpense(double value, String type, int recur) { + int existingListSize = list.size(); + Expense toAdd = new Expense(value, type, recur); list.add(toAdd); Ui.INSTANCE.printAddedCashflow(toAdd); + + int newListSize = list.size(); + assert newListSize == existingListSize + 1; } public void delete(int index) { + int existingListSize = list.size(); int listIndex = index - 1; Cashflow toRemove = list.get(listIndex); list.remove(listIndex); toRemove.deleteCashflowvalue(); Ui.INSTANCE.printDeletedCashflow(toRemove); + + int newListSize = list.size(); + assert newListSize == existingListSize - 1; } //helper method to find the index of a given cashflow in the overall list //given its index in its respective list. e.g. "income 3" is the third income //in the overall list private int cashflowIndexFinder(CashflowCategory category, int cashflowIndex) { - + assert category.equals(CashflowCategory.INCOME) || category.equals(CashflowCategory.EXPENSE); + switch (category) { case INCOME: return findCashflowIndexFromIncomeIndex(cashflowIndex); @@ -80,12 +95,16 @@ private int findCashflowIndexFromExpenseIndex(int cashflowIndex) { } public void deleteCashflow(CashflowCategory category, int index) { + int existingListSize = list.size(); int listIndex = cashflowIndexFinder(category, index); Cashflow toRemove = list.get(listIndex); list.remove(listIndex); toRemove.deleteCashflowvalue(); Ui.INSTANCE.printDeletedCashflow(toRemove); + + int newListSize = list.size(); + assert newListSize == existingListSize - 1; } From 2b845eaedab4f7b60b6c49cd14788b0880ad0e4f Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 16 Oct 2023 23:57:07 +0800 Subject: [PATCH 124/518] Change message shown when recurring value is negative --- .../seedu/financialplanner/commands/AddCashflowCommand.java | 2 +- src/main/java/seedu/financialplanner/list/CashflowList.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index b292de47ef..762e2ae7fa 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -55,7 +55,7 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException rawCommand.extraArgs.remove("r"); } if (recur < 0) { - throw new IllegalArgumentException("Amount cannot be negative"); + throw new IllegalArgumentException("Recurring value cannot be negative"); } if (!rawCommand.extraArgs.isEmpty()) { diff --git a/src/main/java/seedu/financialplanner/list/CashflowList.java b/src/main/java/seedu/financialplanner/list/CashflowList.java index 13ccb2900a..2d11587547 100644 --- a/src/main/java/seedu/financialplanner/list/CashflowList.java +++ b/src/main/java/seedu/financialplanner/list/CashflowList.java @@ -51,7 +51,7 @@ public void delete(int index) { //in the overall list private int cashflowIndexFinder(CashflowCategory category, int cashflowIndex) { assert category.equals(CashflowCategory.INCOME) || category.equals(CashflowCategory.EXPENSE); - + switch (category) { case INCOME: return findCashflowIndexFromIncomeIndex(cashflowIndex); From f46a0628faea24ba86aaa54141916d104fbe1f3a Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 17 Oct 2023 00:14:14 +0800 Subject: [PATCH 125/518] Add logger storage --- .../financialplanner/FinancialPlanner.java | 1 + .../FinancialPlannerLogger.java | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 src/main/java/seedu/financialplanner/FinancialPlannerLogger.java diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index 6596453764..5a3bb53366 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -31,6 +31,7 @@ public void run() { ui.showMessage(e.getMessage()); } + FinancialPlannerLogger.initialise(); ui.welcomeMessage(); String input; AbstractCommand command = null; diff --git a/src/main/java/seedu/financialplanner/FinancialPlannerLogger.java b/src/main/java/seedu/financialplanner/FinancialPlannerLogger.java new file mode 100644 index 0000000000..3fb2ae2514 --- /dev/null +++ b/src/main/java/seedu/financialplanner/FinancialPlannerLogger.java @@ -0,0 +1,20 @@ +package seedu.financialplanner; + +import java.util.logging.FileHandler; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.logging.SimpleFormatter; + +public class FinancialPlannerLogger { + private static Logger logger = Logger.getLogger("Financial Planner Logger"); + + public static void initialise() { + try { + FileHandler fh = new FileHandler("data/logger.log"); + logger.addHandler(fh); + fh.setFormatter(new SimpleFormatter()); + } catch (Exception e) { + logger.log(Level.SEVERE, e.getMessage()); + } + } +} From 3705db0f6ea636d00d7f362a21c577710a687ccf Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 17 Oct 2023 09:19:34 +0800 Subject: [PATCH 126/518] Enable assertions --- build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle b/build.gradle index d9b62e0a3b..c5463dea1b 100644 --- a/build.gradle +++ b/build.gradle @@ -46,4 +46,5 @@ checkstyle { run{ standardInput = System.in + enableAssertions = true } From b10f74a3137f0b43f7a486e06506a6cc47ba5ae1 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 17 Oct 2023 09:59:59 +0800 Subject: [PATCH 127/518] Add logging and assertions for budget Fixes #87 --- .../financialplanner/FinancialPlannerLogger.java | 1 + .../financialplanner/commands/BudgetCommand.java | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/src/main/java/seedu/financialplanner/FinancialPlannerLogger.java b/src/main/java/seedu/financialplanner/FinancialPlannerLogger.java index 3fb2ae2514..0145f0293f 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlannerLogger.java +++ b/src/main/java/seedu/financialplanner/FinancialPlannerLogger.java @@ -13,6 +13,7 @@ public static void initialise() { FileHandler fh = new FileHandler("data/logger.log"); logger.addHandler(fh); fh.setFormatter(new SimpleFormatter()); + logger.log(Level.INFO, "Logger initialised"); } catch (Exception e) { logger.log(Level.SEVERE, e.getMessage()); } diff --git a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java index 1dfed2528f..14496edf95 100644 --- a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java +++ b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java @@ -4,31 +4,40 @@ import seedu.financialplanner.list.Budget; import seedu.financialplanner.utils.Ui; +import java.util.logging.Level; +import java.util.logging.Logger; + public class BudgetCommand extends AbstractCommand { + private static Logger logger = Logger.getLogger("Financial Planner Logger"); private double budget; private String command; public BudgetCommand(RawCommand rawCommand) throws FinancialPlannerException { command = String.join(" ", rawCommand.args); if (!command.equals("set") && !command.equals("update")) { + logger.log(Level.WARNING, "Invalid arguments for budget"); throw new FinancialPlannerException("Please indicate whether budget is to be set or update."); } if (command.equals("set") && Budget.hasBudget()) { + logger.log(Level.INFO, "Trying to set existing budget"); throw new FinancialPlannerException("There is an existing budget, did you mean update?"); } if (command.equals("update") && !Budget.hasBudget()) { + logger.log(Level.INFO, "Trying to update non-existent budget"); throw new FinancialPlannerException("There is no budget set yet, did you mean set?"); } if (!rawCommand.extraArgs.containsKey("b")) { + logger.log(Level.WARNING, "Missing arguments b in command"); throw new IllegalArgumentException("Missing /b argument."); } try { budget = Double.parseDouble(rawCommand.extraArgs.get("b")); } catch (IllegalArgumentException e) { + logger.log(Level.WARNING, "Invalid value for budget"); throw new IllegalArgumentException("Budget must be a number."); } rawCommand.extraArgs.remove("b"); @@ -36,6 +45,8 @@ public BudgetCommand(RawCommand rawCommand) throws FinancialPlannerException { @Override public void execute() { + assert command.equals("set") || command.equals("update") : "command should be set or update only"; + switch (command) { case "set": Budget.setBudget(budget); @@ -55,6 +66,7 @@ public void execute() { } break; default: + logger.log(Level.WARNING, "command should never reach default"); Ui.INSTANCE.showMessage("Unknown command."); } } From 5b25ce5873e76f7c67e8c61128f2ef939c22f7f7 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 17 Oct 2023 10:13:18 +0800 Subject: [PATCH 128/518] Update warning message in logger --- .../java/seedu/financialplanner/commands/BudgetCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java index 14496edf95..80c1c65e7f 100644 --- a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java +++ b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java @@ -66,7 +66,7 @@ public void execute() { } break; default: - logger.log(Level.WARNING, "command should never reach default"); + logger.log(Level.WARNING, "command should never reach default case"); Ui.INSTANCE.showMessage("Unknown command."); } } From 02fdad409ee5ae84faed74f3dbab5b53fca89bda Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Tue, 17 Oct 2023 12:32:06 +0800 Subject: [PATCH 129/518] Add logging for AddCashflowCommand --- .../commands/AddCashflowCommand.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index 762e2ae7fa..cf72ba60fe 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -7,10 +7,14 @@ import seedu.financialplanner.utils.Ui; import java.util.ArrayList; +import java.util.logging.Level; +import java.util.logging.Logger; + import static java.lang.Math.abs; public class AddCashflowCommand extends AbstractCommand { + private static Logger logger = Logger.getLogger("Financial Planner Logger"); protected double amount; protected CashflowCategory category; protected String type = null; @@ -21,27 +25,33 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException try { category = CashflowCategory.valueOf(typeString.toUpperCase()); } catch (IllegalArgumentException e) { + logger.log(Level.WARNING, "Invalid arguments for CashflowCategory"); throw new IllegalArgumentException("Entry must be either income or expense"); } if (!rawCommand.extraArgs.containsKey("a")) { + logger.log(Level.WARNING, "Missing arguments for amount"); throw new IllegalArgumentException("Entry must have an amount"); } try { amount = Double.parseDouble(rawCommand.extraArgs.get("a")); } catch (IllegalArgumentException e) { + logger.log(Level.WARNING, "Invalid arguments for amount"); throw new IllegalArgumentException("Amount must be a number"); } if (amount < 0) { + logger.log(Level.WARNING, "Invalid value for amount"); throw new IllegalArgumentException("Amount cannot be negative"); } rawCommand.extraArgs.remove("a"); if (!rawCommand.extraArgs.containsKey("t")) { + logger.log(Level.WARNING, "Missing arguments for type"); throw new IllegalArgumentException("Entry must have a type"); } type = rawCommand.extraArgs.get("t"); if (type.isBlank()) { + logger.log(Level.WARNING, "Invalid arguments for type"); throw new IllegalArgumentException("Type cannot be left empty"); } rawCommand.extraArgs.remove("t"); @@ -50,16 +60,19 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException try { recur = Integer.parseInt(rawCommand.extraArgs.get("r")); } catch (IllegalArgumentException e) { + logger.log(Level.WARNING, "Invalid arguments for recur"); throw new IllegalArgumentException("Recurrence must be an integer"); } rawCommand.extraArgs.remove("r"); } if (recur < 0) { + logger.log(Level.WARNING, "Invalid value for recur"); throw new IllegalArgumentException("Recurring value cannot be negative"); } if (!rawCommand.extraArgs.isEmpty()) { String unknownExtraArgument = new ArrayList<>(rawCommand.extraArgs.keySet()).get(0); + logger.log(Level.WARNING, "Invalid extra arguments found"); throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); } } @@ -83,6 +96,7 @@ public void execute() { } break; default: + logger.log(Level.SEVERE, "Unreachable default case reached"); Ui.INSTANCE.showMessage("Unidentified entry."); break; } From 951cab2e9360ac30ec87e1a28343e9ed0942a20d Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Tue, 17 Oct 2023 12:38:56 +0800 Subject: [PATCH 130/518] Add logging for DeleteCashflowCommand --- .../commands/DeleteCashflowCommand.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java index 2496bd8e5e..64cab42741 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java @@ -4,8 +4,11 @@ import seedu.financialplanner.list.CashflowList; import seedu.financialplanner.utils.Ui; -public class DeleteCashflowCommand extends AbstractCommand{ +import java.util.logging.Level; +import java.util.logging.Logger; +public class DeleteCashflowCommand extends AbstractCommand{ + private static Logger logger = Logger.getLogger("Financial Planner Logger"); protected CashflowCategory category = CashflowCategory.EMPTY; protected int index; @@ -26,10 +29,12 @@ public DeleteCashflowCommand(RawCommand rawCommand) throws IllegalArgumentExcept try { index = Integer.parseInt(stringIndex); } catch (IllegalArgumentException e) { + logger.log(Level.WARNING, "Invalid argument for index"); throw new IllegalArgumentException("Index must be an integer"); } if (index == 0) { + logger.log(Level.WARNING, "Invalid value for index"); throw new IllegalArgumentException("Index must be within the list"); } } @@ -38,6 +43,7 @@ private void handleInvalidCategory(String stringCategory) { try { category = CashflowCategory.valueOf(stringCategory.toUpperCase()); } catch (IllegalArgumentException e) { + logger.log(Level.WARNING, "Invalid arguments for CashflowCategory"); throw new IllegalArgumentException("Entry must be either income or expense"); } } @@ -56,6 +62,7 @@ public void execute() { handleDeleteCashflowWithoutCategory(); break; default: + logger.log(Level.SEVERE, "Unreachable default case reached"); Ui.INSTANCE.showMessage("Unidentified entry."); break; } @@ -65,6 +72,7 @@ private void handleDeleteCashflowWithoutCategory() { try { CashflowList.INSTANCE.delete(index); } catch (IndexOutOfBoundsException e) { + logger.log(Level.WARNING, "Index out of list"); throw new IllegalArgumentException("Index must be within the list"); } } @@ -73,6 +81,7 @@ private void handleDeleteCashflowWithCategory() { try { CashflowList.INSTANCE.deleteCashflow(category, index); } catch (IndexOutOfBoundsException e) { + logger.log(Level.WARNING, "Index out of list"); throw new IllegalArgumentException("Index must be within the list"); } } From 37c006a162c8d924bf64485b7c7712e7fbbc1b2e Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Tue, 17 Oct 2023 12:46:25 +0800 Subject: [PATCH 131/518] Add logging for CashflowList --- .../java/seedu/financialplanner/list/CashflowList.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/list/CashflowList.java b/src/main/java/seedu/financialplanner/list/CashflowList.java index 2d11587547..c83a640a99 100644 --- a/src/main/java/seedu/financialplanner/list/CashflowList.java +++ b/src/main/java/seedu/financialplanner/list/CashflowList.java @@ -3,16 +3,20 @@ import seedu.financialplanner.enumerations.CashflowCategory; import seedu.financialplanner.utils.Ui; import java.util.ArrayList; +import java.util.logging.Level; +import java.util.logging.Logger; public class CashflowList { - public static final CashflowList INSTANCE = new CashflowList(); + public static Logger logger = Logger.getLogger("Financial Planner Logger"); + public static final CashflowList INSTANCE = new CashflowList(); public final ArrayList list = new ArrayList<>(); private CashflowList() { } public void addIncome(double value, String type, int recur) { + logger.log(Level.INFO, "Adding income"); int existingListSize = list.size(); Income toAdd = new Income(value, type, recur); @@ -24,6 +28,7 @@ public void addIncome(double value, String type, int recur) { } public void addExpense(double value, String type, int recur) { + logger.log(Level.INFO, "Adding expense"); int existingListSize = list.size(); Expense toAdd = new Expense(value, type, recur); From 93b4095f0b68d6d7f32f1596a8ee627a79bfb05f Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Tue, 17 Oct 2023 12:48:37 +0800 Subject: [PATCH 132/518] Add logging for try statements in DeleteCashflowCommand --- .../financialplanner/commands/DeleteCashflowCommand.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java index 64cab42741..c7893cc9b3 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java @@ -27,6 +27,7 @@ public DeleteCashflowCommand(RawCommand rawCommand) throws IllegalArgumentExcept } try { + logger.log(Level.INFO, "Parsing index as integer"); index = Integer.parseInt(stringIndex); } catch (IllegalArgumentException e) { logger.log(Level.WARNING, "Invalid argument for index"); @@ -41,6 +42,7 @@ public DeleteCashflowCommand(RawCommand rawCommand) throws IllegalArgumentExcept private void handleInvalidCategory(String stringCategory) { try { + logger.log(Level.INFO, "Parsing CashflowCategory"); category = CashflowCategory.valueOf(stringCategory.toUpperCase()); } catch (IllegalArgumentException e) { logger.log(Level.WARNING, "Invalid arguments for CashflowCategory"); @@ -70,6 +72,7 @@ public void execute() { private void handleDeleteCashflowWithoutCategory() { try { + logger.log(Level.INFO, "Deleting cashflow without category"); CashflowList.INSTANCE.delete(index); } catch (IndexOutOfBoundsException e) { logger.log(Level.WARNING, "Index out of list"); @@ -79,6 +82,7 @@ private void handleDeleteCashflowWithoutCategory() { private void handleDeleteCashflowWithCategory() { try { + logger.log(Level.INFO, "Deleting cashflow with category"); CashflowList.INSTANCE.deleteCashflow(category, index); } catch (IndexOutOfBoundsException e) { logger.log(Level.WARNING, "Index out of list"); From 82e3d8c5fd251bb8e1486bdb6f6c3e95399a0864 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Tue, 17 Oct 2023 12:50:24 +0800 Subject: [PATCH 133/518] Add logging for try statements in AddCashflowCommand --- .../seedu/financialplanner/commands/AddCashflowCommand.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index cf72ba60fe..7e1f19b35c 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -23,6 +23,7 @@ public class AddCashflowCommand extends AbstractCommand { public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException { String typeString = String.join(" ", rawCommand.args); try { + logger.log(Level.INFO, "Parsing CashflowCategory"); category = CashflowCategory.valueOf(typeString.toUpperCase()); } catch (IllegalArgumentException e) { logger.log(Level.WARNING, "Invalid arguments for CashflowCategory"); @@ -34,6 +35,7 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException throw new IllegalArgumentException("Entry must have an amount"); } try { + logger.log(Level.INFO, "Parsing amount as double"); amount = Double.parseDouble(rawCommand.extraArgs.get("a")); } catch (IllegalArgumentException e) { logger.log(Level.WARNING, "Invalid arguments for amount"); @@ -58,6 +60,7 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException if (rawCommand.extraArgs.containsKey("r")) { try { + logger.log(Level.INFO, "Parsing recur as integer"); recur = Integer.parseInt(rawCommand.extraArgs.get("r")); } catch (IllegalArgumentException e) { logger.log(Level.WARNING, "Invalid arguments for recur"); From 401308ac27b8077cd80a9378c8938e2b258ed136 Mon Sep 17 00:00:00 2001 From: hshiah Date: Tue, 17 Oct 2023 13:26:23 +0800 Subject: [PATCH 134/518] Fix some points mentioned by groupmates --- .../commands/AddReminderCommand.java | 3 ++- .../financialplanner/commands/FindCommand.java | 7 ++++--- .../financialplanner/commands/SetGoalCommand.java | 3 ++- .../java/seedu/financialplanner/goal/GoalList.java | 11 +---------- .../java/seedu/financialplanner/list/Cashflow.java | 4 ++++ .../java/seedu/financialplanner/list/Expense.java | 5 +++++ .../java/seedu/financialplanner/list/Income.java | 5 +++++ .../financialplanner/reminder/ReminderList.java | 13 +------------ 8 files changed, 24 insertions(+), 27 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java b/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java index bbc8cb1ce3..0ab96368f4 100644 --- a/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java @@ -1,5 +1,6 @@ package seedu.financialplanner.commands; import seedu.financialplanner.reminder.ReminderList; +import seedu.financialplanner.reminder.Reminder; import seedu.financialplanner.utils.Ui; public class AddReminderCommand extends AbstractCommand{ private final String type; @@ -25,7 +26,7 @@ public AddReminderCommand(RawCommand rawCommand) throws IllegalArgumentException @Override public void execute() { - ReminderList.INSTANCE.addReminder(type, date); + ReminderList.INSTANCE.list.add(new Reminder(type, date)); Ui.INSTANCE.showMessage("Reminder added!"); } } diff --git a/src/main/java/seedu/financialplanner/commands/FindCommand.java b/src/main/java/seedu/financialplanner/commands/FindCommand.java index ec287761c3..565a61dd37 100644 --- a/src/main/java/seedu/financialplanner/commands/FindCommand.java +++ b/src/main/java/seedu/financialplanner/commands/FindCommand.java @@ -25,8 +25,9 @@ public void execute() { ArrayList foundedFinancialList = new ArrayList<>(); ArrayList foundedWatchList = new ArrayList<>(); for (int i = 0; i < cashflowList.list.size(); i++) { - if (cashflowList.list.get(i).formatString().contains(description)) { - foundedFinancialList.add(cashflowList.list.get(i).formatString()+"\tCorresponding index is: "+(i+1)); + if (cashflowList.list.get(i).toString().contains(description)) { + String output = cashflowList.list.get(i).toString()+" | Index: "+(i+1); + foundedFinancialList.add(output); } } if (!foundedFinancialList.isEmpty()) { @@ -40,7 +41,7 @@ public void execute() { for (int i = 0; i < watchList.size(); i++) { if (watchList.get(i).toString().contains(description)) { - foundedWatchList.add(watchList.get(i).toString()+"\tCorresponding index is: "+(i+1)); + foundedWatchList.add(watchList.get(i).toString()+"| Index: "+(i+1)); } } if (!foundedWatchList.isEmpty()) { diff --git a/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java b/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java index d41f8440cf..9ab7a5b8d1 100644 --- a/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java +++ b/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java @@ -1,4 +1,5 @@ package seedu.financialplanner.commands; +import seedu.financialplanner.goal.Goal; import seedu.financialplanner.goal.GoalList; import seedu.financialplanner.utils.Ui; @@ -29,7 +30,7 @@ public SetGoalCommand(RawCommand rawCommand) throws IllegalArgumentException { @Override public void execute() { - GoalList.INSTANCE.addGoal(goal, amount); + GoalList.INSTANCE.list.add(new Goal(goal, amount)); Ui.INSTANCE.showMessage("Set Goal Successfully!"); } } diff --git a/src/main/java/seedu/financialplanner/goal/GoalList.java b/src/main/java/seedu/financialplanner/goal/GoalList.java index 2120439cc1..738b9ce423 100644 --- a/src/main/java/seedu/financialplanner/goal/GoalList.java +++ b/src/main/java/seedu/financialplanner/goal/GoalList.java @@ -2,19 +2,10 @@ import java.util.ArrayList; public class GoalList { public static final GoalList INSTANCE = new GoalList(); - private ArrayList list = new ArrayList<>(); + public ArrayList list = new ArrayList<>(); private GoalList() { } - public void addGoal(String label, int amount) { - list.add(new Goal(label, amount)); - } - public int size() { - return list.size(); - } - public Goal get(int index) { - return list.get(index); - } public void load(Goal goal) { list.add(goal); } diff --git a/src/main/java/seedu/financialplanner/list/Cashflow.java b/src/main/java/seedu/financialplanner/list/Cashflow.java index 61cb1edbac..e400206869 100644 --- a/src/main/java/seedu/financialplanner/list/Cashflow.java +++ b/src/main/java/seedu/financialplanner/list/Cashflow.java @@ -30,4 +30,8 @@ public String getType() { public double getValue() { return value; } + + public String toString() { + return "Value: "+this.value + " | " + "Type: " + this.type + " | " + "Recur: " + this.recur; + } } diff --git a/src/main/java/seedu/financialplanner/list/Expense.java b/src/main/java/seedu/financialplanner/list/Expense.java index 2299bd8105..5324531d0e 100644 --- a/src/main/java/seedu/financialplanner/list/Expense.java +++ b/src/main/java/seedu/financialplanner/list/Expense.java @@ -14,4 +14,9 @@ private void addIncomeValue(double value) { public String formatString() { return "E | " + super.formatString(); } + + @Override + public String toString() { + return "Expense | " + super.toString(); + } } diff --git a/src/main/java/seedu/financialplanner/list/Income.java b/src/main/java/seedu/financialplanner/list/Income.java index 8b21dc1efb..5b7da5e636 100644 --- a/src/main/java/seedu/financialplanner/list/Income.java +++ b/src/main/java/seedu/financialplanner/list/Income.java @@ -14,4 +14,9 @@ private void addIncomeValue(double value) { public String formatString() { return "I | " + super.formatString(); } + + @Override + public String toString() { + return "Income | " + super.toString(); + } } diff --git a/src/main/java/seedu/financialplanner/reminder/ReminderList.java b/src/main/java/seedu/financialplanner/reminder/ReminderList.java index f3a4208640..3aabf432c7 100644 --- a/src/main/java/seedu/financialplanner/reminder/ReminderList.java +++ b/src/main/java/seedu/financialplanner/reminder/ReminderList.java @@ -2,21 +2,10 @@ import java.util.ArrayList; public class ReminderList { public static final ReminderList INSTANCE = new ReminderList(); - private ArrayList list = new ArrayList<>(); + public ArrayList list = new ArrayList<>(); private ReminderList() { } - public void addReminder(String type, String date) { - list.add(new Reminder(type, date)); - } - - public int size() { - return list.size(); - } - - public Reminder get(int index) { - return list.get(index); - } public void load(Reminder reminder) { list.add(reminder); } From e9a6466bf2b37b67c9b63997e1fc4c3a042688ff Mon Sep 17 00:00:00 2001 From: hshiah Date: Tue, 17 Oct 2023 13:40:35 +0800 Subject: [PATCH 135/518] Solve conflict --- src/main/java/seedu/financialplanner/list/Cashflow.java | 3 --- src/main/java/seedu/financialplanner/list/Expense.java | 4 ---- src/main/java/seedu/financialplanner/list/Income.java | 4 ---- 3 files changed, 11 deletions(-) diff --git a/src/main/java/seedu/financialplanner/list/Cashflow.java b/src/main/java/seedu/financialplanner/list/Cashflow.java index e400206869..0d866cd8a8 100644 --- a/src/main/java/seedu/financialplanner/list/Cashflow.java +++ b/src/main/java/seedu/financialplanner/list/Cashflow.java @@ -31,7 +31,4 @@ public double getValue() { return value; } - public String toString() { - return "Value: "+this.value + " | " + "Type: " + this.type + " | " + "Recur: " + this.recur; - } } diff --git a/src/main/java/seedu/financialplanner/list/Expense.java b/src/main/java/seedu/financialplanner/list/Expense.java index 5324531d0e..5d9a78db54 100644 --- a/src/main/java/seedu/financialplanner/list/Expense.java +++ b/src/main/java/seedu/financialplanner/list/Expense.java @@ -15,8 +15,4 @@ public String formatString() { return "E | " + super.formatString(); } - @Override - public String toString() { - return "Expense | " + super.toString(); - } } diff --git a/src/main/java/seedu/financialplanner/list/Income.java b/src/main/java/seedu/financialplanner/list/Income.java index 5b7da5e636..6bb9308909 100644 --- a/src/main/java/seedu/financialplanner/list/Income.java +++ b/src/main/java/seedu/financialplanner/list/Income.java @@ -15,8 +15,4 @@ public String formatString() { return "I | " + super.formatString(); } - @Override - public String toString() { - return "Income | " + super.toString(); - } } From 1f63d6e938171d41ab2214df06a989a882819fe7 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 17 Oct 2023 13:44:37 +0800 Subject: [PATCH 136/518] Add error handling and standardise logging --- .../commands/BudgetCommand.java | 21 ++++++++++++++----- .../seedu/financialplanner/list/Budget.java | 3 +++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java index 80c1c65e7f..a6b25387df 100644 --- a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java +++ b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java @@ -15,31 +15,40 @@ public class BudgetCommand extends AbstractCommand { public BudgetCommand(RawCommand rawCommand) throws FinancialPlannerException { command = String.join(" ", rawCommand.args); if (!command.equals("set") && !command.equals("update")) { - logger.log(Level.WARNING, "Invalid arguments for budget"); + logger.log(Level.WARNING, "Invalid arguments for budget command"); throw new FinancialPlannerException("Please indicate whether budget is to be set or update."); } if (command.equals("set") && Budget.hasBudget()) { - logger.log(Level.INFO, "Trying to set existing budget"); + logger.log(Level.WARNING, "Invalid command: Trying to set existing budget"); throw new FinancialPlannerException("There is an existing budget, did you mean update?"); } if (command.equals("update") && !Budget.hasBudget()) { - logger.log(Level.INFO, "Trying to update non-existent budget"); + logger.log(Level.WARNING, "Invalid command: Trying to update non-existent budget"); throw new FinancialPlannerException("There is no budget set yet, did you mean set?"); } if (!rawCommand.extraArgs.containsKey("b")) { - logger.log(Level.WARNING, "Missing arguments b in command"); + logger.log(Level.WARNING, "Missing argument /b in command"); throw new IllegalArgumentException("Missing /b argument."); } try { + logger.log(Level.INFO, "Parsing budget as double"); budget = Double.parseDouble(rawCommand.extraArgs.get("b")); } catch (IllegalArgumentException e) { logger.log(Level.WARNING, "Invalid value for budget"); throw new IllegalArgumentException("Budget must be a number."); } + + if (budget <= 0) { + logger.log(Level.WARNING, "Invalid value for budget."); + throw new FinancialPlannerException("Budget should be greater than 0"); + } + + //compare budget to balance + assert budget > 0 : "Budget should be greater than 0"; rawCommand.extraArgs.remove("b"); } @@ -49,11 +58,13 @@ public void execute() { switch (command) { case "set": + logger.log(Level.INFO, "Setting budget"); Budget.setBudget(budget); Ui.INSTANCE.showMessage("A monthly budget of " + String.format("%.2f", Budget.getInitialBudget()) + " has been set."); break; case "update": + logger.log(Level.INFO, "Updating budget"); Ui.INSTANCE.showMessage("Budget has been updated:\nOld initial budget: " + String.format("%.2f", Budget.getInitialBudget()) + "\nOld current budget: " + String.format("%.2f", Budget.getCurrentBudget())); @@ -66,7 +77,7 @@ public void execute() { } break; default: - logger.log(Level.WARNING, "command should never reach default case"); + logger.log(Level.SEVERE, "Unreachable default case reached"); Ui.INSTANCE.showMessage("Unknown command."); } } diff --git a/src/main/java/seedu/financialplanner/list/Budget.java b/src/main/java/seedu/financialplanner/list/Budget.java index e3eaafac75..8f25a9b8eb 100644 --- a/src/main/java/seedu/financialplanner/list/Budget.java +++ b/src/main/java/seedu/financialplanner/list/Budget.java @@ -8,6 +8,8 @@ public abstract class Budget { public static void setBudget(double amount) { initialBudget = amount; currentBudget = amount; + assert initialBudget == currentBudget : "Initial and current budget should be the same"; + assert initialBudget != 0 && currentBudget != 0 : "Initial and current budget should not be 0"; } public static double getInitialBudget() { @@ -25,6 +27,7 @@ public static void updateBudget(double budget) { initialBudget = budget; currentBudget -= diff; } + assert initialBudget == budget : "Initial budget should be equal to updated budget"; } public static double getCurrentBudget() { From c97daf2496479364271d54c2da1b3e6466e9fa8c Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 17 Oct 2023 13:49:10 +0800 Subject: [PATCH 137/518] Extract print statement to Ui --- .../financialplanner/commands/AddCashflowCommand.java | 9 +-------- src/main/java/seedu/financialplanner/utils/Ui.java | 11 +++++++++++ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index a63a030e28..abbd054147 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -75,13 +75,6 @@ public void execute() { private static void deductFromBudget(Cashflow entry) { double expenseAmount = entry.getAmount(); Budget.deduct(expenseAmount); - String message = ""; - if (Budget.getCurrentBudget() <= 0) { - message += "You have exceeded your current budget by: "; - } else if (Budget.getCurrentBudget() > 0) { - message += "Your remaining budget for the month is: "; - } - message += Budget.getCurrentBudgetString(); - Ui.INSTANCE.showMessage(message); + Ui.INSTANCE.printBudgetAfterDeduction(); } } diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index c9226b21d3..5ab96ffe7f 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -88,4 +88,15 @@ public void printBudgetAfterUpdate() { showMessage("New initial budget: " + Budget.getInitialBudgetString() + "\nNew current budget: " + Budget.getCurrentBudgetString()); } + + public void printBudgetAfterDeduction() { + String message = ""; + if (Budget.getCurrentBudget() <= 0) { + message += "You have exceeded your current budget by: "; + } else if (Budget.getCurrentBudget() > 0) { + message += "Your remaining budget for the month is: "; + } + message += Budget.getCurrentBudgetString(); + showMessage(message); + } } From f87a53b2a70f909bafc095d6c425d023c4e5c8e9 Mon Sep 17 00:00:00 2001 From: hshiah Date: Tue, 17 Oct 2023 14:05:26 +0800 Subject: [PATCH 138/518] Delete getValue function --- src/main/java/seedu/financialplanner/goal/Goal.java | 2 +- src/main/java/seedu/financialplanner/list/Cashflow.java | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/main/java/seedu/financialplanner/goal/Goal.java b/src/main/java/seedu/financialplanner/goal/Goal.java index 0c9c6024a2..f415ba48ac 100644 --- a/src/main/java/seedu/financialplanner/goal/Goal.java +++ b/src/main/java/seedu/financialplanner/goal/Goal.java @@ -16,7 +16,7 @@ public void markAsDone() { //TODO edit the expense to mark the goal as done this.isDone = true; } - //TODO delete the Reminde + //TODO delete the Reminder public String formatString() { String status = isDone ? "Done" : "Not Done"; return this.label + " | " + this.amount + " | " + this.isDone; diff --git a/src/main/java/seedu/financialplanner/list/Cashflow.java b/src/main/java/seedu/financialplanner/list/Cashflow.java index 1b7542cf7f..23068f621a 100644 --- a/src/main/java/seedu/financialplanner/list/Cashflow.java +++ b/src/main/java/seedu/financialplanner/list/Cashflow.java @@ -62,9 +62,4 @@ public String getType() { return type; } - - public double getValue() { - return value; - } - } From 19dcfc60b44a315ae74f99f0b8cf12b161ce7d81 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 17 Oct 2023 14:31:34 +0800 Subject: [PATCH 139/518] Add error handling for budget --- .../financialplanner/commands/BudgetCommand.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java index b3b4131f5e..b9f7bee6de 100644 --- a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java +++ b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java @@ -2,6 +2,7 @@ import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.list.Budget; +import seedu.financialplanner.list.Cashflow; import seedu.financialplanner.utils.Ui; import java.util.logging.Level; @@ -45,11 +46,16 @@ public BudgetCommand(RawCommand rawCommand) throws FinancialPlannerException { if (budget <= 0) { logger.log(Level.WARNING, "Invalid value for budget."); - throw new FinancialPlannerException("Budget should be greater than 0"); + throw new FinancialPlannerException("Budget should be greater than 0."); } - //compare budget to balance - assert budget > 0 : "Budget should be greater than 0"; + if (budget > Cashflow.getBalance()) { + logger.log(Level.WARNING, "Invalid value for budget"); + throw new FinancialPlannerException("Budget should be lower than total balance."); + } + + assert budget > 0 && budget <= Cashflow.getBalance() : "Budget should be greater than 0 and less than " + + "or equal to total balance"; rawCommand.extraArgs.remove("b"); if (!rawCommand.extraArgs.isEmpty()) { @@ -60,7 +66,7 @@ public BudgetCommand(RawCommand rawCommand) throws FinancialPlannerException { @Override public void execute() { - assert command.equals("set") || command.equals("update") : "command should be set or update only"; + assert command.equals("set") || command.equals("update") : "Command should be set or update only"; switch (command) { case "set": From 06288d6b645b1698db95a5a74fb31a5947820789 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 17 Oct 2023 14:44:31 +0800 Subject: [PATCH 140/518] Update test files --- text-ui-test/EXPECTED.TXT | 20 +++++++++++++------- text-ui-test/input.txt | 5 +++-- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 964ec748b9..fd98355472 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -51,17 +51,23 @@ Use Watchlist to view it! You have successfully added: Gamestop Corporation - Class A Use Watchlist to view it! -A monthly budget of 5000.00 has been set. +You have added an Income + Type: work + Amount: 5000.00 + Recurring every: 30 days +to the Financial Planner. +Balance: 5000.00 +A monthly budget of 3000.00 has been set. Budget has been updated: -Old initial budget: 5000.00 -Old current budget: 5000.00 -New initial budget: 3000.00 -New current budget: 3000.00 +Old initial budget: 3000.00 +Old current budget: 3000.00 +New initial budget: 1000.00 +New current budget: 1000.00 You have added an Expense Type: airpods Amount: 200.00 to the Financial Planner. -Balance: -200.00 -Your remaining budget for the month is: 2800.00 +Balance: 4800.00 +Your remaining budget for the month is: 800.00 Unknown command. Please try again. Exiting Financial Planner. Goodbye. diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index b750f68c07..e8872b6f15 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -8,8 +8,9 @@ delete expense 2 delete 1 addstock /s MSFT addstock /s GME -budget set /b 5000 -budget update /b 3000 +add income /a 5000 /t work /r 30 +budget set /b 3000 +budget update /b 1000 add expense /a 200 /t airpods sdf exit \ No newline at end of file From d37e2a293714b82b7d9f79e06cecb35599196bce Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Tue, 17 Oct 2023 20:30:57 +0800 Subject: [PATCH 141/518] Add logging for Vis Command --- .../java/seedu/financialplanner/commands/VisCommand.java | 5 +++++ .../seedu/financialplanner/visualisations/Visualizer.java | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/VisCommand.java b/src/main/java/seedu/financialplanner/commands/VisCommand.java index dd5cfe51f0..17d1b2a6bd 100644 --- a/src/main/java/seedu/financialplanner/commands/VisCommand.java +++ b/src/main/java/seedu/financialplanner/commands/VisCommand.java @@ -6,11 +6,14 @@ import seedu.financialplanner.visualisations.Visualizer; import java.util.ArrayList; +import java.util.logging.Level; +import java.util.logging.Logger; public class VisCommand extends AbstractCommand { private String type; private String chart; + private static Logger logger = Logger.getLogger("Financial Planner Logger"); public VisCommand(RawCommand rawCommand) throws IllegalArgumentException { if (!rawCommand.extraArgs.containsKey("t")) { @@ -19,12 +22,14 @@ public VisCommand(RawCommand rawCommand) throws IllegalArgumentException { if (!rawCommand.extraArgs.containsKey("c")) { throw new IllegalArgumentException("Chart type must be defined"); } + logger.log(Level.INFO, "Parsing entry type and chart type"); this.type = rawCommand.extraArgs.get("t"); rawCommand.extraArgs.remove("t"); this.chart = rawCommand.extraArgs.get("c"); rawCommand.extraArgs.remove("c"); if (!rawCommand.extraArgs.isEmpty()) { String unknownExtraArgument = new ArrayList<>(rawCommand.extraArgs.keySet()).get(0); + logger.log(Level.WARNING, "Invalid extra arguments found"); throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); } } diff --git a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java index 8171713852..c559c675ee 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java @@ -51,7 +51,7 @@ public static void displayPieChart (Map expensesByCat) { for (Map.Entry set: expensesByCat.entrySet()) { chart.addSeries(set.getKey(), set.getValue()); } - logger.log(Level.INFO, "Showing Pie Chart"); + logger.log(Level.INFO, "Displaying Pie Chart"); // Show it JFrame swHR = new SwingWrapper<>(chart).displayChart(); javax.swing.SwingUtilities.invokeLater( @@ -71,7 +71,7 @@ public static void displayBarChart (Map expensesByCat) { List keys = new ArrayList(expensesByCat.keySet()); chart.addSeries("Expense", keys, values); - logger.log(Level.INFO, "Showing Bar Chart"); + logger.log(Level.INFO, "Displaying Bar Chart"); JFrame swHR = new SwingWrapper<>(chart).displayChart(); javax.swing.SwingUtilities.invokeLater( ()->swHR.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE) From c7897b1d61ad607722a0af7243c2c0412cbb6074 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Tue, 17 Oct 2023 20:40:37 +0800 Subject: [PATCH 142/518] Add assert for visualizations related classes --- .../java/seedu/financialplanner/commands/VisCommand.java | 2 ++ .../seedu/financialplanner/visualisations/Categorizer.java | 2 ++ .../seedu/financialplanner/visualisations/VisualType.java | 5 ----- .../seedu/financialplanner/visualisations/Visualizer.java | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) delete mode 100644 src/main/java/seedu/financialplanner/visualisations/VisualType.java diff --git a/src/main/java/seedu/financialplanner/commands/VisCommand.java b/src/main/java/seedu/financialplanner/commands/VisCommand.java index 17d1b2a6bd..5f1f059b0f 100644 --- a/src/main/java/seedu/financialplanner/commands/VisCommand.java +++ b/src/main/java/seedu/financialplanner/commands/VisCommand.java @@ -35,6 +35,8 @@ public VisCommand(RawCommand rawCommand) throws IllegalArgumentException { } @Override public void execute() throws FinancialPlannerException { + assert !chart.isEmpty(); + assert !type.isEmpty(); Visualizer.displayChart(chart, Categorizer.sortType(CashflowList.INSTANCE, type)); } } diff --git a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java index f2a41671f4..3fee03d636 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java @@ -32,6 +32,7 @@ public static Map sortExpenses(CashflowList cashflowList) { if (e instanceof Expense) { String key = e.getType(); double value = expensesByCat.getOrDefault(key, 0.0) + e.getAmount(); + assert value >= 0; expensesByCat.put(key, value); } } @@ -44,6 +45,7 @@ public static Map sortIncome(CashflowList cashflowList) { if (e instanceof Income) { String key = e.getType(); double value = incomeByCat.getOrDefault(key, 0.0) + e.getAmount(); + assert value >= 0; incomeByCat.put(key, value); } } diff --git a/src/main/java/seedu/financialplanner/visualisations/VisualType.java b/src/main/java/seedu/financialplanner/visualisations/VisualType.java deleted file mode 100644 index 57ec86bbf8..0000000000 --- a/src/main/java/seedu/financialplanner/visualisations/VisualType.java +++ /dev/null @@ -1,5 +0,0 @@ -package seedu.financialplanner.visualisations; - -public enum VisualType { - PIECHART, BARGRAPH -} diff --git a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java index c559c675ee..b955d5b9ff 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java @@ -65,7 +65,7 @@ public static void displayBarChart (Map expensesByCat) { // Customize Chart chart.getStyler().setLegendPosition(Styler.LegendPosition.InsideNW); chart.getStyler().setHasAnnotations(true); - + assert !expensesByCat.isEmpty(); // Series List values = new ArrayList(expensesByCat.values()); List keys = new ArrayList(expensesByCat.keySet()); From a3dd93f6e66d04efcc7f61d57df01c3e05772535 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Tue, 17 Oct 2023 20:44:15 +0800 Subject: [PATCH 143/518] Fix error in check style --- src/main/java/seedu/financialplanner/commands/VisCommand.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/VisCommand.java b/src/main/java/seedu/financialplanner/commands/VisCommand.java index 5f1f059b0f..4227019420 100644 --- a/src/main/java/seedu/financialplanner/commands/VisCommand.java +++ b/src/main/java/seedu/financialplanner/commands/VisCommand.java @@ -10,10 +10,10 @@ import java.util.logging.Logger; public class VisCommand extends AbstractCommand { - + private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private String type; private String chart; - private static Logger logger = Logger.getLogger("Financial Planner Logger"); + public VisCommand(RawCommand rawCommand) throws IllegalArgumentException { if (!rawCommand.extraArgs.containsKey("t")) { From 5562991591bfeb1bc8e0cf33b9e4d9ef55ee5a11 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Wed, 18 Oct 2023 00:16:31 +0800 Subject: [PATCH 144/518] Add logging and assert for watchlist command --- .../seedu/financialplanner/commands/WatchListCommand.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java index 98277c94a4..b9ec800acd 100644 --- a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java @@ -5,19 +5,26 @@ import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.utils.Ui; import java.util.ArrayList; +import java.util.logging.Level; +import java.util.logging.Logger; public class WatchListCommand extends AbstractCommand { + private static final Logger logger = Logger.getLogger("Financial Planner Logger"); public WatchListCommand(RawCommand rawCommand) throws IllegalArgumentException{ if (!rawCommand.extraArgs.isEmpty()) { + logger.log(Level.WARNING, "Invalid extra arguments found"); String unknownExtraArgument = new ArrayList<>(rawCommand.extraArgs.keySet()).get(0); + assert unknownExtraArgument != null; throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); } } @Override public void execute() { JSONArray stocks = WatchList.INSTANCE.fetchFMPStockPrices(); + assert !(stocks == null); Ui.INSTANCE.printWatchListHeader(); + logger.log(Level.INFO, "Printing watchlist"); for (Object o : stocks) { JSONObject stock = (JSONObject) o; Ui.INSTANCE.printStockInfo(stock); From 3de6f7e633a56dea1df03c9b4daf3a112a6212c3 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Wed, 18 Oct 2023 00:36:14 +0800 Subject: [PATCH 145/518] Add logging and assert to AddStockCommand, Stock and Watchlist --- .../commands/AddStockCommand.java | 10 ++++++++++ .../financialplanner/investments/Stock.java | 7 +++++++ .../investments/WatchList.java | 19 +++++++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java index bb4a479681..4a57233fe7 100644 --- a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java @@ -5,18 +5,25 @@ import seedu.financialplanner.utils.Ui; import java.util.ArrayList; +import java.util.logging.Level; +import java.util.logging.Logger; public class AddStockCommand extends AbstractCommand { + private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private final String stockCode; public AddStockCommand(RawCommand rawCommand) throws IllegalArgumentException { if (!rawCommand.extraArgs.containsKey("s")) { throw new IllegalArgumentException("Stock code cannot be empty"); } + + logger.log(Level.INFO, "Parsing stockcode from input"); stockCode = rawCommand.extraArgs.get("s"); + rawCommand.extraArgs.remove("s"); if (!rawCommand.extraArgs.isEmpty()) { String unknownExtraArgument = new ArrayList<>(rawCommand.extraArgs.keySet()).get(0); + logger.log(Level.WARNING, "Invalid extra arguments found"); throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); } } @@ -27,10 +34,13 @@ public void execute() { WatchList watchList = WatchList.INSTANCE; String stockName; + logger.log(Level.INFO, "adding stock to watchlist"); try { stockName = watchList.addStock(stockCode); + assert stockName != null; ui.printAddStock(stockName); } catch (FinancialPlannerException e) { + logger.log(Level.SEVERE, "Error adding stock to watchlist"); System.out.println(e.getMessage()); } } diff --git a/src/main/java/seedu/financialplanner/investments/Stock.java b/src/main/java/seedu/financialplanner/investments/Stock.java index f39275877a..995b3d26f6 100644 --- a/src/main/java/seedu/financialplanner/investments/Stock.java +++ b/src/main/java/seedu/financialplanner/investments/Stock.java @@ -12,8 +12,11 @@ import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.time.Duration; +import java.util.logging.Level; +import java.util.logging.Logger; public class Stock { + private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private String symbol; private String market; private String stockName; @@ -36,6 +39,8 @@ public String getStockNameFromAPI(String symbol) throws FinancialPlannerExceptio .GET() .timeout(Duration.ofSeconds(10)) .build(); + + logger.log(Level.INFO, "Requesting API for stock info"); try { HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); Object obj = new JSONParser().parse(response.body()); @@ -56,6 +61,8 @@ public String getStockNameFromAPI(String symbol) throws FinancialPlannerExceptio if (!symbolFound.equals(symbol)) { throw new FinancialPlannerException("Stock not found"); } + + assert stock.get("2. name") != null; market = (String) stock.get("4. region"); return (String) stock.get("2. name"); } catch (IOException e) { diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index 02396168f8..04855e97b4 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -12,20 +12,30 @@ import java.net.http.HttpResponse; import java.time.Duration; import java.util.ArrayList; +import java.util.logging.Level; +import java.util.logging.Logger; public class WatchList { + private static final Logger logger = Logger.getLogger("Financial Planner Logger"); public static final WatchList INSTANCE = new WatchList(); private final ArrayList stocks; private final String API_ENDPOINT = "https://financialmodelingprep.com/api/v3/quote/"; private final String API_KEY = "iFumtYryBCbHpS3sDqLdVKi2SdP63vSV"; private WatchList() { stocks = new ArrayList<>(); + + logger.log(Level.INFO, "Adding Base Stocks"); try { Stock apple = new Stock("AAPL"); + assert apple.getSymbol() != null && apple.getStockName() != null; stocks.add(apple); + Stock meta = new Stock("META"); + assert meta.getSymbol() != null && meta.getStockName() != null; stocks.add(meta); + Stock google = new Stock("GOOGL"); + assert google.getSymbol() != null && google.getStockName() != null; stocks.add(google); } catch (FinancialPlannerException e) { System.out.println(e.getMessage()); @@ -35,6 +45,8 @@ private WatchList() { public JSONArray fetchFMPStockPrices() { HttpClient client = HttpClient.newHttpClient(); StringBuilder queryStocks = new StringBuilder(); + + assert !stocks.isEmpty(); for (Stock stock : stocks) { queryStocks.append(stock.toString()); } @@ -45,15 +57,20 @@ public JSONArray fetchFMPStockPrices() { .timeout(Duration.ofSeconds(10)) .build(); Object obj; + + logger.log(Level.INFO, "Requesting API endpoint FMP"); try { HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); // System.out.println(response.body()); obj = new JSONParser().parse(response.body()); } catch (IOException e) { + logger.log(Level.SEVERE, "Cant request API endpoint"); throw new RuntimeException(e); } catch (InterruptedException e) { + logger.log(Level.SEVERE, "Interrupted"); throw new RuntimeException(e); } catch (ParseException e) { + logger.log(Level.SEVERE, "Could not parse to JSON"); throw new RuntimeException(e); } return (JSONArray) obj; @@ -62,6 +79,8 @@ public JSONArray fetchFMPStockPrices() { public String addStock(String stockCode) throws FinancialPlannerException { Stock newStock = null; newStock = new Stock(stockCode); + + assert newStock.getSymbol() != null && newStock.getStockName() != null; stocks.add(newStock); return newStock.getStockName(); } From 8d06dc08254699a08a4fff6922f9b7194c4a1dbb Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Wed, 18 Oct 2023 00:47:11 +0800 Subject: [PATCH 146/518] Fix checkstyle errors --- .../java/seedu/financialplanner/investments/WatchList.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index 04855e97b4..1995e1e6be 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -16,8 +16,9 @@ import java.util.logging.Logger; public class WatchList { - private static final Logger logger = Logger.getLogger("Financial Planner Logger"); + public static final WatchList INSTANCE = new WatchList(); + private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private final ArrayList stocks; private final String API_ENDPOINT = "https://financialmodelingprep.com/api/v3/quote/"; private final String API_KEY = "iFumtYryBCbHpS3sDqLdVKi2SdP63vSV"; From 15f9d47404e37efa56d679a640a19715f6fb9b83 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Wed, 18 Oct 2023 01:02:02 +0800 Subject: [PATCH 147/518] Add handling for API limit reach and logging in constructor fix --- src/main/java/seedu/financialplanner/investments/Stock.java | 3 +++ .../java/seedu/financialplanner/investments/WatchList.java | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/investments/Stock.java b/src/main/java/seedu/financialplanner/investments/Stock.java index 995b3d26f6..453e0a19ab 100644 --- a/src/main/java/seedu/financialplanner/investments/Stock.java +++ b/src/main/java/seedu/financialplanner/investments/Stock.java @@ -47,6 +47,9 @@ public String getStockNameFromAPI(String symbol) throws FinancialPlannerExceptio JSONObject jsonObject = (JSONObject) obj; JSONArray ja = (JSONArray) jsonObject.get("bestMatches"); + if (ja == null) { + throw new FinancialPlannerException("API limit Reached"); + } if (ja.isEmpty()) { throw new FinancialPlannerException("stock not found"); } diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index 1995e1e6be..02d14ffe41 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -18,14 +18,14 @@ public class WatchList { public static final WatchList INSTANCE = new WatchList(); - private static final Logger logger = Logger.getLogger("Financial Planner Logger"); + private static Logger logger = Logger.getLogger("Financial Planner Logger"); private final ArrayList stocks; private final String API_ENDPOINT = "https://financialmodelingprep.com/api/v3/quote/"; private final String API_KEY = "iFumtYryBCbHpS3sDqLdVKi2SdP63vSV"; private WatchList() { stocks = new ArrayList<>(); - logger.log(Level.INFO, "Adding Base Stocks"); + // logger.log(Level.INFO, "Adding Base Stocks"); try { Stock apple = new Stock("AAPL"); assert apple.getSymbol() != null && apple.getStockName() != null; From 0ee9efd58624b16160b1d2427a129cc636383756 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Wed, 18 Oct 2023 11:57:59 +0800 Subject: [PATCH 148/518] Standardize logging --- src/main/java/seedu/financialplanner/investments/Stock.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/investments/Stock.java b/src/main/java/seedu/financialplanner/investments/Stock.java index 453e0a19ab..d4aa1986b0 100644 --- a/src/main/java/seedu/financialplanner/investments/Stock.java +++ b/src/main/java/seedu/financialplanner/investments/Stock.java @@ -51,7 +51,7 @@ public String getStockNameFromAPI(String symbol) throws FinancialPlannerExceptio throw new FinancialPlannerException("API limit Reached"); } if (ja.isEmpty()) { - throw new FinancialPlannerException("stock not found"); + throw new FinancialPlannerException("Stock not found"); } JSONObject stock = (JSONObject) ja.get(0); String symbolFound = (String) stock.get("1. symbol"); From 6161f6a7773821576d303d4690b81263e271d4dc Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Wed, 18 Oct 2023 19:12:54 +0800 Subject: [PATCH 149/518] Remove commented code --- src/main/java/seedu/financialplanner/investments/WatchList.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index 02d14ffe41..dd00c9f968 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -24,8 +24,6 @@ public class WatchList { private final String API_KEY = "iFumtYryBCbHpS3sDqLdVKi2SdP63vSV"; private WatchList() { stocks = new ArrayList<>(); - - // logger.log(Level.INFO, "Adding Base Stocks"); try { Stock apple = new Stock("AAPL"); assert apple.getSymbol() != null && apple.getStockName() != null; From f4bb78cbbff71e0d1074ca5c73a2173463dea77e Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Wed, 18 Oct 2023 20:23:35 +0800 Subject: [PATCH 150/518] Remove logger from showing on terminal --- .../java/seedu/financialplanner/FinancialPlannerLogger.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/seedu/financialplanner/FinancialPlannerLogger.java b/src/main/java/seedu/financialplanner/FinancialPlannerLogger.java index 0145f0293f..df085a588b 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlannerLogger.java +++ b/src/main/java/seedu/financialplanner/FinancialPlannerLogger.java @@ -4,6 +4,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.logging.SimpleFormatter; +import java.util.logging.LogManager; public class FinancialPlannerLogger { private static Logger logger = Logger.getLogger("Financial Planner Logger"); @@ -11,6 +12,7 @@ public class FinancialPlannerLogger { public static void initialise() { try { FileHandler fh = new FileHandler("data/logger.log"); + LogManager.getLogManager().reset(); logger.addHandler(fh); fh.setFormatter(new SimpleFormatter()); logger.log(Level.INFO, "Logger initialised"); From 2a7a8aa2c20b6fb8e871c81322c8d3c5f42fc4fc Mon Sep 17 00:00:00 2001 From: YFshadaow Date: Wed, 18 Oct 2023 22:46:24 +0800 Subject: [PATCH 151/518] Fix style error --- .../financialplanner/commands/DeleteCashflowCommand.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java index 10fdbde720..158282222a 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java @@ -7,10 +7,10 @@ import java.util.logging.Level; import java.util.logging.Logger; -public class DeleteCashflowCommand extends AbstractCommand{ +public class DeleteCashflowCommand extends AbstractCommand { + private static final Logger logger = Logger.getLogger("Financial Planner Logger"); protected CashflowCategory category = null; - private static Logger logger = Logger.getLogger("Financial Planner Logger"); protected int index; public DeleteCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException { @@ -46,6 +46,7 @@ public DeleteCashflowCommand(RawCommand rawCommand) throws IllegalArgumentExcept } } } + private void handleInvalidCategory(String stringCategory) { try { logger.log(Level.INFO, "Parsing CashflowCategory"); From 99e9427b0418815aefec44af8fe242507e05b5bd Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 22 Oct 2023 17:18:44 +0800 Subject: [PATCH 152/518] Add getInstance() method for singleton CashflowList class --- .../financialplanner/commands/AddCashflowCommand.java | 8 ++++---- .../commands/DeleteCashflowCommand.java | 11 ++++------- .../seedu/financialplanner/list/CashflowList.java | 11 +++++++++-- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index 255c0b8665..9d5ef81a43 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -18,6 +18,7 @@ public class AddCashflowCommand extends AbstractCommand { protected CashflowCategory category; protected String type; protected int recur = 0; + protected CashflowList cashflowList = CashflowList.getInstance(); public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException { String typeString = String.join(" ", rawCommand.args); @@ -88,13 +89,12 @@ public void execute() { switch (category) { case INCOME: - CashflowList.INSTANCE.addIncome(amount, type, recur); + cashflowList.addIncome(amount, type, recur); break; case EXPENSE: - CashflowList list = CashflowList.INSTANCE; - list.addExpense(amount, type, recur); + cashflowList.addExpense(amount, type, recur); if (Budget.hasBudget()) { - deductFromBudget(list.list.get(list.list.size() - 1)); + deductFromBudget(cashflowList.list.get(cashflowList.list.size() - 1)); } break; default: diff --git a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java index 158282222a..21ae2a6884 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java @@ -12,6 +12,7 @@ public class DeleteCashflowCommand extends AbstractCommand { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); protected CashflowCategory category = null; protected int index; + protected CashflowList cashflowList = CashflowList.getInstance(); public DeleteCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException { String stringIndex; @@ -39,11 +40,7 @@ public DeleteCashflowCommand(RawCommand rawCommand) throws IllegalArgumentExcept throw new IllegalArgumentException("Index must be within the list"); } if (stringCategory != null) { - try { - category = CashflowCategory.valueOf(stringCategory.toUpperCase()); - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException("Entry must be either income or expense"); - } + handleInvalidCategory(stringCategory); } } @@ -81,7 +78,7 @@ public void execute() { private void handleDeleteCashflowWithoutCategory() { try { logger.log(Level.INFO, "Deleting cashflow without category"); - CashflowList.INSTANCE.delete(index); + cashflowList.delete(index); } catch (IndexOutOfBoundsException e) { logger.log(Level.WARNING, "Index out of list"); throw new IllegalArgumentException("Index must be within the list"); @@ -91,7 +88,7 @@ private void handleDeleteCashflowWithoutCategory() { private void handleDeleteCashflowWithCategory() { try { logger.log(Level.INFO, "Deleting cashflow with category"); - CashflowList.INSTANCE.deleteCashflow(category, index); + cashflowList.deleteCashflow(category, index); } catch (IndexOutOfBoundsException e) { logger.log(Level.WARNING, "Index out of list"); throw new IllegalArgumentException("Index must be within the list"); diff --git a/src/main/java/seedu/financialplanner/list/CashflowList.java b/src/main/java/seedu/financialplanner/list/CashflowList.java index c83a640a99..32eb869f6e 100644 --- a/src/main/java/seedu/financialplanner/list/CashflowList.java +++ b/src/main/java/seedu/financialplanner/list/CashflowList.java @@ -7,14 +7,21 @@ import java.util.logging.Logger; public class CashflowList { - public static Logger logger = Logger.getLogger("Financial Planner Logger"); + private static final Logger logger = Logger.getLogger("Financial Planner Logger"); - public static final CashflowList INSTANCE = new CashflowList(); + private static CashflowList cashflowList = null; public final ArrayList list = new ArrayList<>(); private CashflowList() { } + public static CashflowList getInstance() { + if (cashflowList == null) { + cashflowList = new CashflowList(); + } + return cashflowList; + } + public void addIncome(double value, String type, int recur) { logger.log(Level.INFO, "Adding income"); int existingListSize = list.size(); From 19547febc66f3905749b7b3e6e9eb27db45ee85f Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 22 Oct 2023 18:17:39 +0800 Subject: [PATCH 153/518] Add income and expense type enums --- .../seedu/financialplanner/enumerations/ExpenseType.java | 5 +++++ .../java/seedu/financialplanner/enumerations/IncomeType.java | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 src/main/java/seedu/financialplanner/enumerations/ExpenseType.java create mode 100644 src/main/java/seedu/financialplanner/enumerations/IncomeType.java diff --git a/src/main/java/seedu/financialplanner/enumerations/ExpenseType.java b/src/main/java/seedu/financialplanner/enumerations/ExpenseType.java new file mode 100644 index 0000000000..c756905400 --- /dev/null +++ b/src/main/java/seedu/financialplanner/enumerations/ExpenseType.java @@ -0,0 +1,5 @@ +package seedu.financialplanner.enumerations; + +public enum ExpenseType { + DINING, ENTERTAINMENT, SHOPPING, TRAVEL, INSURANCE, OTHERS +} diff --git a/src/main/java/seedu/financialplanner/enumerations/IncomeType.java b/src/main/java/seedu/financialplanner/enumerations/IncomeType.java new file mode 100644 index 0000000000..4fee2b2f78 --- /dev/null +++ b/src/main/java/seedu/financialplanner/enumerations/IncomeType.java @@ -0,0 +1,5 @@ +package seedu.financialplanner.enumerations; + +public enum IncomeType { + SALARY, INVESTMENTS, ALLOWANCE, OTHERS +} From 2afd67b5f1cd51357312a17c58947cfd71a242be Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 22 Oct 2023 18:58:04 +0800 Subject: [PATCH 154/518] Add getInstance() method to Ui singleton class --- .../financialplanner/FinancialPlanner.java | 4 +-- .../commands/BudgetCommand.java | 9 ++++--- .../commands/WatchListCommand.java | 5 ++-- .../java/seedu/financialplanner/utils/Ui.java | 9 +++++-- .../financialplanner/storage/StorageTest.java | 26 +++++++++---------- 5 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index ed6f00f90f..5bd2dd2f3b 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -13,9 +13,9 @@ public class FinancialPlanner { private static final String FILE_PATH = "data/data.txt"; private final Storage storage = Storage.INSTANCE; - private final Ui ui = Ui.INSTANCE; + private final Ui ui = Ui.getInstance(); private final WatchList watchList = WatchList.INSTANCE; - private final CashflowList cashflowList = CashflowList.INSTANCE; + private final CashflowList cashflowList = CashflowList.getInstance(); private FinancialPlanner() { } diff --git a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java index b9f7bee6de..07771ea4a3 100644 --- a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java +++ b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java @@ -68,22 +68,23 @@ public BudgetCommand(RawCommand rawCommand) throws FinancialPlannerException { public void execute() { assert command.equals("set") || command.equals("update") : "Command should be set or update only"; + Ui ui = Ui.getInstance(); switch (command) { case "set": logger.log(Level.INFO, "Setting budget"); Budget.setBudget(budget); - Ui.INSTANCE.showMessage("A monthly budget of " + Budget.getInitialBudgetString() + ui.showMessage("A monthly budget of " + Budget.getInitialBudgetString() + " has been set."); break; case "update": logger.log(Level.INFO, "Updating budget"); - Ui.INSTANCE.printBudgetBeforeUpdate(); + ui.printBudgetBeforeUpdate(); Budget.updateBudget(budget); - Ui.INSTANCE.printBudgetAfterUpdate(); + ui.printBudgetAfterUpdate(); break; default: logger.log(Level.SEVERE, "Unreachable default case reached"); - Ui.INSTANCE.showMessage("Unknown command."); + ui.showMessage("Unknown command."); } } } diff --git a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java index b9ec800acd..beaaa4da2f 100644 --- a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java @@ -20,14 +20,15 @@ public WatchListCommand(RawCommand rawCommand) throws IllegalArgumentException{ } @Override public void execute() { + Ui ui = Ui.getInstance(); JSONArray stocks = WatchList.INSTANCE.fetchFMPStockPrices(); assert !(stocks == null); - Ui.INSTANCE.printWatchListHeader(); + ui.printWatchListHeader(); logger.log(Level.INFO, "Printing watchlist"); for (Object o : stocks) { JSONObject stock = (JSONObject) o; - Ui.INSTANCE.printStockInfo(stock); + ui.printStockInfo(stock); } } } diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 4b9511884c..8cc0242e26 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -8,12 +8,17 @@ import java.util.Scanner; public class Ui { - public static final Ui INSTANCE = new Ui(); + private static Ui ui = null; private Scanner Scanner = new Scanner(System.in); private Ui() { } - + public static Ui getInstance() { + if (ui == null) { + ui = new Ui(); + } + return ui; + } public static void printCorruptedFileError(String message) { System.out.println(message); } diff --git a/src/test/java/seedu/financialplanner/storage/StorageTest.java b/src/test/java/seedu/financialplanner/storage/StorageTest.java index bec28f1863..f168d0097c 100644 --- a/src/test/java/seedu/financialplanner/storage/StorageTest.java +++ b/src/test/java/seedu/financialplanner/storage/StorageTest.java @@ -2,6 +2,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; +import seedu.financialplanner.enumerations.ExpenseType; +import seedu.financialplanner.enumerations.IncomeType; import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.list.Expense; import seedu.financialplanner.list.CashflowList; @@ -20,13 +22,13 @@ public class StorageTest { @TempDir public static Path testFolder; - + protected CashflowList cashflowList = CashflowList.getInstance(); + protected Ui ui = Ui.getInstance(); @Test public void loadValidData() throws FinancialPlannerException { Storage storage = Storage.INSTANCE; - CashflowList cashflowList = CashflowList.INSTANCE; cashflowList.list.clear(); - storage.load(cashflowList, Ui.INSTANCE, "src/test/testData/ValidData.txt"); + storage.load(cashflowList, ui, "src/test/testData/ValidData.txt"); String actual = cashflowList.getList(); cashflowList.list.clear(); getTestData(); @@ -37,20 +39,19 @@ public void loadValidData() throws FinancialPlannerException { @Test public void loadInvalidData_userInputNo() { Storage storage = Storage.INSTANCE; - CashflowList test = CashflowList.INSTANCE; - test.list.clear(); + cashflowList.list.clear(); ByteArrayInputStream in = new ByteArrayInputStream("n".getBytes()); - Ui.INSTANCE.setScanner(new Scanner(in)); + ui.setScanner(new Scanner(in)); assertThrows(FinancialPlannerException.class, - () -> storage.load(test, Ui.INSTANCE, "src/test/testData/InvalidData.txt")); + () -> storage.load(cashflowList, ui, "src/test/testData/InvalidData.txt")); } @Test public void saveValidData() throws FinancialPlannerException, IOException { - CashflowList.INSTANCE.list.clear(); + cashflowList.list.clear(); getTestData(); Storage storage = Storage.INSTANCE; - storage.save(CashflowList.INSTANCE, String.valueOf(testFolder.resolve("temp.txt"))); + storage.save(cashflowList, String.valueOf(testFolder.resolve("temp.txt"))); assertEquals(Files.readAllLines(Path.of("src/test/testData/ValidData.txt")), Files.readAllLines(testFolder.resolve("temp.txt"))); } @@ -59,12 +60,11 @@ public void saveValidData() throws FinancialPlannerException, IOException { public void saveNonExistentFile() { getTestData(); Storage storage = Storage.INSTANCE; - assertThrows(FinancialPlannerException.class, () -> storage.save(CashflowList.INSTANCE, "")); + assertThrows(FinancialPlannerException.class, () -> storage.save(cashflowList, "")); } private void getTestData() { - CashflowList cashflowList = CashflowList.INSTANCE; - cashflowList.load(new Income(123.12, "allowance", 0)); - cashflowList.load(new Expense(100, "daily necessities", 30)); + cashflowList.load(new Income(123.12, IncomeType.ALLOWANCE, 0)); + cashflowList.load(new Expense(100, ExpenseType.SHOPPING, 30)); } } From 25cd60a45336566458b9a16ab9ad66c084aa92ae Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 22 Oct 2023 20:08:08 +0800 Subject: [PATCH 155/518] Change access to CashflowList and Ui classes to getInstance() --- .../financialplanner/commands/AddReminderCommand.java | 2 +- .../seedu/financialplanner/commands/AddStockCommand.java | 2 +- .../seedu/financialplanner/commands/FindCommand.java | 4 ++-- .../seedu/financialplanner/commands/InvalidCommand.java | 2 +- .../seedu/financialplanner/commands/ListCommand.java | 9 +++++---- .../seedu/financialplanner/commands/OverviewCommand.java | 4 ++-- .../seedu/financialplanner/commands/SetGoalCommand.java | 2 +- .../java/seedu/financialplanner/commands/VisCommand.java | 2 +- 8 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java b/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java index 0ab96368f4..11d78166c4 100644 --- a/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java @@ -27,6 +27,6 @@ public AddReminderCommand(RawCommand rawCommand) throws IllegalArgumentException @Override public void execute() { ReminderList.INSTANCE.list.add(new Reminder(type, date)); - Ui.INSTANCE.showMessage("Reminder added!"); + Ui.getInstance().showMessage("Reminder added!"); } } diff --git a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java index 4a57233fe7..da6993133b 100644 --- a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java @@ -30,7 +30,7 @@ public AddStockCommand(RawCommand rawCommand) throws IllegalArgumentException { @Override public void execute() { - Ui ui = Ui.INSTANCE; + Ui ui = Ui.getInstance(); WatchList watchList = WatchList.INSTANCE; String stockName; diff --git a/src/main/java/seedu/financialplanner/commands/FindCommand.java b/src/main/java/seedu/financialplanner/commands/FindCommand.java index 565a61dd37..57df2f8396 100644 --- a/src/main/java/seedu/financialplanner/commands/FindCommand.java +++ b/src/main/java/seedu/financialplanner/commands/FindCommand.java @@ -19,8 +19,8 @@ public FindCommand(RawCommand rawCommand) { @Override public void execute() { - CashflowList cashflowList = CashflowList.INSTANCE; - Ui ui = Ui.INSTANCE; + CashflowList cashflowList = CashflowList.getInstance(); + Ui ui = Ui.getInstance(); WatchList watchList = WatchList.INSTANCE; ArrayList foundedFinancialList = new ArrayList<>(); ArrayList foundedWatchList = new ArrayList<>(); diff --git a/src/main/java/seedu/financialplanner/commands/InvalidCommand.java b/src/main/java/seedu/financialplanner/commands/InvalidCommand.java index 07902d8da4..a9c4fb54ce 100644 --- a/src/main/java/seedu/financialplanner/commands/InvalidCommand.java +++ b/src/main/java/seedu/financialplanner/commands/InvalidCommand.java @@ -8,6 +8,6 @@ public InvalidCommand() { @Override public void execute() { - Ui.INSTANCE.showMessage("Unknown command. Please try again."); + Ui.getInstance().showMessage("Unknown command. Please try again."); } } diff --git a/src/main/java/seedu/financialplanner/commands/ListCommand.java b/src/main/java/seedu/financialplanner/commands/ListCommand.java index ab4699ef78..b9e6f22bd8 100644 --- a/src/main/java/seedu/financialplanner/commands/ListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/ListCommand.java @@ -45,8 +45,9 @@ private boolean shouldPrintCashFlow(Cashflow cashflow) { @Override public void execute() throws Exception { + Ui ui = Ui.getInstance(); - List cashflowList = CashflowList.INSTANCE.list; + List cashflowList = CashflowList.getInstance().list; List cashflowToBePrinted = new ArrayList<>(); for (Cashflow flow : cashflowList) { if (!shouldPrintCashFlow(flow)) { @@ -56,13 +57,13 @@ public void execute() throws Exception { } if (cashflowToBePrinted.isEmpty()) { - Ui.INSTANCE.showMessage("No matching cash flow"); + ui.showMessage("No matching cash flow"); return; } - Ui.INSTANCE.showMessage(String.format("You have %d matching cash flow:", cashflowToBePrinted.size())); + ui.showMessage(String.format("You have %d matching cash flow:", cashflowToBePrinted.size())); for (int i = 0; i < cashflowToBePrinted.size(); i += 1) { - Ui.INSTANCE.showMessage((i+ 1) + ": " + cashflowToBePrinted.get(i).toString()); + ui.showMessage((i+ 1) + ": " + cashflowToBePrinted.get(i).toString()); } } } diff --git a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java index fdb1c1df13..12cdb52f09 100644 --- a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java +++ b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java @@ -20,8 +20,8 @@ public OverviewCommand(RawCommand rawCommand) { @Override public void execute() throws Exception { - CashflowList list = CashflowList.INSTANCE; - Ui.INSTANCE.showMessage("Here is an overview of your financials:\n" + + CashflowList list = CashflowList.getInstance(); + Ui.getInstance().showMessage("Here is an overview of your financials:\n" + "Total balance: " + formatDoubleToString(Cashflow.getBalance()) + "\n" + "Highest income: " + getHighestIncome(list) + "\n" + "Highest expense: " + getHighestExpense(list) + "\n" + diff --git a/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java b/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java index 9ab7a5b8d1..2781175f20 100644 --- a/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java +++ b/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java @@ -31,6 +31,6 @@ public SetGoalCommand(RawCommand rawCommand) throws IllegalArgumentException { @Override public void execute() { GoalList.INSTANCE.list.add(new Goal(goal, amount)); - Ui.INSTANCE.showMessage("Set Goal Successfully!"); + Ui.getInstance().showMessage("Set Goal Successfully!"); } } diff --git a/src/main/java/seedu/financialplanner/commands/VisCommand.java b/src/main/java/seedu/financialplanner/commands/VisCommand.java index 4227019420..0e2f207d1f 100644 --- a/src/main/java/seedu/financialplanner/commands/VisCommand.java +++ b/src/main/java/seedu/financialplanner/commands/VisCommand.java @@ -37,6 +37,6 @@ public VisCommand(RawCommand rawCommand) throws IllegalArgumentException { public void execute() throws FinancialPlannerException { assert !chart.isEmpty(); assert !type.isEmpty(); - Visualizer.displayChart(chart, Categorizer.sortType(CashflowList.INSTANCE, type)); + Visualizer.displayChart(chart, Categorizer.sortType(CashflowList.getInstance(), type)); } } From e92ba9b9c5e429c604f141abe33fd05c6d91d23a Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 22 Oct 2023 20:21:57 +0800 Subject: [PATCH 156/518] Change Income and Expense type from String to enum --- .../commands/AddCashflowCommand.java | 51 ++++++++++++++----- .../commands/DeleteCashflowCommand.java | 13 +++-- .../seedu/financialplanner/list/Cashflow.java | 28 ++++++---- .../financialplanner/list/CashflowList.java | 16 +++--- .../seedu/financialplanner/list/Expense.java | 25 +++++++-- .../seedu/financialplanner/list/Income.java | 25 +++++++-- .../financialplanner/storage/LoadData.java | 19 +++++-- .../visualisations/Categorizer.java | 4 +- 8 files changed, 131 insertions(+), 50 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index 9d5ef81a43..ca73f67631 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -1,6 +1,8 @@ package seedu.financialplanner.commands; import seedu.financialplanner.enumerations.CashflowCategory; +import seedu.financialplanner.enumerations.ExpenseType; +import seedu.financialplanner.enumerations.IncomeType; import seedu.financialplanner.list.Budget; import seedu.financialplanner.list.Cashflow; import seedu.financialplanner.list.CashflowList; @@ -12,19 +14,20 @@ public class AddCashflowCommand extends AbstractCommand { - + protected static Ui ui = Ui.getInstance(); private static Logger logger = Logger.getLogger("Financial Planner Logger"); protected double amount; protected CashflowCategory category; - protected String type; + protected ExpenseType expenseType; + protected IncomeType incomeType; protected int recur = 0; protected CashflowList cashflowList = CashflowList.getInstance(); public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException { - String typeString = String.join(" ", rawCommand.args); + String categoryString = String.join(" ", rawCommand.args); try { logger.log(Level.INFO, "Parsing CashflowCategory"); - category = CashflowCategory.valueOf(typeString.toUpperCase()); + category = CashflowCategory.valueOf(categoryString.toUpperCase()); } catch (IllegalArgumentException e) { logger.log(Level.WARNING, "Invalid arguments for CashflowCategory"); throw new IllegalArgumentException("Entry must be either income or expense"); @@ -51,10 +54,25 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException logger.log(Level.WARNING, "Missing arguments for type"); throw new IllegalArgumentException("Entry must have a type"); } - type = rawCommand.extraArgs.get("t"); - if (type.isBlank()) { - logger.log(Level.WARNING, "Invalid arguments for type"); - throw new IllegalArgumentException("Type cannot be left empty"); + String stringType = rawCommand.extraArgs.get("t"); + if (category.equals(CashflowCategory.EXPENSE)) { + try { + logger.log(Level.INFO, "Parsing ExpenseType"); + expenseType = ExpenseType.valueOf(stringType.toUpperCase()); + } catch (IllegalArgumentException e) { + logger.log(Level.WARNING, "Invalid arguments for ExpenseType"); + throw new IllegalArgumentException("Entry must be one of the following: " + + "dining, entertainment, shopping, travel, insurance, others"); + } + } else if (category.equals(CashflowCategory.INCOME)) { + try { + logger.log(Level.INFO, "Parsing IncomeType"); + incomeType = IncomeType.valueOf(stringType.toUpperCase()); + } catch (IllegalArgumentException e) { + logger.log(Level.WARNING, "Invalid arguments for IncomeType"); + throw new IllegalArgumentException("Entry must be one of the following: " + + "salary, investments, allowance, others"); + } } rawCommand.extraArgs.remove("t"); @@ -85,21 +103,28 @@ public void execute() { assert category.equals(CashflowCategory.INCOME) || category.equals(CashflowCategory.EXPENSE); assert recur >= 0; assert amount >= 0; - assert type != null; + if (category.equals(CashflowCategory.EXPENSE)) { + assert expenseType.equals(ExpenseType.DINING) || expenseType.equals(ExpenseType.ENTERTAINMENT) + || expenseType.equals(ExpenseType.SHOPPING) || expenseType.equals(ExpenseType.TRAVEL) + || expenseType.equals(ExpenseType.INSURANCE) || expenseType.equals(ExpenseType.OTHERS); + } else if (category.equals(CashflowCategory.INCOME)) { + assert incomeType.equals(IncomeType.SALARY) || incomeType.equals(IncomeType.INVESTMENTS) + || incomeType.equals(IncomeType.ALLOWANCE) || incomeType.equals(IncomeType.OTHERS); + } switch (category) { case INCOME: - cashflowList.addIncome(amount, type, recur); + cashflowList.addIncome(amount, incomeType, recur); break; case EXPENSE: - cashflowList.addExpense(amount, type, recur); + cashflowList.addExpense(amount, expenseType, recur); if (Budget.hasBudget()) { deductFromBudget(cashflowList.list.get(cashflowList.list.size() - 1)); } break; default: logger.log(Level.SEVERE, "Unreachable default case reached"); - Ui.INSTANCE.showMessage("Unidentified entry."); + ui.showMessage("Unidentified entry."); break; } } @@ -107,6 +132,6 @@ public void execute() { private static void deductFromBudget(Cashflow entry) { double expenseAmount = entry.getAmount(); Budget.deduct(expenseAmount); - Ui.INSTANCE.printBudgetAfterDeduction(); + ui.printBudgetAfterDeduction(); } } diff --git a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java index 21ae2a6884..a1dc3b993c 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java @@ -22,6 +22,7 @@ public DeleteCashflowCommand(RawCommand rawCommand) throws IllegalArgumentExcept stringIndex = rawCommand.args.get(0); } else if (rawCommand.args.size() == 2) { stringCategory = rawCommand.args.get(0); + handleInvalidCategory(stringCategory); stringIndex = rawCommand.args.get(1); } else { throw new IllegalArgumentException("Incorrect arguments."); @@ -39,9 +40,6 @@ public DeleteCashflowCommand(RawCommand rawCommand) throws IllegalArgumentExcept logger.log(Level.WARNING, "Invalid value for index"); throw new IllegalArgumentException("Index must be within the list"); } - if (stringCategory != null) { - handleInvalidCategory(stringCategory); - } } private void handleInvalidCategory(String stringCategory) { @@ -56,13 +54,14 @@ private void handleInvalidCategory(String stringCategory) { @Override public void execute() { + assert category.equals(CashflowCategory.INCOME) || category.equals(CashflowCategory.EXPENSE); + assert index != 0; + if (category == null) { handleDeleteCashflowWithoutCategory(); return; } - assert category.equals(CashflowCategory.INCOME) || category.equals(CashflowCategory.EXPENSE); - assert index != 0; - + Ui ui = Ui.getInstance(); switch (category) { case INCOME: case EXPENSE: @@ -70,7 +69,7 @@ public void execute() { break; default: logger.log(Level.SEVERE, "Unreachable default case reached"); - Ui.INSTANCE.showMessage("Unidentified entry."); + ui.showMessage("Unidentified entry."); break; } } diff --git a/src/main/java/seedu/financialplanner/list/Cashflow.java b/src/main/java/seedu/financialplanner/list/Cashflow.java index f9ab17af34..54a930b51c 100644 --- a/src/main/java/seedu/financialplanner/list/Cashflow.java +++ b/src/main/java/seedu/financialplanner/list/Cashflow.java @@ -1,19 +1,20 @@ package seedu.financialplanner.list; +import seedu.financialplanner.enumerations.ExpenseType; +import seedu.financialplanner.enumerations.IncomeType; + import java.math.BigDecimal; import java.math.RoundingMode; import java.text.DecimalFormat; -public class Cashflow { +public abstract class Cashflow { protected static double balance = 0; protected double amount; - protected String type; protected int recur; - public Cashflow(double amount, String type, int recur) { + public Cashflow(double amount, int recur) { this.amount = amount; - this.type = type; this.recur = recur; } public void deleteCashflowvalue() { @@ -31,11 +32,19 @@ public static double round(double value, int places) { return bd.doubleValue(); } //@author mhadidg + + //@author Nick Bolton-reused + //Reused from + //https://stackoverflow.com/questions/1892765/how-to-capitalize-the-first-character-of-each-word-in-a-string + public String capitalize(String line) { + return Character.toUpperCase(line.charAt(0)) + line.substring(1); + } + //@author Nick Bolton + public String toString() { DecimalFormat decimalFormat = new DecimalFormat("####0.00"); - String string = " Type: " + type + System.lineSeparator() - + " Amount: " + decimalFormat.format(round(amount, 2)); + String string = " Amount: " + decimalFormat.format(round(amount, 2)); if (recur != 0) { string += System.lineSeparator() + " Recurring every: " + recur + " days"; @@ -59,11 +68,10 @@ public static double getBalance() { } public String formatString() { - return this.amount + " | " + this.type + " | " + this.recur; + return " | " + this.recur; } - public String getType() { - return type; - } + public abstract ExpenseType getExpenseType(); + public abstract IncomeType getIncomeType(); } diff --git a/src/main/java/seedu/financialplanner/list/CashflowList.java b/src/main/java/seedu/financialplanner/list/CashflowList.java index 32eb869f6e..4e61bf1aa0 100644 --- a/src/main/java/seedu/financialplanner/list/CashflowList.java +++ b/src/main/java/seedu/financialplanner/list/CashflowList.java @@ -1,6 +1,8 @@ package seedu.financialplanner.list; import seedu.financialplanner.enumerations.CashflowCategory; +import seedu.financialplanner.enumerations.ExpenseType; +import seedu.financialplanner.enumerations.IncomeType; import seedu.financialplanner.utils.Ui; import java.util.ArrayList; import java.util.logging.Level; @@ -11,7 +13,7 @@ public class CashflowList { private static CashflowList cashflowList = null; public final ArrayList list = new ArrayList<>(); - + protected Ui ui = Ui.getInstance(); private CashflowList() { } @@ -22,25 +24,25 @@ public static CashflowList getInstance() { return cashflowList; } - public void addIncome(double value, String type, int recur) { + public void addIncome(double value, IncomeType type, int recur) { logger.log(Level.INFO, "Adding income"); int existingListSize = list.size(); Income toAdd = new Income(value, type, recur); list.add(toAdd); - Ui.INSTANCE.printAddedCashflow(toAdd); + ui.printAddedCashflow(toAdd); int newListSize = list.size(); assert newListSize == existingListSize + 1; } - public void addExpense(double value, String type, int recur) { + public void addExpense(double value, ExpenseType type, int recur) { logger.log(Level.INFO, "Adding expense"); int existingListSize = list.size(); Expense toAdd = new Expense(value, type, recur); list.add(toAdd); - Ui.INSTANCE.printAddedCashflow(toAdd); + ui.printAddedCashflow(toAdd); int newListSize = list.size(); assert newListSize == existingListSize + 1; @@ -53,7 +55,7 @@ public void delete(int index) { Cashflow toRemove = list.get(listIndex); list.remove(listIndex); toRemove.deleteCashflowvalue(); - Ui.INSTANCE.printDeletedCashflow(toRemove); + ui.printDeletedCashflow(toRemove); int newListSize = list.size(); assert newListSize == existingListSize - 1; @@ -113,7 +115,7 @@ public void deleteCashflow(CashflowCategory category, int index) { Cashflow toRemove = list.get(listIndex); list.remove(listIndex); toRemove.deleteCashflowvalue(); - Ui.INSTANCE.printDeletedCashflow(toRemove); + ui.printDeletedCashflow(toRemove); int newListSize = list.size(); assert newListSize == existingListSize - 1; diff --git a/src/main/java/seedu/financialplanner/list/Expense.java b/src/main/java/seedu/financialplanner/list/Expense.java index 69abc387a9..3818c5fbe6 100644 --- a/src/main/java/seedu/financialplanner/list/Expense.java +++ b/src/main/java/seedu/financialplanner/list/Expense.java @@ -1,11 +1,27 @@ package seedu.financialplanner.list; +import seedu.financialplanner.enumerations.ExpenseType; +import seedu.financialplanner.enumerations.IncomeType; + public class Expense extends Cashflow { - public Expense(double amount, String type, int recur) { - super(amount, type, recur); + protected ExpenseType type; + + public Expense(double amount, ExpenseType type, int recur) { + super(amount, recur); + this.type = type; addExpenseValue(); } + @Override + public ExpenseType getExpenseType() { + return type; + } + + @Override + public IncomeType getIncomeType() { + return null; + } + private void addExpenseValue() { balance -= this.amount; } @@ -17,12 +33,13 @@ public void deleteCashflowvalue() { @Override public String toString() { - return "Expense" + System.lineSeparator() + super.toString(); + return "Expense" + System.lineSeparator() + + " Type: " + capitalize(type.toString().toLowerCase()) + System.lineSeparator() + super.toString(); } @Override public String formatString() { - return "E | " + super.formatString(); + return "E | " + this.amount + " | " + this.type + super.formatString(); } } diff --git a/src/main/java/seedu/financialplanner/list/Income.java b/src/main/java/seedu/financialplanner/list/Income.java index 153d3226d0..07778494c9 100644 --- a/src/main/java/seedu/financialplanner/list/Income.java +++ b/src/main/java/seedu/financialplanner/list/Income.java @@ -1,11 +1,27 @@ package seedu.financialplanner.list; +import seedu.financialplanner.enumerations.ExpenseType; +import seedu.financialplanner.enumerations.IncomeType; + public class Income extends Cashflow{ - public Income(double amount, String type, int recur) { - super(amount, type, recur); + protected IncomeType type; + + public Income(double amount, IncomeType type, int recur) { + super(amount, recur); + this.type = type; addIncomeValue(); } + @Override + public IncomeType getIncomeType() { + return type; + } + + @Override + public ExpenseType getExpenseType() { + return null; + } + private void addIncomeValue() { balance += this.amount; } @@ -17,11 +33,12 @@ public void deleteCashflowvalue() { @Override public String toString() { - return "Income" + System.lineSeparator() + super.toString(); + return "Income" + System.lineSeparator() + + " Type: " + capitalize(type.toString().toLowerCase()) + System.lineSeparator() + super.toString(); } @Override public String formatString() { - return "I | " + super.formatString(); + return "I | " + this.amount + " | " + this.type + super.formatString(); } } diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 9fd2e2c7d6..e17dbe6463 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -1,5 +1,7 @@ package seedu.financialplanner.storage; +import seedu.financialplanner.enumerations.ExpenseType; +import seedu.financialplanner.enumerations.IncomeType; import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.list.Budget; import seedu.financialplanner.list.Cashflow; @@ -71,7 +73,8 @@ private static boolean createNewFile(Ui ui) { return line.equalsIgnoreCase("y"); } - private static Cashflow getEntry(String type, String[] split) throws FinancialPlannerException { + private static Cashflow getEntry(String type, String[] split) + throws FinancialPlannerException, IllegalArgumentException { double value; int recur; Cashflow entry; @@ -80,12 +83,22 @@ private static Cashflow getEntry(String type, String[] split) throws FinancialPl case "I": value = Double.parseDouble(split[1].trim()); recur = Integer.parseInt(split[3].trim()); - entry = new Income(value, split[2].trim(), recur); + try { + IncomeType incomeType = IncomeType.valueOf(split[2].trim().toUpperCase()); + entry = new Income(value, incomeType, recur); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException(); + } break; case "E": value = Double.parseDouble(split[1].trim()); recur = Integer.parseInt(split[3].trim()); - entry = new Expense(value, split[2].trim(), recur); + try { + ExpenseType expenseType = ExpenseType.valueOf(split[2].trim().toUpperCase()); + entry = new Expense(value, expenseType, recur); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException(); + } break; default: throw new FinancialPlannerException("Error loading file"); diff --git a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java index 3fee03d636..83d9661233 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java @@ -30,7 +30,7 @@ public static Map sortExpenses(CashflowList cashflowList) { Map expensesByCat = new HashMap<>(); for (Cashflow e: cashflowList.list) { if (e instanceof Expense) { - String key = e.getType(); + String key = e.getExpenseType().toString().toLowerCase(); double value = expensesByCat.getOrDefault(key, 0.0) + e.getAmount(); assert value >= 0; expensesByCat.put(key, value); @@ -43,7 +43,7 @@ public static Map sortIncome(CashflowList cashflowList) { Map incomeByCat = new HashMap<>(); for (Cashflow e: cashflowList.list) { if (e instanceof Income) { - String key = e.getType(); + String key = e.getIncomeType().toString().toLowerCase(); double value = incomeByCat.getOrDefault(key, 0.0) + e.getAmount(); assert value >= 0; incomeByCat.put(key, value); From c4e41d83fd1e92fe05a4537f7a569dfb27adaa5d Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 22 Oct 2023 20:24:45 +0800 Subject: [PATCH 157/518] Update JUnit tests --- .../commands/AddCashflowCommandTest.java | 16 ++++++++------ .../financialplanner/list/BudgetTest.java | 2 +- .../list/CashflowListTest.java | 22 ++++++++++--------- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/test/java/seedu/financialplanner/commands/AddCashflowCommandTest.java b/src/test/java/seedu/financialplanner/commands/AddCashflowCommandTest.java index d9a4a2b4d4..b8f4fe0f6f 100644 --- a/src/test/java/seedu/financialplanner/commands/AddCashflowCommandTest.java +++ b/src/test/java/seedu/financialplanner/commands/AddCashflowCommandTest.java @@ -1,6 +1,8 @@ package seedu.financialplanner.commands; import org.junit.jupiter.api.Test; +import seedu.financialplanner.enumerations.ExpenseType; +import seedu.financialplanner.enumerations.IncomeType; import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.list.CashflowList; import seedu.financialplanner.utils.Parser; @@ -9,25 +11,25 @@ import static org.junit.jupiter.api.Assertions.assertEquals; class AddCashflowCommandTest { - private Ui ui = Ui.INSTANCE; - private CashflowList cashflowList = CashflowList.INSTANCE; + private Ui ui = Ui.getInstance(); + private CashflowList cashflowList = CashflowList.getInstance(); private WatchList watchList = WatchList.INSTANCE; @Test void testExecute() { - CashflowList.INSTANCE.list.clear(); + cashflowList.list.clear(); AddCashflowCommand testEntry = new AddCashflowCommand(Parser - .parseRawCommand("add income /a 300 /t work /r 30")); + .parseRawCommand("add income /a 300 /t salary /r 30")); testEntry.execute(); assertEquals(300, testEntry.amount); - assertEquals("work", testEntry.type); + assertEquals(IncomeType.SALARY, testEntry.incomeType); assertEquals(30, testEntry.recur); - testEntry = new AddCashflowCommand(Parser.parseRawCommand("add expense /a 15 /t double mcspicy")); + testEntry = new AddCashflowCommand(Parser.parseRawCommand("add expense /a 15 /t dining")); testEntry.execute(); assertEquals(15, testEntry.amount); - assertEquals("double mcspicy", testEntry.type); + assertEquals(ExpenseType.DINING, testEntry.expenseType); assertEquals(0, testEntry.recur); } } diff --git a/src/test/java/seedu/financialplanner/list/BudgetTest.java b/src/test/java/seedu/financialplanner/list/BudgetTest.java index b7b133d9e2..b866976869 100644 --- a/src/test/java/seedu/financialplanner/list/BudgetTest.java +++ b/src/test/java/seedu/financialplanner/list/BudgetTest.java @@ -26,7 +26,7 @@ public void testSetBudget() { @Test @Order(2) public void testNewExpense() { - AddCashflowCommand testExpense = new AddCashflowCommand(Parser.parseRawCommand("add expense /a 50 /t food")); + AddCashflowCommand testExpense = new AddCashflowCommand(Parser.parseRawCommand("add expense /a 50 /t dining")); testExpense.execute(); assertEquals(450, Budget.getCurrentBudget()); } diff --git a/src/test/java/seedu/financialplanner/list/CashflowListTest.java b/src/test/java/seedu/financialplanner/list/CashflowListTest.java index 6648ccbe5b..38bf3efe85 100644 --- a/src/test/java/seedu/financialplanner/list/CashflowListTest.java +++ b/src/test/java/seedu/financialplanner/list/CashflowListTest.java @@ -2,6 +2,8 @@ import org.junit.jupiter.api.Test; import seedu.financialplanner.enumerations.CashflowCategory; +import seedu.financialplanner.enumerations.ExpenseType; +import seedu.financialplanner.enumerations.IncomeType; import java.text.DecimalFormat; @@ -9,51 +11,51 @@ import static org.junit.jupiter.api.Assertions.assertTrue; class CashflowListTest { - private CashflowList testList = CashflowList.INSTANCE; + private CashflowList testList = CashflowList.getInstance(); private DecimalFormat decimalFormat = new DecimalFormat("####0.00"); @Test void testAddIncomeAndExpense() { - CashflowList.INSTANCE.list.clear(); + testList.list.clear(); Cashflow.balance = 0; - testList.addIncome(15, "work", 30); + testList.addIncome(15, IncomeType.SALARY, 30); Cashflow testIncome = testList.list.get(0); double roundedValue = Cashflow.round(testIncome.amount, 2); double roundedBalance = Cashflow.round(Cashflow.balance, 2); assertTrue(testIncome instanceof Income); assertEquals("15.00", decimalFormat.format(roundedValue)); - assertEquals("work", testIncome.type); + assertEquals(IncomeType.SALARY, testIncome.getIncomeType()); assertEquals(30, testIncome.recur); assertEquals("15.00", decimalFormat.format(roundedBalance)); - testList.addIncome(15.999, "rate of returns", 0); + testList.addIncome(15.999, IncomeType.INVESTMENTS, 0); testIncome = testList.list.get(1); roundedValue = Cashflow.round(testIncome.amount, 2); roundedBalance = Cashflow.round(Cashflow.balance, 2); assertTrue(testIncome instanceof Income); assertEquals("16.00", decimalFormat.format(roundedValue)); - assertEquals("rate of returns", testIncome.type); + assertEquals(IncomeType.INVESTMENTS, testIncome.getIncomeType()); assertEquals(0, testIncome.recur); assertEquals("31.00", decimalFormat.format(roundedBalance)); - testList.addExpense(10, "lunch", 0); + testList.addExpense(10, ExpenseType.DINING, 0); Cashflow testExpense = testList.list.get(2); roundedValue = Cashflow.round(testExpense.amount, 2); roundedBalance = Cashflow.round(Cashflow.balance, 2); assertTrue(testExpense instanceof Expense); assertEquals("10.00", decimalFormat.format(roundedValue)); - assertEquals("lunch", testExpense.type); + assertEquals(ExpenseType.DINING, testExpense.getExpenseType()); assertEquals(0, testExpense.recur); assertEquals("21.00", decimalFormat.format(roundedBalance)); - testList.addExpense(19.999, "Apple Music", 30); + testList.addExpense(19.999, ExpenseType.ENTERTAINMENT, 30); testExpense = testList.list.get(3); roundedValue = Cashflow.round(testExpense.amount, 2); roundedBalance = Cashflow.round(Cashflow.balance, 2); assertTrue(testExpense instanceof Expense); assertEquals("20.00", decimalFormat.format(roundedValue)); - assertEquals("Apple Music", testExpense.type); + assertEquals(ExpenseType.ENTERTAINMENT, testExpense.getExpenseType()); assertEquals(30, testExpense.recur); assertEquals("1.00", decimalFormat.format(roundedBalance)); } From 8e33caaf79e0f8465e5f1b78e37684e274ba1be7 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 22 Oct 2023 20:24:58 +0800 Subject: [PATCH 158/518] Update text-ui-test files --- text-ui-test/EXPECTED.TXT | 20 ++++++++++---------- text-ui-test/input.txt | 10 +++++----- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index fd98355472..1231a70416 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -2,45 +2,45 @@ Directory doesn't exist. Creating directory... File not found. Creating new file... Welcome to your Financial Planner. Type something to get started. You have added an Income - Type: work + Type: Salary Amount: 5000.00 Recurring every: 30 days to the Financial Planner. Balance: 5000.00 You have added an Income - Type: allowance + Type: Allowance Amount: 123.12 to the Financial Planner. Balance: 5123.12 You have added an Expense - Type: daily necessities + Type: Entertainment Amount: 100.00 Recurring every: 30 days to the Financial Planner. Balance: 5023.12 You have added an Expense - Type: books + Type: Shopping Amount: 123.21 to the Financial Planner. Balance: 4899.91 You have removed an Income - Type: allowance + Type: Allowance Amount: 123.12 from the Financial Planner. Balance: 4776.79 You have removed an Income - Type: work + Type: Salary Amount: 5000.00 Recurring every: 30 days from the Financial Planner. Balance: -223.21 You have removed an Expense - Type: books + Type: Shopping Amount: 123.21 from the Financial Planner. Balance: -100.00 You have removed an Expense - Type: daily necessities + Type: Entertainment Amount: 100.00 Recurring every: 30 days from the Financial Planner. @@ -52,7 +52,7 @@ You have successfully added: Gamestop Corporation - Class A Use Watchlist to view it! You have added an Income - Type: work + Type: Salary Amount: 5000.00 Recurring every: 30 days to the Financial Planner. @@ -64,7 +64,7 @@ Old current budget: 3000.00 New initial budget: 1000.00 New current budget: 1000.00 You have added an Expense - Type: airpods + Type: Shopping Amount: 200.00 to the Financial Planner. Balance: 4800.00 diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index e8872b6f15..18d4136373 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -1,16 +1,16 @@ -add income /a 5000 /t work /r 30 +add income /a 5000 /t salary /r 30 add income /a 123.12 /t allowance -add expense /a 100 /t daily necessities /r 30 -add expense /a 123.21 /t books +add expense /a 100 /t entertainment /r 30 +add expense /a 123.21 /t shopping delete income 2 delete 1 delete expense 2 delete 1 addstock /s MSFT addstock /s GME -add income /a 5000 /t work /r 30 +add income /a 5000 /t salary /r 30 budget set /b 3000 budget update /b 1000 -add expense /a 200 /t airpods +add expense /a 200 /t shopping sdf exit \ No newline at end of file From e464bd175501acd76ac6cdb02ffa6046f500a709 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 22 Oct 2023 21:12:10 +0800 Subject: [PATCH 159/518] Update JUnit test for Storage --- src/test/testData/ValidData.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/testData/ValidData.txt b/src/test/testData/ValidData.txt index 915220c562..e6cc7f744f 100644 --- a/src/test/testData/ValidData.txt +++ b/src/test/testData/ValidData.txt @@ -1,3 +1,3 @@ -I | 123.12 | allowance | 0 -E | 100.0 | daily necessities | 30 +I | 123.12 | ALLOWANCE | 0 +E | 100.0 | SHOPPING | 30 B | 0.0 | 0.0 \ No newline at end of file From 9f4a09be63259c43bd6fce4a55332a13d793ec68 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 22 Oct 2023 22:56:43 +0800 Subject: [PATCH 160/518] Add functionality to delete stock from watchlist --- .../commands/AddStockCommand.java | 2 +- .../commands/DeleteStockCommand.java | 47 +++++++++++++++++++ .../investments/WatchList.java | 12 +++++ .../seedu/financialplanner/utils/Parser.java | 4 ++ .../java/seedu/financialplanner/utils/Ui.java | 5 ++ 5 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java diff --git a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java index 4a57233fe7..61daac0f6c 100644 --- a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java @@ -18,7 +18,7 @@ public AddStockCommand(RawCommand rawCommand) throws IllegalArgumentException { } logger.log(Level.INFO, "Parsing stockcode from input"); - stockCode = rawCommand.extraArgs.get("s"); + stockCode = rawCommand.extraArgs.get("s").toUpperCase(); rawCommand.extraArgs.remove("s"); if (!rawCommand.extraArgs.isEmpty()) { diff --git a/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java new file mode 100644 index 0000000000..55f2823cd2 --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java @@ -0,0 +1,47 @@ +package seedu.financialplanner.commands; + +import seedu.financialplanner.exceptions.FinancialPlannerException; +import seedu.financialplanner.investments.WatchList; +import seedu.financialplanner.utils.Ui; + +import java.util.ArrayList; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class DeleteStockCommand extends AbstractCommand { + private static final Logger logger = Logger.getLogger("Financial Planner Logger"); + private final String stockCode; + + public DeleteStockCommand(RawCommand rawCommand) throws IllegalArgumentException { + if (!rawCommand.extraArgs.containsKey("s")) { + throw new IllegalArgumentException("Stock code cannot be empty"); + } + + logger.log(Level.INFO, "Parsing stockcode from input"); + stockCode = rawCommand.extraArgs.get("s").toUpperCase(); + + rawCommand.extraArgs.remove("s"); + if (!rawCommand.extraArgs.isEmpty()) { + String unknownExtraArgument = new ArrayList<>(rawCommand.extraArgs.keySet()).get(0); + logger.log(Level.WARNING, "Invalid extra arguments found"); + throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); + } + } + + @Override + public void execute() throws Exception { + Ui ui = Ui.INSTANCE; + WatchList watchList = WatchList.INSTANCE; + String stockName; + + logger.log(Level.INFO, "deleting stock from watchlist"); + try { + stockName = watchList.deleteStock(stockCode); + assert stockName != null; + ui.printDeleteStock(stockName); + } catch (FinancialPlannerException e) { + logger.log(Level.SEVERE, "Error deleting stock from watchlist"); + System.out.println(e.getMessage()); + } + } +} diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index dd00c9f968..0c22e8c8de 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -84,6 +84,18 @@ public String addStock(String stockCode) throws FinancialPlannerException { return newStock.getStockName(); } + public String deleteStock(String stockCode) throws FinancialPlannerException { + if (stocks.isEmpty()) { + throw new FinancialPlannerException("No stock in watchlist!"); + } + Stock toBeRemoved = stocks + .stream() + .filter(stock -> stockCode.equals(stock.getSymbol())) + .findFirst() + .orElseThrow(() -> new FinancialPlannerException("Does not Exist in Watchlist")); + stocks.remove(toBeRemoved); + return toBeRemoved.getStockName(); + } public int size() { return stocks.size(); } diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index f9e37686f4..99aec48f77 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -15,6 +15,7 @@ import seedu.financialplanner.commands.BudgetCommand; import seedu.financialplanner.commands.AddReminderCommand; import seedu.financialplanner.commands.SetGoalCommand; +import seedu.financialplanner.commands.DeleteStockCommand; import seedu.financialplanner.exceptions.FinancialPlannerException; import java.util.ArrayList; @@ -30,6 +31,7 @@ public class Parser { private static final String ADD_CASHFLOW_COMMAND = "add"; private static final String DELETE_CASHFLOW_COMMAND = "delete"; private static final String ADD_STOCK_COMMAND = "addstock"; + private static final String DELETE_STOCK_COMMAND = "deletestock"; private static final String FIND_COMMAND = "find"; private static final String OVERVIEW_COMMAND = "overview"; private static final String BUDGET_COMMAND = "budget"; @@ -55,6 +57,8 @@ public static AbstractCommand parseCommand(RawCommand rawCommand) throws Financi return new DeleteCashflowCommand(rawCommand); case ADD_STOCK_COMMAND: return new AddStockCommand(rawCommand); + case DELETE_STOCK_COMMAND: + return new DeleteStockCommand(rawCommand); case FIND_COMMAND: return new FindCommand(rawCommand); case BUDGET_COMMAND: diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 4b9511884c..32e345d5b1 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -62,7 +62,12 @@ public void printAddStock(String stockName) { System.out.println("You have successfully added:"); System.out.println(stockName); System.out.println("Use Watchlist to view it!"); + } + public void printDeleteStock(String stockName) { + System.out.println("You have successfully deleted: "); + System.out.println(stockName); + System.out.println("Use watchlist command to view updated Watchlist"); } public void printAddedCashflow(Cashflow entry) { System.out.print("You have added an "); From 7e21749289f35e37f0c83c8f6ce72d2958d8c635 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 22 Oct 2023 23:16:28 +0800 Subject: [PATCH 161/518] Isolate JSON object to a single method to reduce chances of bug and give possibility of caching --- .../commands/WatchListCommand.java | 14 ++++++----- .../financialplanner/investments/Stock.java | 9 ++++++++ .../investments/WatchList.java | 23 ++++++++++++++++--- .../java/seedu/financialplanner/utils/Ui.java | 14 +++++++---- 4 files changed, 46 insertions(+), 14 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java index b9ec800acd..29f022c83d 100644 --- a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java @@ -2,6 +2,7 @@ import org.json.simple.JSONArray; import org.json.simple.JSONObject; +import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.utils.Ui; import java.util.ArrayList; @@ -20,14 +21,15 @@ public WatchListCommand(RawCommand rawCommand) throws IllegalArgumentException{ } @Override public void execute() { - JSONArray stocks = WatchList.INSTANCE.fetchFMPStockPrices(); - assert !(stocks == null); Ui.INSTANCE.printWatchListHeader(); + try { + WatchList.INSTANCE.fetchFMPStockPrices(); - logger.log(Level.INFO, "Printing watchlist"); - for (Object o : stocks) { - JSONObject stock = (JSONObject) o; - Ui.INSTANCE.printStockInfo(stock); + logger.log(Level.INFO, "Printing watchlist"); + Ui.INSTANCE.printStocksInfo(WatchList.INSTANCE); + } catch (FinancialPlannerException e) { + System.out.println(e.getMessage()); } + } } diff --git a/src/main/java/seedu/financialplanner/investments/Stock.java b/src/main/java/seedu/financialplanner/investments/Stock.java index d4aa1986b0..a67b73a618 100644 --- a/src/main/java/seedu/financialplanner/investments/Stock.java +++ b/src/main/java/seedu/financialplanner/investments/Stock.java @@ -20,6 +20,7 @@ public class Stock { private String symbol; private String market; private String stockName; + private String price; public Stock(String symbol) throws FinancialPlannerException { this.symbol = symbol; @@ -89,4 +90,12 @@ public void setSymbol(String symbol) { public String toString() { return symbol + ","; } + + public String getPrice() { + return price; + } + + public void setPrice(String price) { + this.price = price; + } } diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index 0c22e8c8de..e511829d8d 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -1,6 +1,8 @@ package seedu.financialplanner.investments; +import org.apache.commons.lang3.StringUtils; import org.json.simple.JSONArray; +import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; import seedu.financialplanner.exceptions.FinancialPlannerException; @@ -41,10 +43,13 @@ private WatchList() { } } - public JSONArray fetchFMPStockPrices() { + public void fetchFMPStockPrices() throws FinancialPlannerException { + if (stocks.isEmpty()) { + throw new FinancialPlannerException("Empty Watchlist. Nothing to display..."); + } + HttpClient client = HttpClient.newHttpClient(); StringBuilder queryStocks = new StringBuilder(); - assert !stocks.isEmpty(); for (Stock stock : stocks) { queryStocks.append(stock.toString()); @@ -72,7 +77,14 @@ public JSONArray fetchFMPStockPrices() { logger.log(Level.SEVERE, "Could not parse to JSON"); throw new RuntimeException(e); } - return (JSONArray) obj; + JSONArray ja = (JSONArray) obj; + int i = 0; + for (Object jo : ja) { + JSONObject stock = (JSONObject) jo; + String price = StringUtils.rightPad(stock.get("price").toString(), 10); + stocks.get(i).setPrice(price); + i += 1; + } } public String addStock(String stockCode) throws FinancialPlannerException { @@ -103,4 +115,9 @@ public int size() { public Stock get(int index) { return stocks.get(index); } + + public ArrayList getStocks() { + return stocks; + } + } diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 32e345d5b1..45dd88ad09 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -2,6 +2,8 @@ import org.apache.commons.lang3.StringUtils; import org.json.simple.JSONObject; +import seedu.financialplanner.investments.Stock; +import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.list.Budget; import seedu.financialplanner.list.Cashflow; @@ -51,11 +53,13 @@ public void printWatchListHeader() { System.out.println(); } - public void printStockInfo(JSONObject stock) { - String symbol = StringUtils.rightPad((String) stock.get("symbol"), 10); - String price = StringUtils.rightPad(stock.get("price").toString(), 10); - String name = StringUtils.rightPad((String) stock.get("name"), 10); - System.out.println(symbol + price + name); + public void printStocksInfo(WatchList watchList) { + for (Stock stock: watchList.getStocks()) { + String symbol = StringUtils.rightPad(stock.getSymbol(), 10); + String price = StringUtils.rightPad(stock.getPrice(), 10); + String name = StringUtils.rightPad((String) stock.getStockName(), 10); + System.out.println(symbol + price + name); + } } public void printAddStock(String stockName) { From b49d747d818583fd3cca5bac61ffcf61ab59c94e Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 22 Oct 2023 23:20:05 +0800 Subject: [PATCH 162/518] Remove unused imports --- .../java/seedu/financialplanner/commands/WatchListCommand.java | 2 -- src/main/java/seedu/financialplanner/utils/Ui.java | 1 - 2 files changed, 3 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java index 29f022c83d..26dd3ab46d 100644 --- a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java @@ -1,7 +1,5 @@ package seedu.financialplanner.commands; -import org.json.simple.JSONArray; -import org.json.simple.JSONObject; import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.utils.Ui; diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 45dd88ad09..f11fdace94 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -1,7 +1,6 @@ package seedu.financialplanner.utils; import org.apache.commons.lang3.StringUtils; -import org.json.simple.JSONObject; import seedu.financialplanner.investments.Stock; import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.list.Budget; From 0f3b189cd17093c5ac7e60d63934b0446d19dda4 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 22 Oct 2023 23:26:54 +0800 Subject: [PATCH 163/518] Update JUnit test due to changes in method implementation --- .../investments/WatchListTest.java | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/test/java/seedu/financialplanner/investments/WatchListTest.java b/src/test/java/seedu/financialplanner/investments/WatchListTest.java index cd7b9b9a66..849127734c 100644 --- a/src/test/java/seedu/financialplanner/investments/WatchListTest.java +++ b/src/test/java/seedu/financialplanner/investments/WatchListTest.java @@ -1,8 +1,9 @@ package seedu.financialplanner.investments; -import org.json.simple.JSONArray; -import org.json.simple.JSONObject; import org.junit.jupiter.api.Test; +import seedu.financialplanner.exceptions.FinancialPlannerException; + +import java.util.ArrayList; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -10,22 +11,26 @@ class WatchListTest { @Test - void fetchFMPStockPrices() { + void fetchFMPStockPrices() throws FinancialPlannerException { WatchList wl = WatchList.INSTANCE; - JSONArray obj = wl.fetchFMPStockPrices(); - JSONObject apple = (JSONObject) obj.get(0); - assertNotNull(apple.get("price")); - JSONObject meta = (JSONObject) obj.get(1); - assertNotNull(meta.get("price")); - JSONObject google = (JSONObject) obj.get(2); - assertNotNull(google.get("price")); + wl.fetchFMPStockPrices(); + ArrayList stocks = wl.getStocks(); + assertNotNull(stocks.get(0).getPrice()); + assertNotNull(stocks.get(1).getPrice()); + assertNotNull(stocks.get(2).getPrice()); } @Test void addStock() throws Exception { WatchList wl = WatchList.INSTANCE; - String market = "NYSE"; String stockCode = "GME"; assertEquals("Gamestop Corporation - Class A", wl.addStock(stockCode)); } + + @Test + void deleteStock() throws FinancialPlannerException { + WatchList wl = WatchList.INSTANCE; + String stockCode = "AAPL"; + assertEquals("Apple Inc", wl.deleteStock(stockCode)); + } } From 968f1a0bb09190f2bce3fdb8acfa5dc8963253e0 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 23 Oct 2023 00:16:59 +0800 Subject: [PATCH 164/518] Add necessities to expensetype enum --- .../seedu/financialplanner/commands/AddCashflowCommand.java | 3 ++- .../java/seedu/financialplanner/enumerations/ExpenseType.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index ca73f67631..a7ddb9881e 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -106,7 +106,8 @@ public void execute() { if (category.equals(CashflowCategory.EXPENSE)) { assert expenseType.equals(ExpenseType.DINING) || expenseType.equals(ExpenseType.ENTERTAINMENT) || expenseType.equals(ExpenseType.SHOPPING) || expenseType.equals(ExpenseType.TRAVEL) - || expenseType.equals(ExpenseType.INSURANCE) || expenseType.equals(ExpenseType.OTHERS); + || expenseType.equals(ExpenseType.INSURANCE) || expenseType.equals(ExpenseType.OTHERS) + || expenseType.equals(ExpenseType.NECESSITIES); } else if (category.equals(CashflowCategory.INCOME)) { assert incomeType.equals(IncomeType.SALARY) || incomeType.equals(IncomeType.INVESTMENTS) || incomeType.equals(IncomeType.ALLOWANCE) || incomeType.equals(IncomeType.OTHERS); diff --git a/src/main/java/seedu/financialplanner/enumerations/ExpenseType.java b/src/main/java/seedu/financialplanner/enumerations/ExpenseType.java index c756905400..ca60b686fc 100644 --- a/src/main/java/seedu/financialplanner/enumerations/ExpenseType.java +++ b/src/main/java/seedu/financialplanner/enumerations/ExpenseType.java @@ -1,5 +1,5 @@ package seedu.financialplanner.enumerations; public enum ExpenseType { - DINING, ENTERTAINMENT, SHOPPING, TRAVEL, INSURANCE, OTHERS + DINING, ENTERTAINMENT, SHOPPING, TRAVEL, INSURANCE, NECESSITIES, OTHERS } From ee85fdd3450c29e6f2fa8ea93bc9d3aa8a7ee4ac Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Mon, 23 Oct 2023 10:11:57 +0800 Subject: [PATCH 165/518] Update error handling for storage --- .../financialplanner/storage/LoadData.java | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index e17dbe6463..1ce7575499 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -42,7 +42,7 @@ public static void load(CashflowList cashflowList, Ui ui, String filePath) throw inputFile.close(); } catch (IOException e) { ui.showMessage("File not found. Creating new file..."); - } catch (NumberFormatException | ArrayIndexOutOfBoundsException | FinancialPlannerException e) { + } catch (ArrayIndexOutOfBoundsException | IllegalArgumentException | FinancialPlannerException e) { handleCorruptedFile(cashflowList, ui); } } @@ -57,9 +57,14 @@ private static void handleCorruptedFile(CashflowList cashflowList, Ui ui) throws } } - private static void loadBudget(String[] split) { + private static void loadBudget(String[] split) throws IllegalArgumentException { double initial = Double.parseDouble(split[1].trim()); double current = Double.parseDouble(split[2].trim()); + if (initial < 0 || current < 0) { + throw new IllegalArgumentException("Negative values for budget"); + } else if (initial > Cashflow.getBalance() || current > Cashflow.getBalance()) { + throw new IllegalArgumentException("Budget exceeds balance"); + } Budget.load(initial, current); } @@ -83,22 +88,16 @@ private static Cashflow getEntry(String type, String[] split) case "I": value = Double.parseDouble(split[1].trim()); recur = Integer.parseInt(split[3].trim()); - try { - IncomeType incomeType = IncomeType.valueOf(split[2].trim().toUpperCase()); - entry = new Income(value, incomeType, recur); - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException(); - } + IncomeType incomeType = IncomeType.valueOf(split[2].trim().toUpperCase()); + checkValidInput(value, recur); + entry = new Income(value, incomeType, recur); break; case "E": value = Double.parseDouble(split[1].trim()); recur = Integer.parseInt(split[3].trim()); - try { - ExpenseType expenseType = ExpenseType.valueOf(split[2].trim().toUpperCase()); - entry = new Expense(value, expenseType, recur); - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException(); - } + ExpenseType expenseType = ExpenseType.valueOf(split[2].trim().toUpperCase()); + checkValidInput(value, recur); + entry = new Expense(value, expenseType, recur); break; default: throw new FinancialPlannerException("Error loading file"); @@ -106,4 +105,10 @@ private static Cashflow getEntry(String type, String[] split) return entry; } + + private static void checkValidInput(double value, int recur) throws FinancialPlannerException { + if (value < 0 || recur < 0) { + throw new FinancialPlannerException("Amount and number of days cannot be negative"); + } + } } From e33e09d9d6bca826602f6a0a646029f3ff5f69f3 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Mon, 23 Oct 2023 10:13:34 +0800 Subject: [PATCH 166/518] Rename AbstractCommand to Command --- src/main/java/seedu/financialplanner/FinancialPlanner.java | 4 ++-- .../seedu/financialplanner/commands/AddCashflowCommand.java | 2 +- .../seedu/financialplanner/commands/AddReminderCommand.java | 2 +- .../seedu/financialplanner/commands/AddStockCommand.java | 2 +- .../java/seedu/financialplanner/commands/BudgetCommand.java | 2 +- .../commands/{AbstractCommand.java => Command.java} | 2 +- .../financialplanner/commands/DeleteCashflowCommand.java | 2 +- .../java/seedu/financialplanner/commands/ExitCommand.java | 2 +- .../java/seedu/financialplanner/commands/FindCommand.java | 2 +- .../seedu/financialplanner/commands/InvalidCommand.java | 2 +- .../java/seedu/financialplanner/commands/ListCommand.java | 2 +- .../seedu/financialplanner/commands/OverviewCommand.java | 2 +- .../seedu/financialplanner/commands/SetGoalCommand.java | 2 +- .../java/seedu/financialplanner/commands/VisCommand.java | 2 +- .../seedu/financialplanner/commands/WatchListCommand.java | 2 +- src/main/java/seedu/financialplanner/utils/Parser.java | 6 +++--- 16 files changed, 19 insertions(+), 19 deletions(-) rename src/main/java/seedu/financialplanner/commands/{AbstractCommand.java => Command.java} (70%) diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index 5bd2dd2f3b..d581b37885 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -1,6 +1,6 @@ package seedu.financialplanner; -import seedu.financialplanner.commands.AbstractCommand; +import seedu.financialplanner.commands.Command; import seedu.financialplanner.commands.ExitCommand; import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.investments.WatchList; @@ -35,7 +35,7 @@ public void run() { FinancialPlannerLogger.initialise(); ui.welcomeMessage(); String input; - AbstractCommand command = null; + Command command = null; while (!(command instanceof ExitCommand)) { input = ui.input(); diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index a7ddb9881e..d9afc930fb 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -13,7 +13,7 @@ import java.util.logging.Logger; -public class AddCashflowCommand extends AbstractCommand { +public class AddCashflowCommand extends Command { protected static Ui ui = Ui.getInstance(); private static Logger logger = Logger.getLogger("Financial Planner Logger"); protected double amount; diff --git a/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java b/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java index 11d78166c4..ea2e163f96 100644 --- a/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java @@ -2,7 +2,7 @@ import seedu.financialplanner.reminder.ReminderList; import seedu.financialplanner.reminder.Reminder; import seedu.financialplanner.utils.Ui; -public class AddReminderCommand extends AbstractCommand{ +public class AddReminderCommand extends Command { private final String type; private final String date; diff --git a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java index da6993133b..2cefe8cb32 100644 --- a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java @@ -8,7 +8,7 @@ import java.util.logging.Level; import java.util.logging.Logger; -public class AddStockCommand extends AbstractCommand { +public class AddStockCommand extends Command { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private final String stockCode; diff --git a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java index 07771ea4a3..f0c977dbff 100644 --- a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java +++ b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java @@ -9,7 +9,7 @@ import java.util.logging.Logger; import java.util.ArrayList; -public class BudgetCommand extends AbstractCommand { +public class BudgetCommand extends Command { private static Logger logger = Logger.getLogger("Financial Planner Logger"); private double budget; private String command; diff --git a/src/main/java/seedu/financialplanner/commands/AbstractCommand.java b/src/main/java/seedu/financialplanner/commands/Command.java similarity index 70% rename from src/main/java/seedu/financialplanner/commands/AbstractCommand.java rename to src/main/java/seedu/financialplanner/commands/Command.java index 83a9a0f624..135ccd4e4d 100644 --- a/src/main/java/seedu/financialplanner/commands/AbstractCommand.java +++ b/src/main/java/seedu/financialplanner/commands/Command.java @@ -1,5 +1,5 @@ package seedu.financialplanner.commands; -public abstract class AbstractCommand { +public abstract class Command { public abstract void execute() throws Exception; } diff --git a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java index a1dc3b993c..1c85336393 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java @@ -7,7 +7,7 @@ import java.util.logging.Level; import java.util.logging.Logger; -public class DeleteCashflowCommand extends AbstractCommand { +public class DeleteCashflowCommand extends Command { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); protected CashflowCategory category = null; diff --git a/src/main/java/seedu/financialplanner/commands/ExitCommand.java b/src/main/java/seedu/financialplanner/commands/ExitCommand.java index 1dbfd24cf5..3c331475a6 100644 --- a/src/main/java/seedu/financialplanner/commands/ExitCommand.java +++ b/src/main/java/seedu/financialplanner/commands/ExitCommand.java @@ -2,7 +2,7 @@ import java.util.ArrayList; -public class ExitCommand extends AbstractCommand { +public class ExitCommand extends Command { public ExitCommand(RawCommand rawCommand) { if (!rawCommand.extraArgs.isEmpty()) { String unknownExtraArgument = new ArrayList<>(rawCommand.extraArgs.keySet()).get(0); diff --git a/src/main/java/seedu/financialplanner/commands/FindCommand.java b/src/main/java/seedu/financialplanner/commands/FindCommand.java index 57df2f8396..ba0397a698 100644 --- a/src/main/java/seedu/financialplanner/commands/FindCommand.java +++ b/src/main/java/seedu/financialplanner/commands/FindCommand.java @@ -6,7 +6,7 @@ import java.util.ArrayList; -public class FindCommand extends AbstractCommand { +public class FindCommand extends Command { private final String description; public FindCommand(RawCommand rawCommand) { diff --git a/src/main/java/seedu/financialplanner/commands/InvalidCommand.java b/src/main/java/seedu/financialplanner/commands/InvalidCommand.java index a9c4fb54ce..97bc73e9fa 100644 --- a/src/main/java/seedu/financialplanner/commands/InvalidCommand.java +++ b/src/main/java/seedu/financialplanner/commands/InvalidCommand.java @@ -2,7 +2,7 @@ import seedu.financialplanner.utils.Ui; -public class InvalidCommand extends AbstractCommand { +public class InvalidCommand extends Command { public InvalidCommand() { } diff --git a/src/main/java/seedu/financialplanner/commands/ListCommand.java b/src/main/java/seedu/financialplanner/commands/ListCommand.java index b9e6f22bd8..d799d05775 100644 --- a/src/main/java/seedu/financialplanner/commands/ListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/ListCommand.java @@ -10,7 +10,7 @@ import java.util.ArrayList; import java.util.List; -public class ListCommand extends AbstractCommand{ +public class ListCommand extends Command { protected CashflowCategory category = null; public ListCommand(RawCommand rawCommand) throws IllegalArgumentException{ String stringCategory = null; diff --git a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java index 12cdb52f09..002527dca0 100644 --- a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java +++ b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java @@ -10,7 +10,7 @@ import java.text.DecimalFormat; import java.util.ArrayList; -public class OverviewCommand extends AbstractCommand { +public class OverviewCommand extends Command { public OverviewCommand(RawCommand rawCommand) { if (!rawCommand.extraArgs.isEmpty()) { String unknownExtraArgument = new ArrayList<>(rawCommand.extraArgs.keySet()).get(0); diff --git a/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java b/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java index 2781175f20..99adeada6c 100644 --- a/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java +++ b/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java @@ -3,7 +3,7 @@ import seedu.financialplanner.goal.GoalList; import seedu.financialplanner.utils.Ui; -public class SetGoalCommand extends AbstractCommand{ +public class SetGoalCommand extends Command { private final String goal; private int amount; public SetGoalCommand(RawCommand rawCommand) throws IllegalArgumentException { diff --git a/src/main/java/seedu/financialplanner/commands/VisCommand.java b/src/main/java/seedu/financialplanner/commands/VisCommand.java index 0e2f207d1f..df3a3e73b4 100644 --- a/src/main/java/seedu/financialplanner/commands/VisCommand.java +++ b/src/main/java/seedu/financialplanner/commands/VisCommand.java @@ -9,7 +9,7 @@ import java.util.logging.Level; import java.util.logging.Logger; -public class VisCommand extends AbstractCommand { +public class VisCommand extends Command { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private String type; private String chart; diff --git a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java index beaaa4da2f..2c92530d98 100644 --- a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java @@ -8,7 +8,7 @@ import java.util.logging.Level; import java.util.logging.Logger; -public class WatchListCommand extends AbstractCommand { +public class WatchListCommand extends Command { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); public WatchListCommand(RawCommand rawCommand) throws IllegalArgumentException{ if (!rawCommand.extraArgs.isEmpty()) { diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index f9e37686f4..5540556b7e 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -1,6 +1,6 @@ package seedu.financialplanner.utils; -import seedu.financialplanner.commands.AbstractCommand; +import seedu.financialplanner.commands.Command; import seedu.financialplanner.commands.AddStockCommand; import seedu.financialplanner.commands.OverviewCommand; import seedu.financialplanner.commands.AddCashflowCommand; @@ -38,12 +38,12 @@ public class Parser { private static final String LIST_COMMAND = "list"; private static final String SET_GOAL_COMMAND = "set"; - public static AbstractCommand parseCommand(String input) throws FinancialPlannerException { + public static Command parseCommand(String input) throws FinancialPlannerException { RawCommand rawCommand = parseRawCommand(input); return parseCommand(rawCommand); } - public static AbstractCommand parseCommand(RawCommand rawCommand) throws FinancialPlannerException { + public static Command parseCommand(RawCommand rawCommand) throws FinancialPlannerException { switch (rawCommand.getCommandName()) { case EXIT_COMMAND: return new ExitCommand(rawCommand); From 21edafcc87654ea480d1c35ab2ec453623792070 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Mon, 23 Oct 2023 10:37:19 +0800 Subject: [PATCH 167/518] Update singleton and error handling for storage, refactor storage --- .../financialplanner/FinancialPlanner.java | 6 ++-- .../financialplanner/storage/LoadData.java | 32 ++++++++++++++----- .../financialplanner/storage/SaveData.java | 4 ++- .../financialplanner/storage/Storage.java | 17 +++++++--- .../financialplanner/storage/StorageTest.java | 14 ++++---- 5 files changed, 48 insertions(+), 25 deletions(-) diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index d581b37885..3b1faa3480 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -12,7 +12,7 @@ public class FinancialPlanner { private static final String FILE_PATH = "data/data.txt"; - private final Storage storage = Storage.INSTANCE; + private final Storage storage = Storage.getInstance(); private final Ui ui = Ui.getInstance(); private final WatchList watchList = WatchList.INSTANCE; private final CashflowList cashflowList = CashflowList.getInstance(); @@ -26,7 +26,7 @@ public static void main(String[] args) { public void run() { try { - storage.load(cashflowList, ui, FILE_PATH); + storage.load(FILE_PATH); } catch (FinancialPlannerException e) { ui.showMessage(e.getMessage()); return; @@ -52,7 +52,7 @@ public void run() { public void save() { try { - storage.save(cashflowList, FILE_PATH); + storage.save(FILE_PATH); } catch (FinancialPlannerException e) { ui.showMessage(e.getMessage()); } diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 1ce7575499..f51d8ad76a 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -15,7 +15,10 @@ import java.util.Scanner; public abstract class LoadData { - public static void load(CashflowList cashflowList, Ui ui, String filePath) throws FinancialPlannerException { + private static final CashflowList cashflowList = CashflowList.getInstance(); + private static final Ui ui = Ui.getInstance(); + + public static void load(String filePath) throws FinancialPlannerException { try { Scanner inputFile = new Scanner(new FileReader(filePath)); String line; @@ -43,17 +46,18 @@ public static void load(CashflowList cashflowList, Ui ui, String filePath) throw } catch (IOException e) { ui.showMessage("File not found. Creating new file..."); } catch (ArrayIndexOutOfBoundsException | IllegalArgumentException | FinancialPlannerException e) { - handleCorruptedFile(cashflowList, ui); + String message = e.getMessage(); + handleCorruptedFile(message); } } - private static void handleCorruptedFile(CashflowList cashflowList, Ui ui) throws FinancialPlannerException { + private static void handleCorruptedFile(String message) throws FinancialPlannerException { ui.showMessage("File appears to be corrupted. Do you want to create a new file? (Y/N)"); - if (createNewFile(ui)) { + if (createNewFile()) { cashflowList.list.clear(); } else { throw new FinancialPlannerException("Please fix the corrupted file, " + - "which can be found in data/data.txt."); + "which can be found in data/data.txt.\nError message: " + message); } } @@ -64,11 +68,13 @@ private static void loadBudget(String[] split) throws IllegalArgumentException { throw new IllegalArgumentException("Negative values for budget"); } else if (initial > Cashflow.getBalance() || current > Cashflow.getBalance()) { throw new IllegalArgumentException("Budget exceeds balance"); + } else if (initial < current) { + throw new IllegalArgumentException("Current budget exceeds initial budget"); } Budget.load(initial, current); } - private static boolean createNewFile(Ui ui) { + private static boolean createNewFile() { String line = ui.input(); while (!line.equalsIgnoreCase("y") && !line.equalsIgnoreCase("n")) { ui.showMessage("Unknown input. Please enter Y or N only."); @@ -88,15 +94,25 @@ private static Cashflow getEntry(String type, String[] split) case "I": value = Double.parseDouble(split[1].trim()); recur = Integer.parseInt(split[3].trim()); - IncomeType incomeType = IncomeType.valueOf(split[2].trim().toUpperCase()); checkValidInput(value, recur); + IncomeType incomeType; + try { + incomeType = IncomeType.valueOf(split[2].trim().toUpperCase()); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Invalid income type"); + } entry = new Income(value, incomeType, recur); break; case "E": value = Double.parseDouble(split[1].trim()); recur = Integer.parseInt(split[3].trim()); - ExpenseType expenseType = ExpenseType.valueOf(split[2].trim().toUpperCase()); checkValidInput(value, recur); + ExpenseType expenseType; + try { + expenseType = ExpenseType.valueOf(split[2].trim().toUpperCase()); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Invalid expense type"); + } entry = new Expense(value, expenseType, recur); break; default: diff --git a/src/main/java/seedu/financialplanner/storage/SaveData.java b/src/main/java/seedu/financialplanner/storage/SaveData.java index d87f449bc1..3a2d6fa3d9 100644 --- a/src/main/java/seedu/financialplanner/storage/SaveData.java +++ b/src/main/java/seedu/financialplanner/storage/SaveData.java @@ -9,7 +9,9 @@ import java.io.IOException; public abstract class SaveData { - public static void save(CashflowList cashflowList, String filePath) throws FinancialPlannerException { + private static final CashflowList cashflowList = CashflowList.getInstance(); + + public static void save(String filePath) throws FinancialPlannerException { try { FileWriter fw = new FileWriter(filePath); for (Cashflow entry : cashflowList.list) { diff --git a/src/main/java/seedu/financialplanner/storage/Storage.java b/src/main/java/seedu/financialplanner/storage/Storage.java index ef340a2d3e..49c6f65b8a 100644 --- a/src/main/java/seedu/financialplanner/storage/Storage.java +++ b/src/main/java/seedu/financialplanner/storage/Storage.java @@ -10,7 +10,7 @@ import java.nio.file.Paths; public class Storage { - public static final Storage INSTANCE = new Storage(); + private static Storage storage = null; private final Path path = Paths.get("data"); private Storage() { @@ -24,11 +24,18 @@ private Storage() { } } - public void load(CashflowList list, Ui ui, String filePath) throws FinancialPlannerException { - LoadData.load(list, ui, filePath); + public static Storage getInstance() { + if (storage == null) { + storage = new Storage(); + } + return storage; + } + + public void load(String filePath) throws FinancialPlannerException { + LoadData.load(filePath); } - public void save(CashflowList list, String filePath) throws FinancialPlannerException { - SaveData.save(list, filePath); + public void save(String filePath) throws FinancialPlannerException { + SaveData.save(filePath); } } diff --git a/src/test/java/seedu/financialplanner/storage/StorageTest.java b/src/test/java/seedu/financialplanner/storage/StorageTest.java index f168d0097c..7ffaa4be4b 100644 --- a/src/test/java/seedu/financialplanner/storage/StorageTest.java +++ b/src/test/java/seedu/financialplanner/storage/StorageTest.java @@ -24,11 +24,12 @@ public class StorageTest { public static Path testFolder; protected CashflowList cashflowList = CashflowList.getInstance(); protected Ui ui = Ui.getInstance(); + protected Storage storage = Storage.getInstance(); + @Test public void loadValidData() throws FinancialPlannerException { - Storage storage = Storage.INSTANCE; cashflowList.list.clear(); - storage.load(cashflowList, ui, "src/test/testData/ValidData.txt"); + storage.load("src/test/testData/ValidData.txt"); String actual = cashflowList.getList(); cashflowList.list.clear(); getTestData(); @@ -38,20 +39,18 @@ public void loadValidData() throws FinancialPlannerException { @Test public void loadInvalidData_userInputNo() { - Storage storage = Storage.INSTANCE; cashflowList.list.clear(); ByteArrayInputStream in = new ByteArrayInputStream("n".getBytes()); ui.setScanner(new Scanner(in)); assertThrows(FinancialPlannerException.class, - () -> storage.load(cashflowList, ui, "src/test/testData/InvalidData.txt")); + () -> storage.load("src/test/testData/InvalidData.txt")); } @Test public void saveValidData() throws FinancialPlannerException, IOException { cashflowList.list.clear(); getTestData(); - Storage storage = Storage.INSTANCE; - storage.save(cashflowList, String.valueOf(testFolder.resolve("temp.txt"))); + storage.save(String.valueOf(testFolder.resolve("temp.txt"))); assertEquals(Files.readAllLines(Path.of("src/test/testData/ValidData.txt")), Files.readAllLines(testFolder.resolve("temp.txt"))); } @@ -59,8 +58,7 @@ public void saveValidData() throws FinancialPlannerException, IOException { @Test public void saveNonExistentFile() { getTestData(); - Storage storage = Storage.INSTANCE; - assertThrows(FinancialPlannerException.class, () -> storage.save(cashflowList, "")); + assertThrows(FinancialPlannerException.class, () -> storage.save("")); } private void getTestData() { From b4bf06354ec1e651df2c1b0835e8c82c2c4d796b Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Mon, 23 Oct 2023 11:52:07 +0800 Subject: [PATCH 168/518] Add ability to delete, reset and view budget Fixes #74 --- .../financialplanner/FinancialPlanner.java | 5 +-- .../commands/BudgetCommand.java | 41 ++++++++++++++++--- .../seedu/financialplanner/list/Budget.java | 13 ++++++ .../java/seedu/financialplanner/utils/Ui.java | 22 +++++++--- 4 files changed, 67 insertions(+), 14 deletions(-) diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index 3b1faa3480..e59ba233b4 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -10,17 +10,15 @@ import seedu.financialplanner.utils.Ui; public class FinancialPlanner { - private static final String FILE_PATH = "data/data.txt"; private final Storage storage = Storage.getInstance(); private final Ui ui = Ui.getInstance(); - private final WatchList watchList = WatchList.INSTANCE; - private final CashflowList cashflowList = CashflowList.getInstance(); private FinancialPlanner() { } public static void main(String[] args) { + FinancialPlannerLogger.initialise(); new FinancialPlanner().run(); } @@ -32,7 +30,6 @@ public void run() { return; } - FinancialPlannerLogger.initialise(); ui.welcomeMessage(); String input; Command command = null; diff --git a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java index f0c977dbff..f6a3ef33db 100644 --- a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java +++ b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java @@ -16,17 +16,19 @@ public class BudgetCommand extends Command { public BudgetCommand(RawCommand rawCommand) throws FinancialPlannerException { command = String.join(" ", rawCommand.args); + if (command.equals("delete") || command.equals("reset") || command.equals("view")) { + return; + } if (!command.equals("set") && !command.equals("update")) { logger.log(Level.WARNING, "Invalid arguments for budget command"); - throw new FinancialPlannerException("Please indicate whether budget is to be set or update."); + throw new FinancialPlannerException("Budget command must be one of the following: set, update, " + + "delete, reset, view."); } if (command.equals("set") && Budget.hasBudget()) { logger.log(Level.WARNING, "Invalid command: Trying to set existing budget"); throw new FinancialPlannerException("There is an existing budget, did you mean update?"); - } - - if (command.equals("update") && !Budget.hasBudget()) { + } else if (command.equals("update") && !Budget.hasBudget()) { logger.log(Level.WARNING, "Invalid command: Trying to update non-existent budget"); throw new FinancialPlannerException("There is no budget set yet, did you mean set?"); } @@ -66,7 +68,8 @@ public BudgetCommand(RawCommand rawCommand) throws FinancialPlannerException { @Override public void execute() { - assert command.equals("set") || command.equals("update") : "Command should be set or update only"; + assert command.equals("set") || command.equals("update") || command.equals("delete") || + command.equals("reset") || command.equals("view"); Ui ui = Ui.getInstance(); switch (command) { @@ -82,6 +85,34 @@ public void execute() { Budget.updateBudget(budget); ui.printBudgetAfterUpdate(); break; + case "delete": + if (Budget.hasBudget()) { + Budget.deleteBudget(); + ui.printDeleteBudget(); + } else { + ui.showMessage("Budget has not been set yet."); + } + break; + case "reset": + if (Budget.getInitialBudget() != Budget.getCurrentBudget()) { + if (Budget.getInitialBudget() > Cashflow.getBalance()) { + Budget.setInitialBudget(Cashflow.getBalance()); + ui.showMessage("Since initial budget exceeds current balance, " + + "budget will be reset to current balance."); + } + Budget.resetBudget(); + ui.printResetBudget(); + } else { + ui.showMessage("Budget has not been spent yet."); + } + break; + case "view": + if (Budget.hasBudget()) { + ui.printBudget(); + } else { + ui.showMessage("There is no existing budget."); + } + break; default: logger.log(Level.SEVERE, "Unreachable default case reached"); ui.showMessage("Unknown command."); diff --git a/src/main/java/seedu/financialplanner/list/Budget.java b/src/main/java/seedu/financialplanner/list/Budget.java index 02504fb9eb..54a059cf84 100644 --- a/src/main/java/seedu/financialplanner/list/Budget.java +++ b/src/main/java/seedu/financialplanner/list/Budget.java @@ -62,4 +62,17 @@ public static boolean hasBudget() { public static String formatString() { return "B | " + initialBudget + " | " + currentBudget; } + + public static void deleteBudget() { + initialBudget = 0; + currentBudget = 0; + } + + public static void resetBudget() { + currentBudget = initialBudget; + } + + public static void setInitialBudget(double amount) { + initialBudget = amount; + } } diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 8cc0242e26..9f2287bb5a 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -99,13 +99,25 @@ public void printBudgetAfterUpdate() { } public void printBudgetAfterDeduction() { - String message = ""; + StringBuilder message = new StringBuilder(); if (Budget.getCurrentBudget() <= 0) { - message += "You have exceeded your current budget by: "; + message.append("You have exceeded your current budget by: "); } else if (Budget.getCurrentBudget() > 0) { - message += "Your remaining budget for the month is: "; + message.append("Your remaining budget for the month is: "); } - message += Budget.getCurrentBudgetString(); - showMessage(message); + message.append(Budget.getCurrentBudgetString()); + showMessage(message.toString()); + } + + public void printBudget() { + showMessage("You have a remaining budget of " + Budget.getCurrentBudgetString() + "."); + } + + public void printDeleteBudget() { + showMessage("Budget has been deleted."); + } + + public void printResetBudget() { + showMessage("Budget has been reset to " + Budget.getInitialBudgetString() + "."); } } From fc2a9f8444ad097c48f388f6a0510c94481b575e Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 23 Oct 2023 14:59:11 +0800 Subject: [PATCH 169/518] Change watchlist singleton access method --- .../java/seedu/financialplanner/FinancialPlanner.java | 2 +- .../seedu/financialplanner/commands/AddStockCommand.java | 2 +- .../financialplanner/commands/DeleteStockCommand.java | 2 +- .../seedu/financialplanner/commands/FindCommand.java | 2 +- .../financialplanner/commands/WatchListCommand.java | 5 +++-- .../seedu/financialplanner/investments/WatchList.java | 9 ++++++++- .../commands/AddCashflowCommandTest.java | 2 +- .../financialplanner/investments/WatchListTest.java | 6 +++--- 8 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index 5bd2dd2f3b..1afc41fede 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -14,7 +14,7 @@ public class FinancialPlanner { private static final String FILE_PATH = "data/data.txt"; private final Storage storage = Storage.INSTANCE; private final Ui ui = Ui.getInstance(); - private final WatchList watchList = WatchList.INSTANCE; + private final WatchList watchList = WatchList.getInstance(); private final CashflowList cashflowList = CashflowList.getInstance(); private FinancialPlanner() { diff --git a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java index 9b63233b88..1d23d1fdd6 100644 --- a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java @@ -31,7 +31,7 @@ public AddStockCommand(RawCommand rawCommand) throws IllegalArgumentException { @Override public void execute() { Ui ui = Ui.getInstance(); - WatchList watchList = WatchList.INSTANCE; + WatchList watchList = WatchList.getInstance(); String stockName; logger.log(Level.INFO, "adding stock to watchlist"); diff --git a/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java index 01e3c3394b..5d6ddaf2a5 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java @@ -31,7 +31,7 @@ public DeleteStockCommand(RawCommand rawCommand) throws IllegalArgumentException @Override public void execute() throws Exception { Ui ui = Ui.getInstance(); - WatchList watchList = WatchList.INSTANCE; + WatchList watchList = WatchList.getInstance(); String stockName; logger.log(Level.INFO, "deleting stock from watchlist"); diff --git a/src/main/java/seedu/financialplanner/commands/FindCommand.java b/src/main/java/seedu/financialplanner/commands/FindCommand.java index 57df2f8396..ff1a553f9c 100644 --- a/src/main/java/seedu/financialplanner/commands/FindCommand.java +++ b/src/main/java/seedu/financialplanner/commands/FindCommand.java @@ -21,7 +21,7 @@ public FindCommand(RawCommand rawCommand) { public void execute() { CashflowList cashflowList = CashflowList.getInstance(); Ui ui = Ui.getInstance(); - WatchList watchList = WatchList.INSTANCE; + WatchList watchList = WatchList.getInstance(); ArrayList foundedFinancialList = new ArrayList<>(); ArrayList foundedWatchList = new ArrayList<>(); for (int i = 0; i < cashflowList.list.size(); i++) { diff --git a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java index 00f1e988e7..4034734887 100644 --- a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java @@ -20,13 +20,14 @@ public WatchListCommand(RawCommand rawCommand) throws IllegalArgumentException{ @Override public void execute() { Ui ui = Ui.getInstance(); + WatchList watchList = WatchList.getInstance(); ui.printWatchListHeader(); try { - WatchList.INSTANCE.fetchFMPStockPrices(); + watchList.fetchFMPStockPrices(); logger.log(Level.INFO, "Printing watchlist"); - ui.printStocksInfo(WatchList.INSTANCE); + ui.printStocksInfo(watchList); } catch (FinancialPlannerException e) { System.out.println(e.getMessage()); } diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index e511829d8d..8491d0b2c2 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -19,7 +19,14 @@ public class WatchList { - public static final WatchList INSTANCE = new WatchList(); + private static WatchList watchlist = null; + + public static WatchList getInstance() { + if (watchlist == null) { + watchlist = new WatchList(); + } + return watchlist; + } private static Logger logger = Logger.getLogger("Financial Planner Logger"); private final ArrayList stocks; private final String API_ENDPOINT = "https://financialmodelingprep.com/api/v3/quote/"; diff --git a/src/test/java/seedu/financialplanner/commands/AddCashflowCommandTest.java b/src/test/java/seedu/financialplanner/commands/AddCashflowCommandTest.java index b8f4fe0f6f..7946111119 100644 --- a/src/test/java/seedu/financialplanner/commands/AddCashflowCommandTest.java +++ b/src/test/java/seedu/financialplanner/commands/AddCashflowCommandTest.java @@ -13,7 +13,7 @@ class AddCashflowCommandTest { private Ui ui = Ui.getInstance(); private CashflowList cashflowList = CashflowList.getInstance(); - private WatchList watchList = WatchList.INSTANCE; + private WatchList watchList = WatchList.getInstance(); @Test void testExecute() { diff --git a/src/test/java/seedu/financialplanner/investments/WatchListTest.java b/src/test/java/seedu/financialplanner/investments/WatchListTest.java index 849127734c..81a6e72ac2 100644 --- a/src/test/java/seedu/financialplanner/investments/WatchListTest.java +++ b/src/test/java/seedu/financialplanner/investments/WatchListTest.java @@ -12,7 +12,7 @@ class WatchListTest { @Test void fetchFMPStockPrices() throws FinancialPlannerException { - WatchList wl = WatchList.INSTANCE; + WatchList wl = WatchList.getInstance(); wl.fetchFMPStockPrices(); ArrayList stocks = wl.getStocks(); assertNotNull(stocks.get(0).getPrice()); @@ -22,14 +22,14 @@ void fetchFMPStockPrices() throws FinancialPlannerException { @Test void addStock() throws Exception { - WatchList wl = WatchList.INSTANCE; + WatchList wl = WatchList.getInstance(); String stockCode = "GME"; assertEquals("Gamestop Corporation - Class A", wl.addStock(stockCode)); } @Test void deleteStock() throws FinancialPlannerException { - WatchList wl = WatchList.INSTANCE; + WatchList wl = WatchList.getInstance(); String stockCode = "AAPL"; assertEquals("Apple Inc", wl.deleteStock(stockCode)); } From d73a5d597b5a1bff82e031898ab0cf938e5ae620 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 23 Oct 2023 15:02:14 +0800 Subject: [PATCH 170/518] Improve code quality in accordance to reviewers --- .../java/seedu/financialplanner/commands/AddStockCommand.java | 2 +- .../seedu/financialplanner/commands/DeleteStockCommand.java | 4 ++-- .../seedu/financialplanner/commands/WatchListCommand.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java index 1d23d1fdd6..77ca48596d 100644 --- a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java @@ -40,7 +40,7 @@ public void execute() { assert stockName != null; ui.printAddStock(stockName); } catch (FinancialPlannerException e) { - logger.log(Level.SEVERE, "Error adding stock to watchlist"); + logger.log(Level.WARNING, "Error adding stock to watchlist"); System.out.println(e.getMessage()); } } diff --git a/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java index 5d6ddaf2a5..ac97bce82d 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java @@ -40,8 +40,8 @@ public void execute() throws Exception { assert stockName != null; ui.printDeleteStock(stockName); } catch (FinancialPlannerException e) { - logger.log(Level.SEVERE, "Error deleting stock from watchlist"); - System.out.println(e.getMessage()); + logger.log(Level.WARNING, "Error deleting stock from watchlist"); + ui.showMessage(e.getMessage()); } } } diff --git a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java index 4034734887..6111bfd174 100644 --- a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java @@ -29,7 +29,7 @@ public void execute() { logger.log(Level.INFO, "Printing watchlist"); ui.printStocksInfo(watchList); } catch (FinancialPlannerException e) { - System.out.println(e.getMessage()); + ui.showMessage(e.getMessage()); } } From 2ad5082d556bde5cd1dacfa4c3f9abcdf11f49a5 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Mon, 23 Oct 2023 15:09:52 +0800 Subject: [PATCH 171/518] Refactor Budget, fix bug and clean up code --- .../commands/BudgetCommand.java | 139 +++++++++++------- .../commands/DeleteCashflowCommand.java | 12 +- .../commands/FindCommand.java | 4 +- .../commands/ListCommand.java | 2 +- .../commands/SetGoalCommand.java | 1 + .../financialplanner/commands/VisCommand.java | 2 +- .../commands/WatchListCommand.java | 2 + .../seedu/financialplanner/goal/Goal.java | 6 +- .../seedu/financialplanner/goal/GoalList.java | 1 + .../financialplanner/investments/Stock.java | 1 + .../investments/WatchList.java | 1 - .../seedu/financialplanner/list/Budget.java | 4 + .../seedu/financialplanner/list/Cashflow.java | 5 + .../financialplanner/list/CashflowList.java | 13 +- .../seedu/financialplanner/list/Income.java | 1 + .../financialplanner/reminder/Reminder.java | 4 +- .../reminder/ReminderList.java | 1 + .../financialplanner/storage/LoadData.java | 7 +- .../java/seedu/financialplanner/utils/Ui.java | 4 +- .../visualisations/Categorizer.java | 2 + .../visualisations/Visualizer.java | 5 +- 21 files changed, 139 insertions(+), 78 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java index f6a3ef33db..9006ab43ca 100644 --- a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java +++ b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java @@ -11,32 +11,16 @@ public class BudgetCommand extends Command { private static Logger logger = Logger.getLogger("Financial Planner Logger"); + private final Ui ui = Ui.getInstance(); private double budget; private String command; public BudgetCommand(RawCommand rawCommand) throws FinancialPlannerException { - command = String.join(" ", rawCommand.args); + command = rawCommand.args.get(0); if (command.equals("delete") || command.equals("reset") || command.equals("view")) { return; } - if (!command.equals("set") && !command.equals("update")) { - logger.log(Level.WARNING, "Invalid arguments for budget command"); - throw new FinancialPlannerException("Budget command must be one of the following: set, update, " + - "delete, reset, view."); - } - - if (command.equals("set") && Budget.hasBudget()) { - logger.log(Level.WARNING, "Invalid command: Trying to set existing budget"); - throw new FinancialPlannerException("There is an existing budget, did you mean update?"); - } else if (command.equals("update") && !Budget.hasBudget()) { - logger.log(Level.WARNING, "Invalid command: Trying to update non-existent budget"); - throw new FinancialPlannerException("There is no budget set yet, did you mean set?"); - } - - if (!rawCommand.extraArgs.containsKey("b")) { - logger.log(Level.WARNING, "Missing argument /b in command"); - throw new IllegalArgumentException("Missing /b argument."); - } + validateCommandFormat(rawCommand); try { logger.log(Level.INFO, "Parsing budget as double"); @@ -45,7 +29,19 @@ public BudgetCommand(RawCommand rawCommand) throws FinancialPlannerException { logger.log(Level.WARNING, "Invalid value for budget"); throw new IllegalArgumentException("Budget must be a number."); } + validateBudget(); + + assert budget > 0 && budget <= Cashflow.getBalance() : "Budget should be greater than 0 and less than " + + "or equal to total balance"; + rawCommand.extraArgs.remove("b"); + if (!rawCommand.extraArgs.isEmpty()) { + String unknownExtraArgument = new ArrayList<>(rawCommand.extraArgs.keySet()).get(0); + throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); + } + } + + private void validateBudget() throws FinancialPlannerException { if (budget <= 0) { logger.log(Level.WARNING, "Invalid value for budget."); throw new FinancialPlannerException("Budget should be greater than 0."); @@ -55,14 +51,26 @@ public BudgetCommand(RawCommand rawCommand) throws FinancialPlannerException { logger.log(Level.WARNING, "Invalid value for budget"); throw new FinancialPlannerException("Budget should be lower than total balance."); } + } - assert budget > 0 && budget <= Cashflow.getBalance() : "Budget should be greater than 0 and less than " + - "or equal to total balance"; - rawCommand.extraArgs.remove("b"); + private void validateCommandFormat(RawCommand rawCommand) throws FinancialPlannerException { + if (!command.equals("set") && !command.equals("update")) { + logger.log(Level.WARNING, "Invalid arguments for budget command"); + throw new FinancialPlannerException("Budget command must be one of the following: set, update, " + + "delete, reset, view."); + } - if (!rawCommand.extraArgs.isEmpty()) { - String unknownExtraArgument = new ArrayList<>(rawCommand.extraArgs.keySet()).get(0); - throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); + if (command.equals("set") && Budget.hasBudget()) { + logger.log(Level.WARNING, "Invalid command: Trying to set existing budget"); + throw new FinancialPlannerException("There is an existing budget, did you mean update?"); + } else if (command.equals("update") && !Budget.hasBudget()) { + logger.log(Level.WARNING, "Invalid command: Trying to update non-existent budget"); + throw new FinancialPlannerException("There is no budget set yet, did you mean set?"); + } + + if (!rawCommand.extraArgs.containsKey("b")) { + logger.log(Level.WARNING, "Missing argument /b in command"); + throw new IllegalArgumentException("Missing /b argument."); } } @@ -71,51 +79,70 @@ public void execute() { assert command.equals("set") || command.equals("update") || command.equals("delete") || command.equals("reset") || command.equals("view"); - Ui ui = Ui.getInstance(); switch (command) { case "set": - logger.log(Level.INFO, "Setting budget"); - Budget.setBudget(budget); - ui.showMessage("A monthly budget of " + Budget.getInitialBudgetString() - + " has been set."); + setBudget(); break; case "update": - logger.log(Level.INFO, "Updating budget"); - ui.printBudgetBeforeUpdate(); - Budget.updateBudget(budget); - ui.printBudgetAfterUpdate(); + updateBudget(); break; case "delete": - if (Budget.hasBudget()) { - Budget.deleteBudget(); - ui.printDeleteBudget(); - } else { - ui.showMessage("Budget has not been set yet."); - } + deleteBudget(); break; case "reset": - if (Budget.getInitialBudget() != Budget.getCurrentBudget()) { - if (Budget.getInitialBudget() > Cashflow.getBalance()) { - Budget.setInitialBudget(Cashflow.getBalance()); - ui.showMessage("Since initial budget exceeds current balance, " + - "budget will be reset to current balance."); - } - Budget.resetBudget(); - ui.printResetBudget(); - } else { - ui.showMessage("Budget has not been spent yet."); - } + resetBudget(); break; case "view": - if (Budget.hasBudget()) { - ui.printBudget(); - } else { - ui.showMessage("There is no existing budget."); - } + viewBudget(); break; default: logger.log(Level.SEVERE, "Unreachable default case reached"); ui.showMessage("Unknown command."); } } + + private void viewBudget() { + if (Budget.hasBudget()) { + ui.printBudget(); + } else { + ui.showMessage("There is no existing budget."); + } + } + + private void resetBudget() { + if (Budget.getInitialBudget() != Budget.getCurrentBudget()) { + if (Budget.getInitialBudget() > Cashflow.getBalance()) { + Budget.setInitialBudget(Cashflow.getBalance()); + ui.showMessage("Since initial budget exceeds current balance, " + + "budget will be reset to current balance."); + } + Budget.resetBudget(); + ui.printResetBudget(); + } else { + ui.showMessage("Budget has not been spent yet."); + } + } + + private void deleteBudget() { + if (Budget.hasBudget()) { + Budget.deleteBudget(); + ui.printDeleteBudget(); + } else { + ui.showMessage("Budget has not been set yet."); + } + } + + private void updateBudget() { + logger.log(Level.INFO, "Updating budget"); + ui.printBudgetBeforeUpdate(); + Budget.updateBudget(budget); + ui.printBudgetAfterUpdate(); + } + + private void setBudget() { + logger.log(Level.INFO, "Setting budget"); + Budget.setBudget(budget); + ui.showMessage("A monthly budget of " + Budget.getInitialBudgetString() + + " has been set."); + } } diff --git a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java index 1c85336393..57ee5d6edb 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java @@ -1,6 +1,7 @@ package seedu.financialplanner.commands; import seedu.financialplanner.enumerations.CashflowCategory; +import seedu.financialplanner.list.Budget; import seedu.financialplanner.list.CashflowList; import seedu.financialplanner.utils.Ui; @@ -8,7 +9,6 @@ import java.util.logging.Logger; public class DeleteCashflowCommand extends Command { - private static final Logger logger = Logger.getLogger("Financial Planner Logger"); protected CashflowCategory category = null; protected int index; @@ -77,7 +77,10 @@ public void execute() { private void handleDeleteCashflowWithoutCategory() { try { logger.log(Level.INFO, "Deleting cashflow without category"); - cashflowList.delete(index); + double amount = cashflowList.delete(index); + if (Budget.hasBudget()) { + Budget.updateCurrentBudget(amount); + } } catch (IndexOutOfBoundsException e) { logger.log(Level.WARNING, "Index out of list"); throw new IllegalArgumentException("Index must be within the list"); @@ -87,7 +90,10 @@ private void handleDeleteCashflowWithoutCategory() { private void handleDeleteCashflowWithCategory() { try { logger.log(Level.INFO, "Deleting cashflow with category"); - cashflowList.deleteCashflow(category, index); + double amount = cashflowList.deleteCashflow(category, index); + if (Budget.hasBudget()) { + Budget.updateCurrentBudget(amount); + } } catch (IndexOutOfBoundsException e) { logger.log(Level.WARNING, "Index out of list"); throw new IllegalArgumentException("Index must be within the list"); diff --git a/src/main/java/seedu/financialplanner/commands/FindCommand.java b/src/main/java/seedu/financialplanner/commands/FindCommand.java index ba0397a698..15958d0ead 100644 --- a/src/main/java/seedu/financialplanner/commands/FindCommand.java +++ b/src/main/java/seedu/financialplanner/commands/FindCommand.java @@ -26,7 +26,7 @@ public void execute() { ArrayList foundedWatchList = new ArrayList<>(); for (int i = 0; i < cashflowList.list.size(); i++) { if (cashflowList.list.get(i).toString().contains(description)) { - String output = cashflowList.list.get(i).toString()+" | Index: "+(i+1); + String output = cashflowList.list.get(i).toString() + " | Index: " + (i + 1); foundedFinancialList.add(output); } } @@ -41,7 +41,7 @@ public void execute() { for (int i = 0; i < watchList.size(); i++) { if (watchList.get(i).toString().contains(description)) { - foundedWatchList.add(watchList.get(i).toString()+"| Index: "+(i+1)); + foundedWatchList.add(watchList.get(i).toString() + " | Index: " + (i + 1)); } } if (!foundedWatchList.isEmpty()) { diff --git a/src/main/java/seedu/financialplanner/commands/ListCommand.java b/src/main/java/seedu/financialplanner/commands/ListCommand.java index d799d05775..2427d7ed83 100644 --- a/src/main/java/seedu/financialplanner/commands/ListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/ListCommand.java @@ -63,7 +63,7 @@ public void execute() throws Exception { ui.showMessage(String.format("You have %d matching cash flow:", cashflowToBePrinted.size())); for (int i = 0; i < cashflowToBePrinted.size(); i += 1) { - ui.showMessage((i+ 1) + ": " + cashflowToBePrinted.get(i).toString()); + ui.showMessage((i + 1) + ": " + cashflowToBePrinted.get(i)); } } } diff --git a/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java b/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java index 99adeada6c..57db61b5c8 100644 --- a/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java +++ b/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java @@ -6,6 +6,7 @@ public class SetGoalCommand extends Command { private final String goal; private int amount; + public SetGoalCommand(RawCommand rawCommand) throws IllegalArgumentException { String labelString = String.join(" ", rawCommand.args); if(!rawCommand.extraArgs.containsKey("g")){ diff --git a/src/main/java/seedu/financialplanner/commands/VisCommand.java b/src/main/java/seedu/financialplanner/commands/VisCommand.java index df3a3e73b4..1bd1c7a937 100644 --- a/src/main/java/seedu/financialplanner/commands/VisCommand.java +++ b/src/main/java/seedu/financialplanner/commands/VisCommand.java @@ -14,7 +14,6 @@ public class VisCommand extends Command { private String type; private String chart; - public VisCommand(RawCommand rawCommand) throws IllegalArgumentException { if (!rawCommand.extraArgs.containsKey("t")) { throw new IllegalArgumentException("Entry type must be defined"); @@ -33,6 +32,7 @@ public VisCommand(RawCommand rawCommand) throws IllegalArgumentException { throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); } } + @Override public void execute() throws FinancialPlannerException { assert !chart.isEmpty(); diff --git a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java index 2c92530d98..6e128cd523 100644 --- a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java @@ -10,6 +10,7 @@ public class WatchListCommand extends Command { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); + public WatchListCommand(RawCommand rawCommand) throws IllegalArgumentException{ if (!rawCommand.extraArgs.isEmpty()) { logger.log(Level.WARNING, "Invalid extra arguments found"); @@ -18,6 +19,7 @@ public WatchListCommand(RawCommand rawCommand) throws IllegalArgumentException{ throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); } } + @Override public void execute() { Ui ui = Ui.getInstance(); diff --git a/src/main/java/seedu/financialplanner/goal/Goal.java b/src/main/java/seedu/financialplanner/goal/Goal.java index f415ba48ac..d78c73f00a 100644 --- a/src/main/java/seedu/financialplanner/goal/Goal.java +++ b/src/main/java/seedu/financialplanner/goal/Goal.java @@ -4,18 +4,22 @@ public class Goal { private String label; private int amount; private boolean isDone = false; + public Goal(String label, int amount) { this.label = label; this.amount = amount; } + public String toString() { String status = isDone ? "Done" : "Not Done"; - return "Goal: "+this.label + " | " + this.amount + " | " + status; + return "Goal: " + this.label + " | " + this.amount + " | " + status; } + public void markAsDone() { //TODO edit the expense to mark the goal as done this.isDone = true; } + //TODO delete the Reminder public String formatString() { String status = isDone ? "Done" : "Not Done"; diff --git a/src/main/java/seedu/financialplanner/goal/GoalList.java b/src/main/java/seedu/financialplanner/goal/GoalList.java index 738b9ce423..c741688742 100644 --- a/src/main/java/seedu/financialplanner/goal/GoalList.java +++ b/src/main/java/seedu/financialplanner/goal/GoalList.java @@ -6,6 +6,7 @@ public class GoalList { private GoalList() { } + public void load(Goal goal) { list.add(goal); } diff --git a/src/main/java/seedu/financialplanner/investments/Stock.java b/src/main/java/seedu/financialplanner/investments/Stock.java index d4aa1986b0..2179b8ed5b 100644 --- a/src/main/java/seedu/financialplanner/investments/Stock.java +++ b/src/main/java/seedu/financialplanner/investments/Stock.java @@ -29,6 +29,7 @@ public Stock(String symbol) throws FinancialPlannerException { public String getStockName() { return stockName; } + public String getStockNameFromAPI(String symbol) throws FinancialPlannerException { final String API_ENDPOINT = "https://www.alphavantage.co/query?function=SYMBOL_SEARCH&keywords="; final String API_KEY = "LNKL0548PHY2F0QU"; diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index dd00c9f968..73fb2d888e 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -16,7 +16,6 @@ import java.util.logging.Logger; public class WatchList { - public static final WatchList INSTANCE = new WatchList(); private static Logger logger = Logger.getLogger("Financial Planner Logger"); private final ArrayList stocks; diff --git a/src/main/java/seedu/financialplanner/list/Budget.java b/src/main/java/seedu/financialplanner/list/Budget.java index 54a059cf84..4ffad82d60 100644 --- a/src/main/java/seedu/financialplanner/list/Budget.java +++ b/src/main/java/seedu/financialplanner/list/Budget.java @@ -75,4 +75,8 @@ public static void resetBudget() { public static void setInitialBudget(double amount) { initialBudget = amount; } + + public static void updateCurrentBudget(double amount) { + currentBudget += amount; + } } diff --git a/src/main/java/seedu/financialplanner/list/Cashflow.java b/src/main/java/seedu/financialplanner/list/Cashflow.java index 54a930b51c..e5bf7f9505 100644 --- a/src/main/java/seedu/financialplanner/list/Cashflow.java +++ b/src/main/java/seedu/financialplanner/list/Cashflow.java @@ -17,6 +17,11 @@ public Cashflow(double amount, int recur) { this.amount = amount; this.recur = recur; } + + public static void clearBalance() { + balance = 0; + } + public void deleteCashflowvalue() { } diff --git a/src/main/java/seedu/financialplanner/list/CashflowList.java b/src/main/java/seedu/financialplanner/list/CashflowList.java index 4e61bf1aa0..3b802e704c 100644 --- a/src/main/java/seedu/financialplanner/list/CashflowList.java +++ b/src/main/java/seedu/financialplanner/list/CashflowList.java @@ -48,7 +48,7 @@ public void addExpense(double value, ExpenseType type, int recur) { assert newListSize == existingListSize + 1; } - public void delete(int index) { + public double delete(int index) { int existingListSize = list.size(); int listIndex = index - 1; @@ -59,6 +59,7 @@ public void delete(int index) { int newListSize = list.size(); assert newListSize == existingListSize - 1; + return toRemove.getAmount(); } //helper method to find the index of a given cashflow in the overall list //given its index in its respective list. e.g. "income 3" is the third income @@ -108,7 +109,7 @@ private int findCashflowIndexFromExpenseIndex(int cashflowIndex) { return overallCashflowIndex; } - public void deleteCashflow(CashflowCategory category, int index) { + public double deleteCashflow(CashflowCategory category, int index) { int existingListSize = list.size(); int listIndex = cashflowIndexFinder(category, index); @@ -119,19 +120,19 @@ public void deleteCashflow(CashflowCategory category, int index) { int newListSize = list.size(); assert newListSize == existingListSize - 1; + return toRemove.getAmount(); } - public void load(Cashflow entry) { list.add(entry); } //temp method public String getList() { - String output = ""; + StringBuilder output = new StringBuilder(); for (Cashflow entry : list) { - output += entry.formatString() + "\n"; + output.append(entry).append("\n"); } - return output; + return output.toString(); } } diff --git a/src/main/java/seedu/financialplanner/list/Income.java b/src/main/java/seedu/financialplanner/list/Income.java index 07778494c9..8e596e43fb 100644 --- a/src/main/java/seedu/financialplanner/list/Income.java +++ b/src/main/java/seedu/financialplanner/list/Income.java @@ -36,6 +36,7 @@ public String toString() { return "Income" + System.lineSeparator() + " Type: " + capitalize(type.toString().toLowerCase()) + System.lineSeparator() + super.toString(); } + @Override public String formatString() { return "I | " + this.amount + " | " + this.type + super.formatString(); diff --git a/src/main/java/seedu/financialplanner/reminder/Reminder.java b/src/main/java/seedu/financialplanner/reminder/Reminder.java index b43b16b5ad..f8a827e642 100644 --- a/src/main/java/seedu/financialplanner/reminder/Reminder.java +++ b/src/main/java/seedu/financialplanner/reminder/Reminder.java @@ -4,6 +4,7 @@ public class Reminder { private String type; private String date; private boolean isDone = false; + public Reminder(String type, String date) { this.type = type; this.date = date; @@ -11,8 +12,9 @@ public Reminder(String type, String date) { public String toString() { String status = isDone ? "Done" : "Not Done"; - return "Reminder: "+this.type + " | " + this.date + " | " + status; + return "Reminder: " + this.type + " | " + this.date + " | " + status; } + public void markAsDone() { this.isDone = true; } diff --git a/src/main/java/seedu/financialplanner/reminder/ReminderList.java b/src/main/java/seedu/financialplanner/reminder/ReminderList.java index 3aabf432c7..66abb1b0be 100644 --- a/src/main/java/seedu/financialplanner/reminder/ReminderList.java +++ b/src/main/java/seedu/financialplanner/reminder/ReminderList.java @@ -1,4 +1,5 @@ package seedu.financialplanner.reminder; + import java.util.ArrayList; public class ReminderList { public static final ReminderList INSTANCE = new ReminderList(); diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index f51d8ad76a..429d617761 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -55,6 +55,7 @@ private static void handleCorruptedFile(String message) throws FinancialPlannerE ui.showMessage("File appears to be corrupted. Do you want to create a new file? (Y/N)"); if (createNewFile()) { cashflowList.list.clear(); + Cashflow.clearBalance(); } else { throw new FinancialPlannerException("Please fix the corrupted file, " + "which can be found in data/data.txt.\nError message: " + message); @@ -66,9 +67,11 @@ private static void loadBudget(String[] split) throws IllegalArgumentException { double current = Double.parseDouble(split[2].trim()); if (initial < 0 || current < 0) { throw new IllegalArgumentException("Negative values for budget"); - } else if (initial > Cashflow.getBalance() || current > Cashflow.getBalance()) { + } + if (initial > Cashflow.getBalance() || current > Cashflow.getBalance()) { throw new IllegalArgumentException("Budget exceeds balance"); - } else if (initial < current) { + } + if (initial < current) { throw new IllegalArgumentException("Current budget exceeds initial budget"); } Budget.load(initial, current); diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 9f2287bb5a..7cd27749bd 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -10,15 +10,16 @@ public class Ui { private static Ui ui = null; private Scanner Scanner = new Scanner(System.in); - private Ui() { } + public static Ui getInstance() { if (ui == null) { ui = new Ui(); } return ui; } + public static void printCorruptedFileError(String message) { System.out.println(message); } @@ -69,6 +70,7 @@ public void printAddStock(String stockName) { System.out.println("Use Watchlist to view it!"); } + public void printAddedCashflow(Cashflow entry) { System.out.print("You have added an "); System.out.println(entry); diff --git a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java index 83d9661233..fa957b190f 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java @@ -13,6 +13,7 @@ public class Categorizer { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); + public static Map sortType(CashflowList cashflowList, String type) throws FinancialPlannerException { switch (type) { @@ -26,6 +27,7 @@ public static Map sortType(CashflowList cashflowList, String typ throw new FinancialPlannerException("Type not found"); } } + public static Map sortExpenses(CashflowList cashflowList) { Map expensesByCat = new HashMap<>(); for (Cashflow e: cashflowList.list) { diff --git a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java index b955d5b9ff..4169f8e5c0 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java @@ -18,8 +18,8 @@ import java.util.logging.Logger; public class Visualizer { - private static final Logger logger = Logger.getLogger("Financial Planner Logger"); + public static void displayChart(String chartType, Map expensesByCat) throws FinancialPlannerException { switch (chartType) { @@ -32,9 +32,8 @@ public static void displayChart(String chartType, Map expensesBy default: throw new FinancialPlannerException("Chart Type Not Found"); } - - } + public static void displayPieChart (Map expensesByCat) { PieChart chart = new PieChartBuilder().width(800).height(600).title("Test").build(); From f3d525423735d5a193da257d3b598f941e8a3a4b Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Mon, 23 Oct 2023 15:32:11 +0800 Subject: [PATCH 172/518] Add JUnit tests --- .../seedu/financialplanner/list/Cashflow.java | 4 ++ .../commands/BudgetCommandTest.java | 37 +++++++++++++++++++ .../financialplanner/list/BudgetTest.java | 32 ++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100644 src/test/java/seedu/financialplanner/commands/BudgetCommandTest.java diff --git a/src/main/java/seedu/financialplanner/list/Cashflow.java b/src/main/java/seedu/financialplanner/list/Cashflow.java index e5bf7f9505..42cc75492f 100644 --- a/src/main/java/seedu/financialplanner/list/Cashflow.java +++ b/src/main/java/seedu/financialplanner/list/Cashflow.java @@ -22,6 +22,10 @@ public static void clearBalance() { balance = 0; } + public static void setBalance(double amount) { + balance = amount; + } + public void deleteCashflowvalue() { } diff --git a/src/test/java/seedu/financialplanner/commands/BudgetCommandTest.java b/src/test/java/seedu/financialplanner/commands/BudgetCommandTest.java new file mode 100644 index 0000000000..4185076b06 --- /dev/null +++ b/src/test/java/seedu/financialplanner/commands/BudgetCommandTest.java @@ -0,0 +1,37 @@ +package seedu.financialplanner.commands; + +import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import seedu.financialplanner.exceptions.FinancialPlannerException; +import seedu.financialplanner.list.Budget; +import seedu.financialplanner.list.Cashflow; +import seedu.financialplanner.utils.Parser; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@TestMethodOrder(OrderAnnotation.class) +public class BudgetCommandTest { + @Test + @Order(1) + public void testSetBudget() throws FinancialPlannerException { + Cashflow.setBalance(2000); + Budget.deleteBudget(); + BudgetCommand testBudget = new BudgetCommand(Parser.parseRawCommand("budget set /b 1000")); + testBudget.execute(); + assertEquals(1000, Budget.getInitialBudget()); + assertEquals(1000, Budget.getCurrentBudget()); + assertTrue(Budget.hasBudget()); + } + + @Test + @Order(2) + public void testUpdateBudget() throws FinancialPlannerException { + BudgetCommand testBudget = new BudgetCommand(Parser.parseRawCommand("budget update /b 1500")); + testBudget.execute(); + assertEquals(1500, Budget.getInitialBudget()); + assertEquals(1500, Budget.getCurrentBudget()); + } +} diff --git a/src/test/java/seedu/financialplanner/list/BudgetTest.java b/src/test/java/seedu/financialplanner/list/BudgetTest.java index b866976869..215339e732 100644 --- a/src/test/java/seedu/financialplanner/list/BudgetTest.java +++ b/src/test/java/seedu/financialplanner/list/BudgetTest.java @@ -16,6 +16,7 @@ public class BudgetTest { @Test @Order(1) public void testSetBudget() { + Budget.deleteBudget(); assertFalse(Budget.hasBudget()); Budget.setBudget(500); assertTrue(Budget.hasBudget()); @@ -38,4 +39,35 @@ public void testUpdateBudget() { assertEquals(1000, Budget.getInitialBudget()); assertEquals(950, Budget.getCurrentBudget()); } + + @Test + @Order(4) + public void testSetInitialBudget() { + Budget.setInitialBudget(1500); + assertEquals(1500, Budget.getInitialBudget()); + } + + @Test + @Order(5) + public void testUpdateCurrentBudget() { + Budget.updateCurrentBudget(50); + assertEquals(1000, Budget.getCurrentBudget()); + } + + @Test + @Order(6) + public void testResetBudget() { + Budget.resetBudget(); + assertEquals(1500, Budget.getInitialBudget()); + assertEquals(1500, Budget.getCurrentBudget()); + } + + @Test + @Order(7) + public void testDeleteBudget() { + Budget.deleteBudget(); + assertEquals(0, Budget.getInitialBudget()); + assertEquals(0, Budget.getCurrentBudget()); + assertFalse(Budget.hasBudget()); + } } From c0d66053cd92b47cb444435e2f30e55047b9d210 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 23 Oct 2023 15:39:12 +0800 Subject: [PATCH 173/518] Fix checkstyle errors --- .../financialplanner/investments/WatchList.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index 8491d0b2c2..8b90be20ae 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -20,17 +20,11 @@ public class WatchList { private static WatchList watchlist = null; - - public static WatchList getInstance() { - if (watchlist == null) { - watchlist = new WatchList(); - } - return watchlist; - } private static Logger logger = Logger.getLogger("Financial Planner Logger"); private final ArrayList stocks; private final String API_ENDPOINT = "https://financialmodelingprep.com/api/v3/quote/"; private final String API_KEY = "iFumtYryBCbHpS3sDqLdVKi2SdP63vSV"; + private WatchList() { stocks = new ArrayList<>(); try { @@ -50,6 +44,13 @@ private WatchList() { } } + public static WatchList getInstance() { + if (watchlist == null) { + watchlist = new WatchList(); + } + return watchlist; + } + public void fetchFMPStockPrices() throws FinancialPlannerException { if (stocks.isEmpty()) { throw new FinancialPlannerException("Empty Watchlist. Nothing to display..."); From ea37034ac84b421b3b6038ea67cc563809a4ba80 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Mon, 23 Oct 2023 15:43:28 +0800 Subject: [PATCH 174/518] Add balance command Fixes #100 --- .../commands/BalanceCommand.java | 22 +++++++++++++++++++ .../seedu/financialplanner/utils/Parser.java | 4 ++++ 2 files changed, 26 insertions(+) create mode 100644 src/main/java/seedu/financialplanner/commands/BalanceCommand.java diff --git a/src/main/java/seedu/financialplanner/commands/BalanceCommand.java b/src/main/java/seedu/financialplanner/commands/BalanceCommand.java new file mode 100644 index 0000000000..e1ee22afd3 --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/BalanceCommand.java @@ -0,0 +1,22 @@ +package seedu.financialplanner.commands; + +import seedu.financialplanner.list.Cashflow; +import seedu.financialplanner.utils.Ui; + +import java.util.ArrayList; + +public class BalanceCommand extends Command { + private final Ui ui = Ui.getInstance(); + + public BalanceCommand(RawCommand rawCommand) { + if (!rawCommand.extraArgs.isEmpty()) { + String unknownExtraArgument = new ArrayList<>(rawCommand.extraArgs.keySet()).get(0); + throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); + } + } + + @Override + public void execute() throws Exception { + ui.showMessage("Balance: " + Cashflow.getBalance()); + } +} diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index 5540556b7e..44c5017923 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -15,6 +15,7 @@ import seedu.financialplanner.commands.BudgetCommand; import seedu.financialplanner.commands.AddReminderCommand; import seedu.financialplanner.commands.SetGoalCommand; +import seedu.financialplanner.commands.BalanceCommand; import seedu.financialplanner.exceptions.FinancialPlannerException; import java.util.ArrayList; @@ -37,6 +38,7 @@ public class Parser { private static final String ADD_REMINDER_COMMAND = "addreminder"; private static final String LIST_COMMAND = "list"; private static final String SET_GOAL_COMMAND = "set"; + private static final String BALANCE_COMMAND = "balance"; public static Command parseCommand(String input) throws FinancialPlannerException { RawCommand rawCommand = parseRawCommand(input); @@ -69,6 +71,8 @@ public static Command parseCommand(RawCommand rawCommand) throws FinancialPlanne return new ListCommand(rawCommand); case SET_GOAL_COMMAND: return new SetGoalCommand(rawCommand); + case BALANCE_COMMAND: + return new BalanceCommand(rawCommand); default: return new InvalidCommand(); } From 4f0d456e878d1f1cab572bcd372c767ddcad1c25 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Mon, 23 Oct 2023 15:48:35 +0800 Subject: [PATCH 175/518] Remove unused imports --- src/main/java/seedu/financialplanner/FinancialPlanner.java | 2 -- src/main/java/seedu/financialplanner/storage/Storage.java | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index e59ba233b4..3e0f583f06 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -3,8 +3,6 @@ import seedu.financialplanner.commands.Command; import seedu.financialplanner.commands.ExitCommand; import seedu.financialplanner.exceptions.FinancialPlannerException; -import seedu.financialplanner.investments.WatchList; -import seedu.financialplanner.list.CashflowList; import seedu.financialplanner.storage.Storage; import seedu.financialplanner.utils.Parser; import seedu.financialplanner.utils.Ui; diff --git a/src/main/java/seedu/financialplanner/storage/Storage.java b/src/main/java/seedu/financialplanner/storage/Storage.java index 49c6f65b8a..012c1f1095 100644 --- a/src/main/java/seedu/financialplanner/storage/Storage.java +++ b/src/main/java/seedu/financialplanner/storage/Storage.java @@ -1,8 +1,6 @@ package seedu.financialplanner.storage; import seedu.financialplanner.exceptions.FinancialPlannerException; -import seedu.financialplanner.list.CashflowList; -import seedu.financialplanner.utils.Ui; import java.io.IOException; import java.nio.file.Files; From 4727ec201e21927e13f40a0c34c6bc8fe80d0460 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 23 Oct 2023 16:04:32 +0800 Subject: [PATCH 176/518] Fix assertion bug --- .../commands/DeleteCashflowCommand.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java index a1dc3b993c..8b138e4587 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java @@ -54,14 +54,14 @@ private void handleInvalidCategory(String stringCategory) { @Override public void execute() { - assert category.equals(CashflowCategory.INCOME) || category.equals(CashflowCategory.EXPENSE); - assert index != 0; - if (category == null) { handleDeleteCashflowWithoutCategory(); return; } - Ui ui = Ui.getInstance(); + + assert category.equals(CashflowCategory.INCOME) || category.equals(CashflowCategory.EXPENSE); + assert index != 0; + switch (category) { case INCOME: case EXPENSE: @@ -69,7 +69,7 @@ public void execute() { break; default: logger.log(Level.SEVERE, "Unreachable default case reached"); - ui.showMessage("Unidentified entry."); + Ui.getInstance().showMessage("Unidentified entry."); break; } } From 890fc0d7877d7e156bc7303d84168b085542471f Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 23 Oct 2023 17:21:06 +0800 Subject: [PATCH 177/518] Create method to save and load watchlist data to file --- .../financialplanner/storage/LoadData.java | 26 +++++++++++++++++++ .../financialplanner/storage/SaveData.java | 21 +++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index e17dbe6463..1274452e81 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -3,6 +3,7 @@ import seedu.financialplanner.enumerations.ExpenseType; import seedu.financialplanner.enumerations.IncomeType; import seedu.financialplanner.exceptions.FinancialPlannerException; +import seedu.financialplanner.investments.Stock; import seedu.financialplanner.list.Budget; import seedu.financialplanner.list.Cashflow; import seedu.financialplanner.list.CashflowList; @@ -10,11 +11,16 @@ import seedu.financialplanner.list.Expense; import seedu.financialplanner.utils.Ui; +import java.io.StreamCorruptedException; +import java.io.FileInputStream; import java.io.FileReader; import java.io.IOException; +import java.io.ObjectInputStream; +import java.util.ArrayList; import java.util.Scanner; public abstract class LoadData { + private static final String FILE_PATH = "data/watchlist.txt"; public static void load(CashflowList cashflowList, Ui ui, String filePath) throws FinancialPlannerException { try { Scanner inputFile = new Scanner(new FileReader(filePath)); @@ -106,4 +112,24 @@ private static Cashflow getEntry(String type, String[] split) return entry; } + + public static ArrayList loadWatchList() { + Ui ui = Ui.getInstance(); + ArrayList stocksData = new ArrayList<>(); + try { + ObjectInputStream watchListStocksInputStream + = new ObjectInputStream( + new FileInputStream(FILE_PATH) + ); + stocksData = (ArrayList) watchListStocksInputStream.readObject(); + watchListStocksInputStream.close(); + } catch (StreamCorruptedException e) { + ui.showMessage("Watchlist file corrupted.. Rebuilding"); + } catch (IOException e) { + ui.showMessage("Watchlist file not found... Creating"); + } catch (ClassNotFoundException e) { + ui.showMessage("FIle appears to be corrupted..."); + } + return stocksData; + } } diff --git a/src/main/java/seedu/financialplanner/storage/SaveData.java b/src/main/java/seedu/financialplanner/storage/SaveData.java index d87f449bc1..3e3f5b29b5 100644 --- a/src/main/java/seedu/financialplanner/storage/SaveData.java +++ b/src/main/java/seedu/financialplanner/storage/SaveData.java @@ -1,14 +1,20 @@ package seedu.financialplanner.storage; import seedu.financialplanner.exceptions.FinancialPlannerException; +import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.list.Budget; import seedu.financialplanner.list.Cashflow; import seedu.financialplanner.list.CashflowList; +import seedu.financialplanner.utils.Ui; +import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; +import java.io.ObjectOutputStream; public abstract class SaveData { + private static final String FILE_PATH = "data/watchlist.txt"; + public static void save(CashflowList cashflowList, String filePath) throws FinancialPlannerException { try { FileWriter fw = new FileWriter(filePath); @@ -21,4 +27,19 @@ public static void save(CashflowList cashflowList, String filePath) throws Finan throw new FinancialPlannerException("Error saving file."); } } + + public static void saveWatchList() { + Ui ui = Ui.getInstance(); + try { + ObjectOutputStream watchListStocksOutput + = new ObjectOutputStream(new FileOutputStream(FILE_PATH)); + + WatchList wl = WatchList.getInstance(); + watchListStocksOutput.writeObject(wl.getStocks()); + + watchListStocksOutput.close(); + } catch (IOException e) { + ui.showMessage("Unable to save watchlist to file"); + } + } } From 8700572d1c9a8ddad641307b473f8a2b39a03bf5 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 23 Oct 2023 17:21:54 +0800 Subject: [PATCH 178/518] Add calls to load and save methods in required areas --- .../financialplanner/FinancialPlanner.java | 2 ++ .../investments/WatchList.java | 19 +++++++++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index 1afc41fede..acfdaceaf9 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -5,6 +5,7 @@ import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.list.CashflowList; +import seedu.financialplanner.storage.SaveData; import seedu.financialplanner.storage.Storage; import seedu.financialplanner.utils.Parser; import seedu.financialplanner.utils.Ui; @@ -38,6 +39,7 @@ public void run() { AbstractCommand command = null; while (!(command instanceof ExitCommand)) { + SaveData.saveWatchList(); input = ui.input(); try { command = Parser.parseCommand(input); diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index 8b90be20ae..2da00afba4 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -6,6 +6,7 @@ import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; import seedu.financialplanner.exceptions.FinancialPlannerException; +import seedu.financialplanner.storage.LoadData; import java.io.IOException; import java.net.URI; @@ -21,24 +22,25 @@ public class WatchList { private static WatchList watchlist = null; private static Logger logger = Logger.getLogger("Financial Planner Logger"); - private final ArrayList stocks; + private ArrayList stocks = null; private final String API_ENDPOINT = "https://financialmodelingprep.com/api/v3/quote/"; private final String API_KEY = "iFumtYryBCbHpS3sDqLdVKi2SdP63vSV"; private WatchList() { - stocks = new ArrayList<>(); + stocks = LoadData.loadWatchList(); + if (!stocks.isEmpty()) { + return; + } + System.out.println("Initializing New watchlist.. adding AAPL and GOOGL for your reference"); try { Stock apple = new Stock("AAPL"); assert apple.getSymbol() != null && apple.getStockName() != null; stocks.add(apple); - Stock meta = new Stock("META"); - assert meta.getSymbol() != null && meta.getStockName() != null; - stocks.add(meta); - Stock google = new Stock("GOOGL"); assert google.getSymbol() != null && google.getStockName() != null; stocks.add(google); + } catch (FinancialPlannerException e) { System.out.println(e.getMessage()); } @@ -128,4 +130,9 @@ public ArrayList getStocks() { return stocks; } + public void setStocks(ArrayList stocks) { + this.stocks = stocks; + } + + } From 23a689f8e1269eb0c7bf84282a588da8d65b8256 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 23 Oct 2023 17:22:16 +0800 Subject: [PATCH 179/518] Make stock serializable --- src/main/java/seedu/financialplanner/investments/Stock.java | 3 ++- src/main/java/seedu/financialplanner/storage/Storage.java | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/investments/Stock.java b/src/main/java/seedu/financialplanner/investments/Stock.java index a67b73a618..13a4bfc2b2 100644 --- a/src/main/java/seedu/financialplanner/investments/Stock.java +++ b/src/main/java/seedu/financialplanner/investments/Stock.java @@ -7,6 +7,7 @@ import seedu.financialplanner.exceptions.FinancialPlannerException; import java.io.IOException; +import java.io.Serializable; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; @@ -15,7 +16,7 @@ import java.util.logging.Level; import java.util.logging.Logger; -public class Stock { +public class Stock implements Serializable { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private String symbol; private String market; diff --git a/src/main/java/seedu/financialplanner/storage/Storage.java b/src/main/java/seedu/financialplanner/storage/Storage.java index ef340a2d3e..6c9c3721bf 100644 --- a/src/main/java/seedu/financialplanner/storage/Storage.java +++ b/src/main/java/seedu/financialplanner/storage/Storage.java @@ -31,4 +31,5 @@ public void load(CashflowList list, Ui ui, String filePath) throws FinancialPlan public void save(CashflowList list, String filePath) throws FinancialPlannerException { SaveData.save(list, filePath); } + } From 55101bf4b40825d68ee3cbe3881590a37ab77385 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 23 Oct 2023 17:53:30 +0800 Subject: [PATCH 180/518] Fix Test case for fetching stock prices --- .../java/seedu/financialplanner/investments/WatchListTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/seedu/financialplanner/investments/WatchListTest.java b/src/test/java/seedu/financialplanner/investments/WatchListTest.java index 81a6e72ac2..4d29930914 100644 --- a/src/test/java/seedu/financialplanner/investments/WatchListTest.java +++ b/src/test/java/seedu/financialplanner/investments/WatchListTest.java @@ -17,7 +17,6 @@ void fetchFMPStockPrices() throws FinancialPlannerException { ArrayList stocks = wl.getStocks(); assertNotNull(stocks.get(0).getPrice()); assertNotNull(stocks.get(1).getPrice()); - assertNotNull(stocks.get(2).getPrice()); } @Test From 232ce50c57d8211e808b7e4cb44c33a3393c40c4 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 23 Oct 2023 18:03:30 +0800 Subject: [PATCH 181/518] Change colour for visualizer --- .../financialplanner/visualisations/Visualizer.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java index b955d5b9ff..33f4c561f2 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java @@ -40,11 +40,11 @@ public static void displayPieChart (Map expensesByCat) { // Customize Chart Color[] sliceColors = new Color[] { - new Color(224, 68, 14), - new Color(230, 105, 62), - new Color(236, 143, 110), - new Color(243, 180, 159), - new Color(246, 199, 182) + new Color(21, 224, 14), + new Color(62, 154, 230), + new Color(236, 186, 110), + new Color(243, 159, 242), + new Color(246, 182, 197) }; chart.getStyler().setSeriesColors(sliceColors); From 32f49d9e4e4d753a3206ea2a79629224b657674c Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 23 Oct 2023 18:08:32 +0800 Subject: [PATCH 182/518] Update I/O file --- text-ui-test/EXPECTED.TXT | 2 ++ 1 file changed, 2 insertions(+) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 1231a70416..a9bfff1a1a 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,3 +1,5 @@ +Watchlist file not found... Creating +Initializing New watchlist.. adding AAPL and GOOGL for your reference Directory doesn't exist. Creating directory... File not found. Creating new file... Welcome to your Financial Planner. Type something to get started. From df0addf83e4a7e623a8fd3123a50f5e0deda6d63 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 23 Oct 2023 18:12:31 +0800 Subject: [PATCH 183/518] Fix UI file --- text-ui-test/EXPECTED.TXT | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index a9bfff1a1a..0d1b40ab92 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,6 +1,6 @@ +Directory doesn't exist. Creating directory... Watchlist file not found... Creating Initializing New watchlist.. adding AAPL and GOOGL for your reference -Directory doesn't exist. Creating directory... File not found. Creating new file... Welcome to your Financial Planner. Type something to get started. You have added an Income From ce64cbcd25ab1dd64b0f44b72e2cee20f9dfba7a Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 23 Oct 2023 18:17:21 +0800 Subject: [PATCH 184/518] Fix IO test --- text-ui-test/EXPECTED.TXT | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 0d1b40ab92..b856035378 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,6 +1,10 @@ Directory doesn't exist. Creating directory... Watchlist file not found... Creating Initializing New watchlist.. adding AAPL and GOOGL for your reference +Oct 23, 2023 6:16:34 PM seedu.financialplanner.investments.Stock getStockNameFromAPI +INFO: Requesting API for stock info +Oct 23, 2023 6:16:35 PM seedu.financialplanner.investments.Stock getStockNameFromAPI +INFO: Requesting API for stock info File not found. Creating new file... Welcome to your Financial Planner. Type something to get started. You have added an Income From 67fddc3c6856207ecdb706ba890e3351cd224e96 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Mon, 23 Oct 2023 18:17:40 +0800 Subject: [PATCH 185/518] Edit FinancialPlanner --- src/main/java/seedu/financialplanner/FinancialPlanner.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index 3e0f583f06..08d548f1da 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -3,6 +3,7 @@ import seedu.financialplanner.commands.Command; import seedu.financialplanner.commands.ExitCommand; import seedu.financialplanner.exceptions.FinancialPlannerException; +import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.storage.Storage; import seedu.financialplanner.utils.Parser; import seedu.financialplanner.utils.Ui; @@ -11,7 +12,8 @@ public class FinancialPlanner { private static final String FILE_PATH = "data/data.txt"; private final Storage storage = Storage.getInstance(); private final Ui ui = Ui.getInstance(); - + private final WatchList watchList = WatchList.getInstance(); + private FinancialPlanner() { } From 97f8e225de5a41047590156c587a3fb08db56b85 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 23 Oct 2023 18:23:54 +0800 Subject: [PATCH 186/518] Fix text ui test --- text-ui-test/EXPECTED.TXT | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index b856035378..71b26876f1 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,10 +1,6 @@ Directory doesn't exist. Creating directory... Watchlist file not found... Creating Initializing New watchlist.. adding AAPL and GOOGL for your reference -Oct 23, 2023 6:16:34 PM seedu.financialplanner.investments.Stock getStockNameFromAPI -INFO: Requesting API for stock info -Oct 23, 2023 6:16:35 PM seedu.financialplanner.investments.Stock getStockNameFromAPI -INFO: Requesting API for stock info File not found. Creating new file... Welcome to your Financial Planner. Type something to get started. You have added an Income @@ -54,26 +50,3 @@ Balance: 0.00 You have successfully added: Microsoft Corporation Use Watchlist to view it! -You have successfully added: -Gamestop Corporation - Class A -Use Watchlist to view it! -You have added an Income - Type: Salary - Amount: 5000.00 - Recurring every: 30 days -to the Financial Planner. -Balance: 5000.00 -A monthly budget of 3000.00 has been set. -Budget has been updated: -Old initial budget: 3000.00 -Old current budget: 3000.00 -New initial budget: 1000.00 -New current budget: 1000.00 -You have added an Expense - Type: Shopping - Amount: 200.00 -to the Financial Planner. -Balance: 4800.00 -Your remaining budget for the month is: 800.00 -Unknown command. Please try again. -Exiting Financial Planner. Goodbye. From a9e78c6c551b5bc891fd94d486f3140acd809089 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 23 Oct 2023 18:28:15 +0800 Subject: [PATCH 187/518] Update text ui --- text-ui-test/EXPECTED.TXT | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 71b26876f1..0d1b40ab92 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -50,3 +50,26 @@ Balance: 0.00 You have successfully added: Microsoft Corporation Use Watchlist to view it! +You have successfully added: +Gamestop Corporation - Class A +Use Watchlist to view it! +You have added an Income + Type: Salary + Amount: 5000.00 + Recurring every: 30 days +to the Financial Planner. +Balance: 5000.00 +A monthly budget of 3000.00 has been set. +Budget has been updated: +Old initial budget: 3000.00 +Old current budget: 3000.00 +New initial budget: 1000.00 +New current budget: 1000.00 +You have added an Expense + Type: Shopping + Amount: 200.00 +to the Financial Planner. +Balance: 4800.00 +Your remaining budget for the month is: 800.00 +Unknown command. Please try again. +Exiting Financial Planner. Goodbye. From 3f962dd0ac6a834e997ce2c77c602f80cdb3b8e4 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 23 Oct 2023 21:20:42 +0800 Subject: [PATCH 188/518] Change to save watchlist only when exiting --- src/main/java/seedu/financialplanner/FinancialPlanner.java | 1 - src/main/java/seedu/financialplanner/storage/Storage.java | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index 428d1f12cc..a5a65bfdcd 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -36,7 +36,6 @@ public void run() { Command command = null; while (!(command instanceof ExitCommand)) { - SaveData.saveWatchList(); input = ui.input(); try { command = Parser.parseCommand(input); diff --git a/src/main/java/seedu/financialplanner/storage/Storage.java b/src/main/java/seedu/financialplanner/storage/Storage.java index fe6a81505f..b63b0d0c50 100644 --- a/src/main/java/seedu/financialplanner/storage/Storage.java +++ b/src/main/java/seedu/financialplanner/storage/Storage.java @@ -35,6 +35,7 @@ public void load(String filePath) throws FinancialPlannerException { public void save(String filePath) throws FinancialPlannerException { SaveData.save(filePath); + SaveData.saveWatchList(); } } From 7f8f76935e4a066fddfdbd7f1950d5ab0caa5002 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 23 Oct 2023 21:23:15 +0800 Subject: [PATCH 189/518] fix checkstly error --- src/main/java/seedu/financialplanner/storage/LoadData.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 6d8bd486e3..88afaa6c54 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -137,7 +137,7 @@ public static ArrayList loadWatchList() { try { ObjectInputStream watchListStocksInputStream = new ObjectInputStream( - new FileInputStream(FILE_PATH) + new FileInputStream(FILE_PATH) ); stocksData = (ArrayList) watchListStocksInputStream.readObject(); watchListStocksInputStream.close(); From 2bf5672bb389312c948d2408216b6e1cccf27159 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 23 Oct 2023 21:26:27 +0800 Subject: [PATCH 190/518] Remove unused Imports --- src/main/java/seedu/financialplanner/FinancialPlanner.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index a5a65bfdcd..08d548f1da 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -4,7 +4,6 @@ import seedu.financialplanner.commands.ExitCommand; import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.investments.WatchList; -import seedu.financialplanner.storage.SaveData; import seedu.financialplanner.storage.Storage; import seedu.financialplanner.utils.Parser; import seedu.financialplanner.utils.Ui; From dc34fb4f3597f37652bbf91bb168e07ebfbea8ee Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 24 Oct 2023 11:35:59 +0800 Subject: [PATCH 191/518] Add sequence diagrams for budgetcommand --- docs/diagrams/Budget.puml | 27 +++++++++++++++++++++++++++ docs/diagrams/deleteBudget.puml | 15 +++++++++++++++ docs/diagrams/resetBudget.puml | 19 +++++++++++++++++++ docs/diagrams/viewBudget.puml | 14 ++++++++++++++ docs/images/Budget.png | Bin 0 -> 22867 bytes docs/images/deleteBudget.png | Bin 0 -> 12058 bytes docs/images/resetBudget.png | Bin 0 -> 18916 bytes docs/images/viewBudget.png | Bin 0 -> 11256 bytes 8 files changed, 75 insertions(+) create mode 100644 docs/diagrams/Budget.puml create mode 100644 docs/diagrams/deleteBudget.puml create mode 100644 docs/diagrams/resetBudget.puml create mode 100644 docs/diagrams/viewBudget.puml create mode 100644 docs/images/Budget.png create mode 100644 docs/images/deleteBudget.png create mode 100644 docs/images/resetBudget.png create mode 100644 docs/images/viewBudget.png diff --git a/docs/diagrams/Budget.puml b/docs/diagrams/Budget.puml new file mode 100644 index 0000000000..db63529c02 --- /dev/null +++ b/docs/diagrams/Budget.puml @@ -0,0 +1,27 @@ +@startuml + +participant BudgetCommand +participant Budget +participant Ui + +-> BudgetCommand: execute() +BudgetCommand -> Ui: getInstance() + +alt set + BudgetCommand -> Budget: setBudget(budget) + BudgetCommand -> Ui: printSetBudgetMessage() +else update + BudgetCommand -> Ui: printBudgetBeforeUpdate() + BudgetCommand -> Budget: updateBudget(budget) + BudgetCommand -> Ui: printBudgetAfterUpdate() +else delete + ref over BudgetCommand: deleteBudget +else reset + ref over BudgetCommand: resetBudget +else view + ref over BudgetCommand: viewBudget +else invalid command +end + + +@enduml \ No newline at end of file diff --git a/docs/diagrams/deleteBudget.puml b/docs/diagrams/deleteBudget.puml new file mode 100644 index 0000000000..587d2b032d --- /dev/null +++ b/docs/diagrams/deleteBudget.puml @@ -0,0 +1,15 @@ +@startuml + +mainframe sd deleteBudget +participant BudgetCommand +participant Budget +participant Ui + +alt hasBudget + BudgetCommand -> Budget: deleteBudget() + BudgetCommand -> Ui: printDeleteBudget() +else else + BudgetCommand -> Ui: printErrorMessage() +end + +@enduml \ No newline at end of file diff --git a/docs/diagrams/resetBudget.puml b/docs/diagrams/resetBudget.puml new file mode 100644 index 0000000000..116d46680c --- /dev/null +++ b/docs/diagrams/resetBudget.puml @@ -0,0 +1,19 @@ +@startuml + +mainframe sd resetBudget +participant BudgetCommand +participant Budget +participant Ui + +alt spentBudget + opt initialBudgetExceedBalance + BudgetCommand -> Budget: setInitialBudget(balance); + BudgetCommand -> Ui: printUpdateMessage() + end + BudgetCommand -> Budget: resetBudget() + BudgetCommand -> Ui: printResetBudget() +else else + BudgetCommand -> Ui: printErrorMessage() +end + +@enduml \ No newline at end of file diff --git a/docs/diagrams/viewBudget.puml b/docs/diagrams/viewBudget.puml new file mode 100644 index 0000000000..2200b8b453 --- /dev/null +++ b/docs/diagrams/viewBudget.puml @@ -0,0 +1,14 @@ +@startuml + +mainframe sd viewBudget +participant BudgetCommand +participant Budget +participant Ui + +alt hasBudget + BudgetCommand -> Ui: printBudget() +else else + BudgetCommand -> Ui: printErrorMessage() +end + +@enduml \ No newline at end of file diff --git a/docs/images/Budget.png b/docs/images/Budget.png new file mode 100644 index 0000000000000000000000000000000000000000..569908ac3b95fe43fcb9c004565fc699b43676b3 GIT binary patch literal 22867 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 literal 0 HcmV?d00001 diff --git a/docs/images/deleteBudget.png b/docs/images/deleteBudget.png new file mode 100644 index 0000000000000000000000000000000000000000..9a7bdb6f7dcaeb69968ef5dd6664956574048b94 GIT binary patch literal 12058 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 BO&b6J literal 0 HcmV?d00001 diff --git a/docs/images/viewBudget.png b/docs/images/viewBudget.png new file mode 100644 index 0000000000000000000000000000000000000000..d2723288b28d474bb1d3722dd71d3e2a9c2109da GIT binary patch literal 11256 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 Date: Tue, 24 Oct 2023 11:38:34 +0800 Subject: [PATCH 192/518] Fix bug in loadBudget --- src/main/java/seedu/financialplanner/storage/LoadData.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 429d617761..9e15775f7a 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -65,6 +65,9 @@ private static void handleCorruptedFile(String message) throws FinancialPlannerE private static void loadBudget(String[] split) throws IllegalArgumentException { double initial = Double.parseDouble(split[1].trim()); double current = Double.parseDouble(split[2].trim()); + if (initial == 0 && current == 0) { + return; + } if (initial < 0 || current < 0) { throw new IllegalArgumentException("Negative values for budget"); } From 99c4cc5129b3da88815448476934d4dc8f1d3e2e Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Tue, 24 Oct 2023 12:21:21 +0800 Subject: [PATCH 193/518] Add description for the visualization feature in developers guide --- docs/DeveloperGuide.md | 20 ++++++++++++++++++ .../vis/Screenshot 2023-10-24 113526.png | Bin 0 -> 39804 bytes 2 files changed, 20 insertions(+) create mode 100644 docs/images/vis/Screenshot 2023-10-24 113526.png diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 64e1f0ed2b..de0c0f4bb6 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -8,6 +8,26 @@ {Describe the design and implementation of the product. Use UML diagrams and short code snippets where applicable.} +### Visualization Feature + +This feature is implemented with the help of [XChart](https://knowm.org/open-source/xchart/), a simple charting library for Java by Knowm. + +By typing in the vis command with the appropriate arguments (/s and /t), users will be able to visualize their income or expense +using visualization tools (Piechart, Bar Chart) + +Demo: + +`vis /t expense /c pie` + +output + +![](C:\Users\puach\Documents\Y2S1\CS2113\tp\docs\images\vis\Screenshot%202023-10-24%20113526.png) + +This feature was implemented with the help of three different classes. + +Class Diagram + + ## Product scope ### Target user profile diff --git a/docs/images/vis/Screenshot 2023-10-24 113526.png b/docs/images/vis/Screenshot 2023-10-24 113526.png new file mode 100644 index 0000000000000000000000000000000000000000..55c06708188de680fa490fd7a44e776eb6246466 GIT binary patch literal 39804 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 Date: Tue, 24 Oct 2023 12:21:47 +0800 Subject: [PATCH 194/518] Add necessity to the error handling --- .../seedu/financialplanner/commands/AddCashflowCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index d9afc930fb..cd7a763cbd 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -62,7 +62,7 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException } catch (IllegalArgumentException e) { logger.log(Level.WARNING, "Invalid arguments for ExpenseType"); throw new IllegalArgumentException("Entry must be one of the following: " + - "dining, entertainment, shopping, travel, insurance, others"); + "dining, entertainment, shopping, travel, insurance, necessities, others"); } } else if (category.equals(CashflowCategory.INCOME)) { try { From 351638778793c0b541ba6688cdc165881a54b0e5 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Tue, 24 Oct 2023 12:22:29 +0800 Subject: [PATCH 195/518] Add title display for visualization of charats --- .../financialplanner/commands/VisCommand.java | 2 +- .../visualisations/Visualizer.java | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/VisCommand.java b/src/main/java/seedu/financialplanner/commands/VisCommand.java index 1bd1c7a937..acfefeecbc 100644 --- a/src/main/java/seedu/financialplanner/commands/VisCommand.java +++ b/src/main/java/seedu/financialplanner/commands/VisCommand.java @@ -37,6 +37,6 @@ public VisCommand(RawCommand rawCommand) throws IllegalArgumentException { public void execute() throws FinancialPlannerException { assert !chart.isEmpty(); assert !type.isEmpty(); - Visualizer.displayChart(chart, Categorizer.sortType(CashflowList.getInstance(), type)); + Visualizer.displayChart(chart, Categorizer.sortType(CashflowList.getInstance(), type), type); } } diff --git a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java index bb5db9f272..7181d9fcd0 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java @@ -20,22 +20,22 @@ public class Visualizer { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); - public static void displayChart(String chartType, Map expensesByCat) + public static void displayChart(String chartType, Map cashFlowByCat, String type) throws FinancialPlannerException { switch (chartType) { case "pie": - displayPieChart(expensesByCat); + displayPieChart(cashFlowByCat, type); break; case "bar": - displayBarChart(expensesByCat); + displayBarChart(cashFlowByCat, type); break; default: throw new FinancialPlannerException("Chart Type Not Found"); } } - public static void displayPieChart (Map expensesByCat) { - PieChart chart = new PieChartBuilder().width(800).height(600).title("Test").build(); + public static void displayPieChart (Map expensesByCat, String type) { + PieChart chart = new PieChartBuilder().width(800).height(600).title(type).build(); // Customize Chart Color[] sliceColors = new Color[] { @@ -43,7 +43,9 @@ public static void displayPieChart (Map expensesByCat) { new Color(62, 154, 230), new Color(236, 186, 110), new Color(243, 159, 242), - new Color(246, 182, 197) + new Color(246, 182, 197), + new Color(210, 24, 24), + new Color(211, 164, 8), }; chart.getStyler().setSeriesColors(sliceColors); @@ -58,9 +60,9 @@ public static void displayPieChart (Map expensesByCat) { ); } - public static void displayBarChart (Map expensesByCat) { + public static void displayBarChart (Map expensesByCat, String type) { CategoryChart chart = new CategoryChartBuilder().width(800).height(600) - .title("Expenses").xAxisTitle("Type").yAxisTitle("Value").build(); + .title(type).xAxisTitle("Type").yAxisTitle("Value").build(); // Customize Chart chart.getStyler().setLegendPosition(Styler.LegendPosition.InsideNW); chart.getStyler().setHasAnnotations(true); From 3066e3ac34446a5739eafda8ee2f116aaf4238c0 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Tue, 24 Oct 2023 12:22:55 +0800 Subject: [PATCH 196/518] Add class UML diagram for visualization --- docs/UMLdiagrams/vis/visualisationClass.puml | 36 ++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 docs/UMLdiagrams/vis/visualisationClass.puml diff --git a/docs/UMLdiagrams/vis/visualisationClass.puml b/docs/UMLdiagrams/vis/visualisationClass.puml new file mode 100644 index 0000000000..fef51fff02 --- /dev/null +++ b/docs/UMLdiagrams/vis/visualisationClass.puml @@ -0,0 +1,36 @@ +@startuml +'https://plantuml.com/class-diagram + +abstract class Command { +execute() {abstract} +} + +class VisCommand { +String type +String chart +execute() +} + +class RawCommand { +List args +Map extraArgs +} + +class Categorizer { +sortType() +sortExpenses() +sortIncome() +} + +class Visualizer { +displayChart() +displayPieChart() +displayBarChart() +} + +Command <|-- VisCommand +RawCommand <.. VisCommand +Categorizer <.. Visualizer +Visualizer <.. VisCommand + +@enduml \ No newline at end of file From 93663628a169524515042589762b2622c091bdb3 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Tue, 24 Oct 2023 13:27:19 +0800 Subject: [PATCH 197/518] Rename directory --- docs/{UMLdiagrams => diagrams}/vis/visualisationClass.puml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/{UMLdiagrams => diagrams}/vis/visualisationClass.puml (100%) diff --git a/docs/UMLdiagrams/vis/visualisationClass.puml b/docs/diagrams/vis/visualisationClass.puml similarity index 100% rename from docs/UMLdiagrams/vis/visualisationClass.puml rename to docs/diagrams/vis/visualisationClass.puml From 96fe8e91919e5f59141946ed846c5cd4d3804c43 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 24 Oct 2023 14:43:20 +0800 Subject: [PATCH 198/518] Add class diagram for storage Add style.puml from addressbook-level3 --- docs/diagrams/Budget.puml | 1 + docs/diagrams/Storage.puml | 37 +++++++++++++++++ docs/diagrams/style.puml | 79 +++++++++++++++++++++++++++++++++++++ docs/images/Storage.png | Bin 0 -> 24273 bytes 4 files changed, 117 insertions(+) create mode 100644 docs/diagrams/Storage.puml create mode 100644 docs/diagrams/style.puml create mode 100644 docs/images/Storage.png diff --git a/docs/diagrams/Budget.puml b/docs/diagrams/Budget.puml index db63529c02..7ceb236bf9 100644 --- a/docs/diagrams/Budget.puml +++ b/docs/diagrams/Budget.puml @@ -6,6 +6,7 @@ participant Ui -> BudgetCommand: execute() BudgetCommand -> Ui: getInstance() +return ui alt set BudgetCommand -> Budget: setBudget(budget) diff --git a/docs/diagrams/Storage.puml b/docs/diagrams/Storage.puml new file mode 100644 index 0000000000..ffffa92f1e --- /dev/null +++ b/docs/diagrams/Storage.puml @@ -0,0 +1,37 @@ +@startuml +'https://plantuml.com/class-diagram +!include style.puml +skinparam ClassBackgroundColor STORAGE_COLOR + +package Storage as StoragePackage { +Class Storage +Class "{abstract]\nLoadData" as LoadData +Class "{abstract]\nSaveData" as SaveData +Class CashflowList +Class Budget +Class Cashflow +Class Expense +Class Income +Class "<>\nExpenseType" as ExpenseType +Class "<>\nIncomeType" as IncomeType +} + +Class FinancialPlanner #FFFFFF +FinancialPlanner ..> Storage + +Storage .right.-> LoadData: uses > +Storage .left.> SaveData: uses > +SaveData ..> CashflowList +SaveData ..> Budget +LoadData ..> CashflowList +LoadData ..> Budget +LoadData ..> ExpenseType +LoadData ..> IncomeType +SaveData ..> Expense +SaveData ..> Income +LoadData ..> Expense +LoadData ..> Income +Expense -down-|> Cashflow +Income -down-|> Cashflow + +@enduml \ No newline at end of file diff --git a/docs/diagrams/style.puml b/docs/diagrams/style.puml new file mode 100644 index 0000000000..ead497a169 --- /dev/null +++ b/docs/diagrams/style.puml @@ -0,0 +1,79 @@ +/' + 'Commonly used styles and colors across diagrams. + 'Refer to https://plantuml-documentation.readthedocs.io/en/latest for a more + 'comprehensive list of skinparams. + '/ + + +'T1 through T4 are shades of the original color from lightest to darkest + +!define UI_COLOR #1D8900 +!define UI_COLOR_T1 #83E769 +!define UI_COLOR_T2 #3FC71B +!define UI_COLOR_T3 #166800 +!define UI_COLOR_T4 #0E4100 + +!define LOGIC_COLOR #3333C4 +!define LOGIC_COLOR_T1 #C8C8FA +!define LOGIC_COLOR_T2 #6A6ADC +!define LOGIC_COLOR_T3 #1616B0 +!define LOGIC_COLOR_T4 #101086 + +!define MODEL_COLOR #9D0012 +!define MODEL_COLOR_T1 #F97181 +!define MODEL_COLOR_T2 #E41F36 +!define MODEL_COLOR_T3 #7B000E +!define MODEL_COLOR_T4 #51000A + +!define STORAGE_COLOR #A38300 +!define STORAGE_COLOR_T1 #FFE374 +!define STORAGE_COLOR_T2 #EDC520 +!define STORAGE_COLOR_T3 #806600 +!define STORAGE_COLOR_T2 #544400 + +!define USER_COLOR #000000 + +skinparam Package { + BackgroundColor #FFFFFF + BorderThickness 1 + FontSize 16 +} + +skinparam Class { + FontColor #FFFFFF + FontSize 15 + BorderThickness 1 + BorderColor #FFFFFF + StereotypeFontColor #FFFFFF + FontName Arial +} + +skinparam Actor { + BorderColor USER_COLOR + Color USER_COLOR + FontName Arial +} + +skinparam Sequence { + MessageAlign center + BoxFontSize 15 + BoxPadding 0 + BoxFontColor #FFFFFF + FontName Arial +} + +skinparam Participant { + FontColor #FFFFFFF + Padding 20 +} + +skinparam ArrowFontStyle bold +skinparam MinClassWidth 50 +skinparam ParticipantPadding 10 +skinparam Shadowing false +skinparam DefaultTextAlignment center +skinparam packageStyle Rectangle + +hide footbox +hide members +hide circle \ No newline at end of file diff --git a/docs/images/Storage.png b/docs/images/Storage.png new file mode 100644 index 0000000000000000000000000000000000000000..ab5cf000d52d2d61d6dec220e3f5095218db98b8 GIT binary patch literal 24273 zcmd?RWn7hSw=OyX5d{gAMnI%Px;v#qy1N_cMoJ{4OS-$eySuwXO1ksh{NH!&z1G_M zxA!@pk6(1coX_*z_dUinu5pcP`cp=L;kE@d7Rh{F}(MqrER|-+z#*`ZrC3`gENLXy% zBlHY^$cZX@xJn{&n81;6O*$5L9d@+58Q$WY5ZvWl+i@?n|LrU+Oir3U%KBa67qnD) z;amE5-qe?QSCR<{%6B_fSLrmOPNIx+l#4~B1EZw2^^BF? zbO+&7$u>8$M)Az~L7c(4%dH_!RU&!4=4|+|VHJgc4}t?Z(*li2gmP?Yf=@Qdvkdmo zZiG@OHpjEj$E@@di{n3j()JBa74oKN^wi+4gk_a768%`N&Jie7=760s{gcny7czXI z4J8f6{5KAeoy5RWWr$t#BEj8WQf>}*$AUW2Ld&~IicHgY6{~zQ#?@-3C0V1~ccNvk zs)KFa9&d~nY1#~ z4BDB%XG8nGWdpf@DbN`H^c{vGRWZ`M>|rYC?P~#&PmAhRH#Icad_F3zvbDi9Hkz&F^fp_3L_eE-htn67g85 zMs_eV2zzaTeGKW@gvQOzBDI|B@b;wsJBNKy-9A;o09E=>ETK>3S#ygM1Ph=-P z#V0YGDPw^=gP2G6IKln%kC!{of3-S%NBZX_#{Umqrs{e;TqrHWLLjN1c;O&ua!oGw z|ML|LF4zc#7wnK+%;&wx{WJ>2+XdbR;Y9;`MDdax{4oEO9Ylt16hM}YP%4a9U|S>K zzupOc=k*u*`3jI(>gV78pI-8IX)k|-K;+-`J;41iN2<(bULs;oRv1Z_$<-h^ z-R|ZD1qC_NK;U7{UP3`q`8T(=zGBc^?o304a%C?dgU>(|I_yvC?_B?t6%_w#lJG8F z-`zRxj&D`XXu9s@<>V`saBH`E_4bOOW22%@rU}4(1&84D3S2-wxS`=L<^6Y|#_RQ< zw{PF_zi2x<{sMs zxTF>U0ii_;j=dDm{FsY>g!_&vDf!QEl3p^n;c4S(Kc#`^Pl!Lt+U>=@`|Y{&#gvkk z%Pw&Q0*mFM_5%D^V`HPH>))zsi-m}s%uM~^L^k{V=_19Vd7h^mX(go@4#&gNYi@4t z%gal7|KTK#NR+pKWECHO2zB@)nh3zb!3Fl+Lm)x~+!pwSfl8R_M3AVThcY>?&Amq8H+FJjjSlpa9ehtJ^$MhvP@B{Ok5U)q8|rtE{?3>7yt=yS z85xB8mQN?4p24^r%*@O&LMZp<_LI3^E9cV$esFBr9n6L+@;u$!+H9U|^!(Z0?(Xc2 zdbnumi21B`dUiIF!XrIE({vtzQYRdWS2^G0>PXS?ccEs*^U2*t^Wp9)XDf-r(UkEw zm+K`b$!!5NB$cc)HUO?*9qlE?Ylwla54#r`HTC8B`TcPRvftCIfIrEuhu0??{JFJO zB$}QN_Nq zt;mi0HIW{|OHev-Iihd^?-TR_B7-zGHkRUXyX*OQhL3$K$Fr0r9_s^#TrPu;pTcgx z$9Z>9!FZ0rIa92W(RNE&(s;TaL^JM9OT){%7>+QioYMVJ5_8t_^dRko88$>S3$_S6 z5s0likB8f(7S9y#WY0(E>c7iPuDH0k1qua5Zih39un+ZI6e-}Jap@np zP6r?Qzy9!_lJ)!{@aO+a$pTo0Qu6KWWt|N8plm8Azbas-;u(x)^RK!1H*;jFL9fC~ z`dqd%v$Lm5v{FQ&vSB#6xNw-wMbbQlpX)w?{l3?I;^x75LRJ>Bn-_fFz%QC{{S(b& zGEhVmDhwt0;9s$?)~tBA-u*6C^9jGy7pfx#96P?z&80t05C~VU8r)`P zPvY@yr~9RzqBb`r4$%^O`wR+a;6N;m+?7_26mA4`CGV%ziy5twuNhzL>=^OUFa;xH z-??`A{1Vu0%VW4DHgLVC@FMN*Xu4>@c7*E+ zB<)>ZPO|LjF9tU7bng2_H8E5w?QqK8J^eQ`Esqx2DQ5JLiOhhWss-veF17Umf;Mfq(-x)I#H`QR*iH9{isEX1vG|Rqv+e4 z20gJcoFdaii!Gild_FHp+#FG&i!w6x)8)q~{DgL>tB7;l@^>v3>OuIsD;xSQ5Is+f0v|r}OVK+kYNffw38CBO)UE z-g*mf2pm@)Oe*gA^+xE^+#k+27+TU_*jjG3aa1*{OsD)2 zag24kgRyRP6`|ij{l1@^;1;MJa#frci>{vANDgPGv{=~YawP3<$W-o#U4G?T9W7g= z%5>{~vlZ+4a4{1R!9!a8ns2duI6KBZCrb36r$(N614+gBPfxv@)pl$k9zbZ1T^iWU zqOC4F9)+KuV54tjB-b-qX)^JQDnCh+QP|(T{AYg|<+EUgg?j+|*xK59oyKG~O+<=V zV)8}|!G3RY45Q*5*wmCuED8(!toRZ5hV=G+PBZe#qPRaPp2?^Q1qB7+S1@+WRfQZ` z5;J4D%N4t6fl!e1j$$6q;(vIFP@4v}n7H`t=`z~Iq2^T@bxvk2Ed%lC>@Up&Xuc#F z#l5O_?_f2h>O&koNOQ@BIZPlYe5RDP*hQIHX+S3^oYBz9kQ{Q6>?-h=O%c-ggI(!#CN{sLwM?p62z zRg+vlk#I)-2#F0~)KGX8)VRk^Hf8=r*~A)eUSs}Yd-D5>poPT2&cs6+uJMunP~%cX zC8a*S;_iz&_esTS&H%bbqj8&UTM)rrkKtmd_KC{x$`7t{NuLfhzRvKX+u3IX5ej7t ztk?NyWsxLDk`Qa4aVq?H(FP(bfyIhCiRR-DOp#(jax(S#2X7u8o|T0K*VWeV{963U z*i5FQ-xSfG`d~~3``Z-M%erG1SaY`kva)(Uy6J5rklE+t-kH1P>Ovq7rDntbq8XxJ z14i6JwUYaX8b4psE-=?%yDt8$X5U=?s=VBMjOL&+wwaYUe;043W8;w@+EH)7LZT^^jN97Uz9$lX z2~OPtWfzafBN1IhVJAq1Ei)uTVq?JK1DcDc7rkTP{7Ci>3IKkg)~$p&&A#phs!zH{1?E}%8JidBQ(KdCVT~qMs-Pj5oi28~ zDmOgg92ieQ&clZ|;Ykh~g)6yUh@Y>hiuyiHK;I?9Bf12_SIm)km?e2X2(P?SONqrD z`NE)1Z9d0~F7#XCYA!TLZ*MVC4ULo8yV54g#I3Ff+oovBgZV*$6w*pqiicb3zBcd& z$ph_ubG$SBw@Al^CTgl9wWR=|Y`+IjMvNH8$J>#@NwSkI0oo_~;q~i58cm0p6d~1d zKMUJ}pZ{@jXr+@@3w)v;-1pn>yM+$VHKxK~tDQ&24am4|-UUe@Tv_6;Jg6aJ_xR#r;$t-m9#3qM=szj1kr<5*hXVTd z!ZVyCs6K0{MFFE4?N2TZ0`}a8mA~~C%eEXI?jhq6lCPpkh$SVDcL+a!wg5)~c*82p zmaG$^f3;iHT-!oT6TL60`G8FHrUZ1b?Us(p#wv1(PL;Q~F#xI%7TuWY)&?r_P| zLA*Q)#o%gr;&$Z+V~{N^6Kr_+)uM!FqU4r+K#070jVZh#W%2cJX`lOGI|txZXPkhY z4LRi#dc$!g!(3M@IiploZ+rFn!MVX2_ua_=snLW%6thHao#)8-@A1scyw`Z-nwpxR zWh<+x;j!I*gP*P1S(WY17wc5^!{5hw?&RMOH#B;pXJj-}pi~lsL366JWo@r?F-KI4 z0cnLO=D>(mCJOhFd~T^VRV{KjT&%NOD+aAu61#n&=!+;Wb({K5xVzBsYUG)Zhg&|A z1Ee0qBcfE(+bb=${f^OGL57=@V$A z7Q{{zDA9oacKMP zPq>&2@41M%XZNpI{I&!RaaH;^Nf8OCL~#?-4z9sw667gMye2#%utp>e4h)GPsbiyXrh%`q40W>hSs3`gYAj z$4L3@b@j+u4+3nVubZp4H;aGbM&prWceA3-dR4YC8s0)Q!~^p zyT-t9xb=ik`jMK?onZ`|PscqROO3(f`DQ7X_zHSX>p>d78Y~gC2vnun%wf~j^8RcY zA+8B~3i7I=qyd$RP5285SLTyE7|6Lc7klgR2fN5PR*trv2*HkN;q6aLGATAy2=MUO zjK*QsN~@E3a_YJHZ)a}T!;k3Yit!f42Eb|847vV#p)PSvGM~nu>-5{H^a=CC)|=>B zx#8#gNtX8yQCF!Tk0N@HH5ECS2z+k@E}v))c94@1G#BfxwRD7YNV@QJL~XhhIY3cB z$3sZn2>eA&Ex+i$n4cF+OewiiX*AKn1OwUWaO2 zi++!b`vBTB)ss7z-r;K`>7U5d6ob^%)0ry>h=luU9+_vdGU5jr}$e%Mm;_Et+V zxfzR%>8(*ZkHgL8LHm7WV(@H*M}}A+0xT&pj*ZK*kLa-tj(QU4?!Rc#jm%Bu#KbLKXoBR~-i+|gu%+GK-bAm*um3@oZ1nJm zZg~9neb{Z+m?trQbXC5sWo8WBG9pbp#S?6>pNV)9d`VO1;teZSSyj*0L)J-Y4F zNdGZddOPXUJh!RtFlcvMXH_XqXlV?ua&6tiGDyNCE3XBg7%Ei0`` zpNv&m|1vPH8G5ZwvLvW$Iq0?wtJfmhck9quys#;XHU~=yIyg8W6#g|B&yZs@l5A;d zsos@Uv{w9thIHtHbZ~l;;_1QU)RV3hucdVhKK`N(eEe-X6ePIK)ZXi^!*=vSl8mP^ zOTgh)GL%hvoQ%|Z0nS@)#r&K599>JZdMD0aP>1gPD|H-->FaN5uyk~E42FX{i*;u} zot!AqYUv8X0IEiQ>grJq>1(vuYX62uCDt8|QgQL1xd+I|4GnEe^ErO}f7w%QC#3r3 z*IS2Ma^oYo_xbnRPbnGb?iGDqYIF$mb3eG&3TZG-{BPGwOOBoHWLTW zn1bdopRV3~PC-CNH#RU}HkJ;kfJdkOAI11xS3jR-n7d1+l7NY`9rII7MM~mFsx$Ek zmcRcl!r-=xh{Jp=v}w-)Bd1@VOBV_P#%&qdQ+bJ(dL8Tdc711{og$6TA)Mr_as-8V z1??kK{09s{zb)|+?RW3q0g;c%X1xVX@pK+!a=L=Pvx<`0!7*SZQ60 zo%=EUZbW5I<3|oQ^58a+OObTj13k2IG*T(FTD{$F9GxCC3=Gh>Z}L@f?Z|8T8xGMk zZT}2sd_YV(1hkXDN3?d$<6QFEL#p-K% z@`3mFZjO#u&$qH%asg!$3kz!;Mz-lox#4)GXn1(ITNM-p83s3%YNG&-_r~rCaHHSH z;csOj6WNj#H8uF$Znf71KF=SCiHW%c&&I*VR##vD^2Lj=Omrp)WYsDaCd$C=;+(gm z7AT-rbLGU8ltIWa6oLg){{H^dD&_jijm~ayoP{bCB;@2jZN-p9E`G~oq^GAhxn7O; zjh7pU=hI&`zku+@X9mqIA(Jb@MMa@H4?4@byq3vxrYY!{kwIo;eDmhb2QHV&q@<-< zn+;2V)gzIlM)qhlQC+$zTlgSbL%(xmfE*tp}0_|m=VTsFY zj9@!?k&WSwYIf$VBoq)FJZW0hh(QLkw~c^+;9Qaz#tRhFs-PfoKmuW)p|7>MP|cVY zg{vn;O-z24eOjHbGIMrzZp477@n5jF5`nm&QL7HV!iKXDNjTHYP$|>x!uPxxCJ!m@4-QLD8A=fJ1lptx0AE;7(u@) zi=)g+ud$=a4zi>HDm&HJ)zJ`PQQCdpNoeEDxL==W?JefOIs?$N{ z&W#B%gJWN9V{jb$%@h<6unH6G!<;!(K%Wy-tFEj7o1GnF?p9Q=>SOAE?pY3mc=;1ksRX%CjWz4WRr5kY=zX`)ZD6Xj znwOi8f``{^w>$og>TempbWOG@U}G2dWe21hXn)# z0K{Z6pDhK^w!FM-n0!$DL04B7gx1w=P71|w&5!jBfLSCQdeIDyJl=< z#iQF9Fghv&LdzZ+H`NYA3y1xl-Sx2!H}A{byA{ADy`W%r#EjZU<|)7?e%Q+;kxpI& zn+sYt$={47;F%{6+&IlLYinnT7@*Aq!9Xwsheh$B3LZlCVh4g|eR(hk24!GAK4aLR zPfA3judm$Zx)rRu*6s&}V_Fr4L*V__v=x!b$<5!k`hn_x3PlgbKI?mXrqwh!P>`tC zc3$kM1ii>S_q-Vj6WqNPW@I<8L2GMk?XHlP+r0wuSn89u>}@ar1ic^vI+e_~1o?pU z^iTP}`tZLMqR>kkyx>(#g_-OGfB?3A$*SdH`qR^ju#nJm%h?w}obM_HurN4qslsUF zI}F^Z4!rhAG8a&sbE=v8Tp=NAV6UvLty#ZqzQRv61S;U}+LBG(IIG1xT*BtzI~f6)-cQa(*=gD^!9u5uC8~|JP(sIGfI8Z!m@L@o=LPi z(DqJX-1GoWNGg#vZ4jD9qyBug&1V}ccEZ|uvDOB}QnULVGk&&5E}}^&GA3>7Cw`TW zWMsy@VFV%AOure7e(j+$luDY*!`0T+_1W!5M=ra+w@h~w(Bh$i0Q4w1bBF`<=*$ThbqV4bNE1N7@g%3|iaNQonS~i<{m7=oV zL@)5p8i?8;Y4ZD(cqI5WHIv^-p+Mf~1+i=2oNj?pBH9rXZWOBl2m)V!?ihE@{!d`7 zdO*E*zq>3_Dp{VZFuKtu<`V*2Y6<|1;z30`db~`phf=BdSo4OQis}Q~H+^||RFJ!2 z+P3Uo{;!Uj?~2`y^gmNR^-~z=43`C@q-Yf=7NL$~bocZ;j|R5-qsht1-QvhoJ+_{S z1Ylr*nB+*rzr)1LolStUd-H1Lqvd#JpEoRmxrK4=n6c?hvBlio89WgOhbtH?mV118 z;RUZ_%ig-O(gOCUab{8mJ?iaIbRSHH3Qz3IXBMn*?7dE8$EHs|N-d#n=!O4dwA$3_P-57Bqo zpDY7_k1W^Q2VLdE515vtQ7W>svnO*pM|_-kL2VJg#^Cd=JL&W}vQsnDmu) zg&^pvv43P>r~vSza9^KF2i6uY)C^~Pyvj#PN-ETJ&Il%e*LYl{q(9^*W3@a)XL_W$ zZ+wwoehEuT;&QvTmev0G^QT)JRy@5yKM;MLX`JE!Mu#EMjs$f;jsCRQh2VTY?*T-_ zsbpORXcH|S4}haQgOlZQqsnK(Ouz{J5HK8e$GbRbAWlSJi|uV};z2)<^%$%jhC=tG z59JPKZ!Rt_rs8x}CN4Y=sdrzV>TCi>a=;@sT3Th(bZ44#1J26)BoUAGtuo1D{SD z&ffLJ#DvND2TaUsaF7dgbCQXyCjemFIAPzTpp1fJX116w)N0`dJAz#OVKN^Oghq@g zf%;5Pq139)*I-clrV5mBm`oY%c1BZEKXSi;L_*_gQ>xe7^_5GLOei>k(+2og0s9SMHNb)GMmlRim_arI6^n9{t{y%- zC8fpn%5u2?GcYJjVRr*y_xFcyP9YA}|eYv9kIpu3YE{Aa1(?fMur1l-C{nVFgA`!ml> z-wn)SLPe5Dmanov$jvAqM^$9)A>TpEb_NywiJaU7Br(`SFv%R~?_c*Rc!@X< zM9MiJya6r&&gl0V0qf<`ELZ}i!{MhsRwJW7un6d6XC7YhLJ6PWzk5fo*Bv}NtIQ37 zWR!W}hJpFS$_#7>-!(J=nh$a*nZi-2)nYB*yByc6Lqu#w&~AX?K+1xaqdWKG;mro;E?(&Qq6xL4!MI~lrM+D0YO(XjTRAxSr@mef@3r^ko)Boc9~HtA&P?*OubqWvp;0_p7Z z6f_H?fQ5oS?o_80m6eT+{Qeg#TwV-`{|q9!++>2pUHZDGt7|BcZ36Ie z(8~5ZUo=JAJUzOb>MR#Hfv6TgB_<*9M=phzm6bhDLWL;TAwkd#084om5ueA%OG}?m zn>s1pp`tRnoEyv1YJrjD);qz*q%P?TY@ITPtv~ z*C;O!zeACaLV1xgG1<5Kz6J&dcGpWP{OotR@Sxs+1_k46ly#(|L!hq$k_pO`;Ekhh zrc7*wb{q6^!Mkenxp9!3zP>NGc^^j01n;tJHoBh;9%~&x#KpyLFk2PBBb9yy+aS)B z<>2-$S&5YdKfb$bLe7Dv0b#G62FNmF& z#aj%F8j$*c3_rK}fXM^e=l15p7E~t?!Y9iuv(*-AVq)+|3h(4Of$!z<;ZE&13xoOB z=Uy#N)Yq7!P}S`qZ`d6V4|aA~4f>vNqKivQ!)~uZd;)6T+P|ey2}`Ce*Qs$Pv-hg?ESbyI<9ZEFsHx}x)Sl-=<#u-=Hgp3$(M`iqbH!>6 zDJuvE)H@*p-DNTUgNhUByi;l^auehB_f?xzY(e*B9TH?P77|464RxhX@ zNVw(w2?4ypXnT;oT+lK0yGFl23x)4m!AX(j}0*0dbQQd3o>yDRb#bsI9-(R z!4p{}3O70y}5a;!|MkGuGF^lz-AXIA@|K4 zW)>Dl5O9Dulvh+_*d86Pb-2CR_Y)j{w(dOMJ9D@4W75pOY1Kr{O>~J511$yRy`HK< zW@>7x)k<@w*bQW10}usJSn|&0aZ|~_m`@pt@f4U?KsGbtp?M-HujS_ED&+7>rD za?3vDMLj)UwSZG^oT)FZ%7I1f&|K2#y83PowFBAucDgAVpZ(Mae_<<^Es-}W?+qFo zCXYG4df#lx1SHTCtgNiWwR~1A(X{BIfd`Tbusie(3~a!7RSA%`0}kR$BLl>>z}DZz z$#ZjapqQF2H?r+wa!Wvm1TQTve!#^A+K>^q1R^N=AWs1aw*ct}maygO6M5P8fE)b`)j=zDd?SP3 z2Mao!egI#CXOJOY9i6mq&5DpgpYsewK)AO!tAGCZ(F2$~0QNh8C^%>Q-Ig$)oke+;K%ycMe4u{U^JY#*2L>k$Om_Qdy548Qdbn1 zAzuhJv)bj*I`L9XMb_P(9+kbj>^`{B`BT!QP5gL`C(US99U5mT}0$%MW%TN;& z5TpSN2SQ$*lOQH8?&rqe)}yI>P*6~{(%J^2kM?$U`bq@jPy+sMoLS*%1HrB`n@;Wk zs_zB~dq1`B1=^>^yTgXS`qJ#|?B_HB{!aip-4Z$3UTV7xYK z6{+?AW^4QGb3?ljk}D9tU|$7x6wPXLtfQ(IU@+(5;Q zJUl!=&sh-F$lTYh3kzz0Y>`h+PBM{=-OL9w1Sq^a@$HWR+uVX70!%^_pIVOT2Qq&3 zbdQETKiuWb*&iS^5fT#4MN;eN=n%mICL;h>*JmEiLWn)RaBY3ZtFUl1*B8jrl+m_smH_P2*nGp=V&|3BmcZzOFm? z@UDs%H|?(k`s%VjqkeA~V4p!;)x36g=KvnW1)hK&8j4A$+vW`mrjMC#MBpa#74`w& z+hBpz1Jj!(D0HCSfwO6LJklIj0Cggr`B?(a^m3L-L3)LRWH`_Q>P@C-q~Lc7e~M3! z&}p^5DcY~qJ__>kLJ(7phJJT(v66rJ`gGk3e^F@n<^zXAA-{z&`7eAP>g1RF9V@l9 ztY2#p`OtExQ@Ts02AqMx&DRewlZ_InjkJvv>Q{_W>1NQMD=n9P&mSi_E`LX*h1r{c z+UN;28UTshWV7K^cp zIQ|hmlWNiQ(oz$Mrq8OC%GKs7fM4JXi2C~Z)z#I#9;kc|&|IECYtu)541fwiW-U-$ z_~3wPd9~!b7z$9{0S`Byr8N~W9RxZ(AAE1ftsO52Kn8kxCo6-z(V*vI#SQ@VO9*zj zaY#tWmX9QyLRfyE>sC+ibgFnVfCAv^(~|p10CR*~2Lkl|=FGWdj_!{|4q(NvtyG^S za$O#Akse6&G0;5?w(#4pcQQhiWjs8Z-(@Cb0gJ2q5g6<`Z6NM-ynKV%3J2o@tand8 z@I7)h8kqCQ_@tU{wiE0!!NUdK+Cgx!z-qUeqSryS>2~91WMHrb4H=`1*>vF?@H8GR z)^+sIGRgDhlN?23>8TO|ws^AM1!OKfdi_@+lQ-H}WE2$XP<*<&pYXN6dFgCQ7a3B|;t% zu-RmqU0Ep@>6mh*h$ssIt!HNPa$nz1f3+0%ODql3=Wo!kC!1J*TkpNZ`5NkUi1|w1 zh z^azYLd-s5KQS84`ezO|^4(s)RM!j7cfp^vy7yv+(KE6wQ{G&rdA;pR@?tv3PmHQJJ zO+*HQlg6W8P;p21VOq_q%5v!z;2II4a0s?g(K*%gGLL?cf=bA!EDJ_4`d02-9q0cP(lE)ioymJi*3As^mRW#y9v$` zy^O<@-(6i@2B({SfX`+L1pHD@=2L|D1*RQ6u&g~#@r7<3EE_}r+b)+zjUf{@| zgqj-2`BQB?=1uJkYF6Q>La4vvvlmyRq5616gOBffPL5Fux4SW~#6|)zr;G6f>b=Yb zh@Ow65SULg86HXmBR>aFLw1Q=&JQ-o?f@-O)DIsdyvLsxli_#!$g=Dt5JxTy zSE`$0${2jE3(sKghS2|$(J@YELv8fcWIoJ`+^hW2i{i>kJJ2j%45XFeUN|!rr^D_& zeqKKNDijBevZ@z{Z5jf)4Gwm8*^x1DKhRk-S}tA#114a(DP3v;USik4RCy2Vv6B-r zE7QRC!q6i15w!QGXbwO4=LIF6J6LFRQ{wGRDE7ZH>@gJQ(kfdhk92vO9we%lSikZ= zHbu0*!CCSC_Gt*$aP}IV5gKjZ3t0H&&&96JMtCMr0;?^i@~56Bgn| zCQBLiMq7>nsQy5O>ksHeL8N@H4smgq+!4g7cr5hv<1;g{nSJ2v6(ozc+226(Z4Jtc zn>icM<+&Dcb&U@=fcym7D{>ugby3lu*Jv@BZ+xGkfx4+N_C7P+?R-p_-zV%N?G%yh z8R7r(kP4uCL8CZH&I9pMwl;~BWF?6*?j^oQ|IcJfp@*-q#K9IOf|bB8;IVSQmCgCX5?VZMkJ#Q zqqxqPhXOi-Z1ugFlB11{jvsk&yV0o6I~Dcb_tVvg5+1uPP?JC}d zwlm1_FaSpF@pxBs-+U6zxNf*OBvV9JS63TSr3V^&pp!bmSY6N|gOmr;0)VODYf?16 zIlRUzW6AFxZytfPcZ0Z@22_0CRxsGs_6&-n?ykF__OIntMqI5{aVD+Dr$d1~ls{GEl) z_uZ{*TB{f&Z4a8j+)i>mqDnI$of^$!yp$1$j*7eZ`erv;{;z|Zl2$d9Fzn4gJ7&rP z3(RA7ysGOrvjc~~jZOMlcj|9W*@#F|Xr%>cnEx_l*5o$qn(s@>xA=rv|e9exks^rWrHz6z#O;Vs^mpT-5jz!&f;`5de z8Ax@AY>@p|-c=k%RoE04~vf*$%rfe=OPn-RM@{*pLmJ!c760x&lNP#Ql~Sv1z}j8$MpU3lf4 zMoy(`Xz8GG^rF`&+7&}AYwa5{aM$@J+;t&%`~5eI;R{j=57Q$fwp}{;)rg4n)Fgbm z7FNk>F@*06+`SS%smQ4Z#hShh-(tX-ea~{Z z(NS+YOg|BaG+Q@@yi{f#W&id1Gdv|QHJfY-{%%kWF8P@laF%7}(%m#*hh~W2{dB(E zM%n~tnV=Susi1$nj_{+!U`wJNP1&Pi|74@#c0Bs`P2FCppR1#kY&k&f7R+ldjq|*b zW0g6tdZ?4_m*qiC2Zwd5T}_mG*6q+bh#N2VkNA2Y^M^@vRte4Ghz_ZhF66f^*qg$rJ^PLw5j?Cpa z0x*<6RJ74QADqPzFI;Z`qoWX(mO5Mbwq->(O9(*JzlP|2%_b6>;=}!8u^LQ zt{p{h13rG!h^IS)$w@Gy$+|b}-vfajHNHbG5RiL8dX2l{d?_jM{J(f%Zo~!(Uu=kz zldik@@g(El6W`BxuS!cJEmWLaByCOBQC!{?mQL)ll$z>0z}EFOENNoIToqYnGGJ6E z#@MyFI^*g%&qR3c2UBS>{pA^r{-Vx&fLm=k-=v3x+ZrQ!B%@H0qGm&A-c)ND%4qWm zjegf(oz0+&mo7^C`J@u9B(AeJYg2s^7M!V_Y-ZM<5D>4^OFurec2AGL!`4$@AM`ac zgZ)`V^Xo)$7c~=ydy)23x0XnZxtZi!yFt;}&-1W{Cj^dL7~C@8Pp3TCnarFeEKF1{ z^Yc6HC<(ng=*deE4R$|HlIS?8Qy{F!Slb2;UK8`ZmSHwv^+w2Q%R0*UZ}2RjUM8CL z489g+l=R3SW}M46Nf9YwTz6Y4bKIQcFr0$&{`ycQRF^nWD*B#oJQL^JRumdcmyGvG zSM>Xs-IJwa@{_i8&&EakL?u073?=-WMn@v0o}#7oVWViAT!h6fS3|$sS~SYsP4YRP zCxJ=%t&IzwMpD)Pusuf0eF!On4|Rx*iP6u}K%O5O$vrv7t@m&6TDn+=VH4R+Q< z-5+#W0^Uea6!mi|#RPz)Ct2kDNS&-rgfRP=J1Np~>8XB1TJ)>Ny47_>kIMkw;2dsJ zG&XTDM=TSi*YIVg-p{423|*N`pM>T2ihVR63f3tCLT>EQLn&V_beiu_}Es9D}7N zpN(ID(*a*tng{6dj^iMm5DBfMThoCwzS_c)X%DT_QGWQ~?*6oI4xroW{Yw(NzzGaa zLjlzidag)5pNAfq1Sb%Az^({MEZMeGJ5s;9v9E(6LUi>|U0r zIfs6w41YnC_W7FpWK&Jp@5he|$+w0B>(6L;DN9(-6}~XdV&&ZOT!hBPr+!&0RWW1 z{+`_r)({y@(6BSU95yMEZz6(PW~2vg>fvpq7$wh0v=9RhmE7Jt5v0H%oz~7sOOwf7 zB%HFZ>qPKf1&iKJDn_pUFWqb&?!~T74|*#cZ#evJOxkBzZrk^?pT^Wpb@e=8x*}Z$ z{poJt)A+BXAKdFc8uv24UYwQ$!&J>5OWhNW>e0JwjTcP6n(cfohWsnF|6yeS6n|hb zH^YXseqi_d?0SDXdAMRa`Z4q+*0{_`el=OBKWaNYVtALwbkL|%_zj}O4r&gK)1W`A zTy?4~J=v5v=hx`?6R-xxf3E?1m=s=|lCWIhEaLSG)cOogs zA365sG?YhKcBdcse*6{8IK$D|H<^6wRTI%BI=O})&nOpH3R_12R znROliwZTBxft0MQpsuVKdYo`dNqSJY+U*1Q9rS!U#9}5q1K=}gwdpI>rpKJwg~HKQ zU?Pg4{6th8C`GZQ_#bQNalB~qykfkXOLH&4Da*^eC0Pm_@&y0ohwWRt+qv@QONm-6 z>&N5F!pi-23UZ&t!P-*22|x|S!4XJ-BzcWj(Y7@ZEok0cfSpZ}yij%hBm(*Qguz;x z7gE}ISF?9B_qx5jd80q>Lsv)!4X%z_1;NmgHC86wXEV1OK@mdW>o@-gSc8KN@ir(w z@?)zYZP+qFSL{LRZ(V5$>>uv?L1}-->B+_0IkM5{K18{G&WRl)b02kGG3eRvDsz2; z&-JHewW-j-l>gP)e!?hua$aA*9&=~>H-tqBMDNfehb88tI^33K^m0#gQ~uo5lATOh zO9icpQe#7bM61Oq+}A9~2TvKWA+UKkte(c7F5n7}W>|J(>a9(&)~xOTpWJoBlWC;5 ztT1r@E2`lEI3ck1&yuY57@=X9<(iLAc3$?blW)F4#ZWLsPJS=JNqS#()X<+iOm&&~ z@$&?m@+0dW>SbJh^M;t#uUl+kE%x?mLjiTeq%EcJ_?*FiG3z`mtf70uaPMbi+#ZE` z!~SH_D>S3U{9%$M)b_4jDV?SeeC2I4n*F@h$;LZYdYF1pdY~_WYo8_Xp(WLdKgTIM zyOQ%8;c%2%SRuF61t1gBS(5+yx{!Cvw@9(M{ANR)F_4*B6jRS%<6A+PLEqXk=;`sb zI=y}PjGk{b{ud?-(>9=fs{9m2)ag+@7gmWpFXi*T*$AlfUw^N|Ve~&mkP(-)%Z7cD zQqej={q_R8cc#g0c@=9#hicm-CCz;KBYE0=V&{D#(YW*h543wvbl7iJVI4lLjU92} z*=h5Dfx?P=3i`9C_#g(Kd!K#I=lpTbpR9Ly=I43u>w8~yv{yoktK9}((pDTEw{&{;c&043QuaW*bXI-h zP?toi?(@(;GSnqv(yr<|J;J9_c7~nvWZX?R5u-s-&FXaW__^y3k$pG{cNI*T%B-e$ zuW{aMoFBs7e0=lya)*fKGVKi^dGi;xx@h&qgzR{8rfeT4W4vRbW8UMc;~>e;zsd)j2YZLk5{HM>wnwoXzZ4wKFxZ7A($4;4R!T^lmicea!Mdt7(8*Mk^%k ztUOivu&dR5PY&}9uh7lp!TNtZstr{JeQSPygJgKcqF z`FyCh@4lvm5+&O+kDITQfBN~@bt-yxcbd3tvsP5JlxlBqGIi6rJwm1PE3ekJXvbn1%=mYtPhb@kv3M-vIU+u_oeCgG9qF*hwr|g6(TIOoZ_$d#GYTBD=1#0 zWY}9h=^{)v&d%q@Zp%EiKcXZil2&N@j#Zhy^zG1ViPVxDjg>b3#F9?N>R;#Z-B}lH zHq@fH;@@xb(+t_{b^BP}4e88G1H1T^S35MbSb3l5$1wGlr)zAk%@bWdThv`%ZYBQX zCEdZk|9AwcFE=%zTi z?l#R3*Emty5mRAE!(r&`R1hn-ME|X(^(rGfEs8N2 zV|!0rE#2^=CG*xg?;ty9ol3R)3no?fSTFgc<{);rf)5vV2uoO4g^wmrxAw?n)Ws*d zA1``hoyEssFp}4Mha>M>uTRw@S3&TMLGsn~lXqg3PXGtg@*SD$XD*QVkWfZD-$l{)g4ORgZgIV-FZP{{Ht<9mSvesnp~3ZD2w64}ueT2+f@y9tG#mw}70T zBf7Q*%bp>RO@Ezs+bNnSi;9XMQ-O4xBOGYJxwN#jKyoDT6zgJ4pUz)YlX;rzeY~zG zKX0!WK2SS3p;%>_EJEeR4Ni0O^P2_Lk;RG)_-lcO)Pt-#e_Qt&k?d^O;4h*fx!0}k z<8#_!>!XH-JBK@5f#qgrzYj6uvJgak+!JB6ZQEER9qLKup52}r?p|io@0FwIFtO*f z@wmhY(IqV-lWCr&he$NteO;(%@eyNVV+cae;E_WTE!>1dJ<23*U|;|(1kK}iPk#AQ;09rWySUY;Cj%q zFiFuPtoe|i!T+9pAcL2nnt^pohJXv@2*myrrAD#**wl3zjaFHy4HlF*0etNvq(MNv z-3aaT5Q@V9-d8cA#W&W$&4dcaB#Xd_o(GT@`w+@}c0_s7alaHh#97d~oIE_k@Sy5* zOlPiP#uNaX@CFJH38iu8oukv~2gB#H5e7wk7~_x7XYwcJXrO0-Y6XsVBAF=`$sH$6 zIZe&YhsobX+9`d%yezOeHTyI_zMwz}uua>h#j5mlDi2-*V+!ILv_tI;8(7%b7!>{5 zRdRBHBkhg=b!26Q79MjDHHol>(kegNAA#H%Krr(}x*@s%UNlHyX-0i&GO5dmiu=&( zLna^JQsELgblkULQCqNhB;gP7T!tNaZe?1586@@xb z&%rtB!Xbcqz`&O*T{^@}ecjyFCaLLR4LZ!v*B5C6VC&l{HP#Uk5#r+Fp`oD|rrXh! zdfz7Nmk7x9$Ll`GhF4(DxF*MqA^XfG26`I_Vd~8G$OlZ_7$P7tpbKQdc z1H}4gzR&hLS+WuOUg^x#!-jt@A(P=Liu^(_m8hIhK|TxFb<0rzxvfAYSL#+^%3Zl~ zB~(-`8j9J!hdx0_f$6A;k55c&y{7vW(k0Te2J34w;m{(-cNEMBSyN|bpsd%F?e3Cm zZu!xZJj559`@Y!_rhxj);er@}5kiU!@X@-mPhbz2si#p?AV~qEoqVb;Ohl3-eiwnU z*t#0~QrD%D#5O@eL2gOC?iVk9)z(fSNAf&6Nj)wp$*{f~Q{m7;iW$A5V{J1N;b4Pm zR)LC|ndm(MU>&JDp-G+sA|kJ#@Pjb}r_6AKO%IR~>L@Zhz)?cE{R9LsG^x<{16>w9 z2C`$Cf@==onkz^B{Cw+WBuR;7oE*wYSf3p9u%d1K-b?bB$Ph}}b9`#R zfNTXN3c6wq2o8+X*Rau$bYLc%?W*>xh6Ywu8zw>?Ny`pi;9_m>dFjG);wNbZgmph~ z7+}Ej7|6xqXl|zBOZ-B@!VJfkhE`TDAqnXmdc<*YdwnFVkPOfci6?^}ft(71r~*|x zG$|l9CZ-)*3(%JM`1nb(wue!Z23|em=V%1T4pWXVw*Wo+bB83T>gal5SBN;#(a~7m z2brI@VMD<5`S$G_*<}{oC{S(O6*FOArN1VE@N~ z#Uka`-@qKI>!qg_7Z*c4e_I`v!c#21M^rJcx{aj`Bwj;%*vj3m<`qE5~Bp6G3C9PU?EVg~NH)gT!&0c3J#WCW;+ub;=Xecu^A;b9^2 zSW#vraK*W%DKD|5%*`E(V?_?2U733q%BtD5oHFrWctD{Sy}e znwNQY1!6WQNpcVte6VSX0wkIE;&Iwrd;O zlY+}LLSZ8Z5q@AHOyp97aztwgKPH8D)zt5v;p<@I7l>Ztw<&Yqh26-%Rmgeq=`@Am z)VKVMtVtr0(n%7NY(f`!7Ya6li^9&9y_>4sC#(rkPgl3DNMlhjfeE=;{80as(eG<{?=fC~n1cn#^D4PMwCb-SWD0cYUaJKHv3Q}~>hG*DY?0NWVB3ynM zvwGnk3QOc4Pr{$O|381Wk-7Yv?Dizt#{_NC3r<`7;!5AJJ-KzJIU?{gHgmRZOFJdbDPjmuNUIc76?NGsHa?Ob+HAJebP4e4hd)o)UW2=4?pE=@fSN zq}G5E1fIFrXK&>N%~qHn2n;pyadb6)S0eF%<>Aq^G|LuPhCJ+l=zWLzbJnvB~mRO=&$(cb;QG}OA}kU;IY8{dXwg0 z`02jf8Jf4m+sf-I%96b=E?-}}$%Lkywn^uM?b)u+tg6RbPb}2+dk@|kml`hQXruKo zpW%qDHKEf~-&U3Fveq5amH&KO+k^#a4cL+_gbOwWs!p`tTVRxRI@R2LT8LCbMWx>u zmS$t$cZx;Qdn>PBJCw}$j&z*O@ux%;h6`O4MG`;3+OQ}p-&(MV6``lP7 zDf5{#FKQPuZOEz2Nsd#8?`xM|oCs2$ztkynhk1p)O4{5NwvP}&J*G3eLfU;pXR6b$ zhDDHJ)#eZA{wc+KQU~Dnz+t{D?)W!`U?DxC*S7IO$mO>NnTzE&yV|~7^i_SewC)7^ zmcPH_H4JL#!^}<5!GR*eKV5`QRrLQf5mM;s_AV5-*y??{Fn5=B<@%cJHmip4yZf`6 z4{14k>~>>$*qFK+;m;tY;7>hcgOPX3R=33#+V37XMFv27!#)ox@nM{>lH;U!q4U8v z)o)*e%+K$bbpC3!{(6tSwMvs|&)8?JX}=V%_YYgI%-`qG`tGq&`9s7kL#vJfn-SNA z(l_~{s>P=5CaA|9fnZ@7R@YjQH?J0&c6TjEW&cz+)5$}0hIx{vMDVMW4 zvZQ(wtY@GrDV){%I`huN!|z{pTR&eCTDZ&eW04&u-agNttjn3tF1uTz-q{ z%l8L$7!qBpzReX399o)Sn#zIWD869Rm8|!H7rjfW5#JA#-<4NY)z*^>r9m|?Kbjo6G(ou1I%|jeIJ>TjAz2;IVhqttI}`3k@Vnt2cQaoMs$+wP#YY zyE~dLxT)M?;qo?xC?TJ}`o%u~#>FBb>>NVmo3p}hi2Wb`l)|0`+ZYDvty(y?>HY7RcuIE8Q|GTAey_z83 Date: Tue, 24 Oct 2023 16:03:47 +0800 Subject: [PATCH 199/518] Add acknowledgements to DG --- docs/DeveloperGuide.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 64e1f0ed2b..c9a180fb88 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -1,6 +1,12 @@ # Developer Guide ## Acknowledgements +- **round() method in Cashflow.java** + - author: mhadidg + - source: https://stackoverflow.com/questions/2808535/round-a-double-to-2-decimal-places +- **capitalize() method in Cashflow.java** + - author: Nick Bolton + - source: https://stackoverflow.com/questions/1892765/how-to-capitalize-the-first-character-of-each-word-in-a-string {list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well} From 98db3870b2a1642d81b534a75b87f89cbb095ed1 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 24 Oct 2023 16:08:21 +0800 Subject: [PATCH 200/518] Update DG and diagrams Fixes #106 --- docs/DeveloperGuide.md | 53 ++++++++++++++++++++++++++++++-- docs/diagrams/Budget.puml | 2 +- docs/diagrams/Storage.puml | 4 ++- docs/diagrams/deleteBudget.puml | 1 + docs/diagrams/resetBudget.puml | 1 + docs/diagrams/viewBudget.puml | 1 + docs/images/Budget.png | Bin 22867 -> 21328 bytes docs/images/deleteBudget.png | Bin 12058 -> 10085 bytes docs/images/resetBudget.png | Bin 18916 -> 16780 bytes docs/images/viewBudget.png | Bin 11256 -> 9357 bytes 10 files changed, 58 insertions(+), 4 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 64e1f0ed2b..b4b4154b6d 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -1,13 +1,62 @@ # Developer Guide ## Acknowledgements - -{list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well} +[Addressbook-level3](https://github.com/se-edu/addressbook-level3) ## Design & implementation {Describe the design and implementation of the product. Use UML diagrams and short code snippets where applicable.} +### Storage Component +API: `Storage.java` +![](images/Storage.png) +- The storage component loads data from the saved text files when the application starts, and saves the data to the +text files when the application exits. +- The storage class uses the static methods in LoadData and SaveData to load and save data respectively. +- The `load` method in LoadData reads the `data.txt` file and loads any existing Income, Expense and Budget into the application. +- The `save` method in SaveData saves all Incomes, Expenses and existing Budget into the `data.txt` file. + +### Budget Feature +This feature has 5 functions, `set`, `update`, `delete`, `reset`, and `view`. +![](images/Budget.png) + +The BudgetCommand will execute the appropriate command and print through `Budget.java` and prints any message to the user through `Ui.java`. + +**Set and update budget:** + +Example: +``` +budget set /b 500 +budget update /b 1000 +``` +The '/b' is followed by the budget amount. The first line will set the budget by calling `setBudget(500)` method in `Budget.java`. +The second line updates the budget by adding or subtracting the difference between the initial and updated amount to the +initial and current budget. This is done through `updateBudget(500)` method in `Budget.java`. Both functions can be seen +in the diagram above + +**Delete budget:** + +![](images/deleteBudget.png) + +The budget will be deleted by setting the initial and current budget to 0 through the `deleteBudget()` method in `Budget.java`. + +Example: `budget delete` + +**Reset budget:** + +![](images/resetBudget.png) + +The budget will be reset by resetting the current budget to the initial budget through the `resetBudget()` method in `Budget.java`. + +Example : `budget reset` + +**View budget:** + +![](images/viewBudget.png) + +The current budget will be shown to the user through the `Ui`. + +Example: `budget view` ## Product scope ### Target user profile diff --git a/docs/diagrams/Budget.puml b/docs/diagrams/Budget.puml index 7ceb236bf9..fb2592258a 100644 --- a/docs/diagrams/Budget.puml +++ b/docs/diagrams/Budget.puml @@ -24,5 +24,5 @@ else view else invalid command end - +hide footbox @enduml \ No newline at end of file diff --git a/docs/diagrams/Storage.puml b/docs/diagrams/Storage.puml index ffffa92f1e..f363171d35 100644 --- a/docs/diagrams/Storage.puml +++ b/docs/diagrams/Storage.puml @@ -14,10 +14,11 @@ Class Expense Class Income Class "<>\nExpenseType" as ExpenseType Class "<>\nIncomeType" as IncomeType +Class Ui } Class FinancialPlanner #FFFFFF -FinancialPlanner ..> Storage +FinancialPlanner --> Storage Storage .right.-> LoadData: uses > Storage .left.> SaveData: uses > @@ -31,6 +32,7 @@ SaveData ..> Expense SaveData ..> Income LoadData ..> Expense LoadData ..> Income +LoadData -right-> Ui: prints message > Expense -down-|> Cashflow Income -down-|> Cashflow diff --git a/docs/diagrams/deleteBudget.puml b/docs/diagrams/deleteBudget.puml index 587d2b032d..988af8e5ae 100644 --- a/docs/diagrams/deleteBudget.puml +++ b/docs/diagrams/deleteBudget.puml @@ -12,4 +12,5 @@ else else BudgetCommand -> Ui: printErrorMessage() end +hide footbox @enduml \ No newline at end of file diff --git a/docs/diagrams/resetBudget.puml b/docs/diagrams/resetBudget.puml index 116d46680c..cbaa8a69f2 100644 --- a/docs/diagrams/resetBudget.puml +++ b/docs/diagrams/resetBudget.puml @@ -16,4 +16,5 @@ else else BudgetCommand -> Ui: printErrorMessage() end +hide footbox @enduml \ No newline at end of file diff --git a/docs/diagrams/viewBudget.puml b/docs/diagrams/viewBudget.puml index 2200b8b453..70bab0c57f 100644 --- a/docs/diagrams/viewBudget.puml +++ b/docs/diagrams/viewBudget.puml @@ -11,4 +11,5 @@ else else BudgetCommand -> Ui: printErrorMessage() end +hide footbox @enduml \ No newline at end of file diff --git a/docs/images/Budget.png b/docs/images/Budget.png index 569908ac3b95fe43fcb9c004565fc699b43676b3..05e51a22966f16a2552bcbcdade2f17c81169690 100644 GIT binary patch literal 21328 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 diff --git a/docs/images/deleteBudget.png b/docs/images/deleteBudget.png index 9a7bdb6f7dcaeb69968ef5dd6664956574048b94..93474c9bc7651193924d237f626e8da2376916ad 100644 GIT binary patch literal 10085 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 literal 18916 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 BO&b6J diff --git a/docs/images/viewBudget.png b/docs/images/viewBudget.png index d2723288b28d474bb1d3722dd71d3e2a9c2109da..f33d1d9f93c601560ba1d4dfe829d615e3f2afa2 100644 GIT binary patch literal 9357 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�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 Y_NPI$tmsYP|ANp|6g1@D%bErMFV${;`2YX_ literal 11256 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 Date: Tue, 24 Oct 2023 18:51:30 +0800 Subject: [PATCH 201/518] Add sequence diagram for add cashflow mechanism --- docs/AddCashflowSequence.puml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 docs/AddCashflowSequence.puml diff --git a/docs/AddCashflowSequence.puml b/docs/AddCashflowSequence.puml new file mode 100644 index 0000000000..8a986f5a36 --- /dev/null +++ b/docs/AddCashflowSequence.puml @@ -0,0 +1,28 @@ +@startuml + +participant AddCashflowCommand +participant CashflowList +participant Ui +participant Income +participant Expense + +-> AddCashflowCommand: execute() +AddCashflowCommand -> CashflowList: getInstance() +AddCashflowCommand -> Ui: getInstance() +alt income + create Income + AddCashflowCommand -> Income: addIncome(amount, incomeType, recur) + Income -> Income: addIncomeValue() + AddCashflowCommand -> CashflowList: add(toAdd) + AddCashflowCommand -> Ui: printAddedCashflow(toAdd) +else expense + create Expense + AddCashflowCommand -> Expense: addExpense(amount, incomeType, recur) + Expense -> Expense: addExpenseValue() + AddCashflowCommand -> CashflowList: add(toAdd) + AddCashflowCommand -> Ui: printAddedCashflow(toAdd) +else invalid command +end + +hide footbox +@enduml \ No newline at end of file From 01676b3ebdeabe3ceece220b3e009399c5709201 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Tue, 24 Oct 2023 19:26:58 +0800 Subject: [PATCH 202/518] Add Class diagram for Visualization feature --- ...shot 2023-10-24 113526.png => visOutput.png} | Bin docs/images/vis/visualisationClass.png | Bin 0 -> 22498 bytes 2 files changed, 0 insertions(+), 0 deletions(-) rename docs/images/vis/{Screenshot 2023-10-24 113526.png => visOutput.png} (100%) create mode 100644 docs/images/vis/visualisationClass.png diff --git a/docs/images/vis/Screenshot 2023-10-24 113526.png b/docs/images/vis/visOutput.png similarity index 100% rename from docs/images/vis/Screenshot 2023-10-24 113526.png rename to docs/images/vis/visOutput.png diff --git a/docs/images/vis/visualisationClass.png b/docs/images/vis/visualisationClass.png new file mode 100644 index 0000000000000000000000000000000000000000..fb2bc0bf22b185cc3fb2b3e19ff2bb2634c57e4e GIT binary patch literal 22498 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 ZsQez3n}m2RUPb&n*+WXwnUW^w{|`F@B`5#@ literal 33365 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 AddCashflowCommand: execute() -AddCashflowCommand -> Ui: getInstance() AddCashflowCommand -> CashflowList: getInstance() +CashflowList -> Ui: getInstance() alt income + AddCashflowCommand -> CashflowList: addIncome(amount, incomeType, recur) create Income - AddCashflowCommand -> Income: addIncome(amount, incomeType, recur) + CashflowList -> Income: Income(value, type, recur) Income -> Income: addIncomeValue() - AddCashflowCommand -> CashflowList: add(toAdd) - AddCashflowCommand -> Ui: printAddedCashflow(toAdd) + CashflowList -> CashflowList: add(toAdd) + CashflowList -> Ui: printAddedCashflow(toAdd) + else expense + AddCashflowCommand -> CashflowList: addExpense(amount, incomeType, recur) create Expense - AddCashflowCommand -> Expense: addExpense(amount, incomeType, recur) + CashflowList -> Expense: Expense(value, type, recur) Expense -> Expense: addExpenseValue() - AddCashflowCommand -> CashflowList: add(toAdd) - AddCashflowCommand -> Ui: printAddedCashflow(toAdd) + CashflowList -> CashflowList: add(toAdd) + CashflowList -> Ui: printAddedCashflow(toAdd) else invalid command end From 74f6960448f47adae6b4bdbd4dcc1163f72843da Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Tue, 24 Oct 2023 21:23:41 +0800 Subject: [PATCH 210/518] Update class diagram --- docs/CashflowClassDiagram.png | Bin 27529 -> 25273 bytes docs/CashflowClassDiagram.puml | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/CashflowClassDiagram.png b/docs/CashflowClassDiagram.png index 0cd604f053c926622cf81c472701e18b3fd50207..77fdabc6b31a08af2432d2f4cb35bb649746e477 100644 GIT binary patch literal 25273 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 diff --git a/docs/CashflowClassDiagram.puml b/docs/CashflowClassDiagram.puml index 8df6112081..3ec0c7bb5c 100644 --- a/docs/CashflowClassDiagram.puml +++ b/docs/CashflowClassDiagram.puml @@ -18,7 +18,7 @@ Class AddCashflowCommand #FFFFFF enum "<>\nExpenseType" as ExpenseType enum "<>\nIncomeType" as IncomeType -AddCashflowCommand -left-> "1" Ui +CashflowList -right-> "1" Ui AddCashflowCommand --> "1" CashflowList CashflowList --> "*" Cashflow CashflowList ..> Income From ba4027efe30bb026162c36a165a2d18d735282ee Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Tue, 24 Oct 2023 21:24:22 +0800 Subject: [PATCH 211/518] Update UG with add income/expense feature --- docs/DeveloperGuide.md | 45 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index c9a180fb88..2c70ae2c00 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -14,6 +14,51 @@ {Describe the design and implementation of the product. Use UML diagrams and short code snippets where applicable.} +### Add income/expense feature + +The add income/expense command has 2 compulsory arguments `/t` and `/a` and 1 optional argument `/r`. + +Example: +``` +add income /a 100 /t salary /r 30 +``` +Below are the steps that shows the implementation of add income/expense. +#### Step 1 +An instantiated AddCashflowCommand class gets the instance of CashflowList. + +This allows the AddCashflowCommand instance to access the methods of CashflowList. +#### Step 2 +The AddCashflowCommand instance then calls addIncome() or addExpense(), depending on what `category` is initialised as. + +addIncome() or addExpense() instantiates an Income or Expense object respectively. + +Example: +``` +switch (category) { + case INCOME: + cashflowList.addIncome(amount, incomeType, recur); + break; + case EXPENSE: + cashflowList.addExpense(amount, expenseType, recur); + break; + default: + ui.showMessage("Unidentified entry."); + break; + } +``` +#### Step 3 +The instantiated income/expense then updates the overall balance through addIncomeValue() or addExpenseValue(). + +The income/expense object is also added to the list in Cashflowlist which contains all incomes/expenses. +#### Step 4 +The added income/expense is then displayed to the user through the Ui. + +#### Diagrams +Given below is the class diagram showing the class structure of the add income/expense mechanism: +![](CashflowClassDiagram.png) + +Given below is the sequence diagram showing the add income/expense mechanism: +![](AddCashflowSequence.png) ## Product scope ### Target user profile From 364cd90ab3889d86ba988ddec7c0bccc890e5c48 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 24 Oct 2023 22:14:07 +0800 Subject: [PATCH 212/518] Change names in diagram --- docs/DeveloperGuide.md | 6 +++--- docs/diagrams/Budget.puml | 6 +++--- docs/diagrams/deleteBudget.puml | 2 +- docs/diagrams/resetBudget.puml | 2 +- docs/diagrams/viewBudget.puml | 2 +- docs/images/Budget.png | Bin 21328 -> 21477 bytes docs/images/deleteBudget.png | Bin 10085 -> 10111 bytes docs/images/resetBudget.png | Bin 16780 -> 16854 bytes docs/images/viewBudget.png | Bin 9357 -> 9377 bytes 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index b4b4154b6d..e71845fd85 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -36,7 +36,7 @@ in the diagram above **Delete budget:** -![](images/deleteBudget.png) +![](images/DeleteBudget.png) The budget will be deleted by setting the initial and current budget to 0 through the `deleteBudget()` method in `Budget.java`. @@ -44,7 +44,7 @@ Example: `budget delete` **Reset budget:** -![](images/resetBudget.png) +![](images/ResetBudget.png) The budget will be reset by resetting the current budget to the initial budget through the `resetBudget()` method in `Budget.java`. @@ -52,7 +52,7 @@ Example : `budget reset` **View budget:** -![](images/viewBudget.png) +![](images/ViewBudget.png) The current budget will be shown to the user through the `Ui`. diff --git a/docs/diagrams/Budget.puml b/docs/diagrams/Budget.puml index fb2592258a..6b2fb66da2 100644 --- a/docs/diagrams/Budget.puml +++ b/docs/diagrams/Budget.puml @@ -16,11 +16,11 @@ else update BudgetCommand -> Budget: updateBudget(budget) BudgetCommand -> Ui: printBudgetAfterUpdate() else delete - ref over BudgetCommand: deleteBudget + ref over BudgetCommand: DeleteBudget else reset - ref over BudgetCommand: resetBudget + ref over BudgetCommand: ResetBudget else view - ref over BudgetCommand: viewBudget + ref over BudgetCommand: ViewBudget else invalid command end diff --git a/docs/diagrams/deleteBudget.puml b/docs/diagrams/deleteBudget.puml index 988af8e5ae..f9dea38d36 100644 --- a/docs/diagrams/deleteBudget.puml +++ b/docs/diagrams/deleteBudget.puml @@ -1,6 +1,6 @@ @startuml -mainframe sd deleteBudget +mainframe sd DeleteBudget participant BudgetCommand participant Budget participant Ui diff --git a/docs/diagrams/resetBudget.puml b/docs/diagrams/resetBudget.puml index cbaa8a69f2..79902f379e 100644 --- a/docs/diagrams/resetBudget.puml +++ b/docs/diagrams/resetBudget.puml @@ -1,6 +1,6 @@ @startuml -mainframe sd resetBudget +mainframe sd ResetBudget participant BudgetCommand participant Budget participant Ui diff --git a/docs/diagrams/viewBudget.puml b/docs/diagrams/viewBudget.puml index 70bab0c57f..186d176a74 100644 --- a/docs/diagrams/viewBudget.puml +++ b/docs/diagrams/viewBudget.puml @@ -1,6 +1,6 @@ @startuml -mainframe sd viewBudget +mainframe sd ViewBudget participant BudgetCommand participant Budget participant Ui diff --git a/docs/images/Budget.png b/docs/images/Budget.png index 05e51a22966f16a2552bcbcdade2f17c81169690..f417299794203e99bd882ffdf24d3f7208a418f1 100644 GIT binary patch literal 21477 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 Mb=@l^s#X#I1wyx@%K!iX literal 10085 zcmb7K2UL?;x21Oph!jB+s)%$I5Fr#%%Ft9mdY2}>2LqvlNXG(56HpOB0qMPiNL7?x zf|P&~I)O-g7t|SN{&{cxZ!KLh@%wH&=j^@DIXB|EhSD)ARw@Dlf@3PmS8oy!5b}Y) z)D%SE7pe@*Joq^0aZS&|(%Hqw!OGf$K*`F<%FW!v>NdND54)|0hl~4VVPO{sb0-f^ zM+YHGXGgD|_b@Pou${J^$FJWB2*Egr)X?kIPDJuFi+hYhnFOxnnM0gcq(iP=A`Mll zFPtm%z`(J@JpLIx9QQS@G=)YcuMSN|Kt@9KbO}nWC8dlR?godQqq-RV;u(Q@!b$|2 zAfbO|@@sp+Il}%R9L>|b0A}p6z>7QjX3LwjF9$wqY!!L+Qn9rkpK}z|NnaUAj}lBR ze#5@(sZw5af=I}LqIV!HdoM&K2(@37do#qZsEuE;_m;>vOt9}z@7tcG5ECI8dmCf@r zl!cd190aYtl$ebZukxURQYH24w{HxFrskXTG4?zW@b55x{XB{<`O5L6;oFOK+Lw>j z5i%e$CA7?S^$7@gs#UJaYa>jsY1F>jt()x(JltnEFRuQ798 zRZvq?>rID4PF-SWO86p9qpRG+g{7wvc+=3AK1xKZp3ElUq^+$zgTdtF2h983R{ z6*+U|Xr=@^=k6zB=H}+~^z;z;MjsA4n!G+zYTqlfBXB}hP0gsxA=zm}<$cY@M^#r> zSC>0u6|UE#BxgzYFCL^xFx~zU_9U9Ub*V@hI?nyL7RcfSNR#8!*W)cu#O+Va@ z$O||f^xg9J&2Rj=Z`9P)t$HfmF&a-UF6`ph3$ubFu1QQ8J@VPXmNN?(QM|h3_kH8z zbJa#`R4+B+=G>5b7N}Y&`mVbdtf* z9Gs1bqtoj?UymV`=4+m-#jj%|oF|Mf@%VZ$@@@;8)^#nufB(mlx1rcvE3;{ckRU%l zgC^Z)8p{!4cDsQB(~Oi9sXL#}&V88U&mTA%)S&c^ah1nHyIc86O+a(;d0LxVG5dj* z9J2>)vS7#J_l=M`IyzxZ{pZb_Nai(@wA4*Z*Sgo9V%2V53jD zTGbv4O}kFiEiEmJqvep)g!3cH=o13CZKG}|Yoo!5kik-WU6YSGshx?!F!W-2~FyODPm$E$Tmqe%ks zdT-#qPuM960$Q&D%<=!PK4uNEwd*~|2WM)}JC4|UY%d`;KMyhq8MPb`*WDnph>~{B z#?K*45;+Phd|%cI8py|We@Nm2Jcy-V+dHeG)LxN&mnFm-Z*+T zg27bMYf-?7<#gR8+@j?5>(|+10;P!TqsGcUM0UFx{(Ov*!K6_=tJ%A~EBQjJsEblV zbbL+pgkwyNP_~(CJT3^cJ-&?MJ$%zCYQ}NH$$iH2Bq=yRX6f)NZ%D>iI!5Qm=iYrg zPsPM+CybyCHKME#O(_3R-5oz@bpjlw$;v6J%HuAU+|JqFDO?4eXZ4Jp)uJU&xbdLd zlqVFI#g$ABSE7t;bU!=u$A8Rz{oSJgHZC8w+R;-!#)^k_CGE|O<0q6*Tob=rF1c0} z71XLzTT*V`?6pYqM1e#1Z_Df?!mcv&5`6ejdf9ua%+Zif=!_)#%Hqb%OZ^K*JFBpR zOX4o*VoJ&g0G3;mlXpI3m9Ox4NpU;szGK{pjdyuBde$z6A0pEVIhy>fBC_k!-3>MU z;do3s+i;B!wUL^e@^@8~t?=&GJm>z8OBvEWigpY8#N--v>pdA?rWxjXg`W#=Q?xlZV5Gb*FmueZ53 zCm~$3{pI%5!xh($&lavPek;(F`_jZLvelc4{~kbiu#U%slN_W-#hgQOn(J-7^}gW&Q`=F1xsLE!6({!JIc@u_!}fh`n%Ss_-s#ejsq{cce^Y+aL8DqSF|AI7VVKUu|!gZHk zZ7O^}&-Q|TDK;Wv&-?ut(HzY8;N81-{`>1E4$ht`oVLk(>V~=V2a21)gSCXmhyUN*NfWxT<%=6>R-NeJyMl| zn-D4DOKxm9m|JSol{8ssKE2S7*~j-9nz7{~GjZ8@zwP*gjyoD4Zuu_PA{PMnB*9#b zA1fG~SQ;lUK|+_p(;x>)@$r zz3BRsP70ry^SbR7$+R#c#_PZGx;FUD>u;Y%TwOP}M`)OmtC;V|R^5@3IpNkiXBh(V zVKWvZ#|`=KeGA{6uJVMHI3zbZsCfQ3{URKDeK_P`GA9ES4Q0)< zf}U$nx8(}gZk)SKlOKw{VDnnoah7m#^(WKI!5^?;R~7rbMw3 z%LdvyjkHTF+AJbo_u-Slq|ldHg)65W>jMbP+6a6aCKSH)cCr~(N|KvLQ*WVtMlnXCR&IPA2D-)c_$=kde}X7ut^(po0&ex$7Lx7S;)dGjmZi;!D^uG88R z`iydxGb(JgpHFFi1^k!@DJ9Q0DE(SGXswo^5e|XOPhE@rH2Il@&T__wty`jfy^1EV z6$k=S&OXYlNRfNpJADZ&ht$Y9;a8;tFYg;a=6cfjUp0y88CjPO=IIvL5w@Zm zgE@sSa7hIj=9&lpwMk!)R56a- z=}jQ-J6fDCqA?qeX%oA;@ty2rI;_wK_5>n)skGb+I|BZUqb5>VK0_mqq04ajn3bI| zA52CFRJiC7@h$O7DE8fq}aL}xm@c#`~DGnxWrD&+S(fAdJYZ_u~2x- zDaou_kQpKy5E~zqJe_IVzzMm#xuHiu>f?qfvTVQXwaCK2u)fi+>29N=^BJ7tbSe#t z2zqC^-X;e@m`PP{zHc6;DGD<|+X?gY+fOxx@@k}>6%q=w=g?0E%PaG1jN?#1?>~S3 z+yZIzwA^eme_>Mduop3n9>&h2GeaQrBrkk&!aT&H}3v zhvBtv1@!~9k}Pl}j$}H`dqTg?SJE4|&`%yEyT2OizugS0aPNC6Z{{#rSNrT4Nfc`D zJLOgjjIw|ZF+wcvJVC?!;`#H?OWrbF9c#p+CYVZ0dT>fCtJoh7QT8R3or^&5f}E8& zs;}?53se^63%;=Pn!GhEcQOkJ4fR}}s4Xlk%*wigge5UH+J1iZXsNp~;3OmpWCF$& zE`d_ZbvsTXLMAnc{av4>+ngA=lT+#2TvLohn#lef&2ZH!FYNd7`n~8`lJ)AhwUI$9 zr-WuQOU->K+p3rAI^pa+uMNv%SVTERMd_uxQzQl-lkWu(^50ylLG4{W8_oRExLTZr zIn{+XUp!eW4}Rio>&y0 zTyJnX76sH_(Q9Kjx3^`xycxbkicU^KLz`be6SGzM4ZpRjAuu$l!(Mf1dg9)Zz%zz# zVbBZ^b)Kkk94!lMggPrKDFyp|{lrK2itfUcAlMH`+g(&{-1yKE!Jw}pQa@mw>pSx< z9wvMtnq#WcZ-8^Cpnm^y%WkLXege{rk?Llk3gvBr%OpjsYaBhLw%-O`%Rff@9_($I z_p>oGCnhGg3(MZ!u=VmPThW^xb*{(uWfE(*{L!R-s>epK&@XhDvF;PpXNG=AIoSO} z*0s%VgW*Jl!i*L;wmF#f_KEc=(sUd;@>JQ`6|3Ij`}k7am)1xwE-sLEu1#CbiEvAk z-z9KVS+Xz_mauH2p)=IiKiNY3l~J{#Az`~)wq=WNu9;dIi-%=5xjzjwul#nf!5F~k zpr}aZ%O4sZUT#0=1dMM%3D2jR@O9e(^Tp%Fp0Z1aOOS;fMSg4vuL3x6XBrxSR2O0C zf+Z4&6?FX&1jjs2)#Q$_Ag-ic&;feyNY`F@(tkO`h%Jy&dwwGe8(5Zv;xcuT zAetQbA^`LE-)R}4#D#=3JjQA3ciW=b7#SJyc>Kb`LOHW*M9m%J5XAWl7i7JO!Ui;5 zerzY_o^)$>s^?Q8W?_@4=;+UPxhrZV6_J!tC=CtTVt03U)j$5&<_pS>+dX6#;#3*G zDtAmzA%%c|zzp6%Uw^p3RJKoXvd%B>)vF{eH}M&!H&nL5^`MkCTx`Ru{^TOC?9{`7 zfn$r|Fw{IKI_!PloJ33?Q}Mha?c?L)KG$U~P9y4jTRijHk3EnfzAxnDs3j8>)9v_g zbxFF-yaOR+Klnya|LyIrB+;&gDSZ_}!OYA|=lVVIy2qncfyYjszdcdo18POcuemuD z{W_jqE@K8R=c`Lf9zIU1I?FA4$f8%@(#OWe9?YdUpX$jdn8kzg0Z}eZTdr0PtAtZm zDm2~GFrXW`j_I|L^?Ct+Ug}8<%4Z?=q&YR0!`I7uw;>sUPQ%Nztk*tT1+p723n_ z^w|9f1_EN4HLY~61qCTH8R^iO_CtzQCL^;>uxyVBykTO}v(A_*uw05j3{1%rhOaLZ zZ11pb^9@bg**6CA@bWg#%(?8ZBx6=vT3Z_xK-CIp_m>@mOI zE9;M6v%&?R=)!kh=v^ExCQprI5`5p&W37SLPl~VGS&~vAe9a<9AY8Z2c~H>cf(5G= zGO8e8UbCnQoSmIjPrJ;>6u0QVdLhTja|8jb;k7i@;UEI_U6HqDyYlzrprKjxzq>I{ zsMQV%QV4NfZS9SPe%{NMs{qpN;INh&_~HG%9VJD@Kd3^+I4@p2VGX5&?qnL80n}q> z910UOs)!rRVq;M=JuT&R+u3$XRcZWd$!Zi7es>^Wzl+Qg)MC55F6B(lb|x0XpPf>H zjS#L+@%=Dy%dX;>6N|xR6ktookrH!pwY!Vqev)x)c6N5nVaKN3vxR`5`SrN4ZLV&? z1So3?o75y_Wb~TcnBf4Sk|FtFk8}cn{uv$~9&YXu=gGRKPa7WCiELj#3Tu--qR}Q0 zTS`~2dMu6Mw^ygX*bO=i6=vo=h-Q4=jihMZJ(MgyA31~anNII;wR2rCIre6 zzw#sac`Z<8K`ig0cb2LPK$Ub&Jq-xQKV4f?R-}aw3tDc;sL+fM zxlX8gNhAycLji4q4QcD8DnrNDzfeWpx+$kB=AWB%`yTx2kE7)T61Q(6m>hCBwLYKr zbZgp(lbHbXYXt*G;fJio$vR&b7;#zD_P-!ohL#lhNHLjfSQx`$xYHx4jWSV;afHY>7k!b zDX1#p!Mg5YWV5ZIKfLec(?k?L$qc>22qtM)H42W;;HbHj^*^C{_n`ezI^ zkw;Omg1B>YcW(ssYdcq0(Y@2b>L7YTX8kVNedK;owXv}QKo2uB<1ybCSkE;0dx(XU z`n?Mwzl&TfYB$SjE(n%@rT>aI2#vWptS3Vj=H(p`5it^>@fYog*3h$#Gq#ie_|45EiKgcF;0_m!Zbn31X$fY0QUcGun27#W!+-?XUTnxAH2?XsBD{E`T zYu8%a+Hmt9rr*VLy%C~!Ql;}EI2zFRd98dfSzxW-4lW_#xX4g1a)k)c3#sMc8)MLR zAjt;$_#ZF8UkK6e@VJ;f1!)6E&t%)TiCQFRnq9jVnx`5vdOYNGL&q|cfRL$O0mu{0 z)?q~_sEjJztbiouQjAhoQzL;OB?6XsM)D|{&Y)+!shJWBO12K=IQ*v^|B$Q2>lm1t zdP-yfP=`$~R0QC$u`%b^03>Ph9>WnFPyKvRS4T(e_B*!IR%d;ruo6&r$#5 zyEWOFtKXd`HPWR!uypW?RyqiDAo*iqQ=vk@CG<&u1Wjv`z|GeJ|Ey~zZ;1}ak`R{l3hLB-GY34m3zMInLh=t91;jM z`_HdF*ZCo_nv&h=a49aX;Nh`K#Ojwb>Q6w%2{g4RB$(NZOtFHaod4XpyPIDb85sJj zy`7W#JgAo^>+5y$ZtdOzO2X84m9!ua=q1y7R8dh8aM#zbURm^j)}UP6U+r3+9!(iM zx0ICBxpU`aWcFW|PgwN8P}`ZHMG7)1|LJIn8PEZm?M}WBJ{%{#5wvC0dAg3&vHpfUFN(Iew(FGrAXf)1Lw1_flv1xWTs{JJk*y!a#4 zr5tPy^g1bt(BCi|3SkY4RDNrpv@|>TEvPlD6CXb|s9wAn@dLoX`rwF_r_GY2@=C5b zUbGLTk~xNmno7rm&!aJg2f7K*Y2b(I_dO2{3b1CEmx zkYAbTZL_Dfg$qGEu!ko_El9lYP%Ed3u=#F{dshSmES1t?dhRc8p*HhOr-;VFRvOa9 z9iO26=aOxJjB&@W&0dRSva+$cV6#5gt(&h$$Uu**<8%$mGNTP)JhSMDhp(@#z0gRb zG9{;jdN*~uUenjtFC?`RXIUX_bU5Jp$1*@U>pp1t_UAw*tLCli-xT{F?1Q4$SOooh zYVj^ckj;i%GXn{1V;gCOv55(kmG$m?A4el(RQukkFV5ptn{|FWNyVU0WUZ`67}O?b zcO3IdCl90~WDhVPdBMZY&wU#z;_B)Eb)lKgcO4ISr|&DqLXXw9JBWbxSm!@iR1%>< zVVf9V<+uGo307*?A2uwqPy`Fx-~^yxROefX%V4UwA|b8tm*?iQnaU=Z*`=kJLPY2kmSY_@||$ zjDkubxYQ!Pocyauz&Qt#V;I13PzcM&)PW*d{dTLcSr(hP1IvMwU)Z0r=1`YY@3?@x zx}&3`u(4mmgXnLCjek=gN2vb{vM^anBKiPAb|95SC_#XLR zHEjA2*~6=dy##H(Bp3fZeoW2qc;BbB*kCv{jQWJ==C`%qyA1HxTHuWb>3g7JmnP{`C zKSb0M0;w{j25y-;Zr0tP792PIW?ba_(UaaxQboM?xr?1Ygzj_fH01A74Ae|V zqS?k2CQEcUMy=>%-|W1UBJ$%MI`%Q>61M0AqKRV2Z%_23JQ6+ngd7%3Z^}aMA;mXt zk$dHVeMZ?=q^Bpw8B!292YFM|`h%4*NtEFcT9|r00CdiI!dN7KTA7GTn zc29^to0CRD65E%Pf~z@cuO#8P5=(zPA>yRt#`4uglB5<7)OGTcK_b!~Tqicf8a%o$ zy1K|g%Fx8-i4#71nT@u|I}fv!;`mOuIydH6Jq~6IYg*7Fr8?=@08BLA3n<8RWz8or zbi+6A-Wq*QfAp5gwj$+tUBEW$^O9YPXrPE7^b%qz8WPOybQt$^`;#|C4s;R*8Z!@`-tZc_qJ#*^W{J4 z&*^)2r?#>I0}YEyTr;CdO_kE5loZ@wLv(+Ep7k0^y;n*b4IMRVEFmY;g^4iMUD+I% z`E~tEkGUsx3{bt%aLZo5oXS7}&vTN4*DIrg$FE0BERy+#4=?iH_Ad7DPkif1$8&eA;qnA~ zKSvC4e_gpd_0$|fd-dwduvI1Fw$NG`J-fhH=i|dYkE10WMX@70ZEfm}D&n_kY2FSd zJ#X>2eQO1l%#|o(CMI+VFe@kyx(BtYtYt!}8MjwQOSLLnxo|-+1q##;ezs>*Qyczh zVcZsntcpK{i;rLFutJ{SnJmJ_F7WoyBTX)nsV7}Az!YlgH%l^%-Fjt;6gr=68@46T z@#W2}dqrmTjs{|aLOAO>C6E0EUPkw>DUe~jl~2GR-2!`yh%&M^7AO*Wp~Wzm{Ac+@ zSh&-`T|f1pyqS!xfqa7(FJ7d0919HJO;<>2jpZz)#uh^?&L@8|+N`0XM_cm!xjN}I zNlDUbYQ*Y^IHVj(l|p)XRf*6XhQmkZ;$h<6vBadok^{w7G*{nqJop?H6LW#$3HGfJ zdkqbZZLpLtUwS?nDz@^Ns>9k351{JMG7g#&cLMR~+LJ07a6ei4$rHg0hWwr7K?7D? z>=rz40w=j}7HGCSpXCUqs?XJXAHm)e%!5swZ%=Ui_T`OL#onA3gqk2Gv06(-1qFv~ z-}PaAFp2Ga$I(V3O>0ZbT-%GDQb((^g&O^Ak54U(*^#wa>jjCqZWk<-e52M3X9mMJ zblcA1A_bp$9FOS*T*znCEUBYaU$}S)oFG`Bo`s$Lw!Hj%^>-ID?+sa0d!s)m=lwjN z>=MKAU@>G0NyuS&VXzPki2ogBCGU0nMYREuYu6rky@Zdu?NEKArv%gN!daJ+l2Q}! zr$>W8_)WTyW-wm++PO?W=btcf9JRmm^y1Yq*DZNIE@NYExBc&6g8YxZnzzUE+S$)3 zkf~qc$5f%R4JMkXD!_SbbR*YR$&#QBiIXJ*)@L&EiJLu}L#M)Zbwof@TRvHMaG(|o z{Gg`x7B;H_ufy6{QcR4)&ZuMUqIr!k)^`^+0r2f*-&kTbN<}!Bq49czioA`(%8-5T zG`^vG;3vo)uUHfX8sTQ@eVZm4M(NvLk9}x6tW#mIM((GR{h5SldV5MaFxTrKHyR@H z4xB)W1d)hnG1IWMRS-#0867b=Oz#X35s1X7Rt*LNQe)NxV|{G!RtsBhd*a^mNQp;- z{OILvy?4R&Xb=al-Ah zMvVfdl?48^>nYQYj@Jgx=p@Wad{$$|qK#{-9L^5Q zB2;^bA%W$8X+Bog=^8RV`e1W;z(sH~f7uT#NTT>)nRCh>Wo2pU%wYbG-HgE?4r0B$ z3Y@n@w*=fB9h(ac*1k107LX#A6UA_A&TY>2KLi3#=ZjfnVku%NU+s<7 zTWv0X5~d0Y7(ZKyeOBn;%b}&-Og8g0nougCt%X;$6g(z&YvuV*Nptl}<>PsH1wV_n zsm`@&nXLEcdf+c#d-7dsAc^uh3JtS@t659bw`J?xiv7wYL3=vBkz69C8Gdso&f6Z> zu06SU(H(x6x0WW&Hqo>*LbTOinR75rlM)o1b?2Q%Q#`MSZ6WGm)5`D;92OoHHq_jF zwg0_K^eW71Y-)G6u5|VD(-lqu$J*1iH*t5|NDvmXOolE^CM+f9Q4N4j;>t;~ht(oOSxA`=so~0rfI(wR;88tkqm~%))qK4c@gw`C8%K7fqsVjQha0uEwUx*FJVz!2X8lmc!r90W zEq)iYMMy$N&_ehF2TzOEm}0%=?e$v83q%P8LIoR2m4&wR{HO7}Rr+*%X3)l2uq?nT zE#dSiOY79rQM4IJN|BaNG# zr^V6YJFD2M2Of?gN&(mq%<2b@qxCd!6P%=M5s%|9Z{;KB+Fd3+PIi)NYB+s`3PAM~ zsysdA@#7B;nL0xXd%RMf=DEJ2(R)rqNC-D?wmv&oqa^b^iui?{*D_AZcY?n)Zm$Tz z`Sq;^3nKT0>=z|sxbiH9J|ykK<*{*2r17Qsw|BW(<3wDLhp}0^-rwWYFE)*A$;nzE zO<5-N{n*t!#LbQOjgmS>xrS;GV4J^opmFfq2g}jbljAj!{f+m<$K4+-T=Z}GN1i4_ zllL&CzUhV|y}H2e8H4wC>E7M3^4#MZAs8(+{*s(Wd;-o6vR8nXTw_R5=7}Gv20)f% zaS2sP$UAsHI+IElGSiJbX+jXu*hd&wQg&cT7=9t{F*76M$v4H$>QM|^Bbb_`}W$CVbGL>;U zs)5(~%GeS22p2drE4`UZHGZuCCpn^UvVd5kgTZ!_UGyjXJs(CgZBpT}>xtuh&2jT9 zf2*|3C4{8x87;8X*_xn|t8FJC5h-@!jFlutBj)bV7AMzr>FrCmecUS?6(Z@L6ga|M zs*E&x%3G~E$JqKvig$-lDfla-@o{9Frh}9A_H@Ts$4PV(Z1Ls{t>B zoA5?@YN+tQzL)Bqj{JLNDK5wv9SZZWr{D4HvY;0(8@0#R@+9u_mJm6~bt~8qTX3nT zj$c8a`<89w$a>wlt)mp8yjMar{^9Y9B$E%xmK2UZseA>8akK@ zQ^lTEL{Zhm(b933Z*Thd*t`=~hSO81-4`=6@8oLp&b^$Ql5va`8q8m^8@Yt2d>b#O zkP`ST_P0{zI}-vDYVdN_TcX)=ACwxE?ekJqekvX544F@#KGx&|V1bjQk;d!RLpwTT zpSi()E@4EOZJTVLKMb@qNp{1lodz|%k&>K=WP?23Sf_R!QCPVH{N<#}{C{7cs;5Gj zo9evHiyMkSIkqOd*3dt$|L;)IKd%S(*Ac(0ExEP)h>RKm2j;rCG6Va&gb&F58v&RI z5#YJaI>pP=S>Zpq0icKh6fZK^39r2{SI-FnTH+*Y18jd?A8cPQU_DW#S!uWmU>2a1 z!pw@vJZ4_DPICDK=h*>zhoS(yW%O z?_S4|J^!GOvff5G4Ex%XK0u%}Z)`2UgXS8sc6@z*uhel(yL?okjTIV%M@wU&xahK0 z9{b{joVnmvkHba}24-f-jJ|_ly;@tM$(Mblv?%7C73CR-Uqc_gtBRlM3jN3&Eh1Wk z0Q5J^&CQE)6u6`op#BfoDe1WKMGm&p1cgsj69FOnPFlGu4S;}zq~tKD$Ie?uQ_POS zybCfUPH8Y9$5r#e0z(8iSL^jeMg@F=VhA}01J={i6SP(1hXd&DGn@4$P_Du1d;mFF z43D(LX1W281zKtpp|8hB2i3c?oF1l_oT*D@dCg#g#{R&)_~7UR!|YKwJPv^z-x6otc^G zN(QO|x)_-?PwhsKyvguKfEtdh^dMXqP)f`Ow%jraL!3k(2tEdC&2Gxc9?fEultf6g zhZF(baXPFj=Rv7%V^mZWZDSAi6oaF%)o{l`_p8YX!2NlWpV(%s$tVLqDej^)TFxOweHCSD{97a))G*{E%n-f{3C zq8rGs3JNx->Yw(q1o=`%o&?fL94guXxd2l7{aercO7S?8qriqx;Yz*th?;tC!@E1V z6$h)O(~Y5_PoJV1ztebc0?{lBo66Ox6otVZt3*AH%L*lx?=7J9A)&@t^y zo7QkWi%~7!06(vQWBK zah)=Fi0w{}d2a?`cCWVUhV&HfWA+h2hh@yq7*yIGM?ZFVcjMyX%F2X4_is!$f?&qO z52`%czK4laLn|^#+i_VB!i(nrM=+v_g#n0-B=*5Hi9qa8?%g6*Vc{~zwK1`^xl74S z@+5bjACiXoLq!<`1)l)1gO(ctrSuFFFMKAF__CA51e)UZUWqFCge7EWL&-90RgM0t ztZ3$b6dU^vApH1GsL08O%3XFk#ZE>BBz-5*2(etZizMuwGGH9*_br{&m`S=XflMYS ztVVf>b>{6&Hxi^;RGl363ts6Ujp&&p5_(j(^Q|jKS`N( z9i(=9r;9g}PqTN%G0KJWG2k$E-U?=|-&o>zC}?|syxl=3>7Pdv?kTagJWP^YSZsML zeRosBNly6<%;3lIDkb31Fg7#iW}Hbz>GxB+qZC3~zE*3#H1x|d3@<_cP7Yx9SbAGF zreQO;xbHzbGP#yk8JK-OjPb4Y8R@H5BnZwJqUsBV%1h>~+YTBwY+KxG0E5rQrTH zSR(Be1%;X5W?D=!HsIBvB#q2#I5EPBh1Q{;OK?_h;8|6C=&4zaNi|TGbbq_3PeiR1 z;YPJCEPVc)sm5T*RjgP2qQ1fOdqoP{)NlB>2X?Ggm~l#5nNwUN;^Xg@I;?=G^Y%tL zHc=mQGiBz*tgo-K$LDEqaK+K~Ffu9z$haRK^{;|_N<#hhg(?{< z@4)rw`1J8L7)r`?ysGR_VcEkmytaNFluCZVFjvf8cD}kB?G!w~cN|7f~f>?ba`ZO~;Hn>)6Q4G;&26;h~%OZ)rx)vFUj$_XAP2uz% z`$T2iUljCJtFD`VVc>G#c&bxXS$VW#RgLQ6bu^b?RZ~eT*#Tv<>m^g6LoS~#_W3#0^PDU2!XA%ErH)EXPR?O_+YsZ4CqAXFd`snd!;i*QQIAYZEwE9$KI*LshY?YZAT7 zt_D!yxzsP%0F90f860a;w#H?%vh7FMgbqRl30<6Ie}ETs75NCIHI`rMD+O_OL6PigqMg_@?UfoW$$A%2@*(*kg>S={J z5k@)?VSGjH-c1d(0DK6(R_OPYVNzj9e_Z4Q;l0c6NGA3C z6!iXjxc?|i#PX8o{ABafyJM`ru~BCIQC2auG-KXVAa7%E+a_MTdY3?~`Ka0l(o6}N z+sZzfKUxvz;D0QOnDLBG6IMs%@sC_3vC6%6tKH)|%+1wXLTk^QDdKv8C};fe;mBwE zcei3WCcN(YNz1Q|l>=(2s;c^pNbC4?8w4p`-bS#|o9bKePxCBO!-FX1 zr*nflAbSk9oFy>>XeUhv-9JC|p>495F=RVSd_W#74v&3*p5-vTM{a0;JPk60u=tqb zzqu87K&203G4NM z$Cc??;Fv)+$jayP84nf_+3t_=Mq=01)hP|PUo&tFm&BKS4o-MXZ0!8}eEQqB$0Lft z3Cj6omzR4pdyG@uGz{mIR(E)Cq)`5=o846}|1iRSoxfB)h&Vt=OY0H|N&ORsPhymQ zqv)2Y&z|9qaW)<$Ut9ptSWhpt`_YAa1-Vd=|9&mVTo{A>)?7QlUVzR$D0LVuG{(0{ z7V{8gW`^7p5fVB8U{yWj^W`vTcD`9(7Qj=r@Q>z$H6I0s-(+N55fKr&eEBjT-}akW z?Q0)YronUOJCYIvZ0A5T3Qs=!frds*bTs->ZqcKD6+~<1+V$%cyk;NF2d^#KIjcB3 zJ3l4mWa5MA1p|3t7y(0;2Mg<1LPxaNJlrPA{BbW`pr#%JxlmDb&lk40o<+&eAO(a8 z++XSH-f6l5Jd4g528qsd-P@$#wHH8=%4SU|o$8zdu7h6(2=*=t51E&{Y!LhD@B7n5HUAE2R zu)`~l->bQKUIBl_1clqdHWiOa7eL9NyCIbXbV#~2R#1@aR8%h5VB=8Z zZvQav!1a;;1o}4Pk>n3U3hlmq0UftX@tPD&#GtE^^|-7cL~wd)N>|6HXI2hC=Fkc% zC2ls&zR$*+^h#C{gOgF$ zp(?Ad1(N+dnSGWwPs@$-BRq_+C|oZBT4hCRD81Z-F2FT~AE)OPx$LawnGJwm*50je z{u&Oktc}I}-&aOIWM*eS8zNW?B4VzBId3x9GchrFM`#F)eX81yN+D+V6X(rHDWgSZ zqJK#X!s`B5%Mh2TH;%#)nx2#O+nJ)oK(zD2sj~8R=I0vdwinn;-`Lf$wEW-0Ax$ zvg&5#K%AOR*7()=OIDk|G3|K^%53U5Wix$jaRFb(1@;Qs2q=|cmvLXsI&CtG>RU1g z{-+EFf)k)>oQ)o#g(Q0*e@lv5eVm3%9wOkIl|GTW@2OnD`#kE7#$TwmXL({W;k7u=2gFpI0F#>xSqU2 zEf!%v(l;=OjEvMflJ?LFKd(;ar&tXk;mpfPfADLwi|2iWp^o$g(Hg9ck~u43e_Vt= zPmn~HW()dvqf1p>v;Q0o+)|3c8mZpP1MUObYZhe`W|Y5H3IcbZ0~9tSG&Fz}^yX|r zsYMX9>?B9Kd??APzzpe+D=j5wFy3AVU01H6OF|CpMecU>$U}o zv5JBCuW#aNw}8;&UnPU!7b^3Z5RPs$@8+Gw}cbS@co)Kh@^kH z)oFYM?Q+H&BdE|%L=Yk%EN2$>odgA7q~1A~O={yNmx5QA-?~ykv{B%8#OkboN z9VoFiJ^?}usOA3o^4!S}$8it{{pa%$yKax+R_zci%j*<+eMV$Z*|%!d)YNp@~BSkDFGLnddBswWce*6LCJwX3v{W+ioIqQVqMylgVH~zHD zp9eJbfH35;y&MkP%gCZ!n`~`s1M)$4fnn~0SO6-^(uht=^em+5qZb4=Prr?h;UL)ZHBdm*9!V%<~}m8mOw&!qt4_9T3T2b zD=#7<3P8RAUV_|v#UUJT2j~^!xF&%Y0T>B%3XR%lnj;6HwBaX*^J4EPIXnHP^MtT> zybC>h%0O0!!{Lt~7u2ylW98>3HBzxw0h=C)FBPL!HwL7!9a0V6KQJMMb%jg_W#;2D zzl$97_61v1C6Q#}*4A7_c+`_uxO8Cli^OCgPaA|vg4!H!9mOOcFD~MP>>U>sRp;OY zTqOwA6XQ_GcJ8)=%%t}3Lcj3TKS_YaTn+eEW||2pDy?5W`LS3%5-{*m2`F84H_U&Z z*a3{hHBiy3Jq7iQIf^Yu(>_*P&t(IZ>bB;BOory&yEV!Hn4zQNV(@fNSE-;giRN*c ze$9Si9o5y<^-`!e=Rv{>QZ)V}o-6j66>dO;S`Mixe`yS~y-9lZ*x;v685Q)@tS@ts zWMxrTTGPT*FH5S2u!-yVg$#KA3if(nCDvqYZf*j< z2Wsn^k&*j*;^2UPS0wa7E|4`}qdh0>zf-~tjx2244~O)|jT=yE;W*Jp1i??c1nd^N z*4M2UJ!Yft#PeH0-(l^>x~HqoK8y+u4hEt{)oUcyL~3h*9Do%CZ9Yx!MEp2hd zEc~Gk)!1R}+8@a^;`I|59B_TC=|J8j0P1H|*Y@$_XYGAn&OOXf-Bkl~)n^O`H@zat zfby*Sg2kic`Cr*iHe!+L>Uzf&ZH%w?<>cf5+tAX|Vq|1&m|HX-uP6`o0aGO#CZ=z$ zFq?P?AUq`n#c|S-0pN}_=Wh7iAYHy!SpYB|4}bM zBj)&NZUH_c$i=r}Bgy|FV(Y@0fhSXu%hPL=<2OXh%KAJu5TB&|S%)*!6PK5lD|^`i zG15P4GXXk$MKe}->i?WD8 zi6!^%-&t~f4PubFSVI$Z6lx_n>^z2GdOix-+rz%fdGFm?sPr=N< zj{p5n{zE54gOAkwhn`A+W`lzeO;0^OmU^i(&Zqsd#QSCXc?ICp z811)UUOPcibTH8crx>&m)<8#rEL)6gLt*>sD?#D2+k^Vd?ONdI`+LPTH4;O_ zaZbz!G0MN!E8=xcpXLV>Wgt>kgLZ{1G5R&UdC*ndq;a7Hf7*kM|EsV+1=B1tMR(7zDHg;CJQp*3_-d z&5NAcx6NhwT^Ssz5JF-GwDW8+4WM!=lV}!q zHLv^bBt)Oz^a~p6C0v4+uU|7vEd!6$O8{)aWI#>f43;Y?&sa$S~z(HE!-Eu{bgErDK4xRA_C0rl71}#FoeF8mqpV5Im(Y3GSA72JWh^5XC?c7$u$v? zB$yuW2LMIl*u!L+B9goIk9Nk15=7Xejy{<7FexO;mR6_gKF5Hhj)Jxh!ubcA0PV8O z>ztfc9f<;YQZ4Q6ZxmuB)8D-5?(gvK1~65h-Ye+m95hWq1C2)5$@<~LhX9*^PNr<) z88OV`qq|A>?YtW4Lq>s(fz0RUUn#_8eP8Tj z6BVrhE=!J(`%n?nFRwuWU!ZsfI2{26)@}AE;nTLV(vh_S@7s$qAYrb2d4rR$=dG%y zrdD3=KXLrDoVT-LasBs|=&vu6^O=7FhS8Rmmczrt#6(JiLR(#x?I6@R$faR30_)Ck zkCUT3+BffH>HhAgC}dsMC5(-VBEEPLC`;-pD*EOQ9Y9$*fB~y%K>mB9jcN!@RaPNr zre3;q33T}`DmVif@{gw{snrE|E&z4cdjS+?WVHB{&HuY?>uB^7GV+R)QCv z03tlD-}5VItWMA@=;oj2-zLQ>i*cZ~cabOd!fJn}!(tDb`TojdUIjCTKl@BmZtIRA zqjf*ec^{}Pf`GHB|2!Vt0gJEyk3In;@UM*iuUQy${;!^IC#Lr&zn_Oc3sk^=jsnoe zvz}Yw*)-#7BVS{vd-NxHohR{3Rb!CEzf-ADPnkynMpAR-JfTMyxI(*ZQ@FFT~4UM#X2PafzkIa5qQo(DZzKPSu&sN9&q z$YcQY$RIb+?gU{U=D)mbu5@{dA(sS-g9FmkQnH9k;txB%7Eo0>l7#p{Rsr5|ig?Y^ z>}+;6Hk=Rm3X%VH4fqs3L7&en10=@ZYs5EUCVbAb4E^zGPEFWipxp(?;W^LB-FTy* zpSS&-fuXJ|(0@Bvi*oLkXc%|^L&UWhHK`e2V|WTU6u z#;h-8MkcK_CDqaLFq%OP~zhR#aqG(8RMC`9#QsGecPLI=xW&<#M`w0-w#4)DRvN{SglgbA`{S zEiO|vy#^V)RUn`Aw{%G{e^)7ZVokEYGG=vkHCHQA zNouH96aC7YE8zP5%I63Og{o@v zKPy*u(h+Wb>{?Nkdq6_9~2la zwpyFk1x31n??E__mk^yk@Y(`^uP5zR?mcPJIPQPmMGZ(?b`A4`knWOxxRKEuXgLGF zQ-^}{FHFP@Y3BD{5C<9vVu>(rJD&=PS}P4di-|jGFH^Q&<`j?R$S#mZQ+OZ6tmlWU zoJTD|otW+{69>m?Y5;ZG$)kRuU!UW9X5E&R_1yeE_qxIJuWUd4Zdp=}iJ7@HvGpb?bTI1KfZg0$Gv4XKoT|olOp4--w5Iw~kva+&3lI+iUa8Fx% z)tt0e&n@IvnQx3OyLIXw`LWoCno#kvxoZ-*rvMvY1t|nHhpHsC9j}h~joyNs2GZ$n zoJ}1N#lKuh;V)h^I{;fU()9b{v7t&2F*2aibU1KRUW60qRR4SoDaZY$_I5v(+fq_> zlK3LuM;*uWsczo9iGfdz8yOEQO-eMI-aL~W{<`qdWCu{wBO_V9WDP~;G1OOM4X6Yo#&^>B}jMwE`S?Q;MwDX z0sYBvog%S9{}1}vz$dcKaG)*zha2bsiFV zUa=)epnbzd;t#eh;J=?K8-abt;FmlMIWV3iy?VE|!p%irbv{e|9T23bFI)h{>EaY! z7qo7In=)(&2)95*wgx^l2p&0FB&ps!m?r4phETKe^8R?rS@F^!>9j@643hC#kGKv2 zxG=B%p$7v~&X=AZ`pcI==S1hpH^wPppn@718NIskJm%^>CK|v}tUwdC&i@{c=!JW1 z|0p4HtoNTcQoCfQrJ>}s0rN?w?cU~Wx?&0wpM3~0kpiEeRoMnc6o>r zei=@Qr$G)_hqgHGnvQkO4B!jfQ{)l_M-T9YMF`XFIN)9NTI$cu)haaFoN2DZnye-S zjzVQ6rLe?AcAJ`RK8qo{y-h<*&m00Y9^>Eqy17>1 z6Zxq|e4BsbnhLYfc(_oIULGFV_8SKv=r#9Z7~uh7&K2^w4ZPcBInxxbTU7~O+<5K& z68OnqqUd@`01=GPc)Y?*?+dUl}BXCncW2bUTdO%4)L(p!mnp78*~vB!cKyAg^N9+olD(gXo9axpxWwGrJnwC=|D z>T|+DVa*HBwEApDxvwwU;zOZ0`%Tyq#uoXtMz0qVV2gL5y}%)C>)_yEW|mcrzeO0A zOfZa;9j%Kl#cU~I44kQYK_BdwG&H%p4M5K}f_D@c3TIKPC2(^n^1&N+xF@TLIZ?ie1<&H_@<4aenyjfrZXIxS62%tAWNY0m=B3fV;9FE<-3 zU~JO?d{ZhEt0xA$Vpe_l4ner1d{IH06)T52zdG)kA$ETFmoH!NDERU!WoOxb(rG|J z3|c9;CmyGM0BjUk2nZ;cU^9LapXr(_R9-RwsHKY`pYA2`8zlq)nOco98FafWhd;hA zD7YpjmQo=*c8SYszYe+0?U}_BplqAPuxmvCf2nE{2oca{ybGKCOWR7DTCa*{V_^aB zF#=xl?)B@sf%{1-!^Jx`d7z{jBv8v1tf2!437Sg7uVg}Xju!6#Iz5pt{0Hx{2Y$>A z=WV#%sy$f9fbrw)VnEuLqhx-kuP|5oKxkcKqtBElvTE{ZspG4uUh$tuC;%y*&!UA@ z0d&Vm*)_%IV88B78|YEhf@jhmMkiTzD7Jj{Or*e^f{0sqx70N>6hxA98k|WqaDq{< zh}#MZ+sD7K4FvuH!()Dz@1lP$a)$daYbXNv)T`DvcXS-zqD8)b?-dRf*{Qbha=g6X>Zy^vrJm-@NPy-1@Gt zfWPhefMEaizCfJXsZIWW^>u@vKKrxlfgY@mu!jO$E9?LEOPHr}^8dS^drf6)m+woW z!3jcc_Tm=$Dy=R7|<``WaH!i(MgCvAGqjtCQ)U zMB4nvCCO?|3%;-*zLgo$j2+Vt{Jf6kzn&*5(w-85w^T0c#j7C%Ddxdg*^9jX_3@(n zJ01c7<&dJd-qo3qa6yNfzTPhLElWh{{=f{MY>GXY7jLNFm->2gVhQB=CK*BbLr;w^ zp6&s0l8%>`IC~e6Qm-0tuO#l^+~t{*#${z@dv#)uD4EsH6J7~RJYt9o@Q+z7xaeEgBE3+3t zXpQt90)j}fjD(oFi}p&=B@ZIW4`+lNbX=HM>qW6$#e#KRo=PJSY7ei6UXyECo!f*w zbgrNk(?-+`W_$PuQH&&@si=CYHZ(6(Y@JrviQ24IQ(dX-+CNxG^-mr5TSc1dxu>?FQCvCLeZm>+$h$7 z3>iZmTfX|A-&MFC?H6i52Hu+H8%Ly0*$y8OPIbn97|dgL*yM2>FMa@gsN^m(kcSW? zB*AS8q5Aszeq3GCk+OyERB=2S;f`&`h=rnI&f8!f!D!m59#W7Y-)zsV*)OkOziwz~ zC@Z@?vWS)0NU|LK<4FW8odfw#{Qdmy-o5L#vv~jUW7)*PLLF~d2=kjKnwn#*h1F?K zd?y1=xwyDaj`o<7MUJQNdU|?_2Gx{=P^D=V$ETN^PR(QuXcTXmYH4XnNT3vRD{QCJ zE}Nuy?k2mh%G|rBQDMipo?W{d z;}Ti?qxk`9J{r$$m3g&Ck1%O?!4J*9UhjUoxVVTz!Q-P)xj;RkV&X(=K2hnoG*)4c z-<2l$Y~OlWT3W9WKT_m$f1xjn+v{ONw-0=RVJx`E0p1I5!5c4q+sX*Heu|L$1NegvHjNIsZro3V zR03{$t3r;8>M%VyQWBO*;%o?yS#JO_Ey?MA1b=CBKP63r=~y|}gu}_9<6)1=5CH*! zI)q)bT=b+MpnkLCR#)BIAA!}p9u1R#U>xnPq{j}FnsmK;cU@mxX&kGcugYP;4hF>> zNcR=0N$*5z@^#TSFgVB*55m2JBf!8gJydJ}WxsKQn+Of{JDQlo6r*GYUy=H7wd<`8 zq7PQ1Bt%3Ki4?rnn&q}rZ{^}@PIgDpsa-@rB5`-#&wX%1qi9m+?C_zZSQIJ;3p|Up_`wqj zikM-&TqrN`+}DRXDYxb-P%oVZCseN-%$Z$UZvR;ag;TEs6o;o7dl8Z zH|~6P+AEj9%4z|L`Lr_XoLyu)`!)CB`#YxP``zQ;Wu5Z)sUChVA<bad!1(vu0wl>1eZ_fChz#$3|N-p0kb~tE-nynn(HwB8_gqmuSCz zw)LoEX@6{-u`}X*76WzrWB3Yg#C?g`do{RGQ6-m1WuYW3`0_n`fu}hVnAdIC^7JCqLYO7 z{qc4;#!)DiTLiR*$$4>&MNTKqlCB6HhP=En4e~L+!+f>dPWv(YJ1al?J@_>GYpZT2 z@Co?!L1v~B=9$h%t)c=6h8*t?Bcs<)iFnB#?NS|B`zhGwH&Ikg59)Zwy&ln99g_r? z`8~=PzdoD@4Y#WBIB@ggc*|2?;SOK3&- zJzZ>ILhb3`ur#(Q<_)6Ggx$6I@@twR?3 zvy3}jUQ?~UA3V)+-%ExD9yzwXXdt<<`gB3b*toW&gd>DzSF6&2nDQXmJ?-px4yX3) zq?CXlDx4fO|H&C#r`G`xT?9U>Vs+S6?hEDzL2Y;+C z%$c+{q;wj#P()o5V*MjV9EsX$D47H9y?!Kxh=F2!)=R^*(Lz&q4JTgladG{ zr%5??w9Idv9ueask52SdY@J6^`u=#64Q!cDi0WG-Z_mY=r@@L)(9rH;nZ;x>bMZT` zf@E}dm8U}@8;oTePvkgpsIaysX@^EoLngAXKlL(|Ul-3!x^ct!a--Y4Us#Aj=r1h18+5a`N5fb28Ok5noSXqTC~=00e>L|U^i za<*mtXgID?poE4hNuc&TS6sw>dY^B~vm%dl8oh8D5)vuPdfOji^p$w7vt^=Z z$sX%`GrLx$IIq6V=!b;ED(5wsmz+gb!zD3?VhU|-r;*g5*2^1uFS%^K>3<+rf8)G% z3SAxI3fH>d!y!EUV>A&F)?#z(MPa?;Q77~BV+ZG{M&)=F#tU(xOi~QOO*-52p2(t^ z@H$#c;&-I`pv!ljQ9^q|k?#wc^{#ymBU2LQF()c>T49REYsBfvQX*Nwl-rm%JAH)j z5+CcZG~j=z;{jQjj#Togz#Jp9olrjWLzPQ$Gw0c#+JE}AOPR{|RlECIEFp_8i?f|w z8_nsu;FuMsNuao-B)9(#?!v+GmbZQiWmcvWtrw4r)|0{35zczwK3|$>0Vj_-;mH0m zQN^yLiSrEHw8rj5XwuxXP^Urb!N{0Whf``X_-%FE{l=q`=-VuI%V_+BIBcKyed8Q^COFjQo+QO@jf;nND`qD@p5Vi zFzY7Ee1nWWtFAtltX3C}N*$jQ9a)rpaM0zA$mPQeU$>{!u^c9yPbGQTtVm}qoN48YQ=d!b>iB=+`piNSxYG39USt6x(%3eSK|>PDR^J4O^f^s zLcFD8?OZCfSsSacxOWeuBSkvW%g?KHGUeZYifg_6FK_$5gh>&#mdPG_x&J^m7PU3XD{A=mUAJus74o_tzzjg&e z!3vk0UD(07BAO~!u{rhv*Kv!C+Fy#CLV6mWmdlJyVijtCIs_bGBzK~FBc!T*XSv*) zzaY|xt~$d-4dOviF7cQY#(OQ<6SZ*~4*FM;Jvt+^17X7tIR)Y19hR!AN)VaqvP+B| z2`4ZH*W%To27mk>i-~ySN~noW{W=`IxdQ$0=J5ac{W;;mf=joON$`B2^&b7nm;U4T z2G{mcufn*9x@!EUHsE3m8#N}>1-q%VP}c>{8m@@fXV6oNZ!EK3p@wsg&&r%R!OhBo zM_7T)0Qe)gh&=d$e*HfFVInd*uKe~R5;l!>W)!h7AZT*FA^|q8uMK%)z2H7gfU-fT z?Xe-5Pr?@%N90UAHx)#qJ*gH(B|y@UeA}$|8HV2#I$qwvqflgSkAbZH(TP(uy|a@w z@4;j|Kia#xGEYMduJ95|*9Y0352K_}yot*{AvArG^!ddF3%*bTZ(8CvJ8g)>=v?8j z;W#SoM)ky%(T{sTD0x-IUb#$4$;ytDntvwJc!zRF8`UxRSE zBpuN6Cs2FpHn`WtoPT2e*QeLw1}V(Q1E8B2}*EG z*j{RLqoi?5sOez2w99L^G=IZ#?pK3X$+*)^;Ad%f@#2rYHrTXk9)dHVFJ zq=dxG%#6p;%EvNfO&nWeLqq(zrPiYs7P-TuI}rBNV>twip;>l5xJ{b>m{^b?~`s8 zp=5bCOEKvbB&SfYLCBj^s@v9P{y1E(^l>$!w}qe zmwlEs6j*y+mAFqeJfMHq+Hxm%WASV5+NZs5Gp#Yx zFj(Diji>tvA_+&vK2S<%irrL2T`3}K^UD1Lj(+Aoi0!?Qr-X?zUDlN0lfjt&&?%_o?;9$h9RG((Tytlk~5Ky-e2 zBU1SA+K{BAB#p;9;+2_abi2y^xOjNz)7uMuc}_3l;{1E6oNbDpl$j#(WX#4s)CMm_ zGEb)pCwy>!X&^scas1wp7`HE7FoTB@}82b+G8ZrE|4qkd%mM|Ls z54^NNQxP#Jm z!MYge>+8PV?UmyoF!Ax60!9jNH~0MdX9^o=bF;LxG$|2L_ooONk>seTRM&gQ56VnCK89Oo41BP6?l7=~8QY0l^71%6;E45N7+S3QGa|kKDh!=1xsbMMlHkH{;#2 zmA1CjH-Y(1qEVIUx%eh8v|O(=n~KKu}Ccq$dfSMOOd6_uneVFc3N z^13oaqUAY7!f^)u^>mkAqoAw+7)VFEHj83jU%Konid((;g0jQlX(ah_Xgb@?88oqD zG7eVUyey<;@0zW(MHLm5R2)(<{Jr%OSo{@gG5m=piPo(jDpfB2n(KL9r#qUWOuGpZ zx04H#Z1Q<(Z#hM}tU}gQ${`>~$k-(p%GR{8!0S}PmVLI{Nx&dgL_<(}cVqbpadP@c z>r)wx&C2y?dN~NwyOZ%dezXy`>iw|jL7*)wLZ|I*mJNG6-Iyymtyj5oYQN* z2$gw!2fmG0vREMz1y-i>!OtF#y#vD#&g0W|)hU{sN(^!DZ_+a5HFw#3o5bYAi$nE{ z9Cj;~G+{Lgb@(CTUL)bfdp$HDEkda~kAn(e7+(1?pQLjXuy=(L`&%1UHy5%}GT*-C zwjSdX7Op8Tj~99UrIceO11&Wz4QZBYVPRpgKx?V@t(>l|uB+<-@W0|>VhBk{1}g05 zx`dD9_lhDCD^pedh1BX}A^jN@o9v%ksb5Jx_awFz5rn8bd*TROif`QC6HtSLcvJbZ zlu`merKP3O29n(}2F6|BzRW7G19N6fAy`DH}w-sa(= z{1g;Jo`(~=wOX}Cea8-};_cV0JtAX?eo^Y%Q z?v2?)mF&)R&USQc#p8Rb!VmpxS&~{4tTjs{W!7Y%dfBs!qS<(#5!{+?zXV`E$8|i zO@&;1%$)+32{uu|YRo1XSy?|VTpD4I`EEK+RaMpClo{&88Rjb;&mWyB9X$zRs3^va zk%jdP>1SD6?5&R1)2@y7Iiv?N>x{IHpu~qqfAUchK7cx9Me8L=9?erfnCuUb#o3id zeJIrp9bx}$)+b<*zBUWorlxX)?c5-y>J_RVM9Vo{Vf1? zm5B+B(>@V+X_rM>PwM^ATPe|JxAM-iPVz-G5jNJDh~`?EQ?PZDr+vhZukNKwh0`+tANA$_ z4R4(y0Xu`Or|$jRasns#JEbhh7lAEF*Oc?_og47GTb%FTGU?3A$)WR#K5BYK>JP2M z%eJXG2;9&2)G11^GcfRCv!HlUKX(2EH5Sa@Pk^Abej2b~S#8JhyNz(MI&i*fH+|Z8 z2kNXMc(fYCd@CuhGdAOm)>J+T6nRyg?|a zzmbEq>?xSn6vs5pj|z+{U58ZxLi{^V7_vl^e|3h4em)x9{@^@&0p@FaHbwdK z&2jk`nK5kYl=Qji{rkl4kps@Oo_}~f#ORX>>|Wp}3jxM+QiDr?mwJgJ^~>qUqd;sj z{abd|2HnYx0Hwi?9I&92E8)Nc6ZzwDUaG$H^QPui8pg})`tyi6kUt6;WhsZ45U%Sa z3IXF)&S%G4T~<=K-`$kbMX&ys53|~lYj3(~U!0(z1i^50bOerhp0v+WqsoxhBuQIG z$IOYo=9-z`w@>bIv9V^K(2B1fZNgLF&oyYi;+J7PUdes!+O?}!GaeRdzkT}_>Uw&7 zP+cu}ZD(w343MayWk*R`Dh&gG;8r7LzW$b@AHuC1%j8^LU8SU?G&D3UEtlIlYV*wA ze$IdL5fC$8lg>nd=w`1qswyk_1q3Jtbe0ASvpPX68X6fjL7{mX#eV!r$?9Ta^(98_ z!8nTX`VNcz3xJ96yYI3=LK&R<+jMC73IR$61O_@S4{h`*i7+Y(3nrWd24v5t2J8LY zw!c2J0S0xa7-ODh#pdU5il(L}78Vxh9iz4vK(7Gy>N#HN*q5cmthgJI<>Yfxo2pgq zvhjs?;;J{EdY>%zfTDuJI2Z}2W`MLWO3J;=&gSdu3;1ULw%!Vt!RL+yUcAh^Glkxl zO}xCk03oolTFF*P&+c20>0u<^IGg3I_1zjNHfRpOBn(!gtVn-wdMN5*Q@!yymh~a+ zWqc}FKaLIHVyhf^C_gapS4glKbiWa648$1)Weh-ivv0AmgjDCw07lr_+6v8ivaVZH zXku?@YT5AKVsJmXpY~_bMY|6=!kNnFxcK7BX&e7y*t2K;p4^IA%*145G7}L9UPFV% zIs=SXuXYQgjJL471|ur79FG1pf-=4?dV3*34`2Fc@bB1lz!NTqwbk>wlkq~GTCjwT zc0Q+Z+mn-%J_4eIkdn7e4_?&ejAF@A$H&%TrGZ+4hmsR%!U>}q41t{6TtYk74k+lw zfMJx5k=tMps6lCK0a)c*A6_Q#+B8JR@HIs}d-8~)0a@s+m!Gu@KAyz=T81>qi=CX~ zthV_D3EKGV2?b{niBGGbrqm|EEXML^6h>tegVW-N-Gx5%2RNf2ZJ51TwEEgs^-I0o z6(+tZB)rSb&A~}c=7S)GwYAAE%FD~6Fuot2D6iWkN+DuugImHzH=MtXWACbgnPI*#YPWhLkVZa_hhoQxXS-p06m z6`>)0oC$Dl`&oI6*kiH>Ft%&g;zhiL*`hYLwsJt|yv@pr;hh^^)~k!s3j_rlo0C=N zS_VbP4D7)Gm=X*mdfI4Ucz;sMQiSGEP(%CDrSbF`BJeMQ$Ez((q41H9iwh)ojoyXt z;e!V+U%o_Bb5`wwK2lS=<*~mG{sFt2O3>vwpL7HzsOrgDLL^nho#Spi`A}vti0hTX zp;h@}f^iZTg!}q5)l8u9CM}*$dRp3p{Kt|Z)0Gppl{7U0V#v#d#$7Mc7 za-cq|r$^VpRQ4spcY*o@m8=jss;Ce-poyVx-)1to_U!ZsXs!Ar0cZ2q8bA&Jit|Ut z7s;tXWy6b!i4nhhx1_XGDOoVb$_e|$YMn3gdutDe?<91bCV3Z+qU9%(4fgl7t-NiVlIHAY(D=RA#lW|ihG0YbW3+v^LCsLN> z&65npLjJTrX#TJH8`T{M?+zJ&b_Ls2pt3SML6(hv=-l@h$)GnwhLl75>e}ZFMSWAt zaB1fkKTx=^pa2(pRIgXQ-k+0?3v911=8Iz6T9CYFTxBPRm!^DdF(!APtvG zZfM9TTzBrgT3H7a4)}K@*!#|%iFcMGD&29&Z<_*#4eY>F4sxfNj3O04Ric=sEsraa zC8eYq#)5|4C?Ezir&@-AHjOXpj#Mr#D|3)G z>(3@2;=Ix=5s55E9KT=JkO2_7G93jS9epenGX2>SJ=;SgT`Z?@b7iTp*4Vj!{F2-5 z(jcC2gI!Kq+TF?ia4bcX%)1{BHW^OF4O8UINoaZy&Avc&qabI7b{*eo{h?k}yJ{xor8e%mM-pu;@&7biF z6aBZ603ZVIRNH0hX=@C#8uO^wWI)Q6$niRIG5A9~yQ8q?5Ub7c?DPce6tB4?XH##l z7np=h9f^0g+G1IO=a_{a795N)?Dw^8z9-#LnvB<)l9F=w@h3M&DJe8aZ?dgN5hH|AxlnXO8xGhXm0T4R z1OPm>{m8$de4hUTeNVt3%|SPaE;r&?@0x=pu2fEb{+HHPUl~MoKA}mlSwL+89lm!L zBUFKBitZ~8KI97UqoFeH4Gt`voaF#MIe0uhZ|^sk=et#>IF3c&b^)w zGE&byb3|pn0li+-K~y{T`7Z>-h+ZVSvEFfw8f`!mkXt%By5ZqrW~JnQogz-8kd|H7Y-)^aUwZK9Nu5_-icY@0$(aAitqi9q;)(p}d?= znX*3P?ydIafNp#K9LQf{Y?YZ9+#T(CoHRWe97Ou@kp2A1U&O_Zn3h);N3G_bnNERaQ6>5iq~0LbtLei=)SP81Eo}u z)+JB{V*{-<8NPaHGp^@dHc&?S7lJ<;Ysv#cqUX*_S2PtT7D?xt+bGE7$1j24uHE#3 zqwJqPr{eX0I-mb5SG<1Nu0LJ~YFTldDw{vrePEX_TvQY>&4zz>TT|b?3mrkk27yim z+DfJxgI?9pBZbx0#ZZyM!SXqsI2s-`Hrmpjl3@MbwB) zL_y=Is{tJy^7_E}s>;g?<2hhXZmlsh{JmbZIkwy{*|kRA%8|m$3Mp}M=)KPq65OX6 zPZK)_$w&vkxzb<3nDP4YFN z&fwwBQqC4=3w!kF5olm!eUSG?F-siS@@!8&gbh8n-oIyA3->vnQzifWj(!;pUqQp- zcYuoZ|ACV+xU{_8Q@=HH&Zrs#<4^IsA{F*a{OT(IQ~Gur%1ADI9_>yw$o}JnLH4%X zUdJ2K`pk@sVvPQXNG}o-;HhZbE>GS7g zen+e@P)}1a(bS}LJ;7LV;CC=IyxQR(jAKqrOe~pjObF~c(O;jW-6t0@O?3HOrQWt4 zi|0!%I@(!6r)g|xxPJXQiV*U4Mu6=GOcL@DwAg7?IpKr>993nOFVwYu3*o0C$CbQ_ ziGVEJ%LK*a`Vn~=XisuEvuKUF>_N+;MpK<56OE($qAVr|HY{VV*O`lp=H`uvpbn>3 zdIoWa>&>g}p8&R$3N?v?@<7TQwQer5S>fH_Ty3C&W4ud7A{GOAfK>Ea+g{U1uNO1@_yfWSarwNCT^9eL zAiIGPzWu&bcYD6ae<;{n|HmdR#(qFklx zA}H_NynXw{5TY|^APjhf)`H`Sy$x?41ory5@{=z70ZRv$vMC%J)Zcoaoo;Mw0IuQy znQ@p0{ugM72)F>3U+?7#Tn@4?;VR=B0Yxm(JRE{Un7FyQdANduGN`kh53jxaN+Zi0 zw2UCIpHT@of$c<0LNfdPyIBGia!iTRN}b@n(E%SH_ft@n3PNSkl3WC~-=Ftp$Rd$I z{ss^MP_z$LQ}63AKoC%h1H5ce(e=C(bdlsfKTlGJKJ%Fe7O&sD!^#LT%IlO( zU^xy?z4}?r5y%O4rc1LgOalI|(|osY(%*kCwkiqr4h|20>aC`#Dl02%DDv8o@Yn75 zGt85-K{*OQtwm9A>b@>DY`r|*%zqmAGtpU#&oHsG%UenPW?k5_YQU%vOWHQ0eStkUuG%* z1!rG(whIlm8(T|22ZS8$kD?xYGAMX+ljeCkwbUeHARC^5ntqP`LhoD94M@l1Sn#M6 z)Ps0Hng?Wqff{K=6uY7Jbf*xAGJ+$}L=3(^Elx#6#TyBzj5aIf<;%SwLG<>jN()hi z+x$->NCHb=2@2<~;T(>a{omV+l|z{j1v7DkJ zQ>Pd}4hkMikW#i|XCmCprRdOJO@kikYOvgX*2Trepd|qbS>icAsOGm!l<0%bvxu;; z09X8Cv3!uwObOH2{&*?yDLLN^4ZXV5f9pMW;1C${7v66!=>T>>o#w3qIDdfX4DUjR z+|}EIOC&$R`|9c#Zky@Kx}A)x1HkqLry_h2vt*KNGdVx@@+INo1kpzumg=zY-%G$Z z`UNDKI5$!GfcJOzE|OyjRT#f7G3$ew+1cL6Kk%h{A=X++I(=w)Lc5Vos!v@@OTmh7 z61X;X*?D;xolvMmiLs#9G2f_~po4?MZB0h~MtmSlvJ`?#eifd9_NF?XA_?eQyI*{#!S11`|FI2i|O8E0Svf z+x&tl(Y2#TrN#xOb}*;yLv|2fA(D#&olq2{7wHyy}I#NJ&uwE3Bxb zl*KWG3UoU)^a15xuxx-);}eiuY}gtN{6|2{`htimVQEX0ckB#JO|MNL?gOX+>ZbJ; zIKe^ACmh!M1EZpGfv5pQtcZtBRxGhnh&vtLX{YxR(N3HOIZAp2=;GW5`Dyk2KU~RU z)c$aOy?4F9o!#Hxhr#qK`Rw?&%gp*F9}`f7fkH0+69`<#EP3y1{bCFT7}4*dFufbQ zVWw-}J_)(+UgeRuZEJ5|`p6ned!*_c9YAx3(?63?TFNp)YH~Z z{xHnN$#T?>+u>hk^^U%!#xgWC6m)y&`3(aD{Rig!^ASbCAe?bAFBT>taBFoL=f2;>)8%*@>6zjEdY+|jf#qLIDH z$k?=y@h4Y4&-sOhG~RRjJWPQ$2rd5!Gyk(I&cx_0;FQo5!|^ko5uDLLq@EpC{g_&` z_M`j~Fgv8`0=~dNX?&>j#g+rdoc3gELJ)wGn!RuCG0aL4&z>RUxsJbIWnb35 zPW!u8#iLaKNXAE@Tl49Wep>44+x6%)K2fo;O-?PKiD?@26Md`o7P%4<5)$FmLrEfr zZ&UwsT%_!pEnQtfEbg?+|ZSkR&*SQ7Qqa(0T$>+eSG9<6?z9)ZB74gwbv{kUF|B#-pI-*k2(rTlg zo>RUCnORvW0?rX`7gjNu!K?Hi>;!(}W{C~vUmRz+EiM(wwgWV{u~&}c zZbDeC{H;Lqys9p@wAV2H@lG+-DL6Z+k%?gfcxiOTb`1Jvz%i-2mW!Go;R83y&(9Cg zTq!}65#K9=^1EaV0yt0NXw95 zS%?trduGK%j0ztEYhbT71YlMsP3b77cpp#G=z46nG6RpOA5Z?(&F`SH1G->zK3b21 z0&56igFgen#dKiRFfvL`2Bd@b_wT@d$4AhjgSW@YV->UlyoVx3F%lQUn69B80el%kopqxC=?KDP=St*vy^WsX1e#^!`RjbVQPai0H@01prF!5EP8M+Q z#4ww&cSD~(=LTB56Wd5z%wMf$(^aBVnN!(5IV`ZQQ)0dJ6wA{UfK@$?5 z?SCOZZcdsf@;kN}7k&x|Kv^^txZ=3Uw}`eyezV#4)m?dc>)Y28 zM(QKfxA@`tLKOywvy^Bw=&dGds2<2~$AjErsNj6O57`hc!uMa2S_bDLfiE*?BV8T& z`*px;BOu`}N=z1Xy$R?PiefzOF;ICP=s1-}Bg;zi^Y)1or@J3L(9Oj`!<9yn=rsJG z<>|>0IFnccj)8`SVZ$sZYEHnD^?JpUNiHRVoXt7m%iRy6Yk}($7S?Q63LZViR0z7P zlG52sj8ZTT+~Fl~yzrzn&@{tAy%Xd$a40oVIJ!IERco##ia}glJSRrFPsgCKS{L-g z7IlDv5ylW02Pns)p`lR=xv5VV=H&Rc(4GD)#kRM#>GGghP%4vjllt0&LI$t`{SVr~ zwp`%S8v%sIJKmd^l(g?@^r|RGF8;aFmYjfGi&1JQy?Py2=^4ol&{?7K@Zm!Z zje9y**D&IFJcu^Vo? zVh*eC`v7ACCo2bEy?V9$Li#sdd+xyyj0IXx{b4?cYRS>jm(>%|f`QEt+~y*5gf9xV zm_`#gDBK7VLM!F(`%pG;G%67D$++|bg3f|I{nXta2-ynCuZD&+oK&avE}#V?jbAw$ zbc-aX^qc;)AA@@**C;1GL)UQ-hCzeT4<2x?H_LPRfLQb1WY#s#b)@t1hqsMV6IJcO zJMn89EJ8s;{6X3oqKH%(JJbfW(I;c#Vd>=4CIK&?K*(k;ML811b xcPWwpMT`wK;AyD55d3n~`G_t~#&4VWF!?O3hwIq{SVG;uIc~) diff --git a/docs/images/viewBudget.png b/docs/images/viewBudget.png index f33d1d9f93c601560ba1d4dfe829d615e3f2afa2..fc4c0ed2501fd8308c0a127f3090bebe17802b8e 100644 GIT binary patch literal 9377 zcmb_?by(D0w>F3(C5Y0JlF}s|5`s#pNOujO#2{S*($b;A2ofTo(hQx_AOol%jW~42 zATadVSdWkIcYWtv=Q{rk%rEv{d+)XGb+3EPk6GMalb+PJttohA7Apmt^sF0S@= zycUl3ZawcAz%cB#_jFx;UB|)(<9MV5->z{uB}cS;NX}bzs)a7dJOXdy`~?&l8U0}s zy!li9PAN(Jf$y_e4te=-LQ0{jjUfw$Qo@hISW1YL6p^6%Ch5L?7VWENY!duq#_r>L z1ZEFV@qEUaB_0v*cQ}<=c5Ei_`NbKxv;zU{GzLNf5B;42>KzS4uY4#lLD>EoInYIbFBKuAKlUpeY zeQ;m2dIf(`a%agKI@=yf6)%UY;`Rio5 zV%toWJ5ZCRNOg&9zU~Cr_KTS_GX#mZUadJ9&fEqh&pMp>;dd+o*$v zv@O);#Btp=&2a-_VB|ehdH^Gy=tV{eya4D`7NG#BM zV*?j8aZSxoucCu!XO#`FiQH%FvyP#jn`KDvY+=}~K-5b)=F*~A%qoG9y3Ca5U(;T2#rSLo})3WcDcE9TBpG9 zjY-4N8_k@cgKE4F=SfLFW~n3|?(amvpHLM@i;3yF9O8CHo{x2%HithFuxOi}p2q9h z`Qq(3{~;qlldrY_*qtKdE5XIZB`&@@z^xu@U~rR+Bp!)}t*6Wh&o`_RcM z^~|8c!K&xMV1e}U!Da`=rAsw7A1{j^Mbk+>d-B9(b5?Ej(Tn)_hnRI#xWN=yv`JKS zw9=j1Y~jJ|GBQVVX?`Ka?rX-=V^z-V%klB?K|!ZcdeDu@){c%F5W)&f*2}WOy6q7o z_i=JcN>TS!L)TopuDRo8gwx6DW#Doaw@0>?1`~M4}|=LAA#gsuU0oKv_a6~w5Nua|Ac8HtE_;3WwJ{Lc)7v|^H>0g} zW9Gq$H|$xKdu`nh(&@`qYmd4VdNoR1K|!I=xbFS3kadq(c!R@u^~z8&4z397g{1o| zELE11bI~LmAMf1&S#-;v=QRYv%(Hzx*Xb- zF8%r#K9hRna!HAxYcA(2bXn~Ix{FG<)bPYD_bj!|BKFH343;~Ld$oj-A~Vk!+O^TP zPCVl=7}5_)OBQtmvolB3PZ4v$5w4c_bAqTog}MX&~+*T!4U(&@-jX=Hn!0V+yIHuDo$pP*AYk zapKEcEw228IgOh)#UDnX2>J+B;nH>vh0)&7c+#5J2bq?r)3R z+k1KKWhjIu)wwQd=j4}+s(qp|qdakEGnI0eg}dCux!U;z1O(>lw4vFm@Q0|T;O0;g z1$norm}0wOL2g9`zk}j|&P{7;YmHQ?U4~;!JMbTNwddbDm}B^53EF8|jbXKi+oNLs zsCR5qgzIE(4}7Am93K=>$y?A#x=oAImAL`OW>$_?TseQ~)qJTIDJiKKw5gMq>xM;; z#kbD9^mImX@hbhY``lrk<+gpM@rI@JUG4 zzSQj(TeK%J*k7Y}D`?gjn(*DB^LvK9@;OiMB26G{D4(25J3X#q+|3{m_uLUWvBAb* z=5?7xdvx7qkK|h2&X=(b|G@u}B$GFxbg8KX$m<6Nh61iN~BHB?k;z`~1nX=QxG{FYva2rJ#g z)l-IX3gN`Ih26TmG*1DyAFJGO7+o9nyE#U%FKY9N>JD}Ny{<^#P;4_w@a1MoN2Iop zG6*$g$=jzhzN(ZVr$rDr1HMMp~ zT!xbdMF4Az;l3D@@>F|+j3+wz$ynkSkE!nEWzU1e7II9Bi${s%(?S)>lISrGgj%wU z_wiv?R@NLxl_WXEYS(+OjrUKvCTVTfGZxk@-8nTAjVR{6ydQ}!r#^S=m zx4S0fb6YF2n-j*J^nX54Sc|S6W4*Pi0>bg)+_k`7wNUn&%mNj@6DzgY>$V0APKK>I z8Mfbb;bcX5i!82rn6VR!7OTHqUJA3+c8!OB8~+#;M`_vCK)?_bItX$=-!q=zha%UT0!t8rZ@jil zS7zKN=oSXob|qZR73AgVJs54j)CQxOwN=9Fb1ho;`j}Xn$DO9*95-HlUw19D5ah{| zlq{AemgY)?{h*c$2W*$NyaVCt^LMetmH{YQ%z9Boi+*HKe0kfW`U$)vN zpBVSCJpHS|Y&${-VwpKzvl9!d>ZE+ z@Dr!nHRQ?}{G>vtTCI6@G?KT~(`5WGv&n%0ezQo=1oqx*Eo9_}be^VNGom)o?S9{OkM=V+=lBBn zIpNqfeS;=`guahtxt7Q|;Ic`nUuHLZ-80UO97ON&vb*N#`bbP$mPnQ;*SG%M;%H>) zXEU)DHo%HSyUvhmhTyPxHHyyuY)`GczM>H*|yJ{KEDq zIKcfhOjazTe9LJ>!|v=gJ3CrFR2SdQJ28)SouSbRzuv>A$aJ-iz|~EnWD(zPNAZ=K zl>TD#jfL0*)T$V|qr&6vcSrpaM=dne&aSS!wKTyuc7d1au|lZ2;QpwiN-0c{6HzP% z^;1-wmQ|P)EqdEA6B-h7bhyS2W`;^wdnex=rN3!#YNvTNmw|8C7Wb7_?okMxZG}VK zp?_#Sv2$$}R6-Xtk^rw#D5VQ*gOOwYkmE(>q&UEB!` z4P_96rckyflpma>x7quw(>hWkd$7J)vv#!R$lCw)zTCH|T9!o9!Sbd45zU;Qs<~7z z&1~e}l8Gp)!+J+iG@?J8?V#9N*a@CjG&8CRa3;&yeTs#s$C@^ zqPFpQHViu9DrkRxgTKzkIcM^c}aec$`uD>&lpgZ|lW6QM)Xz&t4yQYJV}*Q=H;hyHUPP zej`(fgukJD!_B@%JwGaoXuL6Jf27QybPYd<5jx^7{xgCs#^sD|d&7?0BG-ZQ-_XjC~*E1#iZ>UGx!+pPfTzvHk!ojgCN}uibb8P%~#@pRZ<1@q*k8$1N)u?e_V-RZVG$BF%J8zoqqGufI#a-W% z-EvT+LV0d-ZdI)Nn1clO;{9M2p`P;UQ#fCM+%+~8OYQ7aV-y7?Ybl~oI@oBWqdAe*%7OE`VPL=_VR)+oC(^CAxrZ?<3B$f zwoZF|$b{!@+I~Z@FG>^cIrCxpWPYS*j3wlBj^O5dF4L3MSk-%KDMQK?ApY~NBrHOM zU^4_KYTsT#e9qOWu%{~N+?ns*7+tM+8XlB z?oDa<3ZSE?P=jP&ZnDZozVSzzaQsln09AfeG=Oe47M48S;!{1K zI$>jH*8!Cas93t5@dR2ohn#!!=8c(|SzKHkxGUp>DJoBS`SLPVjP!QWc#|2egbN2V zGfpoty;PE946XR50;8I+u&|@UeP?S=&)s*Aa5C+`E%eQS^k-G!ftx|#ZhAx)Xdo~l zHIbmFudnaswhb6FdUJDwdoq4kkE5epl1kX-{ChrbZnFI;Ec+zE{llG!iDHYhkrJ+p z@9?ASM@kpKsO$ZJQqvy<)qyetl$*^qpWl-EJ^NT{+Xt$Gj}9pQYL|smQ_Uo@hP567 z?%VSpaoW<359UBg9V2;`hziSMX(0d1nKS%eAbmc$VsgQ2LmK`l>XPVWBPf#245?p1 zcFN0@8}$(K)%rInM^Z7lwF!*yTWvq((s3B8#AfE_Ki`w791~3~g!>*PF6p{>ni&+} zLPA1(d~0C6BM*xP8gJaXRbn7UlxM-uYgFxmYC5x8I~6Ty3M|?H1@TztH>4bWhU#wo zhlsUKyZ2A7c)S9YfZzV;#LzdP2IkQ+st>xsIIK4I%Oqx?7!LAIZ|+VOC83iL77?LH zZHv0}U{isUzbI?EXKAod;hvPjy?bPlgd&v}N3YNJzmJ^Z=HjwYGheT9FX!+$k;`h)2HN_=IJ3q=$a>|rpk63j`ki<#X8^^Uh%xxmKu?6lo7k%$pcxg9SF^v!=t>eFEiI0V&Bdbfu37TJ#JC44Q@H*zfs z4?mFiGMJ94ia36uB?#J_iji%@zA7Q%HB@AFumOaKZ{J){_U*m0$7AL82KQPXzKkUp z|2w#_omQw%66|0I(K zy=k(t!ouI;l<9W|EoMJt6%#Cw7u7VE#(y2V>biJu{%vI?)ykvWt+d2Y_xLO)j)GWBB(Sh+d>^ zB;)B?ZXr8L9J_{M-Z;Kq?eE zi#6l-Ng8$_R)Hg|sHo_&@X6}<=_BwgnHS6FG@y~t62 zaet!TcV(muRO?2oAZnJzYeW@C5!StE^h52i@~Ns;w~wT6=~6P_t`hv&2M^REYz$P^_0jDNCT%PtJ!p&mzrC{AV}}R8^50vWNG~_Dk-q zMn*-oA_9b%n6POAv1bNzbz;QJtdy=_-{5NwP#hlYp;i(w)PDDm&rFg-{Z~|I%owA~ z9+16ivTuYgTAGgM8rN0(M2voZt5pM3uHco?h02Tem9WF=uSCSe#F%q6RxdfSn+Xh* zp`DJ@*Zw`Cx%mf^@>gGPlTlK(zZfC%dJ#F*9<%BAd9DIVKP5s@0K}Jf96UTTJs6Bf zxgO7zD<5Yq1NvX)^GZn2tXPY@HJx~3N7V||!`|!``swQ7kMWCqAHh65#nD7`5>F({ zsL9m1Wf~695h>WkN9ZoT%?X9;c`D^`EDVs~k=H*qHxP+x*8&xIIxTw2FlLD1wp? zGI#gt?|@Py3x(u+a0eIEO_bY@>X+Iy+HqSgkLsVxq~fgz;IQw1O)5g^V^topJNq+$ z>2%c~W%obp*SM{;Mo=P3N`}$`->`Icc1qgcJ9?nSgQxACH?4~rEw@ijNYI40c4Pfq z=~?Xr>S*ZJ;%7p9{Dlu0%^x$BTSueyDjbZIFM)hRxwcCNe`!?MnI z7T5d3VA3FhAIPY5p7T4dA_Q@O`c1>TkziMnn`(~_UwE6!=tKMqKL39IagyJee~mN|&SXI+*UYz=2fkw1*PKU(9I;60kVhW@vqBw`h z;x{^XI<1lc!XB^p2gM5Y73JtH0$A1G-(OTz)X~ua5Q#y?XXqodd@=pIgWnm3cJ4$c zX$^$TuJ)ATTX*eEXI9{y-kS#bALEINs2YK+aW;!E3z`6dE@*b_GautU_!o z#QV6msTrC%>ihu#0fIt80E9t3xH3lctCol zmvFJMv*VUpUYc5wdFdO@C>8U|25G<~imZP!382jnLV(@=#gOjjCmeHQV5L|b2F3pc2tTR18Mjc);}q6 zTFgB>kJ-Hw8C>~BSNWea`Mt-6T=?!!-n5-K38*PHyA!@I+3*VD?W5iQK571a>i^+2 zKq>u|s844!{fvbqS>gR3v;6|LSrhEPu0Yt>uI)BxMKj3utYCTDplLGn5D)+g6e$rD zJOL)q>hng;W#Gt>NTm7;iN^D5RcDR55kE83iEBrPMMuw;d*10xM}j`c3IkNkc~%v~ z?f4x^IuQ2lN_LPb>fsY z49ks-B!X0c3L!oH>%hK42D;lh=w~$Dp?&^wqPDh{=IVW^Zyyv!3OV5d7D~5n5g@9Z zj}CTs#@$VB-~IroVNz(L5Wj*FN9<^hM%pUyLO?A55EiQrch@>j)W3SgVtnu6Lv+Oi ztZRw$drEeX*NAI3B&B;AlPv1QGues_4=idZjjzRnBuCb^wSu&4I?3Mv7RY-72l1 zWe4b6>E!7?@|aPF@Ee3oe4^-Bkv&|{pt65bW!f0f7G_EFP2kgHKs1Hdqr_Bs9W!57^pX z0b3Wthoa+#gM)+VM@65v{P2eA-LzhFg zGQcrB#MPd?T7k|>(&k5HhE{Z?(^MPS8U7e%_PNE+ zxwXilAze2bAl}ASzkL0gza2Yo9Hg7w1|pS00|Cf2XWyPEYoXi5&1a9ezd%m)h!TYoV#KgFC?xy zO)4(qg64*?F`IsqesJ6!oqPHESF`H~MzJR2hbh{Buk>&sCymn%8<3zMR6#Jh#O#bk zF7?3al;CNiF&O9)I&m~Ls;*niG|IQwVcVT4Zk$pnHL^|?u`j|gtn<1m5>$&kAre-A zNZip0@?~p_8fMo>1;x#5{ti$0A5LmQ8(U=Uy_8=OLQMA_5EBA+8I0fV45fIW|F|`m zT@E8m#Cv<#dWL9BY10(6m-NWmFwfZH9yQ8@wv#$vMVTbDi$xnZt>|+jN?97I~91RlC zH~N@)Ru(dJ&ZVY@JyW)ly8;N zu7GN17u5f7M0z^b5`8%|_M&1Il-H!b7C5`^8wfI~u`7k&OdcFW(I;Mm^2jxu6>Z^% z(>EgN5oVF}($D|0hfV2H-|0Y-#6I7ze~^nMWTevpW&@Ci2ggibNW+KoSpMNcEJD=W zdZ6~I1EgJBo8nl;P1!Vf%oZm%#Y2NV?9={Q1B16mJ!x5lxd_+eU%RhL)Tx>c{QWO( zQBeY1Ia*|((1h982rvc7$JyDMz+k!S$W{iw} z1I*XcN$6K4ql6JrwGA5uz7WR4!=qMQN&W68?2f5n#B|5j5psdJySuxS%Zoq#kF>rU zG)s%3ouW|bL%?B{m+kbs@tUqeqgYv3-gy9D_{>Lt&h$^Z!beOg4EpO4fpGKPKWeBW z@*)#dK1%)x8ylO1Q9V-hCz<$>`nj5~9}~9BeWxA&)N2UArD4R}s8)n=o!4XDCV}r+ zNFm7E1a#F%Jk%gSvO?fB$zCgsI0Xf*w<(~WHSzvu)9ta3?cVXZ?@8>JFm}*T`mgU? ze+gx(k^f(nEo1l(x$pnc;rp%Q{Vnz>)}jf9{&@GY@$SK<(QhU3zwaIX9{Hz2_&;ts z{!d<9?%-x;pHm57j68KlJds-N{HzlPAjc(z;D;t>ZeP?H;5pf0x>(T7T>1WSz#x4$ Xm^790bQSom5Z2A>>WT&OrUCy2p^~mZ literal 9357 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�wt_~4Z9j9^`$wzgvyu%w!O(D)k0Op489yuA;GHKkAbI}ll_ zmexZYW||RiqCZdHbeI(U^7iFRwDlmZHd>-B_oLnhzI|3?+HxR2O3L@9?hSPUe4Tj3 zw;X2pla(%({%B$0;T6Dn0SON_p?B6ca$!6t)rr0ffrl-qi;RoJV+AmUOjF|5F;}y+ z-bhV-+&tf6UGJ0pbfPf`^9*vXysixBL&b@D(Zhbg1LswN9t$-~tgD|bq2@KzR!0tJ zJcS(_pK98WmqM@la|&RNl7-HiGxk}ZOE1~5Ad!@F@Z}49K=d<~&Cj3Y5e*psc}G+2 zmiZ5u!gS$2$5D#_3yh0DaEj)M+YiJ?k&$Tuz()x8--7i3)Q(IQ6~tjXOLA0E!TS&* zD6gR4u`;yuxhdpDE&E9MxPqYvbX~Yo+~ey=iKP;?K?6F1Accx|R^n#>q@;zVWmRvk zD{vaXwy?IcdiCnnR*fA&r`nGP>-Q%gXYG>lW6v9%8)tqGmaZxK{Vmt_Q0;EJ##!hXXDtS>Mq zPp&=7vG0N_^u>9QH79s@{uf`(~Q`yKvUn9Two(*Z=QVL zUFZYWSi01s7ZcN>fH-7y;nbDFK67WF^a3Jwl7{NQM9V-tV*=55xzwVAktiNnLgGN-$izm}Ce0`hHt zAWM$d`9+;Jx+Wu9H0(z@N?doq9XB19|Z;2+Oq8s(1|@0FQ*~b;FMy~%y=fi zI5z8#Qa|;}@2s#JeGA-{+MR9=i7Ak;z{lNP{a6I&F*WNmZwXh=kf0I2wKp}7h|Jqt zpNfE?misj|HJ7b--VP59d9IB&*;AjplX4Sh`eB;t-JNboO97$kZXX3ID>IW@OBkX>sM84PYBLH@CKl(fB{%%U{X}yq4lDc{|OEXiddE(FC0o?kF7!6R5P*73j8P{X|o7kzD0D1LV z!dTTcG?G(z{>UaI%Z-;?UCx7N7~6gbh8LKB;bE}W-#}}n3;CSxHPduGAW_}(5YBZ~ z!1xa|mjAEkNl`_Q|L&3WZ-jNtLj-SRb$Kv+t?_g*cs<1@&G(B37Dc?G3YqtN)RGih zZLw>p{knP2hgy8#40Xz&UDg10EF1KBaxxLE2=AC8px<$?kR1X5fokgNu}_{niHqBq zu0jpwDA7qWk*{9(cW7NM8|3$uG7=|%g>L5bsrn`l4>9)9>x&s#u1np#o&YM%Td=9Q z49c9pJ<;Nn@um^&O9whbhu>0mzS!w0l19vP4VU@awO0UkMMXu=q5VG^Mn^^l^)?{1 zI-M8VV}Tg;|1yxZy}i9vTonJ|=*b>i@RpP-OdLqaJgdF=XrAT_0h_*LE<>}jhaWZ4 zvcNv!9eZzF<1{Np9T^!JM^74c9hZl>qe=&Od$%E=Yz)CBY_^~vB^?BH6~NL50<_Wr zwMy~y`t@L2UKQPog?TcNM(tuCiGP#o&&ky6Ld1IK>no)OUZDNSa++~&d7Wae4TxzD zJk4is+K*eY$bo`E^(HM$vz5k8v%zL$#BwnJ6`6@uNs zA6kuLTb~#7@P%FFu)wi-4UJ1B6g^#8wBJ5 zv^O1}k~1IhsIqb=;CN_6lK`)rBJ0yBkU;>R41sO{26~CwM6W;44T`asx3lluxdRTY z3{5_Q`qy`VgN}~w6WpeMXy^{osN9a?G7Tl=Sgj8Vzz;j@9QS>FedXoljf|$V6{1t! zKqU`grof>5s}jSbSMMK;7n=jXv=9o$NkQzfMoqYr{#>KinBVquQ%tJ8x0$}r6q!nI zz=WMjcPmz z2|r)?3=+g^3 zOu8?1Qy^Uy7pH4|l2T|G82U9rl;UW$^~lM{S{i~dN*8B$EnI$a4bi|XK$FH>1hyaZ zfzEO@UAM3k);aN7{fd!= zaHZeAV;Bk?2cFkEj$1&PEn8<_FT6)hAq8#tT&YfeeqvS?1)(DD2#_GbeF0Xm&W zbDj@5TkJ}5#YV5`PoB__Ikw;1>EY?2sfY9`d^zP&ztxNn{M2bS=0z&|LNw!Q_a^T50BVbu2&TEY zxxw+Ml>b5T=Z=I+TuMi2LJkJ{`kgQzA0Pew;;;}HBYT(|ILZU{c+>5hZb&r~WGEil zWQ9ZYbI-$_C4YtoAF_dFxA>MyX!-5S;9vXTMs_N-gBlrul##}M5a8j5V}&&El4m7F z0s@LEDgbj-%g#tPaog;xpZwnIY6M+s*s5c|%6M;5_aY&osUiLoss2^3iAHvonPI%_ zZ;>n+jr18#^6S~D>Quk#W>CLfg?52-{{Z&5xw$#`ARTaA>3tM1R%ANc)DAq+R=@9E z-QCTQa!^({OqK;Xc)92xUPu34JyZnpar1|kn@%&em6er12}^?fF1H&^q!Rw8N(>Eb zc@|!&uBH|`J~T8$9-W5%E3G?oLNi0!2&I7}PfttZ=zAaV3!&#`?I%hvtWtlZCW=yj zA=rgLycz}m6y`_$J9jR{q?iWWKbapy`v)VlL|<;rIm=iAViQSaOXm3}GSd$fufNPK zZ|mw>I=lodpI@P$oKuNEztOjbTgUW&*8%(-aG*m1wCcZ%7NmS(qP6@X)8s2Rtrbav z9`{@68W~BXF=AlK*RY~>bc*qF3j{N+ogZlZIA{CUNbB?*K67F`uM&QnVaT)G>wkWi zf>QraoVCAvxj)bL{)tH=Q%UnfJ7&_p_~Cl}W76q0{_W{4Xa3Mf?&y{c4Q&AjjO-ilp)zbvzza()&w`bF%oHHylKxbu(Jz@ Y_NPI$tmsYP|ANp|6g1@D%bErMFV${;`2YX_ From db195afb3523823484f75b050f34047deeb7d5a5 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 24 Oct 2023 22:42:19 +0800 Subject: [PATCH 213/518] Fix visual in DG --- docs/DeveloperGuide.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index e71845fd85..a65a4785c8 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -9,7 +9,9 @@ ### Storage Component API: `Storage.java` + ![](images/Storage.png) + - The storage component loads data from the saved text files when the application starts, and saves the data to the text files when the application exits. - The storage class uses the static methods in LoadData and SaveData to load and save data respectively. @@ -18,6 +20,7 @@ text files when the application exits. ### Budget Feature This feature has 5 functions, `set`, `update`, `delete`, `reset`, and `view`. + ![](images/Budget.png) The BudgetCommand will execute the appropriate command and print through `Budget.java` and prints any message to the user through `Ui.java`. @@ -36,7 +39,7 @@ in the diagram above **Delete budget:** -![](images/DeleteBudget.png) +![](images/deleteBudget.png) The budget will be deleted by setting the initial and current budget to 0 through the `deleteBudget()` method in `Budget.java`. @@ -44,7 +47,7 @@ Example: `budget delete` **Reset budget:** -![](images/ResetBudget.png) +![](images/resetBudget.png) The budget will be reset by resetting the current budget to the initial budget through the `resetBudget()` method in `Budget.java`. @@ -52,7 +55,7 @@ Example : `budget reset` **View budget:** -![](images/ViewBudget.png) +![](images/viewBudget.png) The current budget will be shown to the user through the `Ui`. From d314f8e128228bb2a4e313048d4d3800e5354069 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Wed, 25 Oct 2023 00:34:34 +0800 Subject: [PATCH 214/518] Create Sequence UML for overall visualisation --- docs/diagrams/vis/visualisationSequence.puml | 21 +++++++++++++++++++ docs/images/vis/visualisationSequence.png | Bin 0 -> 14494 bytes 2 files changed, 21 insertions(+) create mode 100644 docs/diagrams/vis/visualisationSequence.puml create mode 100644 docs/images/vis/visualisationSequence.png diff --git a/docs/diagrams/vis/visualisationSequence.puml b/docs/diagrams/vis/visualisationSequence.puml new file mode 100644 index 0000000000..5feb4c811a --- /dev/null +++ b/docs/diagrams/vis/visualisationSequence.puml @@ -0,0 +1,21 @@ +@startuml + +participant ":VisCommand" +participant "<>\nUi" +participant "<>\nCashFlowList" +participant "<>\nCategorizer" +participant "<>\nVisualizer" + +":VisCommand"-> "<>\nUi": Ui.getInstance() + +":VisCommand"-> "<>\nCashFlowList": CashFlowList.getInstance() + +":VisCommand"-> "<>\nUi": ui.printDisplayChart(type) + +ref over "<>\nCategorizer", ":VisCommand" : sort cashflow entries + +ref over "<>\nVisualizer", ":VisCommand": displaying chart + +hide footbox + +@enduml \ No newline at end of file diff --git a/docs/images/vis/visualisationSequence.png b/docs/images/vis/visualisationSequence.png new file mode 100644 index 0000000000000000000000000000000000000000..0fef5ff23df2d0a452686a564947c04676c3576f GIT binary patch literal 14494 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 Oq$L!@KRkHi{l5TaR7^Mk literal 0 HcmV?d00001 From fcf64449e34c5f7cd5bdaf35611dc0d3d63a2b29 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Wed, 25 Oct 2023 00:34:59 +0800 Subject: [PATCH 215/518] Create Sequence UML for categorizer --- docs/diagrams/vis/categorizerSequence.puml | 24 +++++++++++++++++++++ docs/images/vis/categorizerSequence.png | Bin 0 -> 19281 bytes 2 files changed, 24 insertions(+) create mode 100644 docs/diagrams/vis/categorizerSequence.puml create mode 100644 docs/images/vis/categorizerSequence.png diff --git a/docs/diagrams/vis/categorizerSequence.puml b/docs/diagrams/vis/categorizerSequence.puml new file mode 100644 index 0000000000..795fd59a71 --- /dev/null +++ b/docs/diagrams/vis/categorizerSequence.puml @@ -0,0 +1,24 @@ +@startuml + +mainframe sd sort cashflow entries + +autoactivate on + +participant ":VisCommand" +participant "<>\nCategorizer" + +":VisCommand"-> "<>\nCategorizer": Categorizer.sortType(cashflowList, type) + +alt type == "expense" + "<>\nCategorizer" -> "<>\nCategorizer": sortExpenses(cashflowList) + return +else type == "income" + "<>\nCategorizer" -> "<>\nCategorizer": sortIncome(cashflowList) + return +end + +return sortedCashflow: Map + +hide footbox + +@enduml \ No newline at end of file diff --git a/docs/images/vis/categorizerSequence.png b/docs/images/vis/categorizerSequence.png new file mode 100644 index 0000000000000000000000000000000000000000..373fedbf3d95087fa80532d6917292a7a82ec899 GIT binary patch literal 19281 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 literal 0 HcmV?d00001 From 9d446349ea9f6b7a710820f7147e0dcdf84a3b20 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Wed, 25 Oct 2023 00:35:18 +0800 Subject: [PATCH 216/518] Create Sequence UML for visualizer --- docs/diagrams/vis/visualizerSequence.puml | 20 ++++++++++++++++++++ docs/images/vis/visualizerSequence.png | Bin 0 -> 16332 bytes 2 files changed, 20 insertions(+) create mode 100644 docs/diagrams/vis/visualizerSequence.puml create mode 100644 docs/images/vis/visualizerSequence.png diff --git a/docs/diagrams/vis/visualizerSequence.puml b/docs/diagrams/vis/visualizerSequence.puml new file mode 100644 index 0000000000..f1f5d44166 --- /dev/null +++ b/docs/diagrams/vis/visualizerSequence.puml @@ -0,0 +1,20 @@ +@startuml + +mainframe sd displaying chart + +participant ":VisCommand" +participant "<>\nVisualizer" + +":VisCommand"-> "<>\nVisualizer": Visualizer.displayChart(chart, sortedCashFlow, type) + +activate "<>\nVisualizer" + +alt chartType == "pie" + "<>\nVisualizer" -> "<>\nVisualizer": displayPieChart(cashflowList) +else chartType == "bar" + "<>\nVisualizer" -> "<>\nVisualizer": displayBarChart(cashflowList) +end + +hide footbox + +@enduml \ No newline at end of file diff --git a/docs/images/vis/visualizerSequence.png b/docs/images/vis/visualizerSequence.png new file mode 100644 index 0000000000000000000000000000000000000000..2e939cb2041d276c18dfdfae3b1cd269eb1a6cff GIT binary patch literal 16332 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 Date: Wed, 25 Oct 2023 00:35:38 +0800 Subject: [PATCH 217/518] Add diagrams images to developer guide --- docs/DeveloperGuide.md | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 89bb2ad42a..00f88f6e9d 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -34,7 +34,10 @@ Demo: `vis /t expense /c pie` -output +Output + +`Displaying piechart for expense` +A message will be shown telling you that the chart is being displayed ![](C:\Users\puach\Documents\Y2S1\CS2113\tp\docs\images\vis\visOutput.png) @@ -60,10 +63,24 @@ Visualizer's Role: According to the chart type (Pie/Bar) argument and the Hashmap obtained from the categorizer passed in, the visualizer displays the specified visualization chart by calling the charting library Xchart. -Class Diagram +### Class Diagram ![](C:\Users\puach\Documents\Y2S1\CS2113\tp\docs\images\vis\visualisationClass.png) +### Sequence Diagram + +Overall + +![](C:\Users\puach\Documents\Y2S1\CS2113\tp\docs\images\vis\visualisationSequence.png) + +Categorizer + +![](C:\Users\puach\Documents\Y2S1\CS2113\tp\docs\images\vis\categorizerSequence.png) + +Visualizer + +![](C:\Users\puach\Documents\Y2S1\CS2113\tp\docs\images\vis\visualizerSequence.png) + ## Product scope ### Target user profile From 7c95abd280fb99cbc170653776856a389685314e Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Wed, 25 Oct 2023 01:22:49 +0800 Subject: [PATCH 218/518] Fix typo --- docs/CashflowClassDiagram.png | Bin 25273 -> 25368 bytes docs/CashflowClassDiagram.puml | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/CashflowClassDiagram.png b/docs/CashflowClassDiagram.png index 77fdabc6b31a08af2432d2f4cb35bb649746e477..8a4ea7028dcb498b14e6116d8bb311feac24a715 100644 GIT binary patch literal 25368 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 Tu89Alf}pqGaNiTnqu2femfzb! literal 25273 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 Date: Wed, 25 Oct 2023 18:28:22 +0800 Subject: [PATCH 219/518] Update storage diagram --- docs/diagrams/Storage.puml | 19 +++++++------------ docs/images/Storage.png | Bin 24273 -> 21149 bytes 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/docs/diagrams/Storage.puml b/docs/diagrams/Storage.puml index ee31f8eece..6b2a3ef31b 100644 --- a/docs/diagrams/Storage.puml +++ b/docs/diagrams/Storage.puml @@ -10,8 +10,6 @@ Class "{abstract}\nSaveData" as SaveData Class CashflowList Class Budget Class Cashflow -Class Expense -Class Income Class "<>\nExpenseType" as ExpenseType Class "<>\nIncomeType" as IncomeType Class Ui @@ -22,18 +20,15 @@ FinancialPlanner --> Storage Storage .right.-> LoadData: uses > Storage .left.> SaveData: uses > -SaveData ..> CashflowList +SaveData --> CashflowList SaveData ..> Budget -LoadData ..> CashflowList +SaveData ..> Cashflow + +LoadData --> CashflowList LoadData ..> Budget -LoadData ..> ExpenseType -LoadData ..> IncomeType -SaveData ..> Expense -SaveData ..> Income -LoadData ..> Expense -LoadData ..> Income +LoadData --> ExpenseType +LoadData --> IncomeType +LoadData --> Cashflow LoadData -right-> Ui: prints message > -Expense -down-|> Cashflow -Income -down-|> Cashflow @enduml \ No newline at end of file diff --git a/docs/images/Storage.png b/docs/images/Storage.png index ab5cf000d52d2d61d6dec220e3f5095218db98b8..347b2cdb980ad923e98764e7392f60e2294f52ec 100644 GIT binary patch literal 21149 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 A;{X5v literal 24273 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 Date: Wed, 25 Oct 2023 18:39:34 +0800 Subject: [PATCH 220/518] Update DG --- docs/DeveloperGuide.md | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 93221a7478..3301c430ac 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -27,25 +27,26 @@ - source: https://stackoverflow.com/questions/1892765/how-to-capitalize-the-first-character-of-each-word-in-a-string **DG adapted from** - - [Addressbook-level3](https://github.com/se-edu/addressbook-level3) + +* [Addressbook-level3](https://github.com/se-edu/addressbook-level3) {list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well} -## Components +## Design & implementation + +{Describe the design and implementation of the product. Use UML diagrams and short code snippets where applicable.} + ### Storage Component + API: `Storage.java` ![](images/Storage.png) -- The storage component loads data from the saved text files when the application starts, and saves the data to the +* The storage component loads data from the saved text files when the application starts, and saves the data to the text files when the application exits. -- The storage class uses the static methods in LoadData and SaveData to load and save data respectively. -- The `load` method in LoadData reads the `data.txt` file and loads any existing Income, Expense and Budget into the application. -- The `save` method in SaveData saves all Incomes, Expenses and existing Budget into the `data.txt` file. - -## Design & implementation - -{Describe the design and implementation of the product. Use UML diagrams and short code snippets where applicable.} +* The storage class uses the static methods in LoadData and SaveData to load and save data respectively. +* The `load` method in LoadData reads the `data.txt` file and loads any existing Income, Expense and Budget into the application. +* The `save` method in SaveData saves all Incomes, Expenses and existing Budget into the `data.txt` file. ### Visualization Feature @@ -63,7 +64,7 @@ Output `Displaying piechart for expense` A message will be shown telling you that the chart is being displayed -![](C:\Users\puach\Documents\Y2S1\CS2113\tp\docs\images\vis\visOutput.png) +![](images/vis/visOutput.png) This feature was implemented with the help of three different classes. They are namely: Visualizer, Categorizer, VisCommand (Inherits from abstract Command Class) @@ -89,21 +90,21 @@ the visualizer displays the specified visualization chart by calling the chartin ### Class Diagram -![](C:\Users\puach\Documents\Y2S1\CS2113\tp\docs\images\vis\visualisationClass.png) +![](images/vis/visualisationClass.png) ### Sequence Diagram Overall -![](C:\Users\puach\Documents\Y2S1\CS2113\tp\docs\images\vis\visualisationSequence.png) +![](images/vis/visualisationSequence.png) Categorizer -![](C:\Users\puach\Documents\Y2S1\CS2113\tp\docs\images\vis\categorizerSequence.png) +![](images/vis/categorizerSequence.png) Visualizer -![](C:\Users\puach\Documents\Y2S1\CS2113\tp\docs\images\vis\visualizerSequence.png) +![](images/vis/visualizerSequence.png) ### Add income/expense feature @@ -153,13 +154,14 @@ Given below is the sequence diagram showing the add income/expense mechanism: ### Budget Feature + This feature has 5 functions, `set`, `update`, `delete`, `reset`, and `view`. ![](images/Budget.png) The BudgetCommand will execute the appropriate command and print through `Budget.java` and prints any message to the user through `Ui.java`. -**Set and update budget:** +#### Set and update budget: Example: ``` @@ -171,7 +173,7 @@ The second line updates the budget by adding or subtracting the difference betwe initial and current budget. This is done through `updateBudget(500)` method in `Budget.java`. Both functions can be seen in the diagram above -**Delete budget:** +#### Delete budget: ![](images/deleteBudget.png) @@ -179,7 +181,7 @@ The budget will be deleted by setting the initial and current budget to 0 throug Example: `budget delete` -**Reset budget:** +#### Reset budget: ![](images/resetBudget.png) @@ -187,7 +189,7 @@ The budget will be reset by resetting the current budget to the initial budget t Example : `budget reset` -**View budget:** +#### View budget: ![](images/viewBudget.png) From 2a16939ea19a75e7be88095960d6d869f369ce06 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Wed, 25 Oct 2023 20:09:35 +0800 Subject: [PATCH 221/518] Update overview command --- .../commands/OverviewCommand.java | 62 ++++++++++++++----- .../java/seedu/financialplanner/utils/Ui.java | 12 ++++ 2 files changed, 60 insertions(+), 14 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java index 002527dca0..fc8b6bf1bf 100644 --- a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java +++ b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java @@ -5,12 +5,16 @@ import seedu.financialplanner.list.CashflowList; import seedu.financialplanner.list.Income; import seedu.financialplanner.list.Expense; +import seedu.financialplanner.reminder.Reminder; +import seedu.financialplanner.reminder.ReminderList; import seedu.financialplanner.utils.Ui; import java.text.DecimalFormat; import java.util.ArrayList; public class OverviewCommand extends Command { + private static final CashflowList cashflowList = CashflowList.getInstance(); + public OverviewCommand(RawCommand rawCommand) { if (!rawCommand.extraArgs.isEmpty()) { String unknownExtraArgument = new ArrayList<>(rawCommand.extraArgs.keySet()).get(0); @@ -20,39 +24,50 @@ public OverviewCommand(RawCommand rawCommand) { @Override public void execute() throws Exception { - CashflowList list = CashflowList.getInstance(); - Ui.getInstance().showMessage("Here is an overview of your financials:\n" + - "Total balance: " + formatDoubleToString(Cashflow.getBalance()) + "\n" + - "Highest income: " + getHighestIncome(list) + "\n" + - "Highest expense: " + getHighestExpense(list) + "\n" + - "Remaining budget for the month: " + getBudgetDesc()); - //todo: indicate description of income/expense + Ui.getInstance().printOverview(getBalance(), getHighestIncome(), getHighestExpense(), + getBudgetDesc(), getReminders()); + //todo: goal disparity - //todo: add educational tip } private static String getBudgetDesc() { return Budget.getCurrentBudgetString(); } - private static String getHighestIncome(CashflowList list) { + private static String getHighestIncome() { double maxIncome = 0; - for (Cashflow entry : list.list) { + String incomeType = ""; + for (Cashflow entry : cashflowList.list) { if (entry instanceof Income && entry.getAmount() > maxIncome) { maxIncome = entry.getAmount(); + incomeType = entry.capitalize(entry.getIncomeType(). + toString().toLowerCase()); // Capitalise the first letter } } - return formatDoubleToString(maxIncome); + + if (incomeType.isEmpty()) { + return "No income added yet."; + } + + return formatDoubleToString(maxIncome) + " Category: " + incomeType; } - private static String getHighestExpense(CashflowList list) { + private static String getHighestExpense() { double maxExpense = 0; - for (Cashflow entry : list.list) { + String expenseType = ""; + for (Cashflow entry : cashflowList.list) { if (entry instanceof Expense && entry.getAmount() > maxExpense) { maxExpense = entry.getAmount(); + expenseType = entry.capitalize(entry.getExpenseType(). + toString().toLowerCase()); // Capitalise the first letter } } - return formatDoubleToString(maxExpense); + + if (expenseType.isEmpty()) { + return "No expense added yet."; + } + + return formatDoubleToString(maxExpense) + " Category: " + expenseType; } private static String formatDoubleToString(double amount) { @@ -60,4 +75,23 @@ private static String formatDoubleToString(double amount) { return decimalFormat.format(Cashflow.round(amount, 2)); } + + private static String getReminders() { + ReminderList reminderList = ReminderList.INSTANCE; + if (reminderList.list.isEmpty()) { + return "No reminders added yet."; + } + StringBuilder reminders = new StringBuilder(); + int count = 1; + for (Reminder reminder : reminderList.list) { + reminders.append(count).append(". ").append(reminder.toString()).append("\n"); + count++; + } + + return reminders.toString(); + } + + private static String getBalance() { + return formatDoubleToString(Cashflow.getBalance()); + } } diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 445307b991..95655aa5c6 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -134,4 +134,16 @@ public void printResetBudget() { public void printDisplayChart(String type, String chart) { showMessage("Displaying " + chart + "chart for " + type); } + + public void printOverview(String... args) { + String balance = args[0]; + String income = args[1]; + String expense = args[2]; + String budget = args[3]; + String reminders = args[4]; + + showMessage("Here is an overview of your financials:\n" + "Total balance: " + balance + "\n" + + "Highest income: " + income + "\n" + "Highest expense: " + expense + "\n" + + "Remaining budget for the month: " + budget + "\n\n" + "Reminders:\n" + reminders); + } } From 2ee59837d6969e00885d562bf8af21898bf7a84f Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Wed, 25 Oct 2023 20:44:44 +0800 Subject: [PATCH 222/518] Extract method in budget command and update DG --- docs/diagrams/Budget.puml | 2 +- docs/diagrams/deleteBudget.puml | 2 +- docs/diagrams/resetBudget.puml | 4 +-- docs/diagrams/viewBudget.puml | 2 +- docs/images/Budget.png | Bin 21477 -> 21119 bytes docs/images/deleteBudget.png | Bin 10111 -> 10119 bytes docs/images/resetBudget.png | Bin 16854 -> 17026 bytes docs/images/viewBudget.png | Bin 9377 -> 9649 bytes .../commands/BudgetCommand.java | 31 ++++++++---------- .../java/seedu/financialplanner/utils/Ui.java | 24 ++++++++++++++ 10 files changed, 43 insertions(+), 22 deletions(-) diff --git a/docs/diagrams/Budget.puml b/docs/diagrams/Budget.puml index 6b2fb66da2..54174d054a 100644 --- a/docs/diagrams/Budget.puml +++ b/docs/diagrams/Budget.puml @@ -10,7 +10,7 @@ return ui alt set BudgetCommand -> Budget: setBudget(budget) - BudgetCommand -> Ui: printSetBudgetMessage() + BudgetCommand -> Ui: printSetBudget() else update BudgetCommand -> Ui: printBudgetBeforeUpdate() BudgetCommand -> Budget: updateBudget(budget) diff --git a/docs/diagrams/deleteBudget.puml b/docs/diagrams/deleteBudget.puml index f9dea38d36..f3d4a70199 100644 --- a/docs/diagrams/deleteBudget.puml +++ b/docs/diagrams/deleteBudget.puml @@ -9,7 +9,7 @@ alt hasBudget BudgetCommand -> Budget: deleteBudget() BudgetCommand -> Ui: printDeleteBudget() else else - BudgetCommand -> Ui: printErrorMessage() + BudgetCommand -> Ui: printBudgetError("delete") end hide footbox diff --git a/docs/diagrams/resetBudget.puml b/docs/diagrams/resetBudget.puml index 79902f379e..dec5060455 100644 --- a/docs/diagrams/resetBudget.puml +++ b/docs/diagrams/resetBudget.puml @@ -8,12 +8,12 @@ participant Ui alt spentBudget opt initialBudgetExceedBalance BudgetCommand -> Budget: setInitialBudget(balance); - BudgetCommand -> Ui: printUpdateMessage() + BudgetCommand -> Ui: printBudgetExceedBalance() end BudgetCommand -> Budget: resetBudget() BudgetCommand -> Ui: printResetBudget() else else - BudgetCommand -> Ui: printErrorMessage() + BudgetCommand -> Ui: printBudgetError("reset") end hide footbox diff --git a/docs/diagrams/viewBudget.puml b/docs/diagrams/viewBudget.puml index 186d176a74..0988f5cf50 100644 --- a/docs/diagrams/viewBudget.puml +++ b/docs/diagrams/viewBudget.puml @@ -8,7 +8,7 @@ participant Ui alt hasBudget BudgetCommand -> Ui: printBudget() else else - BudgetCommand -> Ui: printErrorMessage() + BudgetCommand -> Ui: printBudgetError("view") end hide footbox diff --git a/docs/images/Budget.png b/docs/images/Budget.png index f417299794203e99bd882ffdf24d3f7208a418f1..32f6e71204b40c0b395d6da6fc869e7e22f90940 100644 GIT binary patch literal 21119 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 Mb=@l^s#X#I1wyx@%K!iX diff --git a/docs/images/resetBudget.png b/docs/images/resetBudget.png index 11b0c19cb4b46e7ecd065b7008fee39501829888..de3d3bdc35cdd67e41729356a97a4724860fbba8 100644 GIT binary patch literal 17026 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 Y9q6Wx!&DCbG6)1YDVXFtaeeRq1NH1e82|tP literal 16854 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%0ACOj zVBE>MpQ$00VzYKdvV-!KIiro;{3+? zUcbP=U?se*D6b7QTuaB()mE--V`eeM2;h8#fjQ@p1>Yxnate zKWSYh69HjDEV-@>%iMQAF}NQsDoYi3nd=hMfc(Ya@6S-UFrxp*mv~Y`6B8tLaOCQE z1-Fb0gIo&%wg%O=NZa>OD5o`zz{^o4rzhx#wxYpddmHHBLE~!ceq49m=c^Fvj7=fr zMN#YhtA>}KUTE*Uf?Ns-Ru)&(p~6$+XO)IAfB0|AyN4KTt>IgO;3hWCP_P!0wHHVX%vfUSvn?fLr++?2o zFsma$KoZ3yCo3ak;MA})tk0qxLy=Yl%XHtEuJ20X&&|ncZEa0_KZ_ypfJ37u?#FKu zU!p|q$GecPEM6DDzGEz~6=DfNuLZIg6wjC>Xf;+eWeJ;=ITR-!tmzS5IpdhUNRduyE zD{Jr=jO|2|ZCq>``o^;7rG|z^S0b-gZ0E=3L|B3IEoktKhvbaf7uKfgy*=TfL`3wW z=Di^V)T${$^M^YtqYEaVN>d{JkLQ@G?8ab5e#hV2`0G&T%Dm7+1(4kAY&Aw}CeI|e1jn5&-CUWSv))f)Q=}U5@`-Duglcos{;IK2j*Cj@=E)aLOw;S(q1qi(+_o%&i-rt7* zfi(I{zE*c{cenQ8d>)VH(Vd^qJ*~{-8ysvqkk#_F<3;JZpw;#3O=}ZXDZcZal-{&s z1(4#P3nZ{64?ziulp`;6e}BKfZF}1V`Um2!uC97TVm6<@mi5UN=vVQrDn-+!OM7X0 z@#}x5;x|0rpNl2v!RKGQNpSjJzbe^4S2vF_;pQWw4iG?s)=wYSUB5`;bPq~ZKvro# zk(it;{&?GZK_f?~(rH)71w4vfJ*-d0d)G;>*r@)o`vF{y6MvDXgrcC>;_+5R@RlBJf6>QBwn!JgFQv&LIW;Sw0F8(mR9oc5bdi2 z0hcD{pD~ta!_OkGpa2WNx-ed8U*NWR=&_?l$-yT~e|rOMNQ|yKQcfk4HjZv$HZ{hB;Q} zRhF5_E*l6aX0yiQea@<d$6UsMFQz`kwGnEg54AJBk}%j;e}&@9CR*{G4Rs#ab3EO&9N_&muMVk~$0ZTxIu--;9>anp@Cv)=kyQ zc^$3o;NXnp(HMLvYgDV0`u)}&S50}9Ae)d>6KZ+8+n#z7a!+ zS4=V3Q$7~?IOnB<{R+y-AyGtiP5Ufs2P zd5VX9kwUv(C28Gz&$4Ss8{Z*5y*K{deRKkU;~|%S)05Yvq;W&T&TW7` zB|R#~^GkzChCa^M-#>6?^cC^>6iC_m$gK4)^lKcQZbgn-Cda<*m%MQOP$K&12|e3O zb(drwA6GjUUuCLtm_q1RIl%4Ak$D>V6}EB_EdtEQ{K7(iA-VN*IXNQUkwV%^^Nx2A zBVQI)*77@)jS1YR3+6b59H-xzPQzpN5ANHKmUO(kzp@`)X33kUFLwAkj8StKvQ(=M zjuD=FgKv2%Zh&3-fQ&mq4|;F_DIGi7$}~zB|IQC%L(a!vEmL2caO`8Y{qEO|c3tFK zLY(d?$7YZn6HxJF3Yy8faB?hqe+l5NLR32sGDyinWQ&^U$b=2OL3!>FZa7-!h(ARm z^7~}=5OpDb=!_eq>Pe0M6;_#Rr#mB7kU}W6rt^n$yXAv9XiDDzxohrZvwa-6MxS;ZW$ES6D*mX@|fe}6X8Oh7gLkajl! z%gD9y1!X*rd%v%t$=*8u0b7`F5(wGH`)=(we@3;o3s=$Y29{=+$dj3wXZ~yhSS6e7YZtJweNNFhCz_n%du0q70q$1Wb^%8wTa?eM zR!h!xF7%u>$yP#&{RReh;>Eb;kbd6(x!$E-5$@5_nQ|5*g~QFH&J-oz^)?$t!9h7E ze|7c#ju(qwT6LTg{;##3Lhm>5wEgdKY(LsSJRd|-=_;p~kg!AP7(s1ur0bfanqE+cFUZR7 zVeYZDP}=#P{d7iuEb!h$j+RYW$k4)($SSY>be@k*@rH{=pEgM*aZR45veHecIK=<> zd+zc4@cYbiYtpu}#a)ohHOf)@nE_Z~rAhbS?Puo}f6BNpIN9LKVMv}E1EL+vQCs)T zgNnz`kEr?XGKpA=>u`08eF!*m_FC49;??$mdycD)-$Uk<<25FsaL|gY`qh>WXJWI~mO;kb-@PeOV5+D6D`m}??Fi<(q zQoJzW4Q6eN@AXeDr|T?MpVxmcOoN%tTrw)Nq{*SxYUe9e+bSszVigh^=DL707F%&{ zyop(HN$oZ*HQnJYZSC&WvB-VKtNa_CD5RM>tyF}=)N>LhJ_D0yd?@3&Pll$sd)tGj zAv81Lv5vKVXq{=E2Q-o*IAJfIJ?jTF4e9u`Q+eXdv!aQCtwr^V z1E(&kg{l8=YTdaNj#6kBym!8|jn3E>j^1r8Bg5}|6&Mofzxyryri|7-F$R$T8q^sD zA;Gyi%U`@GBG2!VjEb4Q*y`kFnU|dY7uZq?41(kW47jmK=RMu-Ev)l|^Gx|(R=}M< z3kb+h?WVh08dN)XuT8lD_l5>TB9<)2SN|-^B6qH@Gm!SB^<=(7v35KWZ7t)GQovk zIVO!pZu%3VLTJEEe2{_m%js68R@Y5$+Yvw1m{ks1*kC4zL^fH*ySGqJn~;YFIp39j zs1ozDItSH${+!rl|4|#%!UjL|<5C;n_D&%ks3msL<&U^W$qv<%WF>_>WEoEjm~y-% za_IT0uz9#6gE?js!v*>O=O5u!UV>9jHEhOudaTlc0+;@;7t*Rr4Ly-dpQJsRxOY^v@+GWE((hYHIw2c!e#yp)W4GsjI7B zz5|o}@S&W5WU1?P8b=;VPe9E_!DhmA*5Qo+I!~KpikkU^>)rg6lmJhG-1lhLy%F`S z6LPmDkyroXE=Q)%mEEw*X;?>h$uhdcDKhkl5eqGD@N79_vJ9$A_i2ca(sk)Z=w%2Xzlt=bMEcgy z+1yOO@q8@~%dN1)_nH~s`sVPJ{F@TApm!#4%kk7I4MGs!$NSDSNF?&d{aH?tp;QkQ z{23tvhghPSsF+I4}{nXLXk(lGO&tT5I?!MU zIoBHP#3<>;2^jICp?B^p!&4((t7m(3JmtN69AU%xg%50`T7 zMTzIOmj?0h@TxucQOL=Z%uGb7S=-Fa4CokKtTZ$RWR>KOR3m!L(XoDq%9EH*1h*CRBp*I}FqYox7FI~zR8f#yAZHw{u%&je8!k+V z-6@Bs@kp50PST3n(an!!8Uwxl-uhG!a%F{JajeX$EtZLd_xsDKTF)@# z;$l*Ke0*G-^TDQtg_JIdNx9wFXUjQ(lHpI)URw*%^kUUpamtJV8V?`(pby>G&G8ps z#q{SKKktt{2o|#)=9&Bq8o;yunTI(Ukzvqat)AWzBN{L2ksvVqUcXI7eE~FGN->u} zImhdpiCRdq!cd&dKH3{@A$7@zZP)NMXK5frD$E1)+s9~c^1+<1F>&l-8Pd& zGEX?EG*Bj9>~`$qQ!dZ%HC48|lgg`Z$6&^o)^7}aoWQV{_2x~&4rsJgXu`w8OKeAq zi0I)b>$Mx3_;!$*@rapb9oPBJgvo>1NPd`Zx%I$wy|+mTiEvP0ps`W46DAj>DSIc* z79Kwr7k-u9be-4c*ADP3MmA;AvaSo=jgEuSD(_tPkrBrHdLOU_8&NQV$)Fw%x4?N^ zx+l1=MGO&bA93u5-cgF+Ego$&#s)d)>gwLPgWo8_&ky=|57;87+{yl&mYPh+h0>SS z&8BE49A%xt0;uxJSQ!U#pA(-^L!D~6WZsjqyo+U|-%bm&0tc8%4uZp~oGz)LMEkTN z4ia`FD7nv_JNMCJ?Qmma8~J>h=W|<+5=YUCnPX9_-biP|DJ z4H`354N4hX@UH9@Ih<^yf71QD-NU)rSybZJjSU0{B(t`d@N0G&n4eaDCMc`)1>n1E zY4+9vfhngYlH}mrP|+d1PBYUwe1J$NPh=FJKrWb`^(sL;w>`U)7-1N)6sqFi#Kx>LXrmCTDSY0;VCIP z%&{2u1AmB8_|HH(>vYcYKfdw*z5X@xh99_o68@d*uGqsvtl?(|KM?kiRs%he{^9n)_wd}Hd%3BT_XI?yi{?T)T_{P%6lMJK_ z!5@2+%DTEVRW(qMvz`Z=^IyJv86DO2yU#!b(~=!GMH_7?zi(1M#Ix%Exjbc zY%R96v6C}Sn$#gczg>IzqwV|JP}ev(I2rvHgos;GT(^n8pjqR3J^v>;G^TGV!!P@k+J zW8%+o_2Ee0gI3s%Ojp|L1NrXJBd#MYc~vrcdhhm#Eu$z~{N2^DpfXQIMa3{;hR=h8 z>3SH~Ui}P*hfRaQVQ-AlhdTxL3x=~*lFF?5B9hk10C929@mL*YHWZe)>kT4XqcXv0%;)J`%Z!m&a zL68CP5NwCfZ#&FlWm>hV85yUmo#$@9U@xUq`|JJFwjRTfTq0^M12;DjA&Dzju1HAe z>CXQR;%&7k2vP$c^5s3GIHRN)?;FVwxy&S(1iA3tM;-#m3` z+5RTy<4p-DE*jJJC%^_e5&Z;K<%>nH&rWBFk`X!=ErueK>tLTyv16(t=*#{GG>88m z7D&-dV*j>DiYA}C4`}wUEhOZkMqdxMo%lb{YJ5Ziw9P_i=o9t#T#0P6D>FZ$9X z%r>ZAkKtcGMNa%IO}ak}3*CVNjXkj55z$as$V0PAFAog?n&u}^cThkgG%mNF7@p=; zD8oj2eC_spTFCPzxb1C=34*+r+ihc-Av817NK;c&NvU%fjGPZ0wq>`8H>H?S~}w1yLOqfz9r2# zI5_gbt5Wyvr>}_UWB&EVpVPV|n5XCc?X-IApCFDXZir>9q_OzG%_;3b3 z^wE6<&}dj5D4nNzF`TI_K`8OkP}gsnM!z|Rzv=4hZYc9n&AW?$G*|9A&B2u|Z{Y-2GGRQXS;w{Po} z7zbo!Yto6@L6^T=r9t?g%GgEDF1e)96xG#9)2#a22pNEh&GRYFC)@BFH;c*hx{F`@ z;$76&{f!7rKz{*ukj|d?>@A=#7Wu5G08qG>fTE^2gZkr3^X=2 zHYL0fx4w#p5z!}RWH^-a-ND4f1jR2Xns|1pPF~f+qjF&?NA(xZ61-}JVpZxwFbF9; zxgc`x9K!LUKPFM#4W}@}3KR;(|+L1PqBeAVxYV6>i*^-&n-}jHxZqvebbTuynH@CkRX-!Q6|0MMA<07L1oJ zt!PydHCGDfKDVmy2T62v0FU2gq*;Yi#t!eROfhmP|XGBYd@F@g3h+5z<#_O zZw1a>Tn8&anuknLClX%@uKvYqE@BaTPlngJxVWgh0@}ScUNL7s?olni+nV9@%nlKHGI-awssFRPuz)r*0zvO9{fq7erb56@`5=rwUY*aN+J2bZ? z13Hf-!+*1&gKAoIx|pLOkWv8L?#H!Sei(O?Jw4uPXI(enKRldGr+;TACDiaqUYhQ35OQ51r~XvL!;@Xr93-BrEsE+I`}wqSY>

i20Z!B_1}TrHhLIMa zeIJD?D=M)&XfSC49?z5gu{@18-Q9Pc8w`|xB0p&Y5vvnuP2OZ>RWE~l5OrO+``|k+j5B$8 zdH8)7E6`)rR^-0m{Q|f+m(1MGXk{X5O)++Mb}-zv2p{~zg$GWZ%OFSzcm?9nyUq`N zn6Cm_*gq8w@DoO%hui#+yRrXnG`I1K0n>2Q;VXfV8U*|P=s=ZvYmK1T$n@%aP>^B- zcrbnWlgQ^Kv4uQqFc#dix$#*ob^6Ceu|XZZ!_92`S06m|@B6{0e#@5n?5%bGP%;0T zk3R*x`NSt@ZPve+`u8WrNtb=mf9apGssENO83z8Y%P3D11DfssKNotKikjMK;N_>A zST9|8q`_Zdnu<{P1O$8J*d~Pi)FTgQk)+rfg3tc^`{r0quMXKSax(B0{C5iD_DxmA JA_e2X{{m8d4}kyx literal 9377 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 Xm^790bQSom5Z2A>>WT&OrUCy2p^~mZ diff --git a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java index 9006ab43ca..dd846e8933 100644 --- a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java +++ b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java @@ -21,15 +21,7 @@ public BudgetCommand(RawCommand rawCommand) throws FinancialPlannerException { return; } validateCommandFormat(rawCommand); - - try { - logger.log(Level.INFO, "Parsing budget as double"); - budget = Double.parseDouble(rawCommand.extraArgs.get("b")); - } catch (IllegalArgumentException e) { - logger.log(Level.WARNING, "Invalid value for budget"); - throw new IllegalArgumentException("Budget must be a number."); - } - validateBudget(); + validateBudget(rawCommand); assert budget > 0 && budget <= Cashflow.getBalance() : "Budget should be greater than 0 and less than " + "or equal to total balance"; @@ -41,7 +33,14 @@ public BudgetCommand(RawCommand rawCommand) throws FinancialPlannerException { } } - private void validateBudget() throws FinancialPlannerException { + private void validateBudget(RawCommand rawCommand) throws FinancialPlannerException { + try { + logger.log(Level.INFO, "Parsing budget as double"); + budget = Double.parseDouble(rawCommand.extraArgs.get("b")); + } catch (IllegalArgumentException e) { + logger.log(Level.WARNING, "Invalid value for budget"); + throw new IllegalArgumentException("Budget must be a number."); + } if (budget <= 0) { logger.log(Level.WARNING, "Invalid value for budget."); throw new FinancialPlannerException("Budget should be greater than 0."); @@ -105,7 +104,7 @@ private void viewBudget() { if (Budget.hasBudget()) { ui.printBudget(); } else { - ui.showMessage("There is no existing budget."); + ui.printBudgetError("view"); } } @@ -113,13 +112,12 @@ private void resetBudget() { if (Budget.getInitialBudget() != Budget.getCurrentBudget()) { if (Budget.getInitialBudget() > Cashflow.getBalance()) { Budget.setInitialBudget(Cashflow.getBalance()); - ui.showMessage("Since initial budget exceeds current balance, " + - "budget will be reset to current balance."); + ui.printBudgetExceedBalance(); } Budget.resetBudget(); ui.printResetBudget(); } else { - ui.showMessage("Budget has not been spent yet."); + ui.printBudgetError("reset"); } } @@ -128,7 +126,7 @@ private void deleteBudget() { Budget.deleteBudget(); ui.printDeleteBudget(); } else { - ui.showMessage("Budget has not been set yet."); + ui.printBudgetError("delete"); } } @@ -142,7 +140,6 @@ private void updateBudget() { private void setBudget() { logger.log(Level.INFO, "Setting budget"); Budget.setBudget(budget); - ui.showMessage("A monthly budget of " + Budget.getInitialBudgetString() - + " has been set."); + ui.printSetBudget(); } } diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 95655aa5c6..eb75291253 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -146,4 +146,28 @@ public void printOverview(String... args) { "Highest income: " + income + "\n" + "Highest expense: " + expense + "\n" + "Remaining budget for the month: " + budget + "\n\n" + "Reminders:\n" + reminders); } + + public void printSetBudget() { + showMessage("A monthly budget of " + Budget.getInitialBudgetString() + " has been set."); + } + + public void printBudgetExceedBalance() { + showMessage("Since initial budget exceeds current balance, budget will be reset to current balance."); + } + + public void printBudgetError(String errorType) { + switch (errorType) { + case "delete": + showMessage("Budget has not been set yet."); + break; + case "reset": + showMessage("Budget has not been spent yet."); + break; + case "view": + showMessage("There is no existing budget."); + break; + default: + showMessage("Unknown command"); + } + } } From 6fa7dc87d5df38ce68d2ee34261b65c9249d5951 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Wed, 25 Oct 2023 20:46:14 +0800 Subject: [PATCH 223/518] Add assertion to Ui --- src/main/java/seedu/financialplanner/utils/Ui.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index eb75291253..7f2aba4533 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -34,6 +34,7 @@ public void setScanner(Scanner scanner) { } public void showMessage(String message) { + assert !message.isEmpty(); System.out.println(message); } From 21773315b5b33b1bad51a78c1b17678fc4e98fe8 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Thu, 26 Oct 2023 19:07:32 +0800 Subject: [PATCH 224/518] Fix Junit for stock delete --- .../financialplanner/investments/WatchListTest.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/test/java/seedu/financialplanner/investments/WatchListTest.java b/src/test/java/seedu/financialplanner/investments/WatchListTest.java index 4d29930914..6874a460d8 100644 --- a/src/test/java/seedu/financialplanner/investments/WatchListTest.java +++ b/src/test/java/seedu/financialplanner/investments/WatchListTest.java @@ -1,6 +1,9 @@ package seedu.financialplanner.investments; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; import seedu.financialplanner.exceptions.FinancialPlannerException; import java.util.ArrayList; @@ -8,9 +11,11 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertEquals; +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) class WatchListTest { @Test + @Order(1) void fetchFMPStockPrices() throws FinancialPlannerException { WatchList wl = WatchList.getInstance(); wl.fetchFMPStockPrices(); @@ -20,6 +25,7 @@ void fetchFMPStockPrices() throws FinancialPlannerException { } @Test + @Order(2) void addStock() throws Exception { WatchList wl = WatchList.getInstance(); String stockCode = "GME"; @@ -27,9 +33,10 @@ void addStock() throws Exception { } @Test + @Order(3) void deleteStock() throws FinancialPlannerException { WatchList wl = WatchList.getInstance(); - String stockCode = "AAPL"; - assertEquals("Apple Inc", wl.deleteStock(stockCode)); + String stockCode = "GME"; + assertEquals("Gamestop Corporation - Class A", wl.deleteStock(stockCode)); } } From 521139faa1b05419956e7ec6d07a1177d61a879f Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Thu, 26 Oct 2023 21:09:50 +0800 Subject: [PATCH 225/518] Add cap to watchlist max stocks --- .../java/seedu/financialplanner/investments/WatchList.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index 36fc50ba84..4063022fde 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -97,6 +97,9 @@ public void fetchFMPStockPrices() throws FinancialPlannerException { } public String addStock(String stockCode) throws FinancialPlannerException { + if (stocks.size() >= 5) { + throw new FinancialPlannerException("Watchlist is full (max 5). Delete a stock to add a new one"); + } Stock newStock = null; newStock = new Stock(stockCode); From 6dda9db4161d3ccb8042e28f3317e341d777be7f Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Thu, 26 Oct 2023 21:10:19 +0800 Subject: [PATCH 226/518] Add disallowing of adding multiple of duplicate stocks to watchlist --- .../java/seedu/financialplanner/investments/WatchList.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index 4063022fde..3776b15539 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -100,6 +100,12 @@ public String addStock(String stockCode) throws FinancialPlannerException { if (stocks.size() >= 5) { throw new FinancialPlannerException("Watchlist is full (max 5). Delete a stock to add a new one"); } + for (Stock stock: stocks) { + if (stockCode.equals(stock.getSymbol().toUpperCase())) { + throw new FinancialPlannerException("Stock is already present in Watchlist. Use watchlist to view it!"); + } + } + Stock newStock = null; newStock = new Stock(stockCode); From d94d5d4abaa0a4c0f5b06b5536858ebb32058b90 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Thu, 26 Oct 2023 21:11:25 +0800 Subject: [PATCH 227/518] Add check for correct size of JSON array response received --- .../java/seedu/financialplanner/investments/WatchList.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index 3776b15539..e8942981fb 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -87,6 +87,9 @@ public void fetchFMPStockPrices() throws FinancialPlannerException { throw new RuntimeException(e); } JSONArray ja = (JSONArray) obj; + if (ja.size() != stocks.size()) { + throw new FinancialPlannerException("Error getting API info!"); + } int i = 0; for (Object jo : ja) { JSONObject stock = (JSONObject) jo; From 7d0d95006240c96ec6ecd789699dcbe9bf8622f2 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Thu, 26 Oct 2023 21:13:16 +0800 Subject: [PATCH 228/518] Add check for the correct matching of JSON stock object to stock class object --- .../java/seedu/financialplanner/investments/WatchList.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index e8942981fb..199a5d62d8 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -94,6 +94,12 @@ public void fetchFMPStockPrices() throws FinancialPlannerException { for (Object jo : ja) { JSONObject stock = (JSONObject) jo; String price = StringUtils.rightPad(stock.get("price").toString(), 10); + + if (!stocks.get(i).getSymbol().equals(stock.get("symbol"))) { + i += 1; + logger.log(Level.WARNING, "Stocks matching error!"); + continue; + } stocks.get(i).setPrice(price); i += 1; } From e589a22a98e287186ce9ef35210fb0325136e0ce Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Thu, 26 Oct 2023 21:13:48 +0800 Subject: [PATCH 229/518] Add the getting and printing of additional watchlist information (Market, daily high, daily low) --- .../financialplanner/investments/Stock.java | 29 +++++++++++++++++-- .../investments/WatchList.java | 17 ++++++++++- .../java/seedu/financialplanner/utils/Ui.java | 22 +++++++++++--- 3 files changed, 61 insertions(+), 7 deletions(-) diff --git a/src/main/java/seedu/financialplanner/investments/Stock.java b/src/main/java/seedu/financialplanner/investments/Stock.java index 5394b5ad29..bc49ce54b6 100644 --- a/src/main/java/seedu/financialplanner/investments/Stock.java +++ b/src/main/java/seedu/financialplanner/investments/Stock.java @@ -19,9 +19,11 @@ public class Stock implements Serializable { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private String symbol; - private String market; + private String exchange; private String stockName; private String price; + private String dayHigh; + private String dayLow; public Stock(String symbol) throws FinancialPlannerException { this.symbol = symbol; @@ -69,7 +71,6 @@ public String getStockNameFromAPI(String symbol) throws FinancialPlannerExceptio } assert stock.get("2. name") != null; - market = (String) stock.get("4. region"); return (String) stock.get("2. name"); } catch (IOException e) { throw new RuntimeException(e); @@ -100,4 +101,28 @@ public String getPrice() { public void setPrice(String price) { this.price = price; } + + public String getExchange() { + return exchange; + } + + public void setExchange(String exchange) { + this.exchange = exchange; + } + + public String getDayHigh() { + return dayHigh; + } + + public void setDayHigh(String dayHigh) { + this.dayHigh = dayHigh; + } + + public String getDayLow() { + return dayLow; + } + + public void setDayLow(String dayLow) { + this.dayLow = dayLow; + } } diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index 199a5d62d8..be64504f73 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -93,14 +93,29 @@ public void fetchFMPStockPrices() throws FinancialPlannerException { int i = 0; for (Object jo : ja) { JSONObject stock = (JSONObject) jo; - String price = StringUtils.rightPad(stock.get("price").toString(), 10); if (!stocks.get(i).getSymbol().equals(stock.get("symbol"))) { i += 1; logger.log(Level.WARNING, "Stocks matching error!"); continue; } + + String price = stock.get("price").toString(); + assert price != null; stocks.get(i).setPrice(price); + + String exchange = stock.get("exchange").toString(); + assert exchange != null; + stocks.get(i).setExchange(exchange); + + String dayHigh = stock.get("dayHigh").toString(); + assert dayHigh != null; + stocks.get(i).setDayHigh(dayHigh); + + String dayLow = stock.get("dayLow").toString(); + assert dayLow != null; + stocks.get(i).setDayLow(dayLow); + i += 1; } } diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 445307b991..f7504258e0 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -9,6 +9,11 @@ import java.util.Scanner; public class Ui { + private final String RED = "\u001B[31m"; + private final String GREEN = "\u001B[32m"; + private final String RESET = "\u001B[0m"; + + private final String YELLOW = "\u001B[33m"; private static Ui ui = null; private Scanner Scanner = new Scanner(System.in); private Ui() { @@ -52,7 +57,13 @@ public String input() { public void printWatchListHeader() { System.out.print("Symbol"); System.out.print(" "); - System.out.print("Price"); + System.out.print("Market"); + System.out.print(" "); + System.out.print(YELLOW + "Price" + RESET); + System.out.print(" "); + System.out.print(GREEN + "Daily High" + RESET); + System.out.print(" "); + System.out.print(RED + "Daily Low" + RESET); System.out.print(" "); System.out.print("Company Name"); System.out.println(); @@ -61,9 +72,12 @@ public void printWatchListHeader() { public void printStocksInfo(WatchList watchList) { for (Stock stock: watchList.getStocks()) { String symbol = StringUtils.rightPad(stock.getSymbol(), 10); - String price = StringUtils.rightPad(stock.getPrice(), 10); - String name = StringUtils.rightPad((String) stock.getStockName(), 10); - System.out.println(symbol + price + name); + String market = StringUtils.rightPad(stock.getExchange(), 10); + String price = YELLOW + StringUtils.rightPad(stock.getPrice(), 10) + RESET; + String dayHigh = GREEN + StringUtils.rightPad(stock.getDayHigh(), 15) + RESET; + String dayLow = RED + StringUtils.rightPad(stock.getDayLow(), 14) + RESET; + String name = StringUtils.rightPad(stock.getStockName(), 10); + System.out.println(symbol + market + price + dayHigh + dayLow + name); } } From ec6fefc088fb562e542bd3cf64be9ab02cbe1f09 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Thu, 26 Oct 2023 21:18:01 +0800 Subject: [PATCH 230/518] Fix checkstyle errors --- .../java/seedu/financialplanner/investments/WatchList.java | 1 - src/main/java/seedu/financialplanner/utils/Ui.java | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index be64504f73..e2b62c24bd 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -1,6 +1,5 @@ package seedu.financialplanner.investments; -import org.apache.commons.lang3.StringUtils; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index f7504258e0..7f4af39a84 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -9,12 +9,11 @@ import java.util.Scanner; public class Ui { + private static Ui ui = null; private final String RED = "\u001B[31m"; private final String GREEN = "\u001B[32m"; private final String RESET = "\u001B[0m"; - private final String YELLOW = "\u001B[33m"; - private static Ui ui = null; private Scanner Scanner = new Scanner(System.in); private Ui() { } From 7590b789233a6734bdc9d6c105001eb4a077d540 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Fri, 27 Oct 2023 08:43:33 +0800 Subject: [PATCH 231/518] Add logging to ui --- .../java/seedu/financialplanner/commands/BudgetCommand.java | 2 +- src/main/java/seedu/financialplanner/utils/Ui.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java index dd846e8933..5ac2c064b8 100644 --- a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java +++ b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java @@ -10,7 +10,7 @@ import java.util.ArrayList; public class BudgetCommand extends Command { - private static Logger logger = Logger.getLogger("Financial Planner Logger"); + private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private final Ui ui = Ui.getInstance(); private double budget; private String command; diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 7f2aba4533..2be9adec36 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -7,8 +7,11 @@ import seedu.financialplanner.list.Cashflow; import java.util.Scanner; +import java.util.logging.Level; +import java.util.logging.Logger; public class Ui { + private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private static Ui ui = null; private Scanner Scanner = new Scanner(System.in); private Ui() { @@ -168,6 +171,7 @@ public void printBudgetError(String errorType) { showMessage("There is no existing budget."); break; default: + logger.log(Level.SEVERE, "Unreachable default case reached"); showMessage("Unknown command"); } } From 02571fe412b0507a0021ac111ef1371cda6b7d15 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Fri, 27 Oct 2023 08:46:00 +0800 Subject: [PATCH 232/518] Add variables to improve readability --- .../seedu/financialplanner/commands/OverviewCommand.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java index fc8b6bf1bf..6be7385e85 100644 --- a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java +++ b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java @@ -24,8 +24,13 @@ public OverviewCommand(RawCommand rawCommand) { @Override public void execute() throws Exception { - Ui.getInstance().printOverview(getBalance(), getHighestIncome(), getHighestExpense(), - getBudgetDesc(), getReminders()); + String balance = getBalance(); + String highestIncome = getHighestIncome(); + String highestExpense = getHighestExpense(); + String budget = getBudgetDesc(); + String reminders = getReminders(); + + Ui.getInstance().printOverview(balance, highestIncome, highestExpense, budget, reminders); //todo: goal disparity } From c92ed860899ec19d3845231e1c01266fae39553f Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Fri, 27 Oct 2023 08:52:42 +0800 Subject: [PATCH 233/518] Update sequence diagrams --- docs/diagrams/Budget.puml | 7 +++---- docs/diagrams/deleteBudget.puml | 6 +++--- docs/diagrams/resetBudget.puml | 6 +++--- docs/diagrams/viewBudget.puml | 6 +++--- docs/images/Budget.png | Bin 21119 -> 23702 bytes docs/images/deleteBudget.png | Bin 10119 -> 10845 bytes docs/images/resetBudget.png | Bin 17026 -> 18164 bytes docs/images/viewBudget.png | Bin 9649 -> 10358 bytes .../commands/OverviewCommand.java | 2 +- 9 files changed, 13 insertions(+), 14 deletions(-) diff --git a/docs/diagrams/Budget.puml b/docs/diagrams/Budget.puml index 54174d054a..755ff562c0 100644 --- a/docs/diagrams/Budget.puml +++ b/docs/diagrams/Budget.puml @@ -1,12 +1,11 @@ @startuml -participant BudgetCommand -participant Budget -participant Ui +participant ":BudgetCommand" as BudgetCommand +participant "<>\nBudget" as Budget +participant "<>\nUi" as Ui -> BudgetCommand: execute() BudgetCommand -> Ui: getInstance() -return ui alt set BudgetCommand -> Budget: setBudget(budget) diff --git a/docs/diagrams/deleteBudget.puml b/docs/diagrams/deleteBudget.puml index f3d4a70199..e689250914 100644 --- a/docs/diagrams/deleteBudget.puml +++ b/docs/diagrams/deleteBudget.puml @@ -1,9 +1,9 @@ @startuml mainframe sd DeleteBudget -participant BudgetCommand -participant Budget -participant Ui +participant ":BudgetCommand" as BudgetCommand +participant "<>\nBudget" as Budget +participant "<>\nUi" as Ui alt hasBudget BudgetCommand -> Budget: deleteBudget() diff --git a/docs/diagrams/resetBudget.puml b/docs/diagrams/resetBudget.puml index dec5060455..9e8de55185 100644 --- a/docs/diagrams/resetBudget.puml +++ b/docs/diagrams/resetBudget.puml @@ -1,9 +1,9 @@ @startuml mainframe sd ResetBudget -participant BudgetCommand -participant Budget -participant Ui +participant ":BudgetCommand" as BudgetCommand +participant "<>\nBudget" as Budget +participant "<>\nUi" as Ui alt spentBudget opt initialBudgetExceedBalance diff --git a/docs/diagrams/viewBudget.puml b/docs/diagrams/viewBudget.puml index 0988f5cf50..39c9ec1ccb 100644 --- a/docs/diagrams/viewBudget.puml +++ b/docs/diagrams/viewBudget.puml @@ -1,9 +1,9 @@ @startuml mainframe sd ViewBudget -participant BudgetCommand -participant Budget -participant Ui +participant ":BudgetCommand" as BudgetCommand +participant "<>\nBudget" as Budget +participant "<>\nUi" as Ui alt hasBudget BudgetCommand -> Ui: printBudget() diff --git a/docs/images/Budget.png b/docs/images/Budget.png index 32f6e71204b40c0b395d6da6fc869e7e22f90940..7a140e5cdfefc8ba438311c2e7eedac16f3815ca 100644 GIT binary patch literal 23702 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

+7k>|Q?z9=*w=~=>LPiNPDXuFpdW28~;Bp;72 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 literal 21119 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 Hj@SPKpHY@G literal 17026 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 Y9q6Wx!&DCbG6)1YDVXFtaeeRq1NH1e82|tP diff --git a/docs/images/viewBudget.png b/docs/images/viewBudget.png index 0b3795c4e7d32b7875aa9debdcfc1781f5612d28..02ff716a103f4c3d5e95e5e28ef4756c6618eb4a 100644 GIT binary patch literal 10358 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%0ACOj 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

i20Z!B_1}TrHhLIMa zeIJD?D=M)&XfSC49?z5gu{@18-Q9Pc8w`|xB0p&Y5vvnuP2OZ>RWE~l5OrO+``|k+j5B$8 zdH8)7E6`)rR^-0m{Q|f+m(1MGXk{X5O)++Mb}-zv2p{~zg$GWZ%OFSzcm?9nyUq`N zn6Cm_*gq8w@DoO%hui#+yRrXnG`I1K0n>2Q;VXfV8U*|P=s=ZvYmK1T$n@%aP>^B- zcrbnWlgQ^Kv4uQqFc#dix$#*ob^6Ceu|XZZ!_92`S06m|@B6{0e#@5n?5%bGP%;0T zk3R*x`NSt@ZPve+`u8WrNtb=mf9apGssENO83z8Y%P3D11DfssKNotKikjMK;N_>A zST9|8q`_Zdnu<{P1O$8J*d~Pi)FTgQk)+rfg3tc^`{r0quMXKSax(B0{C5iD_DxmA JA_e2X{{m8d4}kyx diff --git a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java index 6be7385e85..5014468eee 100644 --- a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java +++ b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java @@ -29,7 +29,7 @@ public void execute() throws Exception { String highestExpense = getHighestExpense(); String budget = getBudgetDesc(); String reminders = getReminders(); - + Ui.getInstance().printOverview(balance, highestIncome, highestExpense, budget, reminders); //todo: goal disparity From 7e07857802377a452d788cdb4964b0ed3cae3e12 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Fri, 27 Oct 2023 08:56:49 +0800 Subject: [PATCH 234/518] Update test files --- text-ui-test/EXPECTED.TXT | 3 +++ text-ui-test/input.txt | 3 +++ 2 files changed, 6 insertions(+) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 0d1b40ab92..7b359ff8fa 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -71,5 +71,8 @@ You have added an Expense to the Financial Planner. Balance: 4800.00 Your remaining budget for the month is: 800.00 +You have a remaining budget of 800.00. +Budget has been reset to 1000.00. +Budget has been deleted. Unknown command. Please try again. Exiting Financial Planner. Goodbye. diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index 18d4136373..0dc7251890 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -12,5 +12,8 @@ add income /a 5000 /t salary /r 30 budget set /b 3000 budget update /b 1000 add expense /a 200 /t shopping +budget view +budget reset +budget delete sdf exit \ No newline at end of file From f966c522ed58082edd1aead60e9efc1df674e51b Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Fri, 27 Oct 2023 15:26:21 +0800 Subject: [PATCH 235/518] Refactor Code --- .../investments/WatchList.java | 43 +++++++++++-------- .../java/seedu/financialplanner/utils/Ui.java | 2 +- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index e2b62c24bd..448583e790 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -93,28 +93,16 @@ public void fetchFMPStockPrices() throws FinancialPlannerException { for (Object jo : ja) { JSONObject stock = (JSONObject) jo; - if (!stocks.get(i).getSymbol().equals(stock.get("symbol"))) { + Stock stockLocal = stocks.get(i); + + // Check if the JSONObject from response matches the stock in the stocks list using symbol + if (!stockLocal.getSymbol().equals(stock.get("symbol"))) { i += 1; logger.log(Level.WARNING, "Stocks matching error!"); continue; } - String price = stock.get("price").toString(); - assert price != null; - stocks.get(i).setPrice(price); - - String exchange = stock.get("exchange").toString(); - assert exchange != null; - stocks.get(i).setExchange(exchange); - - String dayHigh = stock.get("dayHigh").toString(); - assert dayHigh != null; - stocks.get(i).setDayHigh(dayHigh); - - String dayLow = stock.get("dayLow").toString(); - assert dayLow != null; - stocks.get(i).setDayLow(dayLow); - + extractStockInfoFromJSON(stock, stockLocal); i += 1; } } @@ -149,6 +137,25 @@ public String deleteStock(String stockCode) throws FinancialPlannerException { stocks.remove(toBeRemoved); return toBeRemoved.getStockName(); } + + public void extractStockInfoFromJSON(JSONObject stock, Stock stockLocal) { + String price = stock.get("price").toString(); + assert price != null; + stockLocal.setPrice(price); + + String exchange = stock.get("exchange").toString(); + assert exchange != null; + stockLocal.setExchange(exchange); + + String dayHigh = stock.get("dayHigh").toString(); + assert dayHigh != null; + stockLocal.setDayHigh(dayHigh); + + String dayLow = stock.get("dayLow").toString(); + assert dayLow != null; + stockLocal.setDayLow(dayLow); + } + public int size() { return stocks.size(); } @@ -164,6 +171,4 @@ public ArrayList getStocks() { public void setStocks(ArrayList stocks) { this.stocks = stocks; } - - } diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 7f4af39a84..8a26362759 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -64,7 +64,7 @@ public void printWatchListHeader() { System.out.print(" "); System.out.print(RED + "Daily Low" + RESET); System.out.print(" "); - System.out.print("Company Name"); + System.out.print("EquityName"); System.out.println(); } From 412fc190e1de534e10dd256066463d2ea4fe7937 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Fri, 27 Oct 2023 15:45:03 +0800 Subject: [PATCH 236/518] Update JUnit tests --- .../commands/BudgetCommandTest.java | 85 +++++++++++++++++++ .../financialplanner/list/BudgetTest.java | 12 +++ 2 files changed, 97 insertions(+) diff --git a/src/test/java/seedu/financialplanner/commands/BudgetCommandTest.java b/src/test/java/seedu/financialplanner/commands/BudgetCommandTest.java index 4185076b06..c74c6a9d22 100644 --- a/src/test/java/seedu/financialplanner/commands/BudgetCommandTest.java +++ b/src/test/java/seedu/financialplanner/commands/BudgetCommandTest.java @@ -11,6 +11,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertFalse; @TestMethodOrder(OrderAnnotation.class) public class BudgetCommandTest { @@ -34,4 +35,88 @@ public void testUpdateBudget() throws FinancialPlannerException { assertEquals(1500, Budget.getInitialBudget()); assertEquals(1500, Budget.getCurrentBudget()); } + + @Test + @Order(3) + public void testResetBudget() throws FinancialPlannerException { + BudgetCommand testBudget = new BudgetCommand(Parser.parseRawCommand("budget reset")); + AddCashflowCommand testExpense = new AddCashflowCommand(Parser.parseRawCommand("add expense /a 50 /t dining")); + testExpense.execute(); + testBudget.execute(); + assertEquals(1500, Budget.getInitialBudget()); + assertEquals(1500, Budget.getCurrentBudget()); + Budget.deduct(50); + Cashflow.setBalance(1000); + BudgetCommand testBudgetExceedBalance = new BudgetCommand(Parser.parseRawCommand("budget reset")); + testBudgetExceedBalance.execute(); + assertEquals(1000, Budget.getInitialBudget()); + assertEquals(1000, Budget.getCurrentBudget()); + } + + @Test + @Order(4) + public void testDeleteBudget() throws FinancialPlannerException { + BudgetCommand testBudget = new BudgetCommand(Parser.parseRawCommand("budget delete")); + testBudget.execute(); + assertFalse(Budget.hasBudget()); + } + + @Test + @Order(5) + public void testInvalidCommandFormat_throwsException() throws FinancialPlannerException { + try { + BudgetCommand testExtraArgument = new BudgetCommand(Parser.parseRawCommand("budget" + + " set /b 500 /t sdf")); + } catch (IllegalArgumentException e) { + assertEquals("Unknown extra argument: t", e.getMessage()); + } + try { + BudgetCommand testInvalidCommand = new BudgetCommand(Parser.parseRawCommand("budget random /b 5")); + } catch (FinancialPlannerException e) { + assertEquals("Budget command must be one of the following: set, update, " + + "delete, reset, view.", e.getMessage()); + } + + Budget.setBudget(5); + try { + BudgetCommand testSetAndHasBudget = new BudgetCommand(Parser.parseRawCommand("budget set /b 55")); + } catch (FinancialPlannerException e) { + assertEquals("There is an existing budget, did you mean update?", e.getMessage()); + } + Budget.deleteBudget(); + + try { + BudgetCommand testUpdateAndNoBudget = new BudgetCommand(Parser.parseRawCommand("budget update " + + "/b 500")); + } catch (FinancialPlannerException e) { + assertEquals("There is no budget set yet, did you mean set?", e.getMessage()); + } + + try { + BudgetCommand testMissingArgument = new BudgetCommand(Parser.parseRawCommand("budget set")); + } catch (IllegalArgumentException e) { + assertEquals("Missing /b argument.", e.getMessage()); + } + } + + @Test + @Order(6) + public void testInvalidBudget_throwsException() throws FinancialPlannerException { + try { + BudgetCommand testStringBudget = new BudgetCommand(Parser.parseRawCommand("budget set /b f")); + } catch (IllegalArgumentException e) { + assertEquals("Budget must be a number.", e.getMessage()); + } + try { + BudgetCommand testNegativeBudget = new BudgetCommand(Parser.parseRawCommand("budget set /b -5")); + } catch (FinancialPlannerException e) { + assertEquals("Budget should be greater than 0.", e.getMessage()); + } + Cashflow.clearBalance(); + try { + BudgetCommand testBudgetExceedBalance = new BudgetCommand(Parser.parseRawCommand("budget set /b 500")); + } catch (FinancialPlannerException e) { + assertEquals("Budget should be lower than total balance.", e.getMessage()); + } + } } diff --git a/src/test/java/seedu/financialplanner/list/BudgetTest.java b/src/test/java/seedu/financialplanner/list/BudgetTest.java index 215339e732..0d5609ee04 100644 --- a/src/test/java/seedu/financialplanner/list/BudgetTest.java +++ b/src/test/java/seedu/financialplanner/list/BudgetTest.java @@ -35,6 +35,9 @@ public void testNewExpense() { @Test @Order(3) public void testUpdateBudget() { + Budget.updateBudget(300); + assertEquals(300, Budget.getInitialBudget()); + assertEquals(250, Budget.getCurrentBudget()); Budget.updateBudget(1000); assertEquals(1000, Budget.getInitialBudget()); assertEquals(950, Budget.getCurrentBudget()); @@ -70,4 +73,13 @@ public void testDeleteBudget() { assertEquals(0, Budget.getCurrentBudget()); assertFalse(Budget.hasBudget()); } + + @Test + @Order(8) + public void testLoadBudget() { + Budget.load(100, 100); + assertEquals(100, Budget.getInitialBudget()); + assertEquals(100, Budget.getCurrentBudget()); + Budget.deleteBudget(); + } } From a3fc3c5b0968c530439ef2f345088f3161f70ce7 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Sat, 28 Oct 2023 15:50:13 +0800 Subject: [PATCH 237/518] Update UG and fix minor bugs --- docs/DeveloperGuide.md | 13 +- docs/UserGuide.md | 150 ++++++++++++++++-- docs/diagrams/Storage.puml | 11 +- docs/diagrams/resetBudget.puml | 2 + docs/images/Storage.png | Bin 21149 -> 20785 bytes docs/images/resetBudget.png | Bin 18164 -> 20906 bytes .../commands/BalanceCommand.java | 8 +- .../commands/BudgetCommand.java | 2 + .../commands/OverviewCommand.java | 12 +- 9 files changed, 175 insertions(+), 23 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 3301c430ac..e2cd557829 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -48,6 +48,17 @@ API: `Storage.java` * The `load` method in LoadData reads the `data.txt` file and loads any existing Income, Expense and Budget into the application. * The `save` method in SaveData saves all Incomes, Expenses and existing Budget into the `data.txt` file. +#### Design considerations: + +* There are 2 main ways to implement the storage, one is to save the data after every command, and the other is to save +the data one upon exiting the program with the `exit` command. +* Saving the data once upon exit (Currently implemented): + * Advantage: Better efficiency and performance of the program. + * Disadvantage: If the program crashes or is exit incorrectly, data will not be saved. +* Saving the data after every command: + * Advantage: Changes are saved after every command. + * Disadvantage: Executing command might slow down the program when there is a large amount of data to be saved. + ### Visualization Feature This feature is implemented with the help of [XChart](https://knowm.org/open-source/xchart/), a simple charting library for Java by Knowm. @@ -187,7 +198,7 @@ Example: `budget delete` The budget will be reset by resetting the current budget to the initial budget through the `resetBudget()` method in `Budget.java`. -Example : `budget reset` +Example: `budget reset` #### View budget: diff --git a/docs/UserGuide.md b/docs/UserGuide.md index abd9fbe891..476db83e0a 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -2,7 +2,9 @@ ## Introduction -{Give a product intro} +Financial Planner is a Command Line Interface (CLI) application for managing your finances conveniently. +It is optimized for use via the CLI and leverages your expertise in CLI and your ability to type fast and gives +you a one-stop interface to access a plethora of features to manage your finances. ## Quick Start @@ -15,19 +17,138 @@ {Give detailed description of each feature} -### Adding a todo: `todo` -Adds a new item to the list of todo items. +### Budget -Format: `todo n/TODO_NAME d/DEADLINE` +#### Setting a budget: `budget set` -* The `DEADLINE` can be in a natural language format. -* The `TODO_NAME` cannot contain punctuation. +Sets a monthly budget. -Example of usage: +Format: `budget set /b BUDGET` -`todo n/Write the rest of the User Guide d/next week` +* `BUDGET` has to be a positive number. -`todo n/Refactor the User Guide to remove passive voice d/13/04/2020` +Example of usage: `budget set /b 500` + +Example output: + +``` +A monthly budget of 500.00 has been set. +``` + +#### Updating budget: `budget update` + +Updates budget to a new value. + +Format: `budget update /b BUDGET` + +* `Budget` has to be a positive number. +* There has to be an existing budget. + +Example of usage: `budget update /b 1000` + +Example output: + +``` +Budget has been updated: +Old initial budget: 500.00 +Old current budget: 500.00 +New initial budget: 1000.00 +New current budget: 1000.00 +``` + +#### Resetting budget: `budget reset` + +Resets current budget to initial budget if they are different. + +Format: `budget reset` + +* Budget will be reset to initial budget or current balance, whichever is lower. + +Example of usage: `budget reset` + +Example output: + +``` +Budget has been reset to 1000.00. +``` + +#### Deleting budget: `budget delete` + +Deletes existing budget. + +Format: `budget delete` + +Example of usage: `budget delete` + +Example output: + +``` +Budget has been deleted. +``` + +#### Viewing budget: `budget view` + +View existing budget. + +Format: `budget view` + +Example of usage: `budget view` + +Example output: + +``` +You have a remaining budget of 1000.00. +``` + +### Displaying overview: `overview` + +Displays an overview of user's financials. + +Format: `overview` + +Example of usage: `overview` + +Example output: + +``` +Here is an overview of your financials: +Total balance: 3790.00 +Highest income: 5000.00 Category: Salary +Highest expense: 500.00 Category: Others +Remaining budget for the month: 1000.00 + +Reminders: +No reminders added yet. +``` + +### Viewing balance: `balance` + +View user's current balance. + +Format: `balance` + +Example of usage: `balance` + +Example output: + +``` +Balance: 3790.00 +``` + +### Exiting the program: `exit` + +Exits the program. + +Format: `exit` + +### Saving the data + +Data is automatically saved upon exiting the program using the `exit` command. Closing the program without exiting +will not save the data. + +### Loading the data + +Existing data will be automatically loaded when the program starts up. ## FAQ @@ -39,4 +160,13 @@ Example of usage: {Give a 'cheat sheet' of commands here} -* Add todo `todo n/TODO_NAME d/DEADLINE` +| Action | Format | +|----------------------|---------------------------| +| **Set budget** | `budget set /b BUDGET` | +| **Update budget** | `budget update /b BUDGET` | +| **Reset budget** | `budget reset` | +| **Delete budget** | `budget delete` | +| **View budget** | `budget view` | +| **Display Overview** | `overview` | +| **View balance** | `balance` | +| **Exit program** | `exit` | diff --git a/docs/diagrams/Storage.puml b/docs/diagrams/Storage.puml index 6b2a3ef31b..9b856c158d 100644 --- a/docs/diagrams/Storage.puml +++ b/docs/diagrams/Storage.puml @@ -8,8 +8,8 @@ Class Storage Class "{abstract}\nLoadData" as LoadData Class "{abstract}\nSaveData" as SaveData Class CashflowList -Class Budget -Class Cashflow +Class "{abstract}\nBudget" as Budget +Class "{abstract}\nCashflow" as Cashflow Class "<>\nExpenseType" as ExpenseType Class "<>\nIncomeType" as IncomeType Class Ui @@ -26,9 +26,10 @@ SaveData ..> Cashflow LoadData --> CashflowList LoadData ..> Budget -LoadData --> ExpenseType -LoadData --> IncomeType -LoadData --> Cashflow +LoadData ..> ExpenseType +LoadData ..> IncomeType +LoadData ..> Cashflow LoadData -right-> Ui: prints message > + @enduml \ No newline at end of file diff --git a/docs/diagrams/resetBudget.puml b/docs/diagrams/resetBudget.puml index 9e8de55185..8efef02d34 100644 --- a/docs/diagrams/resetBudget.puml +++ b/docs/diagrams/resetBudget.puml @@ -12,6 +12,8 @@ alt spentBudget end BudgetCommand -> Budget: resetBudget() BudgetCommand -> Ui: printResetBudget() +else !hasBudget + BudgetCommand -> Ui: printBudgetError("delete") else else BudgetCommand -> Ui: printBudgetError("reset") end diff --git a/docs/images/Storage.png b/docs/images/Storage.png index 347b2cdb980ad923e98764e7392f60e2294f52ec..d0e6ec236b05e1c93e4e2c0d15ae2c492d6270d1 100644 GIT binary patch literal 20785 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%0DXGj?z^@O~J83M< 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 A;{X5v diff --git a/docs/images/resetBudget.png b/docs/images/resetBudget.png index 50972a0bfc26f8e22b43ab78f4e0deaa4443ee4a..e9f8f5e57821bd82d9b1e3776d752905de956920 100644 GIT binary patch literal 20906 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 Hj@SPKpHY@G diff --git a/src/main/java/seedu/financialplanner/commands/BalanceCommand.java b/src/main/java/seedu/financialplanner/commands/BalanceCommand.java index e1ee22afd3..626197f235 100644 --- a/src/main/java/seedu/financialplanner/commands/BalanceCommand.java +++ b/src/main/java/seedu/financialplanner/commands/BalanceCommand.java @@ -3,6 +3,7 @@ import seedu.financialplanner.list.Cashflow; import seedu.financialplanner.utils.Ui; +import java.text.DecimalFormat; import java.util.ArrayList; public class BalanceCommand extends Command { @@ -17,6 +18,11 @@ public BalanceCommand(RawCommand rawCommand) { @Override public void execute() throws Exception { - ui.showMessage("Balance: " + Cashflow.getBalance()); + ui.showMessage("Balance: " + getBalanceString()); + } + + private String getBalanceString() { + DecimalFormat decimalFormat = new DecimalFormat("####0.00"); + return decimalFormat.format(Cashflow.round(Cashflow.getBalance(), 2)); } } diff --git a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java index 5ac2c064b8..01e3f20e71 100644 --- a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java +++ b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java @@ -116,6 +116,8 @@ private void resetBudget() { } Budget.resetBudget(); ui.printResetBudget(); + } else if (!Budget.hasBudget()) { + ui.printBudgetError("delete"); } else { ui.printBudgetError("reset"); } diff --git a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java index 5014468eee..02ea29342e 100644 --- a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java +++ b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java @@ -35,11 +35,11 @@ public void execute() throws Exception { //todo: goal disparity } - private static String getBudgetDesc() { + private String getBudgetDesc() { return Budget.getCurrentBudgetString(); } - private static String getHighestIncome() { + private String getHighestIncome() { double maxIncome = 0; String incomeType = ""; for (Cashflow entry : cashflowList.list) { @@ -57,7 +57,7 @@ private static String getHighestIncome() { return formatDoubleToString(maxIncome) + " Category: " + incomeType; } - private static String getHighestExpense() { + private String getHighestExpense() { double maxExpense = 0; String expenseType = ""; for (Cashflow entry : cashflowList.list) { @@ -75,13 +75,13 @@ private static String getHighestExpense() { return formatDoubleToString(maxExpense) + " Category: " + expenseType; } - private static String formatDoubleToString(double amount) { + private String formatDoubleToString(double amount) { DecimalFormat decimalFormat = new DecimalFormat("####0.00"); return decimalFormat.format(Cashflow.round(amount, 2)); } - private static String getReminders() { + private String getReminders() { ReminderList reminderList = ReminderList.INSTANCE; if (reminderList.list.isEmpty()) { return "No reminders added yet."; @@ -96,7 +96,7 @@ private static String getReminders() { return reminders.toString(); } - private static String getBalance() { + private String getBalance() { return formatDoubleToString(Cashflow.getBalance()); } } From 656d50e12e416b164337282e07aeee816146ad7d Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sat, 28 Oct 2023 17:06:04 +0800 Subject: [PATCH 238/518] Add description argument --- .../financialplanner/commands/AddCashflowCommand.java | 10 ++++++++-- .../java/seedu/financialplanner/list/Cashflow.java | 10 +++++++--- .../java/seedu/financialplanner/list/CashflowList.java | 8 ++++---- src/main/java/seedu/financialplanner/list/Expense.java | 4 ++-- src/main/java/seedu/financialplanner/list/Income.java | 4 ++-- 5 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index cd7a763cbd..27587228a5 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -21,6 +21,7 @@ public class AddCashflowCommand extends Command { protected ExpenseType expenseType; protected IncomeType incomeType; protected int recur = 0; + protected String description = null; protected CashflowList cashflowList = CashflowList.getInstance(); public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException { @@ -91,6 +92,11 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException throw new IllegalArgumentException("Recurring value cannot be negative"); } + if (rawCommand.extraArgs.containsKey("d")) { + description = rawCommand.extraArgs.get("d"); + } + rawCommand.extraArgs.remove("d"); + if (!rawCommand.extraArgs.isEmpty()) { String unknownExtraArgument = new ArrayList<>(rawCommand.extraArgs.keySet()).get(0); logger.log(Level.WARNING, "Invalid extra arguments found"); @@ -115,10 +121,10 @@ public void execute() { switch (category) { case INCOME: - cashflowList.addIncome(amount, incomeType, recur); + cashflowList.addIncome(amount, incomeType, recur, description); break; case EXPENSE: - cashflowList.addExpense(amount, expenseType, recur); + cashflowList.addExpense(amount, expenseType, recur, description); if (Budget.hasBudget()) { deductFromBudget(cashflowList.list.get(cashflowList.list.size() - 1)); } diff --git a/src/main/java/seedu/financialplanner/list/Cashflow.java b/src/main/java/seedu/financialplanner/list/Cashflow.java index 42cc75492f..48a35ba961 100644 --- a/src/main/java/seedu/financialplanner/list/Cashflow.java +++ b/src/main/java/seedu/financialplanner/list/Cashflow.java @@ -12,10 +12,12 @@ public abstract class Cashflow { protected static double balance = 0; protected double amount; protected int recur; + protected String description; - public Cashflow(double amount, int recur) { + public Cashflow(double amount, int recur, String description) { this.amount = amount; this.recur = recur; + this.description = description; } public static void clearBalance() { @@ -58,7 +60,9 @@ public String toString() { if (recur != 0) { string += System.lineSeparator() + " Recurring every: " + recur + " days"; } - + if (description != null) { + string += System.lineSeparator() + " Description: " + description; + } return string; } @@ -77,7 +81,7 @@ public static double getBalance() { } public String formatString() { - return " | " + this.recur; + return " | " + this.recur + " | " + this.description; } public abstract ExpenseType getExpenseType(); diff --git a/src/main/java/seedu/financialplanner/list/CashflowList.java b/src/main/java/seedu/financialplanner/list/CashflowList.java index 3b802e704c..409bcff93b 100644 --- a/src/main/java/seedu/financialplanner/list/CashflowList.java +++ b/src/main/java/seedu/financialplanner/list/CashflowList.java @@ -24,11 +24,11 @@ public static CashflowList getInstance() { return cashflowList; } - public void addIncome(double value, IncomeType type, int recur) { + public void addIncome(double value, IncomeType type, int recur, String description) { logger.log(Level.INFO, "Adding income"); int existingListSize = list.size(); - Income toAdd = new Income(value, type, recur); + Income toAdd = new Income(value, type, recur, description); list.add(toAdd); ui.printAddedCashflow(toAdd); @@ -36,11 +36,11 @@ public void addIncome(double value, IncomeType type, int recur) { assert newListSize == existingListSize + 1; } - public void addExpense(double value, ExpenseType type, int recur) { + public void addExpense(double value, ExpenseType type, int recur, String description) { logger.log(Level.INFO, "Adding expense"); int existingListSize = list.size(); - Expense toAdd = new Expense(value, type, recur); + Expense toAdd = new Expense(value, type, recur, description); list.add(toAdd); ui.printAddedCashflow(toAdd); diff --git a/src/main/java/seedu/financialplanner/list/Expense.java b/src/main/java/seedu/financialplanner/list/Expense.java index 3818c5fbe6..f6939321b9 100644 --- a/src/main/java/seedu/financialplanner/list/Expense.java +++ b/src/main/java/seedu/financialplanner/list/Expense.java @@ -6,8 +6,8 @@ public class Expense extends Cashflow { protected ExpenseType type; - public Expense(double amount, ExpenseType type, int recur) { - super(amount, recur); + public Expense(double amount, ExpenseType type, int recur, String description) { + super(amount, recur, description); this.type = type; addExpenseValue(); } diff --git a/src/main/java/seedu/financialplanner/list/Income.java b/src/main/java/seedu/financialplanner/list/Income.java index 8e596e43fb..80eb474435 100644 --- a/src/main/java/seedu/financialplanner/list/Income.java +++ b/src/main/java/seedu/financialplanner/list/Income.java @@ -6,8 +6,8 @@ public class Income extends Cashflow{ protected IncomeType type; - public Income(double amount, IncomeType type, int recur) { - super(amount, recur); + public Income(double amount, IncomeType type, int recur, String description) { + super(amount, recur, description); this.type = type; addIncomeValue(); } From b5acf6d892eec6e5b7ea16ecd331f011408758c0 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sat, 28 Oct 2023 17:13:14 +0800 Subject: [PATCH 239/518] Update tests --- .../financialplanner/list/CashflowListTest.java | 12 ++++++++---- .../seedu/financialplanner/storage/StorageTest.java | 4 ++-- src/test/testData/ValidData.txt | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/test/java/seedu/financialplanner/list/CashflowListTest.java b/src/test/java/seedu/financialplanner/list/CashflowListTest.java index 38bf3efe85..883423e86b 100644 --- a/src/test/java/seedu/financialplanner/list/CashflowListTest.java +++ b/src/test/java/seedu/financialplanner/list/CashflowListTest.java @@ -19,7 +19,7 @@ void testAddIncomeAndExpense() { testList.list.clear(); Cashflow.balance = 0; - testList.addIncome(15, IncomeType.SALARY, 30); + testList.addIncome(15, IncomeType.SALARY, 30, "part time job"); Cashflow testIncome = testList.list.get(0); double roundedValue = Cashflow.round(testIncome.amount, 2); double roundedBalance = Cashflow.round(Cashflow.balance, 2); @@ -28,8 +28,9 @@ void testAddIncomeAndExpense() { assertEquals(IncomeType.SALARY, testIncome.getIncomeType()); assertEquals(30, testIncome.recur); assertEquals("15.00", decimalFormat.format(roundedBalance)); + assertEquals("part time job", testIncome.description); - testList.addIncome(15.999, IncomeType.INVESTMENTS, 0); + testList.addIncome(15.999, IncomeType.INVESTMENTS, 0, "AAPL"); testIncome = testList.list.get(1); roundedValue = Cashflow.round(testIncome.amount, 2); roundedBalance = Cashflow.round(Cashflow.balance, 2); @@ -38,8 +39,9 @@ void testAddIncomeAndExpense() { assertEquals(IncomeType.INVESTMENTS, testIncome.getIncomeType()); assertEquals(0, testIncome.recur); assertEquals("31.00", decimalFormat.format(roundedBalance)); + assertEquals("AAPL", testIncome.description); - testList.addExpense(10, ExpenseType.DINING, 0); + testList.addExpense(10, ExpenseType.DINING, 0, "double mcspicy"); Cashflow testExpense = testList.list.get(2); roundedValue = Cashflow.round(testExpense.amount, 2); roundedBalance = Cashflow.round(Cashflow.balance, 2); @@ -48,8 +50,9 @@ void testAddIncomeAndExpense() { assertEquals(ExpenseType.DINING, testExpense.getExpenseType()); assertEquals(0, testExpense.recur); assertEquals("21.00", decimalFormat.format(roundedBalance)); + assertEquals("double mcspicy", testExpense.description); - testList.addExpense(19.999, ExpenseType.ENTERTAINMENT, 30); + testList.addExpense(19.999, ExpenseType.ENTERTAINMENT, 30, "netflix"); testExpense = testList.list.get(3); roundedValue = Cashflow.round(testExpense.amount, 2); roundedBalance = Cashflow.round(Cashflow.balance, 2); @@ -58,6 +61,7 @@ void testAddIncomeAndExpense() { assertEquals(ExpenseType.ENTERTAINMENT, testExpense.getExpenseType()); assertEquals(30, testExpense.recur); assertEquals("1.00", decimalFormat.format(roundedBalance)); + assertEquals("netflix", testExpense.description); } @Test diff --git a/src/test/java/seedu/financialplanner/storage/StorageTest.java b/src/test/java/seedu/financialplanner/storage/StorageTest.java index 7ffaa4be4b..0a03a418b8 100644 --- a/src/test/java/seedu/financialplanner/storage/StorageTest.java +++ b/src/test/java/seedu/financialplanner/storage/StorageTest.java @@ -62,7 +62,7 @@ public void saveNonExistentFile() { } private void getTestData() { - cashflowList.load(new Income(123.12, IncomeType.ALLOWANCE, 0)); - cashflowList.load(new Expense(100, ExpenseType.SHOPPING, 30)); + cashflowList.load(new Income(123.12, IncomeType.ALLOWANCE, 0, null)); + cashflowList.load(new Expense(100, ExpenseType.SHOPPING, 30, "shopee")); } } diff --git a/src/test/testData/ValidData.txt b/src/test/testData/ValidData.txt index e6cc7f744f..d57f2a1793 100644 --- a/src/test/testData/ValidData.txt +++ b/src/test/testData/ValidData.txt @@ -1,3 +1,3 @@ I | 123.12 | ALLOWANCE | 0 -E | 100.0 | SHOPPING | 30 +E | 100.0 | SHOPPING | 30 | shopee B | 0.0 | 0.0 \ No newline at end of file From 96645cb039afa0245efc92e148f14b590b2a9e88 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sat, 28 Oct 2023 17:13:45 +0800 Subject: [PATCH 240/518] Update storage for cashflow --- .../seedu/financialplanner/list/Cashflow.java | 8 +++++++- .../financialplanner/storage/LoadData.java | 19 ++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/main/java/seedu/financialplanner/list/Cashflow.java b/src/main/java/seedu/financialplanner/list/Cashflow.java index 48a35ba961..786071e359 100644 --- a/src/main/java/seedu/financialplanner/list/Cashflow.java +++ b/src/main/java/seedu/financialplanner/list/Cashflow.java @@ -81,7 +81,13 @@ public static double getBalance() { } public String formatString() { - return " | " + this.recur + " | " + this.description; + String string = " | " + this.recur; + + if (description != null) { + string += " | " + this.description; + } + + return string; } public abstract ExpenseType getExpenseType(); diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index a076bf1569..c17f46edb5 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -95,17 +95,25 @@ private static boolean createNewFile() { return line.equalsIgnoreCase("y"); } - + private static boolean hasDescription(String[] split) { + return (split.length > 4); + } private static Cashflow getEntry(String type, String[] split) throws FinancialPlannerException, IllegalArgumentException { double value; int recur; Cashflow entry; + String description; switch (type) { case "I": value = Double.parseDouble(split[1].trim()); recur = Integer.parseInt(split[3].trim()); + if (hasDescription(split)) { + description = split[4].trim(); + } else { + description = null; + } checkValidInput(value, recur); IncomeType incomeType; try { @@ -113,11 +121,16 @@ private static Cashflow getEntry(String type, String[] split) } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Invalid income type"); } - entry = new Income(value, incomeType, recur); + entry = new Income(value, incomeType, recur, description); break; case "E": value = Double.parseDouble(split[1].trim()); recur = Integer.parseInt(split[3].trim()); + if (hasDescription(split)) { + description = split[4].trim(); + } else { + description = null; + } checkValidInput(value, recur); ExpenseType expenseType; try { @@ -125,7 +138,7 @@ private static Cashflow getEntry(String type, String[] split) } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Invalid expense type"); } - entry = new Expense(value, expenseType, recur); + entry = new Expense(value, expenseType, recur, description); break; default: throw new FinancialPlannerException("Error loading file"); From 44859bacf030e50251ea72d5b090a916e2fb5ab2 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sat, 28 Oct 2023 17:14:00 +0800 Subject: [PATCH 241/518] Update text ui test --- text-ui-test/EXPECTED.TXT | 4 ++++ text-ui-test/input.txt | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 7b359ff8fa..25ddd7bb78 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -7,6 +7,7 @@ You have added an Income Type: Salary Amount: 5000.00 Recurring every: 30 days + Description: part time job to the Financial Planner. Balance: 5000.00 You have added an Income @@ -18,6 +19,7 @@ You have added an Expense Type: Entertainment Amount: 100.00 Recurring every: 30 days + Description: netflix to the Financial Planner. Balance: 5023.12 You have added an Expense @@ -34,6 +36,7 @@ You have removed an Income Type: Salary Amount: 5000.00 Recurring every: 30 days + Description: part time job from the Financial Planner. Balance: -223.21 You have removed an Expense @@ -45,6 +48,7 @@ You have removed an Expense Type: Entertainment Amount: 100.00 Recurring every: 30 days + Description: netflix from the Financial Planner. Balance: 0.00 You have successfully added: diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index 0dc7251890..9c5bae1bdc 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -1,6 +1,6 @@ -add income /a 5000 /t salary /r 30 +add income /a 5000 /t salary /r 30 /d part time job add income /a 123.12 /t allowance -add expense /a 100 /t entertainment /r 30 +add expense /a 100 /t entertainment /r 30 /d netflix add expense /a 123.21 /t shopping delete income 2 delete 1 From 4a5cdc73d8b300be5b22d81a4756f7a0aa7b14d2 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sat, 28 Oct 2023 17:19:28 +0800 Subject: [PATCH 242/518] Add logging for getting description --- .../seedu/financialplanner/commands/AddCashflowCommand.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index 27587228a5..fe0291dc4d 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -93,6 +93,7 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException } if (rawCommand.extraArgs.containsKey("d")) { + logger.log(Level.INFO, "Getting description of cashflow"); description = rawCommand.extraArgs.get("d"); } rawCommand.extraArgs.remove("d"); @@ -118,7 +119,7 @@ public void execute() { assert incomeType.equals(IncomeType.SALARY) || incomeType.equals(IncomeType.INVESTMENTS) || incomeType.equals(IncomeType.ALLOWANCE) || incomeType.equals(IncomeType.OTHERS); } - + switch (category) { case INCOME: cashflowList.addIncome(amount, incomeType, recur, description); From 261dfa7799f523f1b961c1b70782fe590f570b91 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Sat, 28 Oct 2023 19:12:54 +0800 Subject: [PATCH 243/518] Fix sentence in DG --- docs/DeveloperGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index e2cd557829..6df0a4e3ed 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -54,7 +54,7 @@ API: `Storage.java` the data one upon exiting the program with the `exit` command. * Saving the data once upon exit (Currently implemented): * Advantage: Better efficiency and performance of the program. - * Disadvantage: If the program crashes or is exit incorrectly, data will not be saved. + * Disadvantage: If the program crashes or exits incorrectly, data will not be saved. * Saving the data after every command: * Advantage: Changes are saved after every command. * Disadvantage: Executing command might slow down the program when there is a large amount of data to be saved. From e27031ba253b578571b583d6e6e92634e07a416a Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sat, 28 Oct 2023 19:17:03 +0800 Subject: [PATCH 244/518] Rename list package to cashflow for clarity --- .../financialplanner/{list => cashflow}/Budget.java | 2 +- .../{list => cashflow}/Cashflow.java | 2 +- .../{list => cashflow}/CashflowList.java | 6 +++--- .../financialplanner/{list => cashflow}/Expense.java | 2 +- .../financialplanner/{list => cashflow}/Income.java | 2 +- .../commands/AddCashflowCommand.java | 8 ++++---- .../financialplanner/commands/BalanceCommand.java | 2 +- .../financialplanner/commands/BudgetCommand.java | 4 ++-- .../commands/DeleteCashflowCommand.java | 8 ++++---- .../seedu/financialplanner/commands/FindCommand.java | 2 +- .../seedu/financialplanner/commands/ListCommand.java | 8 ++++---- .../financialplanner/commands/OverviewCommand.java | 10 +++++----- .../seedu/financialplanner/commands/VisCommand.java | 2 +- .../seedu/financialplanner/storage/LoadData.java | 12 +++++++----- .../seedu/financialplanner/storage/SaveData.java | 6 +++--- src/main/java/seedu/financialplanner/utils/Ui.java | 4 ++-- .../financialplanner/visualisations/Categorizer.java | 8 ++++---- .../{list => cashflow}/BudgetTest.java | 2 +- .../{list => cashflow}/CashflowListTest.java | 10 +++++----- .../commands/AddCashflowCommandTest.java | 2 +- .../financialplanner/commands/BudgetCommandTest.java | 4 ++-- .../seedu/financialplanner/storage/StorageTest.java | 6 +++--- 22 files changed, 57 insertions(+), 55 deletions(-) rename src/main/java/seedu/financialplanner/{list => cashflow}/Budget.java (98%) rename src/main/java/seedu/financialplanner/{list => cashflow}/Cashflow.java (98%) rename src/main/java/seedu/financialplanner/{list => cashflow}/CashflowList.java (95%) rename src/main/java/seedu/financialplanner/{list => cashflow}/Expense.java (96%) rename src/main/java/seedu/financialplanner/{list => cashflow}/Income.java (96%) rename src/test/java/seedu/financialplanner/{list => cashflow}/BudgetTest.java (98%) rename src/test/java/seedu/financialplanner/{list => cashflow}/CashflowListTest.java (93%) diff --git a/src/main/java/seedu/financialplanner/list/Budget.java b/src/main/java/seedu/financialplanner/cashflow/Budget.java similarity index 98% rename from src/main/java/seedu/financialplanner/list/Budget.java rename to src/main/java/seedu/financialplanner/cashflow/Budget.java index 4ffad82d60..6aaae47a11 100644 --- a/src/main/java/seedu/financialplanner/list/Budget.java +++ b/src/main/java/seedu/financialplanner/cashflow/Budget.java @@ -1,4 +1,4 @@ -package seedu.financialplanner.list; +package seedu.financialplanner.cashflow; import java.text.DecimalFormat; diff --git a/src/main/java/seedu/financialplanner/list/Cashflow.java b/src/main/java/seedu/financialplanner/cashflow/Cashflow.java similarity index 98% rename from src/main/java/seedu/financialplanner/list/Cashflow.java rename to src/main/java/seedu/financialplanner/cashflow/Cashflow.java index 786071e359..c9ca8c6f81 100644 --- a/src/main/java/seedu/financialplanner/list/Cashflow.java +++ b/src/main/java/seedu/financialplanner/cashflow/Cashflow.java @@ -1,4 +1,4 @@ -package seedu.financialplanner.list; +package seedu.financialplanner.cashflow; import seedu.financialplanner.enumerations.ExpenseType; import seedu.financialplanner.enumerations.IncomeType; diff --git a/src/main/java/seedu/financialplanner/list/CashflowList.java b/src/main/java/seedu/financialplanner/cashflow/CashflowList.java similarity index 95% rename from src/main/java/seedu/financialplanner/list/CashflowList.java rename to src/main/java/seedu/financialplanner/cashflow/CashflowList.java index 409bcff93b..226d5ea14a 100644 --- a/src/main/java/seedu/financialplanner/list/CashflowList.java +++ b/src/main/java/seedu/financialplanner/cashflow/CashflowList.java @@ -1,4 +1,4 @@ -package seedu.financialplanner.list; +package seedu.financialplanner.cashflow; import seedu.financialplanner.enumerations.CashflowCategory; import seedu.financialplanner.enumerations.ExpenseType; @@ -48,7 +48,7 @@ public void addExpense(double value, ExpenseType type, int recur, String descrip assert newListSize == existingListSize + 1; } - public double delete(int index) { + public double deleteCashflowWithoutCategory(int index) { int existingListSize = list.size(); int listIndex = index - 1; @@ -109,7 +109,7 @@ private int findCashflowIndexFromExpenseIndex(int cashflowIndex) { return overallCashflowIndex; } - public double deleteCashflow(CashflowCategory category, int index) { + public double deleteCashflowWithCategory(CashflowCategory category, int index) { int existingListSize = list.size(); int listIndex = cashflowIndexFinder(category, index); diff --git a/src/main/java/seedu/financialplanner/list/Expense.java b/src/main/java/seedu/financialplanner/cashflow/Expense.java similarity index 96% rename from src/main/java/seedu/financialplanner/list/Expense.java rename to src/main/java/seedu/financialplanner/cashflow/Expense.java index f6939321b9..39310b21d4 100644 --- a/src/main/java/seedu/financialplanner/list/Expense.java +++ b/src/main/java/seedu/financialplanner/cashflow/Expense.java @@ -1,4 +1,4 @@ -package seedu.financialplanner.list; +package seedu.financialplanner.cashflow; import seedu.financialplanner.enumerations.ExpenseType; import seedu.financialplanner.enumerations.IncomeType; diff --git a/src/main/java/seedu/financialplanner/list/Income.java b/src/main/java/seedu/financialplanner/cashflow/Income.java similarity index 96% rename from src/main/java/seedu/financialplanner/list/Income.java rename to src/main/java/seedu/financialplanner/cashflow/Income.java index 80eb474435..0af604eefd 100644 --- a/src/main/java/seedu/financialplanner/list/Income.java +++ b/src/main/java/seedu/financialplanner/cashflow/Income.java @@ -1,4 +1,4 @@ -package seedu.financialplanner.list; +package seedu.financialplanner.cashflow; import seedu.financialplanner.enumerations.ExpenseType; import seedu.financialplanner.enumerations.IncomeType; diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index fe0291dc4d..ed92f2cd1a 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -3,9 +3,9 @@ import seedu.financialplanner.enumerations.CashflowCategory; import seedu.financialplanner.enumerations.ExpenseType; import seedu.financialplanner.enumerations.IncomeType; -import seedu.financialplanner.list.Budget; -import seedu.financialplanner.list.Cashflow; -import seedu.financialplanner.list.CashflowList; +import seedu.financialplanner.cashflow.Budget; +import seedu.financialplanner.cashflow.Cashflow; +import seedu.financialplanner.cashflow.CashflowList; import seedu.financialplanner.utils.Ui; import java.util.ArrayList; @@ -119,7 +119,7 @@ public void execute() { assert incomeType.equals(IncomeType.SALARY) || incomeType.equals(IncomeType.INVESTMENTS) || incomeType.equals(IncomeType.ALLOWANCE) || incomeType.equals(IncomeType.OTHERS); } - + switch (category) { case INCOME: cashflowList.addIncome(amount, incomeType, recur, description); diff --git a/src/main/java/seedu/financialplanner/commands/BalanceCommand.java b/src/main/java/seedu/financialplanner/commands/BalanceCommand.java index e1ee22afd3..75eaf0944f 100644 --- a/src/main/java/seedu/financialplanner/commands/BalanceCommand.java +++ b/src/main/java/seedu/financialplanner/commands/BalanceCommand.java @@ -1,6 +1,6 @@ package seedu.financialplanner.commands; -import seedu.financialplanner.list.Cashflow; +import seedu.financialplanner.cashflow.Cashflow; import seedu.financialplanner.utils.Ui; import java.util.ArrayList; diff --git a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java index 5ac2c064b8..d6f89788df 100644 --- a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java +++ b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java @@ -1,8 +1,8 @@ package seedu.financialplanner.commands; import seedu.financialplanner.exceptions.FinancialPlannerException; -import seedu.financialplanner.list.Budget; -import seedu.financialplanner.list.Cashflow; +import seedu.financialplanner.cashflow.Budget; +import seedu.financialplanner.cashflow.Cashflow; import seedu.financialplanner.utils.Ui; import java.util.logging.Level; diff --git a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java index 30031cc880..7b0e2b5eac 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java @@ -1,8 +1,8 @@ package seedu.financialplanner.commands; import seedu.financialplanner.enumerations.CashflowCategory; -import seedu.financialplanner.list.Budget; -import seedu.financialplanner.list.CashflowList; +import seedu.financialplanner.cashflow.Budget; +import seedu.financialplanner.cashflow.CashflowList; import seedu.financialplanner.utils.Ui; import java.util.logging.Level; @@ -77,7 +77,7 @@ public void execute() { private void handleDeleteCashflowWithoutCategory() { try { logger.log(Level.INFO, "Deleting cashflow without category"); - double amount = cashflowList.delete(index); + double amount = cashflowList.deleteCashflowWithoutCategory(index); if (Budget.hasBudget()) { Budget.updateCurrentBudget(amount); } @@ -90,7 +90,7 @@ private void handleDeleteCashflowWithoutCategory() { private void handleDeleteCashflowWithCategory() { try { logger.log(Level.INFO, "Deleting cashflow with category"); - double amount = cashflowList.deleteCashflow(category, index); + double amount = cashflowList.deleteCashflowWithCategory(category, index); if (Budget.hasBudget()) { Budget.updateCurrentBudget(amount); } diff --git a/src/main/java/seedu/financialplanner/commands/FindCommand.java b/src/main/java/seedu/financialplanner/commands/FindCommand.java index a58a3bdb17..dda7f75480 100644 --- a/src/main/java/seedu/financialplanner/commands/FindCommand.java +++ b/src/main/java/seedu/financialplanner/commands/FindCommand.java @@ -1,7 +1,7 @@ package seedu.financialplanner.commands; import seedu.financialplanner.investments.WatchList; -import seedu.financialplanner.list.CashflowList; +import seedu.financialplanner.cashflow.CashflowList; import seedu.financialplanner.utils.Ui; import java.util.ArrayList; diff --git a/src/main/java/seedu/financialplanner/commands/ListCommand.java b/src/main/java/seedu/financialplanner/commands/ListCommand.java index 2427d7ed83..0395360ff7 100644 --- a/src/main/java/seedu/financialplanner/commands/ListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/ListCommand.java @@ -1,10 +1,10 @@ package seedu.financialplanner.commands; import seedu.financialplanner.enumerations.CashflowCategory; -import seedu.financialplanner.list.Cashflow; -import seedu.financialplanner.list.CashflowList; -import seedu.financialplanner.list.Expense; -import seedu.financialplanner.list.Income; +import seedu.financialplanner.cashflow.Cashflow; +import seedu.financialplanner.cashflow.CashflowList; +import seedu.financialplanner.cashflow.Expense; +import seedu.financialplanner.cashflow.Income; import seedu.financialplanner.utils.Ui; import java.util.ArrayList; diff --git a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java index 5014468eee..4f21c1f28f 100644 --- a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java +++ b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java @@ -1,10 +1,10 @@ package seedu.financialplanner.commands; -import seedu.financialplanner.list.Budget; -import seedu.financialplanner.list.Cashflow; -import seedu.financialplanner.list.CashflowList; -import seedu.financialplanner.list.Income; -import seedu.financialplanner.list.Expense; +import seedu.financialplanner.cashflow.Budget; +import seedu.financialplanner.cashflow.Cashflow; +import seedu.financialplanner.cashflow.CashflowList; +import seedu.financialplanner.cashflow.Income; +import seedu.financialplanner.cashflow.Expense; import seedu.financialplanner.reminder.Reminder; import seedu.financialplanner.reminder.ReminderList; import seedu.financialplanner.utils.Ui; diff --git a/src/main/java/seedu/financialplanner/commands/VisCommand.java b/src/main/java/seedu/financialplanner/commands/VisCommand.java index 79cf05c80d..cef652921e 100644 --- a/src/main/java/seedu/financialplanner/commands/VisCommand.java +++ b/src/main/java/seedu/financialplanner/commands/VisCommand.java @@ -1,7 +1,7 @@ package seedu.financialplanner.commands; import seedu.financialplanner.exceptions.FinancialPlannerException; -import seedu.financialplanner.list.CashflowList; +import seedu.financialplanner.cashflow.CashflowList; import seedu.financialplanner.utils.Ui; import seedu.financialplanner.visualisations.Categorizer; import seedu.financialplanner.visualisations.Visualizer; diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index c17f46edb5..1ba7404a6e 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -4,11 +4,11 @@ import seedu.financialplanner.enumerations.IncomeType; import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.investments.Stock; -import seedu.financialplanner.list.Budget; -import seedu.financialplanner.list.Cashflow; -import seedu.financialplanner.list.CashflowList; -import seedu.financialplanner.list.Income; -import seedu.financialplanner.list.Expense; +import seedu.financialplanner.cashflow.Budget; +import seedu.financialplanner.cashflow.Cashflow; +import seedu.financialplanner.cashflow.CashflowList; +import seedu.financialplanner.cashflow.Income; +import seedu.financialplanner.cashflow.Expense; import seedu.financialplanner.utils.Ui; import java.io.StreamCorruptedException; @@ -95,9 +95,11 @@ private static boolean createNewFile() { return line.equalsIgnoreCase("y"); } + private static boolean hasDescription(String[] split) { return (split.length > 4); } + private static Cashflow getEntry(String type, String[] split) throws FinancialPlannerException, IllegalArgumentException { double value; diff --git a/src/main/java/seedu/financialplanner/storage/SaveData.java b/src/main/java/seedu/financialplanner/storage/SaveData.java index c08e755e72..e3b3162afe 100644 --- a/src/main/java/seedu/financialplanner/storage/SaveData.java +++ b/src/main/java/seedu/financialplanner/storage/SaveData.java @@ -2,9 +2,9 @@ import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.investments.WatchList; -import seedu.financialplanner.list.Budget; -import seedu.financialplanner.list.Cashflow; -import seedu.financialplanner.list.CashflowList; +import seedu.financialplanner.cashflow.Budget; +import seedu.financialplanner.cashflow.Cashflow; +import seedu.financialplanner.cashflow.CashflowList; import seedu.financialplanner.utils.Ui; import java.io.FileOutputStream; diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index ed6a14aa0d..1d49c658a9 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -3,8 +3,8 @@ import org.apache.commons.lang3.StringUtils; import seedu.financialplanner.investments.Stock; import seedu.financialplanner.investments.WatchList; -import seedu.financialplanner.list.Budget; -import seedu.financialplanner.list.Cashflow; +import seedu.financialplanner.cashflow.Budget; +import seedu.financialplanner.cashflow.Cashflow; import java.util.Scanner; import java.util.logging.Level; diff --git a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java index cbdaa2417c..77e29fae73 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java @@ -1,10 +1,10 @@ package seedu.financialplanner.visualisations; import seedu.financialplanner.exceptions.FinancialPlannerException; -import seedu.financialplanner.list.Cashflow; -import seedu.financialplanner.list.CashflowList; -import seedu.financialplanner.list.Expense; -import seedu.financialplanner.list.Income; +import seedu.financialplanner.cashflow.Cashflow; +import seedu.financialplanner.cashflow.CashflowList; +import seedu.financialplanner.cashflow.Expense; +import seedu.financialplanner.cashflow.Income; import java.util.HashMap; import java.util.Map; diff --git a/src/test/java/seedu/financialplanner/list/BudgetTest.java b/src/test/java/seedu/financialplanner/cashflow/BudgetTest.java similarity index 98% rename from src/test/java/seedu/financialplanner/list/BudgetTest.java rename to src/test/java/seedu/financialplanner/cashflow/BudgetTest.java index 215339e732..82a7959ef1 100644 --- a/src/test/java/seedu/financialplanner/list/BudgetTest.java +++ b/src/test/java/seedu/financialplanner/cashflow/BudgetTest.java @@ -1,4 +1,4 @@ -package seedu.financialplanner.list; +package seedu.financialplanner.cashflow; import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; import org.junit.jupiter.api.Order; diff --git a/src/test/java/seedu/financialplanner/list/CashflowListTest.java b/src/test/java/seedu/financialplanner/cashflow/CashflowListTest.java similarity index 93% rename from src/test/java/seedu/financialplanner/list/CashflowListTest.java rename to src/test/java/seedu/financialplanner/cashflow/CashflowListTest.java index 883423e86b..aaf5ee2bfd 100644 --- a/src/test/java/seedu/financialplanner/list/CashflowListTest.java +++ b/src/test/java/seedu/financialplanner/cashflow/CashflowListTest.java @@ -1,4 +1,4 @@ -package seedu.financialplanner.list; +package seedu.financialplanner.cashflow; import org.junit.jupiter.api.Test; import seedu.financialplanner.enumerations.CashflowCategory; @@ -66,22 +66,22 @@ void testAddIncomeAndExpense() { @Test void testDeleteIncomeAndExpense() { - testList.deleteCashflow(CashflowCategory.INCOME, 2); + testList.deleteCashflowWithCategory(CashflowCategory.INCOME, 2); assertEquals(3, testList.list.size()); double roundedBalance = Cashflow.round(Cashflow.balance, 2); assertEquals("-15.00", decimalFormat.format(roundedBalance)); - testList.delete(1); + testList.deleteCashflowWithoutCategory(1); assertEquals(2, testList.list.size()); roundedBalance = Cashflow.round(Cashflow.balance, 2); assertEquals("-30.00", decimalFormat.format(roundedBalance)); - testList.deleteCashflow(CashflowCategory.EXPENSE, 2); + testList.deleteCashflowWithCategory(CashflowCategory.EXPENSE, 2); assertEquals(1, testList.list.size()); roundedBalance = Cashflow.round(Cashflow.balance, 2); assertEquals("-10.00", decimalFormat.format(roundedBalance)); - testList.delete(1); + testList.deleteCashflowWithoutCategory(1); assertEquals(0, testList.list.size()); roundedBalance = Cashflow.round(Cashflow.balance, 2); assertEquals("0.00", decimalFormat.format(roundedBalance)); diff --git a/src/test/java/seedu/financialplanner/commands/AddCashflowCommandTest.java b/src/test/java/seedu/financialplanner/commands/AddCashflowCommandTest.java index 7946111119..cc92029939 100644 --- a/src/test/java/seedu/financialplanner/commands/AddCashflowCommandTest.java +++ b/src/test/java/seedu/financialplanner/commands/AddCashflowCommandTest.java @@ -4,7 +4,7 @@ import seedu.financialplanner.enumerations.ExpenseType; import seedu.financialplanner.enumerations.IncomeType; import seedu.financialplanner.investments.WatchList; -import seedu.financialplanner.list.CashflowList; +import seedu.financialplanner.cashflow.CashflowList; import seedu.financialplanner.utils.Parser; import seedu.financialplanner.utils.Ui; diff --git a/src/test/java/seedu/financialplanner/commands/BudgetCommandTest.java b/src/test/java/seedu/financialplanner/commands/BudgetCommandTest.java index 4185076b06..db4fd6baf5 100644 --- a/src/test/java/seedu/financialplanner/commands/BudgetCommandTest.java +++ b/src/test/java/seedu/financialplanner/commands/BudgetCommandTest.java @@ -5,8 +5,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestMethodOrder; import seedu.financialplanner.exceptions.FinancialPlannerException; -import seedu.financialplanner.list.Budget; -import seedu.financialplanner.list.Cashflow; +import seedu.financialplanner.cashflow.Budget; +import seedu.financialplanner.cashflow.Cashflow; import seedu.financialplanner.utils.Parser; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/seedu/financialplanner/storage/StorageTest.java b/src/test/java/seedu/financialplanner/storage/StorageTest.java index 0a03a418b8..8e1f0b51bb 100644 --- a/src/test/java/seedu/financialplanner/storage/StorageTest.java +++ b/src/test/java/seedu/financialplanner/storage/StorageTest.java @@ -5,9 +5,9 @@ import seedu.financialplanner.enumerations.ExpenseType; import seedu.financialplanner.enumerations.IncomeType; import seedu.financialplanner.exceptions.FinancialPlannerException; -import seedu.financialplanner.list.Expense; -import seedu.financialplanner.list.CashflowList; -import seedu.financialplanner.list.Income; +import seedu.financialplanner.cashflow.Expense; +import seedu.financialplanner.cashflow.CashflowList; +import seedu.financialplanner.cashflow.Income; import seedu.financialplanner.utils.Ui; import java.io.ByteArrayInputStream; From e73f490a7dadf73874a656daa8cb828c2a1b5b30 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sat, 28 Oct 2023 23:41:11 +0800 Subject: [PATCH 245/518] Refactor code to make it more neat --- .../financialplanner/storage/LoadData.java | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 1ba7404a6e..e0e8515067 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -96,10 +96,6 @@ private static boolean createNewFile() { return line.equalsIgnoreCase("y"); } - private static boolean hasDescription(String[] split) { - return (split.length > 4); - } - private static Cashflow getEntry(String type, String[] split) throws FinancialPlannerException, IllegalArgumentException { double value; @@ -111,11 +107,7 @@ private static Cashflow getEntry(String type, String[] split) case "I": value = Double.parseDouble(split[1].trim()); recur = Integer.parseInt(split[3].trim()); - if (hasDescription(split)) { - description = split[4].trim(); - } else { - description = null; - } + description = getDescription(split); checkValidInput(value, recur); IncomeType incomeType; try { @@ -128,11 +120,7 @@ private static Cashflow getEntry(String type, String[] split) case "E": value = Double.parseDouble(split[1].trim()); recur = Integer.parseInt(split[3].trim()); - if (hasDescription(split)) { - description = split[4].trim(); - } else { - description = null; - } + description = getDescription(split); checkValidInput(value, recur); ExpenseType expenseType; try { @@ -149,6 +137,16 @@ private static Cashflow getEntry(String type, String[] split) return entry; } + private static String getDescription(String[] split) { + String description; + if (split.length > 4) { + description = split[4].trim(); + } else { + description = null; + } + return description; + } + public static ArrayList loadWatchList() { Ui ui = Ui.getInstance(); ArrayList stocksData = new ArrayList<>(); From d7b3cf055cd0887b10ce1eea72c80c3909a8fe93 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sat, 28 Oct 2023 23:42:28 +0800 Subject: [PATCH 246/518] Add exception when description is empty --- .../financialplanner/commands/AddCashflowCommand.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index ed92f2cd1a..9b26535953 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -94,7 +94,12 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException if (rawCommand.extraArgs.containsKey("d")) { logger.log(Level.INFO, "Getting description of cashflow"); - description = rawCommand.extraArgs.get("d"); + String line = rawCommand.extraArgs.get("d"); + if (line.isBlank()) { + logger.log(Level.WARNING, "Empty description"); + throw new IllegalArgumentException("Description cannot be left empty"); + } + description = line.trim(); } rawCommand.extraArgs.remove("d"); From adf67a619a295e8354e3e1b591b7abe709b3a3ed Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sat, 28 Oct 2023 23:46:20 +0800 Subject: [PATCH 247/518] Update class diagram for Visualization --- docs/diagrams/vis/visualisationClass.puml | 43 +++++++++++++--------- docs/images/vis/visualisationClass.png | Bin 22498 -> 35536 bytes 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/docs/diagrams/vis/visualisationClass.puml b/docs/diagrams/vis/visualisationClass.puml index fef51fff02..9c0d72d997 100644 --- a/docs/diagrams/vis/visualisationClass.puml +++ b/docs/diagrams/vis/visualisationClass.puml @@ -1,36 +1,43 @@ @startuml 'https://plantuml.com/class-diagram -abstract class Command { -execute() {abstract} +skinparam classFontColor automatic + + +class "{abstract}\nCommand" #lime { ++execute() {abstract} } -class VisCommand { -String type -String chart -execute() +class VisCommand #Cyan { +-String type +-String chart ++execute() } -class RawCommand { -List args -Map extraArgs +class RawCommand #DodgerBlue { +-args: List +-extraArgs: Map +#commandName: String } -class Categorizer { -sortType() -sortExpenses() -sortIncome() +class Categorizer #AquaMarine { ++sortType(cashflowList: CashflowList, type: String) ++sortExpenses(cashflowList: CashflowList) ++sortIncome(cashflowList: CashflowList) } -class Visualizer { -displayChart() -displayPieChart() -displayBarChart() +class Visualizer #Beige { ++displayChart(chartType: String, cashFlowByCat: Map, type: String) ++ displayPieChart(cashFlowByCat: Map, type: String) ++ displayBarChart(cashFlowByCat: Map, type: String) } -Command <|-- VisCommand +"{abstract}\nCommand" <|-- VisCommand RawCommand <.. VisCommand Categorizer <.. Visualizer Visualizer <.. VisCommand +hide Circle +skinparam classAttributeIconSize 0 + @enduml \ No newline at end of file diff --git a/docs/images/vis/visualisationClass.png b/docs/images/vis/visualisationClass.png index fb2bc0bf22b185cc3fb2b3e19ff2bb2634c57e4e..49250fa031801e233d75d05a6a102ac0cfe45e72 100644 GIT binary patch literal 35536 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 JCSv&h{{XQ5&I|wm literal 22498 zcma&OcOcb$|36NOA~cK;lI$bdWu`>PCNnF0B-=5QRitDbB6~}jh3rb=SQ!}^8ONT- z-oNKj*L7d_=X2km@9&T6T&{DS^FFWjT#v`&`Fg6NBuh$6ON@tyM=Ez)S`7~me*^xh zJbnb;x%0$x82-iSd`sK;zWqa_t(mzqo~+peGe=`*Gt&zu$P1Rv&JUeLcz7P#8b5G$ zv9rB=-`>u(wTTfPkzl2v?flpKc=+%f_t*34_mqFCob=wvU;3&0H1m>~m^9@K`|!GDf>cJ{REmz?dp+^qn8W(h`%$-Vg0HAfr?>`9Cwf&?Uzhdo--L&E-_Ox$GNtI{)m=IIfH-EiXKi05$ z6ZN5NYv_pk8}g>8k4E!Gg?cW>VyM$>FzIQhxytnFNDnS0i5g!rNlR(C8_Xx1(5LF&KlncTDYg9N#fdZ4 z7vFrl$Z@<3<0u%@QSxBO#wrz+dLlL_M&p~!<5XYL$_cEx1HOWjoD;g~?Hg3;gu$cZ zoMTak=ojH4U*khJEvhk8n3UMtK?~(NdE-ss&AM99- zD9g*s8yg!(-E#2|BQEwby2yE$82-FwTIL-BM-aFFEw!p>qyarY%7B;KPG)gmtkhvhF;->dz6obIxQ z_eD!Y%~DToU{|%WE46R6;Nb>9Ta02eBWK`E-}ogFuVfn?e{WNThV$Cow6UQ2>fumh z-|wc!HeOnopB#!59h?i6UuPI_>wjita!U|Tn*qWiGAw{Ty=HLKS{fLA5kb$04`=omBPq6Ntn$LB zysp#>CCKUFj22p0qo0+WndWtp^V;wcuRKx}XfpWeBfXfriZ0X3$jGzw^nQB`eyx}1 zYHn-WSYJ1&bYJd%qeVhY?7A>8y|7Si-a>0dbB#J?)FyEj`DM7@{)HJqx+XAP_)+C?p903!~itV;D zK0ZDQC`7r_q>_Qb&_KD9TnnO=qWQLhf`Xh}%F3g7Vf%O5g^xQBO4Eh+8-~gp{K+UK zBqY30$4ICyv9eM{@%rxXP9}Ojug|H?R!y_iiMf2wBofh@?DYIOy{JLi!@BfJ=@i1> zXZJBiuk=CHd~?O)iUXBN@=ImhS^R-zyEj+VNIQsgZhG&m+gV9Jt#DiXk*gV+kwHvG zOx)Dcf{8RRFc90{noKHQT^Ov`LOAO)i59P}&Gu|mBfaDv{%j3dkMXrMFqAa33T$m{-B=imlsO7JbBc~m)V8<4 zb-v$WMV@jXTa}sU#PjFR5lRi@B3B9o5{Q>{W_t45@(WcS$7CG|3=BlHup;AHg?9J$ zw)Eu{D6EaZ{_$=yYfBVqrSE>Mv_S{UJ@i#f;_3Ogl!El!nC5=l-qRCvk8ossax(v3 z1u7$k$8cd}*k~^R~r;j9M7=I2L=y86ObFV^3 zL18vZ2^AF;5D?H#yoAVLAr`#y=Ug)~GDo;)#{o@j~p-NM8mys_hQ#i*>YFZH3+ zTbF{ny!LmIsG(AO#-u%F$V zZth@kT|~}C(0ki?rWH39_O9B$?9-4{UA?vJ;ue!2VUgkK>=J z#6SK%vjf=7BH34jWON!SZfayS%a>YM?xwSF>wQRH@HI9zR#IvmZ;UiVVkip(E*~Df z`#-St_4R48FZRa@>QI%2J}Xb>m7kxJ$GG^^?1H@z9616TqJQsRT3XuHo{$K^p=s!# z4hgw0|o{Ms^}4LWFDR>fwXaOp#x!y?0VmQ$I0#w8o0A%+tR) zSWM$KT@PclQ}nf0oU1HLJT1;q`te;o-O)oA)WvPjSus2DtIogJyk+KRX?{&jO?*7v zUWULe_RBSCnVE-kR4hjk%^dy&0b1+K;TMgza&O`EFcpNj%>Jmu zS(tyd7mFXx8591`@JXv(9r6EoTHPKt8h-8y<6C|ht`momso>8~%aEXb zcb6MXzWE%E1pc!p-!LhQzL|+b?^xx=kY|ai%E5 zTu$=Bo={MK%*xo@Lv=XqC`66J*w>FPvmzoQgvXA}|15oR>~GHxyXLVz_bMTwWz_T` zXXkInpCM7<44w|>5+m-YOG)`vRP6K^`YP6|sjD;kY>u!h#@&g%G6MTvdB@Ak3${VG z#FE#pza%yFBGvBFXYvY{*{|qRDJdynz)>;+#|{rB3p#RCZWWFZosjL)(vnf#|MKo~ zEom}gA0c#rHTGW04`x0(?Ot%dflQ*@YYWSJ|7&bh2-3qNQN$(0I*nQ0*;#-q9ECzf zMBG4EAy+0sD7n~MM$fV-QS1k%r(YtLXO8>5IuV$ho=WR(PNv>+CyNM#f?Vy`*n%zgSjwb>@4q(cbpjR>m3mt0E#r0?`Nr!qiHru~S|uZg6lg zfu2rc^A~~cDIQd0+zS61_6fCz=H}*> zmQ(3+k=p4vca2T|)&Jh6xWwq80z$btPH?u*A}Qm`lhe!*k&!y#A(+X@;?=F{9y1SOISPY$B!TXvAE*m;yrKmWcNnF|8~FC zi#Z0-nR9PV)8iFp;~M(oF8Hm{1_BuSmjdI@7nzwGp3|e5H4s;>EPV+0Z4QmNps>2UoTHvaR?!!P zJIR^t1h>(ikXu-O8WQG2aK?H<6Ym2WVZ`fO^-(q}D*ivH}` zPRNFGk+qNTof&FJBiWQ8nP5svNS4!;vyxW-liXHHs3cW^qv&|j=kG_nv$2>}T_bRV ze(Pp1ncSbvQWVtPhs3Gt?28vKVhFjck&j!iJ!cSa>WEs}*zmn#sCW3N92s;)Sy@0} zASDIGZU4L45?owde0&iZ98BK5@nW1Atoid zjfvsb`;n;_567#s|3QDr)B2Wom1->JBzh9<7Y-eiJSso;G=4NfnFYN4!f;JeQj&6< z1QMH`llL$%h#(#7tPfe~9V;u2NWswfd&ms=W~vWfe})r)!5h&JFbA#TKK3SLYW;J)4+fus|DaEIt5l|%Ng zhmWE%O&~$i`83zWrJ1VH`^k^c_;(djnG+&&l%gm-Ty1B4es*L8+#c!guW+KH^Ir-?#`VFPppz;|yhKGoV zh&o1UZOPD(OW=HR1m-`l6MeHWXGLU0&2iY|&|x_pc(9JmBV-c);0ELv(Dg^EE17lp$tHyLnQ;#i;^|p z+=cp~xx0HU!EH$H_HE07vceLf$WM<{P%rj0RR6M%zSB{h{CA`LKb0vtI5=Ed`1I*h zSC@uFQE<~^ndj$UMMmB%Za;0=9LtMDB0Kt{2m^||=CVTma?UN!lT8P;RmF^5_1Tn_ zm8VZBos2$KsFnVm1}}rhu)28+ks@#*3Ugmllj2W2vv)n3(e#WGlYHgfSshYAgS69auUruTlT`0E7z)wLi?&PHYm8KLkvum2?v9qAt62(0~2a$H+8$#xp z-yU)7l_J;w{8f6X#*c-m&8U&c@nxo)K@bwQx3-oUZ*%K}_my<~kL61+{(Ho6v?j>N z`oE`Y{T#!6{;x5pJ0bE<|C?)wg9!R$=m@3p_taZ|g8_Ved>`z7vgVR#%RG4Sz|pa2 zGl3Hi96)X`q;Hq?%dULSzVnLj)=3)w^z?KV1yuNKJ&y)HtSp{%Ym($a@BJ5pHNJ+; z1yZoPc&BK@+#kNV`xa5dX<~|d!~GG&csDmUa&mI0h8JrN44OX({{A0N&$4}tKFz?8 z`0^!_`A=FHDc)|YvgBS@rXrm=at19cBNM`6ON#p?9}5`q_y${|`{Qy6cJ`^X7ZPVk z`X~;+q6F~*3ZJT~D!@YIQa6^DY52{bX@ASaW#PYkaT!pTukT!8!*fPSr4uvtlGty| zkhxZRtmSHVx&Ho;*w%O?0|P_4yL=>On&)Yv$11;h^Qq8&vcq3!+S}Qvs;rD1J=lrI zJiXuWTy?-TDf}_+@mfPZJ9h6j59ATbDz6>4((Q1$WNp5Fg{z_n$NODhvvQ%M;0*E1 zPa*6pa3{kksC39f;bb2x?#aFU|L@mWd^fctc#p*Wvr_T!Y7=qJ`@g@|B}4&mWQ#*T z@aAa#uh-^Bq8zv<)v2q(pxO?H_FrFrDapfQg>c{z-ulV^>(#s#Hv*%!UpedmWLe-g z`oF(EWMhHH(&5ma{|$3lqF*x0QX#YpPFdbDF&WjfuQKC%6|l$%AGW-G_wElkvv;mj zJ32W+7`qo>AU>F;X!|27w-CA|5O&pVE#j8VSrE$JPG>gOofaDt z9<1MF$=U6qQLhiNK4bq0`=Q=`{0njsC}TS{Nk0uXvN0t2;~$v1<8q7 z8NuT&L)G3DkoEvXabtI=$`eLb<1&l#_xBIiq;a>?)Uzx9R*FE_Tju?|iN{V|P9pH> zqmY>Q#OksGPb1|)tRWkb({UE7p;r$4_410DfJ$X#W)jyy#aq4Fp>U%Bdv%J-?YS5F z6E^7UM{#MAsofY6*+Pdx)v7eFT`vHty!O02*A^%l8I_l5JzZ@pzTHbc{p0<}6NA(L z0?u0hBX9=DiFQt-Gp32s-rnBIDWfDme=(4R`py|1dkAWf*a9FUB_#!k!+oi`elP4? zUoim@nX{W)KBSD`lEAG796>DCeEx2~x;UJK>0s!}(#4hc1*= zbf>)t-ye;sYGr;k>H1+~;a6Wqu}Z|m+Va|IF7C1N$;6*UW+X`iP%L*UOSW{}X*kM} zC~c^(UupcA5WF#yR_yA^ie8avBP7sREOw$bL4p24%A+gy0epj$yU&4zo12@3B_lcc z7oaj+ck_}3lFYiYRW&A|+Dc#1ef-z5rxT|HN$hn`@B7{B@+FEd#fH7ByO)z?_}O0b z1Jmy#^AIYZ(gdWIrMYkR3Q@-}s`C|=irvf7AXh4{Aktjjk;U33kBw|`xq%I(a!*b63eH(%vHRrS~E<*;1_?CrXo??14&!j9po;hF<*H|!3pQ{N@L zx0kN=EdO|`$1y)YPftzV@Uu7sL;g=xt`T#YTTYh3*Vos_EK@a2hV0CFdipH{*6=B} zbhQ~Jchbw3I0RC-&cFTielVlYsTxF!duOhAdhQdXU=W32iiH~CN&4HOLE5LUFxWTg zAD+qVAyw=w_8m7P>)xKAcXj3b3C6fmt;HdejG98XMFT!QmZ`;^#hSJ;HF|X|5q^Gt z0Eqzc!RmJiBI_6M8JS%@CG^`Z9&Zu`^UW28h2#D*>E=S)v?=8zX=8 z`}+W~y9^8re0@%@&~gu&$sJpD(G;aP7K8 zyE~ZAO1kcDbvw*giC!(gS}3#m8#J5bcH!sx!l2&6%fnP%9*sR+h*y0& z;e!S`fb#>^X**Q;iaL|O2M|Q{$TXe1`3BtI64-*s=sE3H5VyHb{Vryysbla72=&Vy zZ^iZykLyvPN)I!X-KLVdkK*arJMlE?uPk80#5MQ4`c{oZGnLLJls=~uelE?!p~gFP zd}MxJk;q7-kCUAp;F2sre&PgezBm%z+!mjDI&h5E*oBVO6W~S7)wq$&vwHqFd}x z6@wpL-hiyQCT;U%*t8J z=6mX~mIyeB2MnuH3rE7T@6cu1iCFeBa;@$h{2IAwy}5XR<<>JsFAi0ddP=RccTJ4A@@BYvhZKXHP;xigpNc2K9!}4GKPtdVz^@%PT8qxx7!64+1nM z%W7s-tQ;q{)}=nKBcGm`iQ^l*ui4k^txtVVoTH+0ooJ@fC9>MO6-rgL-fyFkNJid) zE)!vfaH5e(N=;4O`ITPGYbo>W&j2CT16zs0y~fkZYFo5EJo#SeyS3QW!K&SvH$GBz z#XWf}#a!MKZ|^ZuoVi%l*0o>YiI(ixJ{^`QH*$Mk#zzc^y|nh8P3bi|2Uc=3k`*XN zp6boioVn$CIAR6yBZwSZugsiaYzO0VnJ@oHH7TZNi`q!Bn$TS~M1ykZq#dglC@-HDlcEb6PI@6L{% z#@Fii_nE*Zb1=U2C1&H_vQs|)@O{ZGT(OkG=X;*_({u7%S9@f!_ZA!~6FEZzVk`5rVfOo3$YfIG`-(Cf*DUJM>|WNA$wI$$%%kuL{#*5R>1| z&w(!oxZE<^#+#h(lf(wc53gAZBooonRRF{tjG|LVPIQ& ztm&CbuPsMNE+h|jorH2$)8)YEt31|vdm^HuG$6elA2&rsM@Dw0+$187xCy8!ctJ(_ z1IW}02L3_eOk2k)#*@l-%D>^<_4kS(?(~&Dd+bKn zTVG%Me3>HF`Vl5N(fj@QD+-b%@93X)kY|Z|tQwK$vWr{Y_>n2#*-f$M;=V-P3KZN- zf5pd-Y8Aw!q|s#ia@`O_-h=lGqZ4M3@VdGq)t!FffmOe)O59yt%@M{Zr4HkuR=n&z z9)n8leeo%O@Vu(`?8?5v$-?OEXVBzVU$IEkAD$bdIe)$@%f2`Arp>_!`5Wb=m(=cS zVOyUXcObC+EVWm*=mc<=gOf9LK~F^`+zXF7tRr8 zg+|$LHKe8Pf3PXlA70h*Sn6r*+C27@ztd;_Q|0E@Bgj_=r4~u6!B<5TAYdj(+AuJY zF-qK->_>P{cVw_7c@+UhO)j~+w7EPs{RLGI1$?>h`R@W_#w1MUpql!`InW znJ5K_X_4>dI)Zgr*2>6^cQ0W#Ev0PWvB#Z_A*6usuEvOadv_}DZ%;+;@;jRdGzS)J|Sk&xI2$X>%qS64S)$WFV3BFo8+ zZxdK!D+7^}6x7tiRh}`NuOa>b^)IR&Q(0ogDeHLB%E*;MNPP%%X~? zeHlxh8w)ttUG4+aAy6|eR_|O6?a5J}Y>MW>Q2lb@`?dzCzVS4aD!`=|3DA>gXZfy7 zC`L%sNZjZ2R8^htf4_B8Snvy$70|;PToTqj6l6ntxRBA?Schqw^bm{6@TDM?J5z^T zlwrWjvFT|!Zwm>zd!9hrs`ue>!9(uX0r#>L{EY(${QGK7<;N^jR+Yt9n)!Wq#~3|V zr=*C;g*ba56afG8&2apnp4zZLD@SF~U^|W1Wm42_p_$F*IfmxkM)y9>L{D}E*^vDn z#5*+6#=NYq@BLX

k~GS%GQF4n=lW{TTc9GK;;*Qsw$@Ih$wVkSK3EZ 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 cia*j Date: Sat, 28 Oct 2023 23:55:29 +0800 Subject: [PATCH 248/518] Update visualization sequence diagram --- docs/diagrams/vis/visualisationSequence.puml | 6 +++--- docs/images/vis/visualisationSequence.png | Bin 14494 -> 13640 bytes 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/diagrams/vis/visualisationSequence.puml b/docs/diagrams/vis/visualisationSequence.puml index 5feb4c811a..82bcd9fb5a 100644 --- a/docs/diagrams/vis/visualisationSequence.puml +++ b/docs/diagrams/vis/visualisationSequence.puml @@ -6,11 +6,11 @@ participant "<>\nCashFlowList" participant "<>\nCategorizer" participant "<>\nVisualizer" -":VisCommand"-> "<>\nUi": Ui.getInstance() +":VisCommand"-> "<>\nUi": getInstance() -":VisCommand"-> "<>\nCashFlowList": CashFlowList.getInstance() +":VisCommand"-> "<>\nCashFlowList": getInstance() -":VisCommand"-> "<>\nUi": ui.printDisplayChart(type) +":VisCommand"-> "<>\nUi": printDisplayChart(type) ref over "<>\nCategorizer", ":VisCommand" : sort cashflow entries diff --git a/docs/images/vis/visualisationSequence.png b/docs/images/vis/visualisationSequence.png index 0fef5ff23df2d0a452686a564947c04676c3576f..8a1ea01be4288d78b2b80f4ae2417fa81e911f85 100644 GIT binary patch literal 13640 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 DvkOl5 literal 14494 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 Oq$L!@KRkHi{l5TaR7^Mk From 31aa915c5fa6ab37989c7c0867fa950650d503af Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 29 Oct 2023 00:53:19 +0800 Subject: [PATCH 249/518] Fix typo in ListCommand --- .../java/seedu/financialplanner/commands/ListCommand.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/ListCommand.java b/src/main/java/seedu/financialplanner/commands/ListCommand.java index 0395360ff7..c2b387f651 100644 --- a/src/main/java/seedu/financialplanner/commands/ListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/ListCommand.java @@ -57,11 +57,11 @@ public void execute() throws Exception { } if (cashflowToBePrinted.isEmpty()) { - ui.showMessage("No matching cash flow"); + ui.showMessage("No matching cashflow"); return; } - ui.showMessage(String.format("You have %d matching cash flow:", cashflowToBePrinted.size())); + ui.showMessage(String.format("You have %d matching cashflow:", cashflowToBePrinted.size())); for (int i = 0; i < cashflowToBePrinted.size(); i += 1) { ui.showMessage((i + 1) + ": " + cashflowToBePrinted.get(i)); } From bd6c3572b63fbcd3ad2a9e3abe7cb870c9c6990f Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 29 Oct 2023 01:00:36 +0800 Subject: [PATCH 250/518] Add date to cashflow with recurrence --- .../financialplanner/cashflow/Cashflow.java | 21 +++++++++- .../financialplanner/cashflow/Expense.java | 8 ++++ .../financialplanner/cashflow/Income.java | 8 ++++ .../financialplanner/storage/LoadData.java | 42 +++++++++++++++---- 4 files changed, 70 insertions(+), 9 deletions(-) diff --git a/src/main/java/seedu/financialplanner/cashflow/Cashflow.java b/src/main/java/seedu/financialplanner/cashflow/Cashflow.java index c9ca8c6f81..0d3ae1c04e 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Cashflow.java +++ b/src/main/java/seedu/financialplanner/cashflow/Cashflow.java @@ -6,6 +6,8 @@ import java.math.BigDecimal; import java.math.RoundingMode; import java.text.DecimalFormat; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; public abstract class Cashflow { @@ -13,11 +15,21 @@ public abstract class Cashflow { protected double amount; protected int recur; protected String description; + protected LocalDate date; public Cashflow(double amount, int recur, String description) { this.amount = amount; this.recur = recur; this.description = description; + if (recur != 0) { + this.date = LocalDate.now(); + } + } + public Cashflow(double amount, int recur, String description, LocalDate date) { + this.amount = amount; + this.recur = recur; + this.description = description; + this.date = date; } public static void clearBalance() { @@ -59,6 +71,7 @@ public String toString() { if (recur != 0) { string += System.lineSeparator() + " Recurring every: " + recur + " days"; + string += ", starting from: " + date.format(DateTimeFormatter.ofPattern("MMM dd yyyy")); } if (description != null) { string += System.lineSeparator() + " Description: " + description; @@ -81,8 +94,12 @@ public static double getBalance() { } public String formatString() { - String string = " | " + this.recur; - + String string; + if (recur == 0) { + string = " | 0"; + } else { + string = " | " + this.recur + " | " + date.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")); + } if (description != null) { string += " | " + this.description; } diff --git a/src/main/java/seedu/financialplanner/cashflow/Expense.java b/src/main/java/seedu/financialplanner/cashflow/Expense.java index 39310b21d4..0408595860 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Expense.java +++ b/src/main/java/seedu/financialplanner/cashflow/Expense.java @@ -3,6 +3,8 @@ import seedu.financialplanner.enumerations.ExpenseType; import seedu.financialplanner.enumerations.IncomeType; +import java.time.LocalDate; + public class Expense extends Cashflow { protected ExpenseType type; @@ -12,6 +14,12 @@ public Expense(double amount, ExpenseType type, int recur, String description) { addExpenseValue(); } + public Expense(double amount, ExpenseType type, int recur, String description, LocalDate date) { + super(amount, recur, description, date); + this.type = type; + addExpenseValue(); + } + @Override public ExpenseType getExpenseType() { return type; diff --git a/src/main/java/seedu/financialplanner/cashflow/Income.java b/src/main/java/seedu/financialplanner/cashflow/Income.java index 0af604eefd..5c151c9f9c 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Income.java +++ b/src/main/java/seedu/financialplanner/cashflow/Income.java @@ -3,6 +3,8 @@ import seedu.financialplanner.enumerations.ExpenseType; import seedu.financialplanner.enumerations.IncomeType; +import java.time.LocalDate; + public class Income extends Cashflow{ protected IncomeType type; @@ -12,6 +14,12 @@ public Income(double amount, IncomeType type, int recur, String description) { addIncomeValue(); } + public Income(double amount, IncomeType type, int recur, String description, LocalDate date) { + super(amount, recur, description, date); + this.type = type; + addIncomeValue(); + } + @Override public IncomeType getIncomeType() { return type; diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index e0e8515067..30f4ed9a6e 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -16,6 +16,8 @@ import java.io.FileReader; import java.io.IOException; import java.io.ObjectInputStream; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Scanner; @@ -100,6 +102,8 @@ private static Cashflow getEntry(String type, String[] split) throws FinancialPlannerException, IllegalArgumentException { double value; int recur; + int index; + LocalDate date; Cashflow entry; String description; @@ -107,7 +111,9 @@ private static Cashflow getEntry(String type, String[] split) case "I": value = Double.parseDouble(split[1].trim()); recur = Integer.parseInt(split[3].trim()); - description = getDescription(split); + date = getDate(split, recur); + index = getIndex(recur); + description = getDescription(split, index); checkValidInput(value, recur); IncomeType incomeType; try { @@ -115,12 +121,14 @@ private static Cashflow getEntry(String type, String[] split) } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Invalid income type"); } - entry = new Income(value, incomeType, recur, description); + entry = new Income(value, incomeType, recur, description, date); break; case "E": value = Double.parseDouble(split[1].trim()); recur = Integer.parseInt(split[3].trim()); - description = getDescription(split); + date = getDate(split, recur); + index = getIndex(recur); + description = getDescription(split, index); checkValidInput(value, recur); ExpenseType expenseType; try { @@ -128,7 +136,7 @@ private static Cashflow getEntry(String type, String[] split) } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Invalid expense type"); } - entry = new Expense(value, expenseType, recur, description); + entry = new Expense(value, expenseType, recur, description, date); break; default: throw new FinancialPlannerException("Error loading file"); @@ -137,10 +145,30 @@ private static Cashflow getEntry(String type, String[] split) return entry; } - private static String getDescription(String[] split) { + private static LocalDate getDate(String[] split, int recur) { + LocalDate date; + if (recur != 0) { + date = LocalDate.parse(split[4].trim(), DateTimeFormatter.ofPattern("dd/MM/yyyy")); + } else { + date = null; + } + return date; + } + + private static int getIndex(int recur) { + int index; + if (recur == 0) { + index = 4; + } else { + index = 5; + } + return index; + } + + private static String getDescription(String[] split, int index) { String description; - if (split.length > 4) { - description = split[4].trim(); + if (split.length > index) { + description = split[index].trim(); } else { description = null; } From 19d3b69db5bc5063bfde4d6be606912953666e50 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 29 Oct 2023 01:12:45 +0800 Subject: [PATCH 251/518] Fix class diagram for visualization --- docs/diagrams/vis/visualisationClass.puml | 12 ++++++------ docs/images/vis/visualisationClass.png | Bin 35536 -> 34745 bytes 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/diagrams/vis/visualisationClass.puml b/docs/diagrams/vis/visualisationClass.puml index 9c0d72d997..56f2470921 100644 --- a/docs/diagrams/vis/visualisationClass.puml +++ b/docs/diagrams/vis/visualisationClass.puml @@ -21,15 +21,15 @@ class RawCommand #DodgerBlue { } class Categorizer #AquaMarine { -+sortType(cashflowList: CashflowList, type: String) -+sortExpenses(cashflowList: CashflowList) -+sortIncome(cashflowList: CashflowList) ++sortType(cashflowList: CashflowList, type: String) ++sortExpenses(cashflowList: CashflowList) ++sortIncome(cashflowList: CashflowList) } class Visualizer #Beige { -+displayChart(chartType: String, cashFlowByCat: Map, type: String) -+ displayPieChart(cashFlowByCat: Map, type: String) -+ displayBarChart(cashFlowByCat: Map, type: String) ++displayChart(chartType: String, cashFlowByCat: Map, type: String) ++ displayPieChart(cashFlowByCat: Map, type: String) ++ displayBarChart(cashFlowByCat: Map, type: String) } "{abstract}\nCommand" <|-- VisCommand diff --git a/docs/images/vis/visualisationClass.png b/docs/images/vis/visualisationClass.png index 49250fa031801e233d75d05a6a102ac0cfe45e72..e0776d071bea24247d870fdd2dabcc05bbd0d435 100644 GIT binary patch literal 34745 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 literal 35536 zcmbrm1z1$?*Dj2TARr)0x3r|v-67pwN;eEhmx9tEQqtWB(nAc0$j~93Lk%@_H=K?7 zi}(M%=ljn4o$KO~?abaYPpoyXd);e2gsLdXV4@SFBOxJS%D$9TLqfVIj)Zil;=x_u zm2Y`55a1W%8!4SPrjAaYcIFmukYvmq%$;AqF*l<$@uakR^Tx@ApN-AQ?zO`kS9?2F zQ%8HZ{%#5+q`Umq8ai+OdL8Kw@Hrl-TbhcFQ=*R`JLQBQB*fZ%K69eJr}{>t`kwU1Y6*0quU!%Ab;;W~d^4Xy(Ns^%| zC8&HcpCapp66Ny|LJkW*^dw4OadNQMkQbvG@$(u+X(k`24tYS8rO$J%97kinm&)xg zy5}EeJ`Vld#&OZhGo#E>K9>2?j1Bcr?XwUHBMhJRX=?qbc+jglG!gPkye_sFyoV>J zZ_EgbDB)g&dAjDPu2v1taiGU;%!$1VBx=t)@2M*spSbe=V7iV%FhQFdTUg{gtvm~> zPy4tuP+HVdsc7Mb$3yZt)rKEeilZ%#2#X3zofAddi_&>qDa&xyLYk&%42T_IVmGn= zOtJ{?n*GhnfoIYJ%Mz^L1J^_elLNmbPU`n58pYv`JzZ*{gDxZ_4+wdepfY^62-xWo z4kOLJM*76>?Y-~iPg=mKRmw>Lk2=?P3CC&o{W0~mmm*5Sq0pcY z>|CxN4U+|WZh$fgtGEW;SKe^dDicDMk}r77MHc+nMs(ouAUxkXZ*mY zoau|jQnz9BMu6<|95ZG3xXzIU_njQIEf>miH?ELOC=@IWR?fql1pDQn5l3%h5jfF~ zi!%|qSWkNJu{>t&Ps{qMp&E;;qcj;JVnVDde#%H0Z2jp|?M1u!lepJmPh(uV1f_m> z$qzWSUEh5#lMnCr|E7S1^cG20QcT0cXfqAf19$WsI*@PYwG)po_xL5!ySEIKnQzJ{ zDbYi4@t&cLB8xvRu6`u?3|)soTT}z?D1(fQBPnLhs59S<*B%rXVia@b-$>7wsz5FJ zAhz#9xP^Wo$+1~|rT6Qqxdld**dyfIA3PNWqPLU}0)QXJfLBX@u5$k;SH;Zypq0ey zgZ+m7K1AvbArg{P1KjdBO=w|@Oh2BD2v6)Q=n=9e{!vB-&-KZyXRQPhQs%2o+krCu zI;FGX*Iunqu}2!ZBU~ctS5ufsNIx{D7l=447>v0T*d};^afS1*isbukp&%hC`S~^P zYqlK*Lw z1#W-9UjAwc2?^yJ@MXwJ+FwCRz0?SXLd;d<}|mFd~n^ zeC%Durn1W5bo8}2&>X{5feg7H`LD0jeoE-?pe!l(1xs0p@Sv@BQ{?#A+dawO?uQUt zua;%^H`8|;sDF*8?jq^DErO~Cf4CQk?sBkSIL2=e z-%}J+Lc3R6z8m_WXs8lrPUBFjc(guGEIJJTZP&ZMrp}1`x(iK0*jtyV<;_O|DiRtu z15VKQv*@b+O$Q;Nz$Sudm+1EOT4(73+WJZVO|p}NsImctJoaey`h|IK=v8%K(<@0E zd)4K#%Ze>@@)VU*G|*~l#S!Y8C-(V=TME9B=MGib;es88Z6BvJIiet@gE`svUpfD> zq+X^8F#5a3y4BMvilQYOy6gIAUFIfc@6ylJaiw$a;eEReTvCEp8+9J_Hwl(fcm>R#Q(~xcr1ScVS@bf|+N#IAE)9=zbanznsOxOcc`Ru*JFFyFQxGLDptIopCWg0E zl`{dbG#(A34GWWel0vl3nz0~<2>T;mb8H04+h-eO<=*OLD?GQ#) z%vgAE@nWO=p`AfNJD)X?@3Ntn(08aN^FNC%wz6*cw5GT=C6VvA;{@2`?Pjlh?U(c4 z(n`)?^Y2d`m@LhVCoXnj1k2ISJWemLgqmU+E0pA&rv=krT+fhC*$D|r=!n`BuNR^+ zC|R)P%L=L19jMpu%aBs3+3bPyBXd+|xv#Tk{INP4553+;mgxL5rw=h5JfmB)tpd!Q zvmH!jo`Ki;8BZEf?2K^|Qs=j~WXYrKl6Gb7Eu$*Wz102Em$FvvbpyLDRdclxwM>;9 z@J96&e10(TQhwD_NHmW%{IV_h@~ke3WFFW{B6x<6qc^BSX&6d-WY;0ro%vtaQ}j77 z-FAAlJM(`JC!VxrZFjrG(!zKm#nVfBSQUGQ|5(fwtFZTX8?d&yZ8SEQ2%_&1TWIt zJAauwDbhEjTUew#K>rv1jS|fP2sn5L_!odZ8&~Ko@Qm>P`!oM@%=~*uCC*i#=uQ1{ ztbmO>>dD#-vJ8s-kxVD8@&zkR=qTuaqLPffd?{M=qoE632q^>S*E1O_Q*b^^JF zJH*+2R3|<}Almu%1&}d;@;T!xr6%5-K!KQ0O8T2z%8lf|l3y>`5hnQi7Yp zbA`{fOT3-LFUizp;6{Sq+=(JuPmwSSLE~TEq?Ih0WBlGRO$TlzmoGyP6VO!aXoU9H z7d!^)sveUdS|^A%p)w!{m6&*>3j^UJ6D3dYi<4=vwFsG6+gKa z)@@;v@;^KEh4D4=H+9)X(@wXns<{us>}+AtLBnUT>~mQSR{wlgB1W{yuxvwO@LEv@%trDOI)4S|N)TmtR)$Ctx=)l2{t+8R>rX-V+@-y5EYnC+MMlJ>hmg zT9M)MJ=mpx;{0AiXu~sKf#G6qL}MQ!pL4oE^UKb(a(G`^PeJbS4S_O-e6g6VNR9Lg zB})#Q^4jk}R!tav;VCn2nXi`AF+6lposmI1^_0ow&hsmzWl5 zle1o4C`4G~4_~XN{O-BD!l~aNo4SG z{#~MEJwrX(6C0Ujl)#4ASe0sO>P4>{HEmS@zxl2=We{Lu`gG(NbuEI=S+d1FAjvE)6!CM7Eacp(t$o81oS%GOm(S!|$n4W;o`j>VGR?dt zW1?2G39arOZuIa3LciXXkH;j(pfY*ZTJqvP8BSRE&+b9SX)4PHNoaar?Jqf_W2l@l zsC3C&7;Kdukm2&&d0JC4ly%l2t-=Sk!1HsFcaT{L`#rxUDUSRo48}H^kkrbCZx1`K zR*`hu#)dgM*&4w0wM-1>C$!PA>zBis0X~(IsZC&yetCl08Qgk>0ZRXvIe@HH$j?Tt z&=r`&RQf!~e<4y*p7jzkLfcL6?nP5Q4G<9XsW0|If?LXUzFOl{g27f}nml<#xvquR zf$r*A4m((B_^Tn+d#lI0>|ZRai}%=B>h_%(GMCjKcBQXu^v%6x8+JX51Hw3~JUu4t z>U-x>3OuGTT6ISU4rZ`b?#v4`dist!s<{<{aph|@px3hIQfb@sjRb3TZJ>2hMn2z;@tlbj*>7+^h}y5fFBfEt2mrftBK;ji5yf_- zXIbPMD?|QkJF~BDdMUBp{1~X{e_o<8LV0f7>>NgEud4c#+o@`qMdtaT#*FB2ppBtZZFrur{fj5ddUm&=-Wb*j( z(AkxD(2F$V8%QpeF5r3%<>~8qj~QT9ngGPaxLg7Lr;+G$kb}xIs2Y8}lTceFeQ~lO!(m$yR zdo2hZW$T=W<(So>ObR2A`ZK^>^*bMNz=9MD)tPlm(ADxK{a;k8jhN?;B_dwL+rhrOjMZ+_mBds4;0(q(TG zC6}%iQ)B_;JFedDyI2_6z2Fs0c>Hu1otRRBD%{}ae*R>*(9PnVbCG*Vrj^A2lkSr~ zAs8^jR7#i_34g*uC%lM9`bdW*zo)Wm1ROH#s&v3SuGS`UXafR0m6*F2r9VU|NBvD9 zTs67Nd^&lLl>lJlbFRS{_=c_3&RJ9tb+2GGA=tY(5WVc?ZewV~)t>L(YbUA(&}?g? zu}VSw(?4)F`706NB0Cc8X?jcnZVb}ormCqu%{Nx@eAJShDWhxnYB|*SjmOC-2M~(- z1R>!l{u>jho~dQKg+ZrysF=T#Vht~n4$23`$ZD5u!M`&(IY%Iijeqq2WPtxWHW!}~ z>1{UW<@)IJqtqfng@8X9>@7#SBvnuE4>lUrRCw8<*ke;|TNY(Z;w9s|!*p!?Eacw| zEs34-U#ao&j^=iKvuGN?-%w1`Wq;8x*eG8-^6ya<&)B6l*$|g!TF@a9X!ZmijYq=- zC;anXwFLm_0wFvu$hJg3S#N1zEA(a2=t38osozAxRR_#(hxH&j61@6h64A?)J)Y)C z_pYBe&D~Xr_RjD42Uuqq?Z-Jv(7|DdtUS?I-}~4@;sD5pIBI-ONtCG>v%by8T%UE& zQ{~F_NGp75&=uSAuh~9Wd2F*MV}R@3C5xTo0$V61B62ASWBg)*&^ z!5;_+kFfP1C56q)t>S%^qZK)q^m~grr;gLuKzhY~_S}l#Cfgt4i4Qs|JoM5YWIy>i zHaxW4c`qfggIj*toIVAa3J4Bjjn`is-rqDdWs9}vUosux;rs(tH!M9f;iz6^Y!8$| zR$CkQJGw;zjQmA;RC)3oSJ75Q$d6_%q}0PK?#B_$GVrbXXGDtB1^W=*)F{ef0St+W zlS@k817O!!@7i;e@lNDdE>={Ku9%50s7|NI=Utg9S>c35`-P)6kIW!?n z>MH@$z=Z>Ych^fD_ONnf{FqfVny2Yp?xx}JywDrS|8ciE2?s)rScu#m2lgyQ)H+6a zJ7@%(PNen>H0|d(OBlGB%8~+q`zxnC>G0$B9dCOayzd*Mc1agj+fo-P3HzjuCylziKZ;Bp*%Vl!Nax2GJr5-2gIw5OAQBr=Zo&~NFwB7|3lU3=Rq4Oa@YAts+z)A-@Qv+9^MybJJ0)PsG5_!?5sj#eSK%%HxQCd zitQyaXT$x*et_ayj~(rvka>Af8wZXuF<6d-o|vTMuNVo6st7DnWBuVFg2T5wM4s!X zwX8!*2f!}uYtz%83cgQg8T{?TKO;Y(`d3R=`*g%D0I4;g{7jqL`*}dJc}DNk|8Upm z3k-mxQK{LI+|G@UwcG1p#%+Z`yF|d>*uT*;sn_J`lTrs6sE5XW(hxNe2tMj*7ByCg zG-tS4xC0RkB7PTj+o11+e~xC*GupvGd-eg3OH;21V+;T#o?wK1O6W0D*}J8GQsmZ5 z!<&4~$@ab)t9EB(mm5B(4e*`xcYf(&*Ig&I1E;lXx+x}SxgW+58(Z5;?e0bKtEb;% znjJ;@4lbIG;!eNgIHLg)sU(18pnDPL5Ek3#^{6(rzxAWhO>H{_rco76AN*D_wB6?Y z$<7!0!+ZP9LAC$cm(#Vjw_8l#KRua&2o>>TPJ`VcS=}Jju@p;o<+y{v^cs!)7KQWo zGJ7KlA7}Dc3UMvvA|zV@ij6qlo+rbXOak?hbSkxX(Y?z&P`cW$B)>GR1)PB$3^Dc< zuQvYqM{+IehR)*lR*_;|zS2~P^+NDEd1aG~lQmu3cWq+-Tb(w<15&?so~r=4yJ>s3 zkv}+$<`(T4!+}6ACmbI@xz><-O>d#}M^_n|=0y^vMgB`z{y!1A{~OW98Hpn!SQd=+ zk65#~%68CusOfaY%~JBSte)S`evJ$O?+O3qXAP>AVoKJ7B_#x_og9v$fUpQCj#o=m zvrU^V@;_aC-|-i4u3Ql zH}M6S7|u6*uK@X{?2Ci74G^K|sq(af>FFcRUh5xIcwayodqubx(+Mm}ILbqe+*gv2 z`Ip`R1Vi-6??Bi+0ezOB;3v`EH%v{(Vh#{|!Iu~=KyJ{i`Wg`KNA(IK1)F6@@<=m6 zJ~Fb9ypVOS(pbBEWAtj2FgzT?c*WCaG2=q*+!b`PhhDC)erXdRCgUz5GAqE@DZspz z&gC-IPYU2LTb*=uFNxf(q5an4Gf+`|Pj|rj8{wpVN;0IrId0l^WZ@yV<4$8isI;>@_+BAjk_YTz2F%PnTNB#TAK$F9MLWYRKQ|ubbM@ zrTLMgr}=9gz=F++%O+GI!f71JJK2oY9tFoY+JHLlY&)yf59BmFfF8Ew2m5)HRHU)8 zSA8hFwQ3ovYVAfmNm;R!9r^}$#A0Ke$c)#+z=d%$*hMB5#~6~NeJQa{#p;D)-q%*- zZ7k!Qt&#cSdH4tHoo&460^vc;pHUGZ85dQsv}yK1CHh4oU1tpXzr^+HC-;1DTU? z4C=1|8EteA$SZYQcJTMIGyP)KQ@7?j*dBbF|^pCfc^NG1s_Nh z(Geh^5Ci`uevm8ux8jGpp|I57gZ`(6k!t$*HUsu3E9Q1e*2GPT@94dy>_BNLnLEll zbnygI8-l)YWK-Mg%XyN0rKsc?#Sr9zKx~dyMxi-F2nXadFqelZaJn61jKbDJ52e>G`A9 z|5+0GG_9@t0k&WjC3oS(N_L2jMhZH_+%{a>k?f-HH+P7-Hnu3go>leNi9AZmUnzQdiygmB=O2}%sqYi*_MSEFcknFz8i@iQ9ubz5? zu^u#l)^dx(;lO1dc)PJ(oF;Jrl7$1((2TldM|)nUcBP67DSs>9rfq7=&x_$~-^Gxc6V`FW1(Af}_sz zfJi<*J=-A<%d3MAXQ%&8?02&8GQ=4aWs=Q{J@m(3?bC9;1*F7CKpN^uiSn8+t6!3A zwkQCEaX>G1Iyuh0NAE&CHIj-BY5PeM4;Zv(c53i(X&(EP`A~uA=LGmK739E1ntV>9 z&K(sHoVz1zVWMt~fKel-xg!!2kLD?=YQW%+ty@5fmwnZZ@;6ZScM+bp7JsHY8Uf88 zO7fHm02Mm~ugagwi>3vMjAZT@{@fu3Bib8i4)LNksoY-`1TT^TpQ!s{A8C$6h*tl| z)Qk|IZlfXor?m5{DC4rytJ-Yy+2}UlY2v$Pq&@RH20A~?=rS%}tqoWhB z*FvjZH^xp+Pv4uUCQ)_MJSe8Tt-Axxn{KE+#Oi!TxdnKL45BL6~2v3MzLkxQr1V$CjyYSIkJ?eh#}3Li4V zD1U|bLbbI-V?S9rxkd7RExRQZ+bS(n_|O;toh*2tE%Y0V&SR&q9rQk8bB8TJJ9-|`0M|-O%Q7TKd)5G zahsixo$vnjHK*ssooIiSK^k~b>CcSVfl}Q+cYOtYeDY^MB7hZ575y_VTsu-Y@}DKn z+5JHM*IfaWh2p>m-1cbvkFSa&z7s@={xc5a8w|d8zn8I_VS@MnX0-pBIbeq`f3Ly+ z{3>1*VDtZsV`0PpDgC40Mo9!{TK^ZL{nyMN1Z1K=`(<7K`zx^X=#N$Rkp@RMg=iln z2hN)9j0@3~CJxJfhVt(u`S#N=zso%|4hz7)8B8tudy@p*gU)HmxXUg%PbM)dqMPwW z=1@fWUL2f&)K{6KB_ge zTA}au0j(DaDK%(l3fyLiRnRMs_L*cpWoM%l8IC%VVz{$R#>Rww9fbDJgK=ZfynbcZ zv)K=mpNEIxHFO(eU)0HOB319#fGV%AJKPXW_I+adi&W-QnyT)hTS?0Ha~U;;r_*k0 z^wS@C;?U^c=VB#OOz^7wSL z&z$y_M{4}#rL*2@>NhAzEu%8+tg3Kk-*YS`x@tHjto@Ops!^1AfP9=mr| zpPctmzwPF-#lXb1_n6V=mTB(Qw#S&TlS=!Yu59Pg`?dEeCU?$&xz`>Dc(ahxNBVUf zZ&1`4Uw_5)ALd@VH@)LOwSy&msAv6zGq{_{!oD_**YsjlE!1bf)J(^pv0A&!L*JB~ z5&0|V8`|kg3O2CTF4vdZRN~8VaX$t`=Cl}y%DHUu8yg!vy}URbQX8y?iODr4*emM& zZ&sAjrX*!#biQoY*p7SbwHM%_HGPvSmIxm6*?Et){`9FB4$f<{7Xzt$RK+SS3kz9w zb1=zm+_#l?xs~os@S55&UZ^d}Hfk;|ONdO;IaG}5n#t?gr9g%qS{P0diEh+VA3C_F zStspcYbSehU=@(VdWaL8K)-Rco4W*;Am5=*(Q{7AJ1fn4+I|Czpk0=v`Kw4IZTa!4 z)b#nlmXPpe!>mUL1(_-0^S}mqc(~k!SwUaB`m8-Eg7nhcio`sLTLGP?)8n=*d zjI-gTls8p2X_uEZF-H)1@;WJ9 zx8b3Mg%v1~73x;;^F;L|uCnPoUrsc}@;w1~Nm3HBS4*64 zBRQaSlLYLd_S%y>2|^b|?2#`$h8(5}KSJ7TOiR0vzk>2A*r%R6d zizeoVcaoaUl?mcWm{}U$5$q63A6RbPM|_B@y>xDhLt{576nuvzxB2+&!k@XJfN%$F zTsRqZ1~_JaD-7Z|=jWX~VfQn8eS5ZiuX0x(*c$o7el3lWDiC|i)p32hi7E{PyG#V( zb6+nyHXeu6a{xTT3}t0&B;$p=VIOVpr~n-Y)<`6l5#sQY^wUm12_>30`j$Ly@X_mo zMxl39?q6zs&%zM%67xk==9YwKX0vBZf=kPz3sQgOz`BSC7W&0TA737HL2y zQ71ad?>)X`?IU{%QYpEqbLu$ChPp960u0f5Z7}QTc&l9Hbw?DYJ8V+?$A>wu^}IX{ zC8aVUzsry+OE!_UIFcBiIq#kJ($a;Knc)h(8r~Z3SdK3CvGNRN@^lpBQx4hmbn@)5 z^Bh8?IG|2K{0&NE%2dnNmr*0)qalb*c2c%AVXePnG2JpYHP-=+?GnFoYrSUvM8bPM zZ63MRu^9Y0*uQcX0k)@mX<$aO;_*N}^y9@)P1}MjlerqrPj~MiAn>*yD~s(MHY0_V zP78)!wvJsJBp=@GF3=n&tyIDQIDuuh^>ENm%Z+m^-O+O9l;GA( zz3LV;WI)(k+b$?L7=X~=rpqpR$D#wN*VmU_Z9zf|#81`K9=BXNH_gE%sfByy&(Bn zS%|6d$1W?%<>zF+ zo;feIpTq914!dhd>O`kiZbXQO*K9Ky>#Xv*fZz48R+-OYZxXfbI4j8AeM#)PKKNj@ zg$mofgRD==8Sv)>wt<_Y@izDwVpLwEk;jPF&F*BPLIT(U#uM9+qH0gbW7cl*ZMxI z&2f?Prm@xjMMmw7fZAcv2M;n!y2QVB%p}$aKJdXUF{w&3NlO(7HT}qwMYZ;h+MgL; zr`J08hCWP6NnxsU5Ip^k5pFfy-kxXCXR|RTMEi-yUN82u&hYefc(LHcrhyR2IK&&Z z!^BP3htL%I5Dg3K@aSlJqT+~W4tI9+iR&G(SX^3U`0LF=#=^HnR44|Tm3N#4I*4ow zUqaH4*v~_LZHl>KEZl<-FUmp6m(G ziQ`3ur_Hi^51@L)wKw#pSA++zOIb}RY->zi-t=Ld1BOQrsQ-YTBA0&+I3$%ZzEG$wj)FYkgVM85>lq&{^*8zt*Y~s!JrmY|rX0NMhJM;m}cl z{yxTJDDCUbixnnKzHbvL5nPsbxpBXgNk*qm9luz5-wv`kP#3McB>g zK^tUKa3Xw-4TNcko(-ihveS;J)Kt}(RfaI#J}DcK#*|c4Ha+%2PfAJl)zaH1K<){& zF-s6lg2kZ$d40$orehdb`U!eNNj0xFbC-tE)QP;oyh_KmWTyTcwXJ&~RPsajnT3mb zaP~}^(SbU@1H5JH zrI8yDFbS2QxR^+RJ{=TOP=qI+pV(^%W9$1he{3i7S`a4_B2z5Y6m+11iua>maLIl8 zx%Lf1c*!UW=hMukk<);1?NWysHZaN`W5ghFkE+0hrkib|b_~Qf_vkR2vK0>XqS&S4 zk6Wb3srNMc4P-hTm{QzC&ggF*8ei%~9y_LJo+C0#0gnI(dKR;t0jue-oHRGbSSk1t z+mtUtiqB!B#$wY0lzJ#=nicWkMJ;r%r$8)M!bYVi%hU&w#%gGyOa92HNGa#2DTZCs;YJ|t<1=~#b2HB{GlF6BW}4Uc(y z9BbesZg6iYz?;>g9meoxo(W&uJ-o4?Mviznya5p<_e8sH<#RXHGaIRgb1O-MVTml; zMxd&JaKjhseolLs>e`mH*mBjfALfme8}DnI;}Z~zPGn+cKkLiM_bYObxd-sq+ngir zL!`XLCWq#(8t7?8#odnRu_rEsBr2rzM^Usul4|?scs3y~f`r%w&YmS~O&cqf4HrL{>q$A8c2I2&!!Ma=c5+Z#;W*q{G3-Y*Z5dfX@l=_5SOUh>Ja4l0_Q)X%4RLHP$pQge*dp|1 zzQy2SP&CKO%uvVPYwXRIP%&dHW&$`{_FXQ*G+!D&Sl-|}w&CX<20MjC#t1SCCCon< z_Ijy_NT38Ay%Ty{cg`^9QT9;KoP(GWQWFoX>o~`Gr3#eeimdO;crl z!2=+6{sP-2d+f1`3Ju;Ja%rNQZv-p0mQP!~>$3&Pap)V*S{C;mX{VosqS=!srN4FK zgJF8bJTduH6`JBA2G=QtneBVui{sP&Nqy<&Eq}*m~SFWO3njT<8)=i!r1cQp@;bj46C-4iYe1;#tr;NK>!w2 z@ugcIyZLa0V4L<4O*3wt2Umb1?(;XZ!eNWbEEC$VpUM1M(`mAdj9oVm@F+hXUWyCp z$*wr*oO8j;SO9;*U(RilC)rha#RgN4e}9vTiQ_abNwD*(?xRgBBvIGki`1yhc4dkP zL0vX>5@G}oR0H?v8@t=sTkUbGS1OD^VN-W{k=ce@nalZHyX66}746>ha6~qB6wsvB zu|di;nDc!SY`Zj7oWbv!=`hRhvby4Xu~la5$9H(X!DM1WmEr9`KId(3kB&P^!dcj8 zJ8p~Mgj|+LRW(@bLVrTMgD0!#{cf&|^qv9I3XPEO{O1=Er)AFMU9QQ`JAM3l4(ax3j+d#?1xvUMH)Cn@>yic#p|>`d^9<^-rD-EqC)jx zRe5Z~Fq04BHC*VPWSx!?Sk}&3X`-v!Moryj&8=5!cic{}qyC(g^?ajTB=;;`F+hqdyYutul~zYz{Ud>; zYU2{s>n|O}E~(Moo+IOd*7h^0e0)#nEe4sGSsorCXuHc(nnc->tA7mLWNDWh>EuY` zRn#e^A?sljQL!Wd$z)++d~&j6_@k|>y^aAoMPi8(>#VExiY{p6Kxmn@Ibyg#0Ppb= z+ilpFCJ8q{pvvyUXGtdK-6fAV_IQmG*^!BnJ_krG41VxVtmbD^r2N%4o0Cu4=~&tT zq2n4z^{Q1u%}XCPK4A#(I>_WH`K{G_&>Gum1{zC05ou_-Kb1J(v!62MR61hyr17FI zxXWUi;d{)QcGnZ7a08WM^C;tHQ`Lac%Sx#n#)&YrNM8M(Xd2KjWTbX zhD}Nx;G^0Z%gcZrW{z7)u@Ie82(lz;=+q#(#=bZ{0qKRE`X@pl5J223FYA0AMXLzY zSPfzI_?|B0Xtlxw^z)w|0_qTBGGp8J;qS$aBq``#(wN~@J!nNO*DArctZAsT9WTy& zHRQbmVQ}lB{z<}z*ZHDwi8CS)wQhG`-*IxzlFFI$XQ~mAC-D(0N1scphT7`jW=z}s z@=}M$;>q;NK*r^6n{T0LS($0a7@+XPbYESZ(2Qq0BtWGt@>FhaEt)+HLpm+AV zFhx`o=OR-Cc%oAo%F8^PBg&`6)2O)!o8GP}q#Wybor^LmB(ZbTTjpk$8T~f5Y}g9~ zm({iHCj*ODuikbJ^eYiGj%-;uIMXS-9FJ(b75`9EKc_e>A%`W>OhT^?hsDlZ)!~ET zK-?YRv~}y*UAXrHre1)x%MOW9qYl#xCm1MH&FTLBVYtrT`z)LdMga19u{C`{&Um;v z>3MybU3ZwS4S4-1QPrPz_}T0dnW zAGTMOoNYlN+{iUtguvzsqTvu4{RWmv;q@z2*ayYv4o*usZsX-;1O2Wp`JFAD!R# zvMjgIb`ZQmn;R@h*!SBJY5GX6yjRU37dBx&Qfyu)yFf!7peo*>hgNf!spgEBcDNnv zC$MZB8S!9{VLyXIQh3Ujmf2cn%8VXZpWzJHES~_nL0@n+5`a!z3=AqWggxEFMk>!k z6ZxuzYiwLgvK4`o1O#4ZAEM~p>6Lt_xHm>*AIZmAG&gx-&JrPWt%^Bnb+HcSXWzdE zgpB37>|4~)+w#yQ4~2CeEm~V+Vo|`LJt^E@RR64p^t(m&SoigIE*HeOasowhm}8CA z+;!CTmG^!}(QKpp+SC!NGfP+l>ACw;m`naYYat5fv{n-l^36O=$HC#TGB|iVBtael z93l8+BmKgEop1Q14-%6A{Ry`^<+somUn2FJ1^p2tpu^(xv(;&v7p=WF@TMY*aHc!Mqf@+-H9Je0%FHb?bIqwpuA% zOey$EdLrq*ZVpaPnI0z*Feb1OL70z-$Q;CbZiUIKE$9g5e`8+3L~jX4jA9ghz+=Lv zp&uVB^%I&cB8gEQ2!xfg>O42!hgSecCIBy^jtBq_F_1z#C|YC-j!Meilv0if{Uvl> zcP*@w6&a=W_k`fwvm&f^8sg=`mXmhzI?7kwVUHylA<44nf1<1qFS1CP{&;BA0qBUp z<{6~5tk8iAC})!;XM>i=@lNhz)buCrxt6%+CToY>jZuhHPwLO4DjVk=u77{1@=)40 z!V5F`COOxCy>8|c)%fDC-iSc1)d7Dg@+d3=4Ib{>!y=fBWs%{xiUKma0=qnqE#XQ9 z$i^xr=VoRYozvYR{oK`MV=U1s&B?`Ona$IL4f0l6@;%P2D(lb?qIW2=^y5b|3}&Q} z$iAF7?hdQCDM(77zxm?b`{u-Xies2Vn-#Zw zs*v}4X524_aP76;`~qy;ffo4hGuq({L)#qoVI zAE!07j4NPc)0>6E(Dq# zX4Sm{$Ki~2spEQV=NpF}Uk-}F-2ICySy%}u*MTRmv0JiWnzcHnh~PurtOr4dy4I2Q znM%#%CYI@YjrN~Q{Nvh35kP`72(s~Mm1^#JmGHU0j>?#WjwmQ1$$o~*NweG?-Ab`o zi$#fy4VBx`Nan^|yTcJ3;R#OHWwDGRo9+|2=py3%TF2kfrINw+#KZ|LeucCs`e&wC zRTh}ev7Xj^y0)hd){|QD6@+Ni>X!rRkmF64-n8y}_WTni4%$a$l^>+7A{%Ls_vR$u zM?`sRKy1nD$zey{D6T1vJB9Nme+xhD?(v?+D4)#;*}sBP)eDZJ317VWjvT2R8IKJR zvas@ONT^kR8`pr%*&{r>>&+?`|Er^2AdRxxB_axJXWfgu>FQ+iJWTAnRx?ijz0Zt6M-!t@&D zs1S<9-El(0S)Vq%qB<>4mbRpzOi1f8eq3 z2EFKNr++^LXhkcKM_KobE5Hr=E=h)X}~A@ZyV{td>|k- zai<;gvgQR=SgT(h_V}eAIAmd3@QL1DW&13X!?9-tlSMZ+YxCSuL=7*v$w&pZfaA8u8JaBHC2Jj;7_329Iy?Bul*P8S-`5^y8%d=nie2Vs zgzc=1DuF*IWfoTr(aBEP$*7|@6a&bY1t0SJBqN)0Sc=~Ym-AC^f&H`N?$@Jbaa-9j z85SyLWka4d6vclh80mQMR505K1<1ZfzTf~`!ycYzRW+Y&`--&wokvI7bH;EU$7gz( zuO*c)lM~y5?QwkTPu~a4+%(NJ-)TzVs(r1o(&`aRv>cqX9t;OI=akxU&$&1EiCMIV zuKhf3jHxgPqsReN<3;QG5K-}*%Cum@{JDIk|6;!m&Ugy4kVE(Lh(6N4dJKpGiLu_} zKD#Ww`#`qgeFAGf_dTqzB)2db+W0`;XvfO(cg@rcc@1P#g~ne~QCZ_%^e~ zIrYElK-zP9Cz32#>*h~A-UIIP)~){gT|}#G%*CNC*ObwkAT^L3=P@ z%(NH?UP>A?2kHcP-bhBw;7wRJSZ)a>^GjGrEM9WUEy94=g|f1jNC|uFGz4_&luV8OJFsFDA!LW|f@48<5$$ zgg!NW60ohEUnFvxzzKioljJB&n9 z(Arl6vMGIWlyh*M6NNf!_-JOMXg)psh`hMF%Phr&&VQh15n?sMeB%`OlDcJ$_|X@S zVEm38o2s=`M^8Q~-^Qs{$*7tetbD3MQ5p{od&Ia+^(`|PC#6>o={$X#NY)mWkfNEw zM=DkkD+d)50K#fch> zP7=Hm$>b701icS9*u>c$Sa;Q=;Kt6MTf0QDY3b@U{QV~O3k=o7ac>l&UvUH@Q4$UU3J{BQQw|vL|@+4}4Sd;K{ZiU1ofMmR#)Y z{IAB|IxfoXdmA1_;Ycgp0!lYXmmuBUt#o&z0@5H-(%lUr4Jt6?(49JTch|Ey=X{Un z`+J}F_j&%Fnfu;*?X|AG*0ry_hN?xqg##^(zus=L0?EWAyQzs^MI{EDQqt6x^fL>< z@lv?|;iSsYnkz%5KEBb-<>)FMdIk!o&|BI3dx%)YLB>!HDJd!4uhx+ib>1E=XWfNW zSsebfSU?$6EkU|YL_h#?kck4N=Ui^1Q`KTZtClPutOS#7rf0W=uhxYVvzGe`;)(B<2rft;y{C2Bu_tDm8uJYUoeFntQ#j z>e!H*50-uF!+hS_wKS<^hBMdEf0dd-u&wq*_`&Rpp$@)D#vE+`zPK7zO1+eBQ`hlf zIztlbBrjd`#P|Vg+1C+gok&r}+7Ev)?R*^d>`L1-7^$QITNibWB~X?;Vq}c@NBNlf zzTvcC{L&7`;y!OoMw#-fdW^+TRc<0T8(kfjdfd`r1wo$eP$7zE+%6l!a}6#l{jkfE z89i|JymmaH(cb<_@N|~H<#ZZKsie;6q)^uSD3gixuy=3^rlc^>%KG|Hox?_+oK^e0SQse=3d$p7WMa0Q^s^zW-`rHG z`ss9yRnr-KB;ET!U0Ip2-ii$=RyZu(SQ6BflM@p5;7b{6{A<+ip66<`bY=N#?Yn z@yrx$*==d`@orknXg__l`J$LBD9J>n??d>cm^uT!mHX@0bqNV(z45S?Gq?{jv_tGL zT?WuCHa$z(S$bE++c>b{rOV4pf)wnSg^7HIyGY)jr-B5 zsiefj_(Vi6{BB;?pPIsKry7o*SJM7$U1v&)a|@9>ul@D?1)!vWP=f0JN=exg_YrgU z8$M|tV2?#WY^$Tlt8s8zS&~ip{4xx)H1+t4?|$knba|>;0>tM(#8efEYV=img%Jjw zWo{nT5U-q<9|$_B80g1eG|pE)kN)DN_IF0|8+F5+Hb(Dh3*w*wGPu?7JGS=Q*2|s6 z=Q5^>iJe&g=Bzx!aOE(F-ODS^PO&_6o!t3b-FE$yuDYU0yj8yNIGg+3cx@0n@&Lw) zs#8i(xb8u->G6u9lXd9S$H$GPefZ3`J6^560yLAw8VRfE=?V`CKXn-Y%GUd8-G6=R z7PC3Ll)_&hC4X_Wo)~yR-QjKw5@o}^`#qUqrABR@6yOXPHFv+Gjown<4Nar@LhsCczz=a;rZ;0#r9Bb(ddLAKYL$PaK`(AE4IpX|_iz+=Qd00PQsB+nz zfJ!i|Fl4w0Efl)iE0o0Q@4k~X1lQePu}3|~-qTZT1{9xJwZdo$k9=MNo!8Tx- zE0dq4H;9w$_fNk6-*}~~@6NY30^KzQ$+?x$TC}4=v`{Si?9ak3@9(FnwE7<0m52`y zIIgTM$JIE>JjTH7$x%M>X2fGAP65HQpJSF|@DlY?*KKVaY+29UX1orj^Ni2^V`2{- zD>t~&7Jq(cY`PlPIXP_zPD$nC3SBL-M94RnaKieJ)xZff*Bo>z!8Q(=r1*HZ)vw!W zX*D@(Z&*gAFeOFT>+0+=JYoi$$HS3~IbHBNu)I7f3-@K1mio9o8`hT}`)7&l5&&J! zq)&Dlt$=io($b;6t}Y-b2p!*kw@?KM8x07d!Z<$V=Oaa3p1BV}UgaaxsDx|TmMU7g z^Z%MKz_3~wfh^51azN_eyfdx#bSmKCtXFwxoDc*$R;_2>Pe)7AwB@!OFOeT1!oreT z4hSf^`jB4Gy9+#b-?!rMx5Ye)#8Pf-LRXudx4Y${dr?tQG0&%_2!&4Q zR*SiKu&8pZpx<%+bhW>X_6WOtx+>xlsPPVlDICqOXDWUr0(2k{^nN=@pMqP;F&dmT z{{N9#iKUDuxA^R4iVUQst`0DJy2XAMp>Q2~LeKo}{a=DdDhYGLJ1R=`?pB`yprUHD zxbsCW-J2|y<6}^clNm=7MeEDv@j0BXuDm-8yY79wW^_KQ{`vFU^(B`Rf`nhKo!@gh z=}QOdRIB2#)Pxrbq5JI{B!%C9KI9LwjDC}!Eh$^ly(=BRvSkj!u*-jl|4)bdsw^U} zba>-TJ5V=ybb5-#xieaL?MMhC()-v{;$|QhUA`u^OG--f{Qrk^ijNoRbRzcHU4d=7 zpZ7A?7B}B79fWI@UVY8CYdQZo-X$9J74hN2&}5yBmIuao^~f8NsUPEBG-VimBF(&+(sy&xY<+)EykyeM%x z5@r6-)M|PbW&tcE<#x(!H&hP4j_ux`!qK1YpU0t$25CYr8{FFNg16p8jKv$dfmb~} zaSDUCD-&gU6s>6KS7d7B^z5!%nETgHv($m+t6-6w& z4s3q5p9wijPH!%m!}NG~D8Z?QBx8wY1Le`6=QFaK_r4t{U#yzJ0b^ zL)iJDL3B_y0^XR>&z=Wnl@8_XobouMuW?PVhy!`UeKMyv!F3aE);o5o3kd+nFoghM zmpm=*c3Ev{5ToZsPfvyku^vAbMgJD? z7);oVC+eLfI>QM>{QspYD+R1m+U8WXleu|CRFp=wX>FHG?EL*gE`Bk=dWwz6q+B+} z0(Mhb%trI?EtfkdK(+~_w(x8W&pQO4O}L9Sb58L{Z z;$-FA)nQkPj;++x*X@I5BgLCp7NS!ulWPJL2jRexNJE)!Yk|&5|BJ+SUx^kBlUi2S zChpI$N!7vx;vgI>_{(NQA+r)H6SGh*i)W=ddC&R`7mf2$oYBIwMYg`Amu>Xw!4P8n z-ewL+!}ONLfxN}H7R~86s;W+VP6X>duYApIWTHtz2TU||fcDlQ9^t=OB#iOIbkE}_ z;3_dM7S3`GzOD;g1M6szU)&!NCakJ@214c<9J<{dcYQZ|jk@B{@WRw5Damv;28W12*eSa>E1vEz13qJ*b9&2nC9IP}`!dr52*WSbne zhIi-{S|zt(m&I(5nv^trp*2Dz!UJj%{o|cTx2wT;Aj#Qya7a1BeYzG~H?=y}*n_rv zA>iKti}JbRacaE{L0tlW}_lNI5o6efl7t|AGiyUJ67Lk{)DYi=% zq4>_<{E+(IJtM;N3W`D2tu1y>@Qv}LRW!G*0BQc9lPHbyG+^zRdXnV3B zZ1lIvQMr_wYu%HJ+@dteyAozR^d@g1h;Eq!)fZ)E?rhRECI`lpL*73st?|t{)z5=~ zJ%H44mJL83X?DXJhNruh^_r}Tv#+k=*!b8^DvJ{QBlEM24wa?b-RYlJF;C0`oSNef;cF{L5)Of~0|=rfOmrK^k` zl>5B0dERVhqvn# z=bfIZ66J=TF-z0dNC9&Mwdt_i0aLSRUYSoadSvQJ4E!VPZ}}(}6zajdlTtWh9a-D1 zmFw2E{^kQ8X%yZ2UV=?}n=<2)#%y~clg2QAPc$mFulcWE*DmfC^B$VcaHA6tvLT&_ z7+Uwm#_+EJ@`3NrO^k{FyNa!en0-6eosuLK%QhK)aGP^Sj8W+KJRtCj?4Wp(RfQg+ zN3lRSLG!2NN6@)?Hd=sfOJH}@3tR0qwjO>IO#8W98nTh)aWL^=h>oNS5Dd~6nkYsE zJ|^JnVDex&5$)yAn9ud6>OOdeAU)(K4Z$So=Bv{VE{~XKH0D3D?+7gR;Nx^K|GFc6_2NX(#&;8{%`$+6;Fu zqiNcSx8{#)>%2m_Rt(S^Jc1=cRV!Axdt7D6g)CFt)*b7eA3c~#{afjU^obq{yOvoB zuItz!;X3teBECGcd(P{K-K5eGGZ9U>e{najjxeU^-X{_^?M;3Z;ycKIGOa#I?dxD% z+qo~6+(gW^`o777r_8OZqt%R%?=XBe*5V&&Y|497s3XDU-2SW+j!ATQ^Lkz5c-Q_f z#N?xBHJEIun<2x({%p)iKdtT8gf=fd`&o_b0K?9itw`SaYuCIpsuX?yv`=G{Oswi* zm8nJ1e1ON3XQO`ps*!=TWl0SCoGI<*$NtALLtMO}$l1JxJ1sg;-!ukNJy>Yua2(xP zn_W!8S(clEcEAM7`=k2L#|alcr+{8`nOd&B1kWgV! z00|K`*JcXE6yc1bZvkD4py)uVxi%K8s@NdFU6L@)MY1}p$s)q;3Hz~xekA^RrfG}c z%>IGIJ?W7^(Q5FnMSO-f}#_QpAyQmr#>>WqEqB@ z52UW9c&+rmvGj#`Dy<7u5YvsRAB@K+_w;2vpt372W7ZwrNN_n&ncvgkTB~4@OAo|1 zYdr2{UP$Cp!j;xAlf^*F4l)tOu@y+e&u`oKHko-j!-a1ZfBV95W#piE(nQx|B4Gn{ zhSA3TsOA~9^V zBs4TB{yA@;Dh|JM$M5)Ul~RW1S~GSWy@uz0N92KBE?z;Iz5uJYyKuJnac=_i>hf}f ztzI45k-bE2>_J$rqs_vNSOU{PvVvFLFfZp#3Jt@qvD|*KmPZj|ie~AP{?C>ko((0s zJO<`v+BL%GA!9%2tkClmH>PVA7CcsKJdZcHdE+g{OS(r3DMyC;dqi;~e`Ve#rSjd9 z&Edc<3$kb%LmbFY{roreZ;&Wk*plsAds3L#eJ-5$PlQOdS>=xp(G*sMf>gg3+ZD1c z6BC_}5_t^|V!%q_LgSgJD(NfDDb-2x z9E9|^kkE~n%%7^1p1(jUr5#i&up24eVS86rpgJYJJm*PgCRN8|!q}6EDO*@MiWTV` z5XTp(tRIuRCKVRzSYqDNxUv5SUa@QHmSU#(dXk(Ks-{%f;mDB|C*C4y8L6$?oARTh zNqP-mBAx>q3=F(O3tT$#U$Ko|y@4qHw>NxjJUkbdyAvGNn!ASsqRT@;d~~@1b3Wd) zaRv*XN5HP7Ez6lm>Ms>)ma&S}#)-*cne68SLY;Bw9Z$JxamTlGGU$#T))XnE`@xdA z5^W#n*7hd&p&)yzoGZgS9Z;RAbFj?kC2-`X>VAGxEEDppqeet|Z)*y%PRdtP8Jc|%KWq;;;Ub2g$W zSXor7%59>}6>y=F=Z#5t5k0I`_4?#&zb)>(D6E&SX#P|+ObEYp#@y(;RLuK3X5!X0 zobVX^IytMv!dFc7NJCPV<3^V8;evLJW!E9jf!Ix1aS8Nb_Yt_d{$%HoDw!|7YPNWd zc*I6fpijF&W4b}HKN4kZnDq91^9@ie(DfdO_J}13kMy02X=%A)Eg~y7dmdX(Rpk~J zTNxS}%F2ejGa+Lbr<6`$sS%A5HDC5wXUSaySmOb?3u!nXtEh~IP)`v`IJB53-Sw3_V)J1k!D&Pfso9XBa&01 z6!ly(ueO<4?NJ+PJIQ$IbJh&RnQq4$k9gBQe%!|$k9H$q$>2I3ND~mj)6-28^i=i! z5U#F5Rcp8FwJ~}Ve%XqrpV4v7j*EW=ZSshT12Ljr^4abBf}rP~wDh31`lf6VY4V;K zT!tV?zzd$jLq_#HH81If)sLUwZ!=8+&DeTI5ze{xQ96$9IoWnk+#wSB6<2GyeNoK~ zN4!GGIAe|dp7aoLL$APLc+haB;mdc!2YQn8O2;kvYCZ3@Yn80Ns}Vu8pWh56S2a(@UFbP)lCNq&xTOIPhe zS$wUDiC-2HixG2+vhqz1|4SkR-}A!O+gn;6&y@Id8N)ntHi7rrniBKNla(Yrih;<> zSWj+P7Q_gh zkMe^<8zUpK=IfKE(;2E0&5eEwEprx^5nTG2qsA>Ij(?e#!QjUuj`XLo{GBs1jC7XN zHi~)CP8Az1Kj1~D0;S5hqYV+-D1w(Ic(An|VEk>Y`k#F?9LAM;Sk(1q9 zZ34I*_DG%E5Mr+8p&$u#eFSM~Tdy(a^c#(n?~Oz^X^Qo0zY#UA}hMuk=hokyyqZi zO!O_c&*94L63^9Ua*z0{cI0VSCo5J5_+^jI*Fq=YvL2Vvh|j=}kiC?K+U^iRDLkW- zvpzk^^D6+f1Cz=5W}>+{9b~U=g~yD#__F(5KX?zACd$*5R#Zzg)6hlhX|UzgBXwH} ztaYlng<37g=&nW>mwV!tHPoeD{<88_9C9vd9OGs|)35}QGs~Bk`5NfN3PRV|sdw7S zA=kqd`2#Fp?R@P`1(Wl3Q}bD66r}Q4ezTQ6hnFwyhM`C6CV8^w!jl?S4r7;T>a={8 zbK<2B*X>~32kSMu>+6-+Xm^3>QR%!+z0!BCxO2!AYBAer?k_YZoqmI+roWndN!p5? z+h;jeM0Y53#Ue?-W*~8#r5i)_u<%3)w`UrEm1t$te&jpNy%f2O3gw4ea|Ai4{>6a4(xy#*^l=yR&H6*ARWo};c>mrXNY-_m(6 zyI{7YkM`2@d7b#$uO_X!KTW}sUOd9UIN$GNWMvJC6%-h5I?*3_6{D}zUsqCt&tl(3dLvsO3lD?mD3gv)nA5v%G#(NRln(o3sWmnRX5fZ`9XHY z!E5In6kA)9rh&DBGLdymOuF$7IA>$5XQ7F?M1G)r1TF_%;qsSnh1X3djgecQ><%`@ zijmNX%{>Wswr6U0!Tsx#<72&QQy6gEz@hgd;i5P`>zvRU+ie^?H`RGTuy2j~ON-yo zb6>5s_#`iF-(K%lct~e-nl9I9-=Hb14%~`FMGg%i6>F5|@s~c=#UqJ25T_}13DBdG zb+;SJvhWTfz2S59mUlToz)-gG6~95rPGG*x)3u(es{aIu9oAN-{Uv)Ks_iqzGe2*8 z6;{+!tL?lwz7B#s+CYALWYwVA(!97mbnXm( zt>xHz0(R)IXn(rjjU-0F3I<)Q>Ui08z>SdaA~g4kXpi=GhzZ*m8csk(jp$nrcC*1A z5UiP96iv*@RBjuiwp|}@q$S*66Y`ztEqBua%jq~AZ-nHh+w!{Y1jWj%{qg|!Gl1|< zWj-b67-F#u2e~eVwcJr5uwvkevwYAzIi&&TBTUq zj_^ya!szkVQ(A9tFnLjtot#syI2!1`S}u3*K2IQCS+Y6ze^G0jnvE*Kr8`A(Z|5-z zYyYR<;NUa?uh6+mV`Jm{2nc$5dS6L3KNM*oHC8jtt_~dC~`)8z9fi@9#xrY^TwX5nK6+^d@U+_?VVt#~UrHhB z`lo+wk$S0esrK0I)#~$Q9->e!j@7+icIL@9-F2t^tLdg8=Y{=>mm{w=`75<+V}(HO z_G%qmu4Y!?-w!w#E*+lGPO+FhJ@Yw-V^E21-}!RB+tHfQ(e6W#aW&qaAAZP3R4Wgp zW87xw@RUxE&0IGq$jIP|n|RHbf_dXwcv1+BBGYg7d_kQr4n)Pu`VR&^3KsE)>_D#c zSDyQ=je%6>^nh~hV^~=4@#aKFCDQk5 zhk`6-fzG<10tpY645Y0*IiloKo2--VnbC%t1drC&v2s@y46~>6-cD~lRA>%Crunj2 zO?Ou5{IJWh#&Y?5F$%i+K}k$2*a1VBAo3IOGLOU0mbyA_X6Eu{uhUQjb>Tb2A%}Ly zecbE3+{H-bkXoj6`KnAx%GASk9iLMbClnEQnRZb8NITb)h>@WnsK}tTA4pfr4TSD? zOWw1`lplJ08n8UQ8WRUV!9Wfb&;)rNB?U#hZOhWqYXgIY@|Fu};tF(Q;-WQ~AlArx z5c|Gc`gg;0?R7|D;o;UZUv1RY;|KFmCrWi{&kt8od^X9UnV~Jt_=}1(*vQBBpoWfn zhk#V3-<-6Ylbg%K!*jg5kZy;ox`45gEYy>w7*&IL_tm0yY~vKQtn6%XApmSvvHd{O z?Rm1bzPwyx3L~^N{*HQS-VwuImLxO?ep4)Rs87bO&_pRn+8giVc;lUO?&qwCyD=by zK_YM=&`*RMSd|CTSS~Yk;}n+VpcPCcZE1vPd-t!slC7e?H!iJad0-I#0m0@dFrSf(%!+c&zes3x2oTD=Q!| zfB|dvOiXa`@M!Ji=j0r1jM1~O3|_&U#_JsDH|L__Z&&>v(rgx=HjWT+TFTyXkcns& ze9ty5y|#>T$Ma6vnTP2%9L3Z-nPnhrllgGe>(rLXCGl$w$X;I@6TPtHFzx%}uvw8N z_Ik80afH)$mgdF`kG20jNLNobCkA?Z>6w@!cg;*qTaL$dd@hcph|NqHQX_;#BXcXt&|J% zX#evY$Yr=}roX)DjqkFD7!nxIQcl%7f|00JTtr|X@l*@z+7e;Df; z^}t}M92TEiTZOLEYr*fMQ&P4zHj4Ojx>E57x3hMy;wGwPN+FnfT0%ct#zl5MyS0o!7Zkqgo8{^)&BW~7oT!KhD7MKQ@F5wJPoV;? z1VD6*h(^e5{}UiqJNWJkAZPFb?c?;_e+5Pmam_b-X%HhqXheb?#K@_s&H6sG9xYr4 z1Uzs+g;*o!))o}dRH8r>i7^*LmSLeMKs@j+E}H4ynUf?-{rop~R0Q=h@OAcI2fb@0bzWDCIJAz0KaOH08fhKQgE znwa6y+7O8BsY(;1o6-jm9WW^C;gJzw4>C;5w`AKMPusa^?t=`?7zHA{04Aa0>Ut9V zn6klbHw~l?k@t{T0Zsgk*jRTzS;()YynGj+ddIyw3|4ex8E@~at*Pqkt1C8k_PZhL z_~YlJ5OG@X9UbwzZhhv4oMSHj91;^3M1kGElDHOxPNN1bP0*I3*JFc>)s!=i4I06<(l)nmcx9BnhAM z+Q-R0?69# z`~fIapCGf!M^#l-fi%hMWGnI0CyK~>ZxfwX`vFx`2(ZMi^_tVy=N@DW$v8!Rd3iZ7 zAOHlw&W}J8I6h>l7Y3Va_HqNUEx^ye(w|C1M#kI^x}^v zd45B}gFyPop;I5i@R+}X=v(Pa^ziV2e}~0+xDJ~aInM4dV2`gyLa#U`}@IXVId)pgTSOnjZ+xA`}({$OKX8*D<&z4 zE;7y>e3^=u_o4&O0Gy!fwRqPz&&}L}lmy|MnK(K*`TP6N0DZ}F4~|3063BG8LPA2k zPIqbsYB3=YO$^q4s#4wh;m%HKUS4ftn#?~#_HOV+seEn?jg4gd?ux`TA()HOMSN~M zC3=k~fHipn)ZpKc!LS+V=z2y*oWPz17Y^}fCZ_d(!{P7!{XqsBgi7FevZV#06;kpR z-)yEoU1)c8mCJ6P-vJ_AezLnD{1U#LAcm?aplXljbclh~88fChPtR^3llV^T@_m3hKphHK12uF*CSEGO-fbBLU zA_51=`T+n1UgtGMVd1xcp|rQ(3q-+dHv)k`1)K>WAFvH28=Eq5#lv8S4jMi_uWxVf zfraRBI|l%WW}HF-a)CPl1UG%@(bq^pqs2dwCdCIhm&I7o7`!8_1jH*gYly?iYGJ-z#D*4Sqr3|ol#`WASHdP4?HjX=;#P+T@N2T zm~HXVAx7XkTut`_$T1EU;%x8NU4Vjx5bnfW+){OQbyZYUJl&a#iHYf8tsnx%Jvli+ zM?sO1mVN>pM)(wbYr4tf@apOccpx*ny*LSvvfX@>Gz#vd)0jbBg`c^(rDc)3tF^AP zGsi>EJ8$8<&)Ppy$=!Y{??8- znGW6w0%aHUf+DVSD?fezaOEA;wz$^DcUMYXUH#Ro_St$T09}v@2U+X4dZCe#C;R(a z^^UoNyYKKj)i89z9QOD3tIY;Z_V(P5$23lN7ns4Ky^Sz2M%Ws=t8$&!Fo}s%l9P)$ z9xt9%W#WTUXed)OsG+V-HjRJkz>Dl2jK5@Lp$! z0w|ET2CL&^XpHc50T8}`f#QoGFiA7r`s$3cI6OS8UaBo-(FpJ|wy6X7Q3ZmmHDngR zWf~Quc5F`<3kJuD7H^0{Wo2ayl^h_(mq8}!v^B|k7bjbYSVWMN9j6t15m{|QCs$Lq zo#0<9J9;NaBMdx=kE>@*l(}px9#d*ALQA|oRu&s@5N;~goeeeG(B)+UzAxL`FgRTH$pF_v1=}0VddCtQ z9oMspOdc1yWS*F)SJn%HE30Oc{jfJGc@-DOxzrn1*HeKg9|X_gDBxmqv0k#x4W9&vVgD zz?!^$AA$ynJd+wD7oBulAYk5^{Empufk^4$ul)FVeG2jVn~@b5nj9C`$>lDU%v`U+ zy8}eM-YhW&O3|Y8!(1z+abgZh&lmAkgv&p;<_!xAt$T6T=}J<5F1Fz^o7UP&U4O)+ zrKJPhPFH_gT;#j-+x^b1?5Ldc*xRP2P{I-ALsR`IpVTDCd9s;l$SJ=OTz!!z2GN9l$bbtvfK-8 ziNiX};>ndJpnfGm6cl@2s#EQE!)m=dLtUcsfRzcPOdK4eGc%2L3oUm8>h6AQ2C#0n zvmFs45$>QW;8|hPnG;b!GhUipS^g|-dnOm0%B=^ErVxu(8;h;CVg68-j$@>6PNKCN z5wCZIzK9c4N^4dr+kA&r;CrLx+40pt=wwuditnH^`-s-o^bNsR6=m6Rk3Lo=US3`h z5n^Guzjs?mABdH2N+AwG=u*+aoNMWqr$m?Da2}V??b+_>8WS>a!!;VaOcgqTRGV4z z$ui}R&rljY9`1sY!iLi6rCN>BPx_O3mG4Oe=$e=1T_o<(W!t$Yc>?43wSZMy?oG(g z%L~2BdI&#HLVgysa~G|qnY7;Yc>BmDiLhkx`p!d`7CF@zo;cXlr`B6dHv-TSxA*t!rL@{YhD6s==kiRBnA)-otr{EhdWF-80n6 z(x#a6e0v2pHC;12F{hNbBvkcHVTE~kiN`6YEjTR3v1t9vk5C6CB_)u9f`1VGa~hp> zv$`knuwfy!7{%8)*q@~nIK5x1CEEYGPsAd8Vfrx?CwD>zgOo$deoIrmH0j8N{Q8ne zu;yENVa=V@Fv#Ksg_JViJ4?orsJUS?DMyy*XhL6c+888@fD+)gndZ>Yn0Wj4t!NN>NE@&PMj)^S;64m6@D{&X zPr+AKI6-a=4#vYwz^74fe}4+V>@Ft;NbrpkAn;p%{LYEC4zTCG?F{()Te!x$`ug*L zu>(qUHE$(mNMu80NaBdKqMSEn4ZyJ6T!Pf`8DJ_ zfNbY(xl8qgHSX5zDRe&&ALMimKR~1*u|_htgZU2P{5>b~yBlF;cjKcCz;}ZOOw!JJ z&TcyW{zd0BenL{u2Mn|0O?C;1@g|;RR{!NC{0}|xIMnoFeaR0QQ8w{he?O*@6WV-$ zjDli9ORMZDBX625Uik-E3@z)VV)z4+Z598qVjmfBUEigjP*iX;3>OYMY zwporE?lyO_u}3()_tz@bF3}g@^yTmE$Hn9Nua|OjadEnp9Ss+qW2QHES(Qt@+Z}!$ zLq1$d$>$Znyj;nslk<%FROm7sjil!ZmX*$5%uR+{muD4Sl5GKcji|8Rgxq!jcyKN| z!c`Q7l|r1~t88ULtY%w=oh%}f!=To{q4T9{5YKovm5&N9E~3#*?E;4m-vB{Q&PO=B zw?AHAEY1WTP1!dx!u<=1*2bwPv)uDx+j1<2T&&&^-edZE!6gKs`+X9-%lS0RQp~=Q zEC%%jW98ao_#hK#w^#xEIQ0JgoQQh}Ij6(4Si>V|GhYbBM8WAHaXM`&&F|ISVC`?R zoZviP6Bhpv`)z4kBE-ShcWbv5Z6*jK44kDmd#WLutq#bfn<~y1NcdiKSNQBxSPg!w z*xqK;<1kQc{O!S-M2l4N-~h}1;tTfAGTmsw9ZY<4{32zs3-_1GpT3mhOnkZ69IuR~ z%v~L(>8r7zl#dAm|Ho}0G@gs%waFMWX1-9zZ9&2-pY-%Jf$2@Psg&F_*RueZ9fmS% z_1^(i65+tZV}0Sg9_B|vlDmsV@S^9;b2){lMESXTW!7J>QH`ONQ7C<3L+4}h2V=j& z-Fr3$$t_M7JLS}~xi!nvR4K*r4GdwhxR%*6Q#p&%G=W^RgFZYi#^06!eos+gHK7?p zWjxXZhvy9R9gvKz?vWP#o-wvlxYeMrC&hL@$$EAkr9>60N&6#_++3-V_x^H8cSBYb zxr0U86@0g!5UV-ui;&>yn%oJ|a|NXW^<3%Ui9Z%vY=&O}e0clhZl{oE?c`4Vm+$;< z2yrtNdklg6fg$zkrRu-YA`o*?J_VESf;qxO{2$;ku?d%vd(##K8r|gDt=Y_{z&?}v zkXP`lel6kFD*SPYTBsRSR|RFI{0C?L2SCL8b{PG5&^Aa(RTNY#(WD$P_xK;^0t?@h zU{-5Ozzpq_SvYcK76NTF!h$elTF1vS{eNZgr!yGzr=)!LN1#{vU^8c_YdOuaep*Gy zWhxVozj_##*o}x0?;GAbmntTf$S|1|SZ8R>usIg?!kR|FY7PG5s||a<270)er`~^g zfvv6ej_!J{+9A0hYV?GD%>9L287k2n6A9N7hTdKiov)JLWp?~d2#9!NpHoTi1E~hT zhSUoex=T39dIG6>S?s5jD#LvFtyvz6WP`!ZAVz%#5(tT<;G zF3zv#8mss0PYws5ly`ySNFgm)zJ;@my)wUm_TlfD$uU?TY0kUHZLCC+xluf$WSL|vNvrszF_3_E)CYS_8 z>6e_b(?b)#TboHiZ_N~{gkpLb1-xW!l=0HuoAb^J5|Znm2rT~{G9g&G8gvTj@%Lxr z=!ZK=?jxXysufkRn`z!5KwSKP5Fl3Es7#K?AxU>6zZ#aDoA8Ru_BAOf9QjAbUzyGl zh*Uv#^1jum#Q)kA>Qabl<&`8IonzDX2|?hiSA#TYLV#X9_G`^>oO-(D!E5zwM5}4l zi>Gvd2L5}Kg_dEyC2#M^?if1yJv@-w=x>)QzU;A&eO!b7R>-vMcQ^w-4$UajGXbFs z%lg-}I*1nuIXHzkgV8kj!~3d>71s)NKodPX_C=?x_ro30LOKFcy{w9;75Iwz+8odHG8 zn-H_wC216^Z!Jl+aoP-u9rCFE%N|Ib+=owbh=Jz9_;{moe^JZz>*)Gi^7gC+{`H9t zs4P}wi~3|a-C2q?qw5>13uun5qL~jE7|wc`x9V4AUF{|!#l(}GOa5ikhmj6e6IHn~ zQ`<8Pv>`qxiC^SkG6`T!80f=t^VzAXaY;&fVk|dQLDRLZev+?_xv@*C#cjRIjtuVOdA@Kj+U#apcaf> ztyy#v`->Q-4RrskH!%!9KlEa(DABnmj=gW7JK9+Nc!Pob``}QL6cNYN)rKnbflukf z!t^A|D!yC+-Y5U{)}e3*>HU|XMUHRQj};FsV*756nL$1$BkTRG544!GEt^~_f6h1K z9=&VDsM+vk-^Z~Bd6XmlJmWXMsQkoV-G(vgW3SHk`YE|gv3-3VvM;7qnpjpgtg{wC z<;Q3?P}Ip?`p|03xVxJwHRqXn<5zB2=zl$-)|oc>g-nkTcASWa=4!w4;lZ1gO?m-x ziRE>Rvta)X*`oE4sTJ7pp(PO)8wP0gElY3$<6>Y|=&{#pz%TzIjpMo!{^fn(L!DaF z)*DO5kIws3W^%mazqhv(;0KwGPE!Go?y8=ep)`T1v0~+FH_(f|*62r>-Unu4rBtc7 z= zzW~4N_%pa5->B}q6A&cN?xGO_Ne;Lx86bu+cOV9VSP$PKcy#J>*rm;YdIkcK5|e*b JCSv&h{{XQ5&I|wm From 715d104667aefc79944d664c609de2f22381a734 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Sun, 29 Oct 2023 11:39:41 +0800 Subject: [PATCH 252/518] Add table of contents to UG --- docs/UserGuide.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 476db83e0a..4863be0e36 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -1,5 +1,24 @@ # User Guide +## Table of contents + +* [Introduction](#introduction) +* [Quick start](#quick-start) +* [Features](#features) + * [Budget](#budget) + * [Setting budget](#setting-a-budget-budget-set) + * [Updating budget](#updating-budget-budget-update) + * [Resetting budget](#resetting-budget-budget-reset) + * [Deleting budget](#deleting-budget-budget-delete) + * [Viewing budget](#viewing-budget-budget-view) + * [Displaying Overview](#displaying-overview-overview) + * [View Balance](#viewing-balance-balance) + * [Exiting the program](#exiting-the-program-exit) + * [Saving data](#saving-the-data) + * [Loading data](#loading-the-data) +* [FAQ](#faq) +* [Command Summary](#command-summary) + ## Introduction Financial Planner is a Command Line Interface (CLI) application for managing your finances conveniently. @@ -13,7 +32,7 @@ you a one-stop interface to access a plethora of features to manage your finance 1. Ensure that you have Java 11 or above installed. 1. Down the latest version of `Duke` from [here](http://link.to/duke). -## Features +## Features {Give detailed description of each feature} From d229be59baa1ba1901364c90f23a4af5a11efe67 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 29 Oct 2023 12:14:56 +0800 Subject: [PATCH 253/518] Changed colour scheme for visualization class --- docs/diagrams/vis/visualisationClass.puml | 8 ++++---- docs/images/vis/visualisationClass.png | Bin 34745 -> 35821 bytes 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/diagrams/vis/visualisationClass.puml b/docs/diagrams/vis/visualisationClass.puml index 56f2470921..1cb58967be 100644 --- a/docs/diagrams/vis/visualisationClass.puml +++ b/docs/diagrams/vis/visualisationClass.puml @@ -4,23 +4,23 @@ skinparam classFontColor automatic -class "{abstract}\nCommand" #lime { +class "{abstract}\nCommand" #MintCream { +execute() {abstract} } -class VisCommand #Cyan { +class VisCommand #MistyRose { -String type -String chart +execute() } -class RawCommand #DodgerBlue { +class RawCommand #Cornsilk { -args: List -extraArgs: Map #commandName: String } -class Categorizer #AquaMarine { +class Categorizer #HoneyDew { +sortType(cashflowList: CashflowList, type: String) +sortExpenses(cashflowList: CashflowList) +sortIncome(cashflowList: CashflowList) diff --git a/docs/images/vis/visualisationClass.png b/docs/images/vis/visualisationClass.png index e0776d071bea24247d870fdd2dabcc05bbd0d435..18b9672ec78e8966b5a1fabfe9a12a5edf39db89 100644 GIT binary patch literal 35821 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 From 6dedfb58f1ed47f44aa8951b14ef7a989e27afeb Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 29 Oct 2023 12:27:20 +0800 Subject: [PATCH 254/518] Add hyperlink to DG acknowlegdements --- docs/DeveloperGuide.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 6df0a4e3ed..7516f3ec68 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -4,27 +4,27 @@ **Xchart (A Simple Charting Library for Java)** - author: KNOWN -- source: https://knowm.org/open-source/xchart/ +- source: [https://knowm.org/open-source/xchart/]() **JSON Simple (simple Java toolkit for encoding and decoding JSON)** - author: Yidong Fang (Google Code) -- source: https://code.google.com/archive/p/json-simple/ +- source: [https://code.google.com/archive/p/json-simple/]() **Apache Common Langs 3** - author: Apache Commons -- source: https://commons.apache.org/proper/commons-lang/ +- source: [https://commons.apache.org/proper/commons-lang/]() **Alpha Vantage Stock Market API** - author: Alpha Vantage -- source: https://www.alphavantage.co/ +- source: [https://www.alphavantage.co/]() **round() method in Cashflow.java** - author: mhadidg - - source: https://stackoverflow.com/questions/2808535/round-a-double-to-2-decimal-places + - source: [https://stackoverflow.com/questions/2808535/round-a-double-to-2-decimal-places]() **capitalize() method in Cashflow.java** - author: Nick Bolton - - source: https://stackoverflow.com/questions/1892765/how-to-capitalize-the-first-character-of-each-word-in-a-string + - source: [https://stackoverflow.com/questions/1892765/how-to-capitalize-the-first-character-of-each-word-in-a-string]() **DG adapted from** From 452525f3c8c4bb7261beff296d5d0791f25ad8b3 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 29 Oct 2023 12:52:46 +0800 Subject: [PATCH 255/518] Add recurring cashflow function --- .../financialplanner/cashflow/Cashflow.java | 19 ++++++++++++ .../financialplanner/cashflow/Expense.java | 9 ++++++ .../financialplanner/cashflow/Income.java | 9 ++++++ .../financialplanner/storage/LoadData.java | 31 ++++++++++++++++++- 4 files changed, 67 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/cashflow/Cashflow.java b/src/main/java/seedu/financialplanner/cashflow/Cashflow.java index 0d3ae1c04e..9e51af507e 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Cashflow.java +++ b/src/main/java/seedu/financialplanner/cashflow/Cashflow.java @@ -32,6 +32,9 @@ public Cashflow(double amount, int recur, String description, LocalDate date) { this.date = date; } + protected Cashflow() { + } + public static void clearBalance() { balance = 0; } @@ -93,6 +96,22 @@ public static double getBalance() { return balance; } + public int getRecur() { + return recur; + } + + public LocalDate getDate() { + return date; + } + + public void setDate(LocalDate date) { + this.date = date; + } + + public String getDescription() { + return description; + } + public String formatString() { String string; if (recur == 0) { diff --git a/src/main/java/seedu/financialplanner/cashflow/Expense.java b/src/main/java/seedu/financialplanner/cashflow/Expense.java index 0408595860..b97745a1d0 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Expense.java +++ b/src/main/java/seedu/financialplanner/cashflow/Expense.java @@ -20,6 +20,15 @@ public Expense(double amount, ExpenseType type, int recur, String description, L addExpenseValue(); } + public Expense(Expense expense) { + this.amount = expense.getAmount(); + this.recur = expense.getRecur(); + this.description = expense.getDescription(); + this.date = expense.getDate(); + this.type = expense.getExpenseType(); + addExpenseValue(); + } + @Override public ExpenseType getExpenseType() { return type; diff --git a/src/main/java/seedu/financialplanner/cashflow/Income.java b/src/main/java/seedu/financialplanner/cashflow/Income.java index 5c151c9f9c..9a25700e29 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Income.java +++ b/src/main/java/seedu/financialplanner/cashflow/Income.java @@ -20,6 +20,15 @@ public Income(double amount, IncomeType type, int recur, String description, Loc addIncomeValue(); } + public Income(Income income) { + this.amount = income.getAmount(); + this.recur = income.getRecur(); + this.description = income.getDescription(); + this.date = income.getDate(); + this.type = income.getIncomeType(); + addIncomeValue(); + } + @Override public IncomeType getIncomeType() { return type; diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 30f4ed9a6e..2d7d0c39c5 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -22,10 +22,12 @@ import java.util.Scanner; public abstract class LoadData { + protected static LocalDate currentDate = LocalDate.now(); private static final String FILE_PATH = "data/watchlist.txt"; private static final CashflowList cashflowList = CashflowList.getInstance(); private static final Ui ui = Ui.getInstance(); + public static void load(String filePath) throws FinancialPlannerException { try { Scanner inputFile = new Scanner(new FileReader(filePath)); @@ -38,6 +40,7 @@ public static void load(String filePath) throws FinancialPlannerException { String type = split[0].trim(); switch (type) { case "I": + // Fallthrough case "E": final Cashflow entry = getEntry(type, split); cashflowList.load(entry); @@ -48,9 +51,10 @@ public static void load(String filePath) throws FinancialPlannerException { default: throw new FinancialPlannerException("Error loading file"); } - } inputFile.close(); + + addRecurringCashflows(); } catch (IOException e) { ui.showMessage("File not found. Creating new file..."); } catch (ArrayIndexOutOfBoundsException | IllegalArgumentException | FinancialPlannerException e) { @@ -59,6 +63,31 @@ public static void load(String filePath) throws FinancialPlannerException { } } + private static void addRecurringCashflows() throws FinancialPlannerException { + ui.showMessage("Adding any recurring cashflows..."); + for (Cashflow cashflow : cashflowList.list) { + int recur = cashflow.getRecur(); + LocalDate dateOfAddition = cashflow.getDate(); + + if (recur > 0) { + dateOfAddition = dateOfAddition.plusDays(recur); + if (currentDate.isAfter(dateOfAddition)) { + Cashflow toAdd = null; + if (cashflow instanceof Income) { + toAdd = new Income((Income) cashflow); + } else if (cashflow instanceof Expense) { + toAdd = new Expense((Expense) cashflow); + } else { + throw new FinancialPlannerException("Error adding recurring cashflows"); + } + toAdd.setDate(dateOfAddition); + cashflowList.load(toAdd); + ui.printAddedCashflow(toAdd); + } + } + } + } + private static void handleCorruptedFile(String message) throws FinancialPlannerException { ui.showMessage("File appears to be corrupted. Do you want to create a new file? (Y/N)"); if (createNewFile()) { From eada3bc5138a8060034ab0eca3e3e83340af6bb7 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 29 Oct 2023 12:53:39 +0800 Subject: [PATCH 256/518] Update parameter name to chart for standardization --- .../seedu/financialplanner/visualisations/Visualizer.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java index 739c652cee..4171c7510c 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java @@ -20,9 +20,9 @@ public class Visualizer { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); - public static void displayChart(String chartType, Map cashFlowByCat, String type) + public static void displayChart(String chart, Map cashFlowByCat, String type) throws FinancialPlannerException { - switch (chartType) { + switch (chart) { case "pie": displayPieChart(cashFlowByCat, type); break; @@ -30,7 +30,7 @@ public static void displayChart(String chartType, Map cashFlowBy displayBarChart(cashFlowByCat, type); break; default: - throw new FinancialPlannerException(chartType + " Chart Type Not Found"); + throw new FinancialPlannerException(chart + " Chart Type Not Found"); } } From 876b05664326f560f0600b5f1c6c877a238a7deb Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 29 Oct 2023 12:53:53 +0800 Subject: [PATCH 257/518] Update diagrams to match code --- docs/diagrams/vis/visualisationClass.puml | 2 +- docs/images/vis/visualisationClass.png | Bin 35821 -> 35486 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/diagrams/vis/visualisationClass.puml b/docs/diagrams/vis/visualisationClass.puml index 1cb58967be..968e065e00 100644 --- a/docs/diagrams/vis/visualisationClass.puml +++ b/docs/diagrams/vis/visualisationClass.puml @@ -27,7 +27,7 @@ class Categorizer #HoneyDew { } class Visualizer #Beige { -+displayChart(chartType: String, cashFlowByCat: Map, type: String) ++displayChart(chart: String, cashFlowByCat: Map, type: String) + displayPieChart(cashFlowByCat: Map, type: String) + displayBarChart(cashFlowByCat: Map, type: String) } diff --git a/docs/images/vis/visualisationClass.png b/docs/images/vis/visualisationClass.png index 18b9672ec78e8966b5a1fabfe9a12a5edf39db89..aa1d03be018664b646c8c6ffe1d2214a0785d12c 100644 GIT binary patch literal 35486 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 z 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 Zh=yqjy0A!r7yJp45|e-VMdZzg{|7CGCVT(@ literal 35821 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 Date: Sun, 29 Oct 2023 12:54:16 +0800 Subject: [PATCH 258/518] Update UG for visualization feature and watchlist features --- docs/UserGuide.md | 71 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 4863be0e36..ea52bbe26c 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -13,6 +13,10 @@ * [Viewing budget](#viewing-budget-budget-view) * [Displaying Overview](#displaying-overview-overview) * [View Balance](#viewing-balance-balance) + * [WatchList](#viewing-watchlist-watchlist) + * [Adding Stock](#adding-stock-to-watchlist-addstock) + * [Deleting Stock](#deleting-budget-budget-delete) + * [Visualization](#Visualization) * [Exiting the program](#exiting-the-program-exit) * [Saving data](#saving-the-data) * [Loading data](#loading-the-data) @@ -154,6 +158,73 @@ Example output: Balance: 3790.00 ``` +### Viewing Watchlist: `watchlist` + +View your current watchlist with stocks that you are interested in + +Default watchlist: AAPL, GOOGL + +Format: `watchlist` + +Example of usage: `watchlist` + +Example of output: + +``` +Symbol Market Price Daily High Daily Low EquityName +AAPL NASDAQ 168.22 168.96 166.84 Apple Inc +GOOGL NASDAQ 122.17 123.31 120.2057 Alphabet Inc - Class A +GME NYSE 13.12 13.615 13.02 Gamestop Corporation - Class A +``` + +### Adding Stock to Watchlist: `addstock` + +Add a stock that you are interested in monitoring into your personal WatchList + +Format: `addstock /s STOCKCODE` + +Example of usage: `addstock /s META` + +Example of output: + +``` +You have successfully added: +Meta Platforms Inc - Class A +Use Watchlist to view it! +``` + +### Deleting Stock from Watchlist: `deletestock` + +Delete a stock that you are no longer interested in monitoring from your personal WatchList + +Format: `deletestock /s STOCKCODE` + +Example of usage: `deletestock /s META` + +Example of output: + +``` +You have successfully deleted: +Meta Platforms Inc - Class A +Use watchlist command to view updated Watchlist +``` + +### Visualizing your cashflow: `vis` + +Using this command to visualize your income or expenses in a pie chart or bar char + +Format: `vis /t TYPE /c TOOL` + +Example of usage: `vis /t income /c pie` + +Example of output: + +``` +Displaying piechart for expense +``` + +![](images/vis/visOutput.png) + ### Exiting the program: `exit` Exits the program. From 12b45c55eb06fbb16f038d7210d9203a8d1afb68 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 29 Oct 2023 14:57:13 +0800 Subject: [PATCH 259/518] Refactor code and add 2 additonal fields (last updated and last fetched) to watchlist --- .../commands/WatchListCommand.java | 2 +- .../financialplanner/investments/Stock.java | 20 ++++++ .../investments/WatchList.java | 61 ++++++++++++------- .../java/seedu/financialplanner/utils/Ui.java | 11 +++- 4 files changed, 69 insertions(+), 25 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java index ec87d51812..401d5195ed 100644 --- a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java @@ -26,7 +26,7 @@ public void execute() { ui.printWatchListHeader(); try { - watchList.fetchFMPStockPrices(); + watchList.getLatestWatchlistInfo(); logger.log(Level.INFO, "Printing watchlist"); ui.printStocksInfo(watchList); diff --git a/src/main/java/seedu/financialplanner/investments/Stock.java b/src/main/java/seedu/financialplanner/investments/Stock.java index bc49ce54b6..056282ad44 100644 --- a/src/main/java/seedu/financialplanner/investments/Stock.java +++ b/src/main/java/seedu/financialplanner/investments/Stock.java @@ -12,7 +12,9 @@ import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; +import java.sql.Timestamp; import java.time.Duration; +import java.util.Date; import java.util.logging.Level; import java.util.logging.Logger; @@ -24,6 +26,8 @@ public class Stock implements Serializable { private String price; private String dayHigh; private String dayLow; + private Date lastUpdated = null; + private long lastFetched = 0; public Stock(String symbol) throws FinancialPlannerException { this.symbol = symbol; @@ -125,4 +129,20 @@ public String getDayLow() { public void setDayLow(String dayLow) { this.dayLow = dayLow; } + + public Date getLastUpdated() { + return lastUpdated; + } + + public void setLastUpdated(Date lastUpdated) { + this.lastUpdated = lastUpdated; + } + + public long getLastFetched() { + return lastFetched; + } + + public void setLastFetched(long lastFetched) { + this.lastFetched = lastFetched; + } } diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index 448583e790..528f53f58c 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -14,6 +14,7 @@ import java.net.http.HttpResponse; import java.time.Duration; import java.util.ArrayList; +import java.util.Date; import java.util.logging.Level; import java.util.logging.Logger; @@ -51,7 +52,12 @@ public static WatchList getInstance() { return watchlist; } - public void fetchFMPStockPrices() throws FinancialPlannerException { + public void getLatestWatchlistInfo() throws FinancialPlannerException { + JSONArray JSONstocks = fetchFMPStockPrices(); + extractWatchlistInfoFromJSONArray(JSONstocks); + } + + public JSONArray fetchFMPStockPrices() throws FinancialPlannerException { if (stocks.isEmpty()) { throw new FinancialPlannerException("Empty Watchlist. Nothing to display..."); } @@ -86,11 +92,16 @@ public void fetchFMPStockPrices() throws FinancialPlannerException { throw new RuntimeException(e); } JSONArray ja = (JSONArray) obj; - if (ja.size() != stocks.size()) { + return ja; + } + + public void extractWatchlistInfoFromJSONArray(JSONArray JSONstocks) throws FinancialPlannerException { + if (JSONstocks.size() != stocks.size()) { throw new FinancialPlannerException("Error getting API info!"); } + long fetchTime = System.currentTimeMillis(); int i = 0; - for (Object jo : ja) { + for (Object jo : JSONstocks) { JSONObject stock = (JSONObject) jo; Stock stockLocal = stocks.get(i); @@ -102,11 +113,35 @@ public void fetchFMPStockPrices() throws FinancialPlannerException { continue; } - extractStockInfoFromJSON(stock, stockLocal); + extractStockInfoFromJSONObject(stock, stockLocal, fetchTime); i += 1; } } + public void extractStockInfoFromJSONObject(JSONObject stock, Stock stockLocal, long fetchTime) { + stockLocal.setLastFetched(fetchTime); + + String price = stock.get("price").toString(); + assert price != null; + stockLocal.setPrice(price); + + String exchange = stock.get("exchange").toString(); + assert exchange != null; + stockLocal.setExchange(exchange); + + String dayHigh = stock.get("dayHigh").toString(); + assert dayHigh != null; + stockLocal.setDayHigh(dayHigh); + + String dayLow = stock.get("dayLow").toString(); + assert dayLow != null; + stockLocal.setDayLow(dayLow); + + String timestamp = stock.get("timestamp").toString(); + long lastUpdated = Long.parseLong(timestamp) * 1000; + stockLocal.setLastUpdated(new Date(lastUpdated)); + } + public String addStock(String stockCode) throws FinancialPlannerException { if (stocks.size() >= 5) { throw new FinancialPlannerException("Watchlist is full (max 5). Delete a stock to add a new one"); @@ -138,24 +173,6 @@ public String deleteStock(String stockCode) throws FinancialPlannerException { return toBeRemoved.getStockName(); } - public void extractStockInfoFromJSON(JSONObject stock, Stock stockLocal) { - String price = stock.get("price").toString(); - assert price != null; - stockLocal.setPrice(price); - - String exchange = stock.get("exchange").toString(); - assert exchange != null; - stockLocal.setExchange(exchange); - - String dayHigh = stock.get("dayHigh").toString(); - assert dayHigh != null; - stockLocal.setDayHigh(dayHigh); - - String dayLow = stock.get("dayLow").toString(); - assert dayLow != null; - stockLocal.setDayLow(dayLow); - } - public int size() { return stocks.size(); } diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 1d49c658a9..cf31b1878b 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -6,6 +6,7 @@ import seedu.financialplanner.cashflow.Budget; import seedu.financialplanner.cashflow.Cashflow; +import java.text.SimpleDateFormat; import java.util.Scanner; import java.util.logging.Level; import java.util.logging.Logger; @@ -69,6 +70,9 @@ public void printWatchListHeader() { System.out.print(RED + "Daily Low" + RESET); System.out.print(" "); System.out.print("EquityName"); + System.out.print(" "); + System.out.print("Last Updated"); + System.out.print(" "); System.out.println(); } @@ -79,8 +83,11 @@ public void printStocksInfo(WatchList watchList) { String price = YELLOW + StringUtils.rightPad(stock.getPrice(), 10) + RESET; String dayHigh = GREEN + StringUtils.rightPad(stock.getDayHigh(), 15) + RESET; String dayLow = RED + StringUtils.rightPad(stock.getDayLow(), 14) + RESET; - String name = StringUtils.rightPad(stock.getStockName(), 10); - System.out.println(symbol + market + price + dayHigh + dayLow + name); + String name = StringUtils.rightPad(stock.getStockName(), 30); + String date = new SimpleDateFormat("E, MMM dd yyyy HH:mm:ss") + .format(stock.getLastUpdated()); + String lastUpdate = StringUtils.rightPad(date, 10); + System.out.println(symbol + market + price + dayHigh + dayLow + name + lastUpdate); } } From 57fc65e18f26ad8dec4f4a3f9efd395914a2b6a4 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 29 Oct 2023 15:29:42 +0800 Subject: [PATCH 260/518] Chang watchlist data structure to hashmap for easy access and exception handling --- .../investments/WatchList.java | 54 ++++++++----------- .../financialplanner/storage/LoadData.java | 7 +-- .../java/seedu/financialplanner/utils/Ui.java | 5 +- .../investments/WatchListTest.java | 8 +-- 4 files changed, 34 insertions(+), 40 deletions(-) diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index 528f53f58c..f044a9c738 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -15,13 +15,15 @@ import java.time.Duration; import java.util.ArrayList; import java.util.Date; +import java.util.HashMap; +import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; public class WatchList { private static WatchList watchlist = null; private static Logger logger = Logger.getLogger("Financial Planner Logger"); - private ArrayList stocks = null; + private HashMap stocks = null; private final String API_ENDPOINT = "https://financialmodelingprep.com/api/v3/quote/"; private final String API_KEY = "iFumtYryBCbHpS3sDqLdVKi2SdP63vSV"; @@ -34,11 +36,11 @@ private WatchList() { try { Stock apple = new Stock("AAPL"); assert apple.getSymbol() != null && apple.getStockName() != null; - stocks.add(apple); + stocks.put(apple.getSymbol(), apple); Stock google = new Stock("GOOGL"); assert google.getSymbol() != null && google.getStockName() != null; - stocks.add(google); + stocks.put(google.getSymbol(), google); } catch (FinancialPlannerException e) { System.out.println(e.getMessage()); @@ -65,8 +67,8 @@ public JSONArray fetchFMPStockPrices() throws FinancialPlannerException { HttpClient client = HttpClient.newHttpClient(); StringBuilder queryStocks = new StringBuilder(); assert !stocks.isEmpty(); - for (Stock stock : stocks) { - queryStocks.append(stock.toString()); + for (Map.Entry set : stocks.entrySet()) { + queryStocks.append(set.getKey()); } String requestURI = String.format("%s%s?apikey=%s", API_ENDPOINT, queryStocks, API_KEY); HttpRequest request = HttpRequest.newBuilder(URI.create(requestURI)) @@ -91,8 +93,7 @@ public JSONArray fetchFMPStockPrices() throws FinancialPlannerException { logger.log(Level.SEVERE, "Could not parse to JSON"); throw new RuntimeException(e); } - JSONArray ja = (JSONArray) obj; - return ja; + return (JSONArray) obj; } public void extractWatchlistInfoFromJSONArray(JSONArray JSONstocks) throws FinancialPlannerException { @@ -100,21 +101,12 @@ public void extractWatchlistInfoFromJSONArray(JSONArray JSONstocks) throws Finan throw new FinancialPlannerException("Error getting API info!"); } long fetchTime = System.currentTimeMillis(); - int i = 0; for (Object jo : JSONstocks) { JSONObject stock = (JSONObject) jo; - - Stock stockLocal = stocks.get(i); - - // Check if the JSONObject from response matches the stock in the stocks list using symbol - if (!stockLocal.getSymbol().equals(stock.get("symbol"))) { - i += 1; - logger.log(Level.WARNING, "Stocks matching error!"); - continue; + if (stocks.containsKey(stock.get("symbol").toString().toUpperCase())) { + Stock stockLocal = stocks.get(stock.get("symbol").toString().toUpperCase()); + extractStockInfoFromJSONObject(stock, stockLocal, fetchTime); } - - extractStockInfoFromJSONObject(stock, stockLocal, fetchTime); - i += 1; } } @@ -146,17 +138,15 @@ public String addStock(String stockCode) throws FinancialPlannerException { if (stocks.size() >= 5) { throw new FinancialPlannerException("Watchlist is full (max 5). Delete a stock to add a new one"); } - for (Stock stock: stocks) { - if (stockCode.equals(stock.getSymbol().toUpperCase())) { + if (stocks.containsKey(stockCode.toUpperCase())) { // should already be uppercase throw new FinancialPlannerException("Stock is already present in Watchlist. Use watchlist to view it!"); - } } - Stock newStock = null; + Stock newStock; newStock = new Stock(stockCode); assert newStock.getSymbol() != null && newStock.getStockName() != null; - stocks.add(newStock); + stocks.put(newStock.getSymbol(), newStock); return newStock.getStockName(); } @@ -164,13 +154,11 @@ public String deleteStock(String stockCode) throws FinancialPlannerException { if (stocks.isEmpty()) { throw new FinancialPlannerException("No stock in watchlist!"); } - Stock toBeRemoved = stocks - .stream() - .filter(stock -> stockCode.equals(stock.getSymbol())) - .findFirst() - .orElseThrow(() -> new FinancialPlannerException("Does not Exist in Watchlist")); - stocks.remove(toBeRemoved); - return toBeRemoved.getStockName(); + Stock removedStock = stocks.remove(stockCode.toUpperCase()); // should be uppercase already + if (removedStock == null) { + throw new FinancialPlannerException("Does not Exist in Watchlist"); + } + return removedStock.getStockName(); } public int size() { @@ -181,11 +169,11 @@ public Stock get(int index) { return stocks.get(index); } - public ArrayList getStocks() { + public HashMap getStocks() { return stocks; } - public void setStocks(ArrayList stocks) { + public void setStocks(HashMap stocks) { this.stocks = stocks; } } diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index e0e8515067..f7e1d2aaab 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -17,6 +17,7 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.util.ArrayList; +import java.util.HashMap; import java.util.Scanner; public abstract class LoadData { @@ -147,15 +148,15 @@ private static String getDescription(String[] split) { return description; } - public static ArrayList loadWatchList() { + public static HashMap loadWatchList() { Ui ui = Ui.getInstance(); - ArrayList stocksData = new ArrayList<>(); + HashMap stocksData = new HashMap<>(); try { ObjectInputStream watchListStocksInputStream = new ObjectInputStream( new FileInputStream(FILE_PATH) ); - stocksData = (ArrayList) watchListStocksInputStream.readObject(); + stocksData = (HashMap) watchListStocksInputStream.readObject(); watchListStocksInputStream.close(); } catch (StreamCorruptedException e) { ui.showMessage("Watchlist file corrupted.. Rebuilding"); diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index cf31b1878b..84886c4432 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -7,6 +7,7 @@ import seedu.financialplanner.cashflow.Cashflow; import java.text.SimpleDateFormat; +import java.util.Map; import java.util.Scanner; import java.util.logging.Level; import java.util.logging.Logger; @@ -77,7 +78,9 @@ public void printWatchListHeader() { } public void printStocksInfo(WatchList watchList) { - for (Stock stock: watchList.getStocks()) { + for (Map.Entry set : watchList.getStocks().entrySet()) { + Stock stock = set.getValue(); + String symbol = StringUtils.rightPad(stock.getSymbol(), 10); String market = StringUtils.rightPad(stock.getExchange(), 10); String price = YELLOW + StringUtils.rightPad(stock.getPrice(), 10) + RESET; diff --git a/src/test/java/seedu/financialplanner/investments/WatchListTest.java b/src/test/java/seedu/financialplanner/investments/WatchListTest.java index 6874a460d8..f5a41635e2 100644 --- a/src/test/java/seedu/financialplanner/investments/WatchListTest.java +++ b/src/test/java/seedu/financialplanner/investments/WatchListTest.java @@ -7,6 +7,7 @@ import seedu.financialplanner.exceptions.FinancialPlannerException; import java.util.ArrayList; +import java.util.HashMap; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -19,9 +20,10 @@ class WatchListTest { void fetchFMPStockPrices() throws FinancialPlannerException { WatchList wl = WatchList.getInstance(); wl.fetchFMPStockPrices(); - ArrayList stocks = wl.getStocks(); - assertNotNull(stocks.get(0).getPrice()); - assertNotNull(stocks.get(1).getPrice()); + HashMap stocks = wl.getStocks(); + assertNotNull(stocks.get("AAPL").getPrice()); + assertNotNull(stocks.get("GOOGL").getPrice()); + // Might need to update this test } @Test From 23f49b5022c4b5c357678720e93855eac0a406d2 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 29 Oct 2023 15:51:34 +0800 Subject: [PATCH 261/518] Add check for up to date stock to prevent overloading API --- .../investments/WatchList.java | 33 ++++++++++++------- .../investments/WatchListTest.java | 2 +- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index f044a9c738..bf2548b9fb 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -55,21 +55,32 @@ public static WatchList getInstance() { } public void getLatestWatchlistInfo() throws FinancialPlannerException { - JSONArray JSONstocks = fetchFMPStockPrices(); - extractWatchlistInfoFromJSONArray(JSONstocks); + StringBuilder queryStocks = getExpiredStocks(); + fetchFMPStockPrices(queryStocks); } - public JSONArray fetchFMPStockPrices() throws FinancialPlannerException { + public StringBuilder getExpiredStocks() { + StringBuilder queryStocks = new StringBuilder(); + long currentTime = System.currentTimeMillis(); + long fivemin = 300000; + for (Map.Entry set: stocks.entrySet()) { + if (set.getValue().getLastFetched() + fivemin < currentTime) { + queryStocks.append(set.getKey()); + } + } + return queryStocks; + } + + public void fetchFMPStockPrices(StringBuilder queryStocks) throws FinancialPlannerException { if (stocks.isEmpty()) { throw new FinancialPlannerException("Empty Watchlist. Nothing to display..."); } + if (queryStocks.toString().isEmpty()) { + // all stocks prices are up-to-date, just display + return; + } HttpClient client = HttpClient.newHttpClient(); - StringBuilder queryStocks = new StringBuilder(); - assert !stocks.isEmpty(); - for (Map.Entry set : stocks.entrySet()) { - queryStocks.append(set.getKey()); - } String requestURI = String.format("%s%s?apikey=%s", API_ENDPOINT, queryStocks, API_KEY); HttpRequest request = HttpRequest.newBuilder(URI.create(requestURI)) .header("accept", "application/json") @@ -93,12 +104,12 @@ public JSONArray fetchFMPStockPrices() throws FinancialPlannerException { logger.log(Level.SEVERE, "Could not parse to JSON"); throw new RuntimeException(e); } - return (JSONArray) obj; + extractWatchlistInfoFromJSONArray((JSONArray) obj); } public void extractWatchlistInfoFromJSONArray(JSONArray JSONstocks) throws FinancialPlannerException { - if (JSONstocks.size() != stocks.size()) { - throw new FinancialPlannerException("Error getting API info!"); + if (JSONstocks.isEmpty()) { + return; } long fetchTime = System.currentTimeMillis(); for (Object jo : JSONstocks) { diff --git a/src/test/java/seedu/financialplanner/investments/WatchListTest.java b/src/test/java/seedu/financialplanner/investments/WatchListTest.java index f5a41635e2..18c0cfd0ff 100644 --- a/src/test/java/seedu/financialplanner/investments/WatchListTest.java +++ b/src/test/java/seedu/financialplanner/investments/WatchListTest.java @@ -19,7 +19,7 @@ class WatchListTest { @Order(1) void fetchFMPStockPrices() throws FinancialPlannerException { WatchList wl = WatchList.getInstance(); - wl.fetchFMPStockPrices(); + wl.getLatestWatchlistInfo(); HashMap stocks = wl.getStocks(); assertNotNull(stocks.get("AAPL").getPrice()); assertNotNull(stocks.get("GOOGL").getPrice()); From 18197d715fbe34314eb6997aa20e65280dc5fc1b Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 29 Oct 2023 15:55:20 +0800 Subject: [PATCH 262/518] Remove todos that is completed --- src/main/java/seedu/financialplanner/investments/Stock.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/seedu/financialplanner/investments/Stock.java b/src/main/java/seedu/financialplanner/investments/Stock.java index 056282ad44..add05b24f5 100644 --- a/src/main/java/seedu/financialplanner/investments/Stock.java +++ b/src/main/java/seedu/financialplanner/investments/Stock.java @@ -64,11 +64,7 @@ public String getStockNameFromAPI(String symbol) throws FinancialPlannerExceptio } JSONObject stock = (JSONObject) ja.get(0); String symbolFound = (String) stock.get("1. symbol"); - // TODO: Might need to use AMEX when NYSE is used - // TODO: Need to check if it is added already - // TODO: add a cap to adding // TODO: Separate based on market - // TODO: add other info // TODO: testing if (!symbolFound.equals(symbol)) { throw new FinancialPlannerException("Stock not found"); From 7542fa0930f1f7a097542dd2e31baee63bc7811f Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 29 Oct 2023 16:07:08 +0800 Subject: [PATCH 263/518] Fix recur bug --- .../financialplanner/FinancialPlanner.java | 7 ++- .../financialplanner/storage/LoadData.java | 53 ++++++++++++------- .../financialplanner/storage/Storage.java | 5 +- .../java/seedu/financialplanner/utils/Ui.java | 5 +- 4 files changed, 46 insertions(+), 24 deletions(-) diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index 08d548f1da..dba440ff5a 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -8,7 +8,10 @@ import seedu.financialplanner.utils.Parser; import seedu.financialplanner.utils.Ui; +import java.time.LocalDate; + public class FinancialPlanner { + private static final LocalDate date = LocalDate.now(); private static final String FILE_PATH = "data/data.txt"; private final Storage storage = Storage.getInstance(); private final Ui ui = Ui.getInstance(); @@ -24,13 +27,13 @@ public static void main(String[] args) { public void run() { try { - storage.load(FILE_PATH); + storage.load(FILE_PATH, date); } catch (FinancialPlannerException e) { ui.showMessage(e.getMessage()); return; } - ui.welcomeMessage(); + ui.welcomeMessage(date); String input; Command command = null; diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 2d7d0c39c5..ce9d8425ee 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -22,13 +22,12 @@ import java.util.Scanner; public abstract class LoadData { - protected static LocalDate currentDate = LocalDate.now(); private static final String FILE_PATH = "data/watchlist.txt"; private static final CashflowList cashflowList = CashflowList.getInstance(); private static final Ui ui = Ui.getInstance(); - public static void load(String filePath) throws FinancialPlannerException { + public static void load(String filePath, LocalDate date) throws FinancialPlannerException { try { Scanner inputFile = new Scanner(new FileReader(filePath)); String line; @@ -54,7 +53,7 @@ public static void load(String filePath) throws FinancialPlannerException { } inputFile.close(); - addRecurringCashflows(); + addRecurringCashflows(date); } catch (IOException e) { ui.showMessage("File not found. Creating new file..."); } catch (ArrayIndexOutOfBoundsException | IllegalArgumentException | FinancialPlannerException e) { @@ -63,28 +62,44 @@ public static void load(String filePath) throws FinancialPlannerException { } } - private static void addRecurringCashflows() throws FinancialPlannerException { + private static void addRecurringCashflows(LocalDate currentDate) throws FinancialPlannerException { ui.showMessage("Adding any recurring cashflows..."); + ArrayList tempCashflow = new ArrayList<>(); for (Cashflow cashflow : cashflowList.list) { int recur = cashflow.getRecur(); LocalDate dateOfAddition = cashflow.getDate(); + addRecurringCashflowToTempList(currentDate, cashflow, recur, dateOfAddition, tempCashflow); + } + for (Cashflow cashflow : tempCashflow) { + cashflowList.load(cashflow); + ui.printAddedCashflow(cashflow); + } + } - if (recur > 0) { - dateOfAddition = dateOfAddition.plusDays(recur); - if (currentDate.isAfter(dateOfAddition)) { - Cashflow toAdd = null; - if (cashflow instanceof Income) { - toAdd = new Income((Income) cashflow); - } else if (cashflow instanceof Expense) { - toAdd = new Expense((Expense) cashflow); - } else { - throw new FinancialPlannerException("Error adding recurring cashflows"); - } - toAdd.setDate(dateOfAddition); - cashflowList.load(toAdd); - ui.printAddedCashflow(toAdd); - } + private static void addRecurringCashflowToTempList(LocalDate currentDate + , Cashflow cashflow, int recur, LocalDate dateOfAddition + , ArrayList tempCashflow) throws FinancialPlannerException { + if (recur > 0) { + dateOfAddition = dateOfAddition.plusDays(recur); + identifyRecurredCashflows(currentDate, cashflow, recur, dateOfAddition, tempCashflow); + } + } + + private static void identifyRecurredCashflows(LocalDate currentDate + , Cashflow cashflow, int recur, LocalDate dateOfAddition + , ArrayList tempCashflow) throws FinancialPlannerException { + while (currentDate.isAfter(dateOfAddition) || currentDate.isEqual(dateOfAddition)) { + Cashflow toAdd = null; + if (cashflow instanceof Income) { + toAdd = new Income((Income) cashflow); + } else if (cashflow instanceof Expense) { + toAdd = new Expense((Expense) cashflow); + } else { + throw new FinancialPlannerException("Error adding recurring cashflows"); } + toAdd.setDate(dateOfAddition); + tempCashflow.add(toAdd); + dateOfAddition = dateOfAddition.plusDays(recur); } } diff --git a/src/main/java/seedu/financialplanner/storage/Storage.java b/src/main/java/seedu/financialplanner/storage/Storage.java index b63b0d0c50..95eeaf7100 100644 --- a/src/main/java/seedu/financialplanner/storage/Storage.java +++ b/src/main/java/seedu/financialplanner/storage/Storage.java @@ -6,6 +6,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.time.LocalDate; public class Storage { private static Storage storage = null; @@ -29,8 +30,8 @@ public static Storage getInstance() { return storage; } - public void load(String filePath) throws FinancialPlannerException { - LoadData.load(filePath); + public void load(String filePath, LocalDate date) throws FinancialPlannerException { + LoadData.load(filePath, date); } public void save(String filePath) throws FinancialPlannerException { diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 1d49c658a9..decc6340e1 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -6,6 +6,8 @@ import seedu.financialplanner.cashflow.Budget; import seedu.financialplanner.cashflow.Cashflow; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; import java.util.Scanner; import java.util.logging.Level; import java.util.logging.Logger; @@ -45,7 +47,8 @@ public void showMessage(String message) { System.out.println(message); } - public void welcomeMessage() { + public void welcomeMessage(LocalDate date) { + System.out.println("Current date: " + date.format(DateTimeFormatter.ofPattern("MMM dd yyyy"))); showMessage("Welcome to your Financial Planner. Type something to get started."); } From af105fdae7094581e702c5e55582c73a280ac541 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 29 Oct 2023 16:07:21 +0800 Subject: [PATCH 264/518] Add JUnit tests for recur --- .../storage/LoadDataTest.java | 54 +++++++++++++++++++ .../financialplanner/storage/StorageTest.java | 7 +-- src/test/testData/TestData.txt | 3 ++ src/test/testData/ValidData.txt | 2 +- 4 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 src/test/java/seedu/financialplanner/storage/LoadDataTest.java create mode 100644 src/test/testData/TestData.txt diff --git a/src/test/java/seedu/financialplanner/storage/LoadDataTest.java b/src/test/java/seedu/financialplanner/storage/LoadDataTest.java new file mode 100644 index 0000000000..2e71ee62e7 --- /dev/null +++ b/src/test/java/seedu/financialplanner/storage/LoadDataTest.java @@ -0,0 +1,54 @@ +package seedu.financialplanner.storage; + +import org.junit.jupiter.api.Test; +import seedu.financialplanner.cashflow.CashflowList; +import seedu.financialplanner.cashflow.Expense; +import seedu.financialplanner.cashflow.Income; +import seedu.financialplanner.enumerations.ExpenseType; +import seedu.financialplanner.enumerations.IncomeType; +import seedu.financialplanner.exceptions.FinancialPlannerException; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; + +import static org.junit.jupiter.api.Assertions.assertEquals; + + +class LoadDataTest { + protected CashflowList cashflowList = CashflowList.getInstance(); + + @Test + void testLoad() throws FinancialPlannerException { + cashflowList.list.clear(); + LocalDate date = stringToDate("01/01/2023"); + date = date.plusDays(30); + LoadData.load("src/test/testData/TestData.txt", date); + String actual = cashflowList.getList(); + cashflowList.list.clear(); + getTestData(); + String expected = cashflowList.getList(); + assertEquals(expected, actual); + } + + @Test + void loadWatchList() { + } + private LocalDate stringToDate(String string) { + return LocalDate.parse(string, DateTimeFormatter.ofPattern("dd/MM/yyyy")); + } + private void getTestData() { + LocalDate date = stringToDate("01/01/2023"); + cashflowList.load(new Income(123.12, IncomeType.ALLOWANCE, 10, null, date)); + cashflowList.load(new Expense(100, ExpenseType.SHOPPING, 30, "shopee", date)); + + date = date.plusDays(10); + cashflowList.load(new Income(123.12, IncomeType.ALLOWANCE, 10, null, date)); + + date = date.plusDays(10); + cashflowList.load(new Income(123.12, IncomeType.ALLOWANCE, 10, null, date)); + + date = date.plusDays(10); + cashflowList.load(new Income(123.12, IncomeType.ALLOWANCE, 10, null, date)); + cashflowList.load(new Expense(100, ExpenseType.SHOPPING, 30, "shopee", date)); + } +} diff --git a/src/test/java/seedu/financialplanner/storage/StorageTest.java b/src/test/java/seedu/financialplanner/storage/StorageTest.java index 8e1f0b51bb..cfaeb4bd8c 100644 --- a/src/test/java/seedu/financialplanner/storage/StorageTest.java +++ b/src/test/java/seedu/financialplanner/storage/StorageTest.java @@ -14,6 +14,7 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.time.LocalDate; import java.util.Scanner; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -29,7 +30,7 @@ public class StorageTest { @Test public void loadValidData() throws FinancialPlannerException { cashflowList.list.clear(); - storage.load("src/test/testData/ValidData.txt"); + storage.load("src/test/testData/ValidData.txt", LocalDate.now()); String actual = cashflowList.getList(); cashflowList.list.clear(); getTestData(); @@ -43,7 +44,7 @@ public void loadInvalidData_userInputNo() { ByteArrayInputStream in = new ByteArrayInputStream("n".getBytes()); ui.setScanner(new Scanner(in)); assertThrows(FinancialPlannerException.class, - () -> storage.load("src/test/testData/InvalidData.txt")); + () -> storage.load("src/test/testData/InvalidData.txt", LocalDate.now())); } @Test @@ -63,6 +64,6 @@ public void saveNonExistentFile() { private void getTestData() { cashflowList.load(new Income(123.12, IncomeType.ALLOWANCE, 0, null)); - cashflowList.load(new Expense(100, ExpenseType.SHOPPING, 30, "shopee")); + cashflowList.load(new Expense(100, ExpenseType.SHOPPING, 0, "shopee")); } } diff --git a/src/test/testData/TestData.txt b/src/test/testData/TestData.txt new file mode 100644 index 0000000000..dc3cc9368e --- /dev/null +++ b/src/test/testData/TestData.txt @@ -0,0 +1,3 @@ +I | 123.12 | ALLOWANCE | 10 | 01/01/2023 +E | 100.0 | SHOPPING | 30 | 01/01/2023 | shopee +B | 0.0 | 0.0 \ No newline at end of file diff --git a/src/test/testData/ValidData.txt b/src/test/testData/ValidData.txt index d57f2a1793..f9a754ef9e 100644 --- a/src/test/testData/ValidData.txt +++ b/src/test/testData/ValidData.txt @@ -1,3 +1,3 @@ I | 123.12 | ALLOWANCE | 0 -E | 100.0 | SHOPPING | 30 | shopee +E | 100.0 | SHOPPING | 0 | shopee B | 0.0 | 0.0 \ No newline at end of file From a4a02044920878ea4ec1587b5b275dd8e7687071 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 29 Oct 2023 16:16:18 +0800 Subject: [PATCH 265/518] Fix bug and Fix checkstylemain --- .../seedu/financialplanner/investments/Stock.java | 5 ++--- .../financialplanner/investments/WatchList.java | 14 +++++++------- .../seedu/financialplanner/storage/LoadData.java | 1 - src/main/java/seedu/financialplanner/utils/Ui.java | 8 ++++---- 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/main/java/seedu/financialplanner/investments/Stock.java b/src/main/java/seedu/financialplanner/investments/Stock.java index add05b24f5..c064598ffd 100644 --- a/src/main/java/seedu/financialplanner/investments/Stock.java +++ b/src/main/java/seedu/financialplanner/investments/Stock.java @@ -12,7 +12,6 @@ import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; -import java.sql.Timestamp; import java.time.Duration; import java.util.Date; import java.util.logging.Level; @@ -20,6 +19,8 @@ public class Stock implements Serializable { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); + private static final String API_ENDPOINT = "https://www.alphavantage.co/query?function=SYMBOL_SEARCH&keywords="; + private static final String API_KEY = "LNKL0548PHY2F0QU"; private String symbol; private String exchange; private String stockName; @@ -39,8 +40,6 @@ public String getStockName() { } public String getStockNameFromAPI(String symbol) throws FinancialPlannerException { - final String API_ENDPOINT = "https://www.alphavantage.co/query?function=SYMBOL_SEARCH&keywords="; - final String API_KEY = "LNKL0548PHY2F0QU"; String requestURI = String.format("%s%s&apikey=%s", API_ENDPOINT,symbol,API_KEY); HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder(URI.create(requestURI)) diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index bf2548b9fb..81d2ab1a15 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -13,7 +13,6 @@ import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.time.Duration; -import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.Map; @@ -23,9 +22,9 @@ public class WatchList { private static WatchList watchlist = null; private static Logger logger = Logger.getLogger("Financial Planner Logger"); + private static final String API_ENDPOINT = "https://financialmodelingprep.com/api/v3/quote/"; + private static final String API_KEY = "iFumtYryBCbHpS3sDqLdVKi2SdP63vSV"; private HashMap stocks = null; - private final String API_ENDPOINT = "https://financialmodelingprep.com/api/v3/quote/"; - private final String API_KEY = "iFumtYryBCbHpS3sDqLdVKi2SdP63vSV"; private WatchList() { stocks = LoadData.loadWatchList(); @@ -66,6 +65,7 @@ public StringBuilder getExpiredStocks() { for (Map.Entry set: stocks.entrySet()) { if (set.getValue().getLastFetched() + fivemin < currentTime) { queryStocks.append(set.getKey()); + queryStocks.append(","); } } return queryStocks; @@ -107,12 +107,12 @@ public void fetchFMPStockPrices(StringBuilder queryStocks) throws FinancialPlann extractWatchlistInfoFromJSONArray((JSONArray) obj); } - public void extractWatchlistInfoFromJSONArray(JSONArray JSONstocks) throws FinancialPlannerException { - if (JSONstocks.isEmpty()) { + public void extractWatchlistInfoFromJSONArray(JSONArray jsonstocks) throws FinancialPlannerException { + if (jsonstocks.isEmpty()) { return; } long fetchTime = System.currentTimeMillis(); - for (Object jo : JSONstocks) { + for (Object jo : jsonstocks) { JSONObject stock = (JSONObject) jo; if (stocks.containsKey(stock.get("symbol").toString().toUpperCase())) { Stock stockLocal = stocks.get(stock.get("symbol").toString().toUpperCase()); @@ -150,7 +150,7 @@ public String addStock(String stockCode) throws FinancialPlannerException { throw new FinancialPlannerException("Watchlist is full (max 5). Delete a stock to add a new one"); } if (stocks.containsKey(stockCode.toUpperCase())) { // should already be uppercase - throw new FinancialPlannerException("Stock is already present in Watchlist. Use watchlist to view it!"); + throw new FinancialPlannerException("Stock is already present in Watchlist. Use watchlist to view it!"); } Stock newStock; diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index f7e1d2aaab..9fb3a77531 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -16,7 +16,6 @@ import java.io.FileReader; import java.io.IOException; import java.io.ObjectInputStream; -import java.util.ArrayList; import java.util.HashMap; import java.util.Scanner; diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 84886c4432..d8cc620936 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -15,10 +15,10 @@ public class Ui { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private static Ui ui = null; - private final String RED = "\u001B[31m"; - private final String GREEN = "\u001B[32m"; - private final String RESET = "\u001B[0m"; - private final String YELLOW = "\u001B[33m"; + private static final String RED = "\u001B[31m"; + private static final String GREEN = "\u001B[32m"; + private static final String RESET = "\u001B[0m"; + private static final String YELLOW = "\u001B[33m"; private Scanner Scanner = new Scanner(System.in); private Ui() { } From 22dee000f82c19accb5f7c4c8fe5758571d76ba2 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 29 Oct 2023 16:19:13 +0800 Subject: [PATCH 266/518] Fix Typo and description --- docs/UserGuide.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index ea52bbe26c..d898dde525 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -160,7 +160,7 @@ Balance: 3790.00 ### Viewing Watchlist: `watchlist` -View your current watchlist with stocks that you are interested in +View your current watchlist with stocks that you are interested in with the exchanges shown as well Default watchlist: AAPL, GOOGL @@ -211,7 +211,7 @@ Use watchlist command to view updated Watchlist ### Visualizing your cashflow: `vis` -Using this command to visualize your income or expenses in a pie chart or bar char +Using this command to visualize your income or expenses in a pie chart or bar chart Format: `vis /t TYPE /c TOOL` From 3ea07df65421c3d8cce2b46e0c6196bb7614c89b Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 29 Oct 2023 16:20:39 +0800 Subject: [PATCH 267/518] Remove unused import --- .../java/seedu/financialplanner/investments/WatchListTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/seedu/financialplanner/investments/WatchListTest.java b/src/test/java/seedu/financialplanner/investments/WatchListTest.java index 18c0cfd0ff..e19312459a 100644 --- a/src/test/java/seedu/financialplanner/investments/WatchListTest.java +++ b/src/test/java/seedu/financialplanner/investments/WatchListTest.java @@ -6,7 +6,6 @@ import org.junit.jupiter.api.TestMethodOrder; import seedu.financialplanner.exceptions.FinancialPlannerException; -import java.util.ArrayList; import java.util.HashMap; import static org.junit.jupiter.api.Assertions.assertNotNull; From cb04c333db694ebc347c87cfd95456b18cf47994 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 29 Oct 2023 17:32:51 +0800 Subject: [PATCH 268/518] Add delete future cashflow function --- .../financialplanner/storage/LoadData.java | 25 ++++++++++++++++++- .../storage/LoadDataTest.java | 1 + 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index ce9d8425ee..a6ad43e592 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -52,7 +52,7 @@ public static void load(String filePath, LocalDate date) throws FinancialPlanner } } inputFile.close(); - + deleteFutureCashflows(date); addRecurringCashflows(date); } catch (IOException e) { ui.showMessage("File not found. Creating new file..."); @@ -62,6 +62,29 @@ public static void load(String filePath, LocalDate date) throws FinancialPlanner } } + private static void deleteFutureCashflows(LocalDate currentDate) { + ArrayList tempCashflow = new ArrayList<>(); + int indexToDelete = 0; + for (Cashflow cashflow : cashflowList.list) { + int recur = cashflow.getRecur(); + LocalDate dateOfAddition = cashflow.getDate(); + if (recur > 0 && currentDate.isBefore(dateOfAddition)) { + Integer integer = indexToDelete; + tempCashflow.add(integer); + } + indexToDelete++; + } + if (!tempCashflow.isEmpty()) { + ui.showMessage("Cashflows added after system time detected. Removing future cashflows..."); + for (int i = 0; i < tempCashflow.size(); i++) { + indexToDelete = tempCashflow.get(i) - i; + // deleteCashflowWithoutCategory takes in list index starting from 1, indexToDelete starts from 0 + int indexStartingFromOne = indexToDelete + 1; + cashflowList.deleteCashflowWithoutCategory(indexStartingFromOne); + } + } + } + private static void addRecurringCashflows(LocalDate currentDate) throws FinancialPlannerException { ui.showMessage("Adding any recurring cashflows..."); ArrayList tempCashflow = new ArrayList<>(); diff --git a/src/test/java/seedu/financialplanner/storage/LoadDataTest.java b/src/test/java/seedu/financialplanner/storage/LoadDataTest.java index 2e71ee62e7..eba079d95d 100644 --- a/src/test/java/seedu/financialplanner/storage/LoadDataTest.java +++ b/src/test/java/seedu/financialplanner/storage/LoadDataTest.java @@ -39,6 +39,7 @@ private LocalDate stringToDate(String string) { private void getTestData() { LocalDate date = stringToDate("01/01/2023"); cashflowList.load(new Income(123.12, IncomeType.ALLOWANCE, 10, null, date)); + cashflowList.load(new Income(123.12, IncomeType.ALLOWANCE, 0, "parents", date)); cashflowList.load(new Expense(100, ExpenseType.SHOPPING, 30, "shopee", date)); date = date.plusDays(10); From 2b5413510bc053b083b709c13901f1d9559ab68e Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 29 Oct 2023 17:32:59 +0800 Subject: [PATCH 269/518] Update JUnit test --- src/test/testData/TestData.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test/testData/TestData.txt b/src/test/testData/TestData.txt index dc3cc9368e..f66d8f2e24 100644 --- a/src/test/testData/TestData.txt +++ b/src/test/testData/TestData.txt @@ -1,3 +1,7 @@ I | 123.12 | ALLOWANCE | 10 | 01/01/2023 +I | 123.12 | ALLOWANCE | 0 | parents E | 100.0 | SHOPPING | 30 | 01/01/2023 | shopee +I | 123.12 | ALLOWANCE | 10 | 01/02/2023 +I | 123.12 | ALLOWANCE | 10 | 01/03/2023 +I | 123.12 | ALLOWANCE | 10 | 01/04/2023 B | 0.0 | 0.0 \ No newline at end of file From a03910018423fddc74ad56eac3bcedcf42b29efb Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 29 Oct 2023 17:55:30 +0800 Subject: [PATCH 270/518] Add exception for error in parsing date --- .../java/seedu/financialplanner/storage/LoadData.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index a6ad43e592..8046578850 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -18,6 +18,7 @@ import java.io.ObjectInputStream; import java.time.LocalDate; import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; import java.util.ArrayList; import java.util.Scanner; @@ -56,7 +57,7 @@ public static void load(String filePath, LocalDate date) throws FinancialPlanner addRecurringCashflows(date); } catch (IOException e) { ui.showMessage("File not found. Creating new file..."); - } catch (ArrayIndexOutOfBoundsException | IllegalArgumentException | FinancialPlannerException e) { + } catch (IndexOutOfBoundsException | IllegalArgumentException | FinancialPlannerException e) { String message = e.getMessage(); handleCorruptedFile(message); } @@ -178,7 +179,11 @@ private static Cashflow getEntry(String type, String[] split) case "I": value = Double.parseDouble(split[1].trim()); recur = Integer.parseInt(split[3].trim()); - date = getDate(split, recur); + try { + date = getDate(split, recur); + } catch (DateTimeParseException e) { + throw new FinancialPlannerException("Error in parsing date"); + } index = getIndex(recur); description = getDescription(split, index); checkValidInput(value, recur); @@ -208,7 +213,6 @@ private static Cashflow getEntry(String type, String[] split) default: throw new FinancialPlannerException("Error loading file"); } - return entry; } From 0defa4994e9c06827a4a49ee850f129434738510 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 29 Oct 2023 17:57:56 +0800 Subject: [PATCH 271/518] Update text ui test --- text-ui-test/EXPECTED.TXT | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 25ddd7bb78..eb1bfd89a1 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -2,11 +2,12 @@ Directory doesn't exist. Creating directory... Watchlist file not found... Creating Initializing New watchlist.. adding AAPL and GOOGL for your reference File not found. Creating new file... +Current date: Oct 29 2023 Welcome to your Financial Planner. Type something to get started. You have added an Income Type: Salary Amount: 5000.00 - Recurring every: 30 days + Recurring every: 30 days, starting from: Oct 29 2023 Description: part time job to the Financial Planner. Balance: 5000.00 @@ -18,7 +19,7 @@ Balance: 5123.12 You have added an Expense Type: Entertainment Amount: 100.00 - Recurring every: 30 days + Recurring every: 30 days, starting from: Oct 29 2023 Description: netflix to the Financial Planner. Balance: 5023.12 @@ -35,7 +36,7 @@ Balance: 4776.79 You have removed an Income Type: Salary Amount: 5000.00 - Recurring every: 30 days + Recurring every: 30 days, starting from: Oct 29 2023 Description: part time job from the Financial Planner. Balance: -223.21 @@ -47,7 +48,7 @@ Balance: -100.00 You have removed an Expense Type: Entertainment Amount: 100.00 - Recurring every: 30 days + Recurring every: 30 days, starting from: Oct 29 2023 Description: netflix from the Financial Planner. Balance: 0.00 @@ -60,7 +61,7 @@ Use Watchlist to view it! You have added an Income Type: Salary Amount: 5000.00 - Recurring every: 30 days + Recurring every: 30 days, starting from: Oct 29 2023 to the Financial Planner. Balance: 5000.00 A monthly budget of 3000.00 has been set. From 73157cd084b48382b033d78a3761bbf46a49c5fc Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 29 Oct 2023 18:06:32 +0800 Subject: [PATCH 272/518] Remove redundant statement --- src/main/java/seedu/financialplanner/storage/LoadData.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 8046578850..8e2fd87ae7 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -113,7 +113,7 @@ private static void identifyRecurredCashflows(LocalDate currentDate , Cashflow cashflow, int recur, LocalDate dateOfAddition , ArrayList tempCashflow) throws FinancialPlannerException { while (currentDate.isAfter(dateOfAddition) || currentDate.isEqual(dateOfAddition)) { - Cashflow toAdd = null; + Cashflow toAdd; if (cashflow instanceof Income) { toAdd = new Income((Income) cashflow); } else if (cashflow instanceof Expense) { From 8ecb91b4d6e3961a000d8d81cf874438da9c09cb Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 29 Oct 2023 21:58:34 +0800 Subject: [PATCH 273/518] Fix missing try-catch and replace ui message --- .../seedu/financialplanner/storage/LoadData.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 8e2fd87ae7..adbec9d6ce 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -57,7 +57,8 @@ public static void load(String filePath, LocalDate date) throws FinancialPlanner addRecurringCashflows(date); } catch (IOException e) { ui.showMessage("File not found. Creating new file..."); - } catch (IndexOutOfBoundsException | IllegalArgumentException | FinancialPlannerException e) { + } catch (IndexOutOfBoundsException | IllegalArgumentException + | FinancialPlannerException | DateTimeParseException e) { String message = e.getMessage(); handleCorruptedFile(message); } @@ -76,7 +77,7 @@ private static void deleteFutureCashflows(LocalDate currentDate) { indexToDelete++; } if (!tempCashflow.isEmpty()) { - ui.showMessage("Cashflows added after system time detected. Removing future cashflows..."); + ui.showMessage("Detected erroneous cashflow entries. Removing future cashflows..."); for (int i = 0; i < tempCashflow.size(); i++) { indexToDelete = tempCashflow.get(i) - i; // deleteCashflowWithoutCategory takes in list index starting from 1, indexToDelete starts from 0 @@ -167,7 +168,7 @@ private static boolean createNewFile() { } private static Cashflow getEntry(String type, String[] split) - throws FinancialPlannerException, IllegalArgumentException { + throws FinancialPlannerException, IllegalArgumentException, DateTimeParseException { double value; int recur; int index; @@ -179,11 +180,7 @@ private static Cashflow getEntry(String type, String[] split) case "I": value = Double.parseDouble(split[1].trim()); recur = Integer.parseInt(split[3].trim()); - try { - date = getDate(split, recur); - } catch (DateTimeParseException e) { - throw new FinancialPlannerException("Error in parsing date"); - } + date = getDate(split, recur); index = getIndex(recur); description = getDescription(split, index); checkValidInput(value, recur); From 6616773df5f34ae6a6d64e9510e2a2de46787f9f Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 29 Oct 2023 23:24:09 +0800 Subject: [PATCH 274/518] Fix add recur bug --- .../financialplanner/cashflow/Cashflow.java | 16 +++++- .../financialplanner/cashflow/Expense.java | 5 +- .../financialplanner/cashflow/Income.java | 4 +- .../financialplanner/storage/LoadData.java | 53 ++++++++++--------- 4 files changed, 47 insertions(+), 31 deletions(-) diff --git a/src/main/java/seedu/financialplanner/cashflow/Cashflow.java b/src/main/java/seedu/financialplanner/cashflow/Cashflow.java index 9e51af507e..f5fa352d46 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Cashflow.java +++ b/src/main/java/seedu/financialplanner/cashflow/Cashflow.java @@ -16,6 +16,7 @@ public abstract class Cashflow { protected int recur; protected String description; protected LocalDate date; + protected boolean hasRecurred; public Cashflow(double amount, int recur, String description) { this.amount = amount; @@ -24,12 +25,14 @@ public Cashflow(double amount, int recur, String description) { if (recur != 0) { this.date = LocalDate.now(); } + this.hasRecurred = false; } - public Cashflow(double amount, int recur, String description, LocalDate date) { + public Cashflow(double amount, int recur, String description, LocalDate date, boolean hasRecurred) { this.amount = amount; this.recur = recur; this.description = description; this.date = date; + this.hasRecurred = hasRecurred; } protected Cashflow() { @@ -108,6 +111,14 @@ public void setDate(LocalDate date) { this.date = date; } + public boolean isHasRecurred() { + return hasRecurred; + } + + public void setHasRecurred(boolean hasRecurred) { + this.hasRecurred = hasRecurred; + } + public String getDescription() { return description; } @@ -115,9 +126,10 @@ public String getDescription() { public String formatString() { String string; if (recur == 0) { - string = " | 0"; + string = " | 0 | false"; } else { string = " | " + this.recur + " | " + date.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")); + string += " | " + this.hasRecurred; } if (description != null) { string += " | " + this.description; diff --git a/src/main/java/seedu/financialplanner/cashflow/Expense.java b/src/main/java/seedu/financialplanner/cashflow/Expense.java index b97745a1d0..28ef941cef 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Expense.java +++ b/src/main/java/seedu/financialplanner/cashflow/Expense.java @@ -14,8 +14,9 @@ public Expense(double amount, ExpenseType type, int recur, String description) { addExpenseValue(); } - public Expense(double amount, ExpenseType type, int recur, String description, LocalDate date) { - super(amount, recur, description, date); + public Expense(double amount, ExpenseType type, int recur, + String description, LocalDate date, boolean hasRecurred) { + super(amount, recur, description, date, hasRecurred); this.type = type; addExpenseValue(); } diff --git a/src/main/java/seedu/financialplanner/cashflow/Income.java b/src/main/java/seedu/financialplanner/cashflow/Income.java index 9a25700e29..1ba3697762 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Income.java +++ b/src/main/java/seedu/financialplanner/cashflow/Income.java @@ -14,8 +14,8 @@ public Income(double amount, IncomeType type, int recur, String description) { addIncomeValue(); } - public Income(double amount, IncomeType type, int recur, String description, LocalDate date) { - super(amount, recur, description, date); + public Income(double amount, IncomeType type, int recur, String description, LocalDate date, boolean hasRecurred) { + super(amount, recur, description, date, hasRecurred); this.type = type; addIncomeValue(); } diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index adbec9d6ce..b6a11e5f1a 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -93,7 +93,8 @@ private static void addRecurringCashflows(LocalDate currentDate) throws Financia for (Cashflow cashflow : cashflowList.list) { int recur = cashflow.getRecur(); LocalDate dateOfAddition = cashflow.getDate(); - addRecurringCashflowToTempList(currentDate, cashflow, recur, dateOfAddition, tempCashflow); + boolean hasRecurred = cashflow.isHasRecurred(); + addRecurringCashflowToTempList(currentDate, cashflow, recur, dateOfAddition, tempCashflow, hasRecurred); } for (Cashflow cashflow : tempCashflow) { cashflowList.load(cashflow); @@ -103,8 +104,8 @@ private static void addRecurringCashflows(LocalDate currentDate) throws Financia private static void addRecurringCashflowToTempList(LocalDate currentDate , Cashflow cashflow, int recur, LocalDate dateOfAddition - , ArrayList tempCashflow) throws FinancialPlannerException { - if (recur > 0) { + , ArrayList tempCashflow, boolean hasRecurred) throws FinancialPlannerException { + if (recur > 0 && !hasRecurred) { dateOfAddition = dateOfAddition.plusDays(recur); identifyRecurredCashflows(currentDate, cashflow, recur, dateOfAddition, tempCashflow); } @@ -114,6 +115,7 @@ private static void identifyRecurredCashflows(LocalDate currentDate , Cashflow cashflow, int recur, LocalDate dateOfAddition , ArrayList tempCashflow) throws FinancialPlannerException { while (currentDate.isAfter(dateOfAddition) || currentDate.isEqual(dateOfAddition)) { + cashflow.setHasRecurred(true); Cashflow toAdd; if (cashflow instanceof Income) { toAdd = new Income((Income) cashflow); @@ -124,6 +126,7 @@ private static void identifyRecurredCashflows(LocalDate currentDate } toAdd.setDate(dateOfAddition); tempCashflow.add(toAdd); + cashflow = toAdd; dateOfAddition = dateOfAddition.plusDays(recur); } } @@ -169,43 +172,33 @@ private static boolean createNewFile() { private static Cashflow getEntry(String type, String[] split) throws FinancialPlannerException, IllegalArgumentException, DateTimeParseException { - double value; - int recur; - int index; - LocalDate date; Cashflow entry; - String description; + double value = Double.parseDouble(split[1].trim()); + int recur = Integer.parseInt(split[3].trim()); + boolean hasRecurred = getHasRecurred(split, recur); + LocalDate date = getDate(split, recur); + int index = getIndex(recur); + String description = getDescription(split, index); + checkValidInput(value, recur); switch (type) { case "I": - value = Double.parseDouble(split[1].trim()); - recur = Integer.parseInt(split[3].trim()); - date = getDate(split, recur); - index = getIndex(recur); - description = getDescription(split, index); - checkValidInput(value, recur); IncomeType incomeType; try { incomeType = IncomeType.valueOf(split[2].trim().toUpperCase()); } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Invalid income type"); } - entry = new Income(value, incomeType, recur, description, date); + entry = new Income(value, incomeType, recur, description, date, hasRecurred); break; case "E": - value = Double.parseDouble(split[1].trim()); - recur = Integer.parseInt(split[3].trim()); - date = getDate(split, recur); - index = getIndex(recur); - description = getDescription(split, index); - checkValidInput(value, recur); ExpenseType expenseType; try { expenseType = ExpenseType.valueOf(split[2].trim().toUpperCase()); } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Invalid expense type"); } - entry = new Expense(value, expenseType, recur, description, date); + entry = new Expense(value, expenseType, recur, description, date, hasRecurred); break; default: throw new FinancialPlannerException("Error loading file"); @@ -213,10 +206,20 @@ private static Cashflow getEntry(String type, String[] split) return entry; } + private static boolean getHasRecurred(String[] split, int recur) { + boolean hasRecurred; + if (recur != 0) { + hasRecurred = Boolean.parseBoolean(split[4].trim()); + } else { + hasRecurred = false; + } + return hasRecurred; + } + private static LocalDate getDate(String[] split, int recur) { LocalDate date; if (recur != 0) { - date = LocalDate.parse(split[4].trim(), DateTimeFormatter.ofPattern("dd/MM/yyyy")); + date = LocalDate.parse(split[5].trim(), DateTimeFormatter.ofPattern("dd/MM/yyyy")); } else { date = null; } @@ -225,8 +228,8 @@ private static LocalDate getDate(String[] split, int recur) { private static int getIndex(int recur) { int index; - if (recur == 0) { - index = 4; + if (recur != 0) { + index = 6; } else { index = 5; } From ffb79fe43eb4baacdaeb3c69fbfbe997e6c9bb70 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 29 Oct 2023 23:24:18 +0800 Subject: [PATCH 275/518] Update JUnit tests --- .../storage/LoadDataTest.java | 22 +++++++++++++------ src/test/testData/TestData.txt | 14 +++++++----- src/test/testData/ValidData.txt | 4 ++-- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/test/java/seedu/financialplanner/storage/LoadDataTest.java b/src/test/java/seedu/financialplanner/storage/LoadDataTest.java index eba079d95d..180889048f 100644 --- a/src/test/java/seedu/financialplanner/storage/LoadDataTest.java +++ b/src/test/java/seedu/financialplanner/storage/LoadDataTest.java @@ -38,18 +38,26 @@ private LocalDate stringToDate(String string) { } private void getTestData() { LocalDate date = stringToDate("01/01/2023"); - cashflowList.load(new Income(123.12, IncomeType.ALLOWANCE, 10, null, date)); - cashflowList.load(new Income(123.12, IncomeType.ALLOWANCE, 0, "parents", date)); - cashflowList.load(new Expense(100, ExpenseType.SHOPPING, 30, "shopee", date)); + cashflowList.load(new Income(123.12, IncomeType.ALLOWANCE, 10, null, date, false)); + cashflowList.load(new Income(123.12, IncomeType.ALLOWANCE, 0, "parents", date, false)); + cashflowList.load(new Expense(100, ExpenseType.SHOPPING, 30, "shopee", date, false)); + cashflowList.load(new Expense(100, ExpenseType.INSURANCE, 10, "ntuc", date, true)); date = date.plusDays(10); - cashflowList.load(new Income(123.12, IncomeType.ALLOWANCE, 10, null, date)); + cashflowList.load(new Expense(100, ExpenseType.INSURANCE, 10, "ntuc", date, false)); + cashflowList.load(new Income(123.12, IncomeType.ALLOWANCE, 10, null, date, false)); date = date.plusDays(10); - cashflowList.load(new Income(123.12, IncomeType.ALLOWANCE, 10, null, date)); + cashflowList.load(new Income(123.12, IncomeType.ALLOWANCE, 10, null, date, false)); date = date.plusDays(10); - cashflowList.load(new Income(123.12, IncomeType.ALLOWANCE, 10, null, date)); - cashflowList.load(new Expense(100, ExpenseType.SHOPPING, 30, "shopee", date)); + cashflowList.load(new Income(123.12, IncomeType.ALLOWANCE, 10, null, date, false)); + cashflowList.load(new Expense(100, ExpenseType.SHOPPING, 30, "shopee", date, false)); + + date = stringToDate("21/01/2023"); + cashflowList.load(new Expense(100, ExpenseType.INSURANCE, 10, "ntuc", date, false)); + + date = date.plusDays(10); + cashflowList.load(new Expense(100, ExpenseType.INSURANCE, 10, "ntuc", date, false)); } } diff --git a/src/test/testData/TestData.txt b/src/test/testData/TestData.txt index f66d8f2e24..5df1e14b36 100644 --- a/src/test/testData/TestData.txt +++ b/src/test/testData/TestData.txt @@ -1,7 +1,9 @@ -I | 123.12 | ALLOWANCE | 10 | 01/01/2023 -I | 123.12 | ALLOWANCE | 0 | parents -E | 100.0 | SHOPPING | 30 | 01/01/2023 | shopee -I | 123.12 | ALLOWANCE | 10 | 01/02/2023 -I | 123.12 | ALLOWANCE | 10 | 01/03/2023 -I | 123.12 | ALLOWANCE | 10 | 01/04/2023 +I | 123.12 | ALLOWANCE | 10 | false | 01/01/2023 +I | 123.12 | ALLOWANCE | 0 | false | parents +E | 100.0 | SHOPPING | 30 | false | 01/01/2023 | shopee +E | 100.0 | INSURANCE | 10 | true | 01/01/2023 | ntuc +E | 100.0 | INSURANCE | 10 | false | 11/01/2023 | ntuc +I | 123.12 | ALLOWANCE | 10 | false | 01/02/2023 +I | 123.12 | ALLOWANCE | 10 | false | 01/03/2023 +I | 123.12 | ALLOWANCE | 10 | false | 01/04/2023 B | 0.0 | 0.0 \ No newline at end of file diff --git a/src/test/testData/ValidData.txt b/src/test/testData/ValidData.txt index f9a754ef9e..f6e30ed6e8 100644 --- a/src/test/testData/ValidData.txt +++ b/src/test/testData/ValidData.txt @@ -1,3 +1,3 @@ -I | 123.12 | ALLOWANCE | 0 -E | 100.0 | SHOPPING | 0 | shopee +I | 123.12 | ALLOWANCE | 0 | false +E | 100.0 | SHOPPING | 0 | false | shopee B | 0.0 | 0.0 \ No newline at end of file From 679b5df76c08b19fb69d2a7975dcf13e08340cc2 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 30 Oct 2023 00:04:47 +0800 Subject: [PATCH 276/518] Fix bug in formatting cashflow for storage --- src/main/java/seedu/financialplanner/cashflow/Cashflow.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/cashflow/Cashflow.java b/src/main/java/seedu/financialplanner/cashflow/Cashflow.java index f5fa352d46..9783c3877e 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Cashflow.java +++ b/src/main/java/seedu/financialplanner/cashflow/Cashflow.java @@ -128,8 +128,8 @@ public String formatString() { if (recur == 0) { string = " | 0 | false"; } else { - string = " | " + this.recur + " | " + date.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")); - string += " | " + this.hasRecurred; + string = " | " + this.recur + " | " + " | " + this.hasRecurred; + string += date.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")); } if (description != null) { string += " | " + this.description; From 085de5a87e4e627a0e51a1c4b05e188f0faede6e Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 30 Oct 2023 00:05:12 +0800 Subject: [PATCH 277/518] Add more exception messages in LoadData --- .../financialplanner/storage/LoadData.java | 72 ++++++++++--------- 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index b6a11e5f1a..47721525ea 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -57,10 +57,12 @@ public static void load(String filePath, LocalDate date) throws FinancialPlanner addRecurringCashflows(date); } catch (IOException e) { ui.showMessage("File not found. Creating new file..."); - } catch (IndexOutOfBoundsException | IllegalArgumentException - | FinancialPlannerException | DateTimeParseException e) { - String message = e.getMessage(); - handleCorruptedFile(message); + } catch (IndexOutOfBoundsException e) { + handleCorruptedFile("Empty/Missing arguments detected"); + } catch (IllegalArgumentException | FinancialPlannerException e) { + handleCorruptedFile(e.getMessage()); + } catch (DateTimeParseException e) { + handleCorruptedFile("Erroneous date format or Wrong position of date detected"); } } @@ -171,45 +173,47 @@ private static boolean createNewFile() { } private static Cashflow getEntry(String type, String[] split) - throws FinancialPlannerException, IllegalArgumentException, DateTimeParseException { - Cashflow entry; - double value = Double.parseDouble(split[1].trim()); - int recur = Integer.parseInt(split[3].trim()); - boolean hasRecurred = getHasRecurred(split, recur); - LocalDate date = getDate(split, recur); - int index = getIndex(recur); - String description = getDescription(split, index); - checkValidInput(value, recur); + throws FinancialPlannerException, IllegalArgumentException, DateTimeParseException + , IndexOutOfBoundsException { + try { + Cashflow entry; + double value = Double.parseDouble(split[1].trim()); + int recur = Integer.parseInt(split[3].trim()); + boolean hasRecurred = getHasRecurred(split, recur); + LocalDate date = getDate(split, recur); + int index = getIndex(recur); + String description = getDescription(split, index); + checkValidInput(value, recur); - switch (type) { - case "I": - IncomeType incomeType; - try { + switch (type) { + case "I": + IncomeType incomeType; incomeType = IncomeType.valueOf(split[2].trim().toUpperCase()); - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException("Invalid income type"); - } - entry = new Income(value, incomeType, recur, description, date, hasRecurred); - break; - case "E": - ExpenseType expenseType; - try { + entry = new Income(value, incomeType, recur, description, date, hasRecurred); + break; + case "E": + ExpenseType expenseType; expenseType = ExpenseType.valueOf(split[2].trim().toUpperCase()); - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException("Invalid expense type"); + entry = new Expense(value, expenseType, recur, description, date, hasRecurred); + break; + default: + throw new FinancialPlannerException("Error loading file"); } - entry = new Expense(value, expenseType, recur, description, date, hasRecurred); - break; - default: - throw new FinancialPlannerException("Error loading file"); + return entry; + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Erroneous arguments detected"); } - return entry; } - private static boolean getHasRecurred(String[] split, int recur) { + private static boolean getHasRecurred(String[] split, int recur) throws IllegalArgumentException { boolean hasRecurred; if (recur != 0) { - hasRecurred = Boolean.parseBoolean(split[4].trim()); + String stringHasRecurred = split[4].trim(); + if (stringHasRecurred.equals("true") || stringHasRecurred.equals("false")) { + hasRecurred = Boolean.parseBoolean(stringHasRecurred); + } else { + throw new IllegalArgumentException(); + } } else { hasRecurred = false; } From cd6b4dce650a22c7effcce964a99c4ffa4b7e55d Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 30 Oct 2023 00:16:53 +0800 Subject: [PATCH 278/518] Add maven repo for GSON --- build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle b/build.gradle index c5463dea1b..6902654579 100644 --- a/build.gradle +++ b/build.gradle @@ -15,6 +15,7 @@ dependencies { implementation group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1' implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.0' implementation group: 'org.knowm.xchart', name: 'xchart', version: '3.2.2' + implementation group: 'com.google.code.gson', name: 'gson', version: '2.10.1' } test { From 9de5b039f7d27bbff4d6025130aed29442c1e277 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 30 Oct 2023 00:33:04 +0800 Subject: [PATCH 279/518] Use new way of serializing objects to JSON using GSON library --- .../financialplanner/investments/Stock.java | 6 ++-- .../financialplanner/storage/LoadData.java | 29 +++++++++---------- .../financialplanner/storage/SaveData.java | 19 ++++++------ 3 files changed, 25 insertions(+), 29 deletions(-) diff --git a/src/main/java/seedu/financialplanner/investments/Stock.java b/src/main/java/seedu/financialplanner/investments/Stock.java index c064598ffd..58135666a5 100644 --- a/src/main/java/seedu/financialplanner/investments/Stock.java +++ b/src/main/java/seedu/financialplanner/investments/Stock.java @@ -7,7 +7,6 @@ import seedu.financialplanner.exceptions.FinancialPlannerException; import java.io.IOException; -import java.io.Serializable; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; @@ -17,10 +16,11 @@ import java.util.logging.Level; import java.util.logging.Logger; -public class Stock implements Serializable { +public class Stock { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private static final String API_ENDPOINT = "https://www.alphavantage.co/query?function=SYMBOL_SEARCH&keywords="; - private static final String API_KEY = "LNKL0548PHY2F0QU"; + ///private static final String API_KEY = "LNKL0548PHY2F0QU"; + private static final String API_KEY = "1AKJMAX4CNWFKSE6"; private String symbol; private String exchange; private String stockName; diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 9fb3a77531..8f1739814d 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -1,5 +1,9 @@ package seedu.financialplanner.storage; +import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; import seedu.financialplanner.enumerations.ExpenseType; import seedu.financialplanner.enumerations.IncomeType; import seedu.financialplanner.exceptions.FinancialPlannerException; @@ -11,16 +15,14 @@ import seedu.financialplanner.cashflow.Expense; import seedu.financialplanner.utils.Ui; -import java.io.StreamCorruptedException; -import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; -import java.io.ObjectInputStream; import java.util.HashMap; import java.util.Scanner; public abstract class LoadData { - private static final String FILE_PATH = "data/watchlist.txt"; + private static final String FILE_PATH = "data/watchlist.json"; private static final CashflowList cashflowList = CashflowList.getInstance(); private static final Ui ui = Ui.getInstance(); @@ -149,20 +151,15 @@ private static String getDescription(String[] split) { public static HashMap loadWatchList() { Ui ui = Ui.getInstance(); + Gson gson = new Gson(); HashMap stocksData = new HashMap<>(); try { - ObjectInputStream watchListStocksInputStream - = new ObjectInputStream( - new FileInputStream(FILE_PATH) - ); - stocksData = (HashMap) watchListStocksInputStream.readObject(); - watchListStocksInputStream.close(); - } catch (StreamCorruptedException e) { - ui.showMessage("Watchlist file corrupted.. Rebuilding"); - } catch (IOException e) { - ui.showMessage("Watchlist file not found... Creating"); - } catch (ClassNotFoundException e) { - ui.showMessage("FIle appears to be corrupted..."); + JsonReader reader = new JsonReader(new FileReader(FILE_PATH)); + stocksData = gson.fromJson(reader, new TypeToken>(){}.getType()); + } catch (FileNotFoundException e) { + ui.showMessage("File not found!"); + } catch (JsonSyntaxException e) { + ui.showMessage("Watchlist JSON is corrupted!"); } return stocksData; } diff --git a/src/main/java/seedu/financialplanner/storage/SaveData.java b/src/main/java/seedu/financialplanner/storage/SaveData.java index e3b3162afe..b11872d84e 100644 --- a/src/main/java/seedu/financialplanner/storage/SaveData.java +++ b/src/main/java/seedu/financialplanner/storage/SaveData.java @@ -1,5 +1,7 @@ package seedu.financialplanner.storage; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.cashflow.Budget; @@ -7,13 +9,11 @@ import seedu.financialplanner.cashflow.CashflowList; import seedu.financialplanner.utils.Ui; -import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; -import java.io.ObjectOutputStream; public abstract class SaveData { - private static final String FILE_PATH = "data/watchlist.txt"; + private static final String FILE_PATH = "data/watchlist.json"; private static final CashflowList cashflowList = CashflowList.getInstance(); @@ -32,14 +32,13 @@ public static void save(String filePath) throws FinancialPlannerException { public static void saveWatchList() { Ui ui = Ui.getInstance(); - try { - ObjectOutputStream watchListStocksOutput - = new ObjectOutputStream(new FileOutputStream(FILE_PATH)); - - WatchList wl = WatchList.getInstance(); - watchListStocksOutput.writeObject(wl.getStocks()); + WatchList wl = WatchList.getInstance(); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); - watchListStocksOutput.close(); + try { + FileWriter fileWriter = new FileWriter(FILE_PATH); + gson.toJson(wl.getStocks(), fileWriter); + fileWriter.close(); } catch (IOException e) { ui.showMessage("Unable to save watchlist to file"); } From b5aab4b31c9771669cb227b5fc8e6a03c56b75e5 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 30 Oct 2023 00:33:28 +0800 Subject: [PATCH 280/518] Create check to user if he wants to fix the file --- src/main/java/seedu/financialplanner/storage/LoadData.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 8f1739814d..791d8ef126 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -160,6 +160,11 @@ public static HashMap loadWatchList() { ui.showMessage("File not found!"); } catch (JsonSyntaxException e) { ui.showMessage("Watchlist JSON is corrupted!"); + ui.showMessage("Would you like to create new file? (Y/N)"); + if (!createNewFile()) { + ui.showMessage("Exiting... Plese fix the file"); + System.exit(1); + } } return stocksData; } From 2e8f3e6862bffc63a12c001f318b733cfd54c0fe Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 30 Oct 2023 00:40:41 +0800 Subject: [PATCH 281/518] Add acknowledgement to docs --- docs/DeveloperGuide.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 7516f3ec68..f439f93ff8 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -4,19 +4,23 @@ **Xchart (A Simple Charting Library for Java)** - author: KNOWN -- source: [https://knowm.org/open-source/xchart/]() +- source: [https://knowm.org/open-source/xchart/](https://knowm.org/open-source/xchart/) **JSON Simple (simple Java toolkit for encoding and decoding JSON)** - author: Yidong Fang (Google Code) -- source: [https://code.google.com/archive/p/json-simple/]() +- source: [https://code.google.com/archive/p/json-simple/](https://code.google.com/archive/p/json-simple/) **Apache Common Langs 3** - author: Apache Commons -- source: [https://commons.apache.org/proper/commons-lang/]() +- source: [https://commons.apache.org/proper/commons-lang/](https://commons.apache.org/proper/commons-lang/) **Alpha Vantage Stock Market API** - author: Alpha Vantage -- source: [https://www.alphavantage.co/]() +- source: [https://www.alphavantage.co/](https://www.alphavantage.co/) + +**Gson Java library** +- author: Google +- source: [https://github.com/google/gson](https://github.com/google/gson) **round() method in Cashflow.java** - author: mhadidg From 47f77bd121783141c5e0e89029ced1bf959c23da Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 30 Oct 2023 00:52:12 +0800 Subject: [PATCH 282/518] Add delete recurrences only functionality --- .../financialplanner/cashflow/Cashflow.java | 4 +++ .../cashflow/CashflowList.java | 26 ++++++++++++++ .../commands/DeleteCashflowCommand.java | 36 +++++++++++++++++-- .../java/seedu/financialplanner/utils/Ui.java | 6 ++++ 4 files changed, 69 insertions(+), 3 deletions(-) diff --git a/src/main/java/seedu/financialplanner/cashflow/Cashflow.java b/src/main/java/seedu/financialplanner/cashflow/Cashflow.java index 9783c3877e..a513e5af0f 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Cashflow.java +++ b/src/main/java/seedu/financialplanner/cashflow/Cashflow.java @@ -103,6 +103,10 @@ public int getRecur() { return recur; } + public void setRecur(int recur) { + this.recur = recur; + } + public LocalDate getDate() { return date; } diff --git a/src/main/java/seedu/financialplanner/cashflow/CashflowList.java b/src/main/java/seedu/financialplanner/cashflow/CashflowList.java index 226d5ea14a..03d50a6b37 100644 --- a/src/main/java/seedu/financialplanner/cashflow/CashflowList.java +++ b/src/main/java/seedu/financialplanner/cashflow/CashflowList.java @@ -61,6 +61,20 @@ public double deleteCashflowWithoutCategory(int index) { assert newListSize == existingListSize - 1; return toRemove.getAmount(); } + + public void deleteRecurWithoutCategory(int index) { + int listIndex = index - 1; + + Cashflow toRemoveRecur = list.get(listIndex); + if (toRemoveRecur.getRecur() == 0 || toRemoveRecur.hasRecurred) { + ui.showMessage("Cashflow is already not recurring or has already recurred"); + } else { + toRemoveRecur.setDate(null); + toRemoveRecur.setRecur(0); + list.set(listIndex, toRemoveRecur); + ui.printDeletedRecur(toRemoveRecur); + } + } //helper method to find the index of a given cashflow in the overall list //given its index in its respective list. e.g. "income 3" is the third income //in the overall list @@ -108,7 +122,19 @@ private int findCashflowIndexFromExpenseIndex(int cashflowIndex) { } return overallCashflowIndex; } + public void deleteRecurWithCategory(CashflowCategory category, int index) { + int listIndex = cashflowIndexFinder(category, index); + Cashflow toRemoveRecur = list.get(listIndex); + if (toRemoveRecur.getRecur() == 0 || toRemoveRecur.hasRecurred) { + ui.showMessage("Cashflow is already not recurring or has already recurred"); + } else { + toRemoveRecur.setDate(null); + toRemoveRecur.setRecur(0); + list.set(listIndex, toRemoveRecur); + ui.printDeletedRecur(toRemoveRecur); + } + } public double deleteCashflowWithCategory(CashflowCategory category, int index) { int existingListSize = list.size(); int listIndex = cashflowIndexFinder(category, index); diff --git a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java index 7b0e2b5eac..257ed31226 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java @@ -12,6 +12,7 @@ public class DeleteCashflowCommand extends Command { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); protected CashflowCategory category = null; protected int index; + protected boolean hasRecur; protected CashflowList cashflowList = CashflowList.getInstance(); public DeleteCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException { @@ -40,6 +41,12 @@ public DeleteCashflowCommand(RawCommand rawCommand) throws IllegalArgumentExcept logger.log(Level.WARNING, "Invalid value for index"); throw new IllegalArgumentException("Index must be within the list"); } + + if (rawCommand.extraArgs.containsKey("r")) { + hasRecur = true; + } else { + hasRecur = false; + } } private void handleInvalidCategory(String stringCategory) { @@ -55,7 +62,11 @@ private void handleInvalidCategory(String stringCategory) { @Override public void execute() { if (category == null) { - handleDeleteCashflowWithoutCategory(); + if (hasRecur) { + handleDeleteRecurWithoutCategory(); + } else { + handleDeleteCashflowWithoutCategory(); + } return; } @@ -64,8 +75,13 @@ public void execute() { switch (category) { case INCOME: + //Fallthrough case EXPENSE: - handleDeleteCashflowWithCategory(); + if (hasRecur) { + handleDeleteRecurWithCategory(); + } else { + handleDeleteCashflowWithCategory(); + } break; default: logger.log(Level.SEVERE, "Unreachable default case reached"); @@ -74,6 +90,14 @@ public void execute() { } } + private void handleDeleteRecurWithoutCategory() { + try { + cashflowList.deleteRecurWithoutCategory(index); + } catch (IndexOutOfBoundsException e) { + throw new IllegalArgumentException("Index must be within the list"); + } + } + private void handleDeleteCashflowWithoutCategory() { try { logger.log(Level.INFO, "Deleting cashflow without category"); @@ -86,7 +110,13 @@ private void handleDeleteCashflowWithoutCategory() { throw new IllegalArgumentException("Index must be within the list"); } } - + private void handleDeleteRecurWithCategory() { + try { + cashflowList.deleteRecurWithCategory(category, index); + } catch (IndexOutOfBoundsException e) { + throw new IllegalArgumentException("Index must be within the list"); + } + } private void handleDeleteCashflowWithCategory() { try { logger.log(Level.INFO, "Deleting cashflow with category"); diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index decc6340e1..f00d1255d9 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -113,6 +113,12 @@ public void printDeletedCashflow(Cashflow entry) { System.out.println("Balance: " + entry.formatBalance()); } + public void printDeletedRecur(Cashflow entry) { + System.out.println("You have removed future recurrences of this cashflow."); + System.out.println("Updated cashflow:"); + System.out.println(entry); + } + public void printBudgetBeforeUpdate() { showMessage("Budget has been updated:\nOld initial budget: " + Budget.getInitialBudgetString() + "\nOld current budget: " + From f2bd630285468d56297898447f10fd4339f809ad Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 30 Oct 2023 01:01:59 +0800 Subject: [PATCH 283/518] Add exceptions if extra arguments after /r is detected --- .../commands/DeleteCashflowCommand.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java index 257ed31226..b865252f11 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java @@ -5,6 +5,7 @@ import seedu.financialplanner.cashflow.CashflowList; import seedu.financialplanner.utils.Ui; +import java.util.ArrayList; import java.util.logging.Level; import java.util.logging.Logger; @@ -43,10 +44,21 @@ public DeleteCashflowCommand(RawCommand rawCommand) throws IllegalArgumentExcept } if (rawCommand.extraArgs.containsKey("r")) { + String recurArgs = rawCommand.extraArgs.get("r"); + if (!recurArgs.isBlank()) { + throw new IllegalArgumentException("Arguments after /r should be left empty."); + } hasRecur = true; } else { hasRecur = false; } + rawCommand.extraArgs.remove("r"); + + if (!rawCommand.extraArgs.isEmpty()) { + String unknownExtraArgument = new ArrayList<>(rawCommand.extraArgs.keySet()).get(0); + logger.log(Level.WARNING, "Invalid extra arguments found"); + throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); + } } private void handleInvalidCategory(String stringCategory) { From c39ad9cac63b561c9cd0666b9d82aec20e7db70a Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 30 Oct 2023 01:04:35 +0800 Subject: [PATCH 284/518] Add logging --- .../financialplanner/commands/DeleteCashflowCommand.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java index b865252f11..341cce3b72 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java @@ -44,8 +44,10 @@ public DeleteCashflowCommand(RawCommand rawCommand) throws IllegalArgumentExcept } if (rawCommand.extraArgs.containsKey("r")) { + logger.log(Level.INFO, "Getting any arguments after /r"); String recurArgs = rawCommand.extraArgs.get("r"); if (!recurArgs.isBlank()) { + logger.log(Level.WARNING, "Arguments after /r found"); throw new IllegalArgumentException("Arguments after /r should be left empty."); } hasRecur = true; @@ -104,8 +106,10 @@ public void execute() { private void handleDeleteRecurWithoutCategory() { try { + logger.log(Level.INFO, "Deleting recurrence without category"); cashflowList.deleteRecurWithoutCategory(index); } catch (IndexOutOfBoundsException e) { + logger.log(Level.WARNING, "Index out of list"); throw new IllegalArgumentException("Index must be within the list"); } } @@ -124,8 +128,10 @@ private void handleDeleteCashflowWithoutCategory() { } private void handleDeleteRecurWithCategory() { try { + logger.log(Level.INFO, "Deleting recurrence with category"); cashflowList.deleteRecurWithCategory(category, index); } catch (IndexOutOfBoundsException e) { + logger.log(Level.WARNING, "Index out of list"); throw new IllegalArgumentException("Index must be within the list"); } } From d650d46de627b27e759f35182e79c45d5b127cd7 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 30 Oct 2023 01:28:57 +0800 Subject: [PATCH 285/518] Add listing by recurring cashflows --- .../financialplanner/cashflow/Cashflow.java | 2 +- .../cashflow/CashflowList.java | 20 ++++++++++++++++++- .../commands/AddCashflowCommand.java | 3 ++- .../commands/DeleteCashflowCommand.java | 5 ++++- .../commands/ListCommand.java | 5 ++++- .../enumerations/CashflowCategory.java | 2 +- .../financialplanner/storage/LoadData.java | 2 +- 7 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/main/java/seedu/financialplanner/cashflow/Cashflow.java b/src/main/java/seedu/financialplanner/cashflow/Cashflow.java index a513e5af0f..7c0da31adc 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Cashflow.java +++ b/src/main/java/seedu/financialplanner/cashflow/Cashflow.java @@ -115,7 +115,7 @@ public void setDate(LocalDate date) { this.date = date; } - public boolean isHasRecurred() { + public boolean getHasRecurred() { return hasRecurred; } diff --git a/src/main/java/seedu/financialplanner/cashflow/CashflowList.java b/src/main/java/seedu/financialplanner/cashflow/CashflowList.java index 03d50a6b37..22dcfb34b1 100644 --- a/src/main/java/seedu/financialplanner/cashflow/CashflowList.java +++ b/src/main/java/seedu/financialplanner/cashflow/CashflowList.java @@ -79,13 +79,16 @@ public void deleteRecurWithoutCategory(int index) { //given its index in its respective list. e.g. "income 3" is the third income //in the overall list private int cashflowIndexFinder(CashflowCategory category, int cashflowIndex) { - assert category.equals(CashflowCategory.INCOME) || category.equals(CashflowCategory.EXPENSE); + assert category.equals(CashflowCategory.INCOME) || category.equals(CashflowCategory.EXPENSE) + || category.equals(CashflowCategory.RECURRING); switch (category) { case INCOME: return findCashflowIndexFromIncomeIndex(cashflowIndex); case EXPENSE: return findCashflowIndexFromExpenseIndex(cashflowIndex); + case RECURRING: + return findCashflowIndexFromRecurIndex(cashflowIndex); default: return -1; } @@ -122,6 +125,21 @@ private int findCashflowIndexFromExpenseIndex(int cashflowIndex) { } return overallCashflowIndex; } + private int findCashflowIndexFromRecurIndex(int cashflowIndex) { + int cashflowCounter = 0; + int overallCashflowIndex = 0; + + for (Cashflow entry : list) { + if (entry.getRecur() > 0 && !entry.getHasRecurred()) { + cashflowCounter += 1; + } + if (cashflowCounter == cashflowIndex) { + break; + } + overallCashflowIndex += 1; + } + return overallCashflowIndex; + } public void deleteRecurWithCategory(CashflowCategory category, int index) { int listIndex = cashflowIndexFinder(category, index); diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index 9b26535953..267ef4be91 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -112,7 +112,8 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException @Override public void execute() { - assert category.equals(CashflowCategory.INCOME) || category.equals(CashflowCategory.EXPENSE); + assert category.equals(CashflowCategory.INCOME) || category.equals(CashflowCategory.EXPENSE) + || category.equals(CashflowCategory.RECURRING); assert recur >= 0; assert amount >= 0; if (category.equals(CashflowCategory.EXPENSE)) { diff --git a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java index 341cce3b72..59b0623c31 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java @@ -84,13 +84,16 @@ public void execute() { return; } - assert category.equals(CashflowCategory.INCOME) || category.equals(CashflowCategory.EXPENSE); + assert category.equals(CashflowCategory.INCOME) || category.equals(CashflowCategory.EXPENSE) + || category.equals(CashflowCategory.RECURRING); assert index != 0; switch (category) { case INCOME: //Fallthrough case EXPENSE: + //Fallthrough + case RECURRING: if (hasRecur) { handleDeleteRecurWithCategory(); } else { diff --git a/src/main/java/seedu/financialplanner/commands/ListCommand.java b/src/main/java/seedu/financialplanner/commands/ListCommand.java index c2b387f651..9d68a063d6 100644 --- a/src/main/java/seedu/financialplanner/commands/ListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/ListCommand.java @@ -25,7 +25,7 @@ public ListCommand(RawCommand rawCommand) throws IllegalArgumentException{ try { category = CashflowCategory.valueOf(stringCategory.toUpperCase()); } catch (IllegalArgumentException e) { - throw new IllegalArgumentException("Entry must be either income or expense"); + throw new IllegalArgumentException("Entry must be either income, expense or recurring"); } } } @@ -40,6 +40,9 @@ private boolean shouldPrintCashFlow(Cashflow cashflow) { if (cashflow instanceof Expense) { return category.equals(CashflowCategory.EXPENSE); } + if (cashflow.getRecur() > 0 && !cashflow.getHasRecurred()) { + return category.equals(CashflowCategory.RECURRING); + } return false; } diff --git a/src/main/java/seedu/financialplanner/enumerations/CashflowCategory.java b/src/main/java/seedu/financialplanner/enumerations/CashflowCategory.java index 0c394fee70..9f5c6815ad 100644 --- a/src/main/java/seedu/financialplanner/enumerations/CashflowCategory.java +++ b/src/main/java/seedu/financialplanner/enumerations/CashflowCategory.java @@ -1,5 +1,5 @@ package seedu.financialplanner.enumerations; public enum CashflowCategory { - INCOME, EXPENSE + INCOME, EXPENSE, RECURRING } diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 47721525ea..9ff2ad60a4 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -95,7 +95,7 @@ private static void addRecurringCashflows(LocalDate currentDate) throws Financia for (Cashflow cashflow : cashflowList.list) { int recur = cashflow.getRecur(); LocalDate dateOfAddition = cashflow.getDate(); - boolean hasRecurred = cashflow.isHasRecurred(); + boolean hasRecurred = cashflow.getHasRecurred(); addRecurringCashflowToTempList(currentDate, cashflow, recur, dateOfAddition, tempCashflow, hasRecurred); } for (Cashflow cashflow : tempCashflow) { From ff5f07ed524ba2fa90f5f490b73b2f6eedb4e724 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 30 Oct 2023 01:31:35 +0800 Subject: [PATCH 286/518] Update JUnit test --- .../java/seedu/financialplanner/cashflow/CashflowListTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/seedu/financialplanner/cashflow/CashflowListTest.java b/src/test/java/seedu/financialplanner/cashflow/CashflowListTest.java index aaf5ee2bfd..bf82fb8b6e 100644 --- a/src/test/java/seedu/financialplanner/cashflow/CashflowListTest.java +++ b/src/test/java/seedu/financialplanner/cashflow/CashflowListTest.java @@ -76,7 +76,7 @@ void testDeleteIncomeAndExpense() { roundedBalance = Cashflow.round(Cashflow.balance, 2); assertEquals("-30.00", decimalFormat.format(roundedBalance)); - testList.deleteCashflowWithCategory(CashflowCategory.EXPENSE, 2); + testList.deleteCashflowWithCategory(CashflowCategory.RECURRING, 1); assertEquals(1, testList.list.size()); roundedBalance = Cashflow.round(Cashflow.balance, 2); assertEquals("-10.00", decimalFormat.format(roundedBalance)); From 94014090da845185ef4f71b9d8259ded8a3e26cd Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 30 Oct 2023 01:35:27 +0800 Subject: [PATCH 287/518] Fix I/O redirection test --- src/main/java/seedu/financialplanner/storage/LoadData.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 791d8ef126..b71fcbf774 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -157,7 +157,7 @@ public static HashMap loadWatchList() { JsonReader reader = new JsonReader(new FileReader(FILE_PATH)); stocksData = gson.fromJson(reader, new TypeToken>(){}.getType()); } catch (FileNotFoundException e) { - ui.showMessage("File not found!"); + ui.showMessage("Watchlist file not found... Creating"); } catch (JsonSyntaxException e) { ui.showMessage("Watchlist JSON is corrupted!"); ui.showMessage("Would you like to create new file? (Y/N)"); From f9d5730119ba1b273b230a4a9680c31c71651480 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 30 Oct 2023 01:41:50 +0800 Subject: [PATCH 288/518] Fix bug in formatting cashflow for storage --- src/main/java/seedu/financialplanner/cashflow/Cashflow.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/cashflow/Cashflow.java b/src/main/java/seedu/financialplanner/cashflow/Cashflow.java index 7c0da31adc..739acf81a1 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Cashflow.java +++ b/src/main/java/seedu/financialplanner/cashflow/Cashflow.java @@ -132,8 +132,8 @@ public String formatString() { if (recur == 0) { string = " | 0 | false"; } else { - string = " | " + this.recur + " | " + " | " + this.hasRecurred; - string += date.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")); + string = " | " + this.recur + " | " + this.hasRecurred; + string += " | " + date.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")); } if (description != null) { string += " | " + this.description; From 7cc49aabeb8914c6c003bedf95fee99b3a35ddfa Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 30 Oct 2023 01:51:27 +0800 Subject: [PATCH 289/518] Fix bug in listing all recurring cashflows --- .../commands/DeleteCashflowCommand.java | 2 +- .../seedu/financialplanner/commands/ListCommand.java | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java index 59b0623c31..ed2fc24785 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java @@ -69,7 +69,7 @@ private void handleInvalidCategory(String stringCategory) { category = CashflowCategory.valueOf(stringCategory.toUpperCase()); } catch (IllegalArgumentException e) { logger.log(Level.WARNING, "Invalid arguments for CashflowCategory"); - throw new IllegalArgumentException("Entry must be either income or expense"); + throw new IllegalArgumentException("Entry must be either income, expense or recurring"); } } diff --git a/src/main/java/seedu/financialplanner/commands/ListCommand.java b/src/main/java/seedu/financialplanner/commands/ListCommand.java index 9d68a063d6..ca076fdb10 100644 --- a/src/main/java/seedu/financialplanner/commands/ListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/ListCommand.java @@ -25,7 +25,7 @@ public ListCommand(RawCommand rawCommand) throws IllegalArgumentException{ try { category = CashflowCategory.valueOf(stringCategory.toUpperCase()); } catch (IllegalArgumentException e) { - throw new IllegalArgumentException("Entry must be either income, expense or recurring"); + throw new IllegalArgumentException("Entry must be either income, expense or recurring."); } } } @@ -34,11 +34,11 @@ private boolean shouldPrintCashFlow(Cashflow cashflow) { if (category == null) { return true; } - if (cashflow instanceof Income) { - return category.equals(CashflowCategory.INCOME); + if (cashflow instanceof Income && category.equals(CashflowCategory.INCOME)) { + return true; } - if (cashflow instanceof Expense) { - return category.equals(CashflowCategory.EXPENSE); + if (cashflow instanceof Expense && category.equals(CashflowCategory.EXPENSE)) { + return true; } if (cashflow.getRecur() > 0 && !cashflow.getHasRecurred()) { return category.equals(CashflowCategory.RECURRING); From 03872b1f13b4295aec4701a550834a504ac33ec1 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 30 Oct 2023 04:31:09 +0800 Subject: [PATCH 290/518] Update command summary --- docs/UserGuide.md | 44 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index d898dde525..6333eb0588 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -250,13 +250,37 @@ Existing data will be automatically loaded when the program starts up. {Give a 'cheat sheet' of commands here} -| Action | Format | -|----------------------|---------------------------| -| **Set budget** | `budget set /b BUDGET` | -| **Update budget** | `budget update /b BUDGET` | -| **Reset budget** | `budget reset` | -| **Delete budget** | `budget delete` | -| **View budget** | `budget view` | -| **Display Overview** | `overview` | -| **View balance** | `balance` | -| **Exit program** | `exit` | +| Action | Format | +|----------------------------------|------------------------------------------------------------| +| **Add income** | `add income /a AMOUNT /t TYPE [/r DAYS] [/d DESCRIPTION]` | +| **Add expense** | `add expense /a AMOUNT /t TYPE [/r DAYS] [/d DESCRIPTION]` | +| **Delete cashflow** | `delete INDEX [/r]` | +| **Delete income** | `delete income INDEX [/r]` | +| **Delete expense** | `delete expense INDEX [/r]` | +| **Delete recurrence** | `delete recurrence INDEX [/r]` | +| **list all cashflows** | `list` | +| **list all incomes** | `list income` | +| **list all expenses** | `list expense` | +| **list all recurring cashflows** | `list recurrence* | +| **Set budget** | `budget set /b BUDGET` | +| **Update budget** | `budget update /b BUDGET` | +| **Reset budget** | `budget reset` | +| **Delete budget** | `budget delete` | +| **View budget** | `budget view` | +| **Display Overview** | `overview` | +| **View balance** | `balance` | +| **Exit program** | `exit` | + +- Note: Cashflow is referring to an income or expense + +**Income and Expense types** + +| Income | Expense | +|---------------|-----------------| +| `salary` | `dining` | +| `investments` | `entertainment` | +| `allowance` | `shopping` | +| `others` | `travel` | +| | `insurance` | +| | `necessities` | +| | `others` | From 81de164062fdd1652f5568b0695cfb48bf4b9f0b Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 30 Oct 2023 04:35:17 +0800 Subject: [PATCH 291/518] Add addIncome and addExpense to features --- docs/UserGuide.md | 63 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 6333eb0588..fe63be49b7 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -34,11 +34,72 @@ you a one-stop interface to access a plethora of features to manage your finance {Give steps to get started quickly} 1. Ensure that you have Java 11 or above installed. -1. Down the latest version of `Duke` from [here](http://link.to/duke). +1. Down the latest version of `Financial Planner` from [here](http://link.to/duke). +1. Copy the file to the folder you want to use as the *home folder* for Neo Chatbot. +1. Open a command terminal, `cd` into the folder you put the jar file in, and use the `java -jar ip.jar` command to run the application. +1. Refer to the **Features** section below for details of each command. ## Features {Give detailed description of each feature} +### Notes about the command format +- Words in `UPPER_CASE` are parameters to be supplied by the user. + + e.g. in `add income /a AMOUNT`, `AMOUNT` is a parameter which can be used as `add income /a 100`. +- Items in square brackets are optional. + + e.g. `[/r DAYS]` can be used as `/r 30` or left empty. + +### Add income: `add income` +Adds an income source to the Financial Planner. + +Format: `add income /a AMOUNT /t TYPE [/r DAYS] [/d DESCRIPTION]` + +- `/r` is used to denote a recurring income, with the period to the next addition is specified by `DAYS`. +- `/d` is used to give a description to the income. +- `/t` is used to specify the income type, where the list of acceptable types is given below + +| Income Types | +|---------------| +| `salary` | +| `investments` | +| `allowance` | +| `others` | + +Example of usage: `add income /a 5000 /t salary /r 30 /d work` + +Example output: + +``` + +``` + +### Add expense +Adds an expense to the Financial Planner + +Format: `add expense /a AMOUNT /t TYPE [/r DAYS] [/d DESCRIPTION]` + +- `/r` is used to denote a recurring expense, with the period to the next addition is specified by `DAYS`. +- `/d` is used to give a description to the expense. +- `/t` is used to specify the expense type, where the list of acceptable types is given below + +| Expense | +|-----------------| +| `dining` | +| `entertainment` | +| `shopping` | +| `travel` | +| `insurance` | +| `necessities` | +| `others` | + +Example of usage: `add income /a 5000 /t salary /r 30 /d work` + +Example output: +``` + +``` + ### Budget From 1a0b086dc05b8f2bb4806de28f5553f05701f2ec Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 30 Oct 2023 04:48:14 +0800 Subject: [PATCH 292/518] Add delete features to UG --- docs/UserGuide.md | 79 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index fe63be49b7..6acc95e6bd 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -100,7 +100,86 @@ Example output: ``` +### Delete cashflow +Deletes an income/expense from the Financial Planner. +Format: `delete INDEX [/r]` + +- `INDEX` refers to the index number shown in the displayed list when `list` command is used. +- `/r` is used to delete all **future** incomes/expenses **only**. + +Example of usage: `delete 2 /r` + +Example output: +``` + +``` +Example of usage: `delete 2` + +Example output: +``` + +``` +### Delete income +Deletes an income from the Financial Planner. + +Format: `delete income INDEX [/r]` + +- `INDEX` refers to the index number shown in the displayed list when `list income` command is used. +- `/r` is used to delete all **future** incomes **only**. + +Example of usage: `delete income 2 /r` + +Example output: +``` + +``` +Example of usage: `delete income 2` + +Example output: +``` + +``` +### Delete expense +Deletes an expense from the Financial Planner. + +Format: `delete expense INDEX [/r]` + +- `INDEX` refers to the index number shown in the displayed list when `list expense` command is used. +- `/r` is used to delete all **future** expenses **only**. + +Example of usage: `delete expense 2 /r` + +Example output: +``` + +``` +Example of usage: `delete expense 2` + +Example output: +``` + +``` +### Delete recurring +Deletes a recurring income/expense from the Financial Planner. + +Format: `delete recurring INDEX [/r]` + +- `INDEX` refers to the index number shown in the displayed list when `list recurring` command is used. +- `/r` is used to delete all **future** recurring incomes/expenses **only**. + +Example of usage: `delete recurring 2` + +Example output: +``` + +``` +Example of usage: `delete recurring 2 /r` + +Example output: +``` + +``` ### Budget #### Setting a budget: `budget set` From 2b335de9713a9223d9ce798ccfaaaa79ea1e63f0 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 30 Oct 2023 04:57:20 +0800 Subject: [PATCH 293/518] Add list functions to UG --- docs/UserGuide.md | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 6acc95e6bd..82d83ea1f9 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -101,11 +101,11 @@ Example output: ``` ### Delete cashflow -Deletes an income/expense from the Financial Planner. +Deletes a cashflow from the Financial Planner. Format: `delete INDEX [/r]` -- `INDEX` refers to the index number shown in the displayed list when `list` command is used. +- `INDEX` refers to the index number shown in the displayed list when [`list`](#list-all) command is used. - `/r` is used to delete all **future** incomes/expenses **only**. Example of usage: `delete 2 /r` @@ -125,7 +125,7 @@ Deletes an income from the Financial Planner. Format: `delete income INDEX [/r]` -- `INDEX` refers to the index number shown in the displayed list when `list income` command is used. +- `INDEX` refers to the index number shown in the displayed list when [`list income`](#list-income) command is used. - `/r` is used to delete all **future** incomes **only**. Example of usage: `delete income 2 /r` @@ -145,7 +145,7 @@ Deletes an expense from the Financial Planner. Format: `delete expense INDEX [/r]` -- `INDEX` refers to the index number shown in the displayed list when `list expense` command is used. +- `INDEX` refers to the index number shown in the displayed list when [`list expense`](#list-expense) command is used. - `/r` is used to delete all **future** expenses **only**. Example of usage: `delete expense 2 /r` @@ -161,11 +161,11 @@ Example output: ``` ### Delete recurring -Deletes a recurring income/expense from the Financial Planner. +Deletes a recurring cashflow from the Financial Planner. Format: `delete recurring INDEX [/r]` -- `INDEX` refers to the index number shown in the displayed list when `list recurring` command is used. +- `INDEX` refers to the index number shown in the displayed list when [`list recurring`](#list-recurring) command is used. - `/r` is used to delete all **future** recurring incomes/expenses **only**. Example of usage: `delete recurring 2` @@ -180,6 +180,26 @@ Example output: ``` ``` +### List all + +### List income + +### List expense + +### List recurring +Lists all recurring cashflows. + +Format: `list recurring` + +- This list will not include any cashflow that has already recurred. + +Example of usage: `list recurring` + +Example output: +``` + +``` + ### Budget #### Setting a budget: `budget set` From 49403686bde95794a2b0630a8cdd3d1ba9941806 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 30 Oct 2023 05:19:49 +0800 Subject: [PATCH 294/518] Add example outputs --- docs/UserGuide.md | 187 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 160 insertions(+), 27 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 82d83ea1f9..eb28544379 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -71,10 +71,16 @@ Example of usage: `add income /a 5000 /t salary /r 30 /d work` Example output: ``` - -``` - -### Add expense +You have added an Income + Type: Salary + Amount: 5000.00 + Recurring every: 30 days, starting from: Oct 30 2023 + Description: work +to the Financial Planner. +Balance: 5000.00 +``` +- Note: Balance displayed above is just an example. Your actual balance may differ. +### Add expense: `add expense` Adds an expense to the Financial Planner Format: `add expense /a AMOUNT /t TYPE [/r DAYS] [/d DESCRIPTION]` @@ -93,34 +99,52 @@ Format: `add expense /a AMOUNT /t TYPE [/r DAYS] [/d DESCRIPTION]` | `necessities` | | `others` | -Example of usage: `add income /a 5000 /t salary /r 30 /d work` +Example of usage: `add expense /a 300 /t necessities /r 30 /d groceries` Example output: ``` - +You have added an Expense + Type: Necessities + Amount: 300.00 + Recurring every: 30 days, starting from: Oct 30 2023 + Description: groceries +to the Financial Planner. +Balance: 4700.00 ``` - -### Delete cashflow +- Note: Balance displayed above is just an example. Your actual balance may differ. +### Delete cashflow: `delete` Deletes a cashflow from the Financial Planner. Format: `delete INDEX [/r]` - `INDEX` refers to the index number shown in the displayed list when [`list`](#list-all) command is used. -- `/r` is used to delete all **future** incomes/expenses **only**. +- `/r` is used to delete all **future** cashflows **only**. -Example of usage: `delete 2 /r` +Example of usage: `delete 1 /r` Example output: ``` - +You have removed future recurrences of this cashflow. +Updated cashflow: +Income + Type: Salary + Amount: 5000.00 + Description: work ``` -Example of usage: `delete 2` +Example of usage: `delete 1` Example output: ``` - +You have removed an Income + Type: Salary + Amount: 5000.00 + Description: work +from the Financial Planner. +Balance: -1130.00 ``` -### Delete income +- Note: Balance displayed above is just an example. Your actual balance may differ. + +### Delete income: `delete income` Deletes an income from the Financial Planner. Format: `delete income INDEX [/r]` @@ -132,15 +156,27 @@ Example of usage: `delete income 2 /r` Example output: ``` - +You have removed future recurrences of this cashflow. +Updated cashflow: +Income + Type: Allowance + Amount: 500.00 + Description: parents ``` Example of usage: `delete income 2` Example output: ``` - +You have removed an Income + Type: Allowance + Amount: 500.00 + Description: parents +from the Financial Planner. +Balance: 5170.00 ``` -### Delete expense +- Note: Balance displayed above is just an example. Your actual balance may differ. + +### Delete expense: `delete expense` Deletes an expense from the Financial Planner. Format: `delete expense INDEX [/r]` @@ -152,41 +188,128 @@ Example of usage: `delete expense 2 /r` Example output: ``` - +You have removed future recurrences of this cashflow. +Updated cashflow: +Expense + Type: Insurance + Amount: 800.00 + Description: ntuc income ``` Example of usage: `delete expense 2` Example output: ``` - +You have removed an Expense + Type: Insurance + Amount: 800.00 + Description: ntuc income +from the Financial Planner. +Balance: -330.00 ``` -### Delete recurring +- Note: Balance displayed above is just an example. Your actual balance may differ. + +### Delete recurring: `delete recurring` Deletes a recurring cashflow from the Financial Planner. Format: `delete recurring INDEX [/r]` - `INDEX` refers to the index number shown in the displayed list when [`list recurring`](#list-recurring) command is used. -- `/r` is used to delete all **future** recurring incomes/expenses **only**. +- `/r` is used to delete all **future** recurring cashflows **only**. -Example of usage: `delete recurring 2` +Example of usage: `delete recurring 2 /r` Example output: ``` - +You have removed future recurrences of this cashflow. +Updated cashflow: +Expense + Type: Insurance + Amount: 800.00 + Description: ntuc income ``` -Example of usage: `delete recurring 2 /r` +Example of usage: `delete recurring 1` Example output: ``` +You have removed an Expense + Type: Necessities + Amount: 300.00 + Recurring every: 30 days, starting from: Oct 30 2023 + Description: groceries +from the Financial Planner. +Balance: -830.00 +- Note: Balance displayed above is just an example. Your actual balance may differ. ``` -### List all +### List all +// TODO +Example output: + +``` +You have 4 matching cashflows: +1: Income + Type: Salary + Amount: 5000.00 + Recurring every: 30 days, starting from: Oct 30 2023 + Description: work +2: Expense + Type: Dining + Amount: 30.00 + Description: Genki Sushi +3: Expense + Type: Insurance + Amount: 800.00 + Recurring every: 365 days, starting from: Oct 30 2023 + Description: ntuc income +4: Expense + Type: Necessities + Amount: 300.00 + Recurring every: 30 days, starting from: Oct 30 2023 + Description: groceries +``` ### List income +//TODO +Example output: +``` +You have 3 matching cashflows: +1: Income + Type: Salary + Amount: 5000.00 + Recurring every: 30 days, starting from: Oct 30 2023 + Description: work +2: Income + Type: Allowance + Amount: 500.00 + Recurring every: 30 days, starting from: Oct 30 2023 + Description: parents +3: Income + Type: Investments + Amount: 1000.00 +``` ### List expense +//TODO -### List recurring +Example output: +``` +You have 3 matching cashflows: +1: Expense + Type: Dining + Amount: 30.00 + Description: Genki Sushi +2: Expense + Type: Insurance + Amount: 800.00 + Recurring every: 365 days, starting from: Oct 30 2023 + Description: ntuc income +3: Expense + Type: Necessities + Amount: 300.00 + Recurring every: 30 days, starting from: Oct 30 2023 + Description: groceries +``` +### List recurring: `list recurring` Lists all recurring cashflows. Format: `list recurring` @@ -197,7 +320,17 @@ Example of usage: `list recurring` Example output: ``` - +You have 2 matching cashflows: +1: Expense + Type: Insurance + Amount: 800.00 + Recurring every: 365 days, starting from: Oct 30 2023 + Description: ntuc income +2: Expense + Type: Necessities + Amount: 300.00 + Recurring every: 30 days, starting from: Oct 30 2023 + Description: groceries ``` ### Budget From 184d6e46721d8ea564e7b90fcb11dc146c34bb9a Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 30 Oct 2023 05:20:01 +0800 Subject: [PATCH 295/518] Fix typo --- .../java/seedu/financialplanner/commands/ListCommand.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/ListCommand.java b/src/main/java/seedu/financialplanner/commands/ListCommand.java index ca076fdb10..c7e8b1e062 100644 --- a/src/main/java/seedu/financialplanner/commands/ListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/ListCommand.java @@ -60,11 +60,11 @@ public void execute() throws Exception { } if (cashflowToBePrinted.isEmpty()) { - ui.showMessage("No matching cashflow"); + ui.showMessage("No matching cashflow."); return; } - ui.showMessage(String.format("You have %d matching cashflow:", cashflowToBePrinted.size())); + ui.showMessage(String.format("You have %d matching cashflows:", cashflowToBePrinted.size())); for (int i = 0; i < cashflowToBePrinted.size(); i += 1) { ui.showMessage((i + 1) + ": " + cashflowToBePrinted.get(i)); } From 943e7c5de6dc2dac2951409efd0e6d2effbd916d Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 30 Oct 2023 05:28:49 +0800 Subject: [PATCH 296/518] Update table of contents --- docs/UserGuide.md | 50 +++++++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index eb28544379..7684f746e9 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -5,6 +5,18 @@ * [Introduction](#introduction) * [Quick start](#quick-start) * [Features](#features) + * [Add cashflow](#add-cashflow) + * [Add income](#add-income-add-income) + * [Add expense](#add-expense-add-expense) + * [Delete cashflow](#delete-cashflow-delete) + * [Delete income](#delete-income-delete-income) + * [Delete expense](#delete-expense-delete-expense) + * [Delete recurring cashflow](#delete-recurring-delete-recurring) + * [List](#list) + * [List all](#list-all-list) + * [List income](#list-income-list-income) + * [List expense](#list-expense-list-expense) + * [List recurring](#list-recurring-list-recurring) * [Budget](#budget) * [Setting budget](#setting-a-budget-budget-set) * [Updating budget](#updating-budget-budget-update) @@ -34,10 +46,10 @@ you a one-stop interface to access a plethora of features to manage your finance {Give steps to get started quickly} 1. Ensure that you have Java 11 or above installed. -1. Down the latest version of `Financial Planner` from [here](http://link.to/duke). -1. Copy the file to the folder you want to use as the *home folder* for Neo Chatbot. -1. Open a command terminal, `cd` into the folder you put the jar file in, and use the `java -jar ip.jar` command to run the application. -1. Refer to the **Features** section below for details of each command. +2. Down the latest version of `Financial Planner` from [here](http://link.to/duke). +3. Copy the file to the folder you want to use as the *home folder* for Neo Chatbot. +4. Open a command terminal, `cd` into the folder you put the jar file in, and use the `java -jar ip.jar` command to run the application. +5. Refer to the **Features** section below for details of each command. ## Features @@ -50,7 +62,9 @@ you a one-stop interface to access a plethora of features to manage your finance e.g. `[/r DAYS]` can be used as `/r 30` or left empty. -### Add income: `add income` +### Add cashflow + +#### Add income: `add income` Adds an income source to the Financial Planner. Format: `add income /a AMOUNT /t TYPE [/r DAYS] [/d DESCRIPTION]` @@ -80,7 +94,7 @@ to the Financial Planner. Balance: 5000.00 ``` - Note: Balance displayed above is just an example. Your actual balance may differ. -### Add expense: `add expense` +#### Add expense: `add expense` Adds an expense to the Financial Planner Format: `add expense /a AMOUNT /t TYPE [/r DAYS] [/d DESCRIPTION]` @@ -117,7 +131,7 @@ Deletes a cashflow from the Financial Planner. Format: `delete INDEX [/r]` -- `INDEX` refers to the index number shown in the displayed list when [`list`](#list-all) command is used. +- `INDEX` refers to the index number shown in the displayed list when [`list`](#list-all-list) command is used. - `/r` is used to delete all **future** cashflows **only**. Example of usage: `delete 1 /r` @@ -144,12 +158,12 @@ Balance: -1130.00 ``` - Note: Balance displayed above is just an example. Your actual balance may differ. -### Delete income: `delete income` +#### Delete income: `delete income` Deletes an income from the Financial Planner. Format: `delete income INDEX [/r]` -- `INDEX` refers to the index number shown in the displayed list when [`list income`](#list-income) command is used. +- `INDEX` refers to the index number shown in the displayed list when [`list income`](#list-income-list-income) command is used. - `/r` is used to delete all **future** incomes **only**. Example of usage: `delete income 2 /r` @@ -176,12 +190,12 @@ Balance: 5170.00 ``` - Note: Balance displayed above is just an example. Your actual balance may differ. -### Delete expense: `delete expense` +#### Delete expense: `delete expense` Deletes an expense from the Financial Planner. Format: `delete expense INDEX [/r]` -- `INDEX` refers to the index number shown in the displayed list when [`list expense`](#list-expense) command is used. +- `INDEX` refers to the index number shown in the displayed list when [`list expense`](#list-expense-list-expense) command is used. - `/r` is used to delete all **future** expenses **only**. Example of usage: `delete expense 2 /r` @@ -208,12 +222,12 @@ Balance: -330.00 ``` - Note: Balance displayed above is just an example. Your actual balance may differ. -### Delete recurring: `delete recurring` +#### Delete recurring: `delete recurring` Deletes a recurring cashflow from the Financial Planner. Format: `delete recurring INDEX [/r]` -- `INDEX` refers to the index number shown in the displayed list when [`list recurring`](#list-recurring) command is used. +- `INDEX` refers to the index number shown in the displayed list when [`list recurring`](#list-recurring-list-recurring) command is used. - `/r` is used to delete all **future** recurring cashflows **only**. Example of usage: `delete recurring 2 /r` @@ -241,7 +255,9 @@ Balance: -830.00 - Note: Balance displayed above is just an example. Your actual balance may differ. ``` -### List all +### List + +#### List all: `list` // TODO Example output: @@ -268,7 +284,7 @@ You have 4 matching cashflows: Recurring every: 30 days, starting from: Oct 30 2023 Description: groceries ``` -### List income +#### List income: `list income` //TODO Example output: @@ -288,7 +304,7 @@ You have 3 matching cashflows: Type: Investments Amount: 1000.00 ``` -### List expense +#### List expense: `list expense` //TODO Example output: @@ -309,7 +325,7 @@ You have 3 matching cashflows: Recurring every: 30 days, starting from: Oct 30 2023 Description: groceries ``` -### List recurring: `list recurring` +#### List recurring: `list recurring` Lists all recurring cashflows. Format: `list recurring` From 84dafe2fbbb343206ff977905ca52d1b7efc8c15 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 30 Oct 2023 12:10:01 +0800 Subject: [PATCH 297/518] Fix typos --- docs/UserGuide.md | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 7684f746e9..6bbd2279f4 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -46,8 +46,8 @@ you a one-stop interface to access a plethora of features to manage your finance {Give steps to get started quickly} 1. Ensure that you have Java 11 or above installed. -2. Down the latest version of `Financial Planner` from [here](http://link.to/duke). -3. Copy the file to the folder you want to use as the *home folder* for Neo Chatbot. +2. Download the latest version of `Financial Planner` from [here](http://link.to/duke). +3. Copy the file to the folder you want to use as the *home folder* for Financial Planner. 4. Open a command terminal, `cd` into the folder you put the jar file in, and use the `java -jar ip.jar` command to run the application. 5. Refer to the **Features** section below for details of each command. @@ -559,26 +559,26 @@ Existing data will be automatically loaded when the program starts up. {Give a 'cheat sheet' of commands here} -| Action | Format | -|----------------------------------|------------------------------------------------------------| -| **Add income** | `add income /a AMOUNT /t TYPE [/r DAYS] [/d DESCRIPTION]` | +| Action | Format | +|----------------------------------|-----------------------------------------------------------| +| **Add income** | `add income /a AMOUNT /t TYPE [/r DAYS] [/d DESCRIPTION]` | | **Add expense** | `add expense /a AMOUNT /t TYPE [/r DAYS] [/d DESCRIPTION]` | -| **Delete cashflow** | `delete INDEX [/r]` | -| **Delete income** | `delete income INDEX [/r]` | -| **Delete expense** | `delete expense INDEX [/r]` | -| **Delete recurrence** | `delete recurrence INDEX [/r]` | -| **list all cashflows** | `list` | -| **list all incomes** | `list income` | -| **list all expenses** | `list expense` | -| **list all recurring cashflows** | `list recurrence* | -| **Set budget** | `budget set /b BUDGET` | -| **Update budget** | `budget update /b BUDGET` | -| **Reset budget** | `budget reset` | -| **Delete budget** | `budget delete` | -| **View budget** | `budget view` | -| **Display Overview** | `overview` | -| **View balance** | `balance` | -| **Exit program** | `exit` | +| **Delete cashflow** | `delete INDEX [/r]` | +| **Delete income** | `delete income INDEX [/r]` | +| **Delete expense** | `delete expense INDEX [/r]` | +| **Delete recurrence** | `delete recurrence INDEX [/r]` | +| **list all cashflows** | `list` | +| **list all incomes** | `list income` | +| **list all expenses** | `list expense` | +| **list all recurring cashflows** | `list recurrence` | +| **Set budget** | `budget set /b BUDGET` | +| **Update budget** | `budget update /b BUDGET` | +| **Reset budget** | `budget reset` | +| **Delete budget** | `budget delete` | +| **View budget** | `budget view` | +| **Display Overview** | `overview` | +| **View balance** | `balance` | +| **Exit program** | `exit` | - Note: Cashflow is referring to an income or expense From ac93b149bf74c52ab090855d5204d8f6f7118339 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 30 Oct 2023 12:24:48 +0800 Subject: [PATCH 298/518] Update text ui test --- text-ui-test/EXPECTED.TXT | 7 +------ text-ui-test/input.txt | 6 +++--- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index eb1bfd89a1..91776db83d 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -2,12 +2,11 @@ Directory doesn't exist. Creating directory... Watchlist file not found... Creating Initializing New watchlist.. adding AAPL and GOOGL for your reference File not found. Creating new file... -Current date: Oct 29 2023 +Current date: Oct 30 2023 Welcome to your Financial Planner. Type something to get started. You have added an Income Type: Salary Amount: 5000.00 - Recurring every: 30 days, starting from: Oct 29 2023 Description: part time job to the Financial Planner. Balance: 5000.00 @@ -19,7 +18,6 @@ Balance: 5123.12 You have added an Expense Type: Entertainment Amount: 100.00 - Recurring every: 30 days, starting from: Oct 29 2023 Description: netflix to the Financial Planner. Balance: 5023.12 @@ -36,7 +34,6 @@ Balance: 4776.79 You have removed an Income Type: Salary Amount: 5000.00 - Recurring every: 30 days, starting from: Oct 29 2023 Description: part time job from the Financial Planner. Balance: -223.21 @@ -48,7 +45,6 @@ Balance: -100.00 You have removed an Expense Type: Entertainment Amount: 100.00 - Recurring every: 30 days, starting from: Oct 29 2023 Description: netflix from the Financial Planner. Balance: 0.00 @@ -61,7 +57,6 @@ Use Watchlist to view it! You have added an Income Type: Salary Amount: 5000.00 - Recurring every: 30 days, starting from: Oct 29 2023 to the Financial Planner. Balance: 5000.00 A monthly budget of 3000.00 has been set. diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index 9c5bae1bdc..60d9e76fe5 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -1,6 +1,6 @@ -add income /a 5000 /t salary /r 30 /d part time job +add income /a 5000 /t salary /d part time job add income /a 123.12 /t allowance -add expense /a 100 /t entertainment /r 30 /d netflix +add expense /a 100 /t entertainment /d netflix add expense /a 123.21 /t shopping delete income 2 delete 1 @@ -8,7 +8,7 @@ delete expense 2 delete 1 addstock /s MSFT addstock /s GME -add income /a 5000 /t salary /r 30 +add income /a 5000 /t salary budget set /b 3000 budget update /b 1000 add expense /a 200 /t shopping From 1a00cd458d480c492d49724d6a170bf1aaff22cc Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 30 Oct 2023 12:29:07 +0800 Subject: [PATCH 299/518] Update toString() in cashflow --- src/main/java/seedu/financialplanner/cashflow/Cashflow.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/cashflow/Cashflow.java b/src/main/java/seedu/financialplanner/cashflow/Cashflow.java index 739acf81a1..e4ba13f2f5 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Cashflow.java +++ b/src/main/java/seedu/financialplanner/cashflow/Cashflow.java @@ -77,7 +77,8 @@ public String toString() { if (recur != 0) { string += System.lineSeparator() + " Recurring every: " + recur + " days"; - string += ", starting from: " + date.format(DateTimeFormatter.ofPattern("MMM dd yyyy")); + string += ", date added: " + date.format(DateTimeFormatter.ofPattern("MMM dd yyyy")); + string += ", recurring on: " + date.plusDays(recur).format(DateTimeFormatter.ofPattern("MMM dd yyyy")); } if (description != null) { string += System.lineSeparator() + " Description: " + description; From 952b76b9be37a317392c19b292672adba24eddd9 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 30 Oct 2023 17:42:44 +0800 Subject: [PATCH 300/518] Fix typo --- src/main/java/seedu/financialplanner/storage/LoadData.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index b71fcbf774..cf51a603e0 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -162,7 +162,7 @@ public static HashMap loadWatchList() { ui.showMessage("Watchlist JSON is corrupted!"); ui.showMessage("Would you like to create new file? (Y/N)"); if (!createNewFile()) { - ui.showMessage("Exiting... Plese fix the file"); + ui.showMessage("Exiting... Please fix the file"); System.exit(1); } } From ce1819a6196432378efde13d53729688cce039b0 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 30 Oct 2023 17:47:40 +0800 Subject: [PATCH 301/518] Fix test ui --- text-ui-test/EXPECTED.TXT | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index eb1bfd89a1..fac51570d2 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -2,12 +2,12 @@ Directory doesn't exist. Creating directory... Watchlist file not found... Creating Initializing New watchlist.. adding AAPL and GOOGL for your reference File not found. Creating new file... -Current date: Oct 29 2023 +Current date: Oct 30 2023 Welcome to your Financial Planner. Type something to get started. You have added an Income Type: Salary Amount: 5000.00 - Recurring every: 30 days, starting from: Oct 29 2023 + Recurring every: 30 days, starting from: Oct 30 2023 Description: part time job to the Financial Planner. Balance: 5000.00 @@ -19,7 +19,7 @@ Balance: 5123.12 You have added an Expense Type: Entertainment Amount: 100.00 - Recurring every: 30 days, starting from: Oct 29 2023 + Recurring every: 30 days, starting from: Oct 30 2023 Description: netflix to the Financial Planner. Balance: 5023.12 @@ -36,7 +36,7 @@ Balance: 4776.79 You have removed an Income Type: Salary Amount: 5000.00 - Recurring every: 30 days, starting from: Oct 29 2023 + Recurring every: 30 days, starting from: Oct 30 2023 Description: part time job from the Financial Planner. Balance: -223.21 @@ -48,7 +48,7 @@ Balance: -100.00 You have removed an Expense Type: Entertainment Amount: 100.00 - Recurring every: 30 days, starting from: Oct 29 2023 + Recurring every: 30 days, starting from: Oct 30 2023 Description: netflix from the Financial Planner. Balance: 0.00 @@ -61,7 +61,7 @@ Use Watchlist to view it! You have added an Income Type: Salary Amount: 5000.00 - Recurring every: 30 days, starting from: Oct 29 2023 + Recurring every: 30 days, starting from: Oct 30 2023 to the Financial Planner. Balance: 5000.00 A monthly budget of 3000.00 has been set. From 0a731bad2ef28a74bad3566f002083d755c46436 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 30 Oct 2023 19:36:18 +0800 Subject: [PATCH 302/518] Remove displaying of current date upon program startup --- src/main/java/seedu/financialplanner/FinancialPlanner.java | 2 +- src/main/java/seedu/financialplanner/utils/Ui.java | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index dba440ff5a..bdd75a6d00 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -33,7 +33,7 @@ public void run() { return; } - ui.welcomeMessage(date); + ui.welcomeMessage(); String input; Command command = null; diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 95fc57cc20..f3231e74de 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -6,8 +6,6 @@ import seedu.financialplanner.cashflow.Budget; import seedu.financialplanner.cashflow.Cashflow; -import java.time.LocalDate; -import java.time.format.DateTimeFormatter; import java.text.SimpleDateFormat; import java.util.Map; import java.util.Scanner; @@ -49,8 +47,7 @@ public void showMessage(String message) { System.out.println(message); } - public void welcomeMessage(LocalDate date) { - System.out.println("Current date: " + date.format(DateTimeFormatter.ofPattern("MMM dd yyyy"))); + public void welcomeMessage() { showMessage("Welcome to your Financial Planner. Type something to get started."); } From 1b0201f634d259d884e552d7bb1a576b83125dfe Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 30 Oct 2023 19:36:29 +0800 Subject: [PATCH 303/518] Update text ui test --- text-ui-test/EXPECTED.TXT | 1 - 1 file changed, 1 deletion(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 91776db83d..b95506d485 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -2,7 +2,6 @@ Directory doesn't exist. Creating directory... Watchlist file not found... Creating Initializing New watchlist.. adding AAPL and GOOGL for your reference File not found. Creating new file... -Current date: Oct 30 2023 Welcome to your Financial Planner. Type something to get started. You have added an Income Type: Salary From e183dbe4aa475904939eafac0effb07e126cec4a Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Tue, 31 Oct 2023 08:28:19 +0800 Subject: [PATCH 304/518] Check for response status when adding new stock and check for US region --- .../java/seedu/financialplanner/investments/Stock.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/seedu/financialplanner/investments/Stock.java b/src/main/java/seedu/financialplanner/investments/Stock.java index 58135666a5..08894ca4db 100644 --- a/src/main/java/seedu/financialplanner/investments/Stock.java +++ b/src/main/java/seedu/financialplanner/investments/Stock.java @@ -51,6 +51,10 @@ public String getStockNameFromAPI(String symbol) throws FinancialPlannerExceptio logger.log(Level.INFO, "Requesting API for stock info"); try { HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + if (response.statusCode() != 200) { + throw new FinancialPlannerException("API might be down at the moment..."); + } + Object obj = new JSONParser().parse(response.body()); JSONObject jsonObject = (JSONObject) obj; @@ -69,6 +73,11 @@ public String getStockNameFromAPI(String symbol) throws FinancialPlannerExceptio throw new FinancialPlannerException("Stock not found"); } + String region = (String) stock.get("4. region"); + if (!region.equals("United States")) { + throw new FinancialPlannerException("Only US stocks are available due to free nature of API :("); + } + assert stock.get("2. name") != null; return (String) stock.get("2. name"); } catch (IOException e) { From ba1459fc3ac4a44558d2b8f8f0839704a92ada46 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Tue, 31 Oct 2023 08:28:50 +0800 Subject: [PATCH 305/518] Add check for response code and change exception handling --- .../seedu/financialplanner/investments/WatchList.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index 81d2ab1a15..7fec595f3f 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -92,17 +92,20 @@ public void fetchFMPStockPrices(StringBuilder queryStocks) throws FinancialPlann logger.log(Level.INFO, "Requesting API endpoint FMP"); try { HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + if(response.statusCode() != 200) { + throw new FinancialPlannerException("API might be down at the moment..."); + } // System.out.println(response.body()); obj = new JSONParser().parse(response.body()); } catch (IOException e) { - logger.log(Level.SEVERE, "Cant request API endpoint"); - throw new RuntimeException(e); + logger.log(Level.SEVERE, "IO exception when sending request or receiving response"); + throw new FinancialPlannerException("Is your internet down?"); } catch (InterruptedException e) { logger.log(Level.SEVERE, "Interrupted"); - throw new RuntimeException(e); + throw new FinancialPlannerException("Request to API was interrupted"); } catch (ParseException e) { logger.log(Level.SEVERE, "Could not parse to JSON"); - throw new RuntimeException(e); + throw new FinancialPlannerException("Could not parse to JSON format"); } extractWatchlistInfoFromJSONArray((JSONArray) obj); } From 342ce085e6af7170891620aee9c32427e55ff9a7 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Tue, 31 Oct 2023 08:29:11 +0800 Subject: [PATCH 306/518] Add ui message for loading watchlist --- src/main/java/seedu/financialplanner/storage/LoadData.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 9a9810b014..6c8282de07 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -257,6 +257,7 @@ public static HashMap loadWatchList() { Ui ui = Ui.getInstance(); Gson gson = new Gson(); HashMap stocksData = new HashMap<>(); + ui.showMessage("Loading existing watchlist.."); try { JsonReader reader = new JsonReader(new FileReader(FILE_PATH)); stocksData = gson.fromJson(reader, new TypeToken>(){}.getType()); From 4112d19e22da77f1f3c054adfe34e7d3bb9c675a Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Tue, 31 Oct 2023 09:00:56 +0800 Subject: [PATCH 307/518] Update UG --- docs/UserGuide.md | 88 +++++++++++++++++++++++++---------- docs/images/vis/barOuput.png | Bin 0 -> 35439 bytes 2 files changed, 64 insertions(+), 24 deletions(-) create mode 100644 docs/images/vis/barOuput.png diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 6bbd2279f4..1d8f51b804 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -471,7 +471,11 @@ Balance: 3790.00 View your current watchlist with stocks that you are interested in with the exchanges shown as well -Default watchlist: AAPL, GOOGL +Default watchlist: AAPL, GOOGL + +This stocks will be added to the watchlist automatically if: +- your watchlist file is corrupted, and you chose to override it +- your watchlist is empty on startup Format: `watchlist` @@ -480,12 +484,20 @@ Example of usage: `watchlist` Example of output: ``` -Symbol Market Price Daily High Daily Low EquityName -AAPL NASDAQ 168.22 168.96 166.84 Apple Inc -GOOGL NASDAQ 122.17 123.31 120.2057 Alphabet Inc - Class A -GME NYSE 13.12 13.615 13.02 Gamestop Corporation - Class A +Symbol Market Price Daily High Daily Low EquityName Last Updated +GOOGL NASDAQ 124.46 125.4 122.75 Alphabet Inc - Class A Tue, Oct 31 2023 04:00:03 +AAPL NASDAQ 170.29 171.17 168.87 Apple Inc Tue, Oct 31 2023 04:00:02 ``` +Format of watchlist output: + +| Symbol | Market | Price | Daily High | Daily Low | Equity Name | Last Updated | +|--------------------------------------------------------|---------------------------------------|------------------------------------------------|--------------------------------|-------------------------------|------------------------|-------------------------------------------------------------------------| +| Ticker Symbol
(Abbreviation for Company 's Stocks) | Exchange at which the stock is traded | Current latest price of stock (before closing) | Intraday Highest trading price | Intraday Lowest trading price | Name of equity product | Last time at which the information of the stocks was updated by the API | + +- Note: To prevent overloading of the stock API, we will only be allowing watchlist updates every 5 minutes. +Any request within the 5-minute window will only show the last updated watchlist + ### Adding Stock to Watchlist: `addstock` Add a stock that you are interested in monitoring into your personal WatchList @@ -502,6 +514,10 @@ Meta Platforms Inc - Class A Use Watchlist to view it! ``` +- Note: Due to the free nature of the API (Alphpa Vantage and FMP), only US stock prices quote will be provided by +this application. Sorry for the inconvenience caused. +- Note: Due to the free nature of the API, there will be a cap of **five** stocks in the watchlist + ### Deleting Stock from Watchlist: `deletestock` Delete a stock that you are no longer interested in monitoring from your personal WatchList @@ -518,13 +534,25 @@ Meta Platforms Inc - Class A Use watchlist command to view updated Watchlist ``` +- Note: Your watchlist information is saved under the file path `data/watchlist.json` in JSON format + ### Visualizing your cashflow: `vis` Using this command to visualize your income or expenses in a pie chart or bar chart Format: `vis /t TYPE /c TOOL` -Example of usage: `vis /t income /c pie` +| Type `/t` | +|-----------------------------| +| Income Cashflows `Income` | +| Expense Cashflows `Expense` | + +| Tool `/c` | +|----------------| +| PieChart `pie` | +| BarChart `bar` | + +Example of usage: `vis /t expense /c pie` Example of output: @@ -534,6 +562,14 @@ Displaying piechart for expense ![](images/vis/visOutput.png) +Example of usage: `vis /t expense /c bar` + +``` +Displaying barchart for income +``` + +![](images/vis/barOuput.png) + ### Exiting the program: `exit` Exits the program. @@ -559,26 +595,30 @@ Existing data will be automatically loaded when the program starts up. {Give a 'cheat sheet' of commands here} -| Action | Format | -|----------------------------------|-----------------------------------------------------------| -| **Add income** | `add income /a AMOUNT /t TYPE [/r DAYS] [/d DESCRIPTION]` | +| Action | Format | +|----------------------------------|------------------------------------------------------------| +| **Add income** | `add income /a AMOUNT /t TYPE [/r DAYS] [/d DESCRIPTION]` | | **Add expense** | `add expense /a AMOUNT /t TYPE [/r DAYS] [/d DESCRIPTION]` | -| **Delete cashflow** | `delete INDEX [/r]` | -| **Delete income** | `delete income INDEX [/r]` | -| **Delete expense** | `delete expense INDEX [/r]` | -| **Delete recurrence** | `delete recurrence INDEX [/r]` | -| **list all cashflows** | `list` | -| **list all incomes** | `list income` | -| **list all expenses** | `list expense` | +| **Delete cashflow** | `delete INDEX [/r]` | +| **Delete income** | `delete income INDEX [/r]` | +| **Delete expense** | `delete expense INDEX [/r]` | +| **Delete recurrence** | `delete recurrence INDEX [/r]` | +| **list all cashflows** | `list` | +| **list all incomes** | `list income` | +| **list all expenses** | `list expense` | | **list all recurring cashflows** | `list recurrence` | -| **Set budget** | `budget set /b BUDGET` | -| **Update budget** | `budget update /b BUDGET` | -| **Reset budget** | `budget reset` | -| **Delete budget** | `budget delete` | -| **View budget** | `budget view` | -| **Display Overview** | `overview` | -| **View balance** | `balance` | -| **Exit program** | `exit` | +| **Set budget** | `budget set /b BUDGET` | +| **Update budget** | `budget update /b BUDGET` | +| **Reset budget** | `budget reset` | +| **Delete budget** | `budget delete` | +| **View budget** | `budget view` | +| **Display Overview** | `overview` | +| **View balance** | `balance` | +| **View Watchlist** | `watchlist` | +| **Add to watchlist** | `addstock /s STOCKCODE` | +| **Delete from watchlist** | `deletestock /s STOCKCODE` | +| **Visualization** | `vis /t TYPE /c CHART` | +| **Exit program** | `exit` | - Note: Cashflow is referring to an income or expense diff --git a/docs/images/vis/barOuput.png b/docs/images/vis/barOuput.png new file mode 100644 index 0000000000000000000000000000000000000000..7993e2bb6a07dcf1fc8d1e0aaaecc2ea7900a4ac GIT binary patch literal 35439 zcmeFa2{_dI-#0$hQJp%a4VBQQM5u%iQXvV+ZY)Kz4%xG%loqm-QpgfzUmD9`Y%TV( zCEJXl?AwgUzCQ2IP)D8Lec!+5`d`=odhX}BT~{4PW4`<6{d&Ka_uN0PD7$XW_B9v` zW}V!b(-$z96&)DN^10P3;U{~ITQuQ6%WN;mp2Q?q?&yX8`NLRBK?;Mx`>mb1!~p;Q z=hZV>wiwJNJM?E+%N34m7>w5+a;K$Kujx@Kf95`^ohupAKM=hC_U^c>#|KpI9NAlT z+;N@z={s##Rtu|MIa{c9N9TP}=h@X|kG1ZUZ|L@lJ;U{+>*1sM+2pX8Fk4Zo8_C6f zOv2c$C8goJsEefeyl9SScV@$&R=-xlyJm)hSySofHj_R=Uxo#ev@^^I21RRF$7hdD zyS`Hm$+-A%Haqg$2Oibfi**S&6S8G?9JMwVk4wK~{E+tyZv;l%e~6PqfW!)gnmUbw%fKcbIx)7y~^OaxNPMSlUJ8><`QQakCpP}cN`hl zdDPt|DKOS|FEjDfG+}Jgy#(7{Ol~xKs@GAuzaYG4<`iSgAUlg&IGiiY`9SfBH#__7 z?HRE|J5#&pYijYT_z=tNx=N8udAsO=rnpIh19eoGe1E_FgUT&~K{0n51@n^AQ}QSI zMANS8jAaHSHG0f^uR15U-A4zJ7b8rW3sN` z)z{*rac;-;Xwx@z&MUAsBusuu5Ae(Ms%byzKzR}5Hq&ZlL7QPn-sY>_Q($BuptV{$vU(PIbw+eAt8&{X;^VCwnT*wBAwb7SEjZ|sQJxeEPc=PIsJ z`UXpv{nszKxrTv(!Cl6W{tG7#Wc9@-Y~8i+HZ1=eZ}V?#>HqsnxMcO5dpUCk^QQ;u zH1vHc;X=4dORdM85IN#HaTOhF`D*:cL^N_<7Swvx?L@*)M`l<2E*adAxuIR6E& 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

CA|T9I>` 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 literal 0 HcmV?d00001 From 8cc7df5d8e3370fe36cd9b60d1927a88a292394b Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Tue, 31 Oct 2023 09:08:36 +0800 Subject: [PATCH 308/518] Update DG acknowledgement --- docs/DeveloperGuide.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index f439f93ff8..ab120bad78 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -22,6 +22,10 @@ - author: Google - source: [https://github.com/google/gson](https://github.com/google/gson) +**Financial Modeling Prep Stock API** +- author: Financial Modeling Prep +- source: https://site.financialmodelingprep.com/ + **round() method in Cashflow.java** - author: mhadidg - source: [https://stackoverflow.com/questions/2808535/round-a-double-to-2-decimal-places]() From 87732a08f74285913b94c1dbdb06e4823d8b7555 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Tue, 31 Oct 2023 09:16:00 +0800 Subject: [PATCH 309/518] Update text ui --- text-ui-test/EXPECTED.TXT | 1 + 1 file changed, 1 insertion(+) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index b95506d485..1962194fd4 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,4 +1,5 @@ Directory doesn't exist. Creating directory... +Loading existing watchlist.. Watchlist file not found... Creating Initializing New watchlist.. adding AAPL and GOOGL for your reference File not found. Creating new file... From 27e3cf1017463e5196bd8ec28733c8107ac1308f Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 31 Oct 2023 09:18:35 +0800 Subject: [PATCH 310/518] Add javadoc for Budget --- .../financialplanner/cashflow/Budget.java | 75 ++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/cashflow/Budget.java b/src/main/java/seedu/financialplanner/cashflow/Budget.java index 6aaae47a11..cf0540f535 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Budget.java +++ b/src/main/java/seedu/financialplanner/cashflow/Budget.java @@ -2,11 +2,19 @@ import java.text.DecimalFormat; +/** + * Represents the monthly budget. + */ public abstract class Budget { private static final int MONTH = 30; private static double initialBudget = 0; private static double currentBudget = 0; + /** + * Sets the monthly budget equal to amount. + * + * @param amount The monthly budget to be set + */ public static void setBudget(double amount) { initialBudget = amount; currentBudget = amount; @@ -14,10 +22,21 @@ public static void setBudget(double amount) { assert initialBudget != 0 && currentBudget != 0 : "Initial and current budget should not be 0"; } + /** + * Returns the initial budget set. + * + * @return The initial budget. + */ public static double getInitialBudget() { return initialBudget; } + /** + * Updates initial budget to the new budget and updates the current budget + * with the difference between the old initial budget and new initial budget. + * + * @param budget The budget to be updated to. + */ public static void updateBudget(double budget) { double diff; if (budget > initialBudget) { @@ -32,50 +51,104 @@ public static void updateBudget(double budget) { assert initialBudget == budget : "Initial budget should be equal to updated budget"; } + /** + * Returns the current budget. + * + * @return The current budget. + */ public static double getCurrentBudget() { return currentBudget; } + /** + * Returns the current budget in 2 decimal places after converting + * it into a string. + * + * @return The current budget in string format. + */ public static String getCurrentBudgetString() { DecimalFormat decimalFormat = new DecimalFormat("####0.00"); return decimalFormat.format(Cashflow.round(currentBudget, 2)); } + /** + * Returns the initial budget in 2 decimal places after converting + * it into a string. + * + * @return The initial budget in string format. + */ public static String getInitialBudgetString() { DecimalFormat decimalFormat = new DecimalFormat("####0.00"); return decimalFormat.format(Cashflow.round(initialBudget, 2)); } + /** + * Deducts the current budget by the amount given. + * + * @param amount The amount to be deducted. + */ public static void deduct(double amount) { - Budget.currentBudget -= amount; + currentBudget -= amount; } + /** + * Loads the budget from the save file. + * + * @param initial The saved initial budget. + * @param current The saved current budget. + */ public static void load(double initial, double current) { initialBudget = initial; currentBudget = current; } + /** + * Checks if there is a budget. + * + * @return True if there is a budget set, false otherwise. + */ public static boolean hasBudget() { return initialBudget != 0; } + /** + * Returns a string representation of the budget to be saved to the save file. + * + * @return A string representation of the budget. + */ public static String formatString() { return "B | " + initialBudget + " | " + currentBudget; } + /** + * Deletes an existing budget. + */ public static void deleteBudget() { initialBudget = 0; currentBudget = 0; } + /** + * Resets the current budget to initial budget. + */ public static void resetBudget() { currentBudget = initialBudget; } + /** + * Sets initial budget to the amount given. + * + * @param amount The amount to be set. + */ public static void setInitialBudget(double amount) { initialBudget = amount; } + /** + * Updates current budget by adding amount to current budget. + * + * @param amount The amount to be updated. + */ public static void updateCurrentBudget(double amount) { currentBudget += amount; } From 68bbd6e6679f1214ba5290bccce7aeec20d16eee Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 31 Oct 2023 11:10:35 +0800 Subject: [PATCH 311/518] Add javadoc for BudgetCommand --- .../commands/BudgetCommand.java | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java index 9dc8d19547..60f24a66f6 100644 --- a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java +++ b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java @@ -9,12 +9,21 @@ import java.util.logging.Logger; import java.util.ArrayList; +/** + * Represents a command to manage the budget. + */ public class BudgetCommand extends Command { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private final Ui ui = Ui.getInstance(); private double budget; private String command; + /** + * Constructs a new BudgetCommand and checks if the user input is a valid command. + * + * @param rawCommand The raw command containing the arguments and parameters given by the user. + * @throws FinancialPlannerException If there is an issue with the command provided. + */ public BudgetCommand(RawCommand rawCommand) throws FinancialPlannerException { command = rawCommand.args.get(0); if (command.equals("delete") || command.equals("reset") || command.equals("view")) { @@ -33,6 +42,12 @@ public BudgetCommand(RawCommand rawCommand) throws FinancialPlannerException { } } + /** + * Checks if budget is a positive number and is lower than or equal to total balance. + * + * @param rawCommand The raw command containing arguments and parameters given by the user. + * @throws FinancialPlannerException If there is an issue with budget format. + */ private void validateBudget(RawCommand rawCommand) throws FinancialPlannerException { try { logger.log(Level.INFO, "Parsing budget as double"); @@ -48,10 +63,16 @@ private void validateBudget(RawCommand rawCommand) throws FinancialPlannerExcept if (budget > Cashflow.getBalance()) { logger.log(Level.WARNING, "Invalid value for budget"); - throw new FinancialPlannerException("Budget should be lower than total balance."); + throw new FinancialPlannerException("Budget should be lower than or equal to total balance."); } } + /** + * Checks that the command is valid and in the right format. + * + * @param rawCommand The raw command containing arguments and parameters given by the user. + * @throws FinancialPlannerException If there is an issue with the command or format. + */ private void validateCommandFormat(RawCommand rawCommand) throws FinancialPlannerException { if (!command.equals("set") && !command.equals("update")) { logger.log(Level.WARNING, "Invalid arguments for budget command"); @@ -73,6 +94,9 @@ private void validateCommandFormat(RawCommand rawCommand) throws FinancialPlanne } } + /** + * Executes the budget command based on the specified operation. + */ @Override public void execute() { assert command.equals("set") || command.equals("update") || command.equals("delete") || From 6338f2071b718b88b209d9d04b6a61c6175d74f8 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 31 Oct 2023 11:22:18 +0800 Subject: [PATCH 312/518] Add javadoc for BalanceCommand --- .../java/seedu/financialplanner/cashflow/Budget.java | 2 +- .../financialplanner/commands/BalanceCommand.java | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/seedu/financialplanner/cashflow/Budget.java b/src/main/java/seedu/financialplanner/cashflow/Budget.java index cf0540f535..6d24cc6939 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Budget.java +++ b/src/main/java/seedu/financialplanner/cashflow/Budget.java @@ -146,7 +146,7 @@ public static void setInitialBudget(double amount) { /** * Updates current budget by adding amount to current budget. - * + * * @param amount The amount to be updated. */ public static void updateCurrentBudget(double amount) { diff --git a/src/main/java/seedu/financialplanner/commands/BalanceCommand.java b/src/main/java/seedu/financialplanner/commands/BalanceCommand.java index 152b4da378..540f9df0bf 100644 --- a/src/main/java/seedu/financialplanner/commands/BalanceCommand.java +++ b/src/main/java/seedu/financialplanner/commands/BalanceCommand.java @@ -6,9 +6,12 @@ import java.text.DecimalFormat; import java.util.ArrayList; +/** + * Represents a command for displaying balance. + */ public class BalanceCommand extends Command { private final Ui ui = Ui.getInstance(); - + public BalanceCommand(RawCommand rawCommand) { if (!rawCommand.extraArgs.isEmpty()) { String unknownExtraArgument = new ArrayList<>(rawCommand.extraArgs.keySet()).get(0); @@ -16,8 +19,11 @@ public BalanceCommand(RawCommand rawCommand) { } } + /** + * Executes the command to display balance. + */ @Override - public void execute() throws Exception { + public void execute() { ui.showMessage("Balance: " + getBalanceString()); } From 671c5dac58e033f23aae0305f24e966924f8969a Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 31 Oct 2023 11:31:29 +0800 Subject: [PATCH 313/518] Add javadoc for exit, invalid, overview and general commands --- .../java/seedu/financialplanner/commands/Command.java | 3 +++ .../java/seedu/financialplanner/commands/ExitCommand.java | 3 +++ .../seedu/financialplanner/commands/InvalidCommand.java | 7 +++++++ .../seedu/financialplanner/commands/OverviewCommand.java | 8 +++++++- 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/commands/Command.java b/src/main/java/seedu/financialplanner/commands/Command.java index 135ccd4e4d..6b7b7e3e74 100644 --- a/src/main/java/seedu/financialplanner/commands/Command.java +++ b/src/main/java/seedu/financialplanner/commands/Command.java @@ -1,5 +1,8 @@ package seedu.financialplanner.commands; +/** + * Represents a generic command that can be inherited. + */ public abstract class Command { public abstract void execute() throws Exception; } diff --git a/src/main/java/seedu/financialplanner/commands/ExitCommand.java b/src/main/java/seedu/financialplanner/commands/ExitCommand.java index 3c331475a6..03b5eb4285 100644 --- a/src/main/java/seedu/financialplanner/commands/ExitCommand.java +++ b/src/main/java/seedu/financialplanner/commands/ExitCommand.java @@ -2,6 +2,9 @@ import java.util.ArrayList; +/** + * Represents a command to exit the program. + */ public class ExitCommand extends Command { public ExitCommand(RawCommand rawCommand) { if (!rawCommand.extraArgs.isEmpty()) { diff --git a/src/main/java/seedu/financialplanner/commands/InvalidCommand.java b/src/main/java/seedu/financialplanner/commands/InvalidCommand.java index 97bc73e9fa..68860c4c1a 100644 --- a/src/main/java/seedu/financialplanner/commands/InvalidCommand.java +++ b/src/main/java/seedu/financialplanner/commands/InvalidCommand.java @@ -2,10 +2,17 @@ import seedu.financialplanner.utils.Ui; +/** + * Represents a command for an invalid input. + */ public class InvalidCommand extends Command { public InvalidCommand() { } + /** + * Executes the command to display an error message when an + * invalid input is received. + */ @Override public void execute() { Ui.getInstance().showMessage("Unknown command. Please try again."); diff --git a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java index 9aa2107a08..5242987f99 100644 --- a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java +++ b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java @@ -12,6 +12,9 @@ import java.text.DecimalFormat; import java.util.ArrayList; +/** + * Represents a command to display overview of user's financials. + */ public class OverviewCommand extends Command { private static final CashflowList cashflowList = CashflowList.getInstance(); @@ -22,8 +25,11 @@ public OverviewCommand(RawCommand rawCommand) { } } + /** + * Executes the command and displays an overview of the user's financials. + */ @Override - public void execute() throws Exception { + public void execute() { String balance = getBalance(); String highestIncome = getHighestIncome(); String highestExpense = getHighestExpense(); From f331a2cdae5e0308e0d57243b1073b0034657d53 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 31 Oct 2023 13:30:45 +0800 Subject: [PATCH 314/518] Add javadocs --- .../financialplanner/FinancialPlanner.java | 18 +++++++++++++++++ .../FinancialPlannerLogger.java | 6 ++++++ .../exceptions/FinancialPlannerException.java | 3 +++ .../financialplanner/storage/LoadData.java | 20 +++++++++++++++++-- .../financialplanner/storage/SaveData.java | 4 +++- .../financialplanner/storage/Storage.java | 3 +++ .../java/seedu/financialplanner/utils/Ui.java | 3 +++ 7 files changed, 54 insertions(+), 3 deletions(-) diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index bdd75a6d00..6d6e3c33a9 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -1,5 +1,6 @@ package seedu.financialplanner; +import seedu.financialplanner.cashflow.CashflowList; import seedu.financialplanner.commands.Command; import seedu.financialplanner.commands.ExitCommand; import seedu.financialplanner.exceptions.FinancialPlannerException; @@ -10,21 +11,35 @@ import java.time.LocalDate; +/** + * Represents the main class for the Financial Planner. + * It manages commands and user interactions. + */ public class FinancialPlanner { private static final LocalDate date = LocalDate.now(); private static final String FILE_PATH = "data/data.txt"; private final Storage storage = Storage.getInstance(); private final Ui ui = Ui.getInstance(); private final WatchList watchList = WatchList.getInstance(); + private final CashflowList cashflowList = CashflowList.getInstance(); private FinancialPlanner() { } + /** + * The main starting point of the Financial Planner. + * + * @param args Unused. + */ public static void main(String[] args) { FinancialPlannerLogger.initialise(); new FinancialPlanner().run(); } + /** + * Loads storage from save file and starts the Financial Planner. + * Saves the storage to save file upon exit. + */ public void run() { try { storage.load(FILE_PATH, date); @@ -50,6 +65,9 @@ public void run() { ui.exitMessage(); } + /** + * Saves existing data to the save file. + */ public void save() { try { storage.save(FILE_PATH); diff --git a/src/main/java/seedu/financialplanner/FinancialPlannerLogger.java b/src/main/java/seedu/financialplanner/FinancialPlannerLogger.java index df085a588b..7751a7e0c5 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlannerLogger.java +++ b/src/main/java/seedu/financialplanner/FinancialPlannerLogger.java @@ -6,9 +6,15 @@ import java.util.logging.SimpleFormatter; import java.util.logging.LogManager; +/** + * Represents the logger for the Financial Planner. + */ public class FinancialPlannerLogger { private static Logger logger = Logger.getLogger("Financial Planner Logger"); + /** + * Initialises the logger and saves logging info to a file. + */ public static void initialise() { try { FileHandler fh = new FileHandler("data/logger.log"); diff --git a/src/main/java/seedu/financialplanner/exceptions/FinancialPlannerException.java b/src/main/java/seedu/financialplanner/exceptions/FinancialPlannerException.java index 387c7ddd06..bda7b2ab4b 100644 --- a/src/main/java/seedu/financialplanner/exceptions/FinancialPlannerException.java +++ b/src/main/java/seedu/financialplanner/exceptions/FinancialPlannerException.java @@ -1,5 +1,8 @@ package seedu.financialplanner.exceptions; +/** + * Represents exceptions specific to the Financial Planner. + */ public class FinancialPlannerException extends Exception { public FinancialPlannerException(String message) { super(message); diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 9a9810b014..cab7c5e59e 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -25,12 +25,22 @@ import java.util.HashMap; import java.util.Scanner; +/** + * Represents the loading of data from storage. + */ public abstract class LoadData { private static final String FILE_PATH = "data/watchlist.json"; private static final CashflowList cashflowList = CashflowList.getInstance(); private static final Ui ui = Ui.getInstance(); + /** + * Loads existing data from the storage file. + * + * @param filePath The file where the data is stored. + * @param date The current date. + * @throws FinancialPlannerException If there is an issue loading data from storage. + */ public static void load(String filePath, LocalDate date) throws FinancialPlannerException { try { Scanner inputFile = new Scanner(new FileReader(filePath)); @@ -148,8 +158,14 @@ private static void handleCorruptedFile(String message) throws FinancialPlannerE } private static void loadBudget(String[] split) throws IllegalArgumentException { - double initial = Double.parseDouble(split[1].trim()); - double current = Double.parseDouble(split[2].trim()); + double initial; + double current; + try { + initial = Double.parseDouble(split[1].trim()); + current = Double.parseDouble(split[2].trim()); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Error parsing budget values."); + } if (initial == 0 && current == 0) { return; } diff --git a/src/main/java/seedu/financialplanner/storage/SaveData.java b/src/main/java/seedu/financialplanner/storage/SaveData.java index b11872d84e..17e49e4e86 100644 --- a/src/main/java/seedu/financialplanner/storage/SaveData.java +++ b/src/main/java/seedu/financialplanner/storage/SaveData.java @@ -12,9 +12,11 @@ import java.io.FileWriter; import java.io.IOException; +/** + * Represents the saving of data to storage. + */ public abstract class SaveData { private static final String FILE_PATH = "data/watchlist.json"; - private static final CashflowList cashflowList = CashflowList.getInstance(); public static void save(String filePath) throws FinancialPlannerException { diff --git a/src/main/java/seedu/financialplanner/storage/Storage.java b/src/main/java/seedu/financialplanner/storage/Storage.java index 95eeaf7100..ef491dc34e 100644 --- a/src/main/java/seedu/financialplanner/storage/Storage.java +++ b/src/main/java/seedu/financialplanner/storage/Storage.java @@ -8,6 +8,9 @@ import java.nio.file.Paths; import java.time.LocalDate; +/** + * Represents the saving and loading of data. + */ public class Storage { private static Storage storage = null; private final Path path = Paths.get("data"); diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index f3231e74de..d183ca2e45 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -12,6 +12,9 @@ import java.util.logging.Level; import java.util.logging.Logger; +/** + * Represents the handling of user interactions. + */ public class Ui { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private static Ui ui = null; From 209fbf85255573871a45f6439c68d6f1d78206e1 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Tue, 31 Oct 2023 13:31:12 +0800 Subject: [PATCH 315/518] Add exception handling for non JSON array --- .../seedu/financialplanner/investments/WatchList.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index 7fec595f3f..ce9723dfa2 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -95,8 +95,8 @@ public void fetchFMPStockPrices(StringBuilder queryStocks) throws FinancialPlann if(response.statusCode() != 200) { throw new FinancialPlannerException("API might be down at the moment..."); } - // System.out.println(response.body()); obj = new JSONParser().parse(response.body()); + extractWatchlistInfoFromJSONArray((JSONArray) obj); } catch (IOException e) { logger.log(Level.SEVERE, "IO exception when sending request or receiving response"); throw new FinancialPlannerException("Is your internet down?"); @@ -106,11 +106,16 @@ public void fetchFMPStockPrices(StringBuilder queryStocks) throws FinancialPlann } catch (ParseException e) { logger.log(Level.SEVERE, "Could not parse to JSON"); throw new FinancialPlannerException("Could not parse to JSON format"); + } catch (ClassCastException e) { + logger.log(Level.SEVERE, "Did not receive object of class JSON Object"); + throw new FinancialPlannerException("Something went wrong when fetching API. Please try again"); } - extractWatchlistInfoFromJSONArray((JSONArray) obj); } public void extractWatchlistInfoFromJSONArray(JSONArray jsonstocks) throws FinancialPlannerException { + if (jsonstocks == null) { + throw new FinancialPlannerException("Incorrect API Response Received. Please try again"); + } if (jsonstocks.isEmpty()) { return; } From cbee184882430ab14d63d537f83937c7ddbf6a4f Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Tue, 31 Oct 2023 13:32:12 +0800 Subject: [PATCH 316/518] Improve clarity of visualization and remove showing chart for empty cashflow --- build.gradle | 2 +- .../financialplanner/commands/VisCommand.java | 15 ++++-- .../visualisations/Categorizer.java | 10 ++-- .../visualisations/Visualizer.java | 46 +++++++++++-------- 4 files changed, 43 insertions(+), 30 deletions(-) diff --git a/build.gradle b/build.gradle index 6902654579..6522488386 100644 --- a/build.gradle +++ b/build.gradle @@ -14,7 +14,7 @@ dependencies { testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.10.0' implementation group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1' implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.0' - implementation group: 'org.knowm.xchart', name: 'xchart', version: '3.2.2' + implementation group: 'org.knowm.xchart', name: 'xchart', version: '3.8.5' implementation group: 'com.google.code.gson', name: 'gson', version: '2.10.1' } diff --git a/src/main/java/seedu/financialplanner/commands/VisCommand.java b/src/main/java/seedu/financialplanner/commands/VisCommand.java index cef652921e..c42ba70d18 100644 --- a/src/main/java/seedu/financialplanner/commands/VisCommand.java +++ b/src/main/java/seedu/financialplanner/commands/VisCommand.java @@ -1,5 +1,7 @@ package seedu.financialplanner.commands; +import org.apache.commons.lang3.StringUtils; +import org.knowm.xchart.CategorySeries; import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.cashflow.CashflowList; import seedu.financialplanner.utils.Ui; @@ -7,6 +9,7 @@ import seedu.financialplanner.visualisations.Visualizer; import java.util.ArrayList; +import java.util.HashMap; import java.util.logging.Level; import java.util.logging.Logger; @@ -23,9 +26,9 @@ public VisCommand(RawCommand rawCommand) throws IllegalArgumentException { throw new IllegalArgumentException("Chart type must be defined"); } logger.log(Level.INFO, "Parsing entry type and chart type"); - this.type = rawCommand.extraArgs.get("t"); + this.type = rawCommand.extraArgs.get("t").toLowerCase(); rawCommand.extraArgs.remove("t"); - this.chart = rawCommand.extraArgs.get("c"); + this.chart = rawCommand.extraArgs.get("c").toLowerCase(); rawCommand.extraArgs.remove("c"); if (!rawCommand.extraArgs.isEmpty()) { String unknownExtraArgument = new ArrayList<>(rawCommand.extraArgs.keySet()).get(0); @@ -41,8 +44,12 @@ public void execute() throws FinancialPlannerException { assert !chart.isEmpty(); assert !type.isEmpty(); + HashMap cashflowbyType = Categorizer.sortType(CashflowList.getInstance(), type); + if (cashflowbyType.isEmpty()) { + ui.showMessage(StringUtils.capitalize(type) + " is empty... Nothing to visualize"); + return; + } ui.printDisplayChart(type, chart); - - Visualizer.displayChart(chart, Categorizer.sortType(CashflowList.getInstance(), type), type); + Visualizer.displayChart(chart, cashflowbyType, type); } } diff --git a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java index 77e29fae73..dbb7e6bc2a 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java @@ -14,7 +14,7 @@ public class Categorizer { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); - public static Map sortType(CashflowList cashflowList, String type) + public static HashMap sortType(CashflowList cashflowList, String type) throws FinancialPlannerException { switch (type) { case "expense": @@ -28,8 +28,8 @@ public static Map sortType(CashflowList cashflowList, String typ } } - public static Map sortExpenses(CashflowList cashflowList) { - Map expensesByCat = new HashMap<>(); + public static HashMap sortExpenses(CashflowList cashflowList) { + HashMap expensesByCat = new HashMap<>(); for (Cashflow e: cashflowList.list) { if (e instanceof Expense) { String key = e.getExpenseType().toString().toLowerCase(); @@ -41,8 +41,8 @@ public static Map sortExpenses(CashflowList cashflowList) { return expensesByCat; } - public static Map sortIncome(CashflowList cashflowList) { - Map incomeByCat = new HashMap<>(); + public static HashMap sortIncome(CashflowList cashflowList) { + HashMap incomeByCat = new HashMap<>(); for (Cashflow e: cashflowList.list) { if (e instanceof Income) { String key = e.getIncomeType().toString().toLowerCase(); diff --git a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java index 4171c7510c..763719eacb 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java @@ -1,26 +1,23 @@ package seedu.financialplanner.visualisations; -import org.knowm.xchart.CategoryChart; -import org.knowm.xchart.CategoryChartBuilder; -import org.knowm.xchart.PieChart; -import org.knowm.xchart.PieChartBuilder; -import org.knowm.xchart.SwingWrapper; +import org.apache.commons.lang3.StringUtils; +import org.knowm.xchart.*; import org.knowm.xchart.style.Styler; +import seedu.financialplanner.cashflow.Income; +import seedu.financialplanner.enumerations.IncomeType; import seedu.financialplanner.exceptions.FinancialPlannerException; -import javax.swing.JFrame; +import javax.swing.*; import java.awt.Color; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; public class Visualizer { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); - public static void displayChart(String chart, Map cashFlowByCat, String type) + public static void displayChart(String chart, HashMap cashFlowByCat, String type) throws FinancialPlannerException { switch (chart) { case "pie": @@ -34,8 +31,10 @@ public static void displayChart(String chart, Map cashFlowByCat, } } - public static void displayPieChart (Map expensesByCat, String type) { - PieChart chart = new PieChartBuilder().width(800).height(600).title(type).build(); + public static void displayPieChart (HashMap cashflowByCat, String type) { + PieChart chart = new PieChartBuilder().width(800).height(600) + .title(StringUtils.capitalize(type) + " Chart") + .build(); // Customize Chart Color[] sliceColors = new Color[] { @@ -49,7 +48,7 @@ public static void displayPieChart (Map expensesByCat, String ty }; chart.getStyler().setSeriesColors(sliceColors); - for (Map.Entry set: expensesByCat.entrySet()) { + for (Map.Entry set: cashflowByCat.entrySet()) { chart.addSeries(set.getKey(), set.getValue()); } logger.log(Level.INFO, "Displaying Pie Chart"); @@ -60,21 +59,28 @@ public static void displayPieChart (Map expensesByCat, String ty ); } - public static void displayBarChart (Map expensesByCat, String type) { + public static void displayBarChart (HashMap cashflowByCat, String type) { CategoryChart chart = new CategoryChartBuilder().width(800).height(600) - .title(type).xAxisTitle("Type").yAxisTitle("Value").build(); + .title(StringUtils.capitalize(type) + " Chart") + .xAxisTitle(StringUtils.capitalize(type) + " Type") + .yAxisTitle("Value") + .build(); + // Customize Chart chart.getStyler().setLegendPosition(Styler.LegendPosition.InsideNW); - chart.getStyler().setHasAnnotations(true); - assert !expensesByCat.isEmpty(); + assert !cashflowByCat.isEmpty(); // Series - List values = new ArrayList(expensesByCat.values()); - List keys = new ArrayList(expensesByCat.keySet()); + List values = new ArrayList(); + List keys = new ArrayList(); + for (Map.Entry set : cashflowByCat.entrySet()) { + keys.add(set.getKey()); + values.add(set.getValue()); + } chart.addSeries("Expense", keys, values); logger.log(Level.INFO, "Displaying Bar Chart"); JFrame swHR = new SwingWrapper<>(chart).displayChart(); - javax.swing.SwingUtilities.invokeLater( + SwingUtilities.invokeLater( ()->swHR.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE) ); } From 60761043e3143eda4aeee812a21be84cde78a453 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Tue, 31 Oct 2023 13:34:47 +0800 Subject: [PATCH 317/518] Add possible new chart type --- .../visualisations/Visualizer.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java index 763719eacb..a4e168bfd0 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java @@ -84,4 +84,25 @@ public static void displayBarChart (HashMap cashflowByCat, Strin ()->swHR.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE) ); } + + public static void displayRadarChart (HashMap cashflowByCat, String type) { + RadarChart radarChart = new RadarChartBuilder().width(800).height(600) + .title(StringUtils.capitalize(type) + " Chart") + .build(); + + // Customize Chart + Color[] sliceColors = new Color[] { + new Color(62, 154, 230), + }; + + radarChart.getStyler().setSeriesColors(sliceColors); + List keys = new ArrayList(); + List values = new ArrayList<>(); + for (Map.Entry set: cashflowByCat.entrySet()) { + keys.add(set.getKey()); + double datapoint = set.getValue()/3000; + values.add(datapoint); + } + + } } From 6caaf551f551785a7c1135f1ed842eddd11b662b Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Tue, 31 Oct 2023 13:35:13 +0800 Subject: [PATCH 318/518] Remove new chart type --- .../visualisations/Visualizer.java | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java index a4e168bfd0..763719eacb 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java @@ -84,25 +84,4 @@ public static void displayBarChart (HashMap cashflowByCat, Strin ()->swHR.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE) ); } - - public static void displayRadarChart (HashMap cashflowByCat, String type) { - RadarChart radarChart = new RadarChartBuilder().width(800).height(600) - .title(StringUtils.capitalize(type) + " Chart") - .build(); - - // Customize Chart - Color[] sliceColors = new Color[] { - new Color(62, 154, 230), - }; - - radarChart.getStyler().setSeriesColors(sliceColors); - List keys = new ArrayList(); - List values = new ArrayList<>(); - for (Map.Entry set: cashflowByCat.entrySet()) { - keys.add(set.getKey()); - double datapoint = set.getValue()/3000; - values.add(datapoint); - } - - } } From 7504d0ec1ad7aefb1356e19551e681cbb5d55c59 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Tue, 31 Oct 2023 13:38:42 +0800 Subject: [PATCH 319/518] Update imports --- .../financialplanner/commands/VisCommand.java | 1 - .../visualisations/Categorizer.java | 1 - .../visualisations/Visualizer.java | 16 +++++++++++----- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/VisCommand.java b/src/main/java/seedu/financialplanner/commands/VisCommand.java index c42ba70d18..c6acf247bc 100644 --- a/src/main/java/seedu/financialplanner/commands/VisCommand.java +++ b/src/main/java/seedu/financialplanner/commands/VisCommand.java @@ -1,7 +1,6 @@ package seedu.financialplanner.commands; import org.apache.commons.lang3.StringUtils; -import org.knowm.xchart.CategorySeries; import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.cashflow.CashflowList; import seedu.financialplanner.utils.Ui; diff --git a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java index dbb7e6bc2a..dc532b84d5 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java @@ -7,7 +7,6 @@ import seedu.financialplanner.cashflow.Income; import java.util.HashMap; -import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; diff --git a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java index 763719eacb..78890cca27 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java @@ -2,15 +2,21 @@ import org.apache.commons.lang3.StringUtils; -import org.knowm.xchart.*; +import org.knowm.xchart.PieChart; +import org.knowm.xchart.PieChartBuilder; +import org.knowm.xchart.SwingWrapper; +import org.knowm.xchart.CategoryChart; +import org.knowm.xchart.CategoryChartBuilder; import org.knowm.xchart.style.Styler; -import seedu.financialplanner.cashflow.Income; -import seedu.financialplanner.enumerations.IncomeType; import seedu.financialplanner.exceptions.FinancialPlannerException; -import javax.swing.*; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; import java.awt.Color; -import java.util.*; +import java.util.HashMap; +import java.util.Map; +import java.util.List; +import java.util.ArrayList; import java.util.logging.Level; import java.util.logging.Logger; From 62d9be75d0f533b1eddf835a001cfc4647fcb0e5 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 31 Oct 2023 13:46:48 +0800 Subject: [PATCH 320/518] Update DG and add table of contents --- docs/DeveloperGuide.md | 28 ++++++++++++++++++++++++++++ docs/diagrams/Budget.puml | 5 +++-- docs/diagrams/deleteBudget.puml | 3 ++- docs/diagrams/resetBudget.puml | 3 ++- docs/diagrams/viewBudget.puml | 3 ++- docs/images/Budget.png | Bin 23702 -> 24824 bytes docs/images/deleteBudget.png | Bin 10845 -> 12114 bytes docs/images/resetBudget.png | Bin 20906 -> 21676 bytes docs/images/viewBudget.png | Bin 10358 -> 10945 bytes 9 files changed, 37 insertions(+), 5 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index f439f93ff8..3f1368658a 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -1,5 +1,33 @@ # Developer Guide +## Table of contents + +* [Acknowledgements](#acknowledgements) +* [Design & implementation](#design--implementation) + * [Storage Component](#storage-component) + * [Design considerations](#design-considerations) + * [Visualization Feature](#visualization-feature-) + * [Class diagram](#class-diagram) + * [Sequence diagram](#sequence-diagram-) + * [Add income/expense feature](#add-incomeexpense-feature) + * [Step 1](#step-1) + * [Step 2](#step-2) + * [Step 3](#step-3) + * [Step 4](#step-4) + * [Diagrams](#diagrams) + * [Budget Feature](#budget-feature) + * [Set and update budget](#set-and-update-budget) + * [Delete budget](#delete-budget) + * [Reset budget](#reset-budget) + * [View budget](#view-budget) + * [Product Scope](#product-scope) + * [Target user profile](#target-user-profile) + * [Value proposition](#value-proposition) + * [User Stories](#user-stories) + * [Non-Functional Requirements](#non-functional-requirements) + * [Glossary](#glossary) + * [Instructions for manual testing](#instructions-for-manual-testing) + ## Acknowledgements **Xchart (A Simple Charting Library for Java)** diff --git a/docs/diagrams/Budget.puml b/docs/diagrams/Budget.puml index 755ff562c0..0474ef325a 100644 --- a/docs/diagrams/Budget.puml +++ b/docs/diagrams/Budget.puml @@ -2,10 +2,11 @@ participant ":BudgetCommand" as BudgetCommand participant "<>\nBudget" as Budget -participant "<>\nUi" as Ui +participant "<>\nUi" as UiClass +participant ":Ui" as Ui -> BudgetCommand: execute() -BudgetCommand -> Ui: getInstance() +BudgetCommand -> UiClass: getInstance() alt set BudgetCommand -> Budget: setBudget(budget) diff --git a/docs/diagrams/deleteBudget.puml b/docs/diagrams/deleteBudget.puml index e689250914..15642e462b 100644 --- a/docs/diagrams/deleteBudget.puml +++ b/docs/diagrams/deleteBudget.puml @@ -3,7 +3,8 @@ mainframe sd DeleteBudget participant ":BudgetCommand" as BudgetCommand participant "<>\nBudget" as Budget -participant "<>\nUi" as Ui +participant "<>\nUi" as UiClass +participant ":Ui" as Ui alt hasBudget BudgetCommand -> Budget: deleteBudget() diff --git a/docs/diagrams/resetBudget.puml b/docs/diagrams/resetBudget.puml index 8efef02d34..38c87562f7 100644 --- a/docs/diagrams/resetBudget.puml +++ b/docs/diagrams/resetBudget.puml @@ -3,7 +3,8 @@ mainframe sd ResetBudget participant ":BudgetCommand" as BudgetCommand participant "<>\nBudget" as Budget -participant "<>\nUi" as Ui +participant "<>\nUi" as UiClass +participant ":Ui" as Ui alt spentBudget opt initialBudgetExceedBalance diff --git a/docs/diagrams/viewBudget.puml b/docs/diagrams/viewBudget.puml index 39c9ec1ccb..6fdde54c64 100644 --- a/docs/diagrams/viewBudget.puml +++ b/docs/diagrams/viewBudget.puml @@ -3,7 +3,8 @@ mainframe sd ViewBudget participant ":BudgetCommand" as BudgetCommand participant "<>\nBudget" as Budget -participant "<>\nUi" as Ui +participant "<>\nUi" as UiClass +participant ":Ui" as Ui alt hasBudget BudgetCommand -> Ui: printBudget() diff --git a/docs/images/Budget.png b/docs/images/Budget.png index 7a140e5cdfefc8ba438311c2e7eedac16f3815ca..347382e90c7b235d1ca2e941b1674ae51ba14155 100644 GIT binary patch literal 24824 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

+7k>|Q?z9=*w=~=>LPiNPDXuFpdW28~;Bp;72 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 diff --git a/docs/images/deleteBudget.png b/docs/images/deleteBudget.png index 761a4c3620187942021edb0ba13a7b032a7a0b27..ee7b8d893044dc4c858f12c370b203b6d8be02e5 100644 GIT binary patch literal 12114 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 KOum#+;Qs;?dOXhn literal 10845 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 literal 10358 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 Date: Tue, 31 Oct 2023 14:07:57 +0800 Subject: [PATCH 321/518] Add function to automatically reset budget each new month/year --- .../seedu/financialplanner/FinancialPlanner.java | 4 ++-- .../seedu/financialplanner/cashflow/Budget.java | 15 ++++++++++++--- .../seedu/financialplanner/storage/LoadData.java | 3 ++- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index bdd75a6d00..a56ff7cfb8 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -11,7 +11,7 @@ import java.time.LocalDate; public class FinancialPlanner { - private static final LocalDate date = LocalDate.now(); + public static final LocalDate currentDate = LocalDate.now(); private static final String FILE_PATH = "data/data.txt"; private final Storage storage = Storage.getInstance(); private final Ui ui = Ui.getInstance(); @@ -27,7 +27,7 @@ public static void main(String[] args) { public void run() { try { - storage.load(FILE_PATH, date); + storage.load(FILE_PATH, currentDate); } catch (FinancialPlannerException e) { ui.showMessage(e.getMessage()); return; diff --git a/src/main/java/seedu/financialplanner/cashflow/Budget.java b/src/main/java/seedu/financialplanner/cashflow/Budget.java index 6aaae47a11..1995f95a6d 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Budget.java +++ b/src/main/java/seedu/financialplanner/cashflow/Budget.java @@ -1,11 +1,15 @@ package seedu.financialplanner.cashflow; import java.text.DecimalFormat; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; + +import static seedu.financialplanner.FinancialPlanner.currentDate; public abstract class Budget { - private static final int MONTH = 30; private static double initialBudget = 0; private static double currentBudget = 0; + private static LocalDate date = currentDate; public static void setBudget(double amount) { initialBudget = amount; @@ -50,9 +54,13 @@ public static void deduct(double amount) { Budget.currentBudget -= amount; } - public static void load(double initial, double current) { + public static void load(double initial, double current, LocalDate savedDate) { initialBudget = initial; currentBudget = current; + // Resets budget if it is a new month or new year. + if (!currentDate.getMonth().equals(savedDate.getMonth()) || currentDate.getYear() != savedDate.getYear()) { + resetBudget(); + } } public static boolean hasBudget() { @@ -60,7 +68,8 @@ public static boolean hasBudget() { } public static String formatString() { - return "B | " + initialBudget + " | " + currentBudget; + return "B | " + initialBudget + " | " + currentBudget + " | " + + date.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")); } public static void deleteBudget() { diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 9a9810b014..93238de8e7 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -162,7 +162,8 @@ private static void loadBudget(String[] split) throws IllegalArgumentException { if (initial < current) { throw new IllegalArgumentException("Current budget exceeds initial budget"); } - Budget.load(initial, current); + LocalDate date = LocalDate.parse(split[3].trim(), DateTimeFormatter.ofPattern("dd/MM/yyyy")); + Budget.load(initial, current, date); } private static boolean createNewFile() { From f55ab08c443a40a17648a296692f679f02607dbc Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 31 Oct 2023 14:09:14 +0800 Subject: [PATCH 322/518] Fix JUnit --- .../java/seedu/financialplanner/commands/BudgetCommandTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/seedu/financialplanner/commands/BudgetCommandTest.java b/src/test/java/seedu/financialplanner/commands/BudgetCommandTest.java index 40e05cc636..019b0b4424 100644 --- a/src/test/java/seedu/financialplanner/commands/BudgetCommandTest.java +++ b/src/test/java/seedu/financialplanner/commands/BudgetCommandTest.java @@ -116,7 +116,7 @@ public void testInvalidBudget_throwsException() throws FinancialPlannerException try { BudgetCommand testBudgetExceedBalance = new BudgetCommand(Parser.parseRawCommand("budget set /b 500")); } catch (FinancialPlannerException e) { - assertEquals("Budget should be lower than total balance.", e.getMessage()); + assertEquals("Budget should be lower than or equal to total balance.", e.getMessage()); } } } From e9943a18286b461c0bd525d383f07d2deee9d7d5 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 31 Oct 2023 14:47:17 +0800 Subject: [PATCH 323/518] Update JUnit test --- .../cashflow/CashflowList.java | 1 - .../financialplanner/cashflow/BudgetTest.java | 9 +++++++- .../financialplanner/storage/StorageTest.java | 22 ++++++++++++++++++- src/test/testData/ValidData.txt | 2 +- 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/main/java/seedu/financialplanner/cashflow/CashflowList.java b/src/main/java/seedu/financialplanner/cashflow/CashflowList.java index 22dcfb34b1..00ee9db9a8 100644 --- a/src/main/java/seedu/financialplanner/cashflow/CashflowList.java +++ b/src/main/java/seedu/financialplanner/cashflow/CashflowList.java @@ -171,7 +171,6 @@ public void load(Cashflow entry) { list.add(entry); } - //temp method public String getList() { StringBuilder output = new StringBuilder(); for (Cashflow entry : list) { diff --git a/src/test/java/seedu/financialplanner/cashflow/BudgetTest.java b/src/test/java/seedu/financialplanner/cashflow/BudgetTest.java index 26ce92608a..81d9a398ee 100644 --- a/src/test/java/seedu/financialplanner/cashflow/BudgetTest.java +++ b/src/test/java/seedu/financialplanner/cashflow/BudgetTest.java @@ -7,6 +7,9 @@ import seedu.financialplanner.commands.AddCashflowCommand; import seedu.financialplanner.utils.Parser; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; + import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -77,9 +80,13 @@ public void testDeleteBudget() { @Test @Order(8) public void testLoadBudget() { - Budget.load(100, 100); + Budget.load(100, 100, LocalDate.now()); assertEquals(100, Budget.getInitialBudget()); assertEquals(100, Budget.getCurrentBudget()); Budget.deleteBudget(); + LocalDate date = LocalDate.parse("11/04/2023", DateTimeFormatter.ofPattern("dd/MM/yyyy")); + Budget.load(100, 95, date); + assertEquals(100, Budget.getInitialBudget()); + assertEquals(100, Budget.getCurrentBudget()); } } diff --git a/src/test/java/seedu/financialplanner/storage/StorageTest.java b/src/test/java/seedu/financialplanner/storage/StorageTest.java index cfaeb4bd8c..b32bccd683 100644 --- a/src/test/java/seedu/financialplanner/storage/StorageTest.java +++ b/src/test/java/seedu/financialplanner/storage/StorageTest.java @@ -11,10 +11,14 @@ import seedu.financialplanner.utils.Ui; import java.io.ByteArrayInputStream; +import java.io.FileOutputStream; +import java.io.FileWriter; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.time.LocalDate; +import java.time.format.DateTimeFormatter; import java.util.Scanner; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -52,7 +56,12 @@ public void saveValidData() throws FinancialPlannerException, IOException { cashflowList.list.clear(); getTestData(); storage.save(String.valueOf(testFolder.resolve("temp.txt"))); - assertEquals(Files.readAllLines(Path.of("src/test/testData/ValidData.txt")), + String date = LocalDate.now().format(DateTimeFormatter.ofPattern("dd/MM/yyyy")); + + String filePath = String.valueOf(testFolder.resolve("ValidDataCopy.txt")); + getTestValidData(filePath, date); + + assertEquals(Files.readAllLines(Path.of(filePath)), Files.readAllLines(testFolder.resolve("temp.txt"))); } @@ -66,4 +75,15 @@ private void getTestData() { cashflowList.load(new Income(123.12, IncomeType.ALLOWANCE, 0, null)); cashflowList.load(new Expense(100, ExpenseType.SHOPPING, 0, "shopee")); } + + private static void getTestValidData(String filePath, String date) throws IOException { + try { + Files.copy(Paths.get("src/test/testData/ValidData.txt"), Path.of(filePath)); + FileWriter fw = new FileWriter(filePath, true); + fw.append(" ").append(date); + fw.close(); + } catch (IOException e) { + throw new IOException(e); + } + } } diff --git a/src/test/testData/ValidData.txt b/src/test/testData/ValidData.txt index f6e30ed6e8..0526a8035e 100644 --- a/src/test/testData/ValidData.txt +++ b/src/test/testData/ValidData.txt @@ -1,3 +1,3 @@ I | 123.12 | ALLOWANCE | 0 | false E | 100.0 | SHOPPING | 0 | false | shopee -B | 0.0 | 0.0 \ No newline at end of file +B | 0.0 | 0.0 | \ No newline at end of file From 334fc8789fc053d0e0bb5ee2046729d88dc68831 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 31 Oct 2023 14:50:13 +0800 Subject: [PATCH 324/518] Remove unused import --- src/test/java/seedu/financialplanner/storage/StorageTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/seedu/financialplanner/storage/StorageTest.java b/src/test/java/seedu/financialplanner/storage/StorageTest.java index b32bccd683..3cf6e14bd1 100644 --- a/src/test/java/seedu/financialplanner/storage/StorageTest.java +++ b/src/test/java/seedu/financialplanner/storage/StorageTest.java @@ -11,7 +11,6 @@ import seedu.financialplanner.utils.Ui; import java.io.ByteArrayInputStream; -import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.nio.file.Files; From a4eaae60a372fbd662b04d1d29c50491ec4a42b6 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 31 Oct 2023 15:03:21 +0800 Subject: [PATCH 325/518] Update JUnit tests --- .../java/seedu/financialplanner/cashflow/BudgetTest.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/test/java/seedu/financialplanner/cashflow/BudgetTest.java b/src/test/java/seedu/financialplanner/cashflow/BudgetTest.java index 81d9a398ee..1235919987 100644 --- a/src/test/java/seedu/financialplanner/cashflow/BudgetTest.java +++ b/src/test/java/seedu/financialplanner/cashflow/BudgetTest.java @@ -84,9 +84,17 @@ public void testLoadBudget() { assertEquals(100, Budget.getInitialBudget()); assertEquals(100, Budget.getCurrentBudget()); Budget.deleteBudget(); + LocalDate date = LocalDate.parse("11/04/2023", DateTimeFormatter.ofPattern("dd/MM/yyyy")); Budget.load(100, 95, date); assertEquals(100, Budget.getInitialBudget()); assertEquals(100, Budget.getCurrentBudget()); + Budget.deleteBudget(); + + date = LocalDate.parse("11/10/2022", DateTimeFormatter.ofPattern("dd/MM/yyyy")); + Budget.load(100, 95, date); + assertEquals(100, Budget.getInitialBudget()); + assertEquals(100, Budget.getCurrentBudget()); + Budget.deleteBudget(); } } From ea1432f7afba22e723327841993662237ca6c5b5 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Tue, 31 Oct 2023 16:44:46 +0800 Subject: [PATCH 326/518] Update sequence diagram for addCashflow --- docs/diagrams/AddCashflowSequence.puml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/diagrams/AddCashflowSequence.puml b/docs/diagrams/AddCashflowSequence.puml index f6c25559ca..bdb766a5fc 100644 --- a/docs/diagrams/AddCashflowSequence.puml +++ b/docs/diagrams/AddCashflowSequence.puml @@ -1,10 +1,10 @@ @startuml -participant AddCashflowCommand -participant CashflowList -participant Income -participant Expense -participant Ui +participant ":AddCashflowCommand" as AddCashflowCommand +participant "<>\nCashflowList" as CashflowList +participant ":Income" as Income +participant ":Expense" as Expense +participant "<>\nUi" as Ui -> AddCashflowCommand: execute() AddCashflowCommand -> CashflowList: getInstance() From 1e066d1878ee714f41fae180d1db53325dcb975c Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Tue, 31 Oct 2023 17:49:05 +0800 Subject: [PATCH 327/518] Update sequence diagram methods --- docs/diagrams/AddCashflowSequence.puml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/diagrams/AddCashflowSequence.puml b/docs/diagrams/AddCashflowSequence.puml index bdb766a5fc..f6c472e373 100644 --- a/docs/diagrams/AddCashflowSequence.puml +++ b/docs/diagrams/AddCashflowSequence.puml @@ -10,19 +10,19 @@ participant "<>\nUi" as Ui AddCashflowCommand -> CashflowList: getInstance() CashflowList -> Ui: getInstance() alt income - AddCashflowCommand -> CashflowList: addIncome(amount, incomeType, recur) + AddCashflowCommand -> CashflowList: addIncome(amount, incomeType, recur, description) create Income - CashflowList -> Income: Income(value, type, recur) + CashflowList -> Income: Income(value, type, recur, description) Income -> Income: addIncomeValue() - CashflowList -> CashflowList: add(toAdd) + CashflowList -> CashflowList: addToList(toAdd) CashflowList -> Ui: printAddedCashflow(toAdd) else expense - AddCashflowCommand -> CashflowList: addExpense(amount, incomeType, recur) + AddCashflowCommand -> CashflowList: addExpense(amount, incomeType, recur, description) create Expense - CashflowList -> Expense: Expense(value, type, recur) + CashflowList -> Expense: Expense(value, type, recur, description) Expense -> Expense: addExpenseValue() - CashflowList -> CashflowList: add(toAdd) + CashflowList -> CashflowList: addToList(toAdd) CashflowList -> Ui: printAddedCashflow(toAdd) else invalid command end From 61ef715e27fa8ca9127a2c8da109c1a043556e30 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Tue, 31 Oct 2023 17:49:20 +0800 Subject: [PATCH 328/518] Update class diagram --- docs/diagrams/CashflowClassDiagram.puml | 60 ++++++++++++++++++------- 1 file changed, 45 insertions(+), 15 deletions(-) diff --git a/docs/diagrams/CashflowClassDiagram.puml b/docs/diagrams/CashflowClassDiagram.puml index ca5c41f090..7211ac0448 100644 --- a/docs/diagrams/CashflowClassDiagram.puml +++ b/docs/diagrams/CashflowClassDiagram.puml @@ -1,28 +1,58 @@ @startuml 'https://plantuml.com/class-diagram -skinparam classAttributeIconSize 0 -hide empty members -!include style.puml -skinparam ClassBackgroundColor STORAGE_COLOR +skinparam classFontColor automatic -Class "{abstract}\nCashflow" as Cashflow -Class Expense extends Cashflow -Class Income extends Cashflow -Class Ui -Class CashflowList { - +addIncome(double, IncomeType, int) - +addExpense(double, ExpenseType, int) -} -Class AddCashflowCommand #FFFFFF +Class "{abstract}\nCashflow" as Cashflow #MistyRose { +#balance: double = 0 +#amount: double +#recur: int +#description: String = null -enum "<>\nExpenseType" as ExpenseType -enum "<>\nIncomeType" as IncomeType +} +Class Expense #MistyRose extends Cashflow { + #type: ExpenseType + +Expense(amount: double, type: ExpenseType, recur: int, description: String) + -addExpenseValue() +} +Class Income #MistyRose extends Cashflow { + +Income(amount: double, type: IncomeType, recur: int, description: String) + #type: IncomeType + -addIncomeValue() +} +Class Ui #Cornsilk { + +getInstance() + +printAddedCashflow(entry: Cashflow) +} +Class CashflowList #Cornsilk { + +getInstance() + +addIncome(amount: double, incometype: IncomeType, recur: int, description: String) + +addExpense(amount: double, expensetype: ExpenseType, recur: int, description: String) + -addToList(toAdd: Cashflow) +} +Class AddCashflowCommand #HoneyDew { + #amount: double + #incomeType: IncomeType + #expenseType: ExpenseType + #recur: int + #description: String = null + +execute() +} +enum "<>\nExpenseType" as ExpenseType #MintCream { +DINING, ENTERTAINMENT, SHOPPING, TRAVEL, INSURANCE, NECESSITIES, OTHERS +} +enum "<>\nIncomeType" as IncomeType #MintCream{ +SALARY, INVESTMENTS, ALLOWANCE, OTHERS +} +hide ExpenseType methods +hide IncomeType methods CashflowList -right-> "1" Ui AddCashflowCommand --> "1" CashflowList CashflowList --> "*" Cashflow CashflowList ..> Income CashflowList ..> Expense +hide Circle +skinparam classAttributeIconSize 0 @enduml \ No newline at end of file From b6ec44989d6bdeb46e7e164eddaaf72d22271596 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Tue, 31 Oct 2023 17:49:33 +0800 Subject: [PATCH 329/518] Extract method of addToList --- .../seedu/financialplanner/cashflow/CashflowList.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/cashflow/CashflowList.java b/src/main/java/seedu/financialplanner/cashflow/CashflowList.java index 22dcfb34b1..2a40b9b995 100644 --- a/src/main/java/seedu/financialplanner/cashflow/CashflowList.java +++ b/src/main/java/seedu/financialplanner/cashflow/CashflowList.java @@ -29,19 +29,23 @@ public void addIncome(double value, IncomeType type, int recur, String descripti int existingListSize = list.size(); Income toAdd = new Income(value, type, recur, description); - list.add(toAdd); + addToList(toAdd); ui.printAddedCashflow(toAdd); int newListSize = list.size(); assert newListSize == existingListSize + 1; } + private void addToList(Cashflow toAdd) { + list.add(toAdd); + } + public void addExpense(double value, ExpenseType type, int recur, String description) { logger.log(Level.INFO, "Adding expense"); int existingListSize = list.size(); Expense toAdd = new Expense(value, type, recur, description); - list.add(toAdd); + addToList(toAdd); ui.printAddedCashflow(toAdd); int newListSize = list.size(); From 2095999a11abe67db4993580ad3f2b7a0e07fad8 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 31 Oct 2023 18:09:56 +0800 Subject: [PATCH 330/518] Add exceptions --- src/main/java/seedu/financialplanner/FinancialPlanner.java | 4 ++-- src/main/java/seedu/financialplanner/cashflow/Budget.java | 6 ++---- src/main/java/seedu/financialplanner/storage/LoadData.java | 3 +++ 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index a56ff7cfb8..bdd75a6d00 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -11,7 +11,7 @@ import java.time.LocalDate; public class FinancialPlanner { - public static final LocalDate currentDate = LocalDate.now(); + private static final LocalDate date = LocalDate.now(); private static final String FILE_PATH = "data/data.txt"; private final Storage storage = Storage.getInstance(); private final Ui ui = Ui.getInstance(); @@ -27,7 +27,7 @@ public static void main(String[] args) { public void run() { try { - storage.load(FILE_PATH, currentDate); + storage.load(FILE_PATH, date); } catch (FinancialPlannerException e) { ui.showMessage(e.getMessage()); return; diff --git a/src/main/java/seedu/financialplanner/cashflow/Budget.java b/src/main/java/seedu/financialplanner/cashflow/Budget.java index 1995f95a6d..f544ba69ba 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Budget.java +++ b/src/main/java/seedu/financialplanner/cashflow/Budget.java @@ -4,12 +4,9 @@ import java.time.LocalDate; import java.time.format.DateTimeFormatter; -import static seedu.financialplanner.FinancialPlanner.currentDate; - public abstract class Budget { private static double initialBudget = 0; private static double currentBudget = 0; - private static LocalDate date = currentDate; public static void setBudget(double amount) { initialBudget = amount; @@ -57,6 +54,7 @@ public static void deduct(double amount) { public static void load(double initial, double current, LocalDate savedDate) { initialBudget = initial; currentBudget = current; + LocalDate currentDate = LocalDate.now(); // Resets budget if it is a new month or new year. if (!currentDate.getMonth().equals(savedDate.getMonth()) || currentDate.getYear() != savedDate.getYear()) { resetBudget(); @@ -69,7 +67,7 @@ public static boolean hasBudget() { public static String formatString() { return "B | " + initialBudget + " | " + currentBudget + " | " + - date.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")); + LocalDate.now().format(DateTimeFormatter.ofPattern("dd/MM/yyyy")); } public static void deleteBudget() { diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 93238de8e7..08657891a6 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -163,6 +163,9 @@ private static void loadBudget(String[] split) throws IllegalArgumentException { throw new IllegalArgumentException("Current budget exceeds initial budget"); } LocalDate date = LocalDate.parse(split[3].trim(), DateTimeFormatter.ofPattern("dd/MM/yyyy")); + if (LocalDate.now().isBefore(date)) { + throw new IllegalArgumentException("Current date is before saved date"); + } Budget.load(initial, current, date); } From 20cfcbcb8901a0f76eb102390d81565265eb1fb1 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Tue, 31 Oct 2023 18:12:05 +0800 Subject: [PATCH 331/518] Remove getInstance methods from class and sequence diagrams --- docs/DeveloperGuide.md | 9 +++------ docs/diagrams/AddCashflowSequence.puml | 6 ++---- docs/diagrams/CashflowClassDiagram.puml | 26 ++++++++++++++----------- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index f439f93ff8..20b2dd583b 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -130,11 +130,8 @@ Example: add income /a 100 /t salary /r 30 ``` Below are the steps that shows the implementation of add income/expense. -#### Step 1 -An instantiated AddCashflowCommand class gets the instance of CashflowList. -This allows the AddCashflowCommand instance to access the methods of CashflowList. -#### Step 2 +#### Step 1 The AddCashflowCommand instance then calls addIncome() or addExpense(), depending on what `category` is initialised as. addIncome() or addExpense() instantiates an Income or Expense object respectively. @@ -153,11 +150,11 @@ switch (category) { break; } ``` -#### Step 3 +#### Step 2 The instantiated income/expense then updates the overall balance through addIncomeValue() or addExpenseValue(). The income/expense object is also added to the list in Cashflowlist which contains all incomes/expenses. -#### Step 4 +#### Step 3 The added income/expense is then displayed to the user through the Ui. #### Diagrams diff --git a/docs/diagrams/AddCashflowSequence.puml b/docs/diagrams/AddCashflowSequence.puml index f6c472e373..47f89d6775 100644 --- a/docs/diagrams/AddCashflowSequence.puml +++ b/docs/diagrams/AddCashflowSequence.puml @@ -1,14 +1,12 @@ @startuml participant ":AddCashflowCommand" as AddCashflowCommand -participant "<>\nCashflowList" as CashflowList +participant "CashflowList" as CashflowList participant ":Income" as Income participant ":Expense" as Expense -participant "<>\nUi" as Ui +participant "Ui" as Ui -> AddCashflowCommand: execute() -AddCashflowCommand -> CashflowList: getInstance() -CashflowList -> Ui: getInstance() alt income AddCashflowCommand -> CashflowList: addIncome(amount, incomeType, recur, description) create Income diff --git a/docs/diagrams/CashflowClassDiagram.puml b/docs/diagrams/CashflowClassDiagram.puml index 7211ac0448..c11060164d 100644 --- a/docs/diagrams/CashflowClassDiagram.puml +++ b/docs/diagrams/CashflowClassDiagram.puml @@ -3,32 +3,34 @@ skinparam classFontColor automatic Class "{abstract}\nCashflow" as Cashflow #MistyRose { -#balance: double = 0 -#amount: double -#recur: int -#description: String = null - + #balance: double = 0 + #amount: double + #recur: int + #description: String = null } + Class Expense #MistyRose extends Cashflow { #type: ExpenseType +Expense(amount: double, type: ExpenseType, recur: int, description: String) -addExpenseValue() } + Class Income #MistyRose extends Cashflow { +Income(amount: double, type: IncomeType, recur: int, description: String) #type: IncomeType -addIncomeValue() } + Class Ui #Cornsilk { - +getInstance() +printAddedCashflow(entry: Cashflow) } + Class CashflowList #Cornsilk { - +getInstance() +addIncome(amount: double, incometype: IncomeType, recur: int, description: String) +addExpense(amount: double, expensetype: ExpenseType, recur: int, description: String) -addToList(toAdd: Cashflow) } + Class AddCashflowCommand #HoneyDew { #amount: double #incomeType: IncomeType @@ -39,19 +41,21 @@ Class AddCashflowCommand #HoneyDew { } enum "<>\nExpenseType" as ExpenseType #MintCream { -DINING, ENTERTAINMENT, SHOPPING, TRAVEL, INSURANCE, NECESSITIES, OTHERS + DINING, ENTERTAINMENT, SHOPPING, TRAVEL, INSURANCE, NECESSITIES, OTHERS } + enum "<>\nIncomeType" as IncomeType #MintCream{ -SALARY, INVESTMENTS, ALLOWANCE, OTHERS + SALARY, INVESTMENTS, ALLOWANCE, OTHERS } -hide ExpenseType methods -hide IncomeType methods + CashflowList -right-> "1" Ui AddCashflowCommand --> "1" CashflowList CashflowList --> "*" Cashflow CashflowList ..> Income CashflowList ..> Expense +hide ExpenseType methods +hide IncomeType methods hide Circle skinparam classAttributeIconSize 0 From 214edc931a3ffa9d87e2ccfbda87e011657933f0 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 31 Oct 2023 18:12:51 +0800 Subject: [PATCH 332/518] Update sequence diagram --- docs/diagrams/Budget.puml | 2 -- docs/diagrams/deleteBudget.puml | 1 - docs/diagrams/resetBudget.puml | 1 - docs/diagrams/viewBudget.puml | 1 - docs/images/Budget.png | Bin 24824 -> 20225 bytes docs/images/deleteBudget.png | Bin 12114 -> 10779 bytes docs/images/resetBudget.png | Bin 21676 -> 20366 bytes docs/images/viewBudget.png | Bin 10945 -> 10236 bytes 8 files changed, 5 deletions(-) diff --git a/docs/diagrams/Budget.puml b/docs/diagrams/Budget.puml index 0474ef325a..11ba20e9e8 100644 --- a/docs/diagrams/Budget.puml +++ b/docs/diagrams/Budget.puml @@ -2,11 +2,9 @@ participant ":BudgetCommand" as BudgetCommand participant "<>\nBudget" as Budget -participant "<>\nUi" as UiClass participant ":Ui" as Ui -> BudgetCommand: execute() -BudgetCommand -> UiClass: getInstance() alt set BudgetCommand -> Budget: setBudget(budget) diff --git a/docs/diagrams/deleteBudget.puml b/docs/diagrams/deleteBudget.puml index 15642e462b..4a8eb03a13 100644 --- a/docs/diagrams/deleteBudget.puml +++ b/docs/diagrams/deleteBudget.puml @@ -3,7 +3,6 @@ mainframe sd DeleteBudget participant ":BudgetCommand" as BudgetCommand participant "<>\nBudget" as Budget -participant "<>\nUi" as UiClass participant ":Ui" as Ui alt hasBudget diff --git a/docs/diagrams/resetBudget.puml b/docs/diagrams/resetBudget.puml index 38c87562f7..a21b3c7506 100644 --- a/docs/diagrams/resetBudget.puml +++ b/docs/diagrams/resetBudget.puml @@ -3,7 +3,6 @@ mainframe sd ResetBudget participant ":BudgetCommand" as BudgetCommand participant "<>\nBudget" as Budget -participant "<>\nUi" as UiClass participant ":Ui" as Ui alt spentBudget diff --git a/docs/diagrams/viewBudget.puml b/docs/diagrams/viewBudget.puml index 6fdde54c64..02c0d77042 100644 --- a/docs/diagrams/viewBudget.puml +++ b/docs/diagrams/viewBudget.puml @@ -3,7 +3,6 @@ mainframe sd ViewBudget participant ":BudgetCommand" as BudgetCommand participant "<>\nBudget" as Budget -participant "<>\nUi" as UiClass participant ":Ui" as Ui alt hasBudget diff --git a/docs/images/Budget.png b/docs/images/Budget.png index 347382e90c7b235d1ca2e941b1674ae51ba14155..89c18a4ef7f39a34001b75436f6c1668e8075769 100644 GIT binary patch literal 20225 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 literal 24824 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 KOum#+;Qs;?dOXhn diff --git a/docs/images/resetBudget.png b/docs/images/resetBudget.png index 940eab58c76a756d137b6570cea72c003bcd249e..0ea63d522b2e2e66f48aa1a5549805a275189613 100644 GIT binary patch literal 20366 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 literal 21676 zcmd741yq$=*fpwjNlQw)0Tl%aL0SYvq*Me1VN;S)(w$0|Akv{Cs7MG(NFz!}qjYy8 zE&V?m%yT^d{l@+8z2iE@8G1JCcdxzPwVpYjIp=!)uPR6%!K1-Dbm-6#nah&b4;?yO z2mfW_pusCiaV^#G*C`vRn>KnDmX4a(>6u%z4K#SUm-(bG*4_ zY6B{{&X1!#yRY&F+xJw{HP$m1(2u0lx;gmq@TPV+M>)603^H5Sp1V`~9&bZuPm>&t z2S1h3u^xB+c_o@`UQic3ookh3?IE6rTwfke^D@7;T{t8;h}?1ESZ{ZJ=I*XmG>U`Q zP<`x(bW@h?DAsa%mT1EkW1%UJh2=>e4Aon_hDzUfp0r*(#;CqF@;MWnF?ZxoS?|k(25++7|GvU*0T3f-d zYi~SW&f_l_^BsPAg^mni`fA+PSQA|<=&tWs&Szus%nr5#Vs0)1XlKKP+OLe8pR95? zCqnWrzXLt5@mkS|?AQS5ZtW=wBZOXLw%lHo~j13vI??JUVAze6eG!VN|yld z#91$kjjXB7TPI)IsY<+d&Rw5h-CCQ-cT!%>RMzYhd&z%hPT7|c$E)Blr>H0VJ$ZQg zs5o)enPemhhIlX9|LOl+6e&?rR(AEAtV$GdR>@Gu+*>+=ZyYa1 zzf)Rn8!YEu`XF_hR#{qa59(B5lZgvsFNN=2&s5E$zUCtw{grdTgVB$UWXIphmh!nO z#^MP{_b13cOceN z>i%^n)*~y6Gq`IA4IQ0_n_D4KxOT-hII8_L4caX%?C%$xZ)Fd*=zFKEp|QQa+!V?n zmN?aVqm#+VWuh@5ARr(}(Z*<5vWbY!f^$;o+pr{kjB zQtW$ynR-I;ks|vAWT6#i-KU0zqeZXz6B^KbsQAr$pUFlQxJc9uUO;`Xmh&Z*24;Ql zY)!ElSy;w=8Qd5b*^*qIOi}WwDJ!pbl%& zcG6#5Tf?Fa=9t{>(Lu5Z0y_&H#av#mOy-NBeKyxOE!u_UQUku zVDw8JSz2sd+uF$+J`XFnoYzbp&ISeqe8a*JpS?V?g6BbJH{00)U)s1W^#K7ptAlmM z6lJWi>!!`#?oQe6=AFE^wlnP=nVNb$zWM6nB2(?^Ob6%9?Bvwc@%k8^P|?ljsagfMWn^SDG>(;|#zaN& zyYFthZ;vqO>+3I%H#l!ER?8r*;j5sdqbtUrKV186^SwA$e`H$&=Z0-pUy*%9hPGpO zTi0nm)6TOn4^)H*e7sbcJ@E_q%zlQg=SwIkC|Fro-Ws)dT@J8wo_pI-`TjkF!=NXu z5kASR@=VR5&9yma*cO7-X-b9-v6%K2UtWG`ek{SMQE*|?h;ZT+PYnt8;lqb*Lxynr z`}=itbOu$vvQFjcf1)_w)8w|6>r3x6`7~5i7vGvMaA0qDeSN^)y~u7(B?~Ff$<3P* zBxnN*{%mkty04PDI$oT)=*%(HE8I`Su4S$I1qJnH>%50$ovBgC?Yg-_&13LYB;LbZ zikL`xg>CvRz4Q9Kyo^lYLg`jzWo4>D!WA(oM(n--M!!kL&v%r>^Oz7TAUce z7zZ^FsAGbRn`Em2j5trw|7S1wi4@))8PCyoT%OpgJyq?6SqRI1D2++G!?Ej7OVV@I zDj$t9H@)sRG14I}_VXIg?uQ(qU0Pq*!xy8*Dr)>h@3#wuhi^0^f9doDFfr`9 z60+V?^gKi#{h^-6Q=aBY_Q+s9J)3|d-c()2Q2#g1u+uJS*= zo@D0Z;$mAxVXpWigVB6*_oV`t6cSGDv?V?A@V^{xGCAa11OSoczBPB>qV!~Kt>bI? zIBXeu8}wEI>r~wj0ruT_!BGevZl4NE(`3h*bGP9>p*%e*$To$GXhHuv0(FDwx! zoxdA0^J;^YX3ZN`Jfd`O7yANI1G^z5_io{zLwdqwSaimr34e<_lPCRg#x1c#!E+O} zY|>R9^PX+w59|^ThtQGfL|k6Tj1iu=ZC^|GW3~))r{3n|m{fRmARWiP2w0Dg=yY<~ z&!;DTwI4akOHNE|xi+hx$@4|teEzzFP_cGJ+}^5I5;?^#QF>ZmQJKp`!uG?5($yge zClvWKCF~L?zjhgJK}}&3)r$-*w5BZH-K>21@{}7QpJ_98Q0v*=S$=+JFF-waH6!Z|FvF{@RX^>eAu0u%;oOl zLhZhH^1~&u4lc{`wNIohzIqoPX-R5G?TA9gvWXsZpt6h?(^{QQ=i4(N^!I5L=rY@x zx6f65caVV;qTwmI zeJu7h=SE|eP3o8!RJA1C`QngTE{mbVdY-;q)iYUTjaj}WR~-u7*84)KsTDUiH$}EB zI}(KUE{5OWkKsLPVWH`q zs2!f@kc^afuCeu4Hkm#6uqQ~7#S0~|Yhg2oCcbn^h-Q|ewy4vvr_;GPrjEmn>92iV zG+a?6X0-}^)udY@6Fpv4k7%P{lNn0Kv_JOrmp8r|*ypo8(l6azm4Yqtg^cKPx-n59 zp(Qd{WOQUY5cXy|8~t+5 zO4_Tb>TgXF5=D&$N}uZT*NTg=_H{nhm(^Mu*Vak?2BPD7eqPlOT^00Ied#8P9q|jdchUxskbN?;E3RSn*Vx$~Q@?(3(s!x2le;Qh zLxp{R^~EY=&5ASR3=gw^UE9tt+iB{`)f$Q|h_fC)?O{IP=6txfYS%xY1L-_7mA1Fj z`Ff#nd-wzUc#{?eXZA?-9-%8EMbloh1fBhyU^$_E<26!TAVOlLE3MlAXCxte%kJa5 zGiAH9BJcf3_VDz*C0t#1+;(Qt$~IDOkJZ^v4OCioRdi{E`wFF|u5D~DAHRy;Gtkxh z0e$s~*SIUv7#2~@#4}63)#jki&krS{9Q|1eU#T3dm?ETFaY@OLnrvJ_B4V<8m1GmU zT{~1}IaD}&DXQ$)@kL(-bG_x+0V(pbGw2~(z;EL$8r$M}4=>%1BK8lZ6FPeIs6^9O z;D$-o+awNtM0A@z0ejdlIlLXqSC+r8u~)tZRjH|{MR2-S z|Ly)RNb6d?f|m2iVJxzjkWSD_zE}S0&{Uf~VmE0|;L~`;RfJCiV*@r8mLpd=$93Vd zva-E_JvaaU(U3=HTx)NYS%>6@%~BiD>%QxGW@y(n6dwVffA|(rgHT)%>|mMZ;wJV6 z*ohm(Dh!koo(8+S7Pte{yAK`Bxz^XaG07`uK__Tv?aUL z`+nGJ9%_QV1>dhPj-E%zrnq}!!hT?fikSF1KT--uFSMv_gZEa63z^b$cR- z;W2-at*nnZqW_&Oe*+uaI%1)!NnrOQOM|x{KK|YnMJb}S?QHjWq4jflM;~?+*^80d z&&O9Gk0mD+>og@(-(l_QgheqyPZ4EJN%WcBIkzxTH5LlblHE5FHdkf4c(7oB${Zdb$oDzY%L|p%_+=*tY7S7 zHQV+OQC1~BLI0u37pUEwKbJC*o>f}0YXbA@E0cHz$E^E$T-(IgU~(WohWHH+8$ z<3!{*Q-`Mu5)b<`t{BtWyam*)r|eJ3&q6h36q1f zv)I=QCyKEKH{@e$Eb506&ih$3#IAQadyZ%iU}L$AMQZRRC5Z5xKaXH#omX^Mzc@eu z-Kzlm9YGr(dum|w0zgRy&Q#vP<^F1LulL^ixT45vSu$2lN{aBiyCZf^>gV4tHyOf` z#KgoTq7w|C*Dvt*dug(u0WnH|zRIG}ODRbX* zbK{z=fwq=a6wN>sMX7pwJJMgi{1)>Wd*Vy^Q_qoUzsV+pw)AJ7*a3=6^xm4P1E-d` z%@R;V;8f>sHw$w`X1YbBV@#d`3XYG;6_xuP?zCOa;O1;=KMCmm(#x2VitA8OW~uVH zez%|$uyEzGb7;r0v^&1!*A>g%N<%?AUTR4}2$je0SO356EKWtQ4GZcXveR@;umAMM zHUK!sOYQDZAI5)PTT{F0(CoWSm6#~w8FFAD$`x<$gZ})qQ_*&wBHQ?Ix=^`_sXA-g*1o=-)}PCML95D^PTb<*OJl9DBv3eB&s z653PV=W*Z`%q)G8T~`c)aB|uKy6m>`Nh{C1ue+loALa)t0YVYk&zsEOC$6;e4w}-@ z(NPZ%kL2WJCJCQ-0c#&S4{7x97cX8Q)HF3k+_t}6#a0yCS@{r1Y1~Aq{v~+u{hZ@aktJjl;Z9dTrFzX@a67Bc&ofeE0xb4?Y3GF(JFt@&S=ytlgfp zXyRdl?9=C1SXekY7b@@L!)M>$x+EzKi|-}P;QG++kZS3AzcVobogjJm$j4xB2bi?`_wN%29TNy&)5tYAGRowUdv}73 z>oG_%18!Rx2G}^<+}w-~Aojd?$|L~70#0&J{(xH?D@$aUbpYJ{*NI3^5$CmXIw9NX z(XoQc%i*JAXFk4@FiGSyqY+&z~=t zPxL#<#KiPw0>luDfl_(h`E6bwGj0scB0Jmm!)qDH`eX#|(+gK`-EsysEcW4zi;XAy zC5fw?oHVnw5BKVqdmLtP-{x|Zi73v!sYTwauBs&hs@J!bHpMi#7}BFhF>9-;B)bpy zdy}>Gx$o_SVbosKP*xtBy}{cq=f%u~gM*VSbC$d2p&jEy*4+yco}QkF+UYO)EW`2` z;;+(Fzhd@2>pXmLdFjvlmp3*xCWfKzB-rG#Q79WzR4FnFPP5PPlO%5GGdfCulp3p$MF%rZ!HF*^#;9=FuVV7l*>ZN zI!Yyph>gtlwz|*6!8NYR{!uT|kyC9IWvR*5)-$TP)$wks^dVZ>tn@)5y~quF)`V-_mfU23NKbc zEiF)Larh8$bZBS@Zp%!2#&H?W>Q&$Qz9I%Ow_}2)-EU3`3JUV_@(KyX_0P<9<-$tt zwRr9JZ3z3sp*lv9Aw=UT9qchY2@TzPZ113ID4wYbGgC+N)Iku+rh9sw(UA|N$Y;Rb zMnc7Q+xlWJDfOyPNQ%s&-LW&GxOnlRm9=$6nv|5(RZ^VTg&~Y(xe8LM4HZ~@=eo59YFh;nTc^hQRNDkJe&fzYj|Idfy|_3nMqZ<~DKuPO zsYPF?Kb}6Tt8h>iQ8h-tpee)llBR}qz5hWKPE}BvwB7!;=+4IgvQR;72I$xHN|RsS zpcJBOsWGd9?z=9W)ln+02BIOy1S+Ef8F5;*W7V?o-XF*Dx`~Ea=D%N%>!Fs#A0UF> z^o_4^`{n+l3oiy2+mA|hbenY_DY)>1qR9@BLM{Q%jcjL%qXaZ$`5eq;06q!rDnAkz zyhW;mL6_Pl3fYH5MS1h5xV1^Hq!q0Q*7h>=TqMR=v@$35&0(jJt{e<&z)3- z6{8uksNPl(6BIALOXg=C(^*kas2~oKaqt6Lx&D{_lZyB=C~+4=xuM)mrj{8>^*xKK z8G7Dv=U(qTx8042(N9^ODLD4(FnhDC2*ic^E~;k`hIT$Tsh+t>Cp?yD9vbDbRg$r> zDXs7vpYA!7UN4&^ICe0Wwn`@!&O@T<45TF{ZrN%}UN)D|7cLgH3|9G*5kqbMs`=Jv z@Wkm^P4f9n0=ht~rI>eFe6=y>R0ptb>LZ=LoaB!#RwipnVr`uPDRU4B1?B2{&{RKt z`XrMm+ydps84B3?Ovl33LRp&3#gg1fX{D7bdZfkQh6B&OI4H)=2z=+L_r64Ippcq& zal;M}6Vno=#i$Nt@Ev@SmT1K{53tkL+Un)y1>(C=PC)?`{e^ja;`H=%_#KAn!Kt*Q zQinxm<0o`R7eML4nLVL&{knO7aaYDIehZ5QsDHa(-xEpr5a8nAOm@FT*&NRt)eU7D zt{ay(-dL(Re`lC}1FO9@QBBf%)yzYA{F!Qkm3Qr}b0j-z3%CeA*)XE4m2WwzJm5 zD`4Jx9w)iDvhre>lB^6rU(L#Juw1- z2!k&o5nk+|%~mnl7m>%=_bR^cS97||WF6;aQ3+;s27%AR=F00kV3%a=&8(;C9?suH(9ScXtfd*ML zoK4Xtc71hKe_5DVi^8gt+U1-rcG{{*G(lD~mclkhSDhU}x$ zUHKLa7^CRuvG=ci45CJ-UdnSCEcXnf=F-Ke8Z|lR*p}g_-jHJOf>+z{l;drLylHQ_ zU}4emJjw4xWk$ra$^dt1=;+F3&%kbbVBs3x;o1ncO<*jwek0YPY>rC-g4W~pifKmN zbugn#PLJ4BU)?03r=K4g$u;j2jCGmG$k#S0+i0+;+C>~1*Q&Ur|%06rk`7(f~fzQSUsAU^6Fn8O);F6S71>vGUTVjFbke7iDd1t1R zvvbt%ZhqpF!2xLIU1+cp8IE#&#_ zYD1W~p=Rdh95~OOKgYR(X|^a5<{a&Q?g1q^R0%@J0MFOop@SCe?#Gn@eXUis}~Uu(L;&q~kN zongD_%8T*(fLH%kh)bO4U^*pD@x9v_>Mz3UJlGw()(r5-${zNitK^Vm3>G8_+m`->%F#LPf#7j->;^OsVPcx zU0wZ(9_N(1MOp@){h}@o0YQCD&3VVA+dHKS4~QP)-qJ}J3DqH@7cR);N;7e2`p9k6 z%=p~5iH}}WW#HZc%Gf{LM;Yh{ZPW&vo3GOFH=mr<9Bn3R9c)ZMNn`>70$|^Xtwyw# zzr0z17ZDKw(wRy}w9>g^Lp{$c$@HQ<4mN78WV#21@YlfgJ=H>an@=8@RY`lMdeO|x z?CMqGxChN&hfd6D4*EZQ^oVtQjJG%q4ag(M>C>aR!IDv5_?e*h`)$&cF>BE%$;rRL zpN);x=`VMH+ati$J!ds~`D^#rq4$7OGsj4o!U#>Xt;Xtrp}v=ao~ABOu;^2TH@1?J z5;__hGc$9);{;u1B$oX`e+m2=bTdHK3R(F$*x6+j6^RH4P;G)dSl{al17gC$E?qhL zyi-=!ySlmpDLGlW5IW19fWd5u4#VL2B2H%Ys-=JXR$hE5h-zqIVW7}@0w6Xb&q$wt^b^01ZBsNewoY0Qcu3c#KZ&}fCCDvzyJm+_||E48mz%E#MV;k z>!=ZTQmqmv+fR?qjP_s@sE}sgO;bqVv*>r3>wXJXV(a?&tmaKnKfz9JTGbhOtyc{< zi;}N!vZ8%G0WaLxn&{UbIh$pI8mv;yDb_R5iLUyw?b#=@#j$@7LAF8qI zdfphf0R}xLJ$qWljdyLCSy_G7n2b~uhG0}|+}z==Z*XJBDim=xHM9MEkAGjI ztBG~{khP>ji_SS->bjL@+C|#`rL~N5WM*c@mdJ=%rv3OUQG`r`io*oqmb}C9-b_uQ z*KE#Fg4Om$pYS1Pfw{r_1=grQz&9A^3$y@ zsyc55dS1om(?rvrFQ@G#g~)m8=EH%DS`Q7vmviJ)!Llp>qo%L$B4Ic3} zauiG^iMkFpEaaK>)bJbK&6w4kKE@F5wR5uLhKkB1y%TSNV0l5i-E!O1^z?S;b8DA5 z#vUcnlMd2E0V$44XFRhTFf_wcime>kY2VvX(Obr{89l=0If9Qr67FZn{9`7N&Oc|u zq6At)oFc@M5J!0YS)Izok?Jh1vQqE^KYzXvey<%m$p=+duFV&gImE@qv*msG7e=>U z7pkn?V~hgY)mCPKZ|KcjVSkl=?onjqxjXHrPuLDu`SZpkB#2n_3p=DK?rxr!c^7}< z%9T1;0hbBZy?EaDZ-61b*|*>(9llgImSHMv+?qlsWOspu!R?z)6o=;J>$$?u)1*V` z5toFIeV@ARsao~4FQ>&ti;KTZU*^c9+&Atkgsw7khQE6LoQlu%X1YqoJNpH<;VRtl zW9LjBmX(S5k8LJY$%Vy( z+f6PE1?BnZ18MrlWpZtB*JA{%S?$+9GOM}DLcfY)c)tqU%u}XEPp?^I5*<6=oNK5k z+ViTseRZ(H8{w01zUPLz`a7NXSWC3R0{dMP3Wq|%51NygUPye?qupn|!Qfma)-KocXyQPfflpS9uI6 z98uB!rY24ik&={@dlq($PzA6FsLBoFaG&3X4#6c)6aqMbAt50_L9=~D>tF`(^5_0_ zTtU&qXHDVHjT>;I@wTs${QdVRJ4mcA5^N=VL(HZC*72-C`@Zh>#|$xY3RhV}@Zp}j zkj-Q^M0j?)JZ_SGUj`5fz#%HefK0{X=xD0p_UF%^S5;ME;!_wQ1Efv|{G4Z!6#A-+ z(pja{N+Fhibox z<^i$%0j}wIPCya3h`yEO{p$y3&i)0pl`%^wsD7gqzu(H=S;P-0R~F9-obfyQdS9P} zChjM^Vu%Zq{5Au_{x$ytV(_0=1Fi`w>eI&4IHPfi+@Hc%8SsAX{eJ|Ra}-W70E z3VJO|{h$WPgEY0xmzbv`2dy^EGpLc|AW9+T!EgWtX2(uwu+;Ev>Ev%a(H6^~#GoOz z9a0HvoqCj<$dp>CKne&*1y}JF96TgwgSFD|u55 z6_rPciG&MJA0LW64a(y{nY)9-w;cUXMmaBEnvB*w&`uwE@2je+8WCYccxEYGYX`5N zRU%ujIt0pKIN~9{ZWRth!C=cVh`K~0K3t1uImaF)w+EE~v?T}>k&uuq6fYBY45+cM z8+DvZorOODlMz&jJ(dwwezrd;UwUKtt0dR8uDZG_4j9mbNJM;!;w-b7BK0@6S{kiY z%|iC&=;IfU8;4^c3?Q(EEORR{;3o}&iVM@9{mI*dm4}BX>a-f#Dymmz1+JieDl?2J;Hg80>I*A5f0 z%I65FIfi4H%H>%cMBg6TcsF$aP5>T=ku;zf#03UokHwLZ5t-}D@v$Ch+RnfbY-0U` zf?mCNq4RE=>|i{ysfvY;%c-47m2U$=?cRSPBqa3FJmWuPsC@Y{&RpotU&tIp{vDaA zqE~}y`58T;P86|WN;gO2Yp~*GFPn7bJnNJkp*W-Nah1^n&4|>bz;%l+YGrkG^_}l_ zd~Ce1BdH)t=r+(M7ZeW|KLI^|o$&?jG%X~Out?JZe*ncM%8Da{X_0(4F2~=RxT#jK z(MCsn=O-*DR(yx$^y7sEgt@G=Tn-PatE!q2J&#|@Tr@U5IlEMlnv=s#^ZwEwM4<4* z-L+Y@Jhm3ka7!X zO2Lr6ua8fqSGWU!1?-a5o;itps}BzkZ!mc79xjPqs_(a4y$x9&Dg?%Vgv??5pZ~FOy0k^v=wu}2%HA$>gvG0C?CHA&Hyj2 zbEezQrj)cau-}@;P|jHG z2V2Nt{gWqLqNzs_h4VMx7?BJZ;3Jw$-XGd{bEkuYnHg=jp{`DMj}S}hH{JqSME^s3 z5KEbQ3`$J1I8fZtI5qvB1pt0t$mlcITgbz8nz5_?)DOZAP37dvUl)1WxiK2q~<71vn2shT_G z`^VgU2mYP$1j^m43?~%lSEu_M8)yT8LDc0Nt=(x_#JV~s77>-I67W)n`Rc^VTzyT}y`1!>k|Gozt zq^A8B#b4uhYvI5gV8-$Kdg7ZrDgr4^d{6q|n&A5iqqKjNet|J`Fz9r=kAHdlOYM4T ziB1dK^*@LQR_}eqLa(ih8z6UqM&Zz$EKZ#5*i;q$h5x`a`Qu?~mKGHOJSTl$tZ>jH1Ux(%oLN7Z89xXpCa^^qi1w9p2fk6Y!KL|$aSo05U;j~~c;&t`+J_CHQ?>8|_L&LZF z_Qui}G*ey<)1O~}u>|_AI(%*rHP2;iOLiMTFFP2?#fxY%CTpX`wZn6BC2l)T4dw_c zX!Cmut#u;s56c@E7;vcNq(El`%{_=3MppVBRnVAym_ZN!lFtir3zzMw{adSSILK89 zQolb6nr{(%n4zHA3Zzh|YLGovl$SqJ5@nz$ZxQ~Zw`b`CX{9kqjHm)k1Y_<~rvhAB zxZ-RCY(Ns8wUi++A;iUfERUnBN`BxQ@qCT;I4m=ZYSu#`v>uMQ`3gKoOCCnX!I}rh z!xNF}{RoW`C*}SO;BovG{r3hx2GjE5(i(Q2vzCdHc>luB{V>iTtJy{3q9+GSI6>zF zMv>I;`3DfMu86zq@TOM2Au+Ze0qRoa?!!B$*x8?Q#b*~36f`a-g!59<(#mG4$BQ^W znmfq=Uf`SJ;`pkwk~eQs{dq}VoyvQFZdw3*;3%RjZ(NIMRF~az0lI7%MWda?Y6hA5 zM2chl&TF%f)o(Gkd>I={a~}6c3w?eFq-tYsAtC4fV#luvVmv$%teS)g;o(-3%}k^c z%}=F?NRRsk|JXF)fithL*-xGFIYQeGJsOynkkIu);N#;*goh8F;cI!4GV%P{)9sxd znc0KZSIq0y)U%#5xAMv%jdXEoX=!p21Rtjn{Ea&mHe+hvn}V66E^ z^UD;C!Y2`m+UZ*~`^MzYO~!EKE<>CDOrKLqZeE7AYu?rNnL)Z|pAMTmO6yAXK2wUuSKxVTUy#*&Ws(fugMU$@6N-TeatkL%ty zGu74AH8Gh+b<~_6nDZpR*Tm~Y!z!Jbr~?TAr|j&3yIFWu)>pq5^lglSb6~-7bCc$$ z(}(;h*W(};pVbl+U7xlpGWq9#ms^OdE`N15Q~O6@`%B&a-6sCNqfs;S7xxy`#Qy^z z{#ML?Lm)`RIDFs4UR-~9`zb2aK>y_)%d2T~j;G(2f+b`;`=J@U{-7X&&9P4Ts;(0d zN;q2wK1oa|cX5h!%RM@pPGDltJYgT9!8jbp&m*tq%5#tv_&!sX18Bf@TcaaYZEaWC zvx>P*KA(s+#*2LlwJz<+6J|CxHn2AG>aI1j3-N}<$Gg-Y#xU)#FR)mRqx@slZc#)Z zrC{ScdwQ0mD~LP%n#mssVW|E)LevLssgybH8}dI^5olNM^>U!9J8V;|+J3L^e zJfr>@98uD?(Yi=>(03QW+OeHc31@01L@>f}m%W0$-7OgiY3wW4gP>fC7a`QHUOkky zw7fj?CB0*JXDeaVhOZ95FbfWf7&gZD_G)DM2Y;%oYi(;2UpXuP-xwmCFv#jJA98#3 zOfY1(e$az2)DCiq-@8he|LiJ_9Br#Tct(zXy|67)h$GGI#xUsPT z+af%%_rz&9H!#zY)iHa?>!l&pv@$dBNG#oNf};e ztEXWevq*r%*y!jJQxqg5cXziPamv5(QXf4kwR`>4zp@5%%-FU2lw)fQfNxmCD6|@l-P3lA|vhjuE&z*F$OU6&QL?;@Z5*w`2s7Z-1>oslW& zO%ST#j!(&Vo*}LF*C?_((jU|ooNJ(H`1G@Y=y}X7rOX$vUIl%$tQ;QJ#Q|zA9r610 z>(SO~&}X|6mmW*NIlODkTm&Q(6qkPcAUuGLuhDX`ytw@z;BeTCQmWiznLKX5dS9XmZQ!)_oqAP;-{@~o)ku7OU_7WRew+RYT((tG#=|GsOW8AlKX63}kcyZ&J ze|2>0-#B~|MO_7jRS-Vfa8v}rC-6^-19pQLqqJz(@d$#lS)4V)BHa0_$gU%7Cu#?B*aX zalIFmS+D03y)+cm`nb_!I=41^3s2f;%LwY zh?1z0Hi%|%(j__D7HXbLRrr}NLOVVV&D%ina^>DzWup5-X5RnG5uqZV(U_NhMVo%U z`JdsWrqt=94jW@pL#*3@Tpy|QOhY@#oy~};E;osR1}Nq~mAqQ?`F%9VxIY`Flba1JPsCO`*!|t-J!JVPoCaW9 zT)0qHaU-PCuUAteu_78eG1Rw%ge`1@N&YCmU2u(i1e0rJB3L)JwyHmTFzd>}4EH5s zP`Gjhq$rk+C83(x{t_V&Nf{X#Pn<9U=K`v}j-tc%x4SrrPSYpN$!Va|7Cdw2$b8(t z!;>nis&MRA^m9dD?axDn*;$Qon7fOC6 zY1S47v~J$SIlQ5JqPs4k{m;l+fSWZ$t?Z{zt`cPScpX8CflkgrpmdHp92NS61IAPl z{raf>4}4w%XayT$&%pwm#nrLE7Y7@o@R||9mI@9im-|T=NJ0^RZf}PZ%#p1A)hC;M zh0+|9s{U9uEfyS*D&r_IVKs)M&;%6_WxT*MH~@iFo4SW5uU)$qCLo~3(E;c{imS%8DaW}%<19={fJT+p?E9vK)KwiP9bIP*cB-#XJy zB(~k0Z=pryw{kDyvw+*%$e0*h=i8n5VvAK|lpGo!qX9?R;lS+U_pmYwVo5L-FG!XZ z?uYbDuzt@pQtf9Nb0I%U>`k&WPTG>R2}iGVyGvc2p)G~R#Pzq>#+$P}r-?DR==ZQG0^rh11Ms?G1)PM3#Q5w>H1ta_)3Wn7Y z<0k@dN)c>q3_^AUUf^W3xeJU+fUd!X{x5on>~89LnFB=xW13pTiC11BLGbPK=aVq=5Ufk&(!;W+Ck>T3Zm51&~BZh1%HBnPVeA1wPCdoGHJ%GI{O(zZDde-s&I+*HoV9Y^d;-iI`PT zNkkl`jo4RAYE{DoW)4W}hG2C^c-!q8H^_UVWIulR;AzizXz@dJbwtXzfK)+_aWBAp zj`95rT^pM>olNJ?M{fo21Q?7hF^^?53R;#c(k*E|3ci@L`RL<*PWb>Or-PzK?%ZYa z=->m}L#p+__TV!8X?ye*JLWbnmW1)*p6e}jjg#Hn+;r-ba8n@3+O&Sm6(2!>v1g)i ztnPRzS<5R8WJ>WDHEhD?*goUAI8R3R1;Yf->U*YDb)P=z>FR=c(AgCt@;4ikmku*F0N~rAW2&iI1;uARX$#5?qh@ z)p*&XC{J2sShsqj)0bptpA`*cyaI}%+JZ6!L$6ZxlX+C%ZcUN-inRf8uq1AMJoy|t zgiPo94uF|1HgUxd)_Rnj{PX9}a?xi!?Vw+Zg%AUTTG$lgFGqmP29Fs)AJaE5Xhrm* z&LuQkA80x&@v#!tMvpWn3TkAtN<`Ott#y4Na1LTuOWf($$U77#QTw{f6McHBRZ2T5&|hICaz8U$ixwxJ1>)%9;vz_rQ&Urb>n^#kQ7R-HW^l=i z@wj3)*Zske)&td~?z2abl^(!U#gg1Mr@-EP^5h9)M0E7zEXQm~{hzJIlK~Cp%{EOZ z*YOxbMr6+IS_qRdP6GMwVfs$wP=`jmIy-L~+7Bt*A^pQBA>XGz^R0JmZEXz3;25Z|MNQ&d3;am13}#n1++ z{ZNVPKSL$averhfG71W!cC%C%aF{Z6ZyH|+-;SJ$@=}^S4)b?q=~ThOu;9$O#=G!H z8?c&9FL`+}ut?0H31>ls`LbN;l&{-BXh=3B99H&OQCQxok$-Wk@KB%feQ~doO9WCS zv-w;c>TjOI(`^u`wUO+qc@_ix)zyX&tw2a5(_OZNuf(pJ3CA+n`1zym=#Ic4ij|d> z^70EOJXqnR#@6}*13i5y9KDEr_3|a!l*cP*0Fj!S@(RHF{8V=eo2k}1;LHLdNYrMs z8B!mC36S-MC`*0(6kDgcuGs|;aD=b?VK^14S(fuqm<;9yOaFrayku0<{-0=m1>USO z7j!A$_y)k_9lPTdov-2P3<>yg8aPJZ)1z0LpadFQ{nL0VSPr{+kMFhh<3-334AvfM zQ!BDFgB(p~43e5yr^vV+E0pL@V=Bcq03JGYBkFHt3GKZe>JtR3%?at{VsG2$EFo|^ zqxS{AE2R(X)$;xP{NO;5gyrUnacodPfY+8)Z9&2LY*GyEH{ZTFgnt%J!%^i61_N1^ zFC+UwP)G=c5C%4OpjOHyZ5Rt5;9w{D!a-!UUp6-_#p)ZiL>WWw$?xgh-%t>rAhdQr zGomW`zavlb4}d(Cr-uF~cj6--YCPVKg$CT2vzGt|2kM?*N?O!%osP|OPY7QB%Xb+a z78GW^jjx78(vy)%M40-1WW|M$R<_t!EMymq2x!0jp$W>b?`wjRRj0!rtHs-T)3JAz zR8pK17S@<0rlG+L#Vx6=v}=16YzaYO2>-OLW5kNEM84NMNIO z@E|t!O4ADgUSESQ+mOKGmF^kqCJ{C}zfsEeO?I zzfSsD(Jk|`Q%>%nM+-21N&T z99HXn?BO5$ylbU9RXz?3F_14H&rvX%;Fq zY`!l|Ty+){L})Jqo!$!kIHEWnLwVvkoN|?X(bCcay5j-8J35aPLHogtAiHrbzY=+l zgTov&>E5@hKR6peiNWDfNQ{$_kW`qf#$g^z8Z(YAUa5`CymD_QAN~(ImaH9|2P;ASq(|-{ikVRh}-Nxzv}zsdJt{rPX`&nz<>t6TT&o$MR$w`<2U!rmVBR7yw)Wo>9{?_gss zXl!TW*wMlU%*a2wi?ILWI1VnbgN_f?l(wr?AR9m8&%9}f6QRI(&W{qxp{1!sdQsJp_rTn{(IPztdZ`PYRoU zee=oA9{FT^rwRE$oGg5IiLK_%L}GZ%^ZOqsJ;+7f?<%T`FN~h8GY$B{t;%*A!7J#? z$MsP3W+?th*v*eMJSTZ6xRcP3T^tu&@1l__3B-uA+J#;m=Tp2C&eAJ%F~nHh zeU>uAG@u2u6sx=`GS4N-SX7*1b~aQQm_b^a=`45;x0NsO@mUV$Os$L*y;Yt3K2}D~Bv$-nE-15-Plj{v;GnUt zE?&yv22%Cee7>uzYwMjb4k&SfLAU)5W$dNLMo*sP!AqXZwREQ{w?iF_3)(6vLB<+qDyU!lpU}9Utd;w4`5TJJzCaJ5hPm zr>$=)oL%Lz{jILeZVEle(Hym4kZNL{ZG1FpKz{TyOzsE zI#}kEJ&o_*m-%#|wl{k3JQkcD|%*h*A1sT; zdbY=jV?<0zGK1h>XJ($Rj?2>NmpQf%IlNq37Z)uO7q-uwIdhWwGLUHW z=!%H6H0IXP^-w1F{kfO|tAT)GMPI_pmoN9Y54jYh*QdE}#WhjzyMkwjS3O;z2qq;Z zt^dTQ*ccMmHMiHTy5XeO*?6^GGUFm+1YuuO@VsC~$N-Q9DnXJYwjH~H% zKiFB9$<}{+gZ8kH4?@^!jmmB!^GjlXs-glJ;ghD1uP~|)Let3fuE+H2l0u_Lu_-C% z9%tO>`fz!*@<4El;qav$J7meA+Zx@})Ydjjlk2e5Pe4Eb4~XmMzR;DWSEdw5QSj)? z^|;yX^XJcRZfvAs7%E)0eVDc8*Vs<>8tL`j)-^nT(2Q_O(~F(Ibcw-E%6TKLy}!_A zWT)-5C|q4bqiBe)zLk@h*v6pyDy&v-B7mIPz*$vI4Hz?0MRQ`rt@=MbDC$U*C4IrG zuG!EK%52DcFdLSUctZ>`k2w@a0by#ZHK%o$GgVJJbZfm$Q__a!@ z*7`U*KFn7tZ{!!fG`LJaT;{aeVWn%eGF)KQ7|Kj!PQ+Yu5A$hbcQ-H)sgf7N#mQkv z^i8I%sp;9XXYVzW@i24c!=oint@<;GCBxVJxYyQzQ)OLu{E~V&v!VN{QQS3(hlhth zw!S`HpS~6yD51c*V@)j2aeRERx?f2ao)1EuodeP!VKe-hm}$R`MnlYc5Czhx=e~~B ziu7vvodV0g^h6gvE-wFx30*7NCNf5Sef^zCPR?cEVOzY>;=C%2XsXEY92$5W#swnT zhO%-w*jZT`$i|X?+gqQR6VFtjrrzI($qCG^hfTNRD=t#dh01V3%zXh864wqHbT=vapd=7t8{zEn;d`D8bLWW|MP&Ug;+zMh9ndUVITA*zof?R2yB09E;gx=_@cM zQt$@$%1uhfKaD&Sgt?&6lWD1>&MGh2{yeG+)kr#i>vLMNcZs zvmLL27b0+VzL%+A)g45;q$79P*~Xs)IX?a>(N*x<7Y!$pNK>I%4lNH#bZl(#N9}Bn z9-NlJT$+VWjkadqSXo!9_f3(bSo0(sIrkqEo`>txQ2F@aVArDSp}KHrrMH85C-T;f zA33&TE~G{q%t&vwL#?;h=%H#G8SKGuCLVPodYYibYpFQ=#e2 zkEd}M-FYria-NkbHA~G63F>|mc0;Fbv!PtcxYyx%XU1t{BIJV6p^?QA@rEc~ssZsFc((880h$=J0?i(S`?*((R+AR=%s z|Jg#Qb6~^!CF&$?0fgA@Hfo{6J{~R!E_~={VNDVAhdDymMUI-z>>C4FvJ@;$b$$2* zC%zvRY3Y+d2Px#PV7-o2651v)w*k?GtX)0nIt`Sj&>JJ%o1fBJ{pXb z3e?na1kWs+D8hcIrM?0>wMQ6q>A4D%lw>b|re-C3d@ zyY^zserez&)wH!A9`N;&+0BQcOa%rXtOvgDhlF_M$}CHJdYoe^(JgqxrFOskXs6f9 ztD1zi{Pt}*K4Su_B$Gf^^LAa$GRHj{4H=G4LdA|cz$sQr*r4T{>*PU3-Hv)aXQq8O z$;Rt~e|ms%GWqiwe`jkMg;RiC#rDo@^J=R^GqRzv)5lW&7)`~UyQNRtnNVg@?Iq79 z?Wh~ApTo|}VJLU=U1ny|8;ZKUJ#uEbe5(QNo-cC`;_7^y#$U^s-l%Pkl2_WFI7!&q zXg$G(txX3DDdj6l*sb0Wst}tDWa|*nuM9ZZG{w+nx<|4)T8|WB>GfIsB~+FklsP`E z+q^C#CMa?t=%>??eE#mVw`doaTFCmXyg0bU_~GSaUS>oA`nY5vrSfotAz1!+PxKM; zhYrJG0fi=?cGe*ly0EXNgR5p(nzJ{U8{gG+(Zesh>R51MgTwwAl=X-ALMuX1Hx29? ziR-QhR&uEP_v5QV{qR!>ujLLt)ytf`v-a11t#XhKW+Ty8thy!{hq#B-Q1flCTj9q8 zRZreJ$F{%&=KL3qj?Q>sZiRU}5VK7*HZG(m39iTF-Of#sEPLEiH0q@qR=r8NxgEte zWajV24<4;B3`;C>Tqy>bfVS8(3}roAZ`A3K>!VR4il+IMlJk79JUmH>wKPA;8tZwX zw@MV-&agy7P9=}Tg`>m6Cr?QBlF<>clOb~qt4yrGn9FpX|68?_)pe?ms00Nl+6=3# z8A2P?GdRpMWIATFIs6!e#d=q9)0+!)u35pfdkLhw*h4NEtGypT@(?J;p8@?;09tjl z^Ky&v`NEXy^Qw>#YvMjcd~_jZ;X$EwyDi?PK+>}rXB7PWjH|~5WLje&?W5t(B|V=e zuOI9rAVxnw^4qF>Sydz`>tmD|`?8^5u32!24m0oq0LQbyhHJlfw_0?6XGMQ4W~9)4 zJX41=n82L=Clb(aP|p8&ujM&2p;IfzLsE48;yA06{k-^;&fH2-dTq8aqDJ?#Mg1lz zJvS64gV!(2fR3e;NeaK{IbFva9yrrjU(veaa}V%%yI2F%?!9c}(e5~gIEvUdX;M=| zPKWk8gHHQvQTgynjW5OP`EVhd@;{e}p_IsGrC%?nf`$f@1sUZolp?(EVC@2r4xoxf ztHay(TBECyB<&bS(n{n3_JPbF3NZnZc|U^=e}>$+St56rc#4~nO!bx?&lstR*DL(H z-pcfkErs5(9}9a6Iz5ab7N zYh!^hJU=~!=j#((xD@Gd*Xa0~pzcr&j+^$R(f>rUchrwGiU zl-l}+!9nlmx%(b6nL7D&a9&hCuHR0+fcDWg}@-Ggqho(}9?Pz%4l#^*=Aj)~|{P zzsMseH&wA~rukU?wUk4{!75K$dU`8Ss@OYbQ2#PQPAeCv|8Y!n9aUQof&x! z%H6B(UFYgg7u5zB2h~A6d>`WNYvS0}<3LzQ11cz=@g)0e)_nT}@0B`G=2{poshBmw z^~?>Va{-AHA(X4b{B;(8${LhQ4#i8%z>o@M2O%&(?U#RAA6ppqDDD1X7Bl=0Lllui z!vF0W{$}dk77rKElU^`d9S#MD%At(H{i0*u8+)V$-f z)d0l~tFRHi#{Arz!?)h%i3!iHH;OVkckhasG=;O10#RXaE=GTl8>#3>QcD%viGBb6 zeO+B$Ful)H-ROS2g7}Q}~+s*xLgrZcKPPt{@M{FQeiISQcPco zKAZbicgrh&=O;j}paeN!ZepU)Rpse9B)qP6#i?z9BgecGHkkW(rU4es!xe4vl%TN` zJ1pb4jM%S7D1(K#?S3B%gtA?k{Q8x+893%v{3WX1X>r%BMO<$n0CgtH-nnxp8(G08 zOOY8(DP}kRaD9@p`Ua#1$WV4;rS(x7a{HY4_4W0VcH^_E+%iPpnqEBDr!F;?gPOO; z5tP}ljvpnR9P(h;;C2H2^yJjh2(4>OSb+=ppuJpRq;#05bWc?dqaY{uzZu1SD{Z@m z3o@DYiib@GjnltQ;_dBCIht1;g;H*bybaZ9udTh(&q+A(aWArqb<-IV1$AuBubwAr zeGu$$^^>2(MEaEQgUUg^Mv*mpq8gwA45k{O(Z!#SB`1KO0eV`FEUi?+I#d?u`qxO7 z>Ff&#bf~|p-MM`my-_fL^fl;Cxkg06;^kFw>)XNt(fV7p7zJG&OoA_R)$QhJ_+@xIPINXf~>XOV(_~hy;8x76VZ@s*# zdQ{W-7tYB#JfEX!2CB<)cPbHnPkF-N7l)3kf2=_Y^X3gZ>}d>4&JDf&t*^Ma_}Mc^ z<-HI>=-YI`TsNQnSOQ3z^A*}(&+54TEv)VBFM0FPbuVyHS@ne?tAQ8wAZI$8nkF%j zdlo<6?IU59l(=}ojaPiE(vF7!NYGD?5BDP?BH;7QbFDG*M_XTzNaUkOkKouzTEyC7 zcPdDl#>U3Z*P_aWs!aNoZY5R&Stue>^2ug??JWE6qa`3b)M5nZnt?cde01R3cl2YM zpO4RoC?ZixLc+1e2WV@_elc+F-jrWk$5i|c=vzlX_UbxwhKORe*|arUuhjl|z076H z-uFP?wH^Na+}#IR`l|l6jI6A7Hu4i9l)#seJWj%f365Fz?S)^qU+lUTOsD8Nj-DY; zWDzyH>FBrv)MAiT4Pk6T((27KnA>#bW@bH~KA4F;J5{`2QOVR{?=8&ED&T0?cj?LS z>M_@=(y161!UU1!vF;yU7FgEQ)GTx+3FW#q@@fPG1k_gMnIuR#C|rR|YAXQ=5OLe3 zt-4y_nBdOj#e*zKJxcoowPbB+@!#glKdcz;f4d4XNKwVh$l++nDH8r*D0d#I{ z-6%%>Yc8cAb}ZzBr_L@jhdU_#+a@eJyI+Wp&qoS?;JoT10!8ZR>?F@)Mr|BMZjHn? zc?se^3A=H(rG9~(*JjZy!bWvzs!_ntqHcSr#E{U?1Yu*sQIlHVa~ics9UUD_Q2-G( zBZY^thrL=_T7eX-M#A`?bPJ4fk07NTZ@V%Qe&+*(kT}a_yxiHt!vm}7G7?B z=Q&z7Hnzl5T3j21Pn{>kN-+39dTlT|HnwTkpQr@r%!nlk>%r=%oJ>#;pC7F<9qv#k z>LojOHPH#^vdDYHbG=Q6N!qeJBnak+y=aIRyrTTiS6-tODrkMH>EL>bkOj75arHS2 zc|tmU1d0Qfaf^$9v@PH|b0g%>eGkoWMx9APXG{QFetL9SPE94+aaYV%#vzLzV8X zDk>@{6bd6@6B!lNnkQp<-4}8yHeN{b3R+_)-z)(FJ|N&PXQGwK&z0@`3Yn*+^mf0dC)M6LCz|uxe`jT6b6fKd zFadxD;7hQ_;btw6h>I-yNNjHadcx}}*ZZe;7R6O;pYhwXsz8d~OeWjozWgh+yRE`U zDY0eW-^{HBqW^JX=@fzsmlh|!Q2I&#N^ccP$6vVm`$t>_4DU|5x_``Clu^*w#TPGL z>|7jGx|c3VZjY!iujB+V=1m=D?U;BNd{?x4S5MDOX34%Eoo*Ir5J?dFX1m5n{^Dh`%u?1O4Pp#xXvsRbUb?n)E<~ax<#G$Q#+OLxRC|nwz{NcnKZ{HTuBK#>b+I4F(xU`q zuwhs*4@>Qr;e9QKn66z5Ci3Odvek&QKTOs|VRCM+57g`4-rfxDY~7J-jtC!=c+PLb z08pOo54g7QjaIli{Y6a34m4QLIz@cHMkxsSz5cynt8B$`i|!PFnF?JcPt70sJFW~X z=77}8%!ET~vDi;5=cM6^#Y_l%j6pZcoS~LhcUQ8KVaew9_DWyI02rRVr3Dc=P-Lf% zzyWeVwdxL6VNh8U#gf>T%QL6HZ)K`XFBK8%{Sf4z9(jKHX16?{+YSv>jd0Sxs@>10 zZEfYqB%cP^|579WB`Ja^8=jyBbh zk3UgYU$@YDzyE=qq9&M19p6z-3zT(SW{6iurnW7L*Zl^+#cj&42om?Cc70 zRBseHYd$#OnyHsLt{?_-v&EK!t81vuzo!-bCi?wIGrrs>e&O+NWC&ge`$mT zjs~*i$y-3U0TX>#YR{`dM@Ls{LXdH=y`+8jZXHDm+A>7>tJRcn=3s^EZb1I-*DnhI zE{dO6TQB<%ka8;jkOad}dG{Y;_<$zR)Nw`T&p2Ljnwy`$QZ0ABL#(yA*-*O0OBKTN z$~+ zg51w+@BxFvTNnxQ=vxr<6VTrU(+T+Ol&?21%Um{Viv|7Y!R~5$T3QI3JkpVc&Ulae zYrz_NwkhJ`DC#npyfT39DT~bMIVyW^l}3d@)n_XC#YMNSA4J8d+m>3`b(5S?2 zYkmE-oV!#V${XeAp`dPN_D;6wUFn-YNQ&j&_Cq5bwl`(y+ocjgQSk5vYuSh8XyJp8 zFsnWvU*FCod1%dRQFFA2nAppsB23RISul8_gcAVrJdBGr?0JMZrV&gRO7bC=x z1MjuY^dEv|(R&BgN>XL2PzXGD&*dgzJcT-6rxg9K%4CWUUH=c{r26J78z1v4FlT^+%IojpK#0(_T%`4q&k82_y=qcz`DDK~+s3uNY}UW3VYJhAxk ztB~>DfQ$fh+PwmDhrurtYB%^HkvWlvKxrt(yZNCxiYJU!I$C?A+*vdeW>>k-olU4= zipn4)C6&3lZUTZEj9IJ6(VDZWgZ%vbq?X)VTm?2G(QJ3tdqvJ-^o*P-=Q;yD_gnQ* z{-D(c<6&OMu}ChpH{5NEJGV#Gi{pVl&&|oHK-P&}dkN9ayCpJd5BN`{d24`?wD|9M z3NZ+u{J7ALSy)&&#oyygX_uU6qq564NN&P^k)KtE@bIxh+~rTK#cXOfZ_Xan&QQvT z*D&Q7VhI!dxZZ;znuD+zEsmH-tI6jVgE9@JTnnCQ49icO{_u9~7CgLu4TBdguCG6l zDC>G9gg=B?lEUSB?$TiX(sLS~LAA;lBk3@hED0?Io7_XA{Rfb`Nxl)zGwPCtwfN43 z))xxzocWWesY-1=ByqLvv7gGwuCyF0EqJqJPeiA*^A^MMANUgBsaf-ep-kdnZm;$5 zAqzcy`oTndA2k(~uvr^}bH6alp?J5ER~2+ZvT}t)N^!M=P2pu2(OSt|8a~DOBi;+yt)?Ans)^VC;D=;y1($Avqb<5 z#=VuVni(whe*)hCNINd8EG570Iwd=gBeIOCYw-q?l>&jn6vlG-_Kw^8KYM`grCT{RXVTsPa5`T zFKU(@2)e0*H!>nXKKU&xRtyu9FsyPYQo;ybVv~}p!r39DZ+w3$aGzaODE%b<(g@$T z4M-gslb&*!KNLlmiVrKNeJhzY&uNR%P^~B;{g+lLj0$gip;OvX?Pvtprzsf==czO& znv(!nswU$Zw(0i2&i)UBa#J$5XOe$6yLQXwABKpUm;b&74BcO6|KsHSe|Xma_o-Vo z*xA|HY+@f2!<$$eDENg#{?a2(ZDl4ct@8wX$Er>&==Z#~fwGFvdUP;dSHm}P8QJH=(%F?VG z)_L&D6vNo=(Xcw_`*Xj!lRJHUl51oZCS=sN!H2Onx7&hmkFA(LDO(@HryMt)uN+aK z$NlDhTRMBNn4R#NWBS#JR0&IU;`)bk#K3p z;VzB}_kW~H!WrA}ApbF+2Lhk>El&8mJJAs1T^giuI}Rjs>iUUKH~EGAoZ;p6+b(&A`nSC5r$%Bs5hB!q1exj1$<4gtBC7zB>Voc+Rqi za%BEBj2=vQO$PtN>#f{}YP!0I*NkGU#>*c*eAoy(!SUTtlDSoxF_8`_%14(a^Cw&x zEe%qB?o-!Lvq_)+xxu#oHF-;F(uX3&JjhtL|AUd&KfmHD@{X#jBmfKG{pWwFKZn%q z%dJ=A|9n)L1M&2%pna2<$0a1R_c4}Jm&0~<>5Ex+Vv4vkba?8LC$*fs`~x+$2wKtf zb=H=xQA|wC-GU_47BC5eO+C<4-PWqW*D2fG!c(*YW??-~C_D>jgsm@8Qf9q-*VfuP zIo66VGIob~BpMikN?YdUVTtu*wYRr7wV?U&DYAa5)=k*nu*S)1e`BVPTTJZP!PZ>m z1~g4-vfOHX%JV4Ptsx>ZQrh#_R;pWYTH!?BPMbl3P-}jSBAEUL+GzYy| zsPi~#;JJGB@kC{@HEeoouFJ^C=+ltZECjnBn!uk4O%Wre5z;Sv94(Ub9DAUCW>N&4 zRU>Z}gpr4lZ@3T!D>YLYc&CzJ{}ti--knZz|w0@c02r7aCZ#Lv}f4R8&;ME2@UQ z)p24%QcVUWC8gts$hFDstt~KjbK?7q41eU4$!fvlfXtSTXqGO{OF6K5&q#?ayb(WK zQo|Bc{BbQpJhBe-aRW*muf?mnB1ipi6%%Uh7ohnJiW(6Sg#oD3nBST6BbD;5HXnG` z{k`*r(dFi3Sy|co(?ibE-Zbg;_Zx?Mt49Y5X@2NPk&M5_JVePs zBy`4XlL*)CNa<4%c6OWn)nj6pipwd^t>k}iV4X1Kt>au?mpd1a*W z1mV@4D7e{vmyy)(BwXAFPDu*+_U|5=@OM{ds(XJ=xCP#=P8ec8)H2w z;tb+WVWTz9>rT|MMv1IESZ}ZigKxv8*Gxbl714HdcH-mV!FwKdz3NUD-Ts`Z+#bn* zyUNQY(UvG^0bkr)t64WsL3rJ|b?e!)!(Qn#_q~&wy4~VvDaZQa)v?Q*ns?)Q(R)a)V^V*=k<-`L*BnIZ z_o9}I!;T5hU(}g9I@j>46_^6}a}Z4eI3~QExwdecS~p~1y)MT(>1oJC zjwV?-Il05#W#_}4C-Xs6uSwmUFufX2mvRgD>xjrwsvVboE4^)tR4j%I0vK&-R?A05 zMvzlpFq+u6k6|t|0pKL2To+PCM@NsPy6&qps!ijQkeES~^zkrEpfGo=N+091x_2>A zm1O=*+A{9yu<15p>*xags;4te*p>I6%_ltCk))NGl_QI2z?gk|SYp4>k#29)#n@cavW*u_KFoL++u-4bnJ;7T9basJ6i$o6(U|~7%aLfypx`_TlY$Hd z<=?&kH;>(4#&S+6DZ7bEo?K=d3%gQiYHGSw$b1PtjChGgh_@IDDe*W8QjRO&;o`dg zo=#-LzQGMbyPMY2+?T3kUN|W1G ze_boRJ5^FIEexk-K9c~oE_ZUr*-#7^DHmr)46&+L>h|Bn}HhTa%#t6_67 zWKw$nA(Hcn1z|T?GY*0gTJnVH+k3-Ci ziIF30HFg{>tjXu4IrQB83kC+J#e}_TliRu#g$U==-(xesZw?E~^f)ByqwZ^q^s??r z4m&kYF=ur+Cpv zfGtxx8EPS7KKs{>?bL&CN$IVIR;>5Ci05&SHfH1u9yK4~X_N0C9SPJpt%}{NttJVC zDlW9D=>KJch^4;%BW|vvnG~I29lan?(K9Mxo)0!txHN**en(U8+jK?ibv0~U7x&i! zd*pDJ2`7H}u%B3o-C%1?6EG}FSBc_*-TY0Gl*3?Cpsh+Uh!lf-U@g5>z z_NgsY)m)=bGhesn*{=DC`(s=6popPuxYu?!X>||cD>L)b>Nt|Sw8G|$XbNUIR;Ik- z;9&T3eG}?;poJGp;pld6>+YsX&}H4sCm73qkO@ZZ>kYzDbkzPaeX>{RmGUy-K-1H+ zzbW7hw*u``XD;5??+ZQM{`vQGx%JBDJ>S1q2>mMIw4(2{H~u9D8!tIxh_W&S<%3n( zFOv;9%o;IfZ+Vd46%uq7-rO~JGOs&YYk&C?7q~!~`4^|{`N)J9!{fjcBEoCIvDySN zCksPDkEXo5Xk2nmLcKi7nQb-e?i)T$+DCw~Z^GTVG5Y2Bx?TTN!N` z4zGS7@7ifKyPb%Q3N^{3{p$P9=2szAD(;40mrNeTk1oQ5m!QORY!xBB78Iyp*|VHo zzBQTs2Ju~J)3qA~3azOs?vwAu1z*NZuuB!{pki&LG^CKmF)MH@X1rxVkdT6G>PuXA zlCw#cRpNg2=2*6!*tO^Lb7ijAA?IVXG#}1pF|lTtMbg&-pYpE3r#{nCHPhQ&@)?VR zc{m#Py`H&$zaL~n%P_r%W_1D1o8{~s2JVx=S#56Y*uq*{{NuJ16Mn)~Bl^9BLFx&Q zThC|hT_zMDAn0Kbb8v47wgaYbo5WJ#b((!QxtV0+`M5v*%V2gX3GMz`M|3(ss>rY~ z-6A;t*RI?|M(0gOmQ-p;!lmZO>=@9_*~BE13M7k+ahcs8K7D zNb+cfaBLu7cNe+0D$Y;y(Q=}45QJvKXLi2Lx`_!de(4qQM^GHvDridZFwE=Q!9tdQ zK!8>*MO4a(6PvimVc?AsyZKL5e0<^7HLF5aUb1V|;GAhyh%Ks{pP8!>C2_hYScwp= zH74m>4sCr7^pVfGTlQ!9<1X_6SG~nwW~F(0e$L3QR;iAA@|sRc#MtY(OfrmhzpSzgG=$i7pg zSC-^f$Jqvp#Qro3nNaX;I6ORvfqs8?m;i48C(Mw6`KSf4ZcSLS1 zX2B>l-K(yQxFJ2ePhwYITaDS=_9Gdu@M;ql?WPk(oqeKLw?B@m%70u8uV1YONSbqX zN^2aG93ZlU5p?2RD_*CiGRr|19tv^cR!ZNv@ktdkk7Z-i&)2u^?3BnW+u}7!nz)gha@1EZOyvl>_bM1A(xDtS%@5}x`=OLeHt(`pouSf9JahfEe-oNJC z^fcT|Jbb_stiYoG`8g7N&4j?*?QR|s`5s9hK9=^n!Z1Z&%_q+Bh!a_1GZj4pBcGAorTzDxSr9IbS;HOrFP;6IIfZ9zFKGDmc=#(t^7R1=K~? zM~lA+u+!R7_GKsy#2F@{D`0fFh^Xi5ewgVA*iGj9Cb+siNx`klS1;u9$7pN5wu$1_ z01zbv4f(GHcE=(<3E^GXv0Lb=<(1VdcmG^>vJUWze4Lfa)dIM3o&x7NLb}Mn9Aeux zkjTOZ92f;AmA6LO_p0zG!er(kIwfi~l$S&i+kRMgQ^b^)8N~NSH#T%ZVdgm(d*H4F zyJze9y#v4R%BxUGH}>_Zv-Mq!K};98MyFxZY9}V?v2Y7os=q%pSIcHPD1e2CK}zVx z4K6M&1gt)2pQeO|+>%D@L-|{q+XGHRwGJ<93II|oK4_*+BA155Uzz~!Ca0{Ngujkn zWL&%5Qv+A(I`NIJ7|NT=By5)Z10ItlwCk)c{**4Bk{=UjOU z*#Q%G zQ>Ohh6dMB0&&cW>I%RM-*BH_)aEEYkC`vO>|H~`-mG@#&r8v2{Pcq})J;+TIdiZfC z`@w+o`qzArzudP*v8$`b7K)Yu#owoA{HO5B1J2 zKRaW7C7K*6av_AZRQ?f{Fu`wwg$YDCL+8zj?q0A#Dpmu`(5@6zc=J z8j_UjuCBaL6m?_CcA!#fAh|q6WzRrvp+%8385R>R>T#RP22;Y)zf8=q_21`##{BD7 z|Gr##{x8MLec3T_xZheZj16EUbYeH|=zJa+fU)2;T?q&XIQ-~LL_xNEh@tV(3onHc zPmkZ`tAxj#I1XWO?%`(uDGr%bVh&gRC7CNfPaURwKeBzN*z@EW-cd8D z^x%R#nLkdYD6Lu-C6HBV$U8^YkeAq(nkn@OIFrH4(%n3W#N^>>;hw`-SVFwll=DrZBX-YV|%Q?tB24pa>gA~y%Q`3y| z@7|BMHj(S!9NJc}k&i`~wq~c+xo@^oPS!XV>Xe$n;qc|5{Na4P_TxO9%0^hV-<>7G zAndmvm^NR(ehtdJLW3HLDfgS4l< zTQUM6!AtKljo$3%XSXs^+|qJ$#QA$i^n~kdO9+sg0s;d`=q2LCyFPvlB%!0e-`L=T z>2BDRCh1xQ?EJN_}X-KR;uqe1`%7Cv`Ead z-OiOv`Lt%9mV9Ds*&oP}2h?NXgEwcu%CL8vQMh6$5c`F*SMMpwgZLO2mXtt|m7x4-A~j ztiqb9T$_*7pULAA1RgcP8U8z{YJoZ$urQKj2#&+>4gU*ZPI%*+g2KgU~qrYBhR!(r32SFc``L{Yit z&M5o7XI)w(ymWcxX*!0}q(D839*BV7b?F?AUM#Pwu`x3hjgTcgQWpq?8LMZb zkJ5blGnFZemO+XklxzWHLIh^bWnE359(<%C&>AKV_P<5?@p+vd8`L=YG)f5(;Nzno zeM%5uyj2~ai=)#^Sxc<36>~Z3+2Q9RBl!{FJCA_TR;nL)=68SG-QWCnHroC0({p9f zLw8*`5W$wowoM`>+aztttqbi=gXr zhFrb+W1^~b?fx1NC2glXkc}bQsv@^tTel~TngbiJW^v%jUFNzZ zat`CBe-B599dVB2It*I}jOX|d&L#k(9aYhV0bZ>C(@>G~(5e9FWr|;DY^=TBR zQMUHK=v~%G+ELUiyTZj|qzHh)ruvJ7WNleRW%} zl|I?I=-iVaz#%1-IyzD1vN>C`R?W%C$jHGF; zEaUIEbXxktwXfQuxbU4%UYg5nNKDKHDj!)t9J_^dh0va4(PqmvT0lUpp_G6Uy6Wtp zHL;_*09)d?^~^@XuK-~=Rmh5(%YKB?fp4M6sCm9OjdWAu;QNaSQR|6H`5+Py72M+D zM+uKo`{}Zd=ex;ENohr7DsKCe{64})dHxPDX=#SA*;!*Mp0&Y(hb>UE$5!Q@Iz@2w zBYs=ONoE!n)f6!e!%Z5ci7Rw;#79fX;WWZHcIcR_g-S2jKV?grxwwd&8Qb=;?~P-s zkrAbQKIfv}hmQrkN#pn?KGnU3F%A63SQU&M2#lGZfwI@{?fQ%RBb@Bl*%Rx|i z(YVs{q`Kz{71a;ti_IoYZ{pEnwOBDA2keyO|2FIkES*w?7GQB|AB*bDkV8N`lbL4w9)ell)(4R z1L|`W`t9lPnB(i7%;kA`M2BHl1OmlB&|yKft&ahgRbpN`$WVH*KRhH;0Z0${Qiz8Z zg*|A+JO!*)f4l|iZI()VKz9RKszFI90A%bqR$}Aga3uu<1jL=!K1Ft_rbI;*IjSFZ+( zUpYNJE%HUPGm_TDDpG9vVE*M}N5}NhtCufXIXIffOo7Bbf!`Gc7`7NzKVKo*+S*D+ zk2P9gPy^&=fvmm3i|lv3x#Ef2N_(ZcEQkNytfZY~IWrpZ)!o32RK=WDIxMvjMGQ}3 ze8D=~N?jXkx1V3;9PxAKE1503cOGqbzgZos0p?Rl5;CZB7ZntYJ!$b^3keM!*OHy{ zQVH2$ycb_wTx@Ic$;NW>`7bL|+YH136AC{0oN+6h8aTO#>sE$msfm!y*NIYJpq>1v zAUEs;ImcUYs4Og?6#zO28VPe@4}U?I?>+n|6wAFI7|Pc}iQ8*>J-?y}>kXB@F`9OD z`Q!d3x~?m~U0ui(>kZajYhx1==d}r?Ugyg)LqYCR!3IG+Zd=dRYmw>c>G36H*{_x3 zc-&8zIibJ5)A@;Vpe|tN;p5|@6LauRdVBxvt;N*(j^_h%KT+h?5bHT++H?@MU|R>s zz{&_I=>C`}ELu?Me5P-%tJ(WVh)ZL-{9lksA9Ma~@4Uj9XB;Em5&WkskYO2l|1=lK zozYPM3vyG8y9xZ*hE1@NPWEvjr>9R#(%N@h2Ny5P4axH}wERjxf1ONN^e$7{9|qC= zi8XBvaEK8i+@A7osT%^p16DTJM@1m^J5y?drJPx9_Q>> z*^uIk-C}U4rl~39@S`u70EdLO!_zFxd8FFW0%T%-etw|+6Z7IlB!l$YW6DXRTp}IP zPIt2NI-&FVMas$tMc$Rlut1_K7<+&K?CtFv;ZuZN;)8&3!vJsDjFw=B0ntNrOu<>( zmoW!Ne;NvE86FQKf+izr>5t+&OJ4}XK=Tsxi$F1(QCT_C&r{ue0qeftG=?()1)1}r zGJvO%;{_iFx&p)6YLoT|K9jbaii&9nr6y9*~*k*w;FRt!(i%QUCmSuUV zKc~`yy>^LxoK(;MxldxI7W=I@AN zBr5tD(RjYR4S)Rl|JbcSZE5!~=Ggx%>COB1!Q+27t`|Aw+$rQ~Qxe}UT14mTRe-2R z9GkgBL@ai!Us^SC+g-xW8bI386zE^j2+0%qO(mu(7ucDZea8`>0KMJU*H2DNq^6{7 zuXtX3FFi2pl`?R+G|$5)yyioBoo9D$x}jRHO^Z8{6M;uO_*H)gt2}>Ld6A=nC&*cg zig@!Cy|I1Bl647e=UCaDvr zL;xyj7=tjS2|R+jyGxW-*>BFaI!`)k$;ik+p(NY9F1TjLKr#o-X3$+o60~?_{bESU zZO<~2UUC{rfHBCKjlU|L=bKOExO9)(bf6jA%Y(Fsvd?S@i909#P728t&% zT53YR2u+kRR=!dJCBt-m56mI)pbB&-;syd}4!V1N3YU}~xMZ{(s4U1w#OUjHj z_L|PA2L`c8TbPd&9Q5bB4GKcA+C`09g7fn7ww^nBg50_bQconriuY&%_dDp}zrJo0 z?N0CujBi8S)BOgElPL0e6a~fw8+JmD6U*_T^hW`3#`+Y(%;`- zRM<0GX=id(m-qEn(v2rg$${-HKbq$E=$t1SUvU@p1&4$*(ls?VZw_-{CJEaF&MCRJ zdUONU=@NX@ZU+R^BTzW-Qh`o8$R$?3){2i@yLJs!QuVHgGqjwK^|+}~p}z^O<8bLq zE?mawu@>8F@`<4<&=ewVYV|@xI-6N1K+~QlyTe=0A-5Nx!84$fEA|Kue?6tr(%!N^ znMhbM6TfnEW0=W!Y!EqN@!CT4@Tt3jZccSG8)~bEB3lG=Kg3?6^R61hp zVv!$!djKEWO&b=cGoC@1Fn`k(Dx*u}W(IxmVNg`94Lb2In_jwnSr&UqC`Hok)p(J* zsNF0U70^H?Mgg8VxvAZ|_jH8Zk`4 zT@bJUV@RvrSI}oKL~MNo6%eVDn%d{>Ug=&PH(R21KQhJu;-gR*OfLhv9V!hmYQp}~oYbiU+ zr6QU|v56a#3+q-GRbvVO?Gz~wvB6`I3hfCybi>@p<_J<=azP2WMGC;?tK%|kkObA@NruJ z7ZQqa4~+jn7%I^ON!YX9CD8F)1hrCjcJ}8p$t0cG*;x<)S;*=jkE6ZD9L04<8eipf zbMGe0p}Z>-nN0?7Jd<#A?0%;cc=R!@Np*R86$PLg5HuhB(f_u+^99FlQtqqnBw?*l z%;;1}H|x<7g`eYm94WWbQ&(3vHDx7ws;T*E=IO29nGm7ud#u}c@7^UEd}3+20%CN= zLDb||`WC==$xoT64|p^gb>q`E{@>-MbTEENNT7s&BGA1bi@u6Ye(C@)fK7dfnseE`bZ+gstECB35mDtJi`&hr%E@7S{! z=;-J!UuM%T`kO<3CVY_#*a4#mS9=7!pXuLnMu{ZKlOqE?CX1LqDbG0r+iAc+O}LRr zcSYJ0@l`>c{pEHl+`{_#gD*{~{;R!HjwZ;T)6rx9w^IWU=fjW(we_b&QJtK8^ZD&PFD@y_HlA From 84f260b20a84f15bbed87e9cef7113aa54daa167 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Tue, 31 Oct 2023 18:36:26 +0800 Subject: [PATCH 333/518] Fix UML seq diagram --- docs/diagrams/vis/visualisationSequence.puml | 18 +++++++++++------- docs/images/vis/visualisationSequence.png | Bin 13640 -> 15921 bytes .../financialplanner/commands/VisCommand.java | 3 +-- .../java/seedu/financialplanner/utils/Ui.java | 4 ++++ 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/docs/diagrams/vis/visualisationSequence.puml b/docs/diagrams/vis/visualisationSequence.puml index 82bcd9fb5a..c09a083995 100644 --- a/docs/diagrams/vis/visualisationSequence.puml +++ b/docs/diagrams/vis/visualisationSequence.puml @@ -1,20 +1,24 @@ @startuml participant ":VisCommand" -participant "<>\nUi" -participant "<>\nCashFlowList" +participant ":Ui" participant "<>\nCategorizer" participant "<>\nVisualizer" -":VisCommand"-> "<>\nUi": getInstance() +":VisCommand"-> ":Ui": printDisplayChart(type) -":VisCommand"-> "<>\nCashFlowList": getInstance() +ref over "<>\nCategorizer", ":VisCommand" : sort cashflow entries -":VisCommand"-> "<>\nUi": printDisplayChart(type) +alt #Pink cashflowbyType.empty() -ref over "<>\nCategorizer", ":VisCommand" : sort cashflow entries + ":VisCommand" -> ":Ui" : ui.printEmptyCashflow(type) + +else #LightBlue !cashflowbyType.empty() + + ref over "<>\nVisualizer", ":VisCommand": displaying chart + +end -ref over "<>\nVisualizer", ":VisCommand": displaying chart hide footbox diff --git a/docs/images/vis/visualisationSequence.png b/docs/images/vis/visualisationSequence.png index 8a1ea01be4288d78b2b80f4ae2417fa81e911f85..46c620a688b0a646d75d0f2b06693b1926931f43 100644 GIT binary patch literal 15921 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 Qx7%RiA~M2dg1Wx{AMyluu>b%7 literal 13640 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 DvkOl5 diff --git a/src/main/java/seedu/financialplanner/commands/VisCommand.java b/src/main/java/seedu/financialplanner/commands/VisCommand.java index c6acf247bc..9144b2c8fc 100644 --- a/src/main/java/seedu/financialplanner/commands/VisCommand.java +++ b/src/main/java/seedu/financialplanner/commands/VisCommand.java @@ -1,6 +1,5 @@ package seedu.financialplanner.commands; -import org.apache.commons.lang3.StringUtils; import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.cashflow.CashflowList; import seedu.financialplanner.utils.Ui; @@ -45,7 +44,7 @@ public void execute() throws FinancialPlannerException { HashMap cashflowbyType = Categorizer.sortType(CashflowList.getInstance(), type); if (cashflowbyType.isEmpty()) { - ui.showMessage(StringUtils.capitalize(type) + " is empty... Nothing to visualize"); + ui.printEmptyCashFlow(type); return; } ui.printDisplayChart(type, chart); diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index f3231e74de..ed8e22fd68 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -204,4 +204,8 @@ public void printBudgetError(String errorType) { showMessage("Unknown command"); } } + + public void printEmptyCashFlow(String type) { + showMessage(StringUtils.capitalize(type) + " is empty... Nothing to visualize"); + } } From 914ad7157ef64ca9aee9190e4dfc2b186d869c91 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Tue, 31 Oct 2023 19:16:49 +0800 Subject: [PATCH 334/518] Add new Visualization tool (radar chart) --- .../enumerations/ExpenseType.java | 8 ++- .../enumerations/IncomeType.java | 8 ++- .../visualisations/Visualizer.java | 61 +++++++++++++++++++ 3 files changed, 75 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/enumerations/ExpenseType.java b/src/main/java/seedu/financialplanner/enumerations/ExpenseType.java index ca60b686fc..ab9f512fa9 100644 --- a/src/main/java/seedu/financialplanner/enumerations/ExpenseType.java +++ b/src/main/java/seedu/financialplanner/enumerations/ExpenseType.java @@ -1,5 +1,11 @@ package seedu.financialplanner.enumerations; +import java.util.Arrays; + public enum ExpenseType { - DINING, ENTERTAINMENT, SHOPPING, TRAVEL, INSURANCE, NECESSITIES, OTHERS + DINING, ENTERTAINMENT, SHOPPING, TRAVEL, INSURANCE, NECESSITIES, OTHERS; + + public static String[] getNames(Class> e) { + return Arrays.stream(e.getEnumConstants()).map(Enum::name).toArray(String[]::new); + } } diff --git a/src/main/java/seedu/financialplanner/enumerations/IncomeType.java b/src/main/java/seedu/financialplanner/enumerations/IncomeType.java index 4fee2b2f78..e4497f2f23 100644 --- a/src/main/java/seedu/financialplanner/enumerations/IncomeType.java +++ b/src/main/java/seedu/financialplanner/enumerations/IncomeType.java @@ -1,5 +1,11 @@ package seedu.financialplanner.enumerations; +import java.util.Arrays; + public enum IncomeType { - SALARY, INVESTMENTS, ALLOWANCE, OTHERS + SALARY, INVESTMENTS, ALLOWANCE, OTHERS; + + public static String[] getNames(Class> e) { + return Arrays.stream(e.getEnumConstants()).map(Enum::name).toArray(String[]::new); + } } diff --git a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java index 78890cca27..734f7c841f 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java @@ -8,6 +8,11 @@ import org.knowm.xchart.CategoryChart; import org.knowm.xchart.CategoryChartBuilder; import org.knowm.xchart.style.Styler; +import org.knowm.xchart.RadarChart; +import org.knowm.xchart.RadarChartBuilder; +import seedu.financialplanner.cashflow.Expense; +import seedu.financialplanner.enumerations.ExpenseType; +import seedu.financialplanner.enumerations.IncomeType; import seedu.financialplanner.exceptions.FinancialPlannerException; import javax.swing.JFrame; @@ -32,6 +37,9 @@ public static void displayChart(String chart, HashMap cashFlowBy case "bar": displayBarChart(cashFlowByCat, type); break; + case "radar": + displayRadarChart(cashFlowByCat, type); + break; default: throw new FinancialPlannerException(chart + " Chart Type Not Found"); } @@ -90,4 +98,57 @@ public static void displayBarChart (HashMap cashflowByCat, Strin ()->swHR.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE) ); } + + + public static void displayRadarChart (HashMap cashflowByCat, String type) + throws FinancialPlannerException { + RadarChart radarChart = new RadarChartBuilder().width(800).height(600) + .title(StringUtils.capitalize(type) + " Chart") + .build(); + + // Customize Chart + Color[] sliceColors = new Color[] { + new Color(62, 154, 230), + }; + + radarChart.getStyler().setSeriesColors(sliceColors); + + String[] keys = new String[0]; + switch (type) { + case "income": + keys = IncomeType.getNames(IncomeType.class); + break; + case "expense": + keys = ExpenseType.getNames(ExpenseType.class); + break; + } + if (keys.length == 0) { + throw new FinancialPlannerException("Error displaying RadarChart"); + } + double[] values = new double[keys.length]; + double max = 1; + for (int i = 0; i < keys.length; i += 1) { + if (cashflowByCat.containsKey(keys[i].toLowerCase())) { + values[i] = cashflowByCat.get(keys[i].toLowerCase()); + max = Math.max(values[i], max); + } else { + values[i] = 0; + } + } + + for (int i = 0; i < keys.length; i += 1) { + values[i] /= max; + } + + radarChart.setRadiiLabels(keys); + radarChart.addSeries(type, values); + + logger.log(Level.INFO, "Displaying Radar Chart"); + JFrame swHR = new SwingWrapper<>(radarChart).displayChart(); + SwingUtilities.invokeLater( + ()->swHR.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE) + ); + } + + } From e4b23255091fc33061d71181a4a2a32b1d9260ec Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Tue, 31 Oct 2023 19:19:44 +0800 Subject: [PATCH 335/518] Update diagram to include radarchart --- docs/diagrams/vis/visualizerSequence.puml | 10 ++++++---- docs/images/vis/visualizerSequence.png | Bin 16332 -> 20366 bytes 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/diagrams/vis/visualizerSequence.puml b/docs/diagrams/vis/visualizerSequence.puml index f1f5d44166..2289204e61 100644 --- a/docs/diagrams/vis/visualizerSequence.puml +++ b/docs/diagrams/vis/visualizerSequence.puml @@ -9,10 +9,12 @@ participant "<>\nVisualizer" activate "<>\nVisualizer" -alt chartType == "pie" - "<>\nVisualizer" -> "<>\nVisualizer": displayPieChart(cashflowList) -else chartType == "bar" - "<>\nVisualizer" -> "<>\nVisualizer": displayBarChart(cashflowList) +alt chart == "pie" + "<>\nVisualizer" -> "<>\nVisualizer": displayPieChart(cashflowList, type) +else chart == "bar" + "<>\nVisualizer" -> "<>\nVisualizer": displayBarChart(cashflowList, type) +else chart == "radar" + "<>\nVisualizer" -> "<>\nVisualizer": displayRadarChart(cashflowList, type) end hide footbox diff --git a/docs/images/vis/visualizerSequence.png b/docs/images/vis/visualizerSequence.png index 2e939cb2041d276c18dfdfae3b1cd269eb1a6cff..11d05c66a32ea7820ae5e7c726a14302bc6e0610 100644 GIT binary patch literal 20366 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 Date: Tue, 31 Oct 2023 19:21:48 +0800 Subject: [PATCH 336/518] Fix check style --- .../seedu/financialplanner/visualisations/Visualizer.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java index 734f7c841f..971e29ca97 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java @@ -10,7 +10,6 @@ import org.knowm.xchart.style.Styler; import org.knowm.xchart.RadarChart; import org.knowm.xchart.RadarChartBuilder; -import seedu.financialplanner.cashflow.Expense; import seedu.financialplanner.enumerations.ExpenseType; import seedu.financialplanner.enumerations.IncomeType; import seedu.financialplanner.exceptions.FinancialPlannerException; @@ -108,7 +107,7 @@ public static void displayRadarChart (HashMap cashflowByCat, Str // Customize Chart Color[] sliceColors = new Color[] { - new Color(62, 154, 230), + new Color(62, 154, 230), }; radarChart.getStyler().setSeriesColors(sliceColors); @@ -121,6 +120,8 @@ public static void displayRadarChart (HashMap cashflowByCat, Str case "expense": keys = ExpenseType.getNames(ExpenseType.class); break; + default: + throw new FinancialPlannerException("Error displaying RadarChart"); } if (keys.length == 0) { throw new FinancialPlannerException("Error displaying RadarChart"); From b773b807986a68a39c8528ac557f16a06a40da49 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Tue, 31 Oct 2023 19:56:29 +0800 Subject: [PATCH 337/518] Rename variable for clarity --- .../financialplanner/storage/LoadData.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 9a9810b014..66a12b5b9c 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -70,21 +70,21 @@ public static void load(String filePath, LocalDate date) throws FinancialPlanner } private static void deleteFutureCashflows(LocalDate currentDate) { - ArrayList tempCashflow = new ArrayList<>(); + ArrayList tempCashflowList = new ArrayList<>(); int indexToDelete = 0; for (Cashflow cashflow : cashflowList.list) { int recur = cashflow.getRecur(); LocalDate dateOfAddition = cashflow.getDate(); if (recur > 0 && currentDate.isBefore(dateOfAddition)) { Integer integer = indexToDelete; - tempCashflow.add(integer); + tempCashflowList.add(integer); } indexToDelete++; } - if (!tempCashflow.isEmpty()) { + if (!tempCashflowList.isEmpty()) { ui.showMessage("Detected erroneous cashflow entries. Removing future cashflows..."); - for (int i = 0; i < tempCashflow.size(); i++) { - indexToDelete = tempCashflow.get(i) - i; + for (int i = 0; i < tempCashflowList.size(); i++) { + indexToDelete = tempCashflowList.get(i) - i; // deleteCashflowWithoutCategory takes in list index starting from 1, indexToDelete starts from 0 int indexStartingFromOne = indexToDelete + 1; cashflowList.deleteCashflowWithoutCategory(indexStartingFromOne); @@ -94,14 +94,14 @@ private static void deleteFutureCashflows(LocalDate currentDate) { private static void addRecurringCashflows(LocalDate currentDate) throws FinancialPlannerException { ui.showMessage("Adding any recurring cashflows..."); - ArrayList tempCashflow = new ArrayList<>(); + ArrayList tempCashflowList = new ArrayList<>(); for (Cashflow cashflow : cashflowList.list) { int recur = cashflow.getRecur(); LocalDate dateOfAddition = cashflow.getDate(); boolean hasRecurred = cashflow.getHasRecurred(); - addRecurringCashflowToTempList(currentDate, cashflow, recur, dateOfAddition, tempCashflow, hasRecurred); + addRecurringCashflowToTempList(currentDate, cashflow, recur, dateOfAddition, tempCashflowList, hasRecurred); } - for (Cashflow cashflow : tempCashflow) { + for (Cashflow cashflow : tempCashflowList) { cashflowList.load(cashflow); ui.printAddedCashflow(cashflow); } @@ -109,16 +109,16 @@ private static void addRecurringCashflows(LocalDate currentDate) throws Financia private static void addRecurringCashflowToTempList(LocalDate currentDate , Cashflow cashflow, int recur, LocalDate dateOfAddition - , ArrayList tempCashflow, boolean hasRecurred) throws FinancialPlannerException { + , ArrayList tempCashflowList, boolean hasRecurred) throws FinancialPlannerException { if (recur > 0 && !hasRecurred) { dateOfAddition = dateOfAddition.plusDays(recur); - identifyRecurredCashflows(currentDate, cashflow, recur, dateOfAddition, tempCashflow); + identifyRecurredCashflows(currentDate, cashflow, recur, dateOfAddition, tempCashflowList); } } private static void identifyRecurredCashflows(LocalDate currentDate , Cashflow cashflow, int recur, LocalDate dateOfAddition - , ArrayList tempCashflow) throws FinancialPlannerException { + , ArrayList tempCashflowList) throws FinancialPlannerException { while (currentDate.isAfter(dateOfAddition) || currentDate.isEqual(dateOfAddition)) { cashflow.setHasRecurred(true); Cashflow toAdd; @@ -130,7 +130,7 @@ private static void identifyRecurredCashflows(LocalDate currentDate throw new FinancialPlannerException("Error adding recurring cashflows"); } toAdd.setDate(dateOfAddition); - tempCashflow.add(toAdd); + tempCashflowList.add(toAdd); cashflow = toAdd; dateOfAddition = dateOfAddition.plusDays(recur); } From cc0864b1d4c08571f3dcb48b529f7d10b59ad8cc Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Tue, 31 Oct 2023 20:53:59 +0800 Subject: [PATCH 338/518] Fix typo in UG --- docs/UserGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 1d8f51b804..86880d167d 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -473,7 +473,7 @@ View your current watchlist with stocks that you are interested in with the exch Default watchlist: AAPL, GOOGL -This stocks will be added to the watchlist automatically if: +These stocks will be added to the watchlist automatically if: - your watchlist file is corrupted, and you chose to override it - your watchlist is empty on startup From b1f7a1ba6633bba14f76e7c31283733eac40836b Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 31 Oct 2023 21:43:00 +0800 Subject: [PATCH 339/518] Fix spacing in line --- src/main/java/seedu/financialplanner/storage/LoadData.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 7293004e91..fd6753f500 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -47,7 +47,7 @@ public static void load(String filePath, LocalDate date) throws FinancialPlanner String line; ui.showMessage("Loading existing file..."); - while(inputFile.hasNext()) { + while (inputFile.hasNext()) { line = inputFile.nextLine(); String[] split = line.split("\\|"); String type = split[0].trim(); From a0b1d83a15d4317e89b03fc814cc26cddb386980 Mon Sep 17 00:00:00 2001 From: hshiah Date: Tue, 31 Oct 2023 22:05:42 +0800 Subject: [PATCH 340/518] Delete Reminder and display reminder --- .../commands/AddReminderCommand.java | 5 ++- .../commands/DeleteReminderCommand.java | 41 +++++++++++++++++++ .../commands/OverviewCommand.java | 2 +- .../commands/ReminderListCommand.java | 16 ++++++++ .../financialplanner/reminder/Reminder.java | 3 +- .../reminder/ReminderList.java | 34 +++++++++++++-- 6 files changed, 94 insertions(+), 7 deletions(-) create mode 100644 src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java create mode 100644 src/main/java/seedu/financialplanner/commands/ReminderListCommand.java diff --git a/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java b/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java index ea2e163f96..802418273f 100644 --- a/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java @@ -26,7 +26,8 @@ public AddReminderCommand(RawCommand rawCommand) throws IllegalArgumentException @Override public void execute() { - ReminderList.INSTANCE.list.add(new Reminder(type, date)); - Ui.getInstance().showMessage("Reminder added!"); + Reminder reminder = new Reminder(type, date); + ReminderList.getInstance().list.add(reminder); + Ui.getInstance().showMessage("You have added "+reminder); } } diff --git a/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java new file mode 100644 index 0000000000..bcf9d1e9a2 --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java @@ -0,0 +1,41 @@ +package seedu.financialplanner.commands; +import seedu.financialplanner.reminder.ReminderList; +import seedu.financialplanner.utils.Ui; + +public class DeleteReminderCommand extends Command{ + private final int index; + + public DeleteReminderCommand(RawCommand rawCommand) throws IllegalArgumentException { + String stringIndex; + if(rawCommand.args.size() == 1) { + stringIndex = rawCommand.args.get(0); + } else { + throw new IllegalArgumentException("Incorrect arguments."); + } + + try{ + index = Integer.parseInt(stringIndex); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Index must be an integer"); + } + + if (index == 0) { + throw new IllegalArgumentException("Index must be within the list"); + } + + if( index > ReminderList.getInstance().list.size()+1){ + throw new IllegalArgumentException("Index exceed the list size"); + } + rawCommand.extraArgs.remove("i"); + if(!rawCommand.extraArgs.isEmpty()){ + String unknownExtraArgument = new java.util.ArrayList<>(rawCommand.extraArgs.keySet()).get(0); + throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); + } + } + + @Override + public void execute() { + ReminderList.getInstance().deleteReminder(index); + Ui.getInstance().showMessage("You have deleted "+ReminderList.getInstance().list.get(index-1)); + } +} diff --git a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java index 9aa2107a08..2e860e1c87 100644 --- a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java +++ b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java @@ -82,7 +82,7 @@ private String formatDoubleToString(double amount) { } private String getReminders() { - ReminderList reminderList = ReminderList.INSTANCE; + ReminderList reminderList = ReminderList.getInstance(); if (reminderList.list.isEmpty()) { return "No reminders added yet."; } diff --git a/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java b/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java new file mode 100644 index 0000000000..ad6343acbc --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java @@ -0,0 +1,16 @@ +package seedu.financialplanner.commands; +import seedu.financialplanner.reminder.ReminderList; +import seedu.financialplanner.utils.Ui; +public class ReminderListCommand extends Command{ + public ReminderListCommand(RawCommand rawCommand) throws IllegalArgumentException{ + + } + + @Override + public void execute() { + Ui ui = Ui.getInstance(); + ReminderList reminderList = ReminderList.getInstance(); + ui.showMessage("Here is your reminder list:"); + ui.showMessage(ReminderList.getInstance().list.toString()); + } +} diff --git a/src/main/java/seedu/financialplanner/reminder/Reminder.java b/src/main/java/seedu/financialplanner/reminder/Reminder.java index f8a827e642..01086009dd 100644 --- a/src/main/java/seedu/financialplanner/reminder/Reminder.java +++ b/src/main/java/seedu/financialplanner/reminder/Reminder.java @@ -12,7 +12,8 @@ public Reminder(String type, String date) { public String toString() { String status = isDone ? "Done" : "Not Done"; - return "Reminder: " + this.type + " | " + this.date + " | " + status; + return "Reminder " + System.lineSeparator() + " Type: " + type + System.lineSeparator() + + " Date: " + date + System.lineSeparator() + " Status: " + status; } public void markAsDone() { diff --git a/src/main/java/seedu/financialplanner/reminder/ReminderList.java b/src/main/java/seedu/financialplanner/reminder/ReminderList.java index 66abb1b0be..bbeb048103 100644 --- a/src/main/java/seedu/financialplanner/reminder/ReminderList.java +++ b/src/main/java/seedu/financialplanner/reminder/ReminderList.java @@ -2,13 +2,41 @@ import java.util.ArrayList; public class ReminderList { - public static final ReminderList INSTANCE = new ReminderList(); - public ArrayList list = new ArrayList<>(); + private static ReminderList reminderList = null; + public final ArrayList list = new ArrayList<>(); private ReminderList() { } + public static ReminderList getInstance() { + if (reminderList == null) { + reminderList = new ReminderList(); + } + return reminderList; + } public void load(Reminder reminder) { list.add(reminder); } - //TODO deleteReminder + public void deleteReminder(int index) { + int existingListSize = list.size(); + int listIndex = index - 1; + assert listIndex >= 0 && listIndex < existingListSize; + Reminder toRemove = list.get(listIndex); + list.remove(listIndex); + + } + public void markReminderAsDone(int index) { + int existingListSize = list.size(); + int listIndex = index - 1; + assert listIndex >= 0 && listIndex < existingListSize; + list.get(listIndex).markAsDone(); + } + + + public String toString() { + String result = ""; + for (int i = 0; i < list.size(); i++) { + result += String.format("%d. %s\n", i + 1, list.get(i)); + } + return result; + } } From f079eb6a95354f32284af0496b863daff8574570 Mon Sep 17 00:00:00 2001 From: hshiah Date: Tue, 31 Oct 2023 22:24:33 +0800 Subject: [PATCH 341/518] Set reminder as done and unmark the reminder. --- .../commands/DeleteReminderCommand.java | 2 +- .../commands/MarkReminderCommand.java | 39 +++++++++++++++++++ .../commands/UnmarkReminderCommand.java | 37 ++++++++++++++++++ .../financialplanner/reminder/Reminder.java | 4 +- .../reminder/ReminderList.java | 7 ---- 5 files changed, 80 insertions(+), 9 deletions(-) create mode 100644 src/main/java/seedu/financialplanner/commands/MarkReminderCommand.java create mode 100644 src/main/java/seedu/financialplanner/commands/UnmarkReminderCommand.java diff --git a/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java index bcf9d1e9a2..b65bee6168 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java @@ -13,7 +13,7 @@ public DeleteReminderCommand(RawCommand rawCommand) throws IllegalArgumentExcept throw new IllegalArgumentException("Incorrect arguments."); } - try{ + try { index = Integer.parseInt(stringIndex); } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Index must be an integer"); diff --git a/src/main/java/seedu/financialplanner/commands/MarkReminderCommand.java b/src/main/java/seedu/financialplanner/commands/MarkReminderCommand.java new file mode 100644 index 0000000000..a1e7def166 --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/MarkReminderCommand.java @@ -0,0 +1,39 @@ +package seedu.financialplanner.commands; +import seedu.financialplanner.reminder.ReminderList; +import seedu.financialplanner.utils.Ui; +public class MarkReminderCommand extends Command{ + private final int index; + public MarkReminderCommand(RawCommand rawCommand) throws IllegalArgumentException { + String stringIndex; + if(rawCommand.args.size() == 1) { + stringIndex = rawCommand.args.get(0); + } else { + throw new IllegalArgumentException("Incorrect arguments."); + } + + try { + index = Integer.parseInt(stringIndex); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Index must be an integer"); + } + if (index == 0) { + throw new IllegalArgumentException("Index must be within the list"); + } + if( index > ReminderList.getInstance().list.size()+1){ + throw new IllegalArgumentException("Index exceed the list size"); + } + rawCommand.extraArgs.remove("i"); + if(!rawCommand.extraArgs.isEmpty()){ + String unknownExtraArgument = new java.util.ArrayList<>(rawCommand.extraArgs.keySet()).get(0); + throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); + } + } + + @Override + public void execute() { + ReminderList.getInstance().list.get(index-1).markAsDone(); + Ui.getInstance().showMessage("You have marked "+ReminderList.getInstance().list.get(index-1)); + } + + +} diff --git a/src/main/java/seedu/financialplanner/commands/UnmarkReminderCommand.java b/src/main/java/seedu/financialplanner/commands/UnmarkReminderCommand.java new file mode 100644 index 0000000000..a2d925e4ce --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/UnmarkReminderCommand.java @@ -0,0 +1,37 @@ +package seedu.financialplanner.commands; +import seedu.financialplanner.reminder.ReminderList; +import seedu.financialplanner.utils.Ui; +public class UnmarkReminderCommand extends Command{ + private final int index; + public UnmarkReminderCommand(RawCommand rawCommand) throws IllegalArgumentException { + String stringIndex; + if(rawCommand.args.size() == 1) { + stringIndex = rawCommand.args.get(0); + } else { + throw new IllegalArgumentException("Incorrect arguments."); + } + + try { + index = Integer.parseInt(stringIndex); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Index must be an integer"); + } + if (index == 0) { + throw new IllegalArgumentException("Index must be within the list"); + } + if( index > ReminderList.getInstance().list.size()+1){ + throw new IllegalArgumentException("Index exceed the list size"); + } + rawCommand.extraArgs.remove("i"); + if(!rawCommand.extraArgs.isEmpty()){ + String unknownExtraArgument = new java.util.ArrayList<>(rawCommand.extraArgs.keySet()).get(0); + throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); + } + } + + @Override + public void execute() { + ReminderList.getInstance().list.get(index-1).unmark(); + Ui.getInstance().showMessage("You have unmarked "+ReminderList.getInstance().list.get(index-1)); + } +} diff --git a/src/main/java/seedu/financialplanner/reminder/Reminder.java b/src/main/java/seedu/financialplanner/reminder/Reminder.java index 01086009dd..1ac0388a04 100644 --- a/src/main/java/seedu/financialplanner/reminder/Reminder.java +++ b/src/main/java/seedu/financialplanner/reminder/Reminder.java @@ -19,7 +19,9 @@ public String toString() { public void markAsDone() { this.isDone = true; } - + public void unmark() { + this.isDone = false; + } /* * Returns a string that can be saved to a file. * Format: type | date | isDone diff --git a/src/main/java/seedu/financialplanner/reminder/ReminderList.java b/src/main/java/seedu/financialplanner/reminder/ReminderList.java index bbeb048103..e6d9b4d3f3 100644 --- a/src/main/java/seedu/financialplanner/reminder/ReminderList.java +++ b/src/main/java/seedu/financialplanner/reminder/ReminderList.java @@ -24,13 +24,6 @@ public void deleteReminder(int index) { list.remove(listIndex); } - public void markReminderAsDone(int index) { - int existingListSize = list.size(); - int listIndex = index - 1; - assert listIndex >= 0 && listIndex < existingListSize; - list.get(listIndex).markAsDone(); - } - public String toString() { String result = ""; From be00b218ca3950819a4704bbb187acd9c0f43636 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Tue, 31 Oct 2023 22:50:26 +0800 Subject: [PATCH 342/518] Update cashflow diagrams --- .../{ => cashflow}/AddCashflowSequence.puml | 15 ++++++++++++--- .../{ => cashflow}/CashflowClassDiagram.puml | 13 +++++++++++-- docs/images/AddCashflowSequence.png | Bin 40300 -> 0 bytes docs/images/CashflowClassDiagram.png | Bin 25368 -> 0 bytes docs/images/cashflow/AddCashflowSequence.png | Bin 0 -> 43896 bytes docs/images/cashflow/CashflowClassDiagram.png | Bin 0 -> 75612 bytes 6 files changed, 23 insertions(+), 5 deletions(-) rename docs/diagrams/{ => cashflow}/AddCashflowSequence.puml (78%) rename docs/diagrams/{ => cashflow}/CashflowClassDiagram.puml (90%) delete mode 100644 docs/images/AddCashflowSequence.png delete mode 100644 docs/images/CashflowClassDiagram.png create mode 100644 docs/images/cashflow/AddCashflowSequence.png create mode 100644 docs/images/cashflow/CashflowClassDiagram.png diff --git a/docs/diagrams/AddCashflowSequence.puml b/docs/diagrams/cashflow/AddCashflowSequence.puml similarity index 78% rename from docs/diagrams/AddCashflowSequence.puml rename to docs/diagrams/cashflow/AddCashflowSequence.puml index 47f89d6775..1b69eec33d 100644 --- a/docs/diagrams/AddCashflowSequence.puml +++ b/docs/diagrams/cashflow/AddCashflowSequence.puml @@ -1,29 +1,38 @@ @startuml participant ":AddCashflowCommand" as AddCashflowCommand -participant "CashflowList" as CashflowList +participant ":CashflowList" as CashflowList participant ":Income" as Income participant ":Expense" as Expense -participant "Ui" as Ui +participant ":Ui" as Ui -> AddCashflowCommand: execute() +activate AddCashflowCommand alt income AddCashflowCommand -> CashflowList: addIncome(amount, incomeType, recur, description) + activate CashflowList create Income CashflowList -> Income: Income(value, type, recur, description) + activate Income Income -> Income: addIncomeValue() + return CashflowList -> CashflowList: addToList(toAdd) CashflowList -> Ui: printAddedCashflow(toAdd) + return else expense AddCashflowCommand -> CashflowList: addExpense(amount, incomeType, recur, description) + activate CashflowList create Expense CashflowList -> Expense: Expense(value, type, recur, description) + activate Expense Expense -> Expense: addExpenseValue() + return CashflowList -> CashflowList: addToList(toAdd) CashflowList -> Ui: printAddedCashflow(toAdd) -else invalid command + return end +return hide footbox @enduml \ No newline at end of file diff --git a/docs/diagrams/CashflowClassDiagram.puml b/docs/diagrams/cashflow/CashflowClassDiagram.puml similarity index 90% rename from docs/diagrams/CashflowClassDiagram.puml rename to docs/diagrams/cashflow/CashflowClassDiagram.puml index c11060164d..f3f3fbf033 100644 --- a/docs/diagrams/CashflowClassDiagram.puml +++ b/docs/diagrams/cashflow/CashflowClassDiagram.puml @@ -41,11 +41,20 @@ Class AddCashflowCommand #HoneyDew { } enum "<>\nExpenseType" as ExpenseType #MintCream { - DINING, ENTERTAINMENT, SHOPPING, TRAVEL, INSURANCE, NECESSITIES, OTHERS + DINING + ENTERTAINMENT + SHOPPING + TRAVEL + INSURANCE + NECESSITIES + OTHERS } enum "<>\nIncomeType" as IncomeType #MintCream{ - SALARY, INVESTMENTS, ALLOWANCE, OTHERS + SALARY + INVESTMENTS + ALLOWANCE + OTHERS } CashflowList -right-> "1" Ui diff --git a/docs/images/AddCashflowSequence.png b/docs/images/AddCashflowSequence.png deleted file mode 100644 index 56a6148bbbadef1d5065273f84bed87a21e2aa0a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40300 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 ZsQez3n}m2RUPb&n*+WXwnUW^w{|`F@B`5#@ diff --git a/docs/images/CashflowClassDiagram.png b/docs/images/CashflowClassDiagram.png deleted file mode 100644 index 8a4ea7028dcb498b14e6116d8bb311feac24a715..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25368 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 Tu89Alf}pqGaNiTnqu2femfzb! diff --git a/docs/images/cashflow/AddCashflowSequence.png b/docs/images/cashflow/AddCashflowSequence.png new file mode 100644 index 0000000000000000000000000000000000000000..7d0c4997b3b75eda20d044dc370f5de9b7388f19 GIT binary patch literal 43896 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

Nf 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 JAgcfBe*p^6XNv#; literal 0 HcmV?d00001 From b5ba1de282b9c2a5191fd57f446583d93f397509 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Tue, 31 Oct 2023 22:50:49 +0800 Subject: [PATCH 343/518] Change method name for clarity --- .../seedu/financialplanner/storage/LoadData.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 66a12b5b9c..7cd9b5bafd 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -99,7 +99,7 @@ private static void addRecurringCashflows(LocalDate currentDate) throws Financia int recur = cashflow.getRecur(); LocalDate dateOfAddition = cashflow.getDate(); boolean hasRecurred = cashflow.getHasRecurred(); - addRecurringCashflowToTempList(currentDate, cashflow, recur, dateOfAddition, tempCashflowList, hasRecurred); + identifyRecurringCashflows(currentDate, cashflow, recur, dateOfAddition, tempCashflowList, hasRecurred); } for (Cashflow cashflow : tempCashflowList) { cashflowList.load(cashflow); @@ -107,16 +107,16 @@ private static void addRecurringCashflows(LocalDate currentDate) throws Financia } } - private static void addRecurringCashflowToTempList(LocalDate currentDate + private static void identifyRecurringCashflows(LocalDate currentDate , Cashflow cashflow, int recur, LocalDate dateOfAddition , ArrayList tempCashflowList, boolean hasRecurred) throws FinancialPlannerException { if (recur > 0 && !hasRecurred) { dateOfAddition = dateOfAddition.plusDays(recur); - identifyRecurredCashflows(currentDate, cashflow, recur, dateOfAddition, tempCashflowList); + addRecurringCashflowToTempList(currentDate, cashflow, recur, dateOfAddition, tempCashflowList); } } - private static void identifyRecurredCashflows(LocalDate currentDate + private static void addRecurringCashflowToTempList(LocalDate currentDate , Cashflow cashflow, int recur, LocalDate dateOfAddition , ArrayList tempCashflowList) throws FinancialPlannerException { while (currentDate.isAfter(dateOfAddition) || currentDate.isEqual(dateOfAddition)) { @@ -130,12 +130,16 @@ private static void identifyRecurredCashflows(LocalDate currentDate throw new FinancialPlannerException("Error adding recurring cashflows"); } toAdd.setDate(dateOfAddition); - tempCashflowList.add(toAdd); + addToTempList(tempCashflowList, toAdd); cashflow = toAdd; dateOfAddition = dateOfAddition.plusDays(recur); } } + private static void addToTempList(ArrayList tempCashflowList, Cashflow toAdd) { + tempCashflowList.add(toAdd); + } + private static void handleCorruptedFile(String message) throws FinancialPlannerException { ui.showMessage("File appears to be corrupted. Do you want to create a new file? (Y/N)"); if (createNewFile()) { From e7355e47d8a1a41484cfba5a93cb23752e7491a6 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Tue, 31 Oct 2023 22:51:21 +0800 Subject: [PATCH 344/518] Update DG with recur feature --- docs/DeveloperGuide.md | 62 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 3 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 20b2dd583b..1c7808d9bf 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -132,7 +132,7 @@ add income /a 100 /t salary /r 30 Below are the steps that shows the implementation of add income/expense. #### Step 1 -The AddCashflowCommand instance then calls addIncome() or addExpense(), depending on what `category` is initialised as. +The AddCashflowCommand instance calls addIncome() or addExpense(), depending on what `category` is initialised as. addIncome() or addExpense() instantiates an Income or Expense object respectively. @@ -159,11 +159,67 @@ The added income/expense is then displayed to the user through the Ui. #### Diagrams Given below is the class diagram showing the class structure of the add income/expense mechanism: -![](images/CashflowClassDiagram.png) +![](images/cashflow/CashflowClassDiagram.png) Given below is the sequence diagram showing the add income/expense mechanism: -![](images/AddCashflowSequence.png) +![](images/cashflow/AddCashflowSequence.png) +### Recurring Cashflow Feature +This feature is called from the user through the `/r` argument in add income/expense command. +If a cashflow is set to be recurring, the program would add another entry of the same cashflow to the Financial Planner after a set period of time. + +Below are the steps that shows the implementation of the recurring cashflow feature. + +#### Step 1 +Once the cashflow is set to be recurring, its corresponding `Cashflow` object would store the date at which the cashflow was added to the Financial Planner. + +The `recur` variable in the object would also be instantiated according to the user's input. + +An additional `boolean` variable, `hasRecurred` is stored in the object and is set to `false` by default. + +Example: +``` +public abstract class Cashflow { + protected int recur; + protected LocalDate date; + protected boolean hasRecurred; +} +``` +#### Step 2 +When the Financial Planner is started again in the future, the date of startup would be collected. + +After loading existing saved cashflows from data.txt, the program will check for cashflows that are set to be recurring and has not recurred. + +Example: +``` +if (recur > 0 && !hasRecurred) { + ... +} +``` + +#### Step 3 +Once a cashflow matches the above criteria, the date of its next addition to the Financial Planner, `dateOfAddition`, would be determined. + +`dateOfAddition` would be compared to the current date, and if the current date is after or equal to `dateOfAddition`, an identical cashflow would be instantiated. + +This identical cashflow would then have its `date` variable set to `dateOfAddition`, then this cashflow would be added to a temporary list, `tempCashflowList`. + +The original cashflow would then have its `hasRecurred` variable be set to `true`. + +#### Step 4 +Each cashflow in `tempCashflowList` goes through **Step 3** again, so that multiple cashflows can be added if it has recurred more than once. + +Once the process is done, all cashflows in `tempCashflowList` are then added to the Financial Planner. + +The added cashflows are then displayed to the user. + +#### Diagrams +Given below is the class diagram showing the class structure of the recurring cashflow mechanism: +![](images/cashflow/RecurClassDiagram.png) + +Given below is the sequence diagram showing the recurring cashflow mechanism: +![](images/cashflow/RecurSequence.png) +![](images/cashflow/AddRecurringSequence.png) ### Budget Feature From bedd062b6caa3ca7d421fc13e66a28684908dad6 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Tue, 31 Oct 2023 22:51:44 +0800 Subject: [PATCH 345/518] Add recur class and sequence diagrams --- .../cashflow/AddRecurringSequence.puml | 26 ++++++++++ docs/diagrams/cashflow/RecurClassDiagram.puml | 46 ++++++++++++++++++ docs/diagrams/cashflow/RecurSequence.puml | 31 ++++++++++++ docs/images/cashflow/AddRecurringSequence.png | Bin 0 -> 32996 bytes docs/images/cashflow/RecurClassDiagram.png | Bin 0 -> 54180 bytes docs/images/cashflow/RecurSequence.png | Bin 0 -> 38665 bytes 6 files changed, 103 insertions(+) create mode 100644 docs/diagrams/cashflow/AddRecurringSequence.puml create mode 100644 docs/diagrams/cashflow/RecurClassDiagram.puml create mode 100644 docs/diagrams/cashflow/RecurSequence.puml create mode 100644 docs/images/cashflow/AddRecurringSequence.png create mode 100644 docs/images/cashflow/RecurClassDiagram.png create mode 100644 docs/images/cashflow/RecurSequence.png diff --git a/docs/diagrams/cashflow/AddRecurringSequence.puml b/docs/diagrams/cashflow/AddRecurringSequence.puml new file mode 100644 index 0000000000..e6cde521c2 --- /dev/null +++ b/docs/diagrams/cashflow/AddRecurringSequence.puml @@ -0,0 +1,26 @@ +@startuml +mainframe sd add recurring cashflows to templist + +participant "<>\nLoadData" as LoadData +participant ":Income" as Income +participant ":Expense" as Expense + +loop current date is after or equals next recurring date + LoadData -> Cashflow: setHasRecurred(true) + +alt income + create Income + LoadData -> Income: Income((Income) cashflow) + LoadData -> Income: setDate(dateOfAddition) + LoadData -> LoadData: addToTempList(tempCashflowList, toAdd) + +else expense + create Expense + LoadData -> Expense: Expense((Expense) cashflow) + LoadData -> Expense: setDate(dateOfAddition) + LoadData -> LoadData: addToTempList(tempCashflowList, toAdd) +end + +end +hide footbox +@enduml \ No newline at end of file diff --git a/docs/diagrams/cashflow/RecurClassDiagram.puml b/docs/diagrams/cashflow/RecurClassDiagram.puml new file mode 100644 index 0000000000..9da06ba216 --- /dev/null +++ b/docs/diagrams/cashflow/RecurClassDiagram.puml @@ -0,0 +1,46 @@ +@startuml +'https://plantuml.com/class-diagram +skinparam classFontColor automatic + +Class "{abstract}\nLoadData" as LoadData #HoneyDew { + -addRecurringCashflows(currentDate: LocalDate) + -identifyRecurringCashflows(currentDate: LocalDate, cashflow: Cashflow, recur: int, dateOfAddition: LocalDate, tempCashflowList: ArrayList, hasRecurred: boolean) + -addRecurringCashflowToTempList(currentDate: LocalDate, cashflow: Cashflow, recur: int, dateOfAddition: LocalDate, tempCashflowList: ArrayList) + -addToTempList(tempCashflowList: ArrayList, toAdd: Cashflow) + +} + +Class "{abstract}\nCashflow" as Cashflow #MistyRose { + #recur: int + #date: LocalDate; + #hasRecurred: boolean; + +setHasRecurred(hasRecurred: boolean) + +setDate(date: LocalDate) +} + +Class Expense #MistyRose extends Cashflow{ + +Expense(expense: Expense) +} + +Class Income #MistyRose extends Cashflow{ + +Income(income: Income) +} + +Class Ui #Cornsilk { + +printAddedCashflow(entry: Cashflow) +} + +Class CashflowList #Cornsilk { + +load(entry: Cashflow) +} + +LoadData -up-> "1" CashflowList +LoadData -up-> "1" Ui +LoadData .up.> Income +LoadData .up.> Expense +LoadData .up.> Cashflow +CashflowList -up-> "*" Cashflow + +hide Circle +skinparam classAttributeIconSize 0 +@enduml \ No newline at end of file diff --git a/docs/diagrams/cashflow/RecurSequence.puml b/docs/diagrams/cashflow/RecurSequence.puml new file mode 100644 index 0000000000..c0fb71b6b0 --- /dev/null +++ b/docs/diagrams/cashflow/RecurSequence.puml @@ -0,0 +1,31 @@ +@startuml + +participant ":LoadData" as LoadData +participant ":Cashflow" as Cashflow +participant ":Income" as Income +participant ":Expense" as Expense +participant ":CashflowList" as CashflowList +participant ":Ui" as Ui + +LoadData -> LoadData: addRecurringCashflows(date); +activate LoadData +loop for each cashflow in cashflowList + LoadData -> LoadData: identifyRecurringCashflows(currentDate, cashflow, recur, dateOfAddition, tempCashflowList, hasRecurred) + activate LoadData +opt is Recurring and has not Recurred + LoadData -> LoadData: addRecurringCashflowToTempList(currentDate, cashflow, recur, dateOfAddition, tempCashflowList) + activate LoadData +ref over LoadData, Expense: add recurring cashflows to templist +return + +return +end + +end +loop for each cashflow in tempCashflowList + LoadData -> CashflowList: load(cashflow) + LoadData -> Ui: printAddedCashflow(cashflow) +end +return +hide footbox +@enduml \ No newline at end of file diff --git a/docs/images/cashflow/AddRecurringSequence.png b/docs/images/cashflow/AddRecurringSequence.png new file mode 100644 index 0000000000000000000000000000000000000000..5bc106550d818a6e42b81dfb3f36a18f2cd2df85 GIT binary patch literal 32996 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

rkx8c@an|KFufI@H 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 KhmyokT>d|n30x)s literal 0 HcmV?d00001 From 42571107e25ed4190fb36d16ef5f468558669058 Mon Sep 17 00:00:00 2001 From: hshiah Date: Tue, 31 Oct 2023 23:12:28 +0800 Subject: [PATCH 346/518] Solve suggestions of Minwei --- .../commands/DeleteReminderCommand.java | 16 ++++++++++++---- .../commands/MarkReminderCommand.java | 3 ++- .../java/seedu/financialplanner/goal/Goal.java | 8 +++++--- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java index b65bee6168..ecea2d4c4e 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java @@ -1,10 +1,13 @@ package seedu.financialplanner.commands; + import seedu.financialplanner.reminder.ReminderList; import seedu.financialplanner.utils.Ui; +import java.util.logging.Level; +import java.util.logging.Logger; public class DeleteReminderCommand extends Command{ + private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private final int index; - public DeleteReminderCommand(RawCommand rawCommand) throws IllegalArgumentException { String stringIndex; if(rawCommand.args.size() == 1) { @@ -14,21 +17,26 @@ public DeleteReminderCommand(RawCommand rawCommand) throws IllegalArgumentExcept } try { + logger.log(Level.INFO, "Parsing index as integer"); index = Integer.parseInt(stringIndex); } catch (IllegalArgumentException e) { + logger.log(Level.WARNING, "Invalid argument for index"); throw new IllegalArgumentException("Index must be an integer"); } if (index == 0) { + logger.log(Level.WARNING, "Invalid value for index"); throw new IllegalArgumentException("Index must be within the list"); } - if( index > ReminderList.getInstance().list.size()+1){ + if (index > ReminderList.getInstance().list.size() + 1) { + logger.log(Level.WARNING, "Invalid value for index"); throw new IllegalArgumentException("Index exceed the list size"); } rawCommand.extraArgs.remove("i"); - if(!rawCommand.extraArgs.isEmpty()){ + if (!rawCommand.extraArgs.isEmpty()) { String unknownExtraArgument = new java.util.ArrayList<>(rawCommand.extraArgs.keySet()).get(0); + logger.log(Level.WARNING, "Invalid extra arguments found"); throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); } } @@ -36,6 +44,6 @@ public DeleteReminderCommand(RawCommand rawCommand) throws IllegalArgumentExcept @Override public void execute() { ReminderList.getInstance().deleteReminder(index); - Ui.getInstance().showMessage("You have deleted "+ReminderList.getInstance().list.get(index-1)); + Ui.getInstance().showMessage("You have deleted " + ReminderList.getInstance().list.get(index-1)); } } diff --git a/src/main/java/seedu/financialplanner/commands/MarkReminderCommand.java b/src/main/java/seedu/financialplanner/commands/MarkReminderCommand.java index a1e7def166..e7c428df37 100644 --- a/src/main/java/seedu/financialplanner/commands/MarkReminderCommand.java +++ b/src/main/java/seedu/financialplanner/commands/MarkReminderCommand.java @@ -1,4 +1,5 @@ package seedu.financialplanner.commands; + import seedu.financialplanner.reminder.ReminderList; import seedu.financialplanner.utils.Ui; public class MarkReminderCommand extends Command{ @@ -19,7 +20,7 @@ public MarkReminderCommand(RawCommand rawCommand) throws IllegalArgumentExceptio if (index == 0) { throw new IllegalArgumentException("Index must be within the list"); } - if( index > ReminderList.getInstance().list.size()+1){ + if (index > ReminderList.getInstance().list.size()+1){ throw new IllegalArgumentException("Index exceed the list size"); } rawCommand.extraArgs.remove("i"); diff --git a/src/main/java/seedu/financialplanner/goal/Goal.java b/src/main/java/seedu/financialplanner/goal/Goal.java index d78c73f00a..fd819e3363 100644 --- a/src/main/java/seedu/financialplanner/goal/Goal.java +++ b/src/main/java/seedu/financialplanner/goal/Goal.java @@ -12,15 +12,17 @@ public Goal(String label, int amount) { public String toString() { String status = isDone ? "Done" : "Not Done"; - return "Goal: " + this.label + " | " + this.amount + " | " + status; + return "Goal " + System.lineSeparator()+ " Label: " + label + System.lineSeparator() + " Amount: " + + amount + System.lineSeparator() + " Status: "+status; } public void markAsDone() { - //TODO edit the expense to mark the goal as done this.isDone = true; } - //TODO delete the Reminder + public void unmark() { + this.isDone = false; + } public String formatString() { String status = isDone ? "Done" : "Not Done"; return this.label + " | " + this.amount + " | " + this.isDone; From 0aa5efad56469ee8dd46b90d8ddb1ad12641c290 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Tue, 31 Oct 2023 23:18:40 +0800 Subject: [PATCH 347/518] Update DG content page --- docs/DeveloperGuide.md | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index ed9e3282cb..e19127a4b5 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -9,12 +9,12 @@ * [Visualization Feature](#visualization-feature-) * [Class diagram](#class-diagram) * [Sequence diagram](#sequence-diagram-) - * [Add income/expense feature](#add-incomeexpense-feature) - * [Step 1](#step-1) - * [Step 2](#step-2) - * [Step 3](#step-3) - * [Step 4](#step-4) - * [Diagrams](#diagrams) + * [Add Income/Expense Feature](#add-incomeexpense-feature) + * [Class Diagram](#add-incomeexpense-class-diagram) + * [Sequence Diagram](#add-incomeexpense-sequence-diagram) + * [Recurring Cashflow Feature](#recurring-cashflow-feature) + * [Class Diagram](#recurring-cashflow-class-diagram) + * [Sequence Diagrams](#recurring-cashflow-sequence-diagrams) * [Budget Feature](#budget-feature) * [Set and update budget](#set-and-update-budget) * [Delete budget](#delete-budget) @@ -153,7 +153,7 @@ Visualizer ![](images/vis/visualizerSequence.png) -### Add income/expense feature +### Add Income/Expense Feature The add income/expense command has 2 compulsory arguments `/t` and `/a` and 1 optional argument `/r`. @@ -189,13 +189,15 @@ The income/expense object is also added to the list in Cashflowlist which contai #### Step 3 The added income/expense is then displayed to the user through the Ui. -#### Diagrams +#### Add Income/Expense Class Diagram Given below is the class diagram showing the class structure of the add income/expense mechanism: ![](images/cashflow/CashflowClassDiagram.png) - +#### Add Income/Expense Sequence Diagram Given below is the sequence diagram showing the add income/expense mechanism: ![](images/cashflow/AddCashflowSequence.png) ### Recurring Cashflow Feature +Cashflow refers to an income or expense. + This feature is called from the user through the `/r` argument in add income/expense command. If a cashflow is set to be recurring, the program would add another entry of the same cashflow to the Financial Planner after a set period of time. @@ -245,10 +247,10 @@ Once the process is done, all cashflows in `tempCashflowList` are then added to The added cashflows are then displayed to the user. -#### Diagrams +#### Recurring Cashflow Class Diagram Given below is the class diagram showing the class structure of the recurring cashflow mechanism: ![](images/cashflow/RecurClassDiagram.png) - +#### Recurring Cashflow Sequence Diagrams Given below is the sequence diagram showing the recurring cashflow mechanism: ![](images/cashflow/RecurSequence.png) ![](images/cashflow/AddRecurringSequence.png) From 8ef4691d972f4f593ad3edcddf721daf2e1c3118 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Tue, 31 Oct 2023 23:18:52 +0800 Subject: [PATCH 348/518] Update UG explaining the meaning of cashflow --- docs/UserGuide.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 86880d167d..1e5ae59135 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -62,6 +62,9 @@ you a one-stop interface to access a plethora of features to manage your finance e.g. `[/r DAYS]` can be used as `/r 30` or left empty. +### Notes about naming convention +- Cashflow refers to an income or expense. + ### Add cashflow #### Add income: `add income` From 425cf725b30b882d8bb634aafebf632a0ccd6971 Mon Sep 17 00:00:00 2001 From: hshiah Date: Wed, 1 Nov 2023 00:03:38 +0800 Subject: [PATCH 349/518] Solve minor errors. --- .../seedu/financialplanner/commands/ReminderListCommand.java | 2 +- .../financialplanner/commands/UnmarkReminderCommand.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java b/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java index ad6343acbc..8cdbf44385 100644 --- a/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java @@ -11,6 +11,6 @@ public void execute() { Ui ui = Ui.getInstance(); ReminderList reminderList = ReminderList.getInstance(); ui.showMessage("Here is your reminder list:"); - ui.showMessage(ReminderList.getInstance().list.toString()); + ui.showMessage(reminderList.list.toString()); } } diff --git a/src/main/java/seedu/financialplanner/commands/UnmarkReminderCommand.java b/src/main/java/seedu/financialplanner/commands/UnmarkReminderCommand.java index a2d925e4ce..5851790d61 100644 --- a/src/main/java/seedu/financialplanner/commands/UnmarkReminderCommand.java +++ b/src/main/java/seedu/financialplanner/commands/UnmarkReminderCommand.java @@ -5,7 +5,7 @@ public class UnmarkReminderCommand extends Command{ private final int index; public UnmarkReminderCommand(RawCommand rawCommand) throws IllegalArgumentException { String stringIndex; - if(rawCommand.args.size() == 1) { + if (rawCommand.args.size() == 1) { stringIndex = rawCommand.args.get(0); } else { throw new IllegalArgumentException("Incorrect arguments."); @@ -19,7 +19,7 @@ public UnmarkReminderCommand(RawCommand rawCommand) throws IllegalArgumentExcept if (index == 0) { throw new IllegalArgumentException("Index must be within the list"); } - if( index > ReminderList.getInstance().list.size()+1){ + if (index > ReminderList.getInstance().list.size()+1){ throw new IllegalArgumentException("Index exceed the list size"); } rawCommand.extraArgs.remove("i"); From 6ac95c68e5e6d9bb8c539b95c9f96f3b91a41922 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Wed, 1 Nov 2023 11:00:34 +0800 Subject: [PATCH 350/518] Add some fix to DG and UG --- docs/DeveloperGuide.md | 6 ++--- docs/UserGuide.md | 21 +++++++++++++----- docs/diagrams/vis/visualisationClass.puml | 7 +++--- docs/images/vis/radarOutput.png | Bin 0 -> 39774 bytes docs/images/vis/visualisationClass.png | Bin 35486 -> 39208 bytes .../visualisations/Visualizer.java | 4 ++-- 6 files changed, 24 insertions(+), 14 deletions(-) create mode 100644 docs/images/vis/radarOutput.png diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index ab120bad78..94b509e924 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -71,8 +71,8 @@ the data one upon exiting the program with the `exit` command. This feature is implemented with the help of [XChart](https://knowm.org/open-source/xchart/), a simple charting library for Java by Knowm. -By typing in the vis command with the appropriate arguments (/s and /t), users will be able to visualize their income or expense -using visualization tools (Piechart, Bar Chart) +By typing in the vis command with the appropriate arguments (`/s` and `/t`), users will be able to visualize their +income or expense using visualization tools (Piechart, Bar Chart or Radar Chart) Demo: @@ -104,7 +104,7 @@ specified cashflow entry according to type using a Hashmap which is returned and Visualizer's Role: -According to the chart type (Pie/Bar) argument and the Hashmap obtained from the categorizer passed in, +According to the chart type (Pie/Bar/Radar) argument and the Hashmap obtained from the categorizer passed in, the visualizer displays the specified visualization chart by calling the charting library Xchart. ### Class Diagram diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 86880d167d..637b6d5515 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -538,7 +538,7 @@ Use watchlist command to view updated Watchlist ### Visualizing your cashflow: `vis` -Using this command to visualize your income or expenses in a pie chart or bar chart +Using this command to visualize your income or expenses in a pie chart, bar chart or radar chart Format: `vis /t TYPE /c TOOL` @@ -547,10 +547,11 @@ Format: `vis /t TYPE /c TOOL` | Income Cashflows `Income` | | Expense Cashflows `Expense` | -| Tool `/c` | -|----------------| -| PieChart `pie` | -| BarChart `bar` | +| Tool `/c` | +|--------------------| +| PieChart `pie` | +| BarChart `bar` | +| RadarChart `radar` | Example of usage: `vis /t expense /c pie` @@ -562,7 +563,7 @@ Displaying piechart for expense ![](images/vis/visOutput.png) -Example of usage: `vis /t expense /c bar` +Example of usage: `vis /t income /c bar` ``` Displaying barchart for income @@ -570,6 +571,14 @@ Displaying barchart for income ![](images/vis/barOuput.png) +Example of usage: `vis /t income /c radar` + +``` +Displaying radarchart for income +``` + +![](images/vis/radarOutput.png) + ### Exiting the program: `exit` Exits the program. diff --git a/docs/diagrams/vis/visualisationClass.puml b/docs/diagrams/vis/visualisationClass.puml index 968e065e00..737d5d423b 100644 --- a/docs/diagrams/vis/visualisationClass.puml +++ b/docs/diagrams/vis/visualisationClass.puml @@ -27,9 +27,10 @@ class Categorizer #HoneyDew { } class Visualizer #Beige { -+displayChart(chart: String, cashFlowByCat: Map, type: String) -+ displayPieChart(cashFlowByCat: Map, type: String) -+ displayBarChart(cashFlowByCat: Map, type: String) ++displayChart(chart: String, cashflowByCat: HashMap, type: String) ++ displayPieChart(cashflowByCat: HashMap, type: String) ++ displayBarChart(cashflowByCat: HashMap, type: String) ++ displayRadarChart (cashflowByCat: HashMap, type: String) } "{abstract}\nCommand" <|-- VisCommand diff --git a/docs/images/vis/radarOutput.png b/docs/images/vis/radarOutput.png new file mode 100644 index 0000000000000000000000000000000000000000..95577b74d7f31d76db607bcb6ac9da82dfdaff79 GIT binary patch literal 39774 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 literal 35486 zcmb@tcRZYJ*ET8z5s@Ie=%WYGgF!?mdheol(Ty?^q7#hXqqiWU*NNy1qIVL#_g==n zB)RYVd7kgxd%y4d`}~t@O0MfX*SX4Z9BWOmqP!&5eUkeqC@5IcQew&|D0hJCTV?ld z1MkRnj;;a!Fgc5BIvd-+f!LUuIipCL+L=1Ob~ZJkG=flCI6J>_;%8%fWAob1*~Qj| z)!5$FwXd531?4uMrK+a$U+<&b0`B9UvK1?5KluVXVCRBa;-{kG8C`GlOPpp97oPUr z7!@{BPWGbl`q6EYH$#^vAHtitiZj(49n0O0y_Zw>!lpUntVsiJc~)2PaL8xjpz7w* zyD0c$vHfTtR`_$-(f|kL@&vUaK0K$GlpG-?As zHVw`TSTT63;zr-H8{(+nt5lj~?X;g*FuNkkw@n(OlHODAz0YsREIF~o`qJ`y0~HJF zoa~oV^|)@ft8mEY>M6;e#@jBm53oe$bIDlDy#*5rU*2z`Q5DXxDyO?LBfa0MYAAn3 zua&+5k5yv#Nvqh7(B3lf9q+<(-Z&cSTr=+xh3Je+2kHlpYk$Jl&1gh1C~XU;b$Z0* zf071sQWlLaBkxwLGymkKTYJEtI=0pze_bm-bm(^E!V!RFMHBO0y>Z6IZM|3>Qug8X z2b>Dlj0x9C4f(t~2S0BQy8Fil4zUyATR(b7QrR!^_CDzzR-o3?VyTXO%T;AB$UyAU3}fZ>ZJK~^>zgXa`)HO?i0$0Ul%B8 zcNTGef6eJF_$EvM&wdywiGmWNZn9(|m(0xqX7X}eG{L@$_4emb%fiDBY2kI+TQ_%< zVb1MOgEC*JAD7zz9|t5?*=xh0jfX=ePA|xBp(tvLz`2*^iYf2Kxk`wMNeOT9qu)F$ z2R~Ah(jqb}EGz~(>GJURohTz-e5b^?S=~p$|M|5Hlj_C@73hmf!3Xl&WWql1wS!#x895mr z81gD@hgr1{yOBqmoDp{tb@SU0gfA|yO!GW%Uwh`0sK_VwU@P3u>2c&C1Ru#(}+w%RDz^6ac z9|ZGQuU4z3+05HZiQC)T5d@X8GiWYtC-*Og4}T&JN|4_+w=Sv= zs6m}lqt7m6+GD%bm=97q`p6a_p#A)vA5D+*6ilkL!(k5$F>v?qp`g6*d_f-joaHGC zhfhz;1)m$)3^&;Mls;9sU|Bz0mO!a~d~#xW?&KWZ%*+g-@GTS%zg)#h8G@stq5>5N zdqA#mYfWJYqFok3WB%dp@WUTD!&WgSD6)|^o{TbiXFtDHi}^D_y>T0a{-kezd=f5Ijg&1eK)@=3-ATNSKIWgxL=a5J^JUSoV3hs2Xg&E zS~y*6UBKbW8prWJ=ilV73*B-#aW-i1a5x`26vYT^?I_D zQPF>Qghsko@(Rn>8E8!p-{0h<@8pq^Xs^cZmjL_E6_!)zl35d|*?DV^)@l4gl=dd4 zyghyk<}kFIgA3-{MJCoJszCC7ylcLMkAEF|_m>OYyNd<;-(CAH4up*39}?ab@%!0* z#QghwI!ts0Z;Ob6{(Agv5x@Tn*9l=RKqmYV}0o zeW^PZvye2KDwjc(xoFuOFHrT4$`@r{bTo}mx&w%5gm9Hv@nA-R z+~sU!-kgu_jIP|PSJQ$s9j{0Zeng<##0T(LY=1(=Mip$U< zmu?!GaJkLNSzd>=z8y5xoWjNS@DZ6jJfRoSn^a|yevrudgNHfgvGk6{z~+zs6^ zj4i_`P9drD-bzm*Wz?ATnw%2DPBHiJx{^fdnKX)@#>GZnEEOvk>3zdlkO)f!s~_4- z)fYpv&JjGHMHI7%RCMVRv|WZLfP&!_4JuH9&=d4G^PEYFBFt2ueN!t`!;wsIFd3IZ zmkbPvWtLzG!?m^_ulbp_;CY(+rwHu5+z)E{Vi}TY&|bt-;&|e0F5mskbUCIT;uaij z_G*2!h?H$A$CEILg>|})QXwZH-7K_MfcKymGH@VtHLpUjytN_c#AKQ!&FgOX3{$hg zV-F$DX$h-$-I=^JJ?Jt+{)jX@$LT+a6w|D5R5~AWPP%<|ca36^qLvbd3wTjLK;WQQ z-(`q*HX0WsuWOAtuS>rig4Om$xYU0t>^Ir zl~pl}FzWkM|3zma4X*j9ffmAD4((kB-WW!%1j!c05Z!mfZZ~NO>AftG_Nm@Ep;+gT zhmp^}sUEF(3&E2hv5PjnZ7ICA)6)Cqc1+B38}0)*eVdki+1D+>|_gSK7C+ zg09;M+Dzgr-B`?XXJZ0h(RB95Jqh1D{}M}WFWRo?;k{QiKYiw1TvqD{+2 zol)z5wk27;1m(kW$98|^kZNcJc3(H-KCz;squZ&3*tcI2*MHcauLosipAJycAiWx< z6?#vX*4YrVO+NJr>x$o~Dle@61ilhEG2^?-vMJ-P-Qpzyqv?Bli7L>ccMmu@InzK_ zmURg#Wz-JQApqtv=IrQe5xBa%a@UkmzhBPj(^K)K%BZS1wRrrcKKEIh!S3QpF}`&9 z*zWhAT+%}^?K+v`lKVl#?$3C|bR1sftJpXm75)_0D^e`DJwdKdzG)PeAZe2E>y*9? z`bxaoUhyLPb3pHasF#87E$IEKT(^nE^fyn?-X$ zVVW$_v4={SS?=Sh(*lTGh_4x@*$@|SrA{s zS;%-V>ZS2w3uTYz{x!N;<&H;hUyo(Hr98jWR#>B-ApEx2Yk`POljF0P1Fx4kwdp*x z#9uJCzv;q#Qtdr1JPx`dh9=q)1?f`sc2#Q{XpJaF&NH8{6kv5;P&CXf%n6Q@0 zIK+UGt&r#8>*jrZY_CDb?eZt3R zYvIn2e&n}~wsiraU=#9~UsWU3$Ptz^Ag`aUj$?DG^Q>djZ%jzx8ViZ2XF680omEab z7)ArxSS17pV|bGD8L7W7D=Tw9dWm4`FBoTPql$g@3vVeDvhoQg4u2g?$a(nT;bmgN zm z9+iKenrJx~_NISNkSjQjMJMj+5ss74<-zOD&)7NwIs%^c$9j_o>9w#Ok0e6CyMQtv zmNy@EI+T&#sqnapNP_cyXb~nmkS5`HVrq}b`4W~ryQkM%)Z>ScP1rA;q}^4Yv&lQD z)j!-qAodBx7b9$jO5fNE+dE-8t>e(HuqbV2O*YV;*B0|of@B!Xu7j^kh74$a^6Aph z2JzwR&^~00h~fMj?kSl70pjy~_s*QDp&un$XiRIvB}T3$=3XcO^HYVj_4V>pdAnWiF;D9I=5ri@BLPiw_N~knHTA0_}djF2bOT|`Q`-u_o3C_P-&gYA^QuK5%w<%T@l!~h~rZ%R@E)s z+!eY?RlPksxqlVs2zOQ8a6!Z+I4*Ugj$jR9tKb#JsvU5KNXq;xNCNvb_5xnpWgPOd zvVFCmvH}1=WNwhKw8y_m(dsMm;PR;DMCo*5P5Q{v`m23aQgj&VP3$yEXt4Zu@ek)c z=hn5F9^=D5Y2?NsU$JbWHzp=(0ldwvb<0pb>1)7$Fj4(Dqu(^t2J|8=uDn;$mIql8 zHDL`mxUeg7)7t$vgwv)0{qV1B_ws5NPuR0-lWC+dhEXLzt_)E+?p_HBX|9jhvfEX^ zqaUd~SShK2DT|q&B;Mj_r!(@`cK=Y_Nl{NO`B7yduECLVt|e5D7Ngsq@(F z@B>U<>siN1Z;EXoGzsut{VIU>T1E`rfEDQ+9%CgF#hH(u*Y$4nClA+1k9k<{A0Hp( zCPpX^3=@H$C7=R%#eF$55rCSdGxa<^6JB2+`_;*CZ>BX>08m)-lro<5*URFQmd1&( zKYtENXq1hO0)5Mj4INC+jrO4NZ%sjpAfqs;3krTScCILEDJePIefj7i4f$vm9yNzg zcpbG1d1Ud$IudA=&Ew+<-1d8gZF<5xO#c-8>hzN+PDzkF$s04GSxPZP$j2-;h0Okc z5XqC&C(_tbMi#k?J1^ld2Y)zrNH@8F+bj0iDBN+@q)WP2$uBta-QL)fH&}MinHjul zlp0}AhHlJtH?=uAzB2+fEXCMzh?ebHN#ps^x{XRz1e-1)PPzTetj(C|va4u8^g+qE zq80cZd{(dVJn6w0{^}G}Mx{wRdpqO@nJd!!LBn7=s~oW;orF24v(9$>&@;53ir+Gn z-F&cqJ2*o(4GnFiu&d`&;-*S3$uLq8c$L=Yf&xZ3y?8)kBC*0Z1C2f&d|M1g7HI+j zPl2RM_c#9uGr(o~_ZKiAdLiK&vY7-aNzvV$D$nL<9mfXrKsy$&5+L(9Z7t$(?i$(! zRn0$-Mlpr;6$Oj|s0C1XUQ`9fqt_GBEaPZd6fKH_Dn3_Wqif0EA-y};>@43My~_DJ zUj$}?=VKIDxbSWN149sp<{~&uyBXrtQnnVe&(;izua~yhpxg&ckD8)A11E^#W(hh8 zoXO5G2KaOCVP^XVZQQmWUrc-U({TR*6It#3TKwkrm$R+O!AaH{)`jz$j31l;X96k^ zMi<7b$KU6!=#T5wPcO{kCZEF<{{=>nWi6HUB-*SZ*cqqTqu>lPmSpy+U9@*hE=)V1;4!DamI#vs-BbT$AOg>Z zPo0zbypJ0WJFWPX4o^4II-jBNp-Stu-A@eOGg@!+z}gTzUAPsszbje3FRP+Z6jqoH4Vfc0p}seID8=y$3Saq&C8YKSl=7j!r*3@-wLk1axPTc;_+VHS$J+PhFcazTp<*)z=?{zN&NO147a#}MW$9)H zgc^iKyI&2V%>nCVV8>^@-7!@ofyJzOSKhV0IrEFjR^b}2GKr?$-puXhze!6pTXiLy zOiWy23+beo03@cCss5?yZz&-v<=kT>qpAb_wv`TaN-x#JHU3v|mgsDA z%<*33nIuexL~$cc2z z9K|^gE?vHA*y_?oFy0>_$rASaKHo^-JiWw@_Ln}u2?6!#Cz*5TaeS7i^r7hNQ7JY6 zVKz;j&j1RcRS@I-N@krHWjDv2)3Xb?bY8(VJLU7}!<`c^gA8T=)yjeW&X)!1smKSn z$sG8%_lfTOrFT4y0IA^AqZpc*saK2405WhwG+o2bj268a-TzW|z#f9J|4WTcN2Kpr zOZ=7+ysXZ5)e5;)D=e0%CFv#e_T>RSjG0VgW^PY!Mgx>;*lk^1J+yEl=j)RTMD4}+ zHkv*65B88)IuLz@-PmMtW^!<_G*&vvMpdyfv@OGMX0Pxkt*d15PRLAwY7VaFnD?ds zCE-lD+4mAa+zmCQUHtFVVk(@!-Nj#)e8aY435>T7zP>eQI0} zfN=0RiOpyGeS6SC`u;`=I9!r`5d4Ru`7cIgMblv1lYY?q2_%rZvgx&H%lJt0 z81}eTE|_XEWF}afXypG?0uZ5T^#34(f206o?1!{ZI8OiHdHuOdpRb&p+}Rcr2Lgd` zhaKjv8OhhmNi5qZIttVNJmce5ZM`x%uqFp57pJo9puQsn`B=#_^_OZgIsgS0poK#q zz1~KW{(|Rtf7MtcHz`Gqqh+-g>y@9W_)Kb)Q!PDydSN&RK~F1g?5C}%9fbb!ca3#D zcHIXBi2V`X7$Tl8so==zk@`%Ie|BgoMfdIn10uXvKo(=wt3-|vQ+#vDN+LjWK7LTz znW>s>p`)b}{4%`UX5tI@b(KsG06G9*_fIJ`f}SbnyGWL)h0IXduKZYyj7<5;b?a)z z#|Uoi54Sh#dKCC?oV*|4{5{6;oWE*S4gjZ&r2c|aOc6wnXrIj2-?l;zI*~l}Q7n>+ z&MYQa0EDce@*3uP3w*{&u9I{HKDJyVK;~79+HM=rE-)>AE^8k|vowU7Dd5@`Rk<3s7q^16vi#<9ZW*m3IDE zH&`nv(LX#I7yE`s8_fRV(T)N)JbF!A*hjeS3t+H4!ubi^d>+fa-hs!GrIR&GSC;31 z*Z@GR#Bv5;p?^rUG)18xAg1)6|EZK6%6^Ys?B#6vHwGx`MBv_ED_3pbf_okR@NB6d(U~=daQ`$ zA44WBMZNd@u#+)S1{~UEx?jQp(0~vP@CO<^lM_>wJA-M0w5cq~?H1q4E56*IF}DJ_ z94@V@jqiPkr#{{zrqhh)>dV5Ssc4|Ozlfz|2N zwf=lADPnj2?7=z~aLX7)1oH7kS1w%Q+t7xD47L+fm5jsU(yNBV@eFHpAW7m)0B%R| z@bar0@i-;+T8&C0f=Bfqw1U>2D(N~}U?91Tj+IuqF)~XE*VyI-{rSR}7C8=pCl;As z_?BX<1)&c=jJ&`K`<)fCR`;bmgzum{xV^73^Xwm9`U3l@_}@(qpe>rhZXEDW2bCRi zZqkI{y5}3vyjZcABO5RCPZt&aA%!N~yYX@Zp9{Qw&3Aph2vBNe?ZKb{8tBCq?^>ST z%1uZ2BcAcXa<~djo^L?!-s29965T{(x7$0kc5zvPs~w-~XlS48?O$trt55UvDPm+K z7AfO~@|F2_WB4QdbgO!9dS*tNe89lFX61GR-S0l}AtAH+r+n1{+%B4P*(zsVlm?QU zt}hD8dFb1>C}Tb^{`EbNkUQuPRST5c4k#k!$Stu^8gBpovPX#9oOe7Zs=C@Oo>gy^ zZDKJB?bcUjl$!`Ru-D zR1%(svA?SI?qz19*JBiY)Zd-)#+F!SjaE4&a>3{=)VD^zI@c&4cOrrR=sxnt0%TE9 zQOblU4Kly?f`S4@|8-wLx%i)S+ELy%-MJorv`X~*6q@ezyu8i-XNNn$qnsc7UhUj1 z$lZUww14kA`|qWC1B?4;{Kxn}KmA3=U+X*Vfd2L3ueLs5R+Ro*H$@ou`@#3$Sh+Vk zvW()NXT|y7{ogMrQu6HwU>CrnR|R$>uKs#~g7V)ONVr+>|FQD(hnL2}|7`v#CdU8F zLjSrTz?x(LtOOqO-3V7pW0iA469r`@uXoB#djjN= zGY|Gle1X9U*4f63o~IKUw2M*O*nHkFuiJN;HM%d$<>?c6Y+;wO=yydvt4208gXS!O zTLKZA@A;Da9pya&na(WO-Tyl;yED79Hd8i<%QJH&Ao1}Inecm1}eT_cy z^|gMN_F!{>b$Pl_Zb}2)GsHmHT(vdBWkWL7P4cQ9h$GtHiaAO zJ843tVCu-qhLv6tAKs%#BI4^2I0*@lKjvAY6z8ADmesFW&?^b-^qR ze6DK2r?ePqcL@loBJhZa8TDi?@tc99v~X3S;_AwSkQahi>rKVsGuI>}#2oA$k5^e@ z@D-_+yjf{y=U~135*?Bbu8ZAF?g}haFOX`lVZTEch=ucbd#0>T$&b?P`V7S9?Cis< zVeaHqPS8uL#JHRXX3okJ;G2whbJVQ%I3Dh5+1#@2iDj;LY00EUW8jI!*ZpGXSXmeg z^#5quqX|G%tLw^XA)mBxXek1fMLKB|I~rWKG<%a~BPa}hl7G3n@@CZsC(z$Za@iml z?C3=xD)bxQ&eV^w=ZS6a_LiHUKzBuY?xRx7l5m50Y&5Ac3pCzuVq~h{WAf5hMBK z#9a(g>Cwo8Ayx|53#x@FaTNeTn@fJ6^&I&^obGn<{(-PTDJOlEtRwR1@IEJX-iIVU z?^m-eV)J1^QH?@7otML5cInWVSZER#ws#J6piyw7hR^kucMAdgi?V`Gh6lM=Fx(SG z($-TxrHscf(Urk#g(yB0XU}8q1CC#39zjmVYp2`ITWu4(JzYyy9*)G}IuxPtKU`H( zeueOQ6j2Ckg!R5fnbRt#Gclvf%}d9?Bwb%$e~J-_hvGoMnvc0e9}_&#tYdhSgXaml?x9ZbbR z(3krCq{z-BvgT~pk04c`it1ucP(YmR17*v%Zz<^Ht@LuaLgyKq{b(*rSCLN zR9Lp0o^BzQ`P&BuplgF`Fkh>Esl}GSGYWm_w;;!_Z}orvq)E^#)&DwE58u^mYO>#_ zrkB5Dh`Vh7Xhe+I`%;|YY3OUQWm)G}$E&!Ho_oBxgF!d=Vta&{6yGAqDG&N-?Szh) zd)8UFLAXj;T;oe4xJa+|bHoE#S*NlZV3vvwE-Y`vLu_W2i^xSxEAYT4TdkhTeC5o^ z{en^^IIY03?Nb|{c(rTin~;YGFu$ibRdzGftag~hfsgF3#^6bg@Bv|dv!UD^lZ&$v zB5td%S(4X2EwZnu?Y5_?UoUnd$@nV@^ml*8-VKTZwcWmRbt=cDqeDt_>oE3PXeR{~ zx`EDLJ3&UFjD$OEi#YtdxR* ze<^cub->m!Rut@H_Gr%8)wRy!h^Sm4wflNkX1mBK0fI^@e5)R+4t@( zua$%OUC-Z77ob*l-T~qOS1ZzEOKOA(zf^y^pGQ!zutcByjO*g%w>{hWgB}(7N1W`8 z9pv3<+{R&LWqaRhACH%OIvle1P@|_0jz~dpvNLBsA=~^wKK=EWHBDIBi)#uVSKUAy zQkAJvF_OfzMmd*lxQ@!bATih+aCC?Eb&h|eq@grBomo?I@<9^!ffzj@?d)t?kw$-S zmvl(Do@$A%*0M>zwJ_AnzhXdOhikc+oLns{iv~D`7utpD#Wx2*%4s(pbiJJXV|v=8 zteww^PCj8*PNKb5r&>P1AIo<3l0{kz8^J6Asc_UoklHs;orEHU&rIaGlai9UQ?(Tl zDkZvnR(W6vz@)t~J-(?^8eHD>v*`-3t`Aeyef?uS-@c{Xl?>aR+X11+QZkMj9-z>iCYF@okgUkhBr3a#>-QD&MQtYU?3k*cMhr2 zR-q-s`%ll$fqTi3(c=fv>I=TQeb109k zwr>6Li5i1G!QF!pC33ZV&7U^=;6j9aR|J)RR?8IIKzlipAF?7EJH z6sT(EfWlQOay8>{p|yA&dgUv(FHm2@WjU%UiVTD=LnpJ6b8>R*<=`#!5j_Xk1y*Jj zl>hofng}VPSfHz9k9HTePx~3~frGk7-__^c;1WAKgaS!hsd_JGe7~^!xy9>4To?yJ zVKNABFiSYC-6rg4_wYwEm})|=-bVr>+D>mQ(r37)Ojd(6YZ0?a@6~p(cTI(0u&yKGfyYl{m#+8ZGHVJ(2b*ffBP3$k|Y-|)!!4TugWx^8xW-t?QmY5 zF01o&VO8wxbU%DM5rK5?-f^;>Y>L&>B;mGudIovcFLCUb7jeJW-ps5$G}N@Mw~E61 zbgOU)Mub5X@!}5MBGAt?%y>!;F)=cNz4`fcPM4^$wPnZ{IVg_45TRSAwY!6Y3gtMB zP2Rj-($dn}qo(gmojo7&A?1b^U4O(TN1VujK4?Q_5-wIsjj|gyCl*8fkqS@#-SFyd z(6R04h|}Ei(4G+iMudRO)G*B`funHH!l4{_ zm(R4{59S=!rKn4E;u~&YSk{&0fwgYX;2^#|#+)Wyr#RDCH_i4Rp%z!H)kQ%%r~^zA zxDI^DafJVyNt3}GfEe)(4bb6%$G*gXWWV?qult2t{x$}{DF7t*x8uAAEB}hI;T-U{ zI!SlNdn4T7U9y`>2-Ii_=+q6x(I; z>EP|huLdd@wuk%UulUlLL!`00J?v7;9y}k6^n%1#C1Cz z{^0@H!uqnAo!#uGHi39MeN$)>PJD^(^6KKEYSU%63wv~Kz|_Q4JkTI;-N>azOOb0j z1;P}cN&VT)aQ8yv>nQ^LH?uH*wIVeZmE16*^n;6Np=N`+nmXkuQ)~4&YDkP1)V{uo zg<1U#J3Hgb!d98>5bkmwYwMQI%KYZ=Cu#3x3{ukhRYQ$h*c4C=YnI2qKwsB7n)V`I zkq%>ibk|qcS5ms%w~@FF%6Yi0HPv8w$1FKHSr8i8={6(Br$5^zqCdTQCcl?r@>J_t zt@elvYGCE&C|0ODQ=7g@qpCo}Enwc}m%p=j(ohJ`opR=Z`T)Ogf57zIWjV|fGSSM& znR~o?gnBT%0eO1Xqxgy`-muQ~qdo|H`feXD#38VYe4hlez3& z>DF#niiD-Jn=g-JEHI=ws}-a8WDU|p`2OMnFD9w!4_=+V&j83CLP2j8xhA;?cR6}y z%c_Grkf*VNn4*`GM?JlGlkvjHm#dcoA`K9~lf!(bel}RV@&U71biC2GAW+}CnK^bK zK*uU}e-5KcXJ^-Bs{jMb@1=u1kscnVPMf!_&<=`@lGbx3sbGu$9Qo6yPdUg1BQJ=h z!83L7?VHKO)kUhs-)xfFS#=fY7Jio2n$YLX{yy&(&*`+88O9$Q3Ogm-HifUQyVIycqH5y%zY;zHp zV=`8#Wjvj5>(bJKTV~OJx->!VskrO-I5q@r9>6OR9k%z=pB);o%(3bmhbInoFc1(5 z(7GO1OU5rkEA>O42=j;yTzddx`hP-n|IvdQ_l1zvu1@b7regs!ovHCRv7&`JfIyGn z!5t3HEMCRi@*j`|g9Vq_^qij|J9CoH4syVn(|Ait%L`AX6FOnBk`lKQ=sg_X1DPNP zvt{9teN&=W&_!*tg|&6B|FYPaB@v`5TVV( zort4@BN$;k*NftEFBQ?!^a6u!kJP`)s|b1c12Rr08E96QlbhSL zDhf7_V++7~0CDUlo96Yc81O`*hbFshjMYb_b#GpE%!6K2%c_%it<7&b1AN{rUAR$H zj-AU2+xco=#H?dWhkio#)$=B~?HEOt7u$s8T_@e*$^f1#F%E(}dMrKB87iw>pw`Sg z;(_%#TLKVb=F5z)V+9Pz48GLGKYiE)K3d0K6*YFA4ls(81VT^W-a{@KUwZx~^!5|f z9)9?6@qygPbA?r(QYcAp2u^Six-Rw$3kK#%9 zyd}f-<1cXOl;;+s0Gp2V&;T7|N^xo-@25%+0ECSec-YM6@U!}a6yhP{`=C3x&CTh4H(AhVhyCoeDNz1{HO#C|u+)M&uL#ipm5 zyqD^Cc%lLw2<%-#UMUD4jA+d0VXD&{?B?^^P5+RLfZb<7!mvE?RjpxBxLkyc_uFhn zN7Z-WbC;VFjr-4{Ncxz$t)AaaK_Z3bpaP=vVIMwZGc7i=wPbSTYUVFE0p0fMwP=Qu z75q>zwSFC>Qe~`9eyK-CTbsw~aR6Vqu>A{#AC74MG2WOpWH!f#qbJL==i%i&JKj?9L-)}tii-e;sT@FZ+A}L6jaJ1nX*vZ#Y?qf-csZMx zW#f+vl{!{H-e{I6OUQbA8%TYpqTh8G5WQTBt2 zTZ@Zd=V{v@X6(sIBA7+UauQ;DDhEUYFj}o#0GryJI4g>hUXN8QyRe#36~MylkP#j6 zB9u;vqPeKA;~%o%vL0O>%n@Duq+9!Kq^P4)N~-gk*L;*|QY}YD9HPzdV`KBFQm7Qq zv%4dGBxe+7KQQ2761Vm3lc%~w>_%e3efrBkBANk;hI7(Si@ikh+^W2_|pbc(UMm|$;HWGvLU+DTLg5xGIX zKK#LvI(csb4!`T>i*vJVHs^B|R_GkNU(=?ARrXvAJNtnkxNyG_pvGK*N+L;%=SLfi zjQH3;WTVlyatuaZzZSJ50MUEr*iBXWYRGZQRNHNJ?e6V`M8xY4KrT=3_unW?PAkVz zjjp!Hc^#5M!#%xvs2DOkyTvAYWpnBT^E?>AYk96)=X~ymPH5r#b4Y<*Jx^kNXR)h= zF~TceQv)3RNNe3)d(x8MzNJNS(b7}D z;7C<;fsZi&t=4r*dsTt0R{aP!fPMU7^ zc7K=UQ2X~4C1s6w2Ip!R5LNA^0i+(g%f>MEn%->JYs2fbd8hAah_Ui9Hqpjd$wT~p zXz2?6WfcK@CqYE`g(Yq*{TcFN2_Y{p^m48krcAv?Xp6jU3DFq)lsJ~zHZ`rFa_{2I z;`QsaC-M)Pg?lv5>keMj@~<=A>RpQvo6_Vr=+#miD<;mt`2YD$Hv1DWi_x7~L@ChYItLFpBc zVrZ7Axor47GB9T7o8ivKg-1#(RH+Zcek=~h}7KYL#H^i znswBkfF=Ct&LYKTfA7ZaiN`wSxxAqj6gf-llr}gJNlt1Qj_P$H`_c#VuVTGLE zcCpM)+Tq~l{^{n``LR7xWCbm`v$0`%?LmR&K&*{Izt!e#e72qva&hr+djF0PYX|+M zg2Njh(n0`!EBewSn%!ZZHzUIjWIFQOFqpp$vo3LaeAg=XL%+1Ly{l`LSM=jw!rjMP z<*iFNd8b&hCk^0k#49}bj{5^|M*Eq%PfA(*R~IMqo9@n!LJ>eTn&noAxwGiG}Vj! zL)d{bda3yxkpzEk@NV1T&1V5mSGLCzhrFzIp~=bnwru=*a<97CbwUqhit|WF`n!zs zW6H}PANf9{s1IrHv63n|ZC1(}Cu$Qaqy?pd))NSG9`;F-@ScN1a)6NpKn(|2C6J6p zib>xrNPx>vcINVrz2i0Bu)tsY5Pe8(8dZnM@b9MCs zq2sFLF(UCb!Ymt-139P$@zEw*spYq=;7?P@$O*RbHZ}^L4QCRu*;y&2lBA|QX_d6t znUT%b64TcOwhb5Y`-n;Ski+w2`*Nfc`1K5aed(y2e3vEVHozv@@1mUpvgoN#M77mX zAEAM>QT51Vwf#)VjAu3)$dq`kVX6Pn!r@O6fxNmpe+Sgfv+DyVc)(%^#S`w3aA161 z`z0)(f>9w~VkSM>`EX)r4)>Sne2>d;y%-$w;X?|SC6PDj;Ev6CNxaY800_`fbaVu9kYTo;=w+9eQLn*I=b4HD6p@jEn2~C9wv`aDfkPm+N1OqPMjo@*Wha_wF4O zWoTZS7OK#M6ZKBt1a%8^se7O+IF+>AsJ3mX!DN9 z-vNd=G4YL;`%*zdNxeG+0}~cT${z${Xy(GTO%=RAm&ci3;Vskq-y~RMUYQOQYZDn3L zZM@V#0gB@rpJ@;xBy`pjprjRo2Pbgb>b}O29zr`=#GlSv9WG$GN&>Qo{cwI?U+UbR z-XDWm)|qa2M#;?$%A!}k26B)10S0Zc(ja^`RDG}tfQCxcrn&Dv*LZED3 z_@m5>8tw4;cc9_#7BSme+ia z`AHEiukzWCAXD*>@Gg~gz`00fGerH?MCID1Dl8qgCg6k1qr-fD%S%J#Z9S|klk6|rxue6;W*YNwS3+rB6>b-g=&t z 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 Zh=yqjy0A!r7yJp45|e-VMdZzg{|7CGCVT(@ diff --git a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java index 971e29ca97..682dbc0e8e 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java @@ -89,7 +89,7 @@ public static void displayBarChart (HashMap cashflowByCat, Strin keys.add(set.getKey()); values.add(set.getValue()); } - chart.addSeries("Expense", keys, values); + chart.addSeries(StringUtils.capitalize(type), keys, values); logger.log(Level.INFO, "Displaying Bar Chart"); JFrame swHR = new SwingWrapper<>(chart).displayChart(); @@ -112,7 +112,7 @@ public static void displayRadarChart (HashMap cashflowByCat, Str radarChart.getStyler().setSeriesColors(sliceColors); - String[] keys = new String[0]; + String[] keys; switch (type) { case "income": keys = IncomeType.getNames(IncomeType.class); From f2077fcbe8bc0213368d25eaf9fd3ecffe55457b Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Wed, 1 Nov 2023 20:08:12 +0800 Subject: [PATCH 351/518] Update DG --- docs/DeveloperGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index e19127a4b5..9685c90032 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -220,7 +220,7 @@ public abstract class Cashflow { } ``` #### Step 2 -When the Financial Planner is started again in the future, the date of startup would be collected. +When the Financial Planner is started again in the future, the date of startup would be obtained from the system. After loading existing saved cashflows from data.txt, the program will check for cashflows that are set to be recurring and has not recurred. From 53cc8caf53e9729ffb2d4f3b0606033a68974d3b Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Wed, 1 Nov 2023 20:08:50 +0800 Subject: [PATCH 352/518] Fix typo to be in camelCase --- .../java/seedu/financialplanner/commands/VisCommand.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/VisCommand.java b/src/main/java/seedu/financialplanner/commands/VisCommand.java index 9144b2c8fc..d02c1dfab0 100644 --- a/src/main/java/seedu/financialplanner/commands/VisCommand.java +++ b/src/main/java/seedu/financialplanner/commands/VisCommand.java @@ -42,12 +42,12 @@ public void execute() throws FinancialPlannerException { assert !chart.isEmpty(); assert !type.isEmpty(); - HashMap cashflowbyType = Categorizer.sortType(CashflowList.getInstance(), type); - if (cashflowbyType.isEmpty()) { + HashMap cashflowByType = Categorizer.sortType(CashflowList.getInstance(), type); + if (cashflowByType.isEmpty()) { ui.printEmptyCashFlow(type); return; } ui.printDisplayChart(type, chart); - Visualizer.displayChart(chart, cashflowbyType, type); + Visualizer.displayChart(chart, cashflowByType, type); } } From c9b08fc67025a01ca04125c77fcffd5553d4f849 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Wed, 1 Nov 2023 20:59:10 +0800 Subject: [PATCH 353/518] FIx formatting error in UG --- docs/UserGuide.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 1e5ae59135..e55232ef9c 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -255,9 +255,9 @@ You have removed an Expense Description: groceries from the Financial Planner. Balance: -830.00 -- Note: Balance displayed above is just an example. Your actual balance may differ. - ``` + +- Note: Balance displayed above is just an example. Your actual balance may differ. ### List #### List all: `list` From d90ccc549b1c618eeb27f21155978291dc4ca2ba Mon Sep 17 00:00:00 2001 From: hshiah Date: Wed, 1 Nov 2023 22:08:27 +0800 Subject: [PATCH 354/518] Finish all user stories for v2.0 --- .../commands/DeleteGoalCommand.java | 50 +++++++++++++++++++ .../commands/DeleteReminderCommand.java | 10 ++-- ...inderCommand.java => MarkGoalCommand.java} | 20 +++++--- .../commands/ReminderListCommand.java | 3 +- .../commands/SetGoalCommand.java | 13 ++--- .../commands/WishListCommand.java | 17 +++++++ .../enumerations/ExpenseType.java | 2 +- .../seedu/financialplanner/goal/Goal.java | 13 +++-- .../seedu/financialplanner/goal/GoalList.java | 14 ------ .../seedu/financialplanner/goal/WishList.java | 35 +++++++++++++ .../reminder/ReminderList.java | 3 +- .../seedu/financialplanner/utils/Parser.java | 24 +++++++++ 12 files changed, 163 insertions(+), 41 deletions(-) create mode 100644 src/main/java/seedu/financialplanner/commands/DeleteGoalCommand.java rename src/main/java/seedu/financialplanner/commands/{UnmarkReminderCommand.java => MarkGoalCommand.java} (59%) create mode 100644 src/main/java/seedu/financialplanner/commands/WishListCommand.java delete mode 100644 src/main/java/seedu/financialplanner/goal/GoalList.java create mode 100644 src/main/java/seedu/financialplanner/goal/WishList.java diff --git a/src/main/java/seedu/financialplanner/commands/DeleteGoalCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteGoalCommand.java new file mode 100644 index 0000000000..fe9615ea1a --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/DeleteGoalCommand.java @@ -0,0 +1,50 @@ +package seedu.financialplanner.commands; + +import seedu.financialplanner.goal.WishList; +import seedu.financialplanner.utils.Ui; +import java.util.logging.Level; +import java.util.logging.Logger; +import seedu.financialplanner.goal.Goal; +public class DeleteGoalCommand extends Command { + private static final Logger logger = Logger.getLogger("Financial Planner Logger"); + private final int index; + public DeleteGoalCommand(RawCommand rawCommand) throws IllegalArgumentException { + String stringIndex; + if (rawCommand.args.size() == 1){ + stringIndex = rawCommand.args.get(0); + } else { + throw new IllegalArgumentException("Incorrect arguments."); + } + + try { + logger.log(Level.INFO, "Parsing index as integer"); + index = Integer.parseInt(stringIndex); + } catch (IllegalArgumentException e) { + logger.log(Level.WARNING, "Invalid argument for index"); + throw new IllegalArgumentException("Index must be an integer"); + } + + if (index <= 0) { + logger.log(Level.WARNING, "Invalid value for index"); + throw new IllegalArgumentException("Index must be within the list"); + } + + if (index > WishList.getInstance().list.size() + 1) { + logger.log(Level.WARNING, "Invalid value for index"); + throw new IllegalArgumentException("Index exceed the list size"); + } + rawCommand.extraArgs.remove("i"); + if (!rawCommand.extraArgs.isEmpty()) { + String unknownExtraArgument = new java.util.ArrayList<>(rawCommand.extraArgs.keySet()).get(0); + logger.log(Level.WARNING, "Invalid extra arguments found"); + throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); + } + } + + @Override + public void execute() { + Goal goalToDelete = WishList.getInstance().list.get(index-1); + WishList.getInstance().deleteGoal(index-1); + Ui.getInstance().showMessage("You have deleted " + goalToDelete); + } +} diff --git a/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java index ecea2d4c4e..5466124ff9 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java @@ -4,7 +4,7 @@ import seedu.financialplanner.utils.Ui; import java.util.logging.Level; import java.util.logging.Logger; - +import seedu.financialplanner.reminder.Reminder; public class DeleteReminderCommand extends Command{ private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private final int index; @@ -24,7 +24,7 @@ public DeleteReminderCommand(RawCommand rawCommand) throws IllegalArgumentExcept throw new IllegalArgumentException("Index must be an integer"); } - if (index == 0) { + if (index <= 0) { logger.log(Level.WARNING, "Invalid value for index"); throw new IllegalArgumentException("Index must be within the list"); } @@ -33,7 +33,6 @@ public DeleteReminderCommand(RawCommand rawCommand) throws IllegalArgumentExcept logger.log(Level.WARNING, "Invalid value for index"); throw new IllegalArgumentException("Index exceed the list size"); } - rawCommand.extraArgs.remove("i"); if (!rawCommand.extraArgs.isEmpty()) { String unknownExtraArgument = new java.util.ArrayList<>(rawCommand.extraArgs.keySet()).get(0); logger.log(Level.WARNING, "Invalid extra arguments found"); @@ -43,7 +42,8 @@ public DeleteReminderCommand(RawCommand rawCommand) throws IllegalArgumentExcept @Override public void execute() { - ReminderList.getInstance().deleteReminder(index); - Ui.getInstance().showMessage("You have deleted " + ReminderList.getInstance().list.get(index-1)); + Reminder reminderToDelete = ReminderList.getInstance().list.get(index-1); + ReminderList.getInstance().deleteReminder(index-1); + Ui.getInstance().showMessage("You have deleted " + reminderToDelete); } } diff --git a/src/main/java/seedu/financialplanner/commands/UnmarkReminderCommand.java b/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java similarity index 59% rename from src/main/java/seedu/financialplanner/commands/UnmarkReminderCommand.java rename to src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java index 5851790d61..f005708712 100644 --- a/src/main/java/seedu/financialplanner/commands/UnmarkReminderCommand.java +++ b/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java @@ -1,11 +1,15 @@ package seedu.financialplanner.commands; -import seedu.financialplanner.reminder.ReminderList; + +import seedu.financialplanner.goal.WishList; import seedu.financialplanner.utils.Ui; -public class UnmarkReminderCommand extends Command{ +import seedu.financialplanner.cashflow.CashflowList; +import seedu.financialplanner.goal.Goal; +import seedu.financialplanner.enumerations.ExpenseType; +public class MarkGoalCommand extends Command { private final int index; - public UnmarkReminderCommand(RawCommand rawCommand) throws IllegalArgumentException { + public MarkGoalCommand(RawCommand rawCommand) throws IllegalArgumentException { String stringIndex; - if (rawCommand.args.size() == 1) { + if(rawCommand.args.size() == 1) { stringIndex = rawCommand.args.get(0); } else { throw new IllegalArgumentException("Incorrect arguments."); @@ -19,7 +23,7 @@ public UnmarkReminderCommand(RawCommand rawCommand) throws IllegalArgumentExcept if (index == 0) { throw new IllegalArgumentException("Index must be within the list"); } - if (index > ReminderList.getInstance().list.size()+1){ + if (index > WishList.getInstance().list.size()+1){ throw new IllegalArgumentException("Index exceed the list size"); } rawCommand.extraArgs.remove("i"); @@ -31,7 +35,9 @@ public UnmarkReminderCommand(RawCommand rawCommand) throws IllegalArgumentExcept @Override public void execute() { - ReminderList.getInstance().list.get(index-1).unmark(); - Ui.getInstance().showMessage("You have unmarked "+ReminderList.getInstance().list.get(index-1)); + Goal goal = WishList.getInstance().list.get(index-1); + goal.markAsDone(); + Ui.getInstance().showMessage("You have achieved " + goal + System.lineSeparator() +"Congratulations!"); + CashflowList.getInstance().addExpense(goal.getAmount(), ExpenseType.GOAL, 0, goal.getLabel()); } } diff --git a/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java b/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java index 8cdbf44385..dbcbd67d23 100644 --- a/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java @@ -1,4 +1,5 @@ package seedu.financialplanner.commands; + import seedu.financialplanner.reminder.ReminderList; import seedu.financialplanner.utils.Ui; public class ReminderListCommand extends Command{ @@ -11,6 +12,6 @@ public void execute() { Ui ui = Ui.getInstance(); ReminderList reminderList = ReminderList.getInstance(); ui.showMessage("Here is your reminder list:"); - ui.showMessage(reminderList.list.toString()); + ui.showMessage(reminderList.toString()); } } diff --git a/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java b/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java index 57db61b5c8..d7456f3ceb 100644 --- a/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java +++ b/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java @@ -1,11 +1,11 @@ package seedu.financialplanner.commands; import seedu.financialplanner.goal.Goal; -import seedu.financialplanner.goal.GoalList; +import seedu.financialplanner.goal.WishList; import seedu.financialplanner.utils.Ui; public class SetGoalCommand extends Command { - private final String goal; - private int amount; + private final String label; + private final int amount; public SetGoalCommand(RawCommand rawCommand) throws IllegalArgumentException { String labelString = String.join(" ", rawCommand.args); @@ -21,7 +21,7 @@ public SetGoalCommand(RawCommand rawCommand) throws IllegalArgumentException { if(!rawCommand.extraArgs.containsKey("l")){ throw new IllegalArgumentException("Please specify the content of the goal"); } - goal = rawCommand.extraArgs.get("l"); + label = rawCommand.extraArgs.get("l"); rawCommand.extraArgs.remove("l"); if(!rawCommand.extraArgs.isEmpty()){ String unknownExtraArgument = new java.util.ArrayList<>(rawCommand.extraArgs.keySet()).get(0); @@ -31,7 +31,8 @@ public SetGoalCommand(RawCommand rawCommand) throws IllegalArgumentException { @Override public void execute() { - GoalList.INSTANCE.list.add(new Goal(goal, amount)); - Ui.getInstance().showMessage("Set Goal Successfully!"); + Goal goal = new Goal(label, amount); + WishList.getInstance().list.add(goal); + Ui.getInstance().showMessage("You have added " + goal); } } diff --git a/src/main/java/seedu/financialplanner/commands/WishListCommand.java b/src/main/java/seedu/financialplanner/commands/WishListCommand.java new file mode 100644 index 0000000000..883e484aa0 --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/WishListCommand.java @@ -0,0 +1,17 @@ +package seedu.financialplanner.commands; + +import seedu.financialplanner.goal.WishList; +import seedu.financialplanner.utils.Ui; +public class WishListCommand extends Command { + public WishListCommand(RawCommand rawCommand) throws IllegalArgumentException{ + + } + + @Override + public void execute() { + Ui ui = Ui.getInstance(); + WishList wishList = WishList.getInstance(); + ui.showMessage("Here is your wish list:"); + ui.showMessage(wishList.toString()); + } +} diff --git a/src/main/java/seedu/financialplanner/enumerations/ExpenseType.java b/src/main/java/seedu/financialplanner/enumerations/ExpenseType.java index ab9f512fa9..e614a49fca 100644 --- a/src/main/java/seedu/financialplanner/enumerations/ExpenseType.java +++ b/src/main/java/seedu/financialplanner/enumerations/ExpenseType.java @@ -3,7 +3,7 @@ import java.util.Arrays; public enum ExpenseType { - DINING, ENTERTAINMENT, SHOPPING, TRAVEL, INSURANCE, NECESSITIES, OTHERS; + DINING, ENTERTAINMENT, SHOPPING, TRAVEL, INSURANCE, NECESSITIES, OTHERS, GOAL; public static String[] getNames(Class> e) { return Arrays.stream(e.getEnumConstants()).map(Enum::name).toArray(String[]::new); diff --git a/src/main/java/seedu/financialplanner/goal/Goal.java b/src/main/java/seedu/financialplanner/goal/Goal.java index fd819e3363..e3541a933e 100644 --- a/src/main/java/seedu/financialplanner/goal/Goal.java +++ b/src/main/java/seedu/financialplanner/goal/Goal.java @@ -1,8 +1,8 @@ package seedu.financialplanner.goal; public class Goal { - private String label; - private int amount; + private final String label; + private final int amount; private boolean isDone = false; public Goal(String label, int amount) { @@ -11,7 +11,7 @@ public Goal(String label, int amount) { } public String toString() { - String status = isDone ? "Done" : "Not Done"; + String status = isDone ? "Achieved" : "Not Achieved"; return "Goal " + System.lineSeparator()+ " Label: " + label + System.lineSeparator() + " Amount: " + amount + System.lineSeparator() + " Status: "+status; } @@ -20,8 +20,11 @@ public void markAsDone() { this.isDone = true; } - public void unmark() { - this.isDone = false; + public String getLabel() { + return this.label; + } + public int getAmount() { + return this.amount; } public String formatString() { String status = isDone ? "Done" : "Not Done"; diff --git a/src/main/java/seedu/financialplanner/goal/GoalList.java b/src/main/java/seedu/financialplanner/goal/GoalList.java deleted file mode 100644 index c741688742..0000000000 --- a/src/main/java/seedu/financialplanner/goal/GoalList.java +++ /dev/null @@ -1,14 +0,0 @@ -package seedu.financialplanner.goal; -import java.util.ArrayList; -public class GoalList { - public static final GoalList INSTANCE = new GoalList(); - public ArrayList list = new ArrayList<>(); - - private GoalList() { - } - - public void load(Goal goal) { - list.add(goal); - } - //TODO deleteGoal -} diff --git a/src/main/java/seedu/financialplanner/goal/WishList.java b/src/main/java/seedu/financialplanner/goal/WishList.java new file mode 100644 index 0000000000..f00083f66b --- /dev/null +++ b/src/main/java/seedu/financialplanner/goal/WishList.java @@ -0,0 +1,35 @@ +package seedu.financialplanner.goal; + +import java.util.ArrayList; +public class WishList { + private static WishList wishList = null; + public final ArrayList list = new ArrayList<>(); + private WishList() { + } + + public static WishList getInstance() { + if (wishList == null) { + wishList = new WishList(); + } + return wishList; + } + + public void load(Goal goal) { + list.add(goal); + } + + public void deleteGoal(int index) { + int existingListSize = list.size(); + int listIndex = index; + assert listIndex >= 0 && listIndex < existingListSize; + Goal toRemove = list.get(listIndex); + list.remove(listIndex); + } + public String toString() { + String result = ""; + for (int i = 0; i < list.size(); i++) { + result += String.format("%d. %s\n", i + 1, list.get(i)); + } + return result; + } +} diff --git a/src/main/java/seedu/financialplanner/reminder/ReminderList.java b/src/main/java/seedu/financialplanner/reminder/ReminderList.java index e6d9b4d3f3..d863011c52 100644 --- a/src/main/java/seedu/financialplanner/reminder/ReminderList.java +++ b/src/main/java/seedu/financialplanner/reminder/ReminderList.java @@ -18,11 +18,10 @@ public void load(Reminder reminder) { } public void deleteReminder(int index) { int existingListSize = list.size(); - int listIndex = index - 1; + int listIndex = index; assert listIndex >= 0 && listIndex < existingListSize; Reminder toRemove = list.get(listIndex); list.remove(listIndex); - } public String toString() { diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index e403cf70e1..24dda0484d 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -17,6 +17,12 @@ import seedu.financialplanner.commands.SetGoalCommand; import seedu.financialplanner.commands.BalanceCommand; import seedu.financialplanner.commands.DeleteStockCommand; +import seedu.financialplanner.commands.MarkGoalCommand; +import seedu.financialplanner.commands.MarkReminderCommand; +import seedu.financialplanner.commands.DeleteGoalCommand; +import seedu.financialplanner.commands.DeleteReminderCommand; +import seedu.financialplanner.commands.ReminderListCommand; +import seedu.financialplanner.commands.WishListCommand; import seedu.financialplanner.exceptions.FinancialPlannerException; import java.util.ArrayList; @@ -41,6 +47,12 @@ public class Parser { private static final String LIST_COMMAND = "list"; private static final String SET_GOAL_COMMAND = "set"; private static final String BALANCE_COMMAND = "balance"; + private static final String MARK_GOAL_COMMAND = "markgoal"; + private static final String MARK_REMINDER_COMMAND = "markreminder"; + private static final String DELETE_GOAL_COMMAND = "deletegoal"; + private static final String DELETE_REMINDER_COMMAND = "deletereminder"; + private static final String REMINDER_LIST_COMMAND = "reminderlist"; + private static final String WISH_LIST_COMMAND = "wishlist"; public static Command parseCommand(String input) throws FinancialPlannerException { RawCommand rawCommand = parseRawCommand(input); @@ -77,6 +89,18 @@ public static Command parseCommand(RawCommand rawCommand) throws FinancialPlanne return new SetGoalCommand(rawCommand); case BALANCE_COMMAND: return new BalanceCommand(rawCommand); + case MARK_GOAL_COMMAND: + return new MarkGoalCommand(rawCommand); + case MARK_REMINDER_COMMAND: + return new MarkReminderCommand(rawCommand); + case DELETE_GOAL_COMMAND: + return new DeleteGoalCommand(rawCommand); + case DELETE_REMINDER_COMMAND: + return new DeleteReminderCommand(rawCommand); + case REMINDER_LIST_COMMAND: + return new ReminderListCommand(rawCommand); + case WISH_LIST_COMMAND: + return new WishListCommand(rawCommand); default: return new InvalidCommand(); } From 2ecb578bea3216838de3e927fedde68016d069a0 Mon Sep 17 00:00:00 2001 From: YFshadaow Date: Wed, 1 Nov 2023 22:11:24 +0800 Subject: [PATCH 355/518] Add help command --- .../commands/HelpCommand.java | 159 ++++++++++++++++++ .../commands/InvalidCommand.java | 2 +- .../seedu/financialplanner/utils/Parser.java | 33 ++-- .../java/seedu/financialplanner/utils/Ui.java | 8 +- 4 files changed, 183 insertions(+), 19 deletions(-) create mode 100644 src/main/java/seedu/financialplanner/commands/HelpCommand.java diff --git a/src/main/java/seedu/financialplanner/commands/HelpCommand.java b/src/main/java/seedu/financialplanner/commands/HelpCommand.java new file mode 100644 index 0000000000..4b5b910b0e --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/HelpCommand.java @@ -0,0 +1,159 @@ +package seedu.financialplanner.commands; + +import seedu.financialplanner.utils.Ui; + +import java.util.ArrayList; + +import static seedu.financialplanner.utils.Parser.ADD_CASHFLOW_COMMAND; +import static seedu.financialplanner.utils.Parser.ADD_REMINDER_COMMAND; +import static seedu.financialplanner.utils.Parser.ADD_STOCK_COMMAND; +import static seedu.financialplanner.utils.Parser.BALANCE_COMMAND; +import static seedu.financialplanner.utils.Parser.BUDGET_COMMAND; +import static seedu.financialplanner.utils.Parser.DELETE_CASHFLOW_COMMAND; +import static seedu.financialplanner.utils.Parser.DELETE_STOCK_COMMAND; +import static seedu.financialplanner.utils.Parser.EXIT_COMMAND; +import static seedu.financialplanner.utils.Parser.FIND_COMMAND; +import static seedu.financialplanner.utils.Parser.HELP_COMMAND; +import static seedu.financialplanner.utils.Parser.LIST_COMMAND; +import static seedu.financialplanner.utils.Parser.OVERVIEW_COMMAND; +import static seedu.financialplanner.utils.Parser.SET_GOAL_COMMAND; +import static seedu.financialplanner.utils.Parser.VISUALIZATION_COMMAND; +import static seedu.financialplanner.utils.Parser.WATCHLIST_COMMAND; + +public class HelpCommand extends Command { + private static final String EXIT_COMMAND_USAGE = + "exit"; + private static final String WATCHLIST_COMMAND_USAGE = + "watchlist"; + private static final String ADD_CASHFLOW_COMMAND_USAGE = + "add [/t TYPE] [/r RECURRENCE INTERVAL IN DAYS] [/d DESCRIPTION]"; + + private static final String DELETE_CASHFLOW_COMMAND_USAGE = + "delete [income/expense] "; + + private static final String ADD_STOCK_COMMAND_USAGE = + "addstock "; + + private static final String DELETE_STOCK_COMMAND_USAGE = + "deletestock "; + + private static final String FIND_COMMAND_USAGE = + "find "; + + private static final String BUDGET_COMMAND_USAGE = + "budget set " + + "\n " + "budget update " + + "\n " + "budget delete" + + "\n " + "budget reset" + + "\n " + "budget view"; + private static final String VISUALIZATION_COMMAND_USAGE = + "vis "; + + private static final String OVERVIEW_COMMAND_USAGE = + "overview"; + private static final String ADD_REMINDER_COMMAND_USAGE = + "addreminder "; + + private static final String LIST_COMMAND_USAGE = + "list [income/expense]"; + + private static final String SET_GOAL_COMMAND_USAGE = + "set "; + + private static final String BALANCE_COMMAND_USAGE = + "balance"; + + private static final String HELP_COMMAND_USAGE = + "help [COMMAND]"; + + private static final String HELP_MESSAGE_GENERAL = + "<> denotes required arguments, [] denotes optional arguments" + + "\n" + "Here are the available commands:" + + "\n " + EXIT_COMMAND_USAGE + + "\n " + WATCHLIST_COMMAND_USAGE + + "\n " + ADD_CASHFLOW_COMMAND_USAGE + + "\n " + DELETE_CASHFLOW_COMMAND_USAGE + + "\n " + ADD_STOCK_COMMAND_USAGE + + "\n " + DELETE_STOCK_COMMAND_USAGE + + "\n " + FIND_COMMAND_USAGE + + "\n " + BUDGET_COMMAND_USAGE + + "\n " + VISUALIZATION_COMMAND_USAGE + + "\n " + OVERVIEW_COMMAND_USAGE + + "\n " + ADD_REMINDER_COMMAND_USAGE + + "\n " + LIST_COMMAND_USAGE + + "\n " + SET_GOAL_COMMAND_USAGE + + "\n " + BALANCE_COMMAND_USAGE + + "\n " + HELP_COMMAND_USAGE; + private final String commandName; + + public HelpCommand(RawCommand rawCommand) { + if (!rawCommand.extraArgs.isEmpty()) { + String unknownExtraArgument = new ArrayList<>(rawCommand.extraArgs.keySet()).get(0); + throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); + } + if (rawCommand.args.isEmpty()) { + commandName = null; + } else if (rawCommand.args.size() == 1) { + commandName = rawCommand.args.get(0); + } else { + throw new IllegalArgumentException("Unknown arguments, type help for help"); + } + } + + @Override + public void execute() throws Exception { + if (commandName == null) { + Ui.getInstance().showMessage(HELP_MESSAGE_GENERAL); + return; + } + switch (commandName) { + case EXIT_COMMAND: + Ui.getInstance().showMessage("Usage:\n " + EXIT_COMMAND_USAGE); + break; + case WATCHLIST_COMMAND: + Ui.getInstance().showMessage("Usage:\n " + WATCHLIST_COMMAND_USAGE); + break; + case ADD_CASHFLOW_COMMAND: + Ui.getInstance().showMessage("Usage:\n " + ADD_CASHFLOW_COMMAND_USAGE); + break; + case DELETE_CASHFLOW_COMMAND: + Ui.getInstance().showMessage("Usage:\n " + DELETE_CASHFLOW_COMMAND_USAGE); + break; + case ADD_STOCK_COMMAND: + Ui.getInstance().showMessage("Usage:\n " + ADD_STOCK_COMMAND_USAGE); + break; + case DELETE_STOCK_COMMAND: + Ui.getInstance().showMessage("Usage:\n " + DELETE_STOCK_COMMAND_USAGE); + break; + case FIND_COMMAND: + Ui.getInstance().showMessage("Usage:\n " + FIND_COMMAND_USAGE); + break; + case BUDGET_COMMAND: + Ui.getInstance().showMessage("Usage:\n " + BUDGET_COMMAND_USAGE); + break; + case VISUALIZATION_COMMAND: + Ui.getInstance().showMessage("Usage:\n " + VISUALIZATION_COMMAND_USAGE); + break; + case OVERVIEW_COMMAND: + Ui.getInstance().showMessage("Usage:\n " + OVERVIEW_COMMAND_USAGE); + break; + case ADD_REMINDER_COMMAND: + Ui.getInstance().showMessage("Usage:\n " + ADD_REMINDER_COMMAND_USAGE); + break; + case LIST_COMMAND: + Ui.getInstance().showMessage("Usage:\n " + LIST_COMMAND_USAGE); + break; + case SET_GOAL_COMMAND: + Ui.getInstance().showMessage("Usage:\n " + SET_GOAL_COMMAND_USAGE); + break; + case BALANCE_COMMAND: + Ui.getInstance().showMessage("Usage:\n " + BALANCE_COMMAND_USAGE); + break; + case HELP_COMMAND: + Ui.getInstance().showMessage("Usage:\n " + HELP_COMMAND_USAGE); + break; + default: + Ui.getInstance().showMessage("Unknown command, type help for help"); + } + } +} diff --git a/src/main/java/seedu/financialplanner/commands/InvalidCommand.java b/src/main/java/seedu/financialplanner/commands/InvalidCommand.java index 68860c4c1a..d560dbc741 100644 --- a/src/main/java/seedu/financialplanner/commands/InvalidCommand.java +++ b/src/main/java/seedu/financialplanner/commands/InvalidCommand.java @@ -15,6 +15,6 @@ public InvalidCommand() { */ @Override public void execute() { - Ui.getInstance().showMessage("Unknown command. Please try again."); + Ui.getInstance().showMessage("Unknown command. Type help for help"); } } diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index e403cf70e1..e3fe94f921 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -2,6 +2,7 @@ import seedu.financialplanner.commands.Command; import seedu.financialplanner.commands.AddStockCommand; +import seedu.financialplanner.commands.HelpCommand; import seedu.financialplanner.commands.OverviewCommand; import seedu.financialplanner.commands.AddCashflowCommand; import seedu.financialplanner.commands.DeleteCashflowCommand; @@ -27,20 +28,22 @@ import java.util.Map; public class Parser { - private static final String EXIT_COMMAND = "exit"; - private static final String WATCHLIST_COMMAND = "watchlist"; - private static final String ADD_CASHFLOW_COMMAND = "add"; - private static final String DELETE_CASHFLOW_COMMAND = "delete"; - private static final String ADD_STOCK_COMMAND = "addstock"; - private static final String DELETE_STOCK_COMMAND = "deletestock"; - private static final String FIND_COMMAND = "find"; - private static final String OVERVIEW_COMMAND = "overview"; - private static final String BUDGET_COMMAND = "budget"; - private static final String VISUALIZATION_COMMAND = "vis"; - private static final String ADD_REMINDER_COMMAND = "addreminder"; - private static final String LIST_COMMAND = "list"; - private static final String SET_GOAL_COMMAND = "set"; - private static final String BALANCE_COMMAND = "balance"; + public static final String EXIT_COMMAND = "exit"; + public static final String WATCHLIST_COMMAND = "watchlist"; + public static final String ADD_CASHFLOW_COMMAND = "add"; + public static final String DELETE_CASHFLOW_COMMAND = "delete"; + public static final String ADD_STOCK_COMMAND = "addstock"; + public static final String DELETE_STOCK_COMMAND = "deletestock"; + public static final String FIND_COMMAND = "find"; + public static final String OVERVIEW_COMMAND = "overview"; + public static final String BUDGET_COMMAND = "budget"; + public static final String VISUALIZATION_COMMAND = "vis"; + public static final String ADD_REMINDER_COMMAND = "addreminder"; + public static final String LIST_COMMAND = "list"; + public static final String SET_GOAL_COMMAND = "set"; + public static final String BALANCE_COMMAND = "balance"; + + public static final String HELP_COMMAND = "help"; public static Command parseCommand(String input) throws FinancialPlannerException { RawCommand rawCommand = parseRawCommand(input); @@ -77,6 +80,8 @@ public static Command parseCommand(RawCommand rawCommand) throws FinancialPlanne return new SetGoalCommand(rawCommand); case BALANCE_COMMAND: return new BalanceCommand(rawCommand); + case HELP_COMMAND: + return new HelpCommand(rawCommand); default: return new InvalidCommand(); } diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 4c40dd97df..57c9435f8b 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -22,7 +22,7 @@ public class Ui { private static final String GREEN = "\u001B[32m"; private static final String RESET = "\u001B[0m"; private static final String YELLOW = "\u001B[33m"; - private Scanner Scanner = new Scanner(System.in); + private Scanner scanner = new Scanner(System.in); private Ui() { } @@ -38,11 +38,11 @@ public static void printCorruptedFileError(String message) { } public Scanner getScanner() { - return Scanner; + return scanner; } public void setScanner(Scanner scanner) { - this.Scanner = scanner; + this.scanner = scanner; } public void showMessage(String message) { @@ -59,7 +59,7 @@ public void exitMessage() { } public String input() { - return Scanner.nextLine().trim(); + return scanner.nextLine().trim(); } public void printWatchListHeader() { From 3f80f218b3dfb6837f8f4e552b36dc2298d07e27 Mon Sep 17 00:00:00 2001 From: YFshadaow Date: Wed, 1 Nov 2023 22:18:02 +0800 Subject: [PATCH 356/518] Update EXPECTED.TXT for UI testing --- .../java/seedu/financialplanner/commands/InvalidCommand.java | 2 +- text-ui-test/EXPECTED.TXT | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/InvalidCommand.java b/src/main/java/seedu/financialplanner/commands/InvalidCommand.java index d560dbc741..428127d638 100644 --- a/src/main/java/seedu/financialplanner/commands/InvalidCommand.java +++ b/src/main/java/seedu/financialplanner/commands/InvalidCommand.java @@ -15,6 +15,6 @@ public InvalidCommand() { */ @Override public void execute() { - Ui.getInstance().showMessage("Unknown command. Type help for help"); + Ui.getInstance().showMessage("Unknown command. Type help for help."); } } diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 1962194fd4..7cd2a194ad 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -74,5 +74,5 @@ Your remaining budget for the month is: 800.00 You have a remaining budget of 800.00. Budget has been reset to 1000.00. Budget has been deleted. -Unknown command. Please try again. +Unknown command. Type help for help. Exiting Financial Planner. Goodbye. From 27418e49f5b3a254b6560c11660442460e52934d Mon Sep 17 00:00:00 2001 From: Shi Haochen <99376359+hshiah@users.noreply.github.com> Date: Wed, 1 Nov 2023 22:35:31 +0800 Subject: [PATCH 357/518] Update src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java Co-authored-by: Neo Min Wei <110591123+NeoMinWei@users.noreply.github.com> --- .../java/seedu/financialplanner/commands/MarkGoalCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java b/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java index f005708712..3b1fe5ded0 100644 --- a/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java +++ b/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java @@ -9,7 +9,7 @@ public class MarkGoalCommand extends Command { private final int index; public MarkGoalCommand(RawCommand rawCommand) throws IllegalArgumentException { String stringIndex; - if(rawCommand.args.size() == 1) { + if (rawCommand.args.size() == 1) { stringIndex = rawCommand.args.get(0); } else { throw new IllegalArgumentException("Incorrect arguments."); From 410558c34c6c140a99f19306231f1fce24088b1f Mon Sep 17 00:00:00 2001 From: Shi Haochen <99376359+hshiah@users.noreply.github.com> Date: Wed, 1 Nov 2023 22:38:34 +0800 Subject: [PATCH 358/518] Update src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java Co-authored-by: Neo Min Wei <110591123+NeoMinWei@users.noreply.github.com> --- .../java/seedu/financialplanner/commands/MarkGoalCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java b/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java index 3b1fe5ded0..71c6c3bd9f 100644 --- a/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java +++ b/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java @@ -37,7 +37,7 @@ public MarkGoalCommand(RawCommand rawCommand) throws IllegalArgumentException { public void execute() { Goal goal = WishList.getInstance().list.get(index-1); goal.markAsDone(); - Ui.getInstance().showMessage("You have achieved " + goal + System.lineSeparator() +"Congratulations!"); + Ui.getInstance().showMessage("You have achieved " + goal + System.lineSeparator() + "Congratulations!"); CashflowList.getInstance().addExpense(goal.getAmount(), ExpenseType.GOAL, 0, goal.getLabel()); } } From d9293b556806fc2a5a9c96d549157683ef65a430 Mon Sep 17 00:00:00 2001 From: Shi Haochen <99376359+hshiah@users.noreply.github.com> Date: Wed, 1 Nov 2023 22:39:52 +0800 Subject: [PATCH 359/518] Update ExpenseType.java --- .../java/seedu/financialplanner/enumerations/ExpenseType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/enumerations/ExpenseType.java b/src/main/java/seedu/financialplanner/enumerations/ExpenseType.java index e614a49fca..ab9f512fa9 100644 --- a/src/main/java/seedu/financialplanner/enumerations/ExpenseType.java +++ b/src/main/java/seedu/financialplanner/enumerations/ExpenseType.java @@ -3,7 +3,7 @@ import java.util.Arrays; public enum ExpenseType { - DINING, ENTERTAINMENT, SHOPPING, TRAVEL, INSURANCE, NECESSITIES, OTHERS, GOAL; + DINING, ENTERTAINMENT, SHOPPING, TRAVEL, INSURANCE, NECESSITIES, OTHERS; public static String[] getNames(Class> e) { return Arrays.stream(e.getEnumConstants()).map(Enum::name).toArray(String[]::new); From 01e764de1267e8671925d5c965505d8e81b5eb8c Mon Sep 17 00:00:00 2001 From: Shi Haochen <99376359+hshiah@users.noreply.github.com> Date: Wed, 1 Nov 2023 22:40:36 +0800 Subject: [PATCH 360/518] Update MarkGoalCommand.java --- .../java/seedu/financialplanner/commands/MarkGoalCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java b/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java index 71c6c3bd9f..7462b2a4a1 100644 --- a/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java +++ b/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java @@ -38,6 +38,6 @@ public void execute() { Goal goal = WishList.getInstance().list.get(index-1); goal.markAsDone(); Ui.getInstance().showMessage("You have achieved " + goal + System.lineSeparator() + "Congratulations!"); - CashflowList.getInstance().addExpense(goal.getAmount(), ExpenseType.GOAL, 0, goal.getLabel()); + CashflowList.getInstance().addExpense(goal.getAmount(), ExpenseType.OTHERS, 0, goal.getLabel()); } } From a026d6c8e196f6f727484a9b737022470a8b0f09 Mon Sep 17 00:00:00 2001 From: Shi Haochen <99376359+hshiah@users.noreply.github.com> Date: Wed, 1 Nov 2023 22:47:11 +0800 Subject: [PATCH 361/518] Update src/main/java/seedu/financialplanner/commands/DeleteGoalCommand.java Co-authored-by: ryan <94791461+ryan1604@users.noreply.github.com> --- .../java/seedu/financialplanner/commands/DeleteGoalCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/commands/DeleteGoalCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteGoalCommand.java index fe9615ea1a..ed22fe3919 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteGoalCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteGoalCommand.java @@ -10,7 +10,7 @@ public class DeleteGoalCommand extends Command { private final int index; public DeleteGoalCommand(RawCommand rawCommand) throws IllegalArgumentException { String stringIndex; - if (rawCommand.args.size() == 1){ + if (rawCommand.args.size() == 1) { stringIndex = rawCommand.args.get(0); } else { throw new IllegalArgumentException("Incorrect arguments."); From 3eab7c3e4dea48a019272fba0ef2c69848704894 Mon Sep 17 00:00:00 2001 From: YFshadaow Date: Wed, 1 Nov 2023 23:20:41 +0800 Subject: [PATCH 362/518] Resolve merge conflicts --- src/main/java/seedu/financialplanner/utils/Parser.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index 243f4b7fe9..5c419372a9 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -2,6 +2,7 @@ import seedu.financialplanner.commands.Command; import seedu.financialplanner.commands.AddStockCommand; +import seedu.financialplanner.commands.HelpCommand; import seedu.financialplanner.commands.OverviewCommand; import seedu.financialplanner.commands.AddCashflowCommand; import seedu.financialplanner.commands.DeleteCashflowCommand; From 810c7185b55719778ecfa059d9d29d64fdfb9ab4 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Thu, 2 Nov 2023 18:09:02 +0800 Subject: [PATCH 363/518] Fix DG sequence diagram for cat and vis --- docs/diagrams/vis/categorizerSequence.puml | 4 ++-- docs/diagrams/vis/visualizerSequence.puml | 6 +++--- docs/images/vis/categorizerSequence.png | Bin 19281 -> 18815 bytes docs/images/vis/visualizerSequence.png | Bin 20366 -> 19631 bytes 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/diagrams/vis/categorizerSequence.puml b/docs/diagrams/vis/categorizerSequence.puml index 795fd59a71..f413138d0e 100644 --- a/docs/diagrams/vis/categorizerSequence.puml +++ b/docs/diagrams/vis/categorizerSequence.puml @@ -9,10 +9,10 @@ participant "<>\nCategorizer" ":VisCommand"-> "<>\nCategorizer": Categorizer.sortType(cashflowList, type) -alt type == "expense" +alt "expense" "<>\nCategorizer" -> "<>\nCategorizer": sortExpenses(cashflowList) return -else type == "income" +else "income" "<>\nCategorizer" -> "<>\nCategorizer": sortIncome(cashflowList) return end diff --git a/docs/diagrams/vis/visualizerSequence.puml b/docs/diagrams/vis/visualizerSequence.puml index 2289204e61..211fce4e84 100644 --- a/docs/diagrams/vis/visualizerSequence.puml +++ b/docs/diagrams/vis/visualizerSequence.puml @@ -9,11 +9,11 @@ participant "<>\nVisualizer" activate "<>\nVisualizer" -alt chart == "pie" +alt "pie" "<>\nVisualizer" -> "<>\nVisualizer": displayPieChart(cashflowList, type) -else chart == "bar" +else "bar" "<>\nVisualizer" -> "<>\nVisualizer": displayBarChart(cashflowList, type) -else chart == "radar" +else "radar" "<>\nVisualizer" -> "<>\nVisualizer": displayRadarChart(cashflowList, type) end diff --git a/docs/images/vis/categorizerSequence.png b/docs/images/vis/categorizerSequence.png index 373fedbf3d95087fa80532d6917292a7a82ec899..2efd8f7a7a01702cac7a9ea04f39c4b4c1242fb0 100644 GIT binary patch literal 18815 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 literal 19281 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 diff --git a/docs/images/vis/visualizerSequence.png b/docs/images/vis/visualizerSequence.png index 11d05c66a32ea7820ae5e7c726a14302bc6e0610..b3303c7ff4f3d54ede8d145c34344a8060b8c03e 100644 GIT binary patch literal 19631 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 Date: Thu, 2 Nov 2023 23:04:54 +0800 Subject: [PATCH 364/518] Update UG. Fix some minor errors of reminder and goal. Update the saving and loading for goals and reminder. --- docs/UserGuide.md | 158 +++++++++++++++++- .../seedu/financialplanner/goal/Goal.java | 14 +- .../seedu/financialplanner/goal/WishList.java | 7 +- .../financialplanner/reminder/Reminder.java | 11 +- .../reminder/ReminderList.java | 7 +- .../financialplanner/storage/LoadData.java | 43 +++++ .../financialplanner/storage/SaveData.java | 10 ++ 7 files changed, 244 insertions(+), 6 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 3d9ba441d8..208749fd39 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -28,7 +28,15 @@ * [WatchList](#viewing-watchlist-watchlist) * [Adding Stock](#adding-stock-to-watchlist-addstock) * [Deleting Stock](#deleting-budget-budget-delete) - * [Visualization](#Visualization) + * [ReminderList](#view-reminder-list-reminderlist) + * [Adding Reminder](#add-reminder-addreminder) + * [Deleting Reminder](#delete-reminder-deletereminder) + * [Marking Reminder as Done](#mark-reminder-as-done-markreminder) + * [WishList](#view-goal-list-wishlist) + * [Adding Goal](#set-goal-set-goal) + * [Deleting Goal](#delete-goal-deletegoal) + * [Marking Goal as Achieved](#mark-goal-as-achieved-markgoal) + * [Visualization](#visualizing-your-cashflow-vis) * [Exiting the program](#exiting-the-program-exit) * [Saving data](#saving-the-data) * [Loading data](#loading-the-data) @@ -539,6 +547,154 @@ Use watchlist command to view updated Watchlist - Note: Your watchlist information is saved under the file path `data/watchlist.json` in JSON format +### View Reminder List: `reminderlist` +View your current reminder list with reminders that you have added. + +Format: `reminderlist` + +Example of usage: `reminderlist` + +Example of output: + +``` +Here is your reminder list: +1. Reminder + Type: debt + Date: 2023.12.11 + Status: Not Done +2. Reminder + Type: loan + Date: 2023.12.18 + Status: Not Done +``` + +### Add reminder: `addreminder` +Adds a reminder to the Financial Planner. + +Format: `addreminder /t TYPE /d DATE` +- `/t` is used to specify the reminder type, which describes what is the reminder used for. +- `/d` is used to give a deadline date to the reminder. + +Example of usage: `addreminder /t debt /d 2023.12.11` + +Example output: +``` +You have added Reminder + Type: debt + Date: 2023.12.11 + Status: Not Done +``` + +### Delete reminder: `deletereminder` +Deletes a reminder from the Financial Planner. + +Format: `deletereminder INDEX` + +- `INDEX` refers to the index number shown in the displayed list when [`reminderlist`](#view-reminder-list-reminderlist) command is used. + +Example of usage: `deletereminder 1` + +Example output: +``` +You have deleted Reminder + Type: debt + Date: 2023.12.11 + Status: Not Done +``` + +### Mark reminder as done: `markreminder` +Marks a reminder as done in the Financial Planner. + +Format: `markreminder INDEX` + +- `INDEX` refers to the index number shown in the displayed list when [`reminderlist`](#view-reminder-list-reminderlist) command is used. + +Example of usage: `markreminder 1` + +Example output: +``` +You have marked Reminder + Type: debt + Date: 2023.12.11 + Status: Done +``` + +### View Goal List: `wishlist` +View your current goal list with goals that you have added. + +Format: `wishlist` + +Example of usage: `wishlist` + +Example of output: +``` +Here is your wish list: +1. Goal + Label: car + Amount: 5000 + Status: Not Achieved +2. Goal + Label: ipad + Amount: 2000 + Status: Not Achieved +``` + +### Set goal: `set goal` +Adds a goal to the Financial Planner. + +Format: `set goal /g GOAL /l LABEL` +- `/g` is used to specify the goal amount. +- `/l` is used to give a label to the goal. + +Example of usage: `set goal /g 5000 /l car` + +Example output: +``` +You have added Goal + Label: car + Amount: 5000 + Status: Not Achieved +``` + +### Delete goal: `deletegoal` +Deletes a goal from the Financial Planner. + +Format: `deletegoal INDEX` +- `INDEX` refers to the index number shown in the displayed list when [`wishlist`](#view-goal-list-wishlist) command is used. + +Example of usage: `deletegoal 1` + +Example output: +``` +You have deleted Goal + Label: car + Amount: 5000 + Status: Not Achieved +``` + +### Mark goal as achieved: `markgoal` +Marks a goal as achieved in the Financial Planner. This operation will automatically create a corresponding expense. + +Format: `markgoal INDEX` +- `INDEX` refers to the index number shown in the displayed list when [`wishlist`](#view-goal-list-wishlist) command is used. + +Example of usage: `markgoal 1` + +Example output: +``` +You have achieved Goal + Label: ipad + Amount: 2000 + Status: Achieved +Congratulations! +You have added an Expense + Type: Others + Amount: 2000.00 + Description: ipad +to the Financial Planner. +Balance: -2000.00 +``` + ### Visualizing your cashflow: `vis` Using this command to visualize your income or expenses in a pie chart, bar chart or radar chart diff --git a/src/main/java/seedu/financialplanner/goal/Goal.java b/src/main/java/seedu/financialplanner/goal/Goal.java index e3541a933e..e7eac78a6a 100644 --- a/src/main/java/seedu/financialplanner/goal/Goal.java +++ b/src/main/java/seedu/financialplanner/goal/Goal.java @@ -10,6 +10,16 @@ public Goal(String label, int amount) { this.amount = amount; } + public Goal(String label, int amount, String status) { + this.label = label; + this.amount = amount; + if (status.equals("Achieved")) { + this.isDone = true; + } else { + this.isDone = false; + } + } + public String toString() { String status = isDone ? "Achieved" : "Not Achieved"; return "Goal " + System.lineSeparator()+ " Label: " + label + System.lineSeparator() + " Amount: " + @@ -27,7 +37,7 @@ public int getAmount() { return this.amount; } public String formatString() { - String status = isDone ? "Done" : "Not Done"; - return this.label + " | " + this.amount + " | " + this.isDone; + String status = isDone ? "Achieved" : "Not Achieved"; + return "G" + " | " + this.label + " | " + this.amount + " | " + status; } } diff --git a/src/main/java/seedu/financialplanner/goal/WishList.java b/src/main/java/seedu/financialplanner/goal/WishList.java index f00083f66b..b03ae4704b 100644 --- a/src/main/java/seedu/financialplanner/goal/WishList.java +++ b/src/main/java/seedu/financialplanner/goal/WishList.java @@ -28,7 +28,12 @@ public void deleteGoal(int index) { public String toString() { String result = ""; for (int i = 0; i < list.size(); i++) { - result += String.format("%d. %s\n", i + 1, list.get(i)); + if (i == list.size() - 1) { + result += String.format("%d. %s", i + 1, list.get(i)); + break; + } else { + result += String.format("%d. %s\n", i + 1, list.get(i)); + } } return result; } diff --git a/src/main/java/seedu/financialplanner/reminder/Reminder.java b/src/main/java/seedu/financialplanner/reminder/Reminder.java index 1ac0388a04..d32c683823 100644 --- a/src/main/java/seedu/financialplanner/reminder/Reminder.java +++ b/src/main/java/seedu/financialplanner/reminder/Reminder.java @@ -10,6 +10,15 @@ public Reminder(String type, String date) { this.date = date; } + public Reminder(String type, String date, String status) { + this.type = type; + this.date = date; + if (status.equals("Done")) { + this.isDone = true; + } else { + this.isDone = false; + } + } public String toString() { String status = isDone ? "Done" : "Not Done"; return "Reminder " + System.lineSeparator() + " Type: " + type + System.lineSeparator() @@ -29,6 +38,6 @@ public void unmark() { */ public String formatString() { String status = isDone ? "Done" : "Not Done"; - return this.type + " | " + this.date + " | " + this.isDone; + return "R" + " | " + this.type + " | " + this.date + " | " + status; } } diff --git a/src/main/java/seedu/financialplanner/reminder/ReminderList.java b/src/main/java/seedu/financialplanner/reminder/ReminderList.java index d863011c52..e54dd13153 100644 --- a/src/main/java/seedu/financialplanner/reminder/ReminderList.java +++ b/src/main/java/seedu/financialplanner/reminder/ReminderList.java @@ -27,7 +27,12 @@ public void deleteReminder(int index) { public String toString() { String result = ""; for (int i = 0; i < list.size(); i++) { - result += String.format("%d. %s\n", i + 1, list.get(i)); + if (i == list.size() - 1) { + result += String.format("%d. %s", i + 1, list.get(i)); + break; + } else { + result += String.format("%d. %s\n", i + 1, list.get(i)); + } } return result; } diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index d5b89b2c54..ed8b2a0f21 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -14,6 +14,10 @@ import seedu.financialplanner.cashflow.Income; import seedu.financialplanner.cashflow.Expense; import seedu.financialplanner.utils.Ui; +import seedu.financialplanner.goal.Goal; +import seedu.financialplanner.goal.WishList; +import seedu.financialplanner.reminder.Reminder; +import seedu.financialplanner.reminder.ReminderList; import java.io.FileNotFoundException; import java.io.FileReader; @@ -32,6 +36,8 @@ public abstract class LoadData { private static final String FILE_PATH = "data/watchlist.json"; private static final CashflowList cashflowList = CashflowList.getInstance(); private static final Ui ui = Ui.getInstance(); + private static final ReminderList reminderList = ReminderList.getInstance(); + private static final WishList wishList = WishList.getInstance(); /** @@ -61,6 +67,14 @@ public static void load(String filePath, LocalDate date) throws FinancialPlanner case "B": loadBudget(split); break; + case "R": + final Reminder reminder = getReminder(split); + reminderList.load(reminder); + break; + case "G": + final Goal goal = getGoal(split); + wishList.load(goal); + break; default: throw new FinancialPlannerException("Error loading file"); } @@ -232,6 +246,35 @@ private static Cashflow getEntry(String type, String[] split) } } + private static Reminder getReminder(String[] split) throws IllegalArgumentException, IndexOutOfBoundsException, + FinancialPlannerException { + try { + Reminder entry; + String type = split[1].trim(); + String date = split[2].trim(); + String status = split[3].trim(); + entry = new Reminder(type, date, status); + return entry; + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Erroneous arguments detected"); + } catch (IndexOutOfBoundsException e) { + throw new FinancialPlannerException("There should be three data members for reminder"); + } + } + + private static Goal getGoal(String[] split) throws IllegalArgumentException { + try { + Goal entry; + String type = split[1].trim(); + int amount = Integer.parseInt(split[2].trim()); + String status = split[3].trim(); + entry = new Goal(type, amount, status); + return entry; + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Erroneous arguments detected"); + } + } + private static boolean getHasRecurred(String[] split, int recur) throws IllegalArgumentException { boolean hasRecurred; if (recur != 0) { diff --git a/src/main/java/seedu/financialplanner/storage/SaveData.java b/src/main/java/seedu/financialplanner/storage/SaveData.java index 17e49e4e86..897f592432 100644 --- a/src/main/java/seedu/financialplanner/storage/SaveData.java +++ b/src/main/java/seedu/financialplanner/storage/SaveData.java @@ -3,10 +3,12 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import seedu.financialplanner.exceptions.FinancialPlannerException; +import seedu.financialplanner.goal.WishList; import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.cashflow.Budget; import seedu.financialplanner.cashflow.Cashflow; import seedu.financialplanner.cashflow.CashflowList; +import seedu.financialplanner.reminder.ReminderList; import seedu.financialplanner.utils.Ui; import java.io.FileWriter; @@ -18,6 +20,8 @@ public abstract class SaveData { private static final String FILE_PATH = "data/watchlist.json"; private static final CashflowList cashflowList = CashflowList.getInstance(); + private static final ReminderList reminderList = ReminderList.getInstance(); + private static final WishList wishList = WishList.getInstance(); public static void save(String filePath) throws FinancialPlannerException { try { @@ -26,6 +30,12 @@ public static void save(String filePath) throws FinancialPlannerException { fw.write(entry.formatString() + "\n"); } fw.write(Budget.formatString() + "\n"); + for (int i = 0; i < reminderList.list.size(); i++) { + fw.write(reminderList.list.get(i).formatString() + "\n"); + } + for (int i = 0; i < wishList.list.size(); i++) { + fw.write(wishList.list.get(i).formatString() + "\n"); + } fw.close(); } catch (IOException e) { throw new FinancialPlannerException("Error saving file."); From 2447cba8d56388bcbde178c05786b7ea06e3d4c1 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Fri, 3 Nov 2023 01:01:33 +0800 Subject: [PATCH 365/518] Fix code according to DG --- docs/DeveloperGuide.md | 13 ++++++++++--- docs/diagrams/vis/visualisationClass.puml | 15 +++++++-------- docs/diagrams/vis/visualisationSequence.puml | 6 +++--- docs/diagrams/vis/visualizerSequence.puml | 2 ++ docs/images/vis/visualisationClass.png | Bin 39208 -> 46246 bytes docs/images/vis/visualisationSequence.png | Bin 15921 -> 16221 bytes docs/images/vis/visualizerSequence.png | Bin 19631 -> 19971 bytes .../financialplanner/commands/VisCommand.java | 2 +- .../java/seedu/financialplanner/utils/Ui.java | 2 +- 9 files changed, 24 insertions(+), 16 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index f4b4bb3bea..ce21c69eef 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -31,7 +31,7 @@ ## Acknowledgements **Xchart (A Simple Charting Library for Java)** -- author: KNOWN +- author: KNOWM - source: [https://knowm.org/open-source/xchart/](https://knowm.org/open-source/xchart/) **JSON Simple (simple Java toolkit for encoding and decoding JSON)** @@ -125,6 +125,13 @@ VisCommand's Role: 3) Calls the Visualizer to display the chart to the user +As with other Commands in our Financial Planner application, the constructor of VisCommand +takes RawCommand as parameter. The RawCommand would provide the arguments (chart type and cashflow type) +for the VisCommand provided. + +The VisCommand also inherits from the abstract Command class which would provide the execute() abstract method +that would be called in main() + Categorizer's Role: According to the cashflow type (Income/Expense) arugment passed in, the Categorizer sorts the @@ -145,11 +152,11 @@ Overall ![](images/vis/visualisationSequence.png) -Categorizer +Categorizer (`sort cashflow entries` ref from overall sequence diagram above) ![](images/vis/categorizerSequence.png) -Visualizer +Visualizer (`displaying chart` ref from overall sequence diagram above) ![](images/vis/visualizerSequence.png) diff --git a/docs/diagrams/vis/visualisationClass.puml b/docs/diagrams/vis/visualisationClass.puml index 737d5d423b..cea4a2f36c 100644 --- a/docs/diagrams/vis/visualisationClass.puml +++ b/docs/diagrams/vis/visualisationClass.puml @@ -3,14 +3,9 @@ skinparam classFontColor automatic - -class "{abstract}\nCommand" #MintCream { -+execute() {abstract} -} - class VisCommand #MistyRose { --String type --String chart +-type: String +-chart: String +execute() } @@ -33,9 +28,13 @@ class Visualizer #Beige { + displayRadarChart (cashflowByCat: HashMap, type: String) } +class "{abstract}\nCommand" #MintCream { ++execute() {abstract} +} + "{abstract}\nCommand" <|-- VisCommand RawCommand <.. VisCommand -Categorizer <.. Visualizer +Categorizer <.. VisCommand Visualizer <.. VisCommand hide Circle diff --git a/docs/diagrams/vis/visualisationSequence.puml b/docs/diagrams/vis/visualisationSequence.puml index c09a083995..df3fce1c41 100644 --- a/docs/diagrams/vis/visualisationSequence.puml +++ b/docs/diagrams/vis/visualisationSequence.puml @@ -5,15 +5,15 @@ participant ":Ui" participant "<>\nCategorizer" participant "<>\nVisualizer" -":VisCommand"-> ":Ui": printDisplayChart(type) +":VisCommand"-> ":Ui": printDisplayChartMessages(type) ref over "<>\nCategorizer", ":VisCommand" : sort cashflow entries -alt #Pink cashflowbyType.empty() +alt #Pink cashflowbyType is empty ":VisCommand" -> ":Ui" : ui.printEmptyCashflow(type) -else #LightBlue !cashflowbyType.empty() +else #LightBlue cashflowbyType is not empty ref over "<>\nVisualizer", ":VisCommand": displaying chart diff --git a/docs/diagrams/vis/visualizerSequence.puml b/docs/diagrams/vis/visualizerSequence.puml index 211fce4e84..35dafb8d74 100644 --- a/docs/diagrams/vis/visualizerSequence.puml +++ b/docs/diagrams/vis/visualizerSequence.puml @@ -17,6 +17,8 @@ else "radar" "<>\nVisualizer" -> "<>\nVisualizer": displayRadarChart(cashflowList, type) end +return + hide footbox @enduml \ No newline at end of file diff --git a/docs/images/vis/visualisationClass.png b/docs/images/vis/visualisationClass.png index 9f2faa4b6ad0ecdfe78fa3391aab506a72752ea2..ad6224effcf5dd6e853601a964b3b4aed3addb1c 100644 GIT binary patch literal 46246 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 diff --git a/docs/images/vis/visualisationSequence.png b/docs/images/vis/visualisationSequence.png index 46c620a688b0a646d75d0f2b06693b1926931f43..4768b5af0f09888cc48cce39d9b1fc5a3f443856 100644 GIT binary patch literal 16221 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 Qx7%RiA~M2dg1Wx{AMyluu>b%7 diff --git a/docs/images/vis/visualizerSequence.png b/docs/images/vis/visualizerSequence.png index b3303c7ff4f3d54ede8d145c34344a8060b8c03e..9ccf49a0d203affcb78470ed9ce1cced47d55559 100644 GIT binary patch literal 19971 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 literal 19631 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 Date: Fri, 3 Nov 2023 10:30:12 +0800 Subject: [PATCH 366/518] Update WishList.java --- src/main/java/seedu/financialplanner/goal/WishList.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/goal/WishList.java b/src/main/java/seedu/financialplanner/goal/WishList.java index b03ae4704b..612a501cbc 100644 --- a/src/main/java/seedu/financialplanner/goal/WishList.java +++ b/src/main/java/seedu/financialplanner/goal/WishList.java @@ -30,7 +30,6 @@ public String toString() { for (int i = 0; i < list.size(); i++) { if (i == list.size() - 1) { result += String.format("%d. %s", i + 1, list.get(i)); - break; } else { result += String.format("%d. %s\n", i + 1, list.get(i)); } From e249eca9e943b9164677c8351cb0e338d387f358 Mon Sep 17 00:00:00 2001 From: Shi Haochen <99376359+hshiah@users.noreply.github.com> Date: Fri, 3 Nov 2023 10:30:33 +0800 Subject: [PATCH 367/518] Update ReminderList.java --- src/main/java/seedu/financialplanner/reminder/ReminderList.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/reminder/ReminderList.java b/src/main/java/seedu/financialplanner/reminder/ReminderList.java index e54dd13153..94ebd7e19a 100644 --- a/src/main/java/seedu/financialplanner/reminder/ReminderList.java +++ b/src/main/java/seedu/financialplanner/reminder/ReminderList.java @@ -29,7 +29,6 @@ public String toString() { for (int i = 0; i < list.size(); i++) { if (i == list.size() - 1) { result += String.format("%d. %s", i + 1, list.get(i)); - break; } else { result += String.format("%d. %s\n", i + 1, list.get(i)); } From 2815bb523c204918e2e140fd23011a56deb0b290 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sat, 4 Nov 2023 15:36:46 +0800 Subject: [PATCH 368/518] Remove long method parameters in recur sequence and class diagrams --- docs/diagrams/cashflow/RecurClassDiagram.puml | 4 ++-- docs/diagrams/cashflow/RecurSequence.puml | 4 ++-- docs/images/cashflow/RecurClassDiagram.png | Bin 54180 -> 48510 bytes docs/images/cashflow/RecurSequence.png | Bin 38665 -> 33673 bytes 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/diagrams/cashflow/RecurClassDiagram.puml b/docs/diagrams/cashflow/RecurClassDiagram.puml index 9da06ba216..367886c631 100644 --- a/docs/diagrams/cashflow/RecurClassDiagram.puml +++ b/docs/diagrams/cashflow/RecurClassDiagram.puml @@ -4,8 +4,8 @@ skinparam classFontColor automatic Class "{abstract}\nLoadData" as LoadData #HoneyDew { -addRecurringCashflows(currentDate: LocalDate) - -identifyRecurringCashflows(currentDate: LocalDate, cashflow: Cashflow, recur: int, dateOfAddition: LocalDate, tempCashflowList: ArrayList, hasRecurred: boolean) - -addRecurringCashflowToTempList(currentDate: LocalDate, cashflow: Cashflow, recur: int, dateOfAddition: LocalDate, tempCashflowList: ArrayList) + -identifyRecurringCashflows() + -addRecurringCashflowToTempList() -addToTempList(tempCashflowList: ArrayList, toAdd: Cashflow) } diff --git a/docs/diagrams/cashflow/RecurSequence.puml b/docs/diagrams/cashflow/RecurSequence.puml index c0fb71b6b0..5ec9f4c49e 100644 --- a/docs/diagrams/cashflow/RecurSequence.puml +++ b/docs/diagrams/cashflow/RecurSequence.puml @@ -10,10 +10,10 @@ participant ":Ui" as Ui LoadData -> LoadData: addRecurringCashflows(date); activate LoadData loop for each cashflow in cashflowList - LoadData -> LoadData: identifyRecurringCashflows(currentDate, cashflow, recur, dateOfAddition, tempCashflowList, hasRecurred) + LoadData -> LoadData: identifyRecurringCashflows() activate LoadData opt is Recurring and has not Recurred - LoadData -> LoadData: addRecurringCashflowToTempList(currentDate, cashflow, recur, dateOfAddition, tempCashflowList) + LoadData -> LoadData: addRecurringCashflowToTempList() activate LoadData ref over LoadData, Expense: add recurring cashflows to templist return diff --git a/docs/images/cashflow/RecurClassDiagram.png b/docs/images/cashflow/RecurClassDiagram.png index d5eedc6eb3310e828078496aa98ebce2a4beb0d5..e1c249e3dd45928851d3265cfcb70ed45ea17f67 100644 GIT binary patch literal 48510 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 literal 54180 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

rkx8c@an|KFufI@H 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 literal 38665 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 KhmyokT>d|n30x)s From 03c556bc87c3f0e7f054fa1d1d0c66aa67501609 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sat, 4 Nov 2023 15:41:58 +0800 Subject: [PATCH 369/518] Resolve spacing issues in headers --- docs/UserGuide.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 3d9ba441d8..4190b04f78 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -48,7 +48,7 @@ you a one-stop interface to access a plethora of features to manage your finance 1. Ensure that you have Java 11 or above installed. 2. Download the latest version of `Financial Planner` from [here](http://link.to/duke). 3. Copy the file to the folder you want to use as the *home folder* for Financial Planner. -4. Open a command terminal, `cd` into the folder you put the jar file in, and use the `java -jar ip.jar` command to run the application. +4. Open a command terminal, `cd` into the folder you put the jar file in, and use the `java -jar tp.jar` command to run the application. 5. Refer to the **Features** section below for details of each command. ## Features @@ -97,6 +97,7 @@ to the Financial Planner. Balance: 5000.00 ``` - Note: Balance displayed above is just an example. Your actual balance may differ. + #### Add expense: `add expense` Adds an expense to the Financial Planner @@ -129,6 +130,7 @@ to the Financial Planner. Balance: 4700.00 ``` - Note: Balance displayed above is just an example. Your actual balance may differ. + ### Delete cashflow: `delete` Deletes a cashflow from the Financial Planner. From 9abcc2f5452d090cd522f2e9df7bdd6f55195ad2 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sat, 4 Nov 2023 15:58:02 +0800 Subject: [PATCH 370/518] Add description for the types accepted in add income and expense --- docs/UserGuide.md | 85 +++++++++++++++++++++++++++++------------------ 1 file changed, 53 insertions(+), 32 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 4190b04f78..24551a2a42 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -72,9 +72,10 @@ Adds an income source to the Financial Planner. Format: `add income /a AMOUNT /t TYPE [/r DAYS] [/d DESCRIPTION]` -- `/r` is used to denote a recurring income, with the period to the next addition is specified by `DAYS`. -- `/d` is used to give a description to the income. -- `/t` is used to specify the income type, where the list of acceptable types is given below +- `/a` is used to specify the amount of the income, where an **integer** or **double** is expected. +- `/r` is used to denote a recurring income, with the period to the next addition is specified by an **integer** representing the number of `DAYS`. +- `/d` is used to give a description to the income, where any **String** is expected. +- `/t` is used to specify the income type, where the list of acceptable types is given below. | Income Types | |---------------| @@ -91,20 +92,22 @@ Example output: You have added an Income Type: Salary Amount: 5000.00 - Recurring every: 30 days, starting from: Oct 30 2023 + Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 Description: work to the Financial Planner. Balance: 5000.00 ``` - Note: Balance displayed above is just an example. Your actual balance may differ. +- Note: Date displayed above is just an example. Your actual date may differ. #### Add expense: `add expense` Adds an expense to the Financial Planner Format: `add expense /a AMOUNT /t TYPE [/r DAYS] [/d DESCRIPTION]` -- `/r` is used to denote a recurring expense, with the period to the next addition is specified by `DAYS`. -- `/d` is used to give a description to the expense. +- `/a` is used to specify the amount of the expense, where an **integer** or **double** is expected. +- `/r` is used to denote a recurring expense, with the period to the next addition is specified by an **integer** representing the number of `DAYS`. +- `/d` is used to give a description to the expense, where any **String** is expected. - `/t` is used to specify the expense type, where the list of acceptable types is given below | Expense | @@ -124,12 +127,13 @@ Example output: You have added an Expense Type: Necessities Amount: 300.00 - Recurring every: 30 days, starting from: Oct 30 2023 + Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 Description: groceries to the Financial Planner. Balance: 4700.00 ``` - Note: Balance displayed above is just an example. Your actual balance may differ. +- Note: Date displayed above is just an example. Your actual date may differ. ### Delete cashflow: `delete` Deletes a cashflow from the Financial Planner. @@ -260,6 +264,8 @@ Balance: -830.00 ``` - Note: Balance displayed above is just an example. Your actual balance may differ. +- Note: Date displayed above is just an example. Your actual date may differ. + ### List #### List all: `list` @@ -269,26 +275,28 @@ Example output: ``` You have 4 matching cashflows: -1: Income +1: Expense + Type: Necessities + Amount: 300.00 + Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 + Description: groceries +2: Income Type: Salary Amount: 5000.00 - Recurring every: 30 days, starting from: Oct 30 2023 + Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 Description: work -2: Expense +3: Expense Type: Dining Amount: 30.00 Description: Genki Sushi -3: Expense - Type: Insurance - Amount: 800.00 - Recurring every: 365 days, starting from: Oct 30 2023 - Description: ntuc income 4: Expense Type: Necessities Amount: 300.00 - Recurring every: 30 days, starting from: Oct 30 2023 + Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 Description: groceries ``` +- Note: Date displayed above is just an example. Your actual date may differ. + #### List income: `list income` //TODO @@ -298,17 +306,18 @@ You have 3 matching cashflows: 1: Income Type: Salary Amount: 5000.00 - Recurring every: 30 days, starting from: Oct 30 2023 + Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 Description: work 2: Income Type: Allowance Amount: 500.00 - Recurring every: 30 days, starting from: Oct 30 2023 - Description: parents + Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 3: Income Type: Investments Amount: 1000.00 ``` +- Note: Date displayed above is just an example. Your actual date may differ. + #### List expense: `list expense` //TODO @@ -316,20 +325,22 @@ Example output: ``` You have 3 matching cashflows: 1: Expense + Type: Necessities + Amount: 300.00 + Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 + Description: groceries +2: Expense Type: Dining Amount: 30.00 Description: Genki Sushi -2: Expense - Type: Insurance - Amount: 800.00 - Recurring every: 365 days, starting from: Oct 30 2023 - Description: ntuc income 3: Expense Type: Necessities Amount: 300.00 - Recurring every: 30 days, starting from: Oct 30 2023 + Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 Description: groceries ``` +- Note: Date displayed above is just an example. Your actual date may differ. + #### List recurring: `list recurring` Lists all recurring cashflows. @@ -341,18 +352,28 @@ Example of usage: `list recurring` Example output: ``` -You have 2 matching cashflows: +You have 4 matching cashflows: 1: Expense - Type: Insurance - Amount: 800.00 - Recurring every: 365 days, starting from: Oct 30 2023 - Description: ntuc income -2: Expense Type: Necessities Amount: 300.00 - Recurring every: 30 days, starting from: Oct 30 2023 + Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 + Description: groceries +2: Income + Type: Salary + Amount: 5000.00 + Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 + Description: work +3: Expense + Type: Necessities + Amount: 300.00 + Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 Description: groceries +4: Income + Type: Allowance + Amount: 500.00 + Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 ``` +- Note: Date displayed above is just an example. Your actual date may differ. ### Budget From c27e5dd49b0a4478de2822ba274e1bd962b237f2 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Sat, 4 Nov 2023 16:50:56 +0800 Subject: [PATCH 371/518] Fix bugs --- .../FinancialPlannerLogger.java | 5 +++ .../commands/BudgetCommand.java | 5 ++- .../investments/WatchList.java | 5 ++- .../financialplanner/storage/SaveData.java | 4 +- .../financialplanner/storage/Storage.java | 5 ++- .../java/seedu/financialplanner/utils/Ui.java | 43 +++++++++---------- .../commands/BudgetCommandTest.java | 7 ++- .../financialplanner/storage/StorageTest.java | 5 ++- src/test/testData/ValidData.txt | 3 +- src/test/testData/ValidDataWithBudget.txt | 3 ++ 10 files changed, 53 insertions(+), 32 deletions(-) create mode 100644 src/test/testData/ValidDataWithBudget.txt diff --git a/src/main/java/seedu/financialplanner/FinancialPlannerLogger.java b/src/main/java/seedu/financialplanner/FinancialPlannerLogger.java index 7751a7e0c5..be0114105e 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlannerLogger.java +++ b/src/main/java/seedu/financialplanner/FinancialPlannerLogger.java @@ -1,5 +1,6 @@ package seedu.financialplanner; +import java.io.File; import java.util.logging.FileHandler; import java.util.logging.Level; import java.util.logging.Logger; @@ -17,6 +18,10 @@ public class FinancialPlannerLogger { */ public static void initialise() { try { + File dir = new File("data"); + if (!dir.exists()) { + dir.mkdir(); + } FileHandler fh = new FileHandler("data/logger.log"); LogManager.getLogManager().reset(); logger.addHandler(fh); diff --git a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java index 60f24a66f6..f9f2febbde 100644 --- a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java +++ b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java @@ -25,6 +25,9 @@ public class BudgetCommand extends Command { * @throws FinancialPlannerException If there is an issue with the command provided. */ public BudgetCommand(RawCommand rawCommand) throws FinancialPlannerException { + if (rawCommand.args.isEmpty()) { + throw new FinancialPlannerException("Budget operation cannot be empty."); + } command = rawCommand.args.get(0); if (command.equals("delete") || command.equals("reset") || command.equals("view")) { return; @@ -76,7 +79,7 @@ private void validateBudget(RawCommand rawCommand) throws FinancialPlannerExcept private void validateCommandFormat(RawCommand rawCommand) throws FinancialPlannerException { if (!command.equals("set") && !command.equals("update")) { logger.log(Level.WARNING, "Invalid arguments for budget command"); - throw new FinancialPlannerException("Budget command must be one of the following: set, update, " + + throw new FinancialPlannerException("Budget operation must be one of the following: set, update, " + "delete, reset, view."); } diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index ce9723dfa2..d25f98c708 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -6,6 +6,7 @@ import org.json.simple.parser.ParseException; import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.storage.LoadData; +import seedu.financialplanner.utils.Ui; import java.io.IOException; import java.net.URI; @@ -31,7 +32,7 @@ private WatchList() { if (!stocks.isEmpty()) { return; } - System.out.println("Initializing New watchlist.. adding AAPL and GOOGL for your reference"); + Ui.getInstance().showMessage("Initializing New watchlist.. adding AAPL and GOOGL for your reference"); try { Stock apple = new Stock("AAPL"); assert apple.getSymbol() != null && apple.getStockName() != null; @@ -42,7 +43,7 @@ private WatchList() { stocks.put(google.getSymbol(), google); } catch (FinancialPlannerException e) { - System.out.println(e.getMessage()); + Ui.getInstance().showMessage(e.getMessage()); } } diff --git a/src/main/java/seedu/financialplanner/storage/SaveData.java b/src/main/java/seedu/financialplanner/storage/SaveData.java index 897f592432..ccba165c0a 100644 --- a/src/main/java/seedu/financialplanner/storage/SaveData.java +++ b/src/main/java/seedu/financialplanner/storage/SaveData.java @@ -29,7 +29,9 @@ public static void save(String filePath) throws FinancialPlannerException { for (Cashflow entry : cashflowList.list) { fw.write(entry.formatString() + "\n"); } - fw.write(Budget.formatString() + "\n"); + if (Budget.hasBudget()) { + fw.write(Budget.formatString() + "\n"); + } for (int i = 0; i < reminderList.list.size(); i++) { fw.write(reminderList.list.get(i).formatString() + "\n"); } diff --git a/src/main/java/seedu/financialplanner/storage/Storage.java b/src/main/java/seedu/financialplanner/storage/Storage.java index ef491dc34e..03ed7e25a0 100644 --- a/src/main/java/seedu/financialplanner/storage/Storage.java +++ b/src/main/java/seedu/financialplanner/storage/Storage.java @@ -1,6 +1,7 @@ package seedu.financialplanner.storage; import seedu.financialplanner.exceptions.FinancialPlannerException; +import seedu.financialplanner.utils.Ui; import java.io.IOException; import java.nio.file.Files; @@ -18,10 +19,10 @@ public class Storage { private Storage() { if (!Files.exists(path)) { try { - System.out.println("Directory doesn't exist. Creating directory..."); + Ui.getInstance().showMessage("Directory doesn't exist. Creating directory..."); Files.createDirectory(path); } catch (IOException e) { - System.out.println("Error creating directory: " + e.getMessage()); + Ui.getInstance().showMessage("Error creating directory: " + e.getMessage()); } } } diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index fa8d8dcf0e..58f17ebe0e 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -22,6 +22,7 @@ public class Ui { private static final String GREEN = "\u001B[32m"; private static final String RESET = "\u001B[0m"; private static final String YELLOW = "\u001B[33m"; + private static final String CYAN = "\u001B[36m"; private Scanner scanner = new Scanner(System.in); private Ui() { } @@ -47,7 +48,7 @@ public void setScanner(Scanner scanner) { public void showMessage(String message) { assert !message.isEmpty(); - System.out.println(message); + System.out.println(CYAN + message + RESET); } public void welcomeMessage() { @@ -98,35 +99,33 @@ public void printStocksInfo(WatchList watchList) { } public void printAddStock(String stockName) { - System.out.println("You have successfully added:"); - System.out.println(stockName); - System.out.println("Use Watchlist to view it!"); + showMessage("You have successfully added:"); + showMessage(stockName); + showMessage("Use Watchlist to view it!"); } public void printDeleteStock(String stockName) { - System.out.println("You have successfully deleted: "); - System.out.println(stockName); - System.out.println("Use watchlist command to view updated Watchlist"); + showMessage("You have successfully deleted: "); + showMessage(stockName); + showMessage("Use watchlist command to view updated Watchlist"); } public void printAddedCashflow(Cashflow entry) { - System.out.print("You have added an "); - System.out.println(entry); - System.out.println("to the Financial Planner."); - System.out.println("Balance: " + entry.formatBalance()); + showMessage("You have added an " + entry); + showMessage("to the Financial Planner."); + showMessage("Balance: " + entry.formatBalance()); } public void printDeletedCashflow(Cashflow entry) { - System.out.print("You have removed an "); - System.out.println(entry); - System.out.println("from the Financial Planner."); - System.out.println("Balance: " + entry.formatBalance()); + showMessage("You have removed an " + entry); + showMessage("from the Financial Planner."); + showMessage("Balance: " + entry.formatBalance()); } public void printDeletedRecur(Cashflow entry) { - System.out.println("You have removed future recurrences of this cashflow."); - System.out.println("Updated cashflow:"); - System.out.println(entry); + showMessage("You have removed future recurrences of this cashflow."); + showMessage("Updated cashflow:"); + showMessage(entry.toString()); } public void printBudgetBeforeUpdate() { @@ -146,12 +145,12 @@ public void printBudgetAfterUpdate() { public void printBudgetAfterDeduction() { StringBuilder message = new StringBuilder(); + message.append("Your remaining budget for the month is: ").append(Budget.getCurrentBudgetString()); if (Budget.getCurrentBudget() <= 0) { - message.append("You have exceeded your current budget by: "); - } else if (Budget.getCurrentBudget() > 0) { - message.append("Your remaining budget for the month is: "); + message.append("Oops, you ran out of budget, please update to a larger budget or " + + "reset the current budget to initial budget."); } - message.append(Budget.getCurrentBudgetString()); + showMessage(message.toString()); } diff --git a/src/test/java/seedu/financialplanner/commands/BudgetCommandTest.java b/src/test/java/seedu/financialplanner/commands/BudgetCommandTest.java index 019b0b4424..accf564f55 100644 --- a/src/test/java/seedu/financialplanner/commands/BudgetCommandTest.java +++ b/src/test/java/seedu/financialplanner/commands/BudgetCommandTest.java @@ -64,6 +64,11 @@ public void testDeleteBudget() throws FinancialPlannerException { @Test @Order(5) public void testInvalidCommandFormat_throwsException() throws FinancialPlannerException { + try { + BudgetCommand testEmptyArgument = new BudgetCommand(Parser.parseRawCommand("budget")); + } catch (FinancialPlannerException e) { + assertEquals("Budget operation cannot be empty.", e.getMessage()); + } try { BudgetCommand testExtraArgument = new BudgetCommand(Parser.parseRawCommand("budget" + " set /b 500 /t sdf")); @@ -73,7 +78,7 @@ public void testInvalidCommandFormat_throwsException() throws FinancialPlannerEx try { BudgetCommand testInvalidCommand = new BudgetCommand(Parser.parseRawCommand("budget random /b 5")); } catch (FinancialPlannerException e) { - assertEquals("Budget command must be one of the following: set, update, " + + assertEquals("Budget operation must be one of the following: set, update, " + "delete, reset, view.", e.getMessage()); } diff --git a/src/test/java/seedu/financialplanner/storage/StorageTest.java b/src/test/java/seedu/financialplanner/storage/StorageTest.java index 3cf6e14bd1..682dbba168 100644 --- a/src/test/java/seedu/financialplanner/storage/StorageTest.java +++ b/src/test/java/seedu/financialplanner/storage/StorageTest.java @@ -2,6 +2,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; +import seedu.financialplanner.cashflow.Budget; import seedu.financialplanner.enumerations.ExpenseType; import seedu.financialplanner.enumerations.IncomeType; import seedu.financialplanner.exceptions.FinancialPlannerException; @@ -54,6 +55,7 @@ public void loadInvalidData_userInputNo() { public void saveValidData() throws FinancialPlannerException, IOException { cashflowList.list.clear(); getTestData(); + Budget.setBudget(10); storage.save(String.valueOf(testFolder.resolve("temp.txt"))); String date = LocalDate.now().format(DateTimeFormatter.ofPattern("dd/MM/yyyy")); @@ -62,6 +64,7 @@ public void saveValidData() throws FinancialPlannerException, IOException { assertEquals(Files.readAllLines(Path.of(filePath)), Files.readAllLines(testFolder.resolve("temp.txt"))); + Budget.deleteBudget(); } @Test @@ -77,7 +80,7 @@ private void getTestData() { private static void getTestValidData(String filePath, String date) throws IOException { try { - Files.copy(Paths.get("src/test/testData/ValidData.txt"), Path.of(filePath)); + Files.copy(Paths.get("src/test/testData/ValidDataWithBudget.txt"), Path.of(filePath)); FileWriter fw = new FileWriter(filePath, true); fw.append(" ").append(date); fw.close(); diff --git a/src/test/testData/ValidData.txt b/src/test/testData/ValidData.txt index 0526a8035e..dda0445911 100644 --- a/src/test/testData/ValidData.txt +++ b/src/test/testData/ValidData.txt @@ -1,3 +1,2 @@ I | 123.12 | ALLOWANCE | 0 | false -E | 100.0 | SHOPPING | 0 | false | shopee -B | 0.0 | 0.0 | \ No newline at end of file +E | 100.0 | SHOPPING | 0 | false | shopee \ No newline at end of file diff --git a/src/test/testData/ValidDataWithBudget.txt b/src/test/testData/ValidDataWithBudget.txt new file mode 100644 index 0000000000..a799295a5a --- /dev/null +++ b/src/test/testData/ValidDataWithBudget.txt @@ -0,0 +1,3 @@ +I | 123.12 | ALLOWANCE | 0 | false +E | 100.0 | SHOPPING | 0 | false | shopee +B | 10.0 | 10.0 | \ No newline at end of file From 26bbcd4acb9146d5bcf62c0bcbc359b749579686 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sat, 4 Nov 2023 16:52:56 +0800 Subject: [PATCH 372/518] Add maximum/minimum value exception --- docs/UserGuide.md | 4 ++ .../financialplanner/cashflow/Cashflow.java | 1 + .../cashflow/CashflowList.java | 47 +++++++++++-------- .../financialplanner/cashflow/Expense.java | 17 +++++-- .../financialplanner/cashflow/Income.java | 18 +++++-- .../commands/AddCashflowCommand.java | 5 ++ .../storage/LoadDataTest.java | 2 +- .../financialplanner/storage/StorageTest.java | 4 +- 8 files changed, 66 insertions(+), 32 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 24551a2a42..012410dc7a 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -65,6 +65,10 @@ you a one-stop interface to access a plethora of features to manage your finance ### Notes about naming convention - Cashflow refers to an income or expense. +### Notes about program limitations +- Maximum amount and balance the program can hold is 999,999,999,999.99 +- Minimum amount and balance the program can hold is -999,999,999,999.99 + ### Add cashflow #### Add income: `add income` diff --git a/src/main/java/seedu/financialplanner/cashflow/Cashflow.java b/src/main/java/seedu/financialplanner/cashflow/Cashflow.java index e4ba13f2f5..0f2f45acb7 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Cashflow.java +++ b/src/main/java/seedu/financialplanner/cashflow/Cashflow.java @@ -17,6 +17,7 @@ public abstract class Cashflow { protected String description; protected LocalDate date; protected boolean hasRecurred; + protected final double MAX_AMOUNT = 999999999999.99; public Cashflow(double amount, int recur, String description) { this.amount = amount; diff --git a/src/main/java/seedu/financialplanner/cashflow/CashflowList.java b/src/main/java/seedu/financialplanner/cashflow/CashflowList.java index 969e66878c..3299f5a208 100644 --- a/src/main/java/seedu/financialplanner/cashflow/CashflowList.java +++ b/src/main/java/seedu/financialplanner/cashflow/CashflowList.java @@ -3,6 +3,7 @@ import seedu.financialplanner.enumerations.CashflowCategory; import seedu.financialplanner.enumerations.ExpenseType; import seedu.financialplanner.enumerations.IncomeType; +import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.utils.Ui; import java.util.ArrayList; import java.util.logging.Level; @@ -25,15 +26,19 @@ public static CashflowList getInstance() { } public void addIncome(double value, IncomeType type, int recur, String description) { - logger.log(Level.INFO, "Adding income"); - int existingListSize = list.size(); - - Income toAdd = new Income(value, type, recur, description); - addToList(toAdd); - ui.printAddedCashflow(toAdd); - - int newListSize = list.size(); - assert newListSize == existingListSize + 1; + try { + logger.log(Level.INFO, "Adding income"); + int existingListSize = list.size(); + + Income toAdd = new Income(value, type, recur, description); + addToList(toAdd); + ui.printAddedCashflow(toAdd); + + int newListSize = list.size(); + assert newListSize == existingListSize + 1; + } catch (FinancialPlannerException e) { + ui.showMessage(e.getMessage()); + } } private void addToList(Cashflow toAdd) { @@ -41,15 +46,19 @@ private void addToList(Cashflow toAdd) { } public void addExpense(double value, ExpenseType type, int recur, String description) { - logger.log(Level.INFO, "Adding expense"); - int existingListSize = list.size(); - - Expense toAdd = new Expense(value, type, recur, description); - addToList(toAdd); - ui.printAddedCashflow(toAdd); - - int newListSize = list.size(); - assert newListSize == existingListSize + 1; + try { + logger.log(Level.INFO, "Adding expense"); + int existingListSize = list.size(); + + Expense toAdd = new Expense(value, type, recur, description); + addToList(toAdd); + ui.printAddedCashflow(toAdd); + + int newListSize = list.size(); + assert newListSize == existingListSize + 1; + } catch (FinancialPlannerException e) { + ui.showMessage(e.getMessage()); + } } public double deleteCashflowWithoutCategory(int index) { @@ -172,7 +181,7 @@ public double deleteCashflowWithCategory(CashflowCategory category, int index) { } public void load(Cashflow entry) { - list.add(entry); + addToList(entry); } public String getList() { diff --git a/src/main/java/seedu/financialplanner/cashflow/Expense.java b/src/main/java/seedu/financialplanner/cashflow/Expense.java index 28ef941cef..1eba4bb451 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Expense.java +++ b/src/main/java/seedu/financialplanner/cashflow/Expense.java @@ -2,26 +2,27 @@ import seedu.financialplanner.enumerations.ExpenseType; import seedu.financialplanner.enumerations.IncomeType; +import seedu.financialplanner.exceptions.FinancialPlannerException; import java.time.LocalDate; public class Expense extends Cashflow { protected ExpenseType type; - public Expense(double amount, ExpenseType type, int recur, String description) { + public Expense(double amount, ExpenseType type, int recur, String description) throws FinancialPlannerException { super(amount, recur, description); this.type = type; addExpenseValue(); } public Expense(double amount, ExpenseType type, int recur, - String description, LocalDate date, boolean hasRecurred) { + String description, LocalDate date, boolean hasRecurred) throws FinancialPlannerException { super(amount, recur, description, date, hasRecurred); this.type = type; addExpenseValue(); } - public Expense(Expense expense) { + public Expense(Expense expense) throws FinancialPlannerException { this.amount = expense.getAmount(); this.recur = expense.getRecur(); this.description = expense.getDescription(); @@ -40,8 +41,14 @@ public IncomeType getIncomeType() { return null; } - private void addExpenseValue() { - balance -= this.amount; + private void addExpenseValue() throws FinancialPlannerException { + double tempBalance = balance - this.amount; + + if (tempBalance < -MAX_AMOUNT) { + throw new FinancialPlannerException("Balance exceeded minimum value this program can hold."); + } + + balance = tempBalance; } @Override diff --git a/src/main/java/seedu/financialplanner/cashflow/Income.java b/src/main/java/seedu/financialplanner/cashflow/Income.java index 1ba3697762..a75e2f8694 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Income.java +++ b/src/main/java/seedu/financialplanner/cashflow/Income.java @@ -2,25 +2,27 @@ import seedu.financialplanner.enumerations.ExpenseType; import seedu.financialplanner.enumerations.IncomeType; +import seedu.financialplanner.exceptions.FinancialPlannerException; import java.time.LocalDate; public class Income extends Cashflow{ protected IncomeType type; - public Income(double amount, IncomeType type, int recur, String description) { + public Income(double amount, IncomeType type, int recur, String description) throws FinancialPlannerException { super(amount, recur, description); this.type = type; addIncomeValue(); } - public Income(double amount, IncomeType type, int recur, String description, LocalDate date, boolean hasRecurred) { + public Income(double amount, IncomeType type, int recur, String description, LocalDate date, boolean hasRecurred) + throws FinancialPlannerException { super(amount, recur, description, date, hasRecurred); this.type = type; addIncomeValue(); } - public Income(Income income) { + public Income(Income income) throws FinancialPlannerException { this.amount = income.getAmount(); this.recur = income.getRecur(); this.description = income.getDescription(); @@ -39,8 +41,14 @@ public ExpenseType getExpenseType() { return null; } - private void addIncomeValue() { - balance += this.amount; + private void addIncomeValue() throws FinancialPlannerException { + double tempBalance = balance + this.amount; + + if (tempBalance > MAX_AMOUNT) { + throw new FinancialPlannerException("Balance exceeded maximum value this program can hold."); + } + + balance = tempBalance; } @Override diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index 267ef4be91..48a291da4c 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -23,6 +23,7 @@ public class AddCashflowCommand extends Command { protected int recur = 0; protected String description = null; protected CashflowList cashflowList = CashflowList.getInstance(); + protected final double MAX_AMOUNT = 999999999999.99; public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException { String categoryString = String.join(" ", rawCommand.args); @@ -49,6 +50,10 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException logger.log(Level.WARNING, "Invalid value for amount"); throw new IllegalArgumentException("Amount cannot be negative"); } + if (amount > MAX_AMOUNT) { + logger.log(Level.WARNING, "Maximum value for amount exceeded."); + throw new IllegalArgumentException("Amount exceeded maximum value this program can hold."); + } rawCommand.extraArgs.remove("a"); if (!rawCommand.extraArgs.containsKey("t")) { diff --git a/src/test/java/seedu/financialplanner/storage/LoadDataTest.java b/src/test/java/seedu/financialplanner/storage/LoadDataTest.java index 180889048f..85190c2914 100644 --- a/src/test/java/seedu/financialplanner/storage/LoadDataTest.java +++ b/src/test/java/seedu/financialplanner/storage/LoadDataTest.java @@ -36,7 +36,7 @@ void loadWatchList() { private LocalDate stringToDate(String string) { return LocalDate.parse(string, DateTimeFormatter.ofPattern("dd/MM/yyyy")); } - private void getTestData() { + private void getTestData() throws FinancialPlannerException{ LocalDate date = stringToDate("01/01/2023"); cashflowList.load(new Income(123.12, IncomeType.ALLOWANCE, 10, null, date, false)); cashflowList.load(new Income(123.12, IncomeType.ALLOWANCE, 0, "parents", date, false)); diff --git a/src/test/java/seedu/financialplanner/storage/StorageTest.java b/src/test/java/seedu/financialplanner/storage/StorageTest.java index 3cf6e14bd1..37354e124d 100644 --- a/src/test/java/seedu/financialplanner/storage/StorageTest.java +++ b/src/test/java/seedu/financialplanner/storage/StorageTest.java @@ -65,12 +65,12 @@ public void saveValidData() throws FinancialPlannerException, IOException { } @Test - public void saveNonExistentFile() { + public void saveNonExistentFile() throws FinancialPlannerException { getTestData(); assertThrows(FinancialPlannerException.class, () -> storage.save("")); } - private void getTestData() { + private void getTestData() throws FinancialPlannerException { cashflowList.load(new Income(123.12, IncomeType.ALLOWANCE, 0, null)); cashflowList.load(new Expense(100, ExpenseType.SHOPPING, 0, "shopee")); } From fd935efa5f9913034140bcfef5bebf058c70bd28 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sat, 4 Nov 2023 17:31:26 +0800 Subject: [PATCH 373/518] Add trimming of arguments from input --- .../commands/AddCashflowCommand.java | 12 ++++----- .../commands/DeleteCashflowCommand.java | 25 +++++++++++++++---- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index 48a291da4c..9711fcd582 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -26,7 +26,7 @@ public class AddCashflowCommand extends Command { protected final double MAX_AMOUNT = 999999999999.99; public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException { - String categoryString = String.join(" ", rawCommand.args); + String categoryString = String.join(" ", rawCommand.args).trim(); try { logger.log(Level.INFO, "Parsing CashflowCategory"); category = CashflowCategory.valueOf(categoryString.toUpperCase()); @@ -41,7 +41,7 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException } try { logger.log(Level.INFO, "Parsing amount as double"); - amount = Double.parseDouble(rawCommand.extraArgs.get("a")); + amount = Double.parseDouble(rawCommand.extraArgs.get("a").trim()); } catch (IllegalArgumentException e) { logger.log(Level.WARNING, "Invalid arguments for amount"); throw new IllegalArgumentException("Amount must be a number"); @@ -58,9 +58,9 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException if (!rawCommand.extraArgs.containsKey("t")) { logger.log(Level.WARNING, "Missing arguments for type"); - throw new IllegalArgumentException("Entry must have a type"); + throw new IllegalArgumentException("Entry must have a type."); } - String stringType = rawCommand.extraArgs.get("t"); + String stringType = rawCommand.extraArgs.get("t").trim(); if (category.equals(CashflowCategory.EXPENSE)) { try { logger.log(Level.INFO, "Parsing ExpenseType"); @@ -85,7 +85,7 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException if (rawCommand.extraArgs.containsKey("r")) { try { logger.log(Level.INFO, "Parsing recur as integer"); - recur = Integer.parseInt(rawCommand.extraArgs.get("r")); + recur = Integer.parseInt(rawCommand.extraArgs.get("r").trim()); } catch (IllegalArgumentException e) { logger.log(Level.WARNING, "Invalid arguments for recur"); throw new IllegalArgumentException("Recurrence must be an integer"); @@ -102,7 +102,7 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException String line = rawCommand.extraArgs.get("d"); if (line.isBlank()) { logger.log(Level.WARNING, "Empty description"); - throw new IllegalArgumentException("Description cannot be left empty"); + throw new IllegalArgumentException("Description cannot be left empty."); } description = line.trim(); } diff --git a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java index ed2fc24785..6b7c1fd4aa 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java @@ -19,13 +19,28 @@ public class DeleteCashflowCommand extends Command { public DeleteCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException { String stringIndex; String stringCategory = null; + int indexToDelete = 0; + ArrayList blankArgsList = new ArrayList<>(); + for (String string : rawCommand.args) { + if (string.isBlank()) { + Integer toAdd = indexToDelete; + blankArgsList.add(toAdd); + } + indexToDelete++; + } + int counter = 0; + for (Integer integer : blankArgsList) { + indexToDelete = integer - counter; + rawCommand.args.remove(indexToDelete); + counter++; + } if (rawCommand.args.size() == 1) { - stringIndex = rawCommand.args.get(0); + stringIndex = rawCommand.args.get(0).trim(); } else if (rawCommand.args.size() == 2) { - stringCategory = rawCommand.args.get(0); + stringCategory = rawCommand.args.get(0).trim(); handleInvalidCategory(stringCategory); - stringIndex = rawCommand.args.get(1); + stringIndex = rawCommand.args.get(1).trim(); } else { throw new IllegalArgumentException("Incorrect arguments."); } @@ -35,12 +50,12 @@ public DeleteCashflowCommand(RawCommand rawCommand) throws IllegalArgumentExcept index = Integer.parseInt(stringIndex); } catch (IllegalArgumentException e) { logger.log(Level.WARNING, "Invalid argument for index"); - throw new IllegalArgumentException("Index must be an integer"); + throw new IllegalArgumentException("Index must be an integer."); } if (index == 0) { logger.log(Level.WARNING, "Invalid value for index"); - throw new IllegalArgumentException("Index must be within the list"); + throw new IllegalArgumentException("Index must be within the list."); } if (rawCommand.extraArgs.containsKey("r")) { From b75a5898db6145059726c39bf06cb02f9160a2b5 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sat, 4 Nov 2023 17:48:09 +0800 Subject: [PATCH 374/518] Add listing of total balance in list command and removing of extra spaces in user input --- docs/UserGuide.md | 5 +++-- .../financialplanner/cashflow/Cashflow.java | 10 +++++++++ .../financialplanner/cashflow/Expense.java | 1 + .../financialplanner/cashflow/Income.java | 1 + .../commands/ListCommand.java | 22 +++++++++++++++++++ 5 files changed, 37 insertions(+), 2 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 012410dc7a..b5e908e145 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -66,8 +66,9 @@ you a one-stop interface to access a plethora of features to manage your finance - Cashflow refers to an income or expense. ### Notes about program limitations -- Maximum amount and balance the program can hold is 999,999,999,999.99 -- Minimum amount and balance the program can hold is -999,999,999,999.99 +- Maximum amount for each cashflow and total balance that the program can hold is 999,999,999,999.99 +- Minimum amount for each cashflow and total balance that the program can hold is -999,999,999,999.99 +- Total balance is separate from Income Balance and Expense Balance, where the latter do not have the same limitations. ### Add cashflow diff --git a/src/main/java/seedu/financialplanner/cashflow/Cashflow.java b/src/main/java/seedu/financialplanner/cashflow/Cashflow.java index 0f2f45acb7..fa3cfa617f 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Cashflow.java +++ b/src/main/java/seedu/financialplanner/cashflow/Cashflow.java @@ -12,6 +12,8 @@ public abstract class Cashflow { protected static double balance = 0; + protected static double incomeBalance = 0; + protected static double expenseBalance = 0; protected double amount; protected int recur; protected String description; @@ -101,6 +103,14 @@ public static double getBalance() { return balance; } + public static double getIncomeBalance() { + return incomeBalance; + } + + public static double getExpenseBalance() { + return expenseBalance; + } + public int getRecur() { return recur; } diff --git a/src/main/java/seedu/financialplanner/cashflow/Expense.java b/src/main/java/seedu/financialplanner/cashflow/Expense.java index 1eba4bb451..3fda463e4d 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Expense.java +++ b/src/main/java/seedu/financialplanner/cashflow/Expense.java @@ -49,6 +49,7 @@ private void addExpenseValue() throws FinancialPlannerException { } balance = tempBalance; + expenseBalance += this.amount; } @Override diff --git a/src/main/java/seedu/financialplanner/cashflow/Income.java b/src/main/java/seedu/financialplanner/cashflow/Income.java index a75e2f8694..6a76dfdb78 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Income.java +++ b/src/main/java/seedu/financialplanner/cashflow/Income.java @@ -49,6 +49,7 @@ private void addIncomeValue() throws FinancialPlannerException { } balance = tempBalance; + incomeBalance += this.amount; } @Override diff --git a/src/main/java/seedu/financialplanner/commands/ListCommand.java b/src/main/java/seedu/financialplanner/commands/ListCommand.java index c7e8b1e062..f3f7858a27 100644 --- a/src/main/java/seedu/financialplanner/commands/ListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/ListCommand.java @@ -14,6 +14,21 @@ public class ListCommand extends Command { protected CashflowCategory category = null; public ListCommand(RawCommand rawCommand) throws IllegalArgumentException{ String stringCategory = null; + int indexToDelete = 0; + ArrayList blankArgsList = new ArrayList<>(); + for (String string : rawCommand.args) { + if (string.isBlank()) { + Integer toAdd = indexToDelete; + blankArgsList.add(toAdd); + } + indexToDelete++; + } + int counter = 0; + for (Integer integer : blankArgsList) { + indexToDelete = integer - counter; + rawCommand.args.remove(indexToDelete); + counter++; + } if (rawCommand.args.size() == 1) { stringCategory = rawCommand.args.get(0); @@ -68,5 +83,12 @@ public void execute() throws Exception { for (int i = 0; i < cashflowToBePrinted.size(); i += 1) { ui.showMessage((i + 1) + ": " + cashflowToBePrinted.get(i)); } + if (category == null) { + ui.showMessage("Balance: " + Cashflow.getBalance()); + } else if (category.equals(CashflowCategory.INCOME)) { + ui.showMessage("Income Balance: " + Cashflow.getIncomeBalance()); + } else if (category.equals(CashflowCategory.EXPENSE)) { + ui.showMessage("Expense Balance: " + Cashflow.getExpenseBalance()); + } } } From 661114625fb9eed2fa268dcb1353f6d0a185d563 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Sat, 4 Nov 2023 17:51:15 +0800 Subject: [PATCH 375/518] Update diagrams, DG and UG --- docs/DeveloperGuide.md | 32 ++++++++++++++++++++++---------- docs/UserGuide.md | 2 +- docs/diagrams/Budget.puml | 7 +++++++ docs/diagrams/Storage.puml | 13 +++++++++---- docs/diagrams/deleteBudget.puml | 7 +++++++ docs/diagrams/resetBudget.puml | 12 +++++++++++- docs/diagrams/viewBudget.puml | 6 ++++++ docs/images/Budget.png | Bin 20225 -> 24926 bytes docs/images/Storage.png | Bin 20785 -> 28321 bytes docs/images/deleteBudget.png | Bin 10779 -> 12992 bytes docs/images/resetBudget.png | Bin 20366 -> 23981 bytes docs/images/viewBudget.png | Bin 10236 -> 11422 bytes 12 files changed, 63 insertions(+), 16 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index aea8b16f3d..cc3d531868 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -88,13 +88,15 @@ API: `Storage.java` * There are 2 main ways to implement the storage, one is to save the data after every command, and the other is to save the data one upon exiting the program with the `exit` command. -* Saving the data once upon exit (Currently implemented): +* Option 1 (Currently implemented): Saving the data once upon exit * Advantage: Better efficiency and performance of the program. * Disadvantage: If the program crashes or exits incorrectly, data will not be saved. -* Saving the data after every command: +* Option 2: Saving the data after every command: * Advantage: Changes are saved after every command. * Disadvantage: Executing command might slow down the program when there is a large amount of data to be saved. +Option 1 is chosen to prioritise the performance of the program. + ### Visualization Feature This feature is implemented with the help of [XChart](https://knowm.org/open-source/xchart/), a simple charting library for Java by Knowm. @@ -277,16 +279,25 @@ Example: budget set /b 500 budget update /b 1000 ``` -The '/b' is followed by the budget amount. The first line will set the budget by calling `setBudget(500)` method in `Budget.java`. -The second line updates the budget by adding or subtracting the difference between the initial and updated amount to the -initial and current budget. This is done through `updateBudget(500)` method in `Budget.java`. Both functions can be seen -in the diagram above +The `/b` is followed by the budget amount. + +##### Set budget: + +The first line will set the budget by calling `setBudget(500)` method in `Budget.java`. The `setBudget(500)` method then sets the +`initialBudget` and `currentBudget` variable to the input amount, in this case 500. + +##### Update budget: + +The second line updates the budget by adding or subtracting the difference between the initial and updated amount to `initialBudget` +and `currentBudget`. This is done through `updateBudget(1000)` method in `Budget.java`. In the example above, since the budget is +being updated from `500` to `1000`, `500` will be added to the variables `initialBudget` and `currentBudget`. Both functions can be seen +in the diagram above. #### Delete budget: ![](images/deleteBudget.png) -The budget will be deleted by setting the initial and current budget to 0 through the `deleteBudget()` method in `Budget.java`. +The budget will be deleted by setting the `initialBudget` and `currentBudget` variables to `0` through the `deleteBudget()` method in `Budget.java`. Example: `budget delete` @@ -294,7 +305,7 @@ Example: `budget delete` ![](images/resetBudget.png) -The budget will be reset by resetting the current budget to the initial budget through the `resetBudget()` method in `Budget.java`. +The budget will be reset by resetting the `currentBudget` variable to the `initialBudget` variable through the `resetBudget()` method in `Budget.java`. Example: `budget reset` @@ -302,7 +313,7 @@ Example: `budget reset` ![](images/viewBudget.png) -The current budget will be shown to the user through the `Ui`. +The `currentBudget` will be shown to the user through the `Ui`. Example: `budget view` @@ -329,7 +340,8 @@ Example: `budget view` ## Glossary -* *glossary item* - Definition +* *Cashflow* - Refers to an income or expense. +* *WishList* - A list containing goals/targets. ## Instructions for manual testing diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 208749fd39..a9c3ceceac 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -51,7 +51,7 @@ you a one-stop interface to access a plethora of features to manage your finance ## Quick Start -{Give steps to get started quickly} +{TO BE UPDATED WHEN V2.1 IS COMPLETED!!!} 1. Ensure that you have Java 11 or above installed. 2. Download the latest version of `Financial Planner` from [here](http://link.to/duke). diff --git a/docs/diagrams/Budget.puml b/docs/diagrams/Budget.puml index 11ba20e9e8..0e7322fb9a 100644 --- a/docs/diagrams/Budget.puml +++ b/docs/diagrams/Budget.puml @@ -1,5 +1,7 @@ @startuml +autoactivate on + participant ":BudgetCommand" as BudgetCommand participant "<>\nBudget" as Budget participant ":Ui" as Ui @@ -8,11 +10,16 @@ participant ":Ui" as Ui alt set BudgetCommand -> Budget: setBudget(budget) + return BudgetCommand -> Ui: printSetBudget() + return else update BudgetCommand -> Ui: printBudgetBeforeUpdate() + return BudgetCommand -> Budget: updateBudget(budget) + return BudgetCommand -> Ui: printBudgetAfterUpdate() + return else delete ref over BudgetCommand: DeleteBudget else reset diff --git a/docs/diagrams/Storage.puml b/docs/diagrams/Storage.puml index 9b856c158d..073899ee00 100644 --- a/docs/diagrams/Storage.puml +++ b/docs/diagrams/Storage.puml @@ -7,24 +7,29 @@ package Storage as StoragePackage { Class Storage Class "{abstract}\nLoadData" as LoadData Class "{abstract}\nSaveData" as SaveData -Class CashflowList Class "{abstract}\nBudget" as Budget Class "{abstract}\nCashflow" as Cashflow Class "<>\nExpenseType" as ExpenseType Class "<>\nIncomeType" as IncomeType Class Ui +Class Lists } -Class FinancialPlanner #FFFFFF +note "Cashflow refers to income and expense" as N1 +N1 -up-> Cashflow + +note "Lists refer to CashflowList, ReminderList, WishList" as N2 +N2 -up-> Lists + FinancialPlanner --> Storage Storage .right.-> LoadData: uses > Storage .left.> SaveData: uses > -SaveData --> CashflowList SaveData ..> Budget SaveData ..> Cashflow +SaveData --> Lists -LoadData --> CashflowList +LoadData --> Lists LoadData ..> Budget LoadData ..> ExpenseType LoadData ..> IncomeType diff --git a/docs/diagrams/deleteBudget.puml b/docs/diagrams/deleteBudget.puml index 4a8eb03a13..e0a3d734fe 100644 --- a/docs/diagrams/deleteBudget.puml +++ b/docs/diagrams/deleteBudget.puml @@ -1,15 +1,22 @@ @startuml +autoactivate on + mainframe sd DeleteBudget participant ":BudgetCommand" as BudgetCommand participant "<>\nBudget" as Budget participant ":Ui" as Ui +activate BudgetCommand + alt hasBudget BudgetCommand -> Budget: deleteBudget() + return BudgetCommand -> Ui: printDeleteBudget() + return else else BudgetCommand -> Ui: printBudgetError("delete") + return end hide footbox diff --git a/docs/diagrams/resetBudget.puml b/docs/diagrams/resetBudget.puml index a21b3c7506..4c082bd9e4 100644 --- a/docs/diagrams/resetBudget.puml +++ b/docs/diagrams/resetBudget.puml @@ -1,21 +1,31 @@ @startuml +autoactivate on + mainframe sd ResetBudget participant ":BudgetCommand" as BudgetCommand participant "<>\nBudget" as Budget participant ":Ui" as Ui +activate BudgetCommand + alt spentBudget opt initialBudgetExceedBalance - BudgetCommand -> Budget: setInitialBudget(balance); + BudgetCommand -> Budget: setInitialBudget(balance) + return BudgetCommand -> Ui: printBudgetExceedBalance() + return end BudgetCommand -> Budget: resetBudget() + return BudgetCommand -> Ui: printResetBudget() + return else !hasBudget BudgetCommand -> Ui: printBudgetError("delete") + return else else BudgetCommand -> Ui: printBudgetError("reset") + return end hide footbox diff --git a/docs/diagrams/viewBudget.puml b/docs/diagrams/viewBudget.puml index 02c0d77042..fbf7287464 100644 --- a/docs/diagrams/viewBudget.puml +++ b/docs/diagrams/viewBudget.puml @@ -1,14 +1,20 @@ @startuml +autoactivate on + mainframe sd ViewBudget participant ":BudgetCommand" as BudgetCommand participant "<>\nBudget" as Budget participant ":Ui" as Ui +activate BudgetCommand + alt hasBudget BudgetCommand -> Ui: printBudget() + return else else BudgetCommand -> Ui: printBudgetError("view") + return end hide footbox diff --git a/docs/images/Budget.png b/docs/images/Budget.png index 89c18a4ef7f39a34001b75436f6c1668e8075769..2cad026630ebd80ddaefd44095eee63fb86f0dc3 100644 GIT binary patch literal 24926 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 literal 20225 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 diff --git a/docs/images/Storage.png b/docs/images/Storage.png index d0e6ec236b05e1c93e4e2c0d15ae2c492d6270d1..f5c1901f13cf9b378409dc7656ce5332e8ddaa3d 100644 GIT binary patch literal 28321 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�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 literal 20785 zcmeFZWmMMf*DVSnprn9w2}qZ8cXx<%i8KgEHzLyA-QC^XfCAFpE#2L{FP`VW&)M%j z?>OJi7-yVuzKC+e@4jNKx#pT{-UcelOCTfQAwWSvAxlY$DnmiNu!MqwCVTY)dDGimY=Qc9llyJe6jxO zIMhcB1qJiUOhw)Pe|{ed8a&52sn)F*Y zf`X$l4=XTrR-Rhq{-`c?+}iv5sD;I&L-)3`#X@%3MAopLEnlWUM^u!kfI!)` zYi9mqvOEW}zjP{e6zL7e*{o1SgI`|CN8RkWF`)aY&J9Y3$Y-2yNVa>_t!iSV#iTNbyw~R&$$?|e0_U1c$SJIiIu|A;mGVn+X8n! zgD#zciJ+gp)5RNw3R5;{(Q0D$=0`8zbX&Q%WdwmSEFv!#bmX6mgcW7`W~Wty*zY4B zJY?TF74%x)x?|4x_2r@?hU3epNu7B0!ea27jN)if363uI-$&4kWRKFnrl`XXTV46h zXRuweexbbDh2Lh2l8u z)e)?5W~sItweQKbbw=r0Njalm@vCI-IvCY5iKF-G7WEK57=#?5w571e)Gk3cgyqrA zMOS`)R4rRRPZohjPpvauQB=>|ckcabHj93`ogzXWZ=9z|XU&^;Clg?yu}Qv8F+Hh{ z;@}T>r2VCE4?c5vlU%&$E)=MIO46oPN4+B}E;Pu!PI|P3N|XT0XWp7N`^ReXVCe_! zDaprSjhswlE`Kf=G8W(1-oT(pN*PsO8m!}6O^jn?jL$!1^nZOT9nNKCY1Bky>SR%L zrN7p`LA(DtdvwXI$33$Y&h}Kf`EAt0QM-yiDn)wgx@P{HdYs1)a=^M$&~#x^^{rcC-o(k&ldodjG`@M{x$W zL2vB9R-E=S3T^wz=d}?0fr4Y2b4SS_B?(kLW7^-j4>^Em5& zuTJ(5Co9WVB$EV!43I065*1Q$);&mtcgF0R>sC^#(1yenD~p{VqE|`{yBBLk_991Ou=0|x-n=`ffHTXy!qR*fA&8K3bqX=GNf}7vVa0ZJIK{SOQuvf6u}&m#o!|NpW7 zmmWw0N7mid(bf66`|&S$8R!fqLs274D5&jlJT~(X0xo7Ywok0_o1vx;w-+!lFh=xH zc;92eCBI4GaVj$zPD|x>K#$!F-R?jYNJ&klw}2jj!cl_yt|TcXMRG@FK7g;JS>Hzk zRRb;l7E1r!`#aMm_1^(6{Gp#u2kqVf)ne7q+o7IFvW||9@$qqmRPM(mZc>yzbYC4J{aT zTY8@Qf55`R@|_K^&}-Gbmy?$tN?`g@q*kt*C!1)J?onqkT{c~=x3%Kq;{*OG=i+=e z$k7`VT)4iWXX5DOlrP}w?5rqR1`qZ2b*0uK&s$VZ<#$ju9kC&%TSKXZM==aKOd`gD)H$8-#t#mJDMkv9^zl*z%na=HzFQ79B%M3-y$jJ7l%ZI;C3OwBm z3;Dq5G}`*Y>$`eh@8qYCWyZ%(U%0nGAUhS-%dG}~Ge!IT z_}s5QG@3p1y>Qx}iA0&Nw^ndza6Fj9w{9WHo6MF#wJle#B<17txY(V{{Yg6j^_`T& zamCGl6S~x5FSzZu+Zhhf!})Kw%XFF(%1vhiPB;3;R|-Go&#df> z=kHW#H`*HfJ=+>SJ9fFTCd_6#JYMPGXFP^Lu2GW@cr8|0wzrix@y*XMn@1PZIHK}t*!I*T&+d4 z@$uhZ`0SS8ypnM6gM%2gG*lMi>0Q1U7|f7BwHyC$4~K? z){9LS_h-W_dtEMnz2SfS_@NGUX{cD(mbTYuzcUuCz)uaAHy02RV(6XdCn0aYJtBlO zkhY&I*+a|9s^ZRFZ#JGc@awU`WSD5QUgdEJ_n&t-wsLq<xT9nubQ#rj(B!bk%)$bWlgH)MklWtLDZT?5DhU2xlyY3j4(B(ZRf{}X z>+WBHg6hhC3tqtdkmX3i#B_2tEKsi9cna`PyUBh>I+i9Bk1dGL?j=+O-~j(E+`&E< zO+kQz9{;zf`2Wz4QQDoXik&DjXGJjr)JMQk`fIp3m|SnY%T%#OoP5#^8>ER8}og>Fw^8KtVttV>p!@TcoX;G9CFIk%sl$w%!|U$WyFZD(x6UU?|id&!|_X-B?lafs3j_(p7pO_M_(n zN^I!3jc|vss&SRJFqFODS*WSJeBN?`e~eB~2Kx2cxb16i%$D2TVnfcwg@vAgsGIZC z)7$Or@O8nA4+R{svd*%zbfHwNbPa!CY5vY}E(f6ZJ$^Bb42Cb!2b(tJp;ayE@zkob zY_ynW;CfT>!pMiUtj7pO(5pRQPH%k`dappEdNcUO{$OqrWZ)&-RHkLbAIwHesBKgn zrMqD5met6F1gc`~7^!FqCbBtj8sEP|&Caj9r^G+?OQ{mVQ(Ldn@W;~0Q{k_|g7WoX zU6!t~;_DlFUV{k+>l-?qrW%jCOAxk^585#yAt4~NAdk0u7kkr`_4@}l1)Ey6=4@`4 z`^U#NvkKi*_&MLi7?K@E0<*(J7Q4fyCh*Ac(9u^nHpnf!i($yjy&{9v-X zSu}hq+b-vXM*)VCT2(n)?RPdmtOg=i)~tCs>ve1U{!flHl}^;LSccPmS25D_KPAMt zWJ3_=&--bWp&Ff4+bvDz>%JDwj~6_Qh@e)YnAK?oNgwjtu1ogE(VI1R?H1;n{%vr* zprMYAin=}D5kXTeQ2abmproOpVNUXujFya={6ySp2x595Y;SL0s#&{#{R6g73*3H5 zZCIOvAV1?esL#WSv2d`kQrK=9IK5x%ifZ|(l`UB9t)u#l3BA&*m2(Sdl|Fr}&l)nC zN~+Qa5$1I{YXV?naGq%VdDHZoHGloHra`HtQ7us~RL%wb#FjjJq`LRV*V!uHIl-IL z4X?+WEn=_x$Rw<;IhoOUoiH*9R_vb$QL&9cd+!Kqn#aD_s!W>p-I$Q?X)i0 z1}K@md`^c8dR`B)1j}Ae5KT$^cZkvuBWoM$rxT;tTEpsl)@!ufG2;{Br|pX~3)`yk zjRh^}Vl8qIcbR&4neHAQcD9E{zw~vZ<}E*2xGJB%Jy;llNYNz4R@}zxrv`K5IdB;L z^@f2TN@VdTfPq7LbK&jn4d7%G93LP@bykbgVdj%Xfw#Q0LllTN%TJF^Pmd1+dKc7oYq~aApY$*K;Ztwlr{Z$9}wJYk`f->g$tLg`=Wj70Sa} z$Pn@w%aswh{_9iXVVBdM71eAODTVm!kvw$?Q2%od+7 zhBHyb7K6C49hhoksWkc$5^!usR+T4~A#PrT9VlWPslPxfE8m>Rd`93)=Jng(w>-?d zNXJQjK7r3a{rqmPuR)EE>C+2i*^ps`bgs61TZ5B{-xRfP=m2CGWFS( z;Q*oh&%a#9&?$#`Yje})YHpT|l;P#Lb82)d8nNAFc>9p7!c!I+FUciA=~Q`|CKdoj zS>mcJ#Af&Sq_+-htA8%ec-8fp=x>o1Ip4AHJ*r+4V@18=YWiX*E&S49zo&nGYM`hn zM7ocDIC)T!Qm;Z^sKXB#RP4{5N@@rlv5k$53lR4kTTT4R4wEz&39(Wwu?-j6D<{&YSg;vZ9?2R2KPVJdhydZ{7BA+3InZ5RXHN zNyEbOv2d%R#?r?R76Re*_oL>Dcl1?Tdk{JKP6k`W1KWQu=;+8T5E9Jos(<$P`|EJV z^z-$~)a5)1F=oDpy~Bg(Uv}ooum^g}N9*YV%zPIvyEp5v60SSF<$Mms(>GUKQr25- z$3&s0hRUo+UgP1J8fNOV=8b4mu%AXS)1Wie^9r71TD6&uW>Lr`QKb(V{fWK3Pvvn^ z&o;RQAsiPTouVPc_h|%hh@XTJ3@J=&(X1Unl#c zktqyo`%#LFl(a;upS_c%03)*6RLz-fN#LI@qnRvj%Gz>g{o0~W^W6!tnx6o%(9@jp zsqx`PblR#1GatF}@SJYnQ&3@q+rxcR--o;(Qk`OinU#XL;(a!@?wlJM2>KE+FhYRY z?}Y5nRDN0SiEN={wU`Pa0Hl`FVfQT;FE6j;Y`LC*?Rbs-beYb2Mx+>h&Q~g0iS*|! z2GuC2q*HcnLkjhKOT=c4=-TC{zC*)o4yP-G0gfBwN}XVI_1u>z->7{@IxRbXF#v|K*hXD2(PAM=aeUk4Fo? zb_{On@25iY{;Zh1h(6Tb^zN;6UlmB0w;m8l+<83!v2&3)Z9=O{Gae!FJ_?AXYRcV< zFplo&lRd#d%fOMv#q6COp{8^U%}WV}X7#=OgUHyT25V@ zq);L(#%%e7ZQZv$M5o zOojGFHL8tc(GS~_nzs-r3aC z)8Sh)B1#~*7n^5w7#xsX_nNI}XR%*1!49XFmTLL6HL6Ur@RcNR;M{p!0X2YR@X=#q z-AgGg_gdyvU*Bkc&yAy5r!qc-MqLFuu;%vAhwHSN@(!*VTZL|Ig!W(RC z4(p|sU~I-dqCcW^7rzEYtbUf}`y!@Bwx>TeE|xo3u9I-Xw#aw3qhN6@`}u03)DnC4 zj?x+Y3SCM@h?B*TjzL=lS_NQbL|*qN&+W{Y?l7P##EYnRCT+&6g``?1Hj+ zFjsqZFi&}hi&Z&c&(MkAk$3MaDZPqZt7)6lbHmO&;kmG|!0mMCe!i_V%Sc?f?{_F? z(DZzc`Geg zL$9e{Pn*e+8LxGgJ>}+i=1_>GF7aeuqq^*3nTs*D-80t~09Y9dbSR@jKUS7%iH~&8BA*(V zAJ_WRkW*!uf(x5*EZ-F?W(qgjZkSIL2w|{2F5>H&Q-Je@MMOS-(M&J~LIrODkkpxG zr=w&JYg@gI-dg2>$9USoTTNYI8NEWqkl>o&pn{I-~JZf2^@bY0M9odKS=9 z_{F9B@hU@H9W+T*%Cr;N81XinoQ{STNLyQ5ZN=6%B9&3{rz3t=U2C&H-O|u=SZgoz zpq%}z2GZmZ@kGuAyqA<*+9VIkO~1ZbWZ%Wu7G72Lm@}^!O+0~oH_3dBS;v++fNOFd z={*>8Zv#R+O$3#fBgF18*%wsEu9HQdc$|+P$-b~lKGMPhPOR6GJ;q!112DOG;2&( z4i4n#2lx4uc1Co6XJb}(R#;m{eSyFIPDe$L1dsub)l^Ur3`R0@m-0*bstC+c)QjC< zSd_-kkgO*@ajGlQ9FRbOy?f(M)|iy=kgX9J9IpVhE;T)mjo){oQkSK7P6MGM10kLJ z`{z9M3j12i@os_h&<}rjosE}sKu`F7dImdehPL~ zED2Frd=RI5$Y2<*6x!!KRXO_Zj(&i|mf1wLg z(U9mOuV#Io_1ns5QP=Q=FQJ0&~Z)=Vgrb1o=y&ubhH)i7j8qP)E^e z0E3|Oo}EsT0faU;5}~XFIr>&rN2$|K?o9Jh^xUy+idVDtdT{sawj3-19MX@|8g89+ zx;e~6TqUI(h#y64s1LX;VGd96Fwk2rwA3V0PdXwOkyGvt=8-;(TK==qIL+bz^7v@! zj-llu`zOe;w}8Olh51RaYc-m*7c0IWER3HBZ#6gC^RA}FCsb_8Gw1&N`YHoKKhi$M zKYKG+?sa9|9|LwZ8MWqGtI{b@|<)Y%L3Ol>%8);Vk z-)q|CSYDa`?V*9Ft_}6cyD#Q86f!$d{iyh)W9Dszd#*?c%rGK(K(CDS#JMt5_3(mq%oNA``@pfjxT|OMjPKb;HM0_Enu<8L19IWNg5I#upL0 z^=iq@%E}5T9onFZ*`7Y2+A&8yMTGyGCc6APg%xCH;~xzQLo2x z;1KXS9|IjeAS^77PeqYkaxF-k9qJrDq~Jk}fe1?MXIugh8gDj}t$F$QAT2GPK=~40 zuKlC*zy2gSAD<2b36yHJK8a95#WVULe@M;4Ps z7eHz6{PU*|7Vcd-=&VKjQF=AC0>i_Jc^vl#5?Q)Jb^WmLunIU;3V!~4*;oU$4Y!3q zdLFYa;L}9g9DzpeEMNL_#;!!W-fHpoa^AW(CJdM5&n>=Y`-YUfJW#54=j+RpleK_G zWptDk9T&&`%|=_Zao02SRyUtj+OTOA0S z6w$ro<7d^w{LSt+OU3hNhit#?clHo{g)Iy;Hr#FP><+E}f~gDoAUmj~6_&Hi)y=L@ zHl$4-vhX4k6S=<5v1(|E8V{#=taiQzf3sR@xw)9uYi@2lNr@?Ei^RD*-b z?2xOf{nZMieypS&>@6YGA)rEgxV!hn+}_?|d11Z~Jke5;mX-!|z*K|I?QL?p=dBr# zY^&;K{@S99;Fnp7)_bEmr!(?H})No;A&q+Q6gM zyE2JzA`J~kH{>-i@8f^Ew?jn@2Xn;vlUpJi1SKVGO@niNmDav|1+g&5~pF$8x0HV0!<+DQCL9Ryamgb2*tbDD{t%5Ozs&P zI$Uh74-XIDSK?*RYXzC}7ZAW9Ky}H<#V+B*-!U^+fr!v^Kk+>$b$0s(fB>{0QJY%W zjJh!oLBA4Np0_Ger*T<9%*s=uR=(6|ca^R-{VFIOK{)l{@?gG-7;0{SX)GIO+()oeVya42UAX1ckDxLyC8SIsg^PLnNW{py|_;Zh0 z+a;J?8TAbu?c>8;GwJMJH`n@j zYoSpLJrM;kVke=PE;2HbOgtom{BD1?`oNQm5Q8y_E^ z7Z?={49L#na}pTy@Hp&>(hB2cm+L}k{71g8udjm@nb{Xx_ePPIYSlY_VzC3h0C14# z!?;lXV8s&+DclZ4PDe|~c&r&GD0vea`%94I`Jsr2H*)17oJi)HHLBGskV`12>h^%$ z__glvE3h7L8=jt?A9BMe>F5TGEGfyDm@2`ba&M|Mnhy%9?gg1SPvT9Frkfp5w}|*$ zTTc6Ep`oG6STptzD6LlVFAf{Ntr?cGyMsybvin(R2|ccC66?4a)uNNd6lf3P^+0rt|H3+7?FxRly8?C()M0O zOc1WR4K|r24siBZrf_r?&{W)IW}@Lld~msFqcZ}-Z-&ee?emMSKFn<`dAP3H8bT}cwR2Th(2JZfC6COQs| z^X<8r#vWDAk0`?2$|%dCeYM{iVoSi70OkfT931sv%mIWZ9h4Qp9{brV2M@80&Oi+L zHcT2JLOYPtRjR}}IXQm|`4m;O#{cd{8^hZaMSLjWZU^_ne%ZC=aQt+JE~Z zf{{{TJsu2qH(Tg7P)}9Mb?Gf+pnwc-C;+Z#5{wx^1b)19bTGaAn=oCYX}s9v0ESu4 zPY+k&1YD$dToE9#z3vX`t5o4bKtK8W=WDQRMGV)y(t2Q0PtgUK96W4Zl6a5uDG1646^I2Q@|7dTL}`MT0^#(zThwhkouySPvz)7;4uyqBC5nL{ze@ZG ztO-a&yfcG?gNDq#OWgW16`$porJ}B;5p5kDXeVq8jf`$?Zjf<42wp;EyaQp7+KPmX ziYoAJ^(TlAR;-sVUp^-+unu|Kl{3sCVSWZ7V3=+W5@N~ih+e0Om7QG`<>liG#va)A z$c7BGNfm=WS!p^-%E-tFZ(UrElsMKEjLl&>@{FM0lTj+X47K*IcmRXh>=|a2j}BulNH! zr;o_>hq0I;|1(lX9UTFT zKEv{?2z*X{{%|q}__r$<&e;;%l4yn`D<;J)T`GfP_E>qr82*(I&ApOKPkZ z=a!fCE=S-C3k$1_2eZsBfN;&I*GlJRF#t*$m_S|tb?@nXT!B&{Ee3MY2><}p0JGmK z*P2yPz={+~z@b@rLemWzN`!!(TLhqq z$66@Iv4^(4qV{0GSWF#|BdV~}<%ETQgVYBz8;LLije8S!s=Dvrzk`A?QLHvBSRa;h zx3owanUb;q)Vb`o^{S8g@*s(-rh4?hYTDYck#Pfw_^9nkcj^bJEzn0nRRV?k4vdIH zgMy+Uh&~}BNo*E?q;=@RgQdD=Yn$tVlT$E^{X^R!rfA0*e6Ta?Ya6 z(7E8`c_1x+!%J%Oq0Csc4R{4WRQ7A?V|@Ge4REP1U{r3ZtDNI+43CTlhEc?&Ko8w2 zm&9yzzc~d^0;qjForXcos5_`V)-5M~N)%LanLF0*?ky#3bQ7l@9v)!7W_Wmjw7bDz z|DFulzB_6wKO1Iz7N_Wewbai#XkUNU+d=S)s zQ+eQGIsoUi*l6cZjY`bF|KiA$Fg?8TPeV*hOdP#dnP#o@CDg5tcn%twxMFuC-*=h6 z%HphCT#aD(4B)ZKe<%QW>Atji+&RvQT#aOX1r@%A#$zkh2@hm^mRK;L!hPP~FWtc* zf(dkdEfkdh8h8RN?H+*LD%E%baJwBHBEwp!gUnz4AX!^mCqcKI{J{sPdwOxfHuYkN z?bWMS$ET;vBe5n>+BosdS$_;bX##$rs+CzaN@kF6BO{8ND5$8!?3Orkuz7OH#sTmF zz!3NF@Nm!yJN0XXwNgHnd&uJ>Sp^~*8XE9;#niT&wg+%W1JXD)CqIQ31l$FvxXeFg zsb|&rtjlw#WxyFNc|CcE2n33-Jr_B6IJiC{22pTpMEsVAP@qIl6@4mpTK1TxIy!h^ z?2QHs+tbrCQ)BiKv^e<+=?r&;B5`Ja+r7bH58zGOlB4#|pFeB9&es89bUorBFu3`xN(Gz0#>s> zS6kfH)`rZ%Gn_7>*v>x_p4kz-w)AhrxB0S(%+J(& zugTEZSUEnEYkMS9B(zEb*G6CT7esB{&D9kcEUf@H?P`;712M(#ajW6y6)nz3IY_{(00@{a?D}aCQ z1VLMAXJ>bJ)%J9-P+qtX`diQmfr3t1tj}m6(Ur*OR_E{E4ZI=_k4+Nu4fZ?Az~noW z#z*V+9UW${)C@(Mkdl*A{St<|-66yjz`xEHw^z&h|<_wr#)gO2~;TaWBS^9lBT0YhSj>W}?h zHiTrm8ygOr1GpL%f~Ge!fG~ms?k8gC1pb;)U}v@9a?Z5&VmA9_bRy6`u#^JJ0R^k&e&ZTUC3L}tLG<@$>cmHqNuUsLDo({&0tEw$PQ85r04`{*Y@v_P zhXHQ`WR?Yp3LT5%-=L8!MGF~6l?V3WMS;0M`#SLtaH2IH^JS)_q-11d07<(Rly7@a zP#*|y9AD*&j0b@BH@1LO3#PPYce1$q@Xg)bT^slSfo%Z#FjxR6KPsTAf#Q_xAu$7P zn56hS--ik`azN7f%vo30gEfbNzu?(G9gIVgK@u1ms#9aC1kyDJ`|Zf9(|*Rb06dt_ zgZ)^~Mi7%@A5{K#ALl@$5OtPGwScfeRWE>y%WMetuA8q+a0}xM?xKb=YCj?qEl}oBZMW?)P z>C3x_sHlL#hX({W1D~C~D1Eilk?uw*Ly;7o@-c;2^A}69q=W?ZR`(lV9hObwZ3Hy3 z#=Q`@N`d5HwV-AQBBvCbsUZvC&*Wtl80hFNEiE%&N$`Zg;Lo&^wrQgBt8*EkK+zO$ zK)J~hy9vagG_+QOt{09S=?iRv`P2_umu(v$$pB6CCt7Wyg1|!!D2xm@R*aMemSoZZ zIQ(2ya;0NUA;KuTw*IKZaWJ_4fVLDuc;c~4($dmuq_YjiT7KCqpFca}0hh3>doYv+ zodib_bP|2z60E`k!ly5wrhF<=$z)f^_XHjhWPEmaCSopviXWix6>%4d)UfgxIFmIw zpR5AgSEc7|<7j@W2c8%1SC$z zF_}Byj>n?ce2yVdQgBb)qK&Ozuc;OonQo|*>+LFbtjaHy{5+d>wM^Gk(t4xC<(?s)0~cl#{W;U;@=Acmyz77%LTG`VVl zL0_lGsE0)G^T>>(%nb+z#e+{}+Af^|XtuBPF~A~3&o&1OHAW)L=L0NR%%^oGUm+vs zChCJ@?eUbX=SB2Y)d#wRToP-cW-SfAsHtz0?S?d03d3t8q#RtR()T^P<3+)A>G}Ej zy@oXQ^j5e~_Nsv{Y6zbb4`t`(u$=5g9<))pAM;o`tpecx>cbprBRhDZP6A zdS@gPruom^5YJK1(yfnb5S#hLJH$D_Fo04qu5I!s1Q#$pTTU%0DXGj?z^@O~J83M< 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 diff --git a/docs/images/viewBudget.png b/docs/images/viewBudget.png index fe7179a4eca52eb03b56809dba34af139498b383..ab4ac1e3f2020cfbd00869f0d7dc1aca1eeac5a0 100644 GIT binary patch literal 11422 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 literal 10236 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 Date: Sat, 4 Nov 2023 18:07:13 +0800 Subject: [PATCH 376/518] Add change for loading watchlist with more than 5 stocks, initallize stocks as null --- .../financialplanner/investments/WatchList.java | 3 ++- .../seedu/financialplanner/storage/LoadData.java | 13 ++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index ce9723dfa2..ce73640564 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -28,9 +28,10 @@ public class WatchList { private WatchList() { stocks = LoadData.loadWatchList(); - if (!stocks.isEmpty()) { + if (stocks != null) { return; } + stocks = new HashMap<>(); System.out.println("Initializing New watchlist.. adding AAPL and GOOGL for your reference"); try { Stock apple = new Stock("AAPL"); diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index ed8b2a0f21..a96a2b0224 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -323,11 +323,14 @@ private static String getDescription(String[] split, int index) { public static HashMap loadWatchList() { Ui ui = Ui.getInstance(); Gson gson = new Gson(); - HashMap stocksData = new HashMap<>(); + HashMap stocksData = null; ui.showMessage("Loading existing watchlist.."); try { JsonReader reader = new JsonReader(new FileReader(FILE_PATH)); stocksData = gson.fromJson(reader, new TypeToken>(){}.getType()); + if (stocksData.size() > 5) { + throw new FinancialPlannerException("You have more than 5 entries in watchlist.json"); + } } catch (FileNotFoundException e) { ui.showMessage("Watchlist file not found... Creating"); } catch (JsonSyntaxException e) { @@ -337,6 +340,14 @@ public static HashMap loadWatchList() { ui.showMessage("Exiting... Please fix the file"); System.exit(1); } + } catch (FinancialPlannerException e) { + ui.showMessage(e.getMessage()); + ui.showMessage("Would you like to create new file? (Y/N)"); + if (!createNewFile()) { + ui.showMessage("Exiting... Please fix the file"); + System.exit(1); + } + stocksData = null; } return stocksData; } From e0869ff64cb802872262ac17535ba0dc666dce95 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Sat, 4 Nov 2023 18:10:59 +0800 Subject: [PATCH 377/518] Update UG --- docs/UserGuide.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index a9c3ceceac..9d179dbfde 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -54,9 +54,9 @@ you a one-stop interface to access a plethora of features to manage your finance {TO BE UPDATED WHEN V2.1 IS COMPLETED!!!} 1. Ensure that you have Java 11 or above installed. -2. Download the latest version of `Financial Planner` from [here](http://link.to/duke). +2. Download the latest version of `Financial Planner` from [here](https://github.com/AY2324S1-CS2113-T18-2/tp/releases). 3. Copy the file to the folder you want to use as the *home folder* for Financial Planner. -4. Open a command terminal, `cd` into the folder you put the jar file in, and use the `java -jar ip.jar` command to run the application. +4. Open a command terminal, `cd` into the folder you put the jar file in, and use the `java -jar tp.jar` command to run the application. 5. Refer to the **Features** section below for details of each command. ## Features From 1c504785dbad5374bb86c5939ac72af99d14b6ac Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Sat, 4 Nov 2023 18:14:21 +0800 Subject: [PATCH 378/518] Update test file --- text-ui-test/EXPECTED.TXT | 125 +++++++++++++++++++------------------- 1 file changed, 62 insertions(+), 63 deletions(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 7cd2a194ad..6265123e09 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,78 +1,77 @@ -Directory doesn't exist. Creating directory... -Loading existing watchlist.. -Watchlist file not found... Creating -Initializing New watchlist.. adding AAPL and GOOGL for your reference -File not found. Creating new file... -Welcome to your Financial Planner. Type something to get started. -You have added an Income +Loading existing watchlist.. +Watchlist file not found... Creating +Initializing New watchlist.. adding AAPL and GOOGL for your reference +File not found. Creating new file... +Welcome to your Financial Planner. Type something to get started. +You have added an Income Type: Salary Amount: 5000.00 - Description: part time job -to the Financial Planner. -Balance: 5000.00 -You have added an Income + Description: part time job +to the Financial Planner. +Balance: 5000.00 +You have added an Income Type: Allowance - Amount: 123.12 -to the Financial Planner. -Balance: 5123.12 -You have added an Expense + Amount: 123.12 +to the Financial Planner. +Balance: 5123.12 +You have added an Expense Type: Entertainment Amount: 100.00 - Description: netflix -to the Financial Planner. -Balance: 5023.12 -You have added an Expense + Description: netflix +to the Financial Planner. +Balance: 5023.12 +You have added an Expense Type: Shopping - Amount: 123.21 -to the Financial Planner. -Balance: 4899.91 -You have removed an Income + Amount: 123.21 +to the Financial Planner. +Balance: 4899.91 +You have removed an Income Type: Allowance - Amount: 123.12 -from the Financial Planner. -Balance: 4776.79 -You have removed an Income + Amount: 123.12 +from the Financial Planner. +Balance: 4776.79 +You have removed an Income Type: Salary Amount: 5000.00 - Description: part time job -from the Financial Planner. -Balance: -223.21 -You have removed an Expense + Description: part time job +from the Financial Planner. +Balance: -223.21 +You have removed an Expense Type: Shopping - Amount: 123.21 -from the Financial Planner. -Balance: -100.00 -You have removed an Expense + Amount: 123.21 +from the Financial Planner. +Balance: -100.00 +You have removed an Expense Type: Entertainment Amount: 100.00 - Description: netflix -from the Financial Planner. -Balance: 0.00 -You have successfully added: -Microsoft Corporation -Use Watchlist to view it! -You have successfully added: -Gamestop Corporation - Class A -Use Watchlist to view it! -You have added an Income + Description: netflix +from the Financial Planner. +Balance: 0.00 +You have successfully added: +Microsoft Corporation +Use Watchlist to view it! +You have successfully added: +Gamestop Corporation - Class A +Use Watchlist to view it! +You have added an Income Type: Salary - Amount: 5000.00 -to the Financial Planner. -Balance: 5000.00 -A monthly budget of 3000.00 has been set. -Budget has been updated: + Amount: 5000.00 +to the Financial Planner. +Balance: 5000.00 +A monthly budget of 3000.00 has been set. +Budget has been updated: Old initial budget: 3000.00 -Old current budget: 3000.00 -New initial budget: 1000.00 -New current budget: 1000.00 -You have added an Expense +Old current budget: 3000.00 +New initial budget: 1000.00 +New current budget: 1000.00 +You have added an Expense Type: Shopping - Amount: 200.00 -to the Financial Planner. -Balance: 4800.00 -Your remaining budget for the month is: 800.00 -You have a remaining budget of 800.00. -Budget has been reset to 1000.00. -Budget has been deleted. -Unknown command. Type help for help. -Exiting Financial Planner. Goodbye. + Amount: 200.00 +to the Financial Planner. +Balance: 4800.00 +Your remaining budget for the month is: 800.00 +You have a remaining budget of 800.00. +Budget has been reset to 1000.00. +Budget has been deleted. +Unknown command. Type help for help. +Exiting Financial Planner. Goodbye. From 0a1278b9bcca357517b8a3614e78263237a9122b Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sat, 4 Nov 2023 18:22:13 +0800 Subject: [PATCH 379/518] Create new constructor for adding base stocks --- .../financialplanner/investments/Stock.java | 5 +++++ .../financialplanner/investments/WatchList.java | 16 ++++++---------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/main/java/seedu/financialplanner/investments/Stock.java b/src/main/java/seedu/financialplanner/investments/Stock.java index 08894ca4db..cebe213d6c 100644 --- a/src/main/java/seedu/financialplanner/investments/Stock.java +++ b/src/main/java/seedu/financialplanner/investments/Stock.java @@ -35,6 +35,11 @@ public Stock(String symbol) throws FinancialPlannerException { this.stockName = getStockNameFromAPI(symbol); } + public Stock(String symbol, String stockName) { + this.symbol = symbol; + this.stockName = stockName; + } + public String getStockName() { return stockName; } diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index ce73640564..ddf425c306 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -33,18 +33,14 @@ private WatchList() { } stocks = new HashMap<>(); System.out.println("Initializing New watchlist.. adding AAPL and GOOGL for your reference"); - try { - Stock apple = new Stock("AAPL"); - assert apple.getSymbol() != null && apple.getStockName() != null; - stocks.put(apple.getSymbol(), apple); - Stock google = new Stock("GOOGL"); - assert google.getSymbol() != null && google.getStockName() != null; - stocks.put(google.getSymbol(), google); + Stock apple = new Stock("AAPL", "Apple Inc"); + assert apple.getSymbol() != null && apple.getStockName() != null; + stocks.put(apple.getSymbol(), apple); - } catch (FinancialPlannerException e) { - System.out.println(e.getMessage()); - } + Stock google = new Stock("GOOGL", "Alphabet Inc - Class A"); + assert google.getSymbol() != null && google.getStockName() != null; + stocks.put(google.getSymbol(), google); } public static WatchList getInstance() { From 9430c212e5da1e1accb31fc83b212743d24e8650 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Sat, 4 Nov 2023 18:26:58 +0800 Subject: [PATCH 380/518] Update reset budget diagram --- docs/diagrams/resetBudget.puml | 2 +- docs/images/resetBudget.png | Bin 23981 -> 24291 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/diagrams/resetBudget.puml b/docs/diagrams/resetBudget.puml index 4c082bd9e4..62f3874bd9 100644 --- a/docs/diagrams/resetBudget.puml +++ b/docs/diagrams/resetBudget.puml @@ -20,7 +20,7 @@ alt spentBudget return BudgetCommand -> Ui: printResetBudget() return -else !hasBudget +else Does not have Budget BudgetCommand -> Ui: printBudgetError("delete") return else else diff --git a/docs/images/resetBudget.png b/docs/images/resetBudget.png index 4f1fa9a1d3a15777024f419f5e0b00e9102b8681..51c25e3004e0163075d8a7d8e5439d8662f5e243 100644 GIT binary patch literal 24291 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 literal 23981 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 Date: Sat, 4 Nov 2023 19:13:40 +0800 Subject: [PATCH 381/518] Fix typo --- docs/DeveloperGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index cc3d531868..fbd8f1682f 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -108,7 +108,7 @@ Demo: `vis /t expense /c pie` -Output +Output: `Displaying piechart for expense` A message will be shown telling you that the chart is being displayed From 2902393923606f19c5ed8b44297eb8e9322301c3 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sat, 4 Nov 2023 20:02:03 +0800 Subject: [PATCH 382/518] Add mechanism to clean up watchlist as much as possible to remove nonsense entries --- .../investments/WatchList.java | 38 +++++++++++++++---- .../financialplanner/storage/LoadData.java | 2 +- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index ddf425c306..40af3a071e 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -24,23 +24,44 @@ public class WatchList { private static Logger logger = Logger.getLogger("Financial Planner Logger"); private static final String API_ENDPOINT = "https://financialmodelingprep.com/api/v3/quote/"; private static final String API_KEY = "iFumtYryBCbHpS3sDqLdVKi2SdP63vSV"; - private HashMap stocks = null; + private HashMap stocks; - private WatchList() { - stocks = LoadData.loadWatchList(); - if (stocks != null) { + private void cleanUpLoadedWatchList() { + if (stocks == null) { + stocks = initalizeNewWatchlist(); return; } - stocks = new HashMap<>(); + stocks.entrySet().removeIf(stockPair -> !checkValidStock(stockPair.getKey(), stockPair.getValue())); + if (stocks.isEmpty()) { + stocks = initalizeNewWatchlist(); + } + } + + private boolean checkValidStock(String key, Stock stockToCheck) { + if (stockToCheck.getStockName() == null || stockToCheck.getSymbol() == null) { + return false; + } + return key.equals(stockToCheck.getSymbol()); + } + + public HashMap initalizeNewWatchlist() { + HashMap baseStocks = new HashMap<>(); System.out.println("Initializing New watchlist.. adding AAPL and GOOGL for your reference"); Stock apple = new Stock("AAPL", "Apple Inc"); assert apple.getSymbol() != null && apple.getStockName() != null; - stocks.put(apple.getSymbol(), apple); + baseStocks.put(apple.getSymbol(), apple); Stock google = new Stock("GOOGL", "Alphabet Inc - Class A"); assert google.getSymbol() != null && google.getStockName() != null; - stocks.put(google.getSymbol(), google); + baseStocks.put(google.getSymbol(), google); + + return baseStocks; + } + + private WatchList() { + stocks = LoadData.loadWatchList(); + cleanUpLoadedWatchList(); } public static WatchList getInstance() { @@ -60,7 +81,8 @@ public StringBuilder getExpiredStocks() { long currentTime = System.currentTimeMillis(); long fivemin = 300000; for (Map.Entry set: stocks.entrySet()) { - if (set.getValue().getLastFetched() + fivemin < currentTime) { + Stock currentStock = set.getValue(); + if (currentStock.getLastFetched() + fivemin < currentTime) { queryStocks.append(set.getKey()); queryStocks.append(","); } diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index a96a2b0224..63d37f1f94 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -342,7 +342,7 @@ public static HashMap loadWatchList() { } } catch (FinancialPlannerException e) { ui.showMessage(e.getMessage()); - ui.showMessage("Would you like to create new file? (Y/N)"); + ui.showMessage("Would you like to create new watchlist? (Y/N)"); if (!createNewFile()) { ui.showMessage("Exiting... Please fix the file"); System.exit(1); From f0080342f0796be89989456aae86f2e42ae3f188 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sat, 4 Nov 2023 20:02:39 +0800 Subject: [PATCH 383/518] Add to UG to warn user --- docs/UserGuide.md | 18 ++++++++++++++++++ .../investments/watchlistjsonexample.png | Bin 0 -> 49214 bytes 2 files changed, 18 insertions(+) create mode 100644 docs/images/investments/watchlistjsonexample.png diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 208749fd39..7655c75080 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -547,6 +547,24 @@ Use watchlist command to view updated Watchlist - Note: Your watchlist information is saved under the file path `data/watchlist.json` in JSON format +### watchlist.json + +You are able to read the watchlist.json populated by the Financial Planner to see the stock prices even when +the application is not running + +Example file content of watchlist.json: + +![](/images/investments/watchlistjsonexample.png) + +**Editing of watchlist.json** + +WARNING: Do not edit the json file unless you are familiar with the format of the JSON file +Incorrect format of JSON file may lead to: +- Corrupted file (user will be prompted to repair the file if he wants to) +- Deletion of stock entries that are erroneous (Financial Planner has a built-in method to remove +stock entries that does not match the format specified above) +- Incorrect information printed by Financial Planner application (eg. changing stock prices directly in JSON file) + ### View Reminder List: `reminderlist` View your current reminder list with reminders that you have added. diff --git a/docs/images/investments/watchlistjsonexample.png b/docs/images/investments/watchlistjsonexample.png new file mode 100644 index 0000000000000000000000000000000000000000..5799f6113bb9e72b196c59d2624bf7b62f64f0e5 GIT binary patch literal 49214 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%0D@ceRpKqaQ$S@br%EE_Lp3$t7yDQku@;|Q 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 literal 0 HcmV?d00001 From 1f63e8de0caeb0c4e5826e2cc7954431f24ad282 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sat, 4 Nov 2023 20:32:59 +0800 Subject: [PATCH 384/518] Add check for whether null stocks are passed before printing --- build.gradle | 2 +- src/main/java/seedu/financialplanner/utils/Ui.java | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 6522488386..3dc27bb456 100644 --- a/build.gradle +++ b/build.gradle @@ -13,7 +13,7 @@ dependencies { testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.10.0' testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.10.0' implementation group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1' - implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.0' + implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.12.0' implementation group: 'org.knowm.xchart', name: 'xchart', version: '3.8.5' implementation group: 'com.google.code.gson', name: 'gson', version: '2.10.1' } diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index fa8d8dcf0e..11a32e0cba 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -1,5 +1,6 @@ package seedu.financialplanner.utils; +import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import seedu.financialplanner.investments.Stock; import seedu.financialplanner.investments.WatchList; @@ -84,6 +85,17 @@ public void printStocksInfo(WatchList watchList) { for (Map.Entry set : watchList.getStocks().entrySet()) { Stock stock = set.getValue(); + if (!ObjectUtils.allNotNull( + stock.getPrice(), + stock.getDayHigh(), + stock.getDayLow(), + stock.getLastUpdated(), + stock.getExchange() + )) { + System.out.println(stock.getStockName() + " (" + stock.getSymbol() + ") is not found on FMP"); + continue; + } + String symbol = StringUtils.rightPad(stock.getSymbol(), 10); String market = StringUtils.rightPad(stock.getExchange(), 10); String price = YELLOW + StringUtils.rightPad(stock.getPrice(), 10) + RESET; From 466e04d992503462e9c5a99d9f32925138dffb38 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sat, 4 Nov 2023 20:49:14 +0800 Subject: [PATCH 385/518] Add saving of watchlist after watchlist command --- .../java/seedu/financialplanner/commands/WatchListCommand.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java index 401d5195ed..16ac46c619 100644 --- a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java @@ -2,6 +2,7 @@ import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.investments.WatchList; +import seedu.financialplanner.storage.SaveData; import seedu.financialplanner.utils.Ui; import java.util.ArrayList; import java.util.logging.Level; @@ -30,6 +31,7 @@ public void execute() { logger.log(Level.INFO, "Printing watchlist"); ui.printStocksInfo(watchList); + SaveData.saveWatchList(); } catch (FinancialPlannerException e) { ui.showMessage(e.getMessage()); } From 8b5663537504e3f8640b31edaa373a4bef62f9be Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sat, 4 Nov 2023 20:50:38 +0800 Subject: [PATCH 386/518] Add attempt of removing of both normal stock and its uppercase form --- .../seedu/financialplanner/commands/DeleteStockCommand.java | 2 +- .../java/seedu/financialplanner/investments/WatchList.java | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java index df600bb3de..b8506b1544 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java @@ -18,7 +18,7 @@ public DeleteStockCommand(RawCommand rawCommand) throws IllegalArgumentException } logger.log(Level.INFO, "Parsing stockcode from input"); - stockCode = rawCommand.extraArgs.get("s").toUpperCase(); + stockCode = rawCommand.extraArgs.get("s"); rawCommand.extraArgs.remove("s"); if (!rawCommand.extraArgs.isEmpty()) { diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index 40af3a071e..996cf492df 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -192,7 +192,10 @@ public String deleteStock(String stockCode) throws FinancialPlannerException { if (stocks.isEmpty()) { throw new FinancialPlannerException("No stock in watchlist!"); } - Stock removedStock = stocks.remove(stockCode.toUpperCase()); // should be uppercase already + Stock removedStock = stocks.remove(stockCode); + if (removedStock == null) { + removedStock = stocks.remove(stockCode.toUpperCase()); + } if (removedStock == null) { throw new FinancialPlannerException("Does not Exist in Watchlist"); } From 4270383f85a50ef5154c8d764ed350abccc5cdcb Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sat, 4 Nov 2023 20:50:49 +0800 Subject: [PATCH 387/518] Add details to UG --- docs/UserGuide.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 7655c75080..ec980fe56c 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -500,6 +500,8 @@ GOOGL NASDAQ 124.46 125.4 122.75 Alphabet Inc - Class AAPL NASDAQ 170.29 171.17 168.87 Apple Inc Tue, Oct 31 2023 04:00:02 ``` +- Note: Your watchlist information is saved under the file path `data/watchlist.json` in JSON format + Format of watchlist output: | Symbol | Market | Price | Daily High | Daily Low | Equity Name | Last Updated | @@ -525,7 +527,7 @@ Meta Platforms Inc - Class A Use Watchlist to view it! ``` -- Note: Due to the free nature of the API (Alphpa Vantage and FMP), only US stock prices quote will be provided by +- Note: Due to the free nature of the API (Alpha Vantage and FMP), only US stock prices quote will be provided by this application. Sorry for the inconvenience caused. - Note: Due to the free nature of the API, there will be a cap of **five** stocks in the watchlist @@ -545,7 +547,7 @@ Meta Platforms Inc - Class A Use watchlist command to view updated Watchlist ``` -- Note: Your watchlist information is saved under the file path `data/watchlist.json` in JSON format +- Note: Delete stock command is case-sensitive. Please enter the exact stock code of the stock that you have added. ### watchlist.json From 6edb7eaa446b2196cd27b6670b180be623cd4bce Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sat, 4 Nov 2023 20:58:17 +0800 Subject: [PATCH 388/518] Add printing of acknowledgement to APIs --- src/main/java/seedu/financialplanner/utils/Ui.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 11a32e0cba..2d9dc82509 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -81,6 +81,11 @@ public void printWatchListHeader() { System.out.println(); } + public void printWatchListAcknowledgement() { + System.out.println("Data provided by Financial Modeling Prep and Alpha Vantage 😊"); + } + + public void printStocksInfo(WatchList watchList) { for (Map.Entry set : watchList.getStocks().entrySet()) { Stock stock = set.getValue(); @@ -107,6 +112,7 @@ public void printStocksInfo(WatchList watchList) { String lastUpdate = StringUtils.rightPad(date, 10); System.out.println(symbol + market + price + dayHigh + dayLow + name + lastUpdate); } + printWatchListAcknowledgement(); } public void printAddStock(String stockName) { From 0146afb802dc0e011199f04b851e73a0590b86a3 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Sat, 4 Nov 2023 21:07:19 +0800 Subject: [PATCH 389/518] Add PPP to be completed --- docs/team/ryan1604.md | 45 +++++++++++++++++++++++++++++++++++++++++++ docs/team/ryanchua.md | 0 2 files changed, 45 insertions(+) create mode 100644 docs/team/ryan1604.md delete mode 100644 docs/team/ryanchua.md diff --git a/docs/team/ryan1604.md b/docs/team/ryan1604.md new file mode 100644 index 0000000000..e19125aaa8 --- /dev/null +++ b/docs/team/ryan1604.md @@ -0,0 +1,45 @@ +# Ryan Chua - Project Portfolio Page + +## Overview + +Financial Planner is a Command Line Interface (CLI) application for managing your finances conveniently. +It is optimized for use via the CLI and leverages your expertise in CLI and your ability to type fast and gives +you a one-stop interface to access a plethora of features to manage your finances. + +## Summary of contributions + +### Code contributed: [RepoSense link](https://nus-cs2113-ay2324s1.github.io/tp-dashboard/?search=ryan1604&breakdown=true) + +### Enhancements implemented: + +* General structure of the code (parts of FinancialPlanner, Storage, Parser and Ui) +* Budget feature +* Overview feature +* Balance feature +* General code enhancements and improvements + +### Contributions to the UG: + +* Feature guide for budget, overview, balance, and exiting program +* Saving and loading data components +* Introduction +* Command summary for my features + +### Contributions to the DG: + +* Storage component: + * Implementation + * Class diagram + * Design considerations +* Budget feature + +### Contributions to team-based tasks: + +### Review/Mentoring contributions: + +* Reviewed teammates code (giving suggestions and improvements) + +### Contributions beyond the project team: + +* Reviewed UG & DG of other teams. +* Product testing for other teams. \ No newline at end of file diff --git a/docs/team/ryanchua.md b/docs/team/ryanchua.md deleted file mode 100644 index e69de29bb2..0000000000 From d7e4477b09a031df934dad347e5f4fbd984919e7 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sat, 4 Nov 2023 21:10:51 +0800 Subject: [PATCH 390/518] Add instructions for adding stock using JSON --- docs/UserGuide.md | 8 ++++++++ .../investments/Exampleaddingstockjson.png | Bin 0 -> 7641 bytes 2 files changed, 8 insertions(+) create mode 100644 docs/images/investments/Exampleaddingstockjson.png diff --git a/docs/UserGuide.md b/docs/UserGuide.md index ec980fe56c..ad1e0ce8be 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -480,6 +480,8 @@ Balance: 3790.00 ### Viewing Watchlist: `watchlist` +- Note: Stockcode and symbol will be used interchangeably and have the same meaning + View your current watchlist with stocks that you are interested in with the exchanges shown as well Default watchlist: AAPL, GOOGL @@ -567,6 +569,12 @@ Incorrect format of JSON file may lead to: stock entries that does not match the format specified above) - Incorrect information printed by Financial Planner application (eg. changing stock prices directly in JSON file) +**Adding stock** + +If you would like to add stock, do provide information for the symbol and stockName as shown below + +![](images/investments/Exampleaddingstockjson.png) + ### View Reminder List: `reminderlist` View your current reminder list with reminders that you have added. diff --git a/docs/images/investments/Exampleaddingstockjson.png b/docs/images/investments/Exampleaddingstockjson.png new file mode 100644 index 0000000000000000000000000000000000000000..f18a928f74e81d7cf1b0df23e93ed401db5953bf GIT binary patch literal 7641 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 Date: Sat, 4 Nov 2023 21:26:12 +0800 Subject: [PATCH 391/518] Add additonal checks for adding stock and handle exception for stock constructor properly --- docs/UserGuide.md | 1 + .../seedu/financialplanner/commands/AddStockCommand.java | 2 +- src/main/java/seedu/financialplanner/investments/Stock.java | 6 +++--- .../java/seedu/financialplanner/investments/WatchList.java | 5 ++++- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index ad1e0ce8be..1ed0b43b4b 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -481,6 +481,7 @@ Balance: 3790.00 ### Viewing Watchlist: `watchlist` - Note: Stockcode and symbol will be used interchangeably and have the same meaning +- Note: watchlist feature requires a stable internet connection View your current watchlist with stocks that you are interested in with the exchanges shown as well diff --git a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java index bd96a877ed..076bf7cf2b 100644 --- a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java @@ -18,7 +18,7 @@ public AddStockCommand(RawCommand rawCommand) throws IllegalArgumentException { } logger.log(Level.INFO, "Parsing stockcode from input"); - stockCode = rawCommand.extraArgs.get("s").toUpperCase(); + stockCode = rawCommand.extraArgs.get("s"); rawCommand.extraArgs.remove("s"); if (!rawCommand.extraArgs.isEmpty()) { diff --git a/src/main/java/seedu/financialplanner/investments/Stock.java b/src/main/java/seedu/financialplanner/investments/Stock.java index cebe213d6c..7f7f086d68 100644 --- a/src/main/java/seedu/financialplanner/investments/Stock.java +++ b/src/main/java/seedu/financialplanner/investments/Stock.java @@ -86,11 +86,11 @@ public String getStockNameFromAPI(String symbol) throws FinancialPlannerExceptio assert stock.get("2. name") != null; return (String) stock.get("2. name"); } catch (IOException e) { - throw new RuntimeException(e); + throw new FinancialPlannerException("Error sending request to API.. Are you connected to the internet?"); } catch (InterruptedException e) { - throw new RuntimeException(e); + throw new FinancialPlannerException("Command was interrupted... Try again"); } catch (ParseException e) { - throw new RuntimeException(e); + throw new FinancialPlannerException("Error parsing JSON response from API... Try again"); } } diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index 996cf492df..2227fbbd76 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -176,7 +176,10 @@ public String addStock(String stockCode) throws FinancialPlannerException { if (stocks.size() >= 5) { throw new FinancialPlannerException("Watchlist is full (max 5). Delete a stock to add a new one"); } - if (stocks.containsKey(stockCode.toUpperCase())) { // should already be uppercase + if (stocks.containsKey(stockCode.toUpperCase())) { + throw new FinancialPlannerException("Stock is already present in Watchlist. Use watchlist to view it!"); + } + if (stocks.containsKey(stockCode)) { throw new FinancialPlannerException("Stock is already present in Watchlist. Use watchlist to view it!"); } From 52300e6d5358830f062b6678f7315766d438ddbc Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sat, 4 Nov 2023 21:47:29 +0800 Subject: [PATCH 392/518] Add to UG q and A --- docs/UserGuide.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 1ed0b43b4b..c8c120920b 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -788,6 +788,28 @@ Existing data will be automatically loaded when the program starts up. **A**: {your answer here} +**Q**: Should I edit the watchlist.json file? + +**A**: You should not edit the watchlist.json file unless you are very familiar with the format used. +If you would like to edit the watchlist.json file directly to manipulate your watchlist, please follow the instructions +above in the watchlist feature section. However, do note that there is risk of file corruption. + +**Q**: How is the radar chart derived? + +**A**: To obtain the radar chart in our application, the income/expense category with the highest amount is noted. +After which, amounts of all other categories are taken as a ratio of the maximum category. The ratios are then displayed +in the radar chart + +**Q**: Why can't I add Singapore exchange stocks or other exchange stocks using the add stock command? + +**A**: Due to the restrictions of the free API provided, only US-exchange stocks are provided. Sorry for the +inconvenience caused + +**Q**: Why is saying that the API is done or something? + +**A**: Due to the free nature of the API, there is a restriction in the number of requests allowed in a specific time +window. Sorry for the inconvenience caused. + ## Command Summary {Give a 'cheat sheet' of commands here} From 1bafe66502601b15abcdfc3d4d6e52b772af2d22 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sat, 4 Nov 2023 21:47:50 +0800 Subject: [PATCH 393/518] Fix bug --- docs/UserGuide.md | 53 ++++++++++--------- .../financialplanner/cashflow/Cashflow.java | 5 -- .../commands/ListCommand.java | 6 +-- .../java/seedu/financialplanner/utils/Ui.java | 11 +++- 4 files changed, 41 insertions(+), 34 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index b5e908e145..c9d0bc5346 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -279,27 +279,32 @@ Balance: -830.00 Example output: ``` -You have 4 matching cashflows: +You have 6 matching cashflows: 1: Expense - Type: Necessities - Amount: 300.00 - Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 - Description: groceries -2: Income - Type: Salary - Amount: 5000.00 - Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 - Description: work -3: Expense Type: Dining Amount: 30.00 Description: Genki Sushi -4: Expense +2: Expense Type: Necessities Amount: 300.00 Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 Description: groceries +3: Income + Type: Allowance + Amount: 500.00 + Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 +4: Income + Type: Investments + Amount: 1000.00 +5: Income + Type: Salary + Amount: 100.00 +6: Expense + Type: Others + Amount: 0.23 +Balance: 1269.77 ``` +- Note: Balance displayed above is just an example. Your actual balance may differ. - Note: Date displayed above is just an example. Your actual date may differ. #### List income: `list income` @@ -309,18 +314,18 @@ Example output: ``` You have 3 matching cashflows: 1: Income - Type: Salary - Amount: 5000.00 - Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 - Description: work -2: Income Type: Allowance Amount: 500.00 Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 -3: Income +2: Income Type: Investments Amount: 1000.00 +3: Income + Type: Salary + Amount: 100.00 +Income Balance: 1600.00 ``` +- Note: Balance displayed above is just an example. Your actual balance may differ. - Note: Date displayed above is just an example. Your actual date may differ. #### List expense: `list expense` @@ -330,20 +335,20 @@ Example output: ``` You have 3 matching cashflows: 1: Expense - Type: Necessities - Amount: 300.00 - Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 - Description: groceries -2: Expense Type: Dining Amount: 30.00 Description: Genki Sushi -3: Expense +2: Expense Type: Necessities Amount: 300.00 Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 Description: groceries +3: Expense + Type: Others + Amount: 0.23 +Expense Balance: 330.23 ``` +- Note: Balance displayed above is just an example. Your actual balance may differ. - Note: Date displayed above is just an example. Your actual date may differ. #### List recurring: `list recurring` diff --git a/src/main/java/seedu/financialplanner/cashflow/Cashflow.java b/src/main/java/seedu/financialplanner/cashflow/Cashflow.java index fa3cfa617f..54e03788c6 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Cashflow.java +++ b/src/main/java/seedu/financialplanner/cashflow/Cashflow.java @@ -89,11 +89,6 @@ public String toString() { return string; } - public String formatBalance() { - DecimalFormat decimalFormat = new DecimalFormat("####0.00"); - - return decimalFormat.format(round(Cashflow.balance, 2)); - } public double getAmount() { return this.amount; diff --git a/src/main/java/seedu/financialplanner/commands/ListCommand.java b/src/main/java/seedu/financialplanner/commands/ListCommand.java index f3f7858a27..fdbd4ead80 100644 --- a/src/main/java/seedu/financialplanner/commands/ListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/ListCommand.java @@ -84,11 +84,11 @@ public void execute() throws Exception { ui.showMessage((i + 1) + ": " + cashflowToBePrinted.get(i)); } if (category == null) { - ui.showMessage("Balance: " + Cashflow.getBalance()); + ui.showMessage("Balance: " + ui.formatBalance(Cashflow.getBalance())); } else if (category.equals(CashflowCategory.INCOME)) { - ui.showMessage("Income Balance: " + Cashflow.getIncomeBalance()); + ui.showMessage("Income Balance: " + ui.formatBalance(Cashflow.getIncomeBalance())); } else if (category.equals(CashflowCategory.EXPENSE)) { - ui.showMessage("Expense Balance: " + Cashflow.getExpenseBalance()); + ui.showMessage("Expense Balance: " + ui.formatBalance(Cashflow.getExpenseBalance())); } } } diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 57c9435f8b..51cd8bd444 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -6,6 +6,7 @@ import seedu.financialplanner.cashflow.Budget; import seedu.financialplanner.cashflow.Cashflow; +import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.Map; import java.util.Scanner; @@ -109,18 +110,24 @@ public void printDeleteStock(String stockName) { System.out.println("Use watchlist command to view updated Watchlist"); } + public String formatBalance(double balance) { + DecimalFormat decimalFormat = new DecimalFormat("####0.00"); + + return decimalFormat.format(Cashflow.round(balance, 2)); + } + public void printAddedCashflow(Cashflow entry) { System.out.print("You have added an "); System.out.println(entry); System.out.println("to the Financial Planner."); - System.out.println("Balance: " + entry.formatBalance()); + System.out.println("Balance: " + formatBalance(Cashflow.getBalance())); } public void printDeletedCashflow(Cashflow entry) { System.out.print("You have removed an "); System.out.println(entry); System.out.println("from the Financial Planner."); - System.out.println("Balance: " + entry.formatBalance()); + System.out.println("Balance: " + formatBalance(Cashflow.getBalance())); } public void printDeletedRecur(Cashflow entry) { From 98daeacceaae74b0716c26676683a7b6a02fe07e Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sat, 4 Nov 2023 21:49:30 +0800 Subject: [PATCH 394/518] Fix checkstyle --- .../seedu/financialplanner/investments/WatchList.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index 2227fbbd76..ee2f757474 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -26,6 +26,11 @@ public class WatchList { private static final String API_KEY = "iFumtYryBCbHpS3sDqLdVKi2SdP63vSV"; private HashMap stocks; + private WatchList() { + stocks = LoadData.loadWatchList(); + cleanUpLoadedWatchList(); + } + private void cleanUpLoadedWatchList() { if (stocks == null) { stocks = initalizeNewWatchlist(); @@ -59,11 +64,6 @@ public HashMap initalizeNewWatchlist() { return baseStocks; } - private WatchList() { - stocks = LoadData.loadWatchList(); - cleanUpLoadedWatchList(); - } - public static WatchList getInstance() { if (watchlist == null) { watchlist = new WatchList(); From 11d11744263ed4dad13af4179cb1204b7c1d4564 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sat, 4 Nov 2023 23:16:56 +0800 Subject: [PATCH 395/518] Fix code according to reviewer --- docs/UserGuide.md | 5 +++-- .../java/seedu/financialplanner/investments/WatchList.java | 4 ++-- src/main/java/seedu/financialplanner/utils/Ui.java | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index c8c120920b..db39b831a9 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -805,10 +805,11 @@ in the radar chart **A**: Due to the restrictions of the free API provided, only US-exchange stocks are provided. Sorry for the inconvenience caused -**Q**: Why is saying that the API is done or something? +**Q**: Why is it saying that API limit is reached, not working or something like that when I use watchlist +features? 🤬 **A**: Due to the free nature of the API, there is a restriction in the number of requests allowed in a specific time -window. Sorry for the inconvenience caused. +window. Sorry for the inconvenience caused. 🥲 ## Command Summary diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index ee2f757474..6c12f3ec32 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -79,10 +79,10 @@ public void getLatestWatchlistInfo() throws FinancialPlannerException { public StringBuilder getExpiredStocks() { StringBuilder queryStocks = new StringBuilder(); long currentTime = System.currentTimeMillis(); - long fivemin = 300000; + long fiveMin = 300000; for (Map.Entry set: stocks.entrySet()) { Stock currentStock = set.getValue(); - if (currentStock.getLastFetched() + fivemin < currentTime) { + if (currentStock.getLastFetched() + fiveMin < currentTime) { queryStocks.append(set.getKey()); queryStocks.append(","); } diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 2d9dc82509..cb22b4127c 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -82,7 +82,7 @@ public void printWatchListHeader() { } public void printWatchListAcknowledgement() { - System.out.println("Data provided by Financial Modeling Prep and Alpha Vantage 😊"); + showMessage("Data provided by Financial Modeling Prep and Alpha Vantage 😊"); } @@ -110,7 +110,7 @@ public void printStocksInfo(WatchList watchList) { String date = new SimpleDateFormat("E, MMM dd yyyy HH:mm:ss") .format(stock.getLastUpdated()); String lastUpdate = StringUtils.rightPad(date, 10); - System.out.println(symbol + market + price + dayHigh + dayLow + name + lastUpdate); + showMessage(symbol + market + price + dayHigh + dayLow + name + lastUpdate); } printWatchListAcknowledgement(); } From 8d7db09ee27e77a05d269ff058b6ccf3c02bfa23 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 5 Nov 2023 18:01:55 +0800 Subject: [PATCH 396/518] Fix typo --- docs/UserGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index db39b831a9..068c80b1cd 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -481,7 +481,7 @@ Balance: 3790.00 ### Viewing Watchlist: `watchlist` - Note: Stockcode and symbol will be used interchangeably and have the same meaning -- Note: watchlist feature requires a stable internet connection +- Note: Watchlist feature requires a stable internet connection View your current watchlist with stocks that you are interested in with the exchanges shown as well From f9593b3690e2157ea73bf58d95fcccb829b40608 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Sun, 5 Nov 2023 18:32:40 +0800 Subject: [PATCH 397/518] Add return in Budget --- docs/diagrams/Budget.puml | 2 ++ docs/images/Budget.png | Bin 24926 -> 25264 bytes 2 files changed, 2 insertions(+) diff --git a/docs/diagrams/Budget.puml b/docs/diagrams/Budget.puml index 0e7322fb9a..0c5f991e5d 100644 --- a/docs/diagrams/Budget.puml +++ b/docs/diagrams/Budget.puml @@ -29,5 +29,7 @@ else view else invalid command end +return + hide footbox @enduml \ No newline at end of file diff --git a/docs/images/Budget.png b/docs/images/Budget.png index 2cad026630ebd80ddaefd44095eee63fb86f0dc3..a57a916f16c61efd176a376027a5f76ab4b7f6bc 100644 GIT binary patch literal 25264 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 From 058defcc5357f403a2885b9845d34310c6940781 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 5 Nov 2023 22:53:39 +0800 Subject: [PATCH 398/518] Make changes according to PR reviews --- docs/UserGuide.md | 13 ++++--------- .../seedu/financialplanner/cashflow/Expense.java | 3 ++- .../seedu/financialplanner/cashflow/Income.java | 3 ++- .../commands/AddCashflowCommand.java | 3 ++- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 2211fdfb53..ca8c7cfacd 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -76,7 +76,7 @@ you a one-stop interface to access a plethora of features to manage your finance ### Notes about program limitations - Maximum amount for each cashflow and total balance that the program can hold is 999,999,999,999.99 - Minimum amount for each cashflow and total balance that the program can hold is -999,999,999,999.99 -- Total balance is separate from Income Balance and Expense Balance, where the latter do not have the same limitations. +- Total Balance, Income balance, and Expense balance are different entities where the latter two do not have the same limitations. ### Add cashflow @@ -287,7 +287,7 @@ Balance: -830.00 Example output: ``` -You have 6 matching cashflows: +You have 4 matching cashflows: 1: Expense Type: Dining Amount: 30.00 @@ -304,14 +304,9 @@ You have 6 matching cashflows: 4: Income Type: Investments Amount: 1000.00 -5: Income - Type: Salary - Amount: 100.00 -6: Expense - Type: Others - Amount: 0.23 -Balance: 1269.77 +Balance: 1170.00 ``` + - Note: Balance displayed above is just an example. Your actual balance may differ. - Note: Date displayed above is just an example. Your actual date may differ. diff --git a/src/main/java/seedu/financialplanner/cashflow/Expense.java b/src/main/java/seedu/financialplanner/cashflow/Expense.java index 3fda463e4d..a791a00560 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Expense.java +++ b/src/main/java/seedu/financialplanner/cashflow/Expense.java @@ -45,7 +45,8 @@ private void addExpenseValue() throws FinancialPlannerException { double tempBalance = balance - this.amount; if (tempBalance < -MAX_AMOUNT) { - throw new FinancialPlannerException("Balance exceeded minimum value this program can hold."); + throw new FinancialPlannerException("Balance exceeded minimum value this program can hold." + + " Please add a different expense."); } balance = tempBalance; diff --git a/src/main/java/seedu/financialplanner/cashflow/Income.java b/src/main/java/seedu/financialplanner/cashflow/Income.java index 6a76dfdb78..f30312308d 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Income.java +++ b/src/main/java/seedu/financialplanner/cashflow/Income.java @@ -45,7 +45,8 @@ private void addIncomeValue() throws FinancialPlannerException { double tempBalance = balance + this.amount; if (tempBalance > MAX_AMOUNT) { - throw new FinancialPlannerException("Balance exceeded maximum value this program can hold."); + throw new FinancialPlannerException("Balance exceeded maximum value this program can hold." + + " Please add a different income."); } balance = tempBalance; diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index 9711fcd582..2332d50cce 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -52,7 +52,8 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException } if (amount > MAX_AMOUNT) { logger.log(Level.WARNING, "Maximum value for amount exceeded."); - throw new IllegalArgumentException("Amount exceeded maximum value this program can hold."); + throw new IllegalArgumentException("Amount exceeded maximum value this program can hold. " + + "Please add a different cashflow."); } rawCommand.extraArgs.remove("a"); From 07b02e6333d39652c54475a13e035fdfa0ac1aad Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 5 Nov 2023 23:30:32 +0800 Subject: [PATCH 399/518] Add trimming for commands --- .../java/seedu/financialplanner/commands/AddStockCommand.java | 2 +- .../seedu/financialplanner/commands/DeleteStockCommand.java | 2 +- src/main/java/seedu/financialplanner/commands/VisCommand.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java index 076bf7cf2b..d09246e537 100644 --- a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java @@ -18,7 +18,7 @@ public AddStockCommand(RawCommand rawCommand) throws IllegalArgumentException { } logger.log(Level.INFO, "Parsing stockcode from input"); - stockCode = rawCommand.extraArgs.get("s"); + stockCode = rawCommand.extraArgs.get("s").trim(); rawCommand.extraArgs.remove("s"); if (!rawCommand.extraArgs.isEmpty()) { diff --git a/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java index b8506b1544..1ffbbb0aed 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java @@ -18,7 +18,7 @@ public DeleteStockCommand(RawCommand rawCommand) throws IllegalArgumentException } logger.log(Level.INFO, "Parsing stockcode from input"); - stockCode = rawCommand.extraArgs.get("s"); + stockCode = rawCommand.extraArgs.get("s").trim(); rawCommand.extraArgs.remove("s"); if (!rawCommand.extraArgs.isEmpty()) { diff --git a/src/main/java/seedu/financialplanner/commands/VisCommand.java b/src/main/java/seedu/financialplanner/commands/VisCommand.java index 63a30efa95..4e9762ffc2 100644 --- a/src/main/java/seedu/financialplanner/commands/VisCommand.java +++ b/src/main/java/seedu/financialplanner/commands/VisCommand.java @@ -24,9 +24,9 @@ public VisCommand(RawCommand rawCommand) throws IllegalArgumentException { throw new IllegalArgumentException("Chart type must be defined"); } logger.log(Level.INFO, "Parsing entry type and chart type"); - this.type = rawCommand.extraArgs.get("t").toLowerCase(); + this.type = rawCommand.extraArgs.get("t").toLowerCase().trim(); rawCommand.extraArgs.remove("t"); - this.chart = rawCommand.extraArgs.get("c").toLowerCase(); + this.chart = rawCommand.extraArgs.get("c").toLowerCase().trim(); rawCommand.extraArgs.remove("c"); if (!rawCommand.extraArgs.isEmpty()) { String unknownExtraArgument = new ArrayList<>(rawCommand.extraArgs.keySet()).get(0); From 265b96c02a4692f6543ef1b686e0e912279694f0 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 5 Nov 2023 23:30:47 +0800 Subject: [PATCH 400/518] Add padding to watchlist command --- src/main/java/seedu/financialplanner/utils/Ui.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index cb22b4127c..5a4e7bdbec 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -106,7 +106,7 @@ public void printStocksInfo(WatchList watchList) { String price = YELLOW + StringUtils.rightPad(stock.getPrice(), 10) + RESET; String dayHigh = GREEN + StringUtils.rightPad(stock.getDayHigh(), 15) + RESET; String dayLow = RED + StringUtils.rightPad(stock.getDayLow(), 14) + RESET; - String name = StringUtils.rightPad(stock.getStockName(), 30); + String name = StringUtils.rightPad(stock.getStockName(), 33); String date = new SimpleDateFormat("E, MMM dd yyyy HH:mm:ss") .format(stock.getLastUpdated()); String lastUpdate = StringUtils.rightPad(date, 10); From 49276534a0b2380ba6ea272588100ae24c53dbde Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 5 Nov 2023 23:30:59 +0800 Subject: [PATCH 401/518] Add on to UG --- docs/UserGuide.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 068c80b1cd..3e283232bc 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -533,6 +533,7 @@ Use Watchlist to view it! - Note: Due to the free nature of the API (Alpha Vantage and FMP), only US stock prices quote will be provided by this application. Sorry for the inconvenience caused. - Note: Due to the free nature of the API, there will be a cap of **five** stocks in the watchlist +- Note: StockCode should not have any spaces ### Deleting Stock from Watchlist: `deletestock` @@ -551,6 +552,7 @@ Use watchlist command to view updated Watchlist ``` - Note: Delete stock command is case-sensitive. Please enter the exact stock code of the stock that you have added. +- Note: StockCode should not have any spaces ### watchlist.json @@ -572,7 +574,8 @@ stock entries that does not match the format specified above) **Adding stock** -If you would like to add stock, do provide information for the symbol and stockName as shown below +If you would like to add stock directly, do provide accurate information for the symbol and stockName as shown below. If +the format is not followed, the stock might not be loaded to watchlist upon start up. ![](images/investments/Exampleaddingstockjson.png) From 12a072472faa957a31338cc4ead606e5633db32c Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 5 Nov 2023 23:59:41 +0800 Subject: [PATCH 402/518] Add PPP --- docs/team/wwweert123.md | 54 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 docs/team/wwweert123.md diff --git a/docs/team/wwweert123.md b/docs/team/wwweert123.md new file mode 100644 index 0000000000..d54d3fa8d7 --- /dev/null +++ b/docs/team/wwweert123.md @@ -0,0 +1,54 @@ +# Frederick Pua - Project Portfolio Page + +# Overview + +Financial Planner is a Command Line Interface (CLI) application for managing your finances conveniently. +It is optimized for use via the CLI and leverages your expertise in CLI and your ability to type fast and gives +you a one-stop interface to access a plethora of features to manage your finances. + +## Summary of contributions + +### Code contributed: [Reposense link](https://nus-cs2113-ay2324s1.github.io/tp-dashboard/?search=wwweert123&breakdown=true) + +### Enhancements Implemented: + +* Watchlist Feature + * Querying Stock API (Alpha Vantage and FMP) using HTTP Client + * Parsing HTTP JSON response into JAVA object + * Displaying of watchlist + * Adding and deleting stock from watchlist + * Saving and loading of watchlist in file using human-readable format (JSON) +* Visualization Feature + * Sorting of Cashflow into respective categories + * Visualizing cashflow using appropriate visualization tools (Piechart, Barchart, Radarchart) +* Utility classes (Part of storage and UI) + +### Contributions to the UG: + +* Feature guide for watchlist and visualization feature +* Furnish the Q&A with relevant information and doubts that the user might have +* Command summary for my features + +### Contributions to the DG + +* Acknowledgements of relevant 3-rd Party libraries used in watchlist and visualization feature +* Visualization Component + * Implementation + * Class Diagram + * Sequence Diagrams + +### Contributions to team-based tasks: + +* Adding of dependencies to build.gradle +* Checking of issue tracker to ensure all group members are on task and does not miss deadline +* Approving pull request by team members + +### Review/ Mentoring contributions: + +* Reviewing of teammates codes in Pull Requests (giving suggestions and improvements) + +### Contributions beyond the project team + +* Reviewed UG & DG of other teams +* Product system and acceptance testing for other teams + From f988a32c5e36bbfff291de96db85bf2a18611c45 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 6 Nov 2023 00:07:19 +0800 Subject: [PATCH 403/518] Change colour of message printed --- .../seedu/financialplanner/commands/AddStockCommand.java | 2 +- src/main/java/seedu/financialplanner/utils/Ui.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java index d09246e537..37328afa6a 100644 --- a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java @@ -41,7 +41,7 @@ public void execute() { ui.printAddStock(stockName); } catch (FinancialPlannerException e) { logger.log(Level.WARNING, "Error adding stock to watchlist"); - System.out.println(e.getMessage()); + Ui.getInstance().showMessage(e.getMessage()); } } } diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 8a6bd97639..37c6351dcc 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -65,9 +65,9 @@ public String input() { } public void printWatchListHeader() { - System.out.print("Symbol"); + showMessage("Symbol"); System.out.print(" "); - System.out.print("Market"); + showMessage("Market"); System.out.print(" "); System.out.print(YELLOW + "Price" + RESET); System.out.print(" "); @@ -98,7 +98,7 @@ public void printStocksInfo(WatchList watchList) { stock.getLastUpdated(), stock.getExchange() )) { - System.out.println(stock.getStockName() + " (" + stock.getSymbol() + ") is not found on FMP"); + showMessage(stock.getStockName() + " (" + stock.getSymbol() + ") is not found on FMP"); continue; } From 03c0c585e280d24eeac33dfbc1ec5d57fb5037b3 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 6 Nov 2023 00:36:25 +0800 Subject: [PATCH 404/518] Add PPP --- docs/team/NeoMinWei.md | 52 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/docs/team/NeoMinWei.md b/docs/team/NeoMinWei.md index d23055a4b1..8518b3e3ce 100644 --- a/docs/team/NeoMinWei.md +++ b/docs/team/NeoMinWei.md @@ -2,5 +2,55 @@ ## Overview +Financial Planner is a Command Line Interface (CLI) application for managing your finances conveniently. +It is optimized for use via the CLI and leverages your expertise in CLI and your ability to type fast and gives +you a one-stop interface to access a plethora of features to manage your finances. -### Summary of Contributions +## Summary of Contributions + +### Code contributed: [Reposense link](https://nus-cs2113-ay2324s1.github.io/tp-dashboard/?search=neominwei&sort=groupTitle&sortWithin=title&timeframe=commit&mergegroup=&groupSelect=groupByRepos&breakdown=false&since=2023-09-22) + +### Enhancements Implemented: + +* Add Cashflow Feature + * Keep track of total balance + * Ability to set a recurring cashflow +* Delete Cashflow Feature + * Ability to delete a cashflow based on its respective index in overall list, income list, expense list or recur list. + * Ability to delete the recurrence portion of a cashflow, making it a one-time entry only. +* Recurring Cashflow Feature + * Ability to automatically add cashflows based on the system date. +* List Recurring Cashflows Feature + +### Contributions to the UG: + +* Feature guide for add and delete cashflow feature +* Provide quick start guide +* Command summary for add, delete and listing of cashflow + +### Contributions to the DG + +* Acknowledgements of reused code found in add/delete cashflow feature +* Add/Delete Cashflow Feature + * Implementation + * Class Diagram + * Sequence Diagram +* Recurring Cashflow Feature + * Implementation + * Class Diagram + * Sequence Diagram + +### Contributions to team-based tasks: + +* Submission of first draft of UG +* Creating and assigning relevant issues in the issue tracker to teammates +* Approving pull requests by team members + +### Review/ Mentoring contributions: + +* Reviewing of teammates codes in Pull Requests (giving suggestions and improvements) + +### Contributions beyond the project team + +* Reviewed UG & DG of other teams +* Product system and acceptance testing for other teams From a93e83d8ed843c000ddcf40f2747018c30241574 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 6 Nov 2023 00:39:08 +0800 Subject: [PATCH 405/518] Rename PPP file to be in lower case --- docs/team/{NeoMinWei.md => neominwei.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/team/{NeoMinWei.md => neominwei.md} (100%) diff --git a/docs/team/NeoMinWei.md b/docs/team/neominwei.md similarity index 100% rename from docs/team/NeoMinWei.md rename to docs/team/neominwei.md From 24f5843eea52361ba236c576a1434210abbda6cc Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Mon, 6 Nov 2023 11:30:07 +0800 Subject: [PATCH 406/518] Remove activation bars for ref sd --- docs/diagrams/deleteBudget.puml | 7 ------- docs/diagrams/resetBudget.puml | 10 ---------- docs/diagrams/viewBudget.puml | 6 ------ docs/images/deleteBudget.png | Bin 12992 -> 10779 bytes docs/images/resetBudget.png | Bin 24291 -> 20693 bytes docs/images/viewBudget.png | Bin 11422 -> 10236 bytes 6 files changed, 23 deletions(-) diff --git a/docs/diagrams/deleteBudget.puml b/docs/diagrams/deleteBudget.puml index e0a3d734fe..4a8eb03a13 100644 --- a/docs/diagrams/deleteBudget.puml +++ b/docs/diagrams/deleteBudget.puml @@ -1,22 +1,15 @@ @startuml -autoactivate on - mainframe sd DeleteBudget participant ":BudgetCommand" as BudgetCommand participant "<>\nBudget" as Budget participant ":Ui" as Ui -activate BudgetCommand - alt hasBudget BudgetCommand -> Budget: deleteBudget() - return BudgetCommand -> Ui: printDeleteBudget() - return else else BudgetCommand -> Ui: printBudgetError("delete") - return end hide footbox diff --git a/docs/diagrams/resetBudget.puml b/docs/diagrams/resetBudget.puml index 62f3874bd9..8c9e161d63 100644 --- a/docs/diagrams/resetBudget.puml +++ b/docs/diagrams/resetBudget.puml @@ -1,31 +1,21 @@ @startuml -autoactivate on - mainframe sd ResetBudget participant ":BudgetCommand" as BudgetCommand participant "<>\nBudget" as Budget participant ":Ui" as Ui -activate BudgetCommand - alt spentBudget opt initialBudgetExceedBalance BudgetCommand -> Budget: setInitialBudget(balance) - return BudgetCommand -> Ui: printBudgetExceedBalance() - return end BudgetCommand -> Budget: resetBudget() - return BudgetCommand -> Ui: printResetBudget() - return else Does not have Budget BudgetCommand -> Ui: printBudgetError("delete") - return else else BudgetCommand -> Ui: printBudgetError("reset") - return end hide footbox diff --git a/docs/diagrams/viewBudget.puml b/docs/diagrams/viewBudget.puml index fbf7287464..02c0d77042 100644 --- a/docs/diagrams/viewBudget.puml +++ b/docs/diagrams/viewBudget.puml @@ -1,20 +1,14 @@ @startuml -autoactivate on - mainframe sd ViewBudget participant ":BudgetCommand" as BudgetCommand participant "<>\nBudget" as Budget participant ":Ui" as Ui -activate BudgetCommand - alt hasBudget BudgetCommand -> Ui: printBudget() - return else else BudgetCommand -> Ui: printBudgetError("view") - return end hide footbox diff --git a/docs/images/deleteBudget.png b/docs/images/deleteBudget.png index 48224b6765a86256717be378a4e0eefda8a10740..58576256187618be4259d2bc93ce5dbc9930a1e8 100644 GIT binary patch literal 10779 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 literal 24291 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 diff --git a/docs/images/viewBudget.png b/docs/images/viewBudget.png index ab4ac1e3f2020cfbd00869f0d7dc1aca1eeac5a0..fe7179a4eca52eb03b56809dba34af139498b383 100644 GIT binary patch literal 10236 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 From 08d0112fd99efd55d1514bffae52e644e896d110 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Mon, 6 Nov 2023 12:26:52 +0800 Subject: [PATCH 407/518] Update overview command --- .../commands/OverviewCommand.java | 22 +++++++++---------- .../java/seedu/financialplanner/utils/Ui.java | 8 ++++--- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java index e42f0e48d0..57d08389d4 100644 --- a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java +++ b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java @@ -5,7 +5,7 @@ import seedu.financialplanner.cashflow.CashflowList; import seedu.financialplanner.cashflow.Income; import seedu.financialplanner.cashflow.Expense; -import seedu.financialplanner.reminder.Reminder; +import seedu.financialplanner.goal.WishList; import seedu.financialplanner.reminder.ReminderList; import seedu.financialplanner.utils.Ui; @@ -35,10 +35,9 @@ public void execute() { String highestExpense = getHighestExpense(); String budget = getBudgetDesc(); String reminders = getReminders(); + String wishlist = getWishlist(); - Ui.getInstance().printOverview(balance, highestIncome, highestExpense, budget, reminders); - - //todo: goal disparity + Ui.getInstance().printOverview(balance, highestIncome, highestExpense, budget, reminders, wishlist); } private String getBudgetDesc() { @@ -92,14 +91,15 @@ private String getReminders() { if (reminderList.list.isEmpty()) { return "No reminders added yet."; } - StringBuilder reminders = new StringBuilder(); - int count = 1; - for (Reminder reminder : reminderList.list) { - reminders.append(count).append(". ").append(reminder.toString()).append("\n"); - count++; - } + return reminderList.toString(); + } - return reminders.toString(); + private String getWishlist() { + WishList wishList = WishList.getInstance(); + if (wishList.list.isEmpty()) { + return "No goals added yet."; + } + return wishList.toString(); } private String getBalance() { diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index c482a4a769..9a984de91c 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -66,9 +66,9 @@ public String input() { } public void printWatchListHeader() { - showMessage("Symbol"); + System.out.print(CYAN + "Symbol" + RESET); System.out.print(" "); - showMessage("Market"); + System.out.print(CYAN + "Market" + RESET); System.out.print(" "); System.out.print(YELLOW + "Price" + RESET); System.out.print(" "); @@ -201,10 +201,12 @@ public void printOverview(String... args) { String expense = args[2]; String budget = args[3]; String reminders = args[4]; + String wishlist = args[5]; showMessage("Here is an overview of your financials:\n" + "Total balance: " + balance + "\n" + "Highest income: " + income + "\n" + "Highest expense: " + expense + "\n" + - "Remaining budget for the month: " + budget + "\n\n" + "Reminders:\n" + reminders); + "Remaining budget for the month: " + budget + "\n\n" + "Reminders:\n" + reminders + + "\n\nWishlist:\n" + wishlist); } public void printSetBudget() { From 9a4f943c843165c7321fa6d9bc9f937436f4ae51 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 6 Nov 2023 23:49:49 +0800 Subject: [PATCH 408/518] Add JUnit testing for DeleteCashflowCommand --- .../commands/DeleteCashflowCommandTest.java | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 src/test/java/seedu/financialplanner/commands/DeleteCashflowCommandTest.java diff --git a/src/test/java/seedu/financialplanner/commands/DeleteCashflowCommandTest.java b/src/test/java/seedu/financialplanner/commands/DeleteCashflowCommandTest.java new file mode 100644 index 0000000000..44b8361938 --- /dev/null +++ b/src/test/java/seedu/financialplanner/commands/DeleteCashflowCommandTest.java @@ -0,0 +1,126 @@ +package seedu.financialplanner.commands; + +import org.junit.jupiter.api.Test; +import seedu.financialplanner.cashflow.Cashflow; +import seedu.financialplanner.cashflow.CashflowList; +import seedu.financialplanner.enumerations.ExpenseType; +import seedu.financialplanner.enumerations.IncomeType; +import seedu.financialplanner.exceptions.FinancialPlannerException; +import seedu.financialplanner.utils.Parser; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.fail; + +class DeleteCashflowCommandTest { + protected CashflowList cashflowList = CashflowList.getInstance(); + + @Test + void testIllegalArgumentException() { + try { + DeleteCashflowCommand testEntry = new DeleteCashflowCommand(Parser.parseRawCommand("delete")); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Incorrect arguments.", e.getMessage()); + } + try { + DeleteCashflowCommand testEntry = new DeleteCashflowCommand(Parser.parseRawCommand("delete a")); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Index must be an integer.", e.getMessage()); + } + try { + DeleteCashflowCommand testEntry = new DeleteCashflowCommand(Parser.parseRawCommand("delete 0")); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Index must be within the list.", e.getMessage()); + } + try { + DeleteCashflowCommand testEntry = new DeleteCashflowCommand(Parser.parseRawCommand("delete 1 /r 3")); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Arguments after /r should be left empty.", e.getMessage()); + } + try { + DeleteCashflowCommand testEntry = new DeleteCashflowCommand(Parser.parseRawCommand("delete 1 /a")); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Unknown extra argument: a", e.getMessage()); + } + try { + DeleteCashflowCommand testEntry = new DeleteCashflowCommand(Parser.parseRawCommand("delete abc 1")); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Entry must be either income, expense or recurring.", e.getMessage()); + } + } + + @Test + void testExecute() throws FinancialPlannerException { + cashflowList.list.clear(); + + try { + DeleteCashflowCommand testEntry = new DeleteCashflowCommand(Parser.parseRawCommand("delete 2 /r")); + testEntry.execute(); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Index must be within the list.", e.getMessage()); + } + try { + DeleteCashflowCommand testEntry = new DeleteCashflowCommand(Parser.parseRawCommand("delete 2")); + testEntry.execute(); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Index must be within the list.", e.getMessage()); + } + try { + DeleteCashflowCommand testEntry = new DeleteCashflowCommand(Parser.parseRawCommand("delete income 2 /r")); + testEntry.execute(); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Index must be within the list.", e.getMessage()); + } + try { + DeleteCashflowCommand testEntry = new DeleteCashflowCommand(Parser.parseRawCommand("delete income 2")); + testEntry.execute(); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Index must be within the list.", e.getMessage()); + } + + cashflowList.addIncome(1, IncomeType.SALARY, 10, "work"); + cashflowList.addExpense(1, ExpenseType.ENTERTAINMENT, 10, "Apple Music"); + cashflowList.addIncome(1, IncomeType.SALARY, 10, "work"); + cashflowList.addExpense(1, ExpenseType.ENTERTAINMENT, 10, "Apple Music"); + + DeleteCashflowCommand testEntry = new DeleteCashflowCommand(Parser.parseRawCommand("delete recurring 3 /r")); + testEntry.execute(); + Cashflow testIncome = cashflowList.list.get(2); + assertEquals(0, testIncome.getRecur()); + assertNull(testIncome.getDate()); + + testEntry = new DeleteCashflowCommand(Parser.parseRawCommand("delete recurring 3")); + testEntry.execute(); + assertEquals(3, cashflowList.list.size()); + + testEntry = new DeleteCashflowCommand(Parser.parseRawCommand("delete income 1 /r")); + testEntry.execute(); + testIncome = cashflowList.list.get(0); + assertEquals(0, testIncome.getRecur()); + assertNull(testIncome.getDate()); + + testEntry = new DeleteCashflowCommand(Parser.parseRawCommand("delete income 1")); + testEntry.execute(); + assertEquals(2, cashflowList.list.size()); + + testEntry = new DeleteCashflowCommand(Parser.parseRawCommand("delete expense 1 /r")); + testEntry.execute(); + Cashflow testExpense = cashflowList.list.get(1); + assertEquals(0, testExpense.getRecur()); + assertNull(testExpense.getDate()); + + testEntry = new DeleteCashflowCommand(Parser.parseRawCommand("delete expense 1")); + testEntry.execute(); + assertEquals(1, cashflowList.list.size()); + } +} From bd8a8bfebdcb89d8d28539bc336a7687791731e3 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 6 Nov 2023 23:50:04 +0800 Subject: [PATCH 409/518] Add JUnit test for Cashflow --- .../cashflow/CashflowTest.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/test/java/seedu/financialplanner/cashflow/CashflowTest.java diff --git a/src/test/java/seedu/financialplanner/cashflow/CashflowTest.java b/src/test/java/seedu/financialplanner/cashflow/CashflowTest.java new file mode 100644 index 0000000000..3e4278b348 --- /dev/null +++ b/src/test/java/seedu/financialplanner/cashflow/CashflowTest.java @@ -0,0 +1,56 @@ +package seedu.financialplanner.cashflow; + +import org.junit.jupiter.api.Test; +import seedu.financialplanner.enumerations.ExpenseType; +import seedu.financialplanner.enumerations.IncomeType; +import seedu.financialplanner.exceptions.FinancialPlannerException; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; + +class CashflowTest { + protected CashflowList cashflowList = CashflowList.getInstance(); + + + @Test + void round() { + double testValue = Cashflow.round(123.555, 2); + assertEquals(123.56, testValue); + testValue = Cashflow.round(123.554, 2); + assertEquals(123.55, testValue); + } + + @Test + void getIncomeBalance() { + cashflowList.list.clear(); + cashflowList.addIncome(123.12, IncomeType.SALARY, 0 , null); + cashflowList.addIncome(321.21, IncomeType.SALARY, 0, null); + assertEquals(444.33, Cashflow.round(Cashflow.getIncomeBalance(), 2)); + } + + @Test + void getExpenseBalance() { + cashflowList.list.clear(); + cashflowList.addExpense(123.12, ExpenseType.OTHERS, 0 ,null); + cashflowList.addExpense(321.21, ExpenseType.OTHERS, 0, null); + assertEquals(444.33, Cashflow.round(Cashflow.getExpenseBalance(), 2)); + } + + @Test + void testFinancialPlannerException() { + try { + Cashflow testIncome = new Income(9999999999999.99, IncomeType.SALARY, 0, null); + fail(); + } catch (FinancialPlannerException e) { + assertEquals("Balance exceeded maximum value this program can hold." + + " Please add a different income.", e.getMessage()); + } + try { + Cashflow testExpense = new Expense(9999999999999.99, ExpenseType.OTHERS, 0, null); + fail(); + } catch (FinancialPlannerException e) { + assertEquals("Balance exceeded minimum value this program can hold." + + " Please add a different expense.", e.getMessage()); + } + } +} From 2df3f9347925def1c2758f73dd51ac71e8fc8d05 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 6 Nov 2023 23:50:44 +0800 Subject: [PATCH 410/518] Update JUnit tests in CashflowList and AddCashflowCommand to include exception testing --- .../cashflow/CashflowListTest.java | 14 +- .../commands/AddCashflowCommandTest.java | 132 ++++++++++++++++-- 2 files changed, 131 insertions(+), 15 deletions(-) diff --git a/src/test/java/seedu/financialplanner/cashflow/CashflowListTest.java b/src/test/java/seedu/financialplanner/cashflow/CashflowListTest.java index bf82fb8b6e..1096490eec 100644 --- a/src/test/java/seedu/financialplanner/cashflow/CashflowListTest.java +++ b/src/test/java/seedu/financialplanner/cashflow/CashflowListTest.java @@ -9,10 +9,11 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertNull; class CashflowListTest { - private CashflowList testList = CashflowList.getInstance(); - private DecimalFormat decimalFormat = new DecimalFormat("####0.00"); + protected CashflowList testList = CashflowList.getInstance(); + protected DecimalFormat decimalFormat = new DecimalFormat("####0.00"); @Test void testAddIncomeAndExpense() { @@ -86,4 +87,13 @@ void testDeleteIncomeAndExpense() { roundedBalance = Cashflow.round(Cashflow.balance, 2); assertEquals("0.00", decimalFormat.format(roundedBalance)); } + + @Test + void testDeleteRecur() { + testList.addExpense(19.999, ExpenseType.ENTERTAINMENT, 1, "netflix"); + testList.deleteRecurWithoutCategory(1); + Cashflow testExpense = testList.list.get(0); + assertEquals(0, testExpense.getRecur()); + assertNull(testExpense.getDate()); + } } diff --git a/src/test/java/seedu/financialplanner/commands/AddCashflowCommandTest.java b/src/test/java/seedu/financialplanner/commands/AddCashflowCommandTest.java index cc92029939..4fe59b56b7 100644 --- a/src/test/java/seedu/financialplanner/commands/AddCashflowCommandTest.java +++ b/src/test/java/seedu/financialplanner/commands/AddCashflowCommandTest.java @@ -1,35 +1,141 @@ package seedu.financialplanner.commands; import org.junit.jupiter.api.Test; +import seedu.financialplanner.cashflow.Cashflow; import seedu.financialplanner.enumerations.ExpenseType; import seedu.financialplanner.enumerations.IncomeType; -import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.cashflow.CashflowList; import seedu.financialplanner.utils.Parser; -import seedu.financialplanner.utils.Ui; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.fail; class AddCashflowCommandTest { - private Ui ui = Ui.getInstance(); - private CashflowList cashflowList = CashflowList.getInstance(); - private WatchList watchList = WatchList.getInstance(); - + protected CashflowList cashflowList = CashflowList.getInstance(); + @Test + void testIllegalArgumentException() { + try { + AddCashflowCommand testEntry = new AddCashflowCommand(Parser.parseRawCommand("add abc")); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Entry must be either income or expense.", e.getMessage()); + } + try { + AddCashflowCommand testEntry = new AddCashflowCommand(Parser.parseRawCommand("add income")); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Entry must have an amount.", e.getMessage()); + } + try { + AddCashflowCommand testEntry = new AddCashflowCommand(Parser.parseRawCommand("add income /a abc")); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Amount must be a number.", e.getMessage()); + } + try { + AddCashflowCommand testEntry = new AddCashflowCommand(Parser.parseRawCommand("add income /a -1")); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Amount cannot be negative.", e.getMessage()); + } + try { + AddCashflowCommand testEntry = new AddCashflowCommand(Parser + .parseRawCommand("add income /a 9999999999999")); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Amount exceeded maximum value this program can hold. " + + "Please add a different cashflow.", e.getMessage()); + } + try { + AddCashflowCommand testEntry = new AddCashflowCommand(Parser.parseRawCommand("add income /a 1")); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Entry must have a type.", e.getMessage()); + } + try { + AddCashflowCommand testEntry = new AddCashflowCommand(Parser.parseRawCommand("add expense /a 1 /t abc")); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Entry must be one of the following: " + + "dining, entertainment, shopping, travel, insurance, necessities, others", e.getMessage()); + } + try { + AddCashflowCommand testEntry = new AddCashflowCommand(Parser.parseRawCommand("add income /a 1 /t abc")); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Entry must be one of the following: " + + "salary, investments, allowance, others", e.getMessage()); + } + try { + AddCashflowCommand testEntry = new AddCashflowCommand(Parser. + parseRawCommand("add income /a 1 /t salary /r ")); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Recurrence must be an integer.", e.getMessage()); + } + try { + AddCashflowCommand testEntry = new AddCashflowCommand(Parser. + parseRawCommand("add income /a 1 /t salary /r -1")); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Recurring value cannot be negative.", e.getMessage()); + } + try { + AddCashflowCommand testEntry = new AddCashflowCommand(Parser. + parseRawCommand("add income /a 1 /t salary /r 1 /d ")); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Description cannot be left empty.", e.getMessage()); + } + try { + AddCashflowCommand testEntry = new AddCashflowCommand(Parser. + parseRawCommand("add income /a 1 /t salary /r 1 /d 1 /x")); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Unknown extra argument: x", e.getMessage()); + } + } @Test void testExecute() { cashflowList.list.clear(); AddCashflowCommand testEntry = new AddCashflowCommand(Parser - .parseRawCommand("add income /a 300 /t salary /r 30")); + .parseRawCommand("add income /a 300 /t salary")); testEntry.execute(); - assertEquals(300, testEntry.amount); - assertEquals(IncomeType.SALARY, testEntry.incomeType); - assertEquals(30, testEntry.recur); + assertEquals(1,cashflowList.list.size()); + Cashflow testIncome = cashflowList.list.get(0); + assertEquals(300, testIncome.getAmount()); + assertEquals(IncomeType.SALARY, testIncome.getIncomeType()); + assertEquals(0, testIncome.getRecur()); + assertNull(testIncome.getDescription()); + + testEntry = new AddCashflowCommand(Parser + .parseRawCommand("add income /a 300 /t salary /r 30 /d abc")); + testEntry.execute(); + assertEquals(2,cashflowList.list.size()); + testIncome = cashflowList.list.get(1); + assertEquals(300, testIncome.getAmount()); + assertEquals(IncomeType.SALARY, testIncome.getIncomeType()); + assertEquals(30, testIncome.getRecur()); + assertEquals("abc", testIncome.getDescription()); testEntry = new AddCashflowCommand(Parser.parseRawCommand("add expense /a 15 /t dining")); testEntry.execute(); - assertEquals(15, testEntry.amount); - assertEquals(ExpenseType.DINING, testEntry.expenseType); - assertEquals(0, testEntry.recur); + assertEquals(3,cashflowList.list.size()); + Cashflow testExpense = cashflowList.list.get(2); + assertEquals(15, testExpense.getAmount()); + assertEquals(ExpenseType.DINING, testExpense.getExpenseType()); + assertEquals(0, testExpense.getRecur()); + assertNull(testExpense.getDescription()); + + testEntry = new AddCashflowCommand(Parser.parseRawCommand("add expense /a 15 /t dining /r 30 /d abc")); + testEntry.execute(); + assertEquals(4,cashflowList.list.size()); + testExpense = cashflowList.list.get(3); + assertEquals(15, testExpense.getAmount()); + assertEquals(ExpenseType.DINING, testExpense.getExpenseType()); + assertEquals(30, testExpense.getRecur()); + assertEquals("abc", testExpense.getDescription()); } } From d9bd60dc0cde0e399fdac59d9c43e0ea1d673378 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 6 Nov 2023 23:50:56 +0800 Subject: [PATCH 411/518] Add fullstops to exception messages --- .../commands/AddCashflowCommand.java | 12 ++++++------ .../commands/DeleteCashflowCommand.java | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index 2332d50cce..786803e9e9 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -32,23 +32,23 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException category = CashflowCategory.valueOf(categoryString.toUpperCase()); } catch (IllegalArgumentException e) { logger.log(Level.WARNING, "Invalid arguments for CashflowCategory"); - throw new IllegalArgumentException("Entry must be either income or expense"); + throw new IllegalArgumentException("Entry must be either income or expense."); } if (!rawCommand.extraArgs.containsKey("a")) { logger.log(Level.WARNING, "Missing arguments for amount"); - throw new IllegalArgumentException("Entry must have an amount"); + throw new IllegalArgumentException("Entry must have an amount."); } try { logger.log(Level.INFO, "Parsing amount as double"); amount = Double.parseDouble(rawCommand.extraArgs.get("a").trim()); } catch (IllegalArgumentException e) { logger.log(Level.WARNING, "Invalid arguments for amount"); - throw new IllegalArgumentException("Amount must be a number"); + throw new IllegalArgumentException("Amount must be a number."); } if (amount < 0) { logger.log(Level.WARNING, "Invalid value for amount"); - throw new IllegalArgumentException("Amount cannot be negative"); + throw new IllegalArgumentException("Amount cannot be negative."); } if (amount > MAX_AMOUNT) { logger.log(Level.WARNING, "Maximum value for amount exceeded."); @@ -89,13 +89,13 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException recur = Integer.parseInt(rawCommand.extraArgs.get("r").trim()); } catch (IllegalArgumentException e) { logger.log(Level.WARNING, "Invalid arguments for recur"); - throw new IllegalArgumentException("Recurrence must be an integer"); + throw new IllegalArgumentException("Recurrence must be an integer."); } rawCommand.extraArgs.remove("r"); } if (recur < 0) { logger.log(Level.WARNING, "Invalid value for recur"); - throw new IllegalArgumentException("Recurring value cannot be negative"); + throw new IllegalArgumentException("Recurring value cannot be negative."); } if (rawCommand.extraArgs.containsKey("d")) { diff --git a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java index 6b7c1fd4aa..6a97a9a151 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java @@ -84,7 +84,7 @@ private void handleInvalidCategory(String stringCategory) { category = CashflowCategory.valueOf(stringCategory.toUpperCase()); } catch (IllegalArgumentException e) { logger.log(Level.WARNING, "Invalid arguments for CashflowCategory"); - throw new IllegalArgumentException("Entry must be either income, expense or recurring"); + throw new IllegalArgumentException("Entry must be either income, expense or recurring."); } } @@ -128,7 +128,7 @@ private void handleDeleteRecurWithoutCategory() { cashflowList.deleteRecurWithoutCategory(index); } catch (IndexOutOfBoundsException e) { logger.log(Level.WARNING, "Index out of list"); - throw new IllegalArgumentException("Index must be within the list"); + throw new IllegalArgumentException("Index must be within the list."); } } @@ -141,7 +141,7 @@ private void handleDeleteCashflowWithoutCategory() { } } catch (IndexOutOfBoundsException e) { logger.log(Level.WARNING, "Index out of list"); - throw new IllegalArgumentException("Index must be within the list"); + throw new IllegalArgumentException("Index must be within the list."); } } private void handleDeleteRecurWithCategory() { @@ -150,7 +150,7 @@ private void handleDeleteRecurWithCategory() { cashflowList.deleteRecurWithCategory(category, index); } catch (IndexOutOfBoundsException e) { logger.log(Level.WARNING, "Index out of list"); - throw new IllegalArgumentException("Index must be within the list"); + throw new IllegalArgumentException("Index must be within the list."); } } private void handleDeleteCashflowWithCategory() { @@ -162,7 +162,7 @@ private void handleDeleteCashflowWithCategory() { } } catch (IndexOutOfBoundsException e) { logger.log(Level.WARNING, "Index out of list"); - throw new IllegalArgumentException("Index must be within the list"); + throw new IllegalArgumentException("Index must be within the list."); } } } From 72a16ae644ac98e5ef14148a0c1b2af6fac85c87 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Tue, 7 Nov 2023 00:02:28 +0800 Subject: [PATCH 412/518] Fix JUnit --- src/test/java/seedu/financialplanner/cashflow/CashflowTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/java/seedu/financialplanner/cashflow/CashflowTest.java b/src/test/java/seedu/financialplanner/cashflow/CashflowTest.java index 3e4278b348..5a7c53831b 100644 --- a/src/test/java/seedu/financialplanner/cashflow/CashflowTest.java +++ b/src/test/java/seedu/financialplanner/cashflow/CashflowTest.java @@ -23,6 +23,7 @@ void round() { @Test void getIncomeBalance() { cashflowList.list.clear(); + Cashflow.incomeBalance = 0.00; cashflowList.addIncome(123.12, IncomeType.SALARY, 0 , null); cashflowList.addIncome(321.21, IncomeType.SALARY, 0, null); assertEquals(444.33, Cashflow.round(Cashflow.getIncomeBalance(), 2)); @@ -31,6 +32,7 @@ void getIncomeBalance() { @Test void getExpenseBalance() { cashflowList.list.clear(); + Cashflow.expenseBalance = 0.00; cashflowList.addExpense(123.12, ExpenseType.OTHERS, 0 ,null); cashflowList.addExpense(321.21, ExpenseType.OTHERS, 0, null); assertEquals(444.33, Cashflow.round(Cashflow.getExpenseBalance(), 2)); From 3a0fb325a92033a30f219c20805666ad6796597f Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Tue, 7 Nov 2023 00:02:54 +0800 Subject: [PATCH 413/518] Rename method to follow camelCase --- src/main/java/seedu/financialplanner/cashflow/Cashflow.java | 2 +- .../java/seedu/financialplanner/cashflow/CashflowList.java | 4 ++-- src/main/java/seedu/financialplanner/cashflow/Expense.java | 2 +- src/main/java/seedu/financialplanner/cashflow/Income.java | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/seedu/financialplanner/cashflow/Cashflow.java b/src/main/java/seedu/financialplanner/cashflow/Cashflow.java index 54e03788c6..0087f07f96 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Cashflow.java +++ b/src/main/java/seedu/financialplanner/cashflow/Cashflow.java @@ -49,7 +49,7 @@ public static void setBalance(double amount) { balance = amount; } - public void deleteCashflowvalue() { + public void deleteCashflowValue() { } //@author mhadidg-reused diff --git a/src/main/java/seedu/financialplanner/cashflow/CashflowList.java b/src/main/java/seedu/financialplanner/cashflow/CashflowList.java index 3299f5a208..4341f3df23 100644 --- a/src/main/java/seedu/financialplanner/cashflow/CashflowList.java +++ b/src/main/java/seedu/financialplanner/cashflow/CashflowList.java @@ -67,7 +67,7 @@ public double deleteCashflowWithoutCategory(int index) { Cashflow toRemove = list.get(listIndex); list.remove(listIndex); - toRemove.deleteCashflowvalue(); + toRemove.deleteCashflowValue(); ui.printDeletedCashflow(toRemove); int newListSize = list.size(); @@ -172,7 +172,7 @@ public double deleteCashflowWithCategory(CashflowCategory category, int index) { Cashflow toRemove = list.get(listIndex); list.remove(listIndex); - toRemove.deleteCashflowvalue(); + toRemove.deleteCashflowValue(); ui.printDeletedCashflow(toRemove); int newListSize = list.size(); diff --git a/src/main/java/seedu/financialplanner/cashflow/Expense.java b/src/main/java/seedu/financialplanner/cashflow/Expense.java index a791a00560..7c87dc69e9 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Expense.java +++ b/src/main/java/seedu/financialplanner/cashflow/Expense.java @@ -54,7 +54,7 @@ private void addExpenseValue() throws FinancialPlannerException { } @Override - public void deleteCashflowvalue() { + public void deleteCashflowValue() { balance += this.amount; } diff --git a/src/main/java/seedu/financialplanner/cashflow/Income.java b/src/main/java/seedu/financialplanner/cashflow/Income.java index f30312308d..fa794737c6 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Income.java +++ b/src/main/java/seedu/financialplanner/cashflow/Income.java @@ -54,7 +54,7 @@ private void addIncomeValue() throws FinancialPlannerException { } @Override - public void deleteCashflowvalue() { + public void deleteCashflowValue() { balance -= this.amount; } From f52f1e192ed2d2190367c6dbff0a2c82cbdde379 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Tue, 7 Nov 2023 21:41:00 +0800 Subject: [PATCH 414/518] Add javadoc comments --- .../financialplanner/cashflow/Cashflow.java | 53 +++++++- .../cashflow/CashflowList.java | 114 ++++++++++++++---- .../financialplanner/cashflow/Expense.java | 42 +++++++ .../financialplanner/cashflow/Income.java | 42 +++++++ .../commands/AddCashflowCommand.java | 13 +- .../commands/DeleteCashflowCommand.java | 12 ++ .../financialplanner/storage/LoadData.java | 1 + 7 files changed, 250 insertions(+), 27 deletions(-) diff --git a/src/main/java/seedu/financialplanner/cashflow/Cashflow.java b/src/main/java/seedu/financialplanner/cashflow/Cashflow.java index 0087f07f96..d2b057a8d9 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Cashflow.java +++ b/src/main/java/seedu/financialplanner/cashflow/Cashflow.java @@ -9,6 +9,9 @@ import java.time.LocalDate; import java.time.format.DateTimeFormatter; +/** + * Represents an income or expense. + */ public abstract class Cashflow { protected static double balance = 0; @@ -21,6 +24,14 @@ public abstract class Cashflow { protected boolean hasRecurred; protected final double MAX_AMOUNT = 999999999999.99; + /** + * Constructor for a cashflow. hasRecurred variable is set to false by default and date is initialised depending + * on whether recur is set by the user. + * + * @param amount The value of the cashflow. + * @param recur The number of days before the next automatic addition of the cashflow. + * @param description The description of the cashflow. + */ public Cashflow(double amount, int recur, String description) { this.amount = amount; this.recur = recur; @@ -30,6 +41,16 @@ public Cashflow(double amount, int recur, String description) { } this.hasRecurred = false; } + + /** + * Constructor for a cashflow. + * + * @param amount The value of the cashflow. + * @param recur The number of days before the next automatic addition of the cashflow. + * @param description The description of the cashflow. + * @param date The date that the cashflow is added. + * @param hasRecurred Whether the cashflow has recurred. + */ public Cashflow(double amount, int recur, String description, LocalDate date, boolean hasRecurred) { this.amount = amount; this.recur = recur; @@ -41,6 +62,9 @@ public Cashflow(double amount, int recur, String description, LocalDate date, bo protected Cashflow() { } + /** + * Sets the balance to 0. + */ public static void clearBalance() { balance = 0; } @@ -49,9 +73,18 @@ public static void setBalance(double amount) { balance = amount; } - public void deleteCashflowValue() { - } + /** + * Deletes the value of a cashflow from the balance. + */ + public abstract void deleteCashflowValue(); + /** + * Rounds a double to the specified number of decimal places. The rounding is done half-up. + * + * @param value The double to be rounded. + * @param places The number of decimal places to round to. + * @return The rounded double. + */ //@author mhadidg-reused //Reused from https://stackoverflow.com/questions/2808535/round-a-double-to-2-decimal-places public static double round(double value, int places) { @@ -65,6 +98,12 @@ public static double round(double value, int places) { } //@author mhadidg + /** + * Capitalizes the first letter of a provided string. + * + * @param line The input string to be capitalized. + * @return The string that has been capitalized. + */ //@author Nick Bolton-reused //Reused from //https://stackoverflow.com/questions/1892765/how-to-capitalize-the-first-character-of-each-word-in-a-string @@ -73,6 +112,11 @@ public String capitalize(String line) { } //@author Nick Bolton + /** + * Formats the cashflow into an easy-to-read format to be output to the user. + * + * @return The formatted cashflow. + */ public String toString() { DecimalFormat decimalFormat = new DecimalFormat("####0.00"); @@ -134,6 +178,11 @@ public String getDescription() { return description; } + /** + * Formats the cashflow into a standard format to be saved into a text file. + * + * @return The formatted cashflow. + */ public String formatString() { String string; if (recur == 0) { diff --git a/src/main/java/seedu/financialplanner/cashflow/CashflowList.java b/src/main/java/seedu/financialplanner/cashflow/CashflowList.java index 4341f3df23..ed1edccb00 100644 --- a/src/main/java/seedu/financialplanner/cashflow/CashflowList.java +++ b/src/main/java/seedu/financialplanner/cashflow/CashflowList.java @@ -9,6 +9,9 @@ import java.util.logging.Level; import java.util.logging.Logger; +/** + * Represents the list containing all cashflows. + */ public class CashflowList { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); @@ -18,6 +21,11 @@ public class CashflowList { private CashflowList() { } + /** + * Gets the single instance of CashflowList class. + * + * @return the CashflowList instance. + */ public static CashflowList getInstance() { if (cashflowList == null) { cashflowList = new CashflowList(); @@ -25,6 +33,14 @@ public static CashflowList getInstance() { return cashflowList; } + /** + * Add an income to the list. + * + * @param value The value of the income. + * @param type The type of the income, using the values in the enum of IncomeType. + * @param recur The number of days before the next automatic addition of the income. + * @param description The description of the income. + */ public void addIncome(double value, IncomeType type, int recur, String description) { try { logger.log(Level.INFO, "Adding income"); @@ -45,6 +61,14 @@ private void addToList(Cashflow toAdd) { list.add(toAdd); } + /** + * Adds an expense to the list. + * + * @param value The value of the expense. + * @param type The type of the expense, using the values in the enum of ExpenseType. + * @param recur The number of days before the next automatic addition of the expense. + * @param description The description of the expense. + */ public void addExpense(double value, ExpenseType type, int recur, String description) { try { logger.log(Level.INFO, "Adding expense"); @@ -61,6 +85,12 @@ public void addExpense(double value, ExpenseType type, int recur, String descrip } } + /** + * Deletes a cashflow when its category is not specified. + * + * @param index The index of the cashflow as displayed to the user. + * @return The value of the cashflow to be removed. + */ public double deleteCashflowWithoutCategory(int index) { int existingListSize = list.size(); int listIndex = index - 1; @@ -75,6 +105,11 @@ public double deleteCashflowWithoutCategory(int index) { return toRemove.getAmount(); } + /** + * Deletes all future recurrences of a cashflow that has an unspecified category. + * + * @param index The index of the cashflow as displayed to the user. + */ public void deleteRecurWithoutCategory(int index) { int listIndex = index - 1; @@ -88,10 +123,8 @@ public void deleteRecurWithoutCategory(int index) { ui.printDeletedRecur(toRemoveRecur); } } - //helper method to find the index of a given cashflow in the overall list - //given its index in its respective list. e.g. "income 3" is the third income - //in the overall list - private int cashflowIndexFinder(CashflowCategory category, int cashflowIndex) { + + private int cashflowIndexFinder(CashflowCategory category, int cashflowIndex) throws FinancialPlannerException { assert category.equals(CashflowCategory.INCOME) || category.equals(CashflowCategory.EXPENSE) || category.equals(CashflowCategory.RECURRING); @@ -103,7 +136,7 @@ private int cashflowIndexFinder(CashflowCategory category, int cashflowIndex) { case RECURRING: return findCashflowIndexFromRecurIndex(cashflowIndex); default: - return -1; + throw new FinancialPlannerException("Error in finding cashflow in the list."); } } @@ -153,37 +186,70 @@ private int findCashflowIndexFromRecurIndex(int cashflowIndex) { } return overallCashflowIndex; } - public void deleteRecurWithCategory(CashflowCategory category, int index) { - int listIndex = cashflowIndexFinder(category, index); - Cashflow toRemoveRecur = list.get(listIndex); - if (toRemoveRecur.getRecur() == 0 || toRemoveRecur.hasRecurred) { - ui.showMessage("Cashflow is already not recurring or has already recurred"); - } else { - toRemoveRecur.setDate(null); - toRemoveRecur.setRecur(0); - list.set(listIndex, toRemoveRecur); - ui.printDeletedRecur(toRemoveRecur); + /** + * Deletes all future recurrences of a cashflow that has a specified category. + * + * @param category The type of cashflow: income, expense or recurring. + * @param index The index of the cashflow as displayed to the user. + */ + public void deleteRecurWithCategory(CashflowCategory category, int index) { + try { + int listIndex = cashflowIndexFinder(category, index); + Cashflow toRemoveRecur = list.get(listIndex); + if (toRemoveRecur.getRecur() == 0 || toRemoveRecur.hasRecurred) { + ui.showMessage("Cashflow is already not recurring or has already recurred"); + } else { + toRemoveRecur.setDate(null); + toRemoveRecur.setRecur(0); + list.set(listIndex, toRemoveRecur); + ui.printDeletedRecur(toRemoveRecur); + } + } catch (FinancialPlannerException e) { + ui.showMessage(e.getMessage()); } } + + /** + * Deletes a cashflow that has a specified category. + * + * @param category The type of cashflow: income, expense or recurring. + * @param index The index of the cashflow as displayed to the user. + * @return The value of the cashflow to be deleted. + */ public double deleteCashflowWithCategory(CashflowCategory category, int index) { - int existingListSize = list.size(); - int listIndex = cashflowIndexFinder(category, index); + try { + int existingListSize = list.size(); + int listIndex = cashflowIndexFinder(category, index); - Cashflow toRemove = list.get(listIndex); - list.remove(listIndex); - toRemove.deleteCashflowValue(); - ui.printDeletedCashflow(toRemove); + Cashflow toRemove = list.get(listIndex); + list.remove(listIndex); + toRemove.deleteCashflowValue(); + ui.printDeletedCashflow(toRemove); - int newListSize = list.size(); - assert newListSize == existingListSize - 1; - return toRemove.getAmount(); + int newListSize = list.size(); + assert newListSize == existingListSize - 1; + return toRemove.getAmount(); + } catch (FinancialPlannerException e) { + ui.showMessage(e.getMessage()); + } + return 0; } + /** + * Adds a saved cashflow from the storage to the list. + * + * @param entry The cashflow object to be laoded. + */ public void load(Cashflow entry) { addToList(entry); } + /** + * Formats the list to string with each entry seperated by a newline. + * + * @return The formatted list. + */ public String getList() { StringBuilder output = new StringBuilder(); for (Cashflow entry : list) { diff --git a/src/main/java/seedu/financialplanner/cashflow/Expense.java b/src/main/java/seedu/financialplanner/cashflow/Expense.java index 7c87dc69e9..0bae678868 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Expense.java +++ b/src/main/java/seedu/financialplanner/cashflow/Expense.java @@ -6,15 +6,38 @@ import java.time.LocalDate; +/** + * A cashflow object that represents an expense. + */ public class Expense extends Cashflow { protected ExpenseType type; + /** + * Constructor for an expense. + * + * @param amount The value of the expense. + * @param type The type of the expense, using the values in the enum of ExpenseType. + * @param recur The number of days before the next automatic addition of the expense. + * @param description The description of the expense. + * @throws FinancialPlannerException if the balance exceeds the minimum value of -999,999,999,999.99. + */ public Expense(double amount, ExpenseType type, int recur, String description) throws FinancialPlannerException { super(amount, recur, description); this.type = type; addExpenseValue(); } + /** + * Constructor for an expense. + * + * @param amount The value of the expense. + * @param type The type of the expense, using the values in the enum of ExpenseType. + * @param recur The number of days before the next automatic addition of the expense. + * @param description The description of the expense. + * @param date The date that the expense is added. + * @param hasRecurred Whether the expense has recurred. + * @throws FinancialPlannerException if the balance exceeds the minimum value of -999,999,999,999.99. + */ public Expense(double amount, ExpenseType type, int recur, String description, LocalDate date, boolean hasRecurred) throws FinancialPlannerException { super(amount, recur, description, date, hasRecurred); @@ -22,6 +45,12 @@ public Expense(double amount, ExpenseType type, int recur, addExpenseValue(); } + /** + * Constructor for an expense. + * + * @param expense An expense object to be copied. + * @throws FinancialPlannerException if the balance exceeds the minimum value of -999,999,999,999.99. + */ public Expense(Expense expense) throws FinancialPlannerException { this.amount = expense.getAmount(); this.recur = expense.getRecur(); @@ -53,17 +82,30 @@ private void addExpenseValue() throws FinancialPlannerException { expenseBalance += this.amount; } + /** + * Deletes the value of an expense from the balance. + */ @Override public void deleteCashflowValue() { balance += this.amount; } + /** + * Formats the expense into an easy-to-read format to be output to the user. + * + * @return The formatted expense. + */ @Override public String toString() { return "Expense" + System.lineSeparator() + " Type: " + capitalize(type.toString().toLowerCase()) + System.lineSeparator() + super.toString(); } + /** + * Formats the expense into a standard format to be saved into a text file. + * + * @return The formatted expense. + */ @Override public String formatString() { return "E | " + this.amount + " | " + this.type + super.formatString(); diff --git a/src/main/java/seedu/financialplanner/cashflow/Income.java b/src/main/java/seedu/financialplanner/cashflow/Income.java index fa794737c6..89c51e5fec 100644 --- a/src/main/java/seedu/financialplanner/cashflow/Income.java +++ b/src/main/java/seedu/financialplanner/cashflow/Income.java @@ -6,15 +6,38 @@ import java.time.LocalDate; +/** + * A cashflow object that represents an income. + */ public class Income extends Cashflow{ protected IncomeType type; + /** + * Constructor for an income. + * + * @param amount The value of the income. + * @param type The type of the income, using the values in the enum of IncomeType. + * @param recur The number of days before the next automatic addition of the income. + * @param description The description of the income. + * @throws FinancialPlannerException if the balance exceeds the maximum value of 999,999,999,999.99. + */ public Income(double amount, IncomeType type, int recur, String description) throws FinancialPlannerException { super(amount, recur, description); this.type = type; addIncomeValue(); } + /** + * Constructor for an income + * + * @param amount The value of the income. + * @param type The type of the income, using the values in the enum of IncomeType. + * @param recur The number of days before the next automatic addition of the income. + * @param description The description of the income. + * @param date The date that the income is added. + * @param hasRecurred Whether the income has recurred. + * @throws FinancialPlannerException if the balance exceeds the maximum value of 999,999,999,999.99. + */ public Income(double amount, IncomeType type, int recur, String description, LocalDate date, boolean hasRecurred) throws FinancialPlannerException { super(amount, recur, description, date, hasRecurred); @@ -22,6 +45,12 @@ public Income(double amount, IncomeType type, int recur, String description, Loc addIncomeValue(); } + /** + * Constructor for an income. + * + * @param income An income object to be copied. + * @throws FinancialPlannerException if the balance exceeds the maximum value of 999,999,999,999.99. + */ public Income(Income income) throws FinancialPlannerException { this.amount = income.getAmount(); this.recur = income.getRecur(); @@ -53,17 +82,30 @@ private void addIncomeValue() throws FinancialPlannerException { incomeBalance += this.amount; } + /** + * Deletes the value of an income from the balance. + */ @Override public void deleteCashflowValue() { balance -= this.amount; } + /** + * Formats the income into an easy-to-read format to be output to the user. + * + * @return The formatted income. + */ @Override public String toString() { return "Income" + System.lineSeparator() + " Type: " + capitalize(type.toString().toLowerCase()) + System.lineSeparator() + super.toString(); } + /** + * Formats the income into a standard format to be saved into a text file. + * + * @return The formatted income. + */ @Override public String formatString() { return "I | " + this.amount + " | " + this.type + super.formatString(); diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index 786803e9e9..3afbaf8c91 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -12,7 +12,9 @@ import java.util.logging.Level; import java.util.logging.Logger; - +/** + * Represents the command to add a cashflow. + */ public class AddCashflowCommand extends Command { protected static Ui ui = Ui.getInstance(); private static Logger logger = Logger.getLogger("Financial Planner Logger"); @@ -25,6 +27,12 @@ public class AddCashflowCommand extends Command { protected CashflowList cashflowList = CashflowList.getInstance(); protected final double MAX_AMOUNT = 999999999999.99; + /** + * Constructor for the command to add a cashflow. + * + * @param rawCommand The input from the user. + * @throws IllegalArgumentException if erroneous inputs are detected. + */ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException { String categoryString = String.join(" ", rawCommand.args).trim(); try { @@ -116,6 +124,9 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException } } + /** + * Executes the command to add a cashflow. + */ @Override public void execute() { assert category.equals(CashflowCategory.INCOME) || category.equals(CashflowCategory.EXPENSE) diff --git a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java index 6a97a9a151..83564cbd7a 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java @@ -9,6 +9,9 @@ import java.util.logging.Level; import java.util.logging.Logger; +/** + * Represents a command to delete a cashflow. + */ public class DeleteCashflowCommand extends Command { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); protected CashflowCategory category = null; @@ -16,6 +19,12 @@ public class DeleteCashflowCommand extends Command { protected boolean hasRecur; protected CashflowList cashflowList = CashflowList.getInstance(); + /** + * Constructor of the command to delete a cashflow. + * + * @param rawCommand The input from the user. + * @throws IllegalArgumentException if erroneous inputs are detected. + */ public DeleteCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException { String stringIndex; String stringCategory = null; @@ -88,6 +97,9 @@ private void handleInvalidCategory(String stringCategory) { } } + /** + * Executes the command to delete a cashflow. + */ @Override public void execute() { if (category == null) { diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 63d37f1f94..dce3a6781e 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -42,6 +42,7 @@ public abstract class LoadData { /** * Loads existing data from the storage file. + * Adds recurrences of a cashflow if applicable. * * @param filePath The file where the data is stored. * @param date The current date. From 52da987d0e1a40917124473cf274a1fa83e4abeb Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Tue, 7 Nov 2023 21:44:17 +0800 Subject: [PATCH 415/518] Update text ui test --- text-ui-test/EXPECTED.TXT | 35 +++++++++++++++++++++++++++++++++++ text-ui-test/input.txt | 4 ++++ 2 files changed, 39 insertions(+) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 6265123e09..500dc2db1a 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -25,6 +25,41 @@ Amount: 123.21 to the Financial Planner. Balance: 4899.91 +You have 4 matching cashflows: +1: Income + Type: Salary + Amount: 5000.00 + Description: part time job +2: Income + Type: Allowance + Amount: 123.12 +3: Expense + Type: Entertainment + Amount: 100.00 + Description: netflix +4: Expense + Type: Shopping + Amount: 123.21 +Balance: 4899.91 +You have 2 matching cashflows: +1: Income + Type: Salary + Amount: 5000.00 + Description: part time job +2: Income + Type: Allowance + Amount: 123.12 +Income Balance: 5123.12 +You have 2 matching cashflows: +1: Expense + Type: Entertainment + Amount: 100.00 + Description: netflix +2: Expense + Type: Shopping + Amount: 123.21 +Expense Balance: 223.21 +No matching cashflow. You have removed an Income Type: Allowance Amount: 123.12 diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index 60d9e76fe5..aac6db94ad 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -2,6 +2,10 @@ add income /a 5000 /t salary /d part time job add income /a 123.12 /t allowance add expense /a 100 /t entertainment /d netflix add expense /a 123.21 /t shopping +list +list income +list expense +list recurring delete income 2 delete 1 delete expense 2 From e2ebbe973250e39d0a51e8d7d847cb59a8a958e9 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Tue, 7 Nov 2023 21:48:18 +0800 Subject: [PATCH 416/518] Add fullstop to error message --- src/main/java/seedu/financialplanner/cashflow/CashflowList.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/cashflow/CashflowList.java b/src/main/java/seedu/financialplanner/cashflow/CashflowList.java index ed1edccb00..dc98e35a39 100644 --- a/src/main/java/seedu/financialplanner/cashflow/CashflowList.java +++ b/src/main/java/seedu/financialplanner/cashflow/CashflowList.java @@ -198,7 +198,7 @@ public void deleteRecurWithCategory(CashflowCategory category, int index) { int listIndex = cashflowIndexFinder(category, index); Cashflow toRemoveRecur = list.get(listIndex); if (toRemoveRecur.getRecur() == 0 || toRemoveRecur.hasRecurred) { - ui.showMessage("Cashflow is already not recurring or has already recurred"); + ui.showMessage("Cashflow is already not recurring or has already recurred."); } else { toRemoveRecur.setDate(null); toRemoveRecur.setRecur(0); From c3c411bcedb31411852bb90f816db675faeff0dd Mon Sep 17 00:00:00 2001 From: YFshadaow Date: Wed, 8 Nov 2023 00:11:31 +0800 Subject: [PATCH 417/518] Refactor help command structure: - Separate command name and usage into each command class - Move Command.java, RawCommand.java to new utils package - Refactor parser --- build.gradle | 3 + .../financialplanner/FinancialPlanner.java | 2 +- .../commands/AddCashflowCommand.java | 54 ++++--- .../commands/AddReminderCommand.java | 19 ++- .../commands/AddStockCommand.java | 7 + .../commands/BalanceCommand.java | 9 +- .../commands/BudgetCommand.java | 23 ++- .../commands/DeleteCashflowCommand.java | 13 +- .../commands/DeleteGoalCommand.java | 15 +- .../commands/DeleteReminderCommand.java | 19 ++- .../commands/DeleteStockCommand.java | 8 + .../commands/ExitCommand.java | 9 ++ .../commands/FindCommand.java | 9 +- .../commands/HelpCommand.java | 151 ++++-------------- .../commands/InvalidCommand.java | 20 --- .../commands/ListCommand.java | 12 +- .../commands/MarkGoalCommand.java | 20 ++- .../commands/MarkReminderCommand.java | 20 ++- .../commands/OverviewCommand.java | 9 +- .../commands/ReminderListCommand.java | 12 +- .../commands/SetGoalCommand.java | 18 ++- .../financialplanner/commands/VisCommand.java | 13 +- .../commands/WatchListCommand.java | 10 +- .../commands/WishListCommand.java | 10 +- .../commands/{ => utils}/Command.java | 2 +- .../commands/utils/CommandManager.java | 82 ++++++++++ .../commands/{ => utils}/RawCommand.java | 2 +- .../seedu/financialplanner/utils/Parser.java | 124 ++++---------- 28 files changed, 384 insertions(+), 311 deletions(-) delete mode 100644 src/main/java/seedu/financialplanner/commands/InvalidCommand.java rename src/main/java/seedu/financialplanner/commands/{ => utils}/Command.java (76%) create mode 100644 src/main/java/seedu/financialplanner/commands/utils/CommandManager.java rename src/main/java/seedu/financialplanner/commands/{ => utils}/RawCommand.java (93%) diff --git a/build.gradle b/build.gradle index 3dc27bb456..8b78a0daba 100644 --- a/build.gradle +++ b/build.gradle @@ -16,6 +16,9 @@ dependencies { implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.12.0' implementation group: 'org.knowm.xchart', name: 'xchart', version: '3.8.5' implementation group: 'com.google.code.gson', name: 'gson', version: '2.10.1' + // https://mvnrepository.com/artifact/org.reflections/reflections + implementation group: 'org.reflections', name: 'reflections', version: '0.10.2' + } test { diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index 6d6e3c33a9..f841b4b29b 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -1,7 +1,7 @@ package seedu.financialplanner; import seedu.financialplanner.cashflow.CashflowList; -import seedu.financialplanner.commands.Command; +import seedu.financialplanner.commands.utils.Command; import seedu.financialplanner.commands.ExitCommand; import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.investments.WatchList; diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index 2332d50cce..ed762d8817 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -1,21 +1,28 @@ package seedu.financialplanner.commands; -import seedu.financialplanner.enumerations.CashflowCategory; -import seedu.financialplanner.enumerations.ExpenseType; -import seedu.financialplanner.enumerations.IncomeType; import seedu.financialplanner.cashflow.Budget; import seedu.financialplanner.cashflow.Cashflow; import seedu.financialplanner.cashflow.CashflowList; +import seedu.financialplanner.commands.utils.Command; +import seedu.financialplanner.commands.utils.RawCommand; +import seedu.financialplanner.enumerations.CashflowCategory; +import seedu.financialplanner.enumerations.ExpenseType; +import seedu.financialplanner.enumerations.IncomeType; import seedu.financialplanner.utils.Ui; import java.util.ArrayList; import java.util.logging.Level; import java.util.logging.Logger; - +@SuppressWarnings("unused") public class AddCashflowCommand extends Command { + public static final String NAME = "add"; + + public static final String USAGE = + "add [/t TYPE] [/r RECURRENCE INTERVAL IN DAYS] [/d DESCRIPTION]"; protected static Ui ui = Ui.getInstance(); - private static Logger logger = Logger.getLogger("Financial Planner Logger"); + private static final Logger logger = Logger.getLogger("Financial Planner Logger"); + protected final double MAX_AMOUNT = 999999999999.99; protected double amount; protected CashflowCategory category; protected ExpenseType expenseType; @@ -23,7 +30,6 @@ public class AddCashflowCommand extends Command { protected int recur = 0; protected String description = null; protected CashflowList cashflowList = CashflowList.getInstance(); - protected final double MAX_AMOUNT = 999999999999.99; public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException { String categoryString = String.join(" ", rawCommand.args).trim(); @@ -53,7 +59,7 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException if (amount > MAX_AMOUNT) { logger.log(Level.WARNING, "Maximum value for amount exceeded."); throw new IllegalArgumentException("Amount exceeded maximum value this program can hold. " + - "Please add a different cashflow."); + "Please add a different cashflow."); } rawCommand.extraArgs.remove("a"); @@ -69,7 +75,8 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException } catch (IllegalArgumentException e) { logger.log(Level.WARNING, "Invalid arguments for ExpenseType"); throw new IllegalArgumentException("Entry must be one of the following: " + - "dining, entertainment, shopping, travel, insurance, necessities, others"); + "dining, entertainment, shopping, travel, " + + "insurance, necessities, others"); } } else if (category.equals(CashflowCategory.INCOME)) { try { @@ -78,7 +85,7 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException } catch (IllegalArgumentException e) { logger.log(Level.WARNING, "Invalid arguments for IncomeType"); throw new IllegalArgumentException("Entry must be one of the following: " + - "salary, investments, allowance, others"); + "salary, investments, allowance, others"); } } rawCommand.extraArgs.remove("t"); @@ -116,20 +123,29 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException } } + private static void deductFromBudget(Cashflow entry) { + double expenseAmount = entry.getAmount(); + Budget.deduct(expenseAmount); + ui.printBudgetAfterDeduction(); + } + @Override public void execute() { assert category.equals(CashflowCategory.INCOME) || category.equals(CashflowCategory.EXPENSE) - || category.equals(CashflowCategory.RECURRING); + || category.equals(CashflowCategory.RECURRING); assert recur >= 0; assert amount >= 0; if (category.equals(CashflowCategory.EXPENSE)) { assert expenseType.equals(ExpenseType.DINING) || expenseType.equals(ExpenseType.ENTERTAINMENT) - || expenseType.equals(ExpenseType.SHOPPING) || expenseType.equals(ExpenseType.TRAVEL) - || expenseType.equals(ExpenseType.INSURANCE) || expenseType.equals(ExpenseType.OTHERS) - || expenseType.equals(ExpenseType.NECESSITIES); - } else if (category.equals(CashflowCategory.INCOME)) { - assert incomeType.equals(IncomeType.SALARY) || incomeType.equals(IncomeType.INVESTMENTS) - || incomeType.equals(IncomeType.ALLOWANCE) || incomeType.equals(IncomeType.OTHERS); + || expenseType.equals(ExpenseType.SHOPPING) || expenseType.equals(ExpenseType.TRAVEL) + || expenseType.equals(ExpenseType.INSURANCE) || expenseType.equals(ExpenseType.OTHERS) + || expenseType.equals(ExpenseType.NECESSITIES); + } else { + assert !category.equals(CashflowCategory.INCOME) + || incomeType.equals(IncomeType.SALARY) + || incomeType.equals(IncomeType.INVESTMENTS) + || incomeType.equals(IncomeType.ALLOWANCE) + || incomeType.equals(IncomeType.OTHERS); } switch (category) { @@ -148,10 +164,4 @@ public void execute() { break; } } - - private static void deductFromBudget(Cashflow entry) { - double expenseAmount = entry.getAmount(); - Budget.deduct(expenseAmount); - ui.printBudgetAfterDeduction(); - } } diff --git a/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java b/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java index 802418273f..b159ac152c 100644 --- a/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java @@ -1,24 +1,33 @@ package seedu.financialplanner.commands; -import seedu.financialplanner.reminder.ReminderList; + +import seedu.financialplanner.commands.utils.Command; +import seedu.financialplanner.commands.utils.RawCommand; import seedu.financialplanner.reminder.Reminder; +import seedu.financialplanner.reminder.ReminderList; import seedu.financialplanner.utils.Ui; + +@SuppressWarnings("unused") public class AddReminderCommand extends Command { + public static final String NAME = "addreminder"; + + public static final String USAGE = + "addreminder "; private final String type; private final String date; public AddReminderCommand(RawCommand rawCommand) throws IllegalArgumentException { String typeString = String.join(" ", rawCommand.args); - if(!rawCommand.extraArgs.containsKey("t")){ + if (!rawCommand.extraArgs.containsKey("t")) { throw new IllegalArgumentException("Reminder must have a type"); } type = rawCommand.extraArgs.get("t"); rawCommand.extraArgs.remove("t"); - if(!rawCommand.extraArgs.containsKey("d")){ + if (!rawCommand.extraArgs.containsKey("d")) { throw new IllegalArgumentException("Reminder must have a date"); } date = rawCommand.extraArgs.get("d"); rawCommand.extraArgs.remove("d"); - if(!rawCommand.extraArgs.isEmpty()){ + if (!rawCommand.extraArgs.isEmpty()) { String unknownExtraArgument = new java.util.ArrayList<>(rawCommand.extraArgs.keySet()).get(0); throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); } @@ -28,6 +37,6 @@ public AddReminderCommand(RawCommand rawCommand) throws IllegalArgumentException public void execute() { Reminder reminder = new Reminder(type, date); ReminderList.getInstance().list.add(reminder); - Ui.getInstance().showMessage("You have added "+reminder); + Ui.getInstance().showMessage("You have added " + reminder); } } diff --git a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java index 37328afa6a..468d544b48 100644 --- a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java @@ -1,5 +1,7 @@ package seedu.financialplanner.commands; +import seedu.financialplanner.commands.utils.Command; +import seedu.financialplanner.commands.utils.RawCommand; import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.utils.Ui; @@ -8,7 +10,12 @@ import java.util.logging.Level; import java.util.logging.Logger; +@SuppressWarnings("unused") public class AddStockCommand extends Command { + public static final String NAME = "addstock"; + + public static final String USAGE = + "addstock "; private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private final String stockCode; diff --git a/src/main/java/seedu/financialplanner/commands/BalanceCommand.java b/src/main/java/seedu/financialplanner/commands/BalanceCommand.java index 540f9df0bf..68c827145c 100644 --- a/src/main/java/seedu/financialplanner/commands/BalanceCommand.java +++ b/src/main/java/seedu/financialplanner/commands/BalanceCommand.java @@ -1,6 +1,8 @@ package seedu.financialplanner.commands; import seedu.financialplanner.cashflow.Cashflow; +import seedu.financialplanner.commands.utils.Command; +import seedu.financialplanner.commands.utils.RawCommand; import seedu.financialplanner.utils.Ui; import java.text.DecimalFormat; @@ -9,9 +11,14 @@ /** * Represents a command for displaying balance. */ +@SuppressWarnings("unused") public class BalanceCommand extends Command { + public static final String NAME = "balance"; + + public static final String USAGE = + "balance"; private final Ui ui = Ui.getInstance(); - + public BalanceCommand(RawCommand rawCommand) { if (!rawCommand.extraArgs.isEmpty()) { String unknownExtraArgument = new ArrayList<>(rawCommand.extraArgs.keySet()).get(0); diff --git a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java index f9f2febbde..439572e05a 100644 --- a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java +++ b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java @@ -1,22 +1,33 @@ package seedu.financialplanner.commands; -import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.cashflow.Budget; import seedu.financialplanner.cashflow.Cashflow; +import seedu.financialplanner.commands.utils.Command; +import seedu.financialplanner.commands.utils.RawCommand; +import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.utils.Ui; +import java.util.ArrayList; import java.util.logging.Level; import java.util.logging.Logger; -import java.util.ArrayList; /** * Represents a command to manage the budget. */ +@SuppressWarnings("unused") public class BudgetCommand extends Command { + public static final String NAME = "budget"; + + public static final String USAGE = + "budget set " + + "\n" + "budget update " + + "\n" + "budget delete" + + "\n" + "budget reset" + + "\n" + "budget view"; private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private final Ui ui = Ui.getInstance(); private double budget; - private String command; + private final String command; /** * Constructs a new BudgetCommand and checks if the user input is a valid command. @@ -36,7 +47,7 @@ public BudgetCommand(RawCommand rawCommand) throws FinancialPlannerException { validateBudget(rawCommand); assert budget > 0 && budget <= Cashflow.getBalance() : "Budget should be greater than 0 and less than " + - "or equal to total balance"; + "or equal to total balance"; rawCommand.extraArgs.remove("b"); if (!rawCommand.extraArgs.isEmpty()) { @@ -80,7 +91,7 @@ private void validateCommandFormat(RawCommand rawCommand) throws FinancialPlanne if (!command.equals("set") && !command.equals("update")) { logger.log(Level.WARNING, "Invalid arguments for budget command"); throw new FinancialPlannerException("Budget operation must be one of the following: set, update, " + - "delete, reset, view."); + "delete, reset, view."); } if (command.equals("set") && Budget.hasBudget()) { @@ -103,7 +114,7 @@ private void validateCommandFormat(RawCommand rawCommand) throws FinancialPlanne @Override public void execute() { assert command.equals("set") || command.equals("update") || command.equals("delete") || - command.equals("reset") || command.equals("view"); + command.equals("reset") || command.equals("view"); switch (command) { case "set": diff --git a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java index 6b7c1fd4aa..ef2a09cb46 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java @@ -1,15 +1,22 @@ package seedu.financialplanner.commands; -import seedu.financialplanner.enumerations.CashflowCategory; import seedu.financialplanner.cashflow.Budget; import seedu.financialplanner.cashflow.CashflowList; +import seedu.financialplanner.commands.utils.Command; +import seedu.financialplanner.commands.utils.RawCommand; +import seedu.financialplanner.enumerations.CashflowCategory; import seedu.financialplanner.utils.Ui; import java.util.ArrayList; import java.util.logging.Level; import java.util.logging.Logger; +@SuppressWarnings("unused") public class DeleteCashflowCommand extends Command { + public static final String NAME = "delete"; + + public static final String USAGE = + "delete [income/expense] "; private static final Logger logger = Logger.getLogger("Financial Planner Logger"); protected CashflowCategory category = null; protected int index; @@ -100,7 +107,7 @@ public void execute() { } assert category.equals(CashflowCategory.INCOME) || category.equals(CashflowCategory.EXPENSE) - || category.equals(CashflowCategory.RECURRING); + || category.equals(CashflowCategory.RECURRING); assert index != 0; switch (category) { @@ -144,6 +151,7 @@ private void handleDeleteCashflowWithoutCategory() { throw new IllegalArgumentException("Index must be within the list"); } } + private void handleDeleteRecurWithCategory() { try { logger.log(Level.INFO, "Deleting recurrence with category"); @@ -153,6 +161,7 @@ private void handleDeleteRecurWithCategory() { throw new IllegalArgumentException("Index must be within the list"); } } + private void handleDeleteCashflowWithCategory() { try { logger.log(Level.INFO, "Deleting cashflow with category"); diff --git a/src/main/java/seedu/financialplanner/commands/DeleteGoalCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteGoalCommand.java index ed22fe3919..a9860dae07 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteGoalCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteGoalCommand.java @@ -1,13 +1,22 @@ package seedu.financialplanner.commands; +import seedu.financialplanner.commands.utils.Command; +import seedu.financialplanner.commands.utils.RawCommand; +import seedu.financialplanner.goal.Goal; import seedu.financialplanner.goal.WishList; import seedu.financialplanner.utils.Ui; + import java.util.logging.Level; import java.util.logging.Logger; -import seedu.financialplanner.goal.Goal; + +@SuppressWarnings("unused") public class DeleteGoalCommand extends Command { + public static final String NAME = "deletegoal"; + + public static final String USAGE = "UNDONE, PLEASE FILL THIS UP!"; private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private final int index; + public DeleteGoalCommand(RawCommand rawCommand) throws IllegalArgumentException { String stringIndex; if (rawCommand.args.size() == 1) { @@ -43,8 +52,8 @@ public DeleteGoalCommand(RawCommand rawCommand) throws IllegalArgumentException @Override public void execute() { - Goal goalToDelete = WishList.getInstance().list.get(index-1); - WishList.getInstance().deleteGoal(index-1); + Goal goalToDelete = WishList.getInstance().list.get(index - 1); + WishList.getInstance().deleteGoal(index - 1); Ui.getInstance().showMessage("You have deleted " + goalToDelete); } } diff --git a/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java index 5466124ff9..94dead5a00 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java @@ -1,16 +1,25 @@ package seedu.financialplanner.commands; +import seedu.financialplanner.commands.utils.Command; +import seedu.financialplanner.commands.utils.RawCommand; +import seedu.financialplanner.reminder.Reminder; import seedu.financialplanner.reminder.ReminderList; import seedu.financialplanner.utils.Ui; + import java.util.logging.Level; import java.util.logging.Logger; -import seedu.financialplanner.reminder.Reminder; -public class DeleteReminderCommand extends Command{ + +@SuppressWarnings("unused") +public class DeleteReminderCommand extends Command { + public static final String NAME = "deletereminder"; + + public static final String USAGE = "UNDONE, PLEASE FILL THIS UP!"; private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private final int index; + public DeleteReminderCommand(RawCommand rawCommand) throws IllegalArgumentException { String stringIndex; - if(rawCommand.args.size() == 1) { + if (rawCommand.args.size() == 1) { stringIndex = rawCommand.args.get(0); } else { throw new IllegalArgumentException("Incorrect arguments."); @@ -42,8 +51,8 @@ public DeleteReminderCommand(RawCommand rawCommand) throws IllegalArgumentExcept @Override public void execute() { - Reminder reminderToDelete = ReminderList.getInstance().list.get(index-1); - ReminderList.getInstance().deleteReminder(index-1); + Reminder reminderToDelete = ReminderList.getInstance().list.get(index - 1); + ReminderList.getInstance().deleteReminder(index - 1); Ui.getInstance().showMessage("You have deleted " + reminderToDelete); } } diff --git a/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java index 1ffbbb0aed..9e9bbccbe7 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java @@ -1,5 +1,7 @@ package seedu.financialplanner.commands; +import seedu.financialplanner.commands.utils.Command; +import seedu.financialplanner.commands.utils.RawCommand; import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.utils.Ui; @@ -8,7 +10,13 @@ import java.util.logging.Level; import java.util.logging.Logger; +@SuppressWarnings("unused") + public class DeleteStockCommand extends Command { + public static final String NAME = "deletestock"; + + public static final String USAGE = + "deletestock "; private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private final String stockCode; diff --git a/src/main/java/seedu/financialplanner/commands/ExitCommand.java b/src/main/java/seedu/financialplanner/commands/ExitCommand.java index 03b5eb4285..d47e5a1214 100644 --- a/src/main/java/seedu/financialplanner/commands/ExitCommand.java +++ b/src/main/java/seedu/financialplanner/commands/ExitCommand.java @@ -1,11 +1,20 @@ package seedu.financialplanner.commands; +import seedu.financialplanner.commands.utils.Command; +import seedu.financialplanner.commands.utils.RawCommand; + import java.util.ArrayList; /** * Represents a command to exit the program. */ +@SuppressWarnings("unused") public class ExitCommand extends Command { + public static final String NAME = "exit"; + + public static final String USAGE = + "exit"; + public ExitCommand(RawCommand rawCommand) { if (!rawCommand.extraArgs.isEmpty()) { String unknownExtraArgument = new ArrayList<>(rawCommand.extraArgs.keySet()).get(0); diff --git a/src/main/java/seedu/financialplanner/commands/FindCommand.java b/src/main/java/seedu/financialplanner/commands/FindCommand.java index dda7f75480..97e64f958e 100644 --- a/src/main/java/seedu/financialplanner/commands/FindCommand.java +++ b/src/main/java/seedu/financialplanner/commands/FindCommand.java @@ -1,12 +1,19 @@ package seedu.financialplanner.commands; -import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.cashflow.CashflowList; +import seedu.financialplanner.commands.utils.Command; +import seedu.financialplanner.commands.utils.RawCommand; +import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.utils.Ui; import java.util.ArrayList; +@SuppressWarnings("unused") public class FindCommand extends Command { + public static final String NAME = "find"; + + public static final String USAGE = + "find "; private final String description; public FindCommand(RawCommand rawCommand) { diff --git a/src/main/java/seedu/financialplanner/commands/HelpCommand.java b/src/main/java/seedu/financialplanner/commands/HelpCommand.java index 4b5b910b0e..4282d7ec35 100644 --- a/src/main/java/seedu/financialplanner/commands/HelpCommand.java +++ b/src/main/java/seedu/financialplanner/commands/HelpCommand.java @@ -1,89 +1,27 @@ package seedu.financialplanner.commands; +import seedu.financialplanner.commands.utils.Command; +import seedu.financialplanner.commands.utils.CommandManager; +import seedu.financialplanner.commands.utils.RawCommand; import seedu.financialplanner.utils.Ui; import java.util.ArrayList; -import static seedu.financialplanner.utils.Parser.ADD_CASHFLOW_COMMAND; -import static seedu.financialplanner.utils.Parser.ADD_REMINDER_COMMAND; -import static seedu.financialplanner.utils.Parser.ADD_STOCK_COMMAND; -import static seedu.financialplanner.utils.Parser.BALANCE_COMMAND; -import static seedu.financialplanner.utils.Parser.BUDGET_COMMAND; -import static seedu.financialplanner.utils.Parser.DELETE_CASHFLOW_COMMAND; -import static seedu.financialplanner.utils.Parser.DELETE_STOCK_COMMAND; -import static seedu.financialplanner.utils.Parser.EXIT_COMMAND; -import static seedu.financialplanner.utils.Parser.FIND_COMMAND; -import static seedu.financialplanner.utils.Parser.HELP_COMMAND; -import static seedu.financialplanner.utils.Parser.LIST_COMMAND; -import static seedu.financialplanner.utils.Parser.OVERVIEW_COMMAND; -import static seedu.financialplanner.utils.Parser.SET_GOAL_COMMAND; -import static seedu.financialplanner.utils.Parser.VISUALIZATION_COMMAND; -import static seedu.financialplanner.utils.Parser.WATCHLIST_COMMAND; - +@SuppressWarnings("unused") public class HelpCommand extends Command { - private static final String EXIT_COMMAND_USAGE = - "exit"; - private static final String WATCHLIST_COMMAND_USAGE = - "watchlist"; - private static final String ADD_CASHFLOW_COMMAND_USAGE = - "add [/t TYPE] [/r RECURRENCE INTERVAL IN DAYS] [/d DESCRIPTION]"; - - private static final String DELETE_CASHFLOW_COMMAND_USAGE = - "delete [income/expense] "; - - private static final String ADD_STOCK_COMMAND_USAGE = - "addstock "; - - private static final String DELETE_STOCK_COMMAND_USAGE = - "deletestock "; - - private static final String FIND_COMMAND_USAGE = - "find "; + public static final String NAME = "help"; - private static final String BUDGET_COMMAND_USAGE = - "budget set " - + "\n " + "budget update " - + "\n " + "budget delete" - + "\n " + "budget reset" - + "\n " + "budget view"; - private static final String VISUALIZATION_COMMAND_USAGE = - "vis "; + public static final String USAGE = "help"; - private static final String OVERVIEW_COMMAND_USAGE = - "overview"; - private static final String ADD_REMINDER_COMMAND_USAGE = - "addreminder "; - - private static final String LIST_COMMAND_USAGE = - "list [income/expense]"; - - private static final String SET_GOAL_COMMAND_USAGE = - "set "; + private static final String HELP_MESSAGE_GENERAL = + "<> denotes required arguments, [] denotes optional arguments"; - private static final String BALANCE_COMMAND_USAGE = - "balance"; + private static final String HELP_ALL_PREFIX = + "Here are the available commands:"; - private static final String HELP_COMMAND_USAGE = - "help [COMMAND]"; + // Will replace this in the future + private static final String DELIMITER = "------------------------------"; - private static final String HELP_MESSAGE_GENERAL = - "<> denotes required arguments, [] denotes optional arguments" - + "\n" + "Here are the available commands:" - + "\n " + EXIT_COMMAND_USAGE - + "\n " + WATCHLIST_COMMAND_USAGE - + "\n " + ADD_CASHFLOW_COMMAND_USAGE - + "\n " + DELETE_CASHFLOW_COMMAND_USAGE - + "\n " + ADD_STOCK_COMMAND_USAGE - + "\n " + DELETE_STOCK_COMMAND_USAGE - + "\n " + FIND_COMMAND_USAGE - + "\n " + BUDGET_COMMAND_USAGE - + "\n " + VISUALIZATION_COMMAND_USAGE - + "\n " + OVERVIEW_COMMAND_USAGE - + "\n " + ADD_REMINDER_COMMAND_USAGE - + "\n " + LIST_COMMAND_USAGE - + "\n " + SET_GOAL_COMMAND_USAGE - + "\n " + BALANCE_COMMAND_USAGE - + "\n " + HELP_COMMAND_USAGE; private final String commandName; public HelpCommand(RawCommand rawCommand) { @@ -102,58 +40,23 @@ public HelpCommand(RawCommand rawCommand) { @Override public void execute() throws Exception { + Ui ui = Ui.getInstance(); + CommandManager commandManager = CommandManager.getInstance(); if (commandName == null) { - Ui.getInstance().showMessage(HELP_MESSAGE_GENERAL); + ui.showMessage(HELP_MESSAGE_GENERAL); + ui.showMessage(HELP_ALL_PREFIX); + ui.showMessage(DELIMITER); + for (String name : commandManager.getCommandNames()) { + String usage = commandManager.getCommandUsage(name); + ui.showMessage("Usage of " + name + ":"); + ui.showMessage(usage); + ui.showMessage(DELIMITER); + } return; } - switch (commandName) { - case EXIT_COMMAND: - Ui.getInstance().showMessage("Usage:\n " + EXIT_COMMAND_USAGE); - break; - case WATCHLIST_COMMAND: - Ui.getInstance().showMessage("Usage:\n " + WATCHLIST_COMMAND_USAGE); - break; - case ADD_CASHFLOW_COMMAND: - Ui.getInstance().showMessage("Usage:\n " + ADD_CASHFLOW_COMMAND_USAGE); - break; - case DELETE_CASHFLOW_COMMAND: - Ui.getInstance().showMessage("Usage:\n " + DELETE_CASHFLOW_COMMAND_USAGE); - break; - case ADD_STOCK_COMMAND: - Ui.getInstance().showMessage("Usage:\n " + ADD_STOCK_COMMAND_USAGE); - break; - case DELETE_STOCK_COMMAND: - Ui.getInstance().showMessage("Usage:\n " + DELETE_STOCK_COMMAND_USAGE); - break; - case FIND_COMMAND: - Ui.getInstance().showMessage("Usage:\n " + FIND_COMMAND_USAGE); - break; - case BUDGET_COMMAND: - Ui.getInstance().showMessage("Usage:\n " + BUDGET_COMMAND_USAGE); - break; - case VISUALIZATION_COMMAND: - Ui.getInstance().showMessage("Usage:\n " + VISUALIZATION_COMMAND_USAGE); - break; - case OVERVIEW_COMMAND: - Ui.getInstance().showMessage("Usage:\n " + OVERVIEW_COMMAND_USAGE); - break; - case ADD_REMINDER_COMMAND: - Ui.getInstance().showMessage("Usage:\n " + ADD_REMINDER_COMMAND_USAGE); - break; - case LIST_COMMAND: - Ui.getInstance().showMessage("Usage:\n " + LIST_COMMAND_USAGE); - break; - case SET_GOAL_COMMAND: - Ui.getInstance().showMessage("Usage:\n " + SET_GOAL_COMMAND_USAGE); - break; - case BALANCE_COMMAND: - Ui.getInstance().showMessage("Usage:\n " + BALANCE_COMMAND_USAGE); - break; - case HELP_COMMAND: - Ui.getInstance().showMessage("Usage:\n " + HELP_COMMAND_USAGE); - break; - default: - Ui.getInstance().showMessage("Unknown command, type help for help"); - } + String commandUsage = CommandManager.getInstance().getCommandUsage(commandName.toLowerCase()); + ui.showMessage(HELP_MESSAGE_GENERAL); + ui.showMessage("Usage of " + commandName.toLowerCase() + ":"); + ui.showMessage(commandUsage); } } diff --git a/src/main/java/seedu/financialplanner/commands/InvalidCommand.java b/src/main/java/seedu/financialplanner/commands/InvalidCommand.java deleted file mode 100644 index 428127d638..0000000000 --- a/src/main/java/seedu/financialplanner/commands/InvalidCommand.java +++ /dev/null @@ -1,20 +0,0 @@ -package seedu.financialplanner.commands; - -import seedu.financialplanner.utils.Ui; - -/** - * Represents a command for an invalid input. - */ -public class InvalidCommand extends Command { - public InvalidCommand() { - } - - /** - * Executes the command to display an error message when an - * invalid input is received. - */ - @Override - public void execute() { - Ui.getInstance().showMessage("Unknown command. Type help for help."); - } -} diff --git a/src/main/java/seedu/financialplanner/commands/ListCommand.java b/src/main/java/seedu/financialplanner/commands/ListCommand.java index fdbd4ead80..4cc5f2d132 100644 --- a/src/main/java/seedu/financialplanner/commands/ListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/ListCommand.java @@ -1,18 +1,26 @@ package seedu.financialplanner.commands; -import seedu.financialplanner.enumerations.CashflowCategory; import seedu.financialplanner.cashflow.Cashflow; import seedu.financialplanner.cashflow.CashflowList; import seedu.financialplanner.cashflow.Expense; import seedu.financialplanner.cashflow.Income; +import seedu.financialplanner.commands.utils.Command; +import seedu.financialplanner.commands.utils.RawCommand; +import seedu.financialplanner.enumerations.CashflowCategory; import seedu.financialplanner.utils.Ui; import java.util.ArrayList; import java.util.List; +@SuppressWarnings("unused") public class ListCommand extends Command { + public static final String NAME = "list"; + + public static final String USAGE = + "list [income/expense]"; protected CashflowCategory category = null; - public ListCommand(RawCommand rawCommand) throws IllegalArgumentException{ + + public ListCommand(RawCommand rawCommand) throws IllegalArgumentException { String stringCategory = null; int indexToDelete = 0; ArrayList blankArgsList = new ArrayList<>(); diff --git a/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java b/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java index 7462b2a4a1..80a6e173c5 100644 --- a/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java +++ b/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java @@ -1,12 +1,20 @@ package seedu.financialplanner.commands; -import seedu.financialplanner.goal.WishList; -import seedu.financialplanner.utils.Ui; import seedu.financialplanner.cashflow.CashflowList; -import seedu.financialplanner.goal.Goal; +import seedu.financialplanner.commands.utils.Command; +import seedu.financialplanner.commands.utils.RawCommand; import seedu.financialplanner.enumerations.ExpenseType; +import seedu.financialplanner.goal.Goal; +import seedu.financialplanner.goal.WishList; +import seedu.financialplanner.utils.Ui; + +@SuppressWarnings("unused") public class MarkGoalCommand extends Command { + public static final String NAME = "markgoal"; + + public static final String USAGE = "UNDONE, PLEASE FILL THIS UP!"; private final int index; + public MarkGoalCommand(RawCommand rawCommand) throws IllegalArgumentException { String stringIndex; if (rawCommand.args.size() == 1) { @@ -23,11 +31,11 @@ public MarkGoalCommand(RawCommand rawCommand) throws IllegalArgumentException { if (index == 0) { throw new IllegalArgumentException("Index must be within the list"); } - if (index > WishList.getInstance().list.size()+1){ + if (index > WishList.getInstance().list.size() + 1) { throw new IllegalArgumentException("Index exceed the list size"); } rawCommand.extraArgs.remove("i"); - if(!rawCommand.extraArgs.isEmpty()){ + if (!rawCommand.extraArgs.isEmpty()) { String unknownExtraArgument = new java.util.ArrayList<>(rawCommand.extraArgs.keySet()).get(0); throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); } @@ -35,7 +43,7 @@ public MarkGoalCommand(RawCommand rawCommand) throws IllegalArgumentException { @Override public void execute() { - Goal goal = WishList.getInstance().list.get(index-1); + Goal goal = WishList.getInstance().list.get(index - 1); goal.markAsDone(); Ui.getInstance().showMessage("You have achieved " + goal + System.lineSeparator() + "Congratulations!"); CashflowList.getInstance().addExpense(goal.getAmount(), ExpenseType.OTHERS, 0, goal.getLabel()); diff --git a/src/main/java/seedu/financialplanner/commands/MarkReminderCommand.java b/src/main/java/seedu/financialplanner/commands/MarkReminderCommand.java index e7c428df37..bdf7f36e7a 100644 --- a/src/main/java/seedu/financialplanner/commands/MarkReminderCommand.java +++ b/src/main/java/seedu/financialplanner/commands/MarkReminderCommand.java @@ -1,12 +1,20 @@ package seedu.financialplanner.commands; +import seedu.financialplanner.commands.utils.Command; +import seedu.financialplanner.commands.utils.RawCommand; import seedu.financialplanner.reminder.ReminderList; import seedu.financialplanner.utils.Ui; -public class MarkReminderCommand extends Command{ + +@SuppressWarnings("unused") +public class MarkReminderCommand extends Command { + public static final String NAME = "markreminder"; + + public static final String USAGE = "UNDONE, PLEASE FILL THIS UP!"; private final int index; + public MarkReminderCommand(RawCommand rawCommand) throws IllegalArgumentException { String stringIndex; - if(rawCommand.args.size() == 1) { + if (rawCommand.args.size() == 1) { stringIndex = rawCommand.args.get(0); } else { throw new IllegalArgumentException("Incorrect arguments."); @@ -20,11 +28,11 @@ public MarkReminderCommand(RawCommand rawCommand) throws IllegalArgumentExceptio if (index == 0) { throw new IllegalArgumentException("Index must be within the list"); } - if (index > ReminderList.getInstance().list.size()+1){ + if (index > ReminderList.getInstance().list.size() + 1) { throw new IllegalArgumentException("Index exceed the list size"); } rawCommand.extraArgs.remove("i"); - if(!rawCommand.extraArgs.isEmpty()){ + if (!rawCommand.extraArgs.isEmpty()) { String unknownExtraArgument = new java.util.ArrayList<>(rawCommand.extraArgs.keySet()).get(0); throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); } @@ -32,8 +40,8 @@ public MarkReminderCommand(RawCommand rawCommand) throws IllegalArgumentExceptio @Override public void execute() { - ReminderList.getInstance().list.get(index-1).markAsDone(); - Ui.getInstance().showMessage("You have marked "+ReminderList.getInstance().list.get(index-1)); + ReminderList.getInstance().list.get(index - 1).markAsDone(); + Ui.getInstance().showMessage("You have marked " + ReminderList.getInstance().list.get(index - 1)); } diff --git a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java index e42f0e48d0..87027073ae 100644 --- a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java +++ b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java @@ -3,8 +3,10 @@ import seedu.financialplanner.cashflow.Budget; import seedu.financialplanner.cashflow.Cashflow; import seedu.financialplanner.cashflow.CashflowList; -import seedu.financialplanner.cashflow.Income; import seedu.financialplanner.cashflow.Expense; +import seedu.financialplanner.cashflow.Income; +import seedu.financialplanner.commands.utils.Command; +import seedu.financialplanner.commands.utils.RawCommand; import seedu.financialplanner.reminder.Reminder; import seedu.financialplanner.reminder.ReminderList; import seedu.financialplanner.utils.Ui; @@ -15,7 +17,12 @@ /** * Represents a command to display overview of user's financials. */ +@SuppressWarnings("unused") public class OverviewCommand extends Command { + public static final String NAME = "overview"; + + public static final String USAGE = + "overview"; private static final CashflowList cashflowList = CashflowList.getInstance(); public OverviewCommand(RawCommand rawCommand) { diff --git a/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java b/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java index dbcbd67d23..40126e32e9 100644 --- a/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java @@ -1,9 +1,17 @@ package seedu.financialplanner.commands; +import seedu.financialplanner.commands.utils.Command; +import seedu.financialplanner.commands.utils.RawCommand; import seedu.financialplanner.reminder.ReminderList; import seedu.financialplanner.utils.Ui; -public class ReminderListCommand extends Command{ - public ReminderListCommand(RawCommand rawCommand) throws IllegalArgumentException{ + +@SuppressWarnings("unused") +public class ReminderListCommand extends Command { + public static final String NAME = "reminderlist"; + + public static final String USAGE = "UNDONE, PLEASE FILL THIS UP!"; + + public ReminderListCommand(RawCommand rawCommand) throws IllegalArgumentException { } diff --git a/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java b/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java index d7456f3ceb..d4499f9ba6 100644 --- a/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java +++ b/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java @@ -1,29 +1,37 @@ package seedu.financialplanner.commands; + +import seedu.financialplanner.commands.utils.Command; +import seedu.financialplanner.commands.utils.RawCommand; import seedu.financialplanner.goal.Goal; import seedu.financialplanner.goal.WishList; import seedu.financialplanner.utils.Ui; +@SuppressWarnings("unused") public class SetGoalCommand extends Command { + public static final String NAME = "set"; + + public static final String USAGE = + "set "; private final String label; private final int amount; public SetGoalCommand(RawCommand rawCommand) throws IllegalArgumentException { String labelString = String.join(" ", rawCommand.args); - if(!rawCommand.extraArgs.containsKey("g")){ + if (!rawCommand.extraArgs.containsKey("g")) { throw new IllegalArgumentException("Goal must have an amount"); } - try{ + try { amount = Integer.parseInt(rawCommand.extraArgs.get("g")); - } catch (IllegalArgumentException e){ + } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Amount must be a number"); } rawCommand.extraArgs.remove("g"); - if(!rawCommand.extraArgs.containsKey("l")){ + if (!rawCommand.extraArgs.containsKey("l")) { throw new IllegalArgumentException("Please specify the content of the goal"); } label = rawCommand.extraArgs.get("l"); rawCommand.extraArgs.remove("l"); - if(!rawCommand.extraArgs.isEmpty()){ + if (!rawCommand.extraArgs.isEmpty()) { String unknownExtraArgument = new java.util.ArrayList<>(rawCommand.extraArgs.keySet()).get(0); throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); } diff --git a/src/main/java/seedu/financialplanner/commands/VisCommand.java b/src/main/java/seedu/financialplanner/commands/VisCommand.java index 4e9762ffc2..22450c7952 100644 --- a/src/main/java/seedu/financialplanner/commands/VisCommand.java +++ b/src/main/java/seedu/financialplanner/commands/VisCommand.java @@ -1,7 +1,9 @@ package seedu.financialplanner.commands; -import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.cashflow.CashflowList; +import seedu.financialplanner.commands.utils.Command; +import seedu.financialplanner.commands.utils.RawCommand; +import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.utils.Ui; import seedu.financialplanner.visualisations.Categorizer; import seedu.financialplanner.visualisations.Visualizer; @@ -11,10 +13,15 @@ import java.util.logging.Level; import java.util.logging.Logger; +@SuppressWarnings("unused") public class VisCommand extends Command { + public static final String NAME = "vis"; + + public static final String USAGE = + "vis "; private static final Logger logger = Logger.getLogger("Financial Planner Logger"); - private String type; - private String chart; + private final String type; + private final String chart; public VisCommand(RawCommand rawCommand) throws IllegalArgumentException { if (!rawCommand.extraArgs.containsKey("t")) { diff --git a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java index 16ac46c619..4ec04de47a 100644 --- a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java @@ -1,17 +1,25 @@ package seedu.financialplanner.commands; +import seedu.financialplanner.commands.utils.Command; +import seedu.financialplanner.commands.utils.RawCommand; import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.storage.SaveData; import seedu.financialplanner.utils.Ui; + import java.util.ArrayList; import java.util.logging.Level; import java.util.logging.Logger; +@SuppressWarnings("unused") public class WatchListCommand extends Command { + public static final String NAME = "watchlist"; + + public static final String USAGE = + "watchlist"; private static final Logger logger = Logger.getLogger("Financial Planner Logger"); - public WatchListCommand(RawCommand rawCommand) throws IllegalArgumentException{ + public WatchListCommand(RawCommand rawCommand) throws IllegalArgumentException { if (!rawCommand.extraArgs.isEmpty()) { logger.log(Level.WARNING, "Invalid extra arguments found"); String unknownExtraArgument = new ArrayList<>(rawCommand.extraArgs.keySet()).get(0); diff --git a/src/main/java/seedu/financialplanner/commands/WishListCommand.java b/src/main/java/seedu/financialplanner/commands/WishListCommand.java index 883e484aa0..e3443e5b89 100644 --- a/src/main/java/seedu/financialplanner/commands/WishListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/WishListCommand.java @@ -1,9 +1,17 @@ package seedu.financialplanner.commands; +import seedu.financialplanner.commands.utils.Command; +import seedu.financialplanner.commands.utils.RawCommand; import seedu.financialplanner.goal.WishList; import seedu.financialplanner.utils.Ui; + +@SuppressWarnings("unused") public class WishListCommand extends Command { - public WishListCommand(RawCommand rawCommand) throws IllegalArgumentException{ + public static final String NAME = "wishlist"; + + public static final String USAGE = "UNDONE, PLEASE FILL THIS UP!"; + + public WishListCommand(RawCommand rawCommand) throws IllegalArgumentException { } diff --git a/src/main/java/seedu/financialplanner/commands/Command.java b/src/main/java/seedu/financialplanner/commands/utils/Command.java similarity index 76% rename from src/main/java/seedu/financialplanner/commands/Command.java rename to src/main/java/seedu/financialplanner/commands/utils/Command.java index 6b7b7e3e74..39c9779812 100644 --- a/src/main/java/seedu/financialplanner/commands/Command.java +++ b/src/main/java/seedu/financialplanner/commands/utils/Command.java @@ -1,4 +1,4 @@ -package seedu.financialplanner.commands; +package seedu.financialplanner.commands.utils; /** * Represents a generic command that can be inherited. diff --git a/src/main/java/seedu/financialplanner/commands/utils/CommandManager.java b/src/main/java/seedu/financialplanner/commands/utils/CommandManager.java new file mode 100644 index 0000000000..44f6e72cb7 --- /dev/null +++ b/src/main/java/seedu/financialplanner/commands/utils/CommandManager.java @@ -0,0 +1,82 @@ +package seedu.financialplanner.commands.utils; + +import org.reflections.Reflections; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; + +public class CommandManager { + + public static final String COMMAND_CLASS_USAGE_FIELD_NAME = "USAGE"; + + public static final String COMMAND_CLASS_NAME_FIELD_NAME = "NAME"; + private static final String COMMAND_PACKAGE_NAME = "seedu.financialplanner.commands"; + + private static final CommandManager instance = new CommandManager(); + private final Map> nameCommandMap = new HashMap<>(); + + private CommandManager() { + Reflections reflections = new Reflections(COMMAND_PACKAGE_NAME); + Set> commandClasses = reflections.getSubTypesOf(Command.class); + for (Class c : commandClasses) { + if (!Command.class.isAssignableFrom(c)) { + continue; + } + try { + String commandName = (String) c.getField(COMMAND_CLASS_NAME_FIELD_NAME).get(null); + if (nameCommandMap.containsKey(commandName)) { + throw new RuntimeException("Adding command with duplicate name: " + commandName); + } + nameCommandMap.put(commandName, c); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + } + + public static CommandManager getInstance() { + return instance; + } + + @SuppressWarnings("unused") + public Class getCommandClass(String commandName) throws NoSuchElementException { + if (!nameCommandMap.containsKey(commandName)) { + throw new NoSuchElementException("Command not found!"); + } + return nameCommandMap.get(commandName); + } + + @SuppressWarnings("unused") + public String getCommandUsage(Class commandClass) throws NoSuchElementException { + try { + Field usageField = commandClass.getField(COMMAND_CLASS_USAGE_FIELD_NAME); + return (String) usageField.get(null); + } catch (ClassCastException | NoSuchFieldException | IllegalAccessException e) { + throw new IllegalArgumentException("Cannot get command usage. Is there a bug?"); + } + } + + @SuppressWarnings("unused") + public String getCommandUsage(String commandName) throws NoSuchElementException { + try { + return getCommandUsage(getCommandClass(commandName)); + } catch (Exception e) { + throw new NoSuchElementException(e.getMessage()); + } + } + + @SuppressWarnings("unused") + public Set getCommandNames() { + return nameCommandMap.keySet(); + } + + @SuppressWarnings("unused") + public Set> getCommandClasses() { + return new HashSet<>(nameCommandMap.values()); + } + +} diff --git a/src/main/java/seedu/financialplanner/commands/RawCommand.java b/src/main/java/seedu/financialplanner/commands/utils/RawCommand.java similarity index 93% rename from src/main/java/seedu/financialplanner/commands/RawCommand.java rename to src/main/java/seedu/financialplanner/commands/utils/RawCommand.java index ac6e3800be..da4e26bd66 100644 --- a/src/main/java/seedu/financialplanner/commands/RawCommand.java +++ b/src/main/java/seedu/financialplanner/commands/utils/RawCommand.java @@ -1,4 +1,4 @@ -package seedu.financialplanner.commands; +package seedu.financialplanner.commands.utils; import java.util.ArrayList; import java.util.HashMap; diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index 5c419372a9..d0cf6a04ed 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -1,116 +1,56 @@ package seedu.financialplanner.utils; -import seedu.financialplanner.commands.Command; -import seedu.financialplanner.commands.AddStockCommand; -import seedu.financialplanner.commands.HelpCommand; -import seedu.financialplanner.commands.OverviewCommand; -import seedu.financialplanner.commands.AddCashflowCommand; -import seedu.financialplanner.commands.DeleteCashflowCommand; -import seedu.financialplanner.commands.ExitCommand; -import seedu.financialplanner.commands.FindCommand; -import seedu.financialplanner.commands.InvalidCommand; -import seedu.financialplanner.commands.ListCommand; -import seedu.financialplanner.commands.RawCommand; -import seedu.financialplanner.commands.WatchListCommand; -import seedu.financialplanner.commands.VisCommand; -import seedu.financialplanner.commands.BudgetCommand; -import seedu.financialplanner.commands.AddReminderCommand; -import seedu.financialplanner.commands.SetGoalCommand; -import seedu.financialplanner.commands.BalanceCommand; -import seedu.financialplanner.commands.DeleteStockCommand; -import seedu.financialplanner.commands.MarkGoalCommand; -import seedu.financialplanner.commands.MarkReminderCommand; -import seedu.financialplanner.commands.DeleteGoalCommand; -import seedu.financialplanner.commands.DeleteReminderCommand; -import seedu.financialplanner.commands.ReminderListCommand; -import seedu.financialplanner.commands.WishListCommand; +import seedu.financialplanner.commands.utils.Command; +import seedu.financialplanner.commands.utils.CommandManager; +import seedu.financialplanner.commands.utils.RawCommand; import seedu.financialplanner.exceptions.FinancialPlannerException; +import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.NoSuchElementException; public class Parser { - public static final String EXIT_COMMAND = "exit"; - public static final String WATCHLIST_COMMAND = "watchlist"; - public static final String ADD_CASHFLOW_COMMAND = "add"; - public static final String DELETE_CASHFLOW_COMMAND = "delete"; - public static final String ADD_STOCK_COMMAND = "addstock"; - public static final String DELETE_STOCK_COMMAND = "deletestock"; - public static final String FIND_COMMAND = "find"; - public static final String OVERVIEW_COMMAND = "overview"; - public static final String BUDGET_COMMAND = "budget"; - public static final String VISUALIZATION_COMMAND = "vis"; - public static final String ADD_REMINDER_COMMAND = "addreminder"; - public static final String LIST_COMMAND = "list"; - public static final String SET_GOAL_COMMAND = "set"; - public static final String BALANCE_COMMAND = "balance"; - public static final String MARK_GOAL_COMMAND = "markgoal"; - public static final String MARK_REMINDER_COMMAND = "markreminder"; - public static final String DELETE_GOAL_COMMAND = "deletegoal"; - public static final String DELETE_REMINDER_COMMAND = "deletereminder"; - public static final String REMINDER_LIST_COMMAND = "reminderlist"; - public static final String WISH_LIST_COMMAND = "wishlist"; - public static final String HELP_COMMAND = "help"; - public static Command parseCommand(String input) throws FinancialPlannerException { RawCommand rawCommand = parseRawCommand(input); return parseCommand(rawCommand); } public static Command parseCommand(RawCommand rawCommand) throws FinancialPlannerException { - switch (rawCommand.getCommandName()) { - case EXIT_COMMAND: - return new ExitCommand(rawCommand); - case WATCHLIST_COMMAND: - return new WatchListCommand(rawCommand); - case ADD_CASHFLOW_COMMAND: - return new AddCashflowCommand(rawCommand); - case DELETE_CASHFLOW_COMMAND: - return new DeleteCashflowCommand(rawCommand); - case ADD_STOCK_COMMAND: - return new AddStockCommand(rawCommand); - case DELETE_STOCK_COMMAND: - return new DeleteStockCommand(rawCommand); - case FIND_COMMAND: - return new FindCommand(rawCommand); - case BUDGET_COMMAND: - return new BudgetCommand(rawCommand); - case VISUALIZATION_COMMAND: - return new VisCommand(rawCommand); - case OVERVIEW_COMMAND: - return new OverviewCommand(rawCommand); - case ADD_REMINDER_COMMAND: - return new AddReminderCommand(rawCommand); - case LIST_COMMAND: - return new ListCommand(rawCommand); - case SET_GOAL_COMMAND: - return new SetGoalCommand(rawCommand); - case BALANCE_COMMAND: - return new BalanceCommand(rawCommand); - case MARK_GOAL_COMMAND: - return new MarkGoalCommand(rawCommand); - case MARK_REMINDER_COMMAND: - return new MarkReminderCommand(rawCommand); - case DELETE_GOAL_COMMAND: - return new DeleteGoalCommand(rawCommand); - case DELETE_REMINDER_COMMAND: - return new DeleteReminderCommand(rawCommand); - case REMINDER_LIST_COMMAND: - return new ReminderListCommand(rawCommand); - case WISH_LIST_COMMAND: - return new WishListCommand(rawCommand); - case HELP_COMMAND: - return new HelpCommand(rawCommand); - default: - return new InvalidCommand(); + CommandManager commandManager = CommandManager.getInstance(); + Class commandClass; + + try { + commandClass = commandManager.getCommandClass(rawCommand.getCommandName().toLowerCase()); + } catch (NoSuchElementException e) { + throw new FinancialPlannerException("Unknown command. Type help for help."); + } catch (Exception e) { + throw new FinancialPlannerException(e.getMessage()); + } + + Constructor constructorWithRawCommand; + Constructor constructorWithNothing; + + try { + constructorWithRawCommand = commandClass.getConstructor(RawCommand.class); + return constructorWithRawCommand.newInstance(rawCommand); + } catch (NoSuchMethodException noConstructorWithRawCommandException) { + try { + constructorWithNothing = commandClass.getConstructor(); + return constructorWithNothing.newInstance(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } catch (Exception e) { + throw new RuntimeException(e); } } - public static RawCommand parseRawCommand(String input) throws IllegalArgumentException{ + public static RawCommand parseRawCommand(String input) throws IllegalArgumentException { Iterator iterator = Arrays.stream(input.split(" ")).iterator(); if (!iterator.hasNext()) { throw new IllegalArgumentException("Command cannot be empty"); From 932b6e9fcc7a5dccf3ba8e5b3e4764912fad299b Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Wed, 8 Nov 2023 00:11:43 +0800 Subject: [PATCH 418/518] Update DG and UG --- docs/DeveloperGuide.md | 23 ++++++++++++++++++-- docs/UserGuide.md | 2 +- docs/diagrams/ArchitectureDiagram.puml | 29 +++++++++++++++++++++++++ docs/images/ArchitectureDiagram.png | Bin 0 -> 17350 bytes docs/team/ryan1604.md | 11 +++++++++- 5 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 docs/diagrams/ArchitectureDiagram.puml create mode 100644 docs/images/ArchitectureDiagram.png diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index fbd8f1682f..9ec20c3e81 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -4,6 +4,7 @@ * [Acknowledgements](#acknowledgements) * [Design & implementation](#design--implementation) + * [Architecture Diagram](#architecture-diagram) * [Storage Component](#storage-component) * [Design considerations](#design-considerations) * [Visualization Feature](#visualization-feature-) @@ -70,7 +71,23 @@ ## Design & implementation -{Describe the design and implementation of the product. Use UML diagrams and short code snippets where applicable.} +### Architecture Diagram + +![](images/ArchitectureDiagram.png) + +The **Architecture Diagram** given above explains the high-level design of the program. + +#### Main components of the architecture + +`Main` consists of the `FinancialPlanner` class, and is in charge of starting up and shutting down the app. + +The program consists of five main components: + +* `Ui`: User interactions. +* `Parser`: Parse user inputs. +* `Command`: The command executor. +* `Model`: Holds the data of the program in memory. +* `Storage`: Reads data from, and writes data to the hard disk. ### Storage Component @@ -336,7 +353,9 @@ Example: `budget view` ## Non-Functional Requirements -{Give non-functional requirements} +* Should work on main OS (Windows, Linux, Mac) that has Java 11 installed. +* This app is meant for a single user. +* This app targeted towards users with an above-average typing speed. ## Glossary diff --git a/docs/UserGuide.md b/docs/UserGuide.md index bbc8adcdc7..a22894de0b 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -817,7 +817,7 @@ Existing data will be automatically loaded when the program starts up. **Q**: How do I transfer my data to another computer? -**A**: {your answer here} +**A**: Copy the /data/ folder from the home folder to the other computer. **Q**: Should I edit the watchlist.json file? diff --git a/docs/diagrams/ArchitectureDiagram.puml b/docs/diagrams/ArchitectureDiagram.puml new file mode 100644 index 0000000000..9d996c1c75 --- /dev/null +++ b/docs/diagrams/ArchitectureDiagram.puml @@ -0,0 +1,29 @@ +@startuml +!include +!include style.puml + +package "" as f { +Class Ui #blue +Class Parser #Magenta +Class Model #DeepPink +Class Main #PowderBlue +Class Storage #SpringGreen +Class Command #Grey +} + +Class User #red +Class "<$documents>" as File #Lime + +User -down-> Ui +Ui --> Parser +Ui <--> Main +Ui <--> Storage +Main --> Storage +Main --> Parser +Main --> Command +Parser --> Command +Command --> Model + +Storage -left-> File + +@enduml \ No newline at end of file diff --git a/docs/images/ArchitectureDiagram.png b/docs/images/ArchitectureDiagram.png new file mode 100644 index 0000000000000000000000000000000000000000..8871e46cd7de4d385b0a3a72d55645d4f31dae66 GIT binary patch literal 17350 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 literal 0 HcmV?d00001 diff --git a/docs/team/ryan1604.md b/docs/team/ryan1604.md index e19125aaa8..27a94b1489 100644 --- a/docs/team/ryan1604.md +++ b/docs/team/ryan1604.md @@ -24,6 +24,7 @@ you a one-stop interface to access a plethora of features to manage your finance * Saving and loading data components * Introduction * Command summary for my features +* Part of FAQ ### Contributions to the DG: @@ -32,9 +33,17 @@ you a one-stop interface to access a plethora of features to manage your finance * Class diagram * Design considerations * Budget feature + * Implementation + * Sequence diagrams +* Non-functional requirements +* Architecture Diagram ### Contributions to team-based tasks: +* Set up GitHub team org/repo +* Manage releases +* Equal share of workflow processes on GitHub (review PRs, maintain issue tracker) + ### Review/Mentoring contributions: * Reviewed teammates code (giving suggestions and improvements) @@ -42,4 +51,4 @@ you a one-stop interface to access a plethora of features to manage your finance ### Contributions beyond the project team: * Reviewed UG & DG of other teams. -* Product testing for other teams. \ No newline at end of file +* Product system and acceptance testing for other teams. \ No newline at end of file From 700392d5d2bea6ef9856cd40c989fb5a3b98eff8 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Wed, 8 Nov 2023 00:39:13 +0800 Subject: [PATCH 419/518] Fix bug --- .../java/seedu/financialplanner/commands/BudgetCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java index f9f2febbde..ebede7f307 100644 --- a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java +++ b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java @@ -28,7 +28,7 @@ public BudgetCommand(RawCommand rawCommand) throws FinancialPlannerException { if (rawCommand.args.isEmpty()) { throw new FinancialPlannerException("Budget operation cannot be empty."); } - command = rawCommand.args.get(0); + command = String.join(" ", rawCommand.args).trim(); if (command.equals("delete") || command.equals("reset") || command.equals("view")) { return; } From 578564cd4a2cbb645d88c6fb6e35e741daa14afe Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Wed, 8 Nov 2023 09:17:46 +0800 Subject: [PATCH 420/518] Update Architecture Diagram and fix typo --- docs/DeveloperGuide.md | 2 +- docs/diagrams/ArchitectureDiagram.puml | 12 ++++++------ docs/images/ArchitectureDiagram.png | Bin 17350 -> 17887 bytes 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 9ec20c3e81..6188241385 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -355,7 +355,7 @@ Example: `budget view` * Should work on main OS (Windows, Linux, Mac) that has Java 11 installed. * This app is meant for a single user. -* This app targeted towards users with an above-average typing speed. +* This app is targeted towards users with an above-average typing speed. ## Glossary diff --git a/docs/diagrams/ArchitectureDiagram.puml b/docs/diagrams/ArchitectureDiagram.puml index 9d996c1c75..a40f4a0cd5 100644 --- a/docs/diagrams/ArchitectureDiagram.puml +++ b/docs/diagrams/ArchitectureDiagram.puml @@ -4,15 +4,15 @@ package "" as f { Class Ui #blue -Class Parser #Magenta -Class Model #DeepPink -Class Main #PowderBlue -Class Storage #SpringGreen +Class Parser #DarkMagenta +Class Model #Crimson +Class Main #LightSkyBlue +Class Storage #Green Class Command #Grey } -Class User #red -Class "<$documents>" as File #Lime +Class User #IndianRed +Class "<$documents>" as File #DarkOliveGreen User -down-> Ui Ui --> Parser diff --git a/docs/images/ArchitectureDiagram.png b/docs/images/ArchitectureDiagram.png index 8871e46cd7de4d385b0a3a72d55645d4f31dae66..7ab8365d792feb348489ff7cb56bea0126ba8eb0 100644 GIT binary patch literal 17887 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 U4JY_ZD_D2s@88b7W$5?60qX(d;Q#;t literal 17350 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 From 2f2a764bc7045ef07c7fcfcb045221d6d3295e1e Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Wed, 8 Nov 2023 21:16:49 +0800 Subject: [PATCH 421/518] Add javadoc to classes and methods --- .../commands/AddStockCommand.java | 13 ++++ .../commands/DeleteStockCommand.java | 15 ++++ .../financialplanner/commands/VisCommand.java | 15 ++++ .../commands/WatchListCommand.java | 13 ++++ .../financialplanner/investments/Stock.java | 29 +++++++ .../investments/WatchList.java | 77 +++++++++++++++++++ .../financialplanner/storage/LoadData.java | 5 ++ .../financialplanner/storage/SaveData.java | 4 + .../visualisations/Categorizer.java | 26 +++++++ .../visualisations/Visualizer.java | 32 ++++++++ 10 files changed, 229 insertions(+) diff --git a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java index 37328afa6a..8d4f68837f 100644 --- a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java @@ -8,10 +8,20 @@ import java.util.logging.Level; import java.util.logging.Logger; +/** + * Command that inherits from the Command abstract class + * Represents that command that add stock to watchlist + */ public class AddStockCommand extends Command { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private final String stockCode; + /** + * Constructor for the command add stock to watchlist + * + * @param rawCommand + * @throws IllegalArgumentException + */ public AddStockCommand(RawCommand rawCommand) throws IllegalArgumentException { if (!rawCommand.extraArgs.containsKey("s")) { throw new IllegalArgumentException("Stock code cannot be empty"); @@ -28,6 +38,9 @@ public AddStockCommand(RawCommand rawCommand) throws IllegalArgumentException { } } + /** + * Executes the command to add stock to watchlist + */ @Override public void execute() { Ui ui = Ui.getInstance(); diff --git a/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java index 1ffbbb0aed..d09453b973 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java @@ -8,10 +8,20 @@ import java.util.logging.Level; import java.util.logging.Logger; +/** + * Command that inherits from the Command abstract class + * Represents the command to delete stock from watchlist + */ public class DeleteStockCommand extends Command { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private final String stockCode; + /** + * Constructor for the command to delete stock from watchlist + * + * @param rawCommand + * @throws IllegalArgumentException + */ public DeleteStockCommand(RawCommand rawCommand) throws IllegalArgumentException { if (!rawCommand.extraArgs.containsKey("s")) { throw new IllegalArgumentException("Stock code cannot be empty"); @@ -28,6 +38,11 @@ public DeleteStockCommand(RawCommand rawCommand) throws IllegalArgumentException } } + /** + * Executes the command to delete stock from watchlist + * + * @throws Exception + */ @Override public void execute() throws Exception { Ui ui = Ui.getInstance(); diff --git a/src/main/java/seedu/financialplanner/commands/VisCommand.java b/src/main/java/seedu/financialplanner/commands/VisCommand.java index 4e9762ffc2..dffdbd2dcb 100644 --- a/src/main/java/seedu/financialplanner/commands/VisCommand.java +++ b/src/main/java/seedu/financialplanner/commands/VisCommand.java @@ -11,11 +11,21 @@ import java.util.logging.Level; import java.util.logging.Logger; +/** + * Command class that inherit from Command abstract class + * Represents the command to visualize your cash flow + */ public class VisCommand extends Command { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private String type; private String chart; + /** + * Constructor for the command to visualize cash flow + * + * @param rawCommand + * @throws IllegalArgumentException + */ public VisCommand(RawCommand rawCommand) throws IllegalArgumentException { if (!rawCommand.extraArgs.containsKey("t")) { throw new IllegalArgumentException("Entry type must be defined"); @@ -35,6 +45,11 @@ public VisCommand(RawCommand rawCommand) throws IllegalArgumentException { } } + /** + * Executes the command to visualize cash flow + * + * @throws FinancialPlannerException + */ @Override public void execute() throws FinancialPlannerException { Ui ui = Ui.getInstance(); diff --git a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java index 16ac46c619..2c1e997ce7 100644 --- a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java @@ -8,9 +8,19 @@ import java.util.logging.Level; import java.util.logging.Logger; +/** + * Command that inherits from Command abstract class + * Represents the command to fetch and display watchlist data + */ public class WatchListCommand extends Command { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); + /** + * Constructor for the command to fetch and display watchlist data + * + * @param rawCommand + * @throws IllegalArgumentException + */ public WatchListCommand(RawCommand rawCommand) throws IllegalArgumentException{ if (!rawCommand.extraArgs.isEmpty()) { logger.log(Level.WARNING, "Invalid extra arguments found"); @@ -20,6 +30,9 @@ public WatchListCommand(RawCommand rawCommand) throws IllegalArgumentException{ } } + /** + * Executes the command to fetch and display watchlist data + */ @Override public void execute() { Ui ui = Ui.getInstance(); diff --git a/src/main/java/seedu/financialplanner/investments/Stock.java b/src/main/java/seedu/financialplanner/investments/Stock.java index 7f7f086d68..8379e6a42c 100644 --- a/src/main/java/seedu/financialplanner/investments/Stock.java +++ b/src/main/java/seedu/financialplanner/investments/Stock.java @@ -16,6 +16,9 @@ import java.util.logging.Level; import java.util.logging.Logger; +/** + * Represents a stock within the financial planner app + */ public class Stock { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private static final String API_ENDPOINT = "https://www.alphavantage.co/query?function=SYMBOL_SEARCH&keywords="; @@ -30,11 +33,24 @@ public class Stock { private Date lastUpdated = null; private long lastFetched = 0; + /** + * Constructor for stock that sets the symbol and searches the api + * for stock name for it + * + * @param symbol + * @throws FinancialPlannerException + */ public Stock(String symbol) throws FinancialPlannerException { this.symbol = symbol; this.stockName = getStockNameFromAPI(symbol); } + /** + * Constructor that sets the symbol and stock name directly + * + * @param symbol + * @param stockName + */ public Stock(String symbol, String stockName) { this.symbol = symbol; this.stockName = stockName; @@ -44,6 +60,14 @@ public String getStockName() { return stockName; } + /** + * Method that gets the stock name from the Alpha vantage api. Will throw financial planner exception for any errors + * when attempting this. If succuessful, will return the stock name for the symbol provided + * + * @param symbol + * @return stock name + * @throws FinancialPlannerException + */ public String getStockNameFromAPI(String symbol) throws FinancialPlannerException { String requestURI = String.format("%s%s&apikey=%s", API_ENDPOINT,symbol,API_KEY); HttpClient client = HttpClient.newHttpClient(); @@ -102,6 +126,11 @@ public void setSymbol(String symbol) { this.symbol = symbol; } + /** + * toString method is override to output its symbol appended with a comma + * + * @return + */ @Override public String toString() { return symbol + ","; diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index e18d7db483..d13de784df 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -20,6 +20,9 @@ import java.util.logging.Level; import java.util.logging.Logger; +/** + * Class that represents the watchlist in the financial planner app + */ public class WatchList { private static WatchList watchlist = null; private static Logger logger = Logger.getLogger("Financial Planner Logger"); @@ -27,11 +30,20 @@ public class WatchList { private static final String API_KEY = "iFumtYryBCbHpS3sDqLdVKi2SdP63vSV"; private HashMap stocks; + /** + * Constructor for the watchlist. It will load up the watchlist data from watchlist.json file and clean up + * any erroneous inputs + */ private WatchList() { stocks = LoadData.loadWatchList(); cleanUpLoadedWatchList(); } + /** + * Method that helps to clean up the watchlist loaded up after application start up + * If watchlist stocks is null, it will help to initialize a new base watchlist. + * It will call another method checkValidStock to clean up the watchlist stocks loaded if it is not empty + */ private void cleanUpLoadedWatchList() { if (stocks == null) { stocks = initalizeNewWatchlist(); @@ -43,6 +55,14 @@ private void cleanUpLoadedWatchList() { } } + /** + * Checks the validity of the stock key, and the Stock class value in the watchlist stocks hashmap + * If it is not valid, it will return false + * + * @param key + * @param stockToCheck + * @return + */ private boolean checkValidStock(String key, Stock stockToCheck) { if (stockToCheck.getStockName() == null || stockToCheck.getSymbol() == null) { return false; @@ -50,6 +70,11 @@ private boolean checkValidStock(String key, Stock stockToCheck) { return key.equals(stockToCheck.getSymbol()); } + /** + * Initialize a new watchlist stocks hashmap with base stocks (AAPL and GOOGL) + * + * @return + */ public HashMap initalizeNewWatchlist() { HashMap baseStocks = new HashMap<>(); Ui.getInstance().showMessage("Initializing New watchlist.. adding AAPL and GOOGL for your reference"); @@ -65,6 +90,11 @@ public HashMap initalizeNewWatchlist() { return baseStocks; } + /** + * Method to get the watchlist singleton or create one if it does not exist and returns it + * + * @return + */ public static WatchList getInstance() { if (watchlist == null) { watchlist = new WatchList(); @@ -72,11 +102,22 @@ public static WatchList getInstance() { return watchlist; } + /** + * Method to get the latest watchlist info such as price and daily lowest + * + * @throws FinancialPlannerException + */ public void getLatestWatchlistInfo() throws FinancialPlannerException { StringBuilder queryStocks = getExpiredStocks(); fetchFMPStockPrices(queryStocks); } + /** + * Checks the watchlist stocks hashmap for stocks that are expired meaning their data should be refreshed using + * the api. Returns a string of stocks that are expired separated by a comma + * + * @return + */ public StringBuilder getExpiredStocks() { StringBuilder queryStocks = new StringBuilder(); long currentTime = System.currentTimeMillis(); @@ -91,6 +132,14 @@ public StringBuilder getExpiredStocks() { return queryStocks; } + /** + * Request the Financial Modeling prep API for the latest stock info using the query stocks parameter passed in + * by the getExpiredStocks method. Will throw a FinancialPlannerException if an error is encountered in the attempt + * If the attempt is successful, it will update the stock information in the watchlist stocks. + * + * @param queryStocks + * @throws FinancialPlannerException + */ public void fetchFMPStockPrices(StringBuilder queryStocks) throws FinancialPlannerException { if (stocks.isEmpty()) { throw new FinancialPlannerException("Empty Watchlist. Nothing to display..."); @@ -132,6 +181,12 @@ public void fetchFMPStockPrices(StringBuilder queryStocks) throws FinancialPlann } } + /** + * Method to extract out required information from the full JSON array received from the API + * + * @param jsonstocks + * @throws FinancialPlannerException + */ public void extractWatchlistInfoFromJSONArray(JSONArray jsonstocks) throws FinancialPlannerException { if (jsonstocks == null) { throw new FinancialPlannerException("Incorrect API Response Received. Please try again"); @@ -149,6 +204,14 @@ public void extractWatchlistInfoFromJSONArray(JSONArray jsonstocks) throws Finan } } + /** + * Method called by extractWatchlistInfoFromJSONArray to set stock info for individual stocks using information + * obtained from the API (eg. setting latest price) + * + * @param stock + * @param stockLocal + * @param fetchTime + */ public void extractStockInfoFromJSONObject(JSONObject stock, Stock stockLocal, long fetchTime) { stockLocal.setLastFetched(fetchTime); @@ -173,6 +236,13 @@ public void extractStockInfoFromJSONObject(JSONObject stock, Stock stockLocal, l stockLocal.setLastUpdated(new Date(lastUpdated)); } + /** + * Method used to add a new stock to the watchlist that has the stockCode given by the parameter provided + * + * @param stockCode + * @return + * @throws FinancialPlannerException + */ public String addStock(String stockCode) throws FinancialPlannerException { if (stocks.size() >= 5) { throw new FinancialPlannerException("Watchlist is full (max 5). Delete a stock to add a new one"); @@ -192,6 +262,13 @@ public String addStock(String stockCode) throws FinancialPlannerException { return newStock.getStockName(); } + /** + * Method for deleting a stock from the watchlist that has the stockCode given by the parameter provided + * + * @param stockCode + * @return + * @throws FinancialPlannerException + */ public String deleteStock(String stockCode) throws FinancialPlannerException { if (stocks.isEmpty()) { throw new FinancialPlannerException("No stock in watchlist!"); diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index dce3a6781e..b58c626b2f 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -321,6 +321,11 @@ private static String getDescription(String[] split, int index) { return description; } + /** + * Load the watchlist.json file into the application on startup as a hashmap. + * + * @return + */ public static HashMap loadWatchList() { Ui ui = Ui.getInstance(); Gson gson = new Gson(); diff --git a/src/main/java/seedu/financialplanner/storage/SaveData.java b/src/main/java/seedu/financialplanner/storage/SaveData.java index ccba165c0a..84d1ab9230 100644 --- a/src/main/java/seedu/financialplanner/storage/SaveData.java +++ b/src/main/java/seedu/financialplanner/storage/SaveData.java @@ -44,6 +44,10 @@ public static void save(String filePath) throws FinancialPlannerException { } } + /** + * Method to save the current watchlist to watchlist.json file + * + */ public static void saveWatchList() { Ui ui = Ui.getInstance(); WatchList wl = WatchList.getInstance(); diff --git a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java index dc532b84d5..dc5aad9707 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java @@ -10,9 +10,23 @@ import java.util.logging.Level; import java.util.logging.Logger; + +/** + * Class that is used to sort the cash flow list into different categories according to the type they are + * (Income, Expense) + */ public class Categorizer { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); + /** + * Method that calls the required methods to sort the cash flow based on the type is specified by the user + * (Income, Expense) + * + * @param cashflowList + * @param type + * @return + * @throws FinancialPlannerException + */ public static HashMap sortType(CashflowList cashflowList, String type) throws FinancialPlannerException { switch (type) { @@ -27,6 +41,12 @@ public static HashMap sortType(CashflowList cashflowList, String } } + /** + * Method to sort the expenses of the cash flow list into different categories and return the sorted hashmap + * + * @param cashflowList + * @return + */ public static HashMap sortExpenses(CashflowList cashflowList) { HashMap expensesByCat = new HashMap<>(); for (Cashflow e: cashflowList.list) { @@ -40,6 +60,12 @@ public static HashMap sortExpenses(CashflowList cashflowList) { return expensesByCat; } + /** + * Method to sort the incomes of the cash flow list into different categories and return the sorted hashmap + * + * @param cashflowList + * @return + */ public static HashMap sortIncome(CashflowList cashflowList) { HashMap incomeByCat = new HashMap<>(); for (Cashflow e: cashflowList.list) { diff --git a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java index 682dbc0e8e..10c9a0a3f9 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java @@ -24,9 +24,22 @@ import java.util.logging.Level; import java.util.logging.Logger; +/** + * Class the helps to output the visualization of the cash flow to the user so that the user can easily view their + * expense/income based on types + */ public class Visualizer { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); + /** + * Method that calls the appropriate method for printing the different visualizations tools based on the + * preference of the user (pie,bar,radar) + * + * @param chart + * @param cashFlowByCat + * @param type + * @throws FinancialPlannerException + */ public static void displayChart(String chart, HashMap cashFlowByCat, String type) throws FinancialPlannerException { switch (chart) { @@ -44,6 +57,12 @@ public static void displayChart(String chart, HashMap cashFlowBy } } + /** + * Method to display the pier chart to the screen + * + * @param cashflowByCat + * @param type + */ public static void displayPieChart (HashMap cashflowByCat, String type) { PieChart chart = new PieChartBuilder().width(800).height(600) .title(StringUtils.capitalize(type) + " Chart") @@ -72,6 +91,12 @@ public static void displayPieChart (HashMap cashflowByCat, Strin ); } + /** + * Method to display the bar chart to the screen + * + * @param cashflowByCat + * @param type + */ public static void displayBarChart (HashMap cashflowByCat, String type) { CategoryChart chart = new CategoryChartBuilder().width(800).height(600) .title(StringUtils.capitalize(type) + " Chart") @@ -99,6 +124,13 @@ public static void displayBarChart (HashMap cashflowByCat, Strin } + /** + * Method to display the radar chart to the screen + * + * @param cashflowByCat + * @param type + * @throws FinancialPlannerException + */ public static void displayRadarChart (HashMap cashflowByCat, String type) throws FinancialPlannerException { RadarChart radarChart = new RadarChartBuilder().width(800).height(600) From 8660d422247a2824706a05c55ad9d6e761c3f1d6 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Wed, 8 Nov 2023 21:29:21 +0800 Subject: [PATCH 422/518] Add DG value proposition and user profile --- docs/DeveloperGuide.md | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 6188241385..2481091dec 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -338,18 +338,32 @@ Example: `budget view` ## Product scope ### Target user profile -{Describe the target user profile} +Our target user profile is ... +- a working adult with a source of income +- someone who dislike navigating graphic user interface +- someone who can type fast +- someone who cannot manage their finances such as income and expenses properly +- unable to reach their financial goals +- is slightly interested in the equity market + ### Value proposition -{Describe the value proposition: what problem does it solve?} +Our financial planner application can help individuals manage their finances effectively and achieve their financial +goals. The purpose of such an application is to provide users with a range of tools and features to help them better +understand their financial situation. This will enable them to make more informed decisions, and plan for their future +financial well-being. The application will allow the user to keep track of their income, expenses and overall balance. +It also lets user view their income and expenses using visualization tool to have a better view of their cash flow based +on categories. It also allows the user to set the budget for the month. It also allows users to add their financial +goals to the wishlist. Furthermore, it allows users to track the stock market if they have interest in investing in +equities. ## User Stories -|Version| As a ... | I want to ... | So that I can ...| -|--------|----------|---------------|------------------| -|v1.0|new user|see usage instructions|refer to them when I forget how to use the application| -|v2.0|user|find a to-do item by name|locate a to-do without having to go through the entire list| +| Version | As a ... | I want to ... | So that I can ... | +|---------|----------|---------------------------|-------------------------------------------------------------| +| v1.0 | new user | see usage instructions | refer to them when I forget how to use the application | +| v2.0 | user | find a to-do item by name | locate a to-do without having to go through the entire list | ## Non-Functional Requirements From e3d3d0061f8e4169011ff593a182fe3c317c2d77 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Wed, 8 Nov 2023 22:19:12 +0800 Subject: [PATCH 423/518] Add user stories --- docs/DeveloperGuide.md | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 2481091dec..ab43ef8b1d 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -345,6 +345,7 @@ Our target user profile is ... - someone who cannot manage their finances such as income and expenses properly - unable to reach their financial goals - is slightly interested in the equity market +- needs reminders for tasks ### Value proposition @@ -356,20 +357,50 @@ financial well-being. The application will allow the user to keep track of their It also lets user view their income and expenses using visualization tool to have a better view of their cash flow based on categories. It also allows the user to set the budget for the month. It also allows users to add their financial goals to the wishlist. Furthermore, it allows users to track the stock market if they have interest in investing in -equities. +equities. ## User Stories -| Version | As a ... | I want to ... | So that I can ... | -|---------|----------|---------------------------|-------------------------------------------------------------| -| v1.0 | new user | see usage instructions | refer to them when I forget how to use the application | -| v2.0 | user | find a to-do item by name | locate a to-do without having to go through the entire list | +| Version | As a ... | I want to ... | So that I can ... | +|---------|-----------------------|-------------------------------|--------------------------------------------------------------------------------------| +| v1.0 | user | Add my income | Store my income information and view/track them later | +| v1.0 | user | Delete my income | Remove the income entry that I have mistakenly added or do not keep track | +| v1.0 | user | Add my expense | Store my expense information and view/track them later | +| v1.0 | user | Delete my expense | Remove the expense entry that I have mistakenly added or do not keep track | +| v2.0 | user | set my expense type | Break down my expenses into different categories | +| v1.0 | user | set my income type | Break down my income into different categories | +| v2.0 | user | Add recurring cash flows | add a regular expense or income (salary, rent) easily | +| v2.0 | user | Delete recurring cash flows | delete a regular expense of income easily | +| v1.0 | user | list all cash flow entries | view all my income and expenses in a comprehensive list | +| v1.0 | user | list all expenses entries | view all my expenses in a comprehensive list | +| v1.0 | user | list all income entries | view all my income in a comprehensive list | +| v2.0 | user | list all recurring cash flows | view all my recurring income or expenses in a comprehensive list | +| v2.0 | new user | see usage instructions | refer to them when I forget how to use the application | +| v1.0 | user | set a budget | keep track of a budget together with my cash flow and ensure I do not exceed it | +| v1.0 | user | update the budget | make changes to the budget according to my needs | +| v1.0 | user | reset the budget | return to my initial budget easily | +| v1.0 | user | delete budget | remove the budget that I no longer want to keep track of | +| v1.0 | user | view budget | keep track of the amount of budget I have left | +| v1.0 | user | see overview of the app | see the overall view of all income, expense and overall balance as well as reminders | +| v1.0 | user | view balance | see my overall balance according to the income and expenses I am keeping track | +| v1.0 | investment enthusiast | view my watchlist | keep track of stocks that I am interested in | +| v2.0 | investment enthusiast | add new stocks to watchlist | add new stock that I am interested in investing in | +| v2.0 | investment enthusiast | delete stocks from watchlist | remove stocks that I am no longer interested in | +| v1.0 | user | add reminder | add reminders (eg to pay loans) so I will not forget | +| v1.0 | user | delete reminder | delete reminders that I no longer want to keep track | +| v1.0 | user | mark reminder | set the reminder as completed | +| v1.0 | user | view wishlist | keep track of my goals easily | +| v1.0 | user | set goals | add a new goal to my that I think of | +| v1.0 | user | delete goals | remove goals that I can no longer achieve | +| v1.0 | user | mark goal | that I have achieved | +| v1.0 | user | visualize my cash flow | easily see where the distribution for my spending and earnings | ## Non-Functional Requirements * Should work on main OS (Windows, Linux, Mac) that has Java 11 installed. * This app is meant for a single user. * This app is targeted towards users with an above-average typing speed. +* Watchlist should work reliably and not crash the application when the 3rd party dependencies are down (API is down) ## Glossary From 1cbae2bc280aeeb4cf07b28d65b0ca9c004f08d0 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Wed, 8 Nov 2023 22:21:35 +0800 Subject: [PATCH 424/518] Add term to glossary --- docs/DeveloperGuide.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index ab43ef8b1d..69df30a58b 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -406,6 +406,7 @@ equities. * *Cashflow* - Refers to an income or expense. * *WishList* - A list containing goals/targets. +* *Watchlist* - a list of stocks that the financial planner is currently tracking ## Instructions for manual testing From e901e67eaf3ad9606285901861475531380906dc Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Wed, 8 Nov 2023 22:25:45 +0800 Subject: [PATCH 425/518] Add checkstyle fixes --- .../java/seedu/financialplanner/investments/WatchList.java | 4 ++-- .../seedu/financialplanner/visualisations/Categorizer.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index d13de784df..b2d44a67a8 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -240,7 +240,7 @@ public void extractStockInfoFromJSONObject(JSONObject stock, Stock stockLocal, l * Method used to add a new stock to the watchlist that has the stockCode given by the parameter provided * * @param stockCode - * @return + * @return stockName * @throws FinancialPlannerException */ public String addStock(String stockCode) throws FinancialPlannerException { @@ -266,7 +266,7 @@ public String addStock(String stockCode) throws FinancialPlannerException { * Method for deleting a stock from the watchlist that has the stockCode given by the parameter provided * * @param stockCode - * @return + * @return deleted stock name * @throws FinancialPlannerException */ public String deleteStock(String stockCode) throws FinancialPlannerException { diff --git a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java index dc5aad9707..72e9885ec8 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java @@ -24,7 +24,7 @@ public class Categorizer { * * @param cashflowList * @param type - * @return + * @return hashmap of sorted income/expense according to category * @throws FinancialPlannerException */ public static HashMap sortType(CashflowList cashflowList, String type) From dc31f3352f8fba756fccf90bab7521fe3e38f321 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Thu, 9 Nov 2023 20:13:03 +0800 Subject: [PATCH 426/518] Add simple manual testing and fix bugs --- docs/DeveloperGuide.md | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 69df30a58b..b891b6c17d 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -354,8 +354,8 @@ Our financial planner application can help individuals manage their finances eff goals. The purpose of such an application is to provide users with a range of tools and features to help them better understand their financial situation. This will enable them to make more informed decisions, and plan for their future financial well-being. The application will allow the user to keep track of their income, expenses and overall balance. -It also lets user view their income and expenses using visualization tool to have a better view of their cash flow based -on categories. It also allows the user to set the budget for the month. It also allows users to add their financial +It also lets the user view their income and expenses using visualization tool to have a better view of their cash flow +based on categories. It also allows the user to set the budget for the month. It also allows users to add their financial goals to the wishlist. Furthermore, it allows users to track the stock market if they have interest in investing in equities. @@ -406,8 +406,22 @@ equities. * *Cashflow* - Refers to an income or expense. * *WishList* - A list containing goals/targets. -* *Watchlist* - a list of stocks that the financial planner is currently tracking +* *Watchlist* - A list of stocks that the financial planner is currently tracking ## Instructions for manual testing -{Give instructions on how to do a manual product testing e.g., how to load sample data to be used for testing} +Given below are instructions to test the app manually + +- Note: These instructions only provide a starting point for testers to work on + +### Launch and shutdown + +1. Initial Launch + 1. Download the jar file and copy into an empty folder + 2. Open up the terminal and run java -jar tp.jar Expected: +shows you the welcome screen for the financial planner app +2. Closing the application + 1. Type `exit` into the terminal. + 2. Expected: the financial planner will exit with a goodbye message. +Under the data newly created data directory, a watchlist.json and a data.txt file will be created + From cae582799f9bbfc88818d5a995065742ae9732aa Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Thu, 9 Nov 2023 20:17:52 +0800 Subject: [PATCH 427/518] Update contributions for PPP --- docs/team/wwweert123.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/team/wwweert123.md b/docs/team/wwweert123.md index d54d3fa8d7..94d84a4a31 100644 --- a/docs/team/wwweert123.md +++ b/docs/team/wwweert123.md @@ -36,6 +36,10 @@ you a one-stop interface to access a plethora of features to manage your finance * Implementation * Class Diagram * Sequence Diagrams +* Value Proposition +* User Profile +* USer Stories +* Manual Testing ### Contributions to team-based tasks: From c3ed577311d86943c8ebd81487d366bac632daa7 Mon Sep 17 00:00:00 2001 From: YFshadaow Date: Thu, 9 Nov 2023 21:48:04 +0800 Subject: [PATCH 428/518] Resolve merge conflicts --- .../seedu/financialplanner/commands/AddCashflowCommand.java | 3 +++ .../java/seedu/financialplanner/commands/AddStockCommand.java | 3 +++ .../seedu/financialplanner/commands/DeleteCashflowCommand.java | 3 +++ .../seedu/financialplanner/commands/DeleteStockCommand.java | 3 +++ .../java/seedu/financialplanner/commands/OverviewCommand.java | 3 +++ src/main/java/seedu/financialplanner/commands/VisCommand.java | 3 +++ .../java/seedu/financialplanner/commands/WatchListCommand.java | 3 +++ 7 files changed, 21 insertions(+) diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index 3afbaf8c91..a3f594c6b9 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -1,5 +1,7 @@ package seedu.financialplanner.commands; +import seedu.financialplanner.commands.utils.Command; +import seedu.financialplanner.commands.utils.RawCommand; import seedu.financialplanner.enumerations.CashflowCategory; import seedu.financialplanner.enumerations.ExpenseType; import seedu.financialplanner.enumerations.IncomeType; @@ -15,6 +17,7 @@ /** * Represents the command to add a cashflow. */ +@SuppressWarnings("unused") public class AddCashflowCommand extends Command { protected static Ui ui = Ui.getInstance(); private static Logger logger = Logger.getLogger("Financial Planner Logger"); diff --git a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java index 8d4f68837f..730be0392f 100644 --- a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java @@ -1,5 +1,7 @@ package seedu.financialplanner.commands; +import seedu.financialplanner.commands.utils.Command; +import seedu.financialplanner.commands.utils.RawCommand; import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.utils.Ui; @@ -12,6 +14,7 @@ * Command that inherits from the Command abstract class * Represents that command that add stock to watchlist */ +@SuppressWarnings("unused") public class AddStockCommand extends Command { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private final String stockCode; diff --git a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java index 83564cbd7a..77f749cd04 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java @@ -1,5 +1,7 @@ package seedu.financialplanner.commands; +import seedu.financialplanner.commands.utils.Command; +import seedu.financialplanner.commands.utils.RawCommand; import seedu.financialplanner.enumerations.CashflowCategory; import seedu.financialplanner.cashflow.Budget; import seedu.financialplanner.cashflow.CashflowList; @@ -12,6 +14,7 @@ /** * Represents a command to delete a cashflow. */ +@SuppressWarnings("unused") public class DeleteCashflowCommand extends Command { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); protected CashflowCategory category = null; diff --git a/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java index d09453b973..d663afded0 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java @@ -1,5 +1,7 @@ package seedu.financialplanner.commands; +import seedu.financialplanner.commands.utils.Command; +import seedu.financialplanner.commands.utils.RawCommand; import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.utils.Ui; @@ -12,6 +14,7 @@ * Command that inherits from the Command abstract class * Represents the command to delete stock from watchlist */ +@SuppressWarnings("unused") public class DeleteStockCommand extends Command { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private final String stockCode; diff --git a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java index 57d08389d4..30a11e65e3 100644 --- a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java +++ b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java @@ -5,6 +5,8 @@ import seedu.financialplanner.cashflow.CashflowList; import seedu.financialplanner.cashflow.Income; import seedu.financialplanner.cashflow.Expense; +import seedu.financialplanner.commands.utils.Command; +import seedu.financialplanner.commands.utils.RawCommand; import seedu.financialplanner.goal.WishList; import seedu.financialplanner.reminder.ReminderList; import seedu.financialplanner.utils.Ui; @@ -15,6 +17,7 @@ /** * Represents a command to display overview of user's financials. */ +@SuppressWarnings("unused") public class OverviewCommand extends Command { private static final CashflowList cashflowList = CashflowList.getInstance(); diff --git a/src/main/java/seedu/financialplanner/commands/VisCommand.java b/src/main/java/seedu/financialplanner/commands/VisCommand.java index dffdbd2dcb..66bcd13433 100644 --- a/src/main/java/seedu/financialplanner/commands/VisCommand.java +++ b/src/main/java/seedu/financialplanner/commands/VisCommand.java @@ -1,5 +1,7 @@ package seedu.financialplanner.commands; +import seedu.financialplanner.commands.utils.Command; +import seedu.financialplanner.commands.utils.RawCommand; import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.cashflow.CashflowList; import seedu.financialplanner.utils.Ui; @@ -15,6 +17,7 @@ * Command class that inherit from Command abstract class * Represents the command to visualize your cash flow */ +@SuppressWarnings("unused") public class VisCommand extends Command { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private String type; diff --git a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java index 2c1e997ce7..5725494157 100644 --- a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java @@ -1,5 +1,7 @@ package seedu.financialplanner.commands; +import seedu.financialplanner.commands.utils.Command; +import seedu.financialplanner.commands.utils.RawCommand; import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.storage.SaveData; @@ -12,6 +14,7 @@ * Command that inherits from Command abstract class * Represents the command to fetch and display watchlist data */ +@SuppressWarnings("unused") public class WatchListCommand extends Command { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); From 2bf3be5ceb99e0c3e737d406e778405eb48c88d9 Mon Sep 17 00:00:00 2001 From: YFshadaow Date: Thu, 9 Nov 2023 22:26:49 +0800 Subject: [PATCH 429/518] Finish all command usage and example usage. Add example usage to help messages. --- .../commands/AddCashflowCommand.java | 11 ++++++++++ .../commands/AddReminderCommand.java | 3 +++ .../commands/AddStockCommand.java | 7 ++++++ .../commands/BalanceCommand.java | 2 ++ .../commands/BudgetCommand.java | 13 ++++++----- .../commands/DeleteCashflowCommand.java | 14 ++++++++++++ .../commands/DeleteGoalCommand.java | 3 ++- .../commands/DeleteReminderCommand.java | 3 ++- .../commands/DeleteStockCommand.java | 9 ++++++++ .../commands/ExitCommand.java | 2 ++ .../commands/FindCommand.java | 2 ++ .../commands/HelpCommand.java | 13 +++++++++-- .../commands/ListCommand.java | 6 ++++- .../commands/MarkGoalCommand.java | 3 ++- .../commands/MarkReminderCommand.java | 3 ++- .../commands/OverviewCommand.java | 7 ++++++ .../commands/ReminderListCommand.java | 3 ++- .../commands/SetGoalCommand.java | 4 +++- .../financialplanner/commands/VisCommand.java | 10 +++++++++ .../commands/WatchListCommand.java | 7 ++++++ .../commands/WishListCommand.java | 3 ++- .../commands/utils/CommandManager.java | 22 +++++++++++++++++++ 22 files changed, 135 insertions(+), 15 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index a3f594c6b9..643cc040c4 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -19,6 +19,17 @@ */ @SuppressWarnings("unused") public class AddCashflowCommand extends Command { + public static final String NAME = "add"; + + public static final String USAGE = + "add income /a AMOUNT /t TYPE [/r DAYS] [/d DESCRIPTION]" + "\n" + + "add expense /a AMOUNT /t TYPE [/r DAYS] [/d DESCRIPTION]"; + + public static final String EXAMPLE = + "add income /a 5000 /t salary /r 30 /d work" + "\n" + + "add expense /a 300 /t necessities /r 30 /d groceries"; + + protected static Ui ui = Ui.getInstance(); private static Logger logger = Logger.getLogger("Financial Planner Logger"); protected double amount; diff --git a/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java b/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java index b159ac152c..44053a7876 100644 --- a/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java @@ -12,6 +12,9 @@ public class AddReminderCommand extends Command { public static final String USAGE = "addreminder "; + + public static final String EXAMPLE = + "addreminder /t debt /d 2023.12.11"; private final String type; private final String date; diff --git a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java index 730be0392f..5d98583af2 100644 --- a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java @@ -16,6 +16,13 @@ */ @SuppressWarnings("unused") public class AddStockCommand extends Command { + + public static final String NAME = "addstock"; + + public static final String USAGE = + "addstock "; + public static final String EXAMPLE = + "addstock /s META"; private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private final String stockCode; diff --git a/src/main/java/seedu/financialplanner/commands/BalanceCommand.java b/src/main/java/seedu/financialplanner/commands/BalanceCommand.java index 68c827145c..f3c5269bd0 100644 --- a/src/main/java/seedu/financialplanner/commands/BalanceCommand.java +++ b/src/main/java/seedu/financialplanner/commands/BalanceCommand.java @@ -17,6 +17,8 @@ public class BalanceCommand extends Command { public static final String USAGE = "balance"; + public static final String EXAMPLE = + "balance"; private final Ui ui = Ui.getInstance(); public BalanceCommand(RawCommand rawCommand) { diff --git a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java index 4b608d2f77..98892c5b12 100644 --- a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java +++ b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java @@ -19,11 +19,14 @@ public class BudgetCommand extends Command { public static final String NAME = "budget"; public static final String USAGE = - "budget set " - + "\n" + "budget update " - + "\n" + "budget delete" - + "\n" + "budget reset" - + "\n" + "budget view"; + "budget set " + "\n" + + "budget update " + "\n" + + "budget delete" + "\n" + + "budget reset" + "\n" + + "budget view"; + public static final String EXAMPLE = + "budget set /b 500" + "\n" + + "budget reset"; private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private final Ui ui = Ui.getInstance(); private double budget; diff --git a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java index 77f749cd04..73271c9e1a 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java @@ -16,6 +16,20 @@ */ @SuppressWarnings("unused") public class DeleteCashflowCommand extends Command { + public static final String NAME = "delete"; + + public static final String USAGE = + "delete INDEX [/r]" + "\n" + + "delete income INDEX [/r]" + "\n" + + "delete expense INDEX [/r]" + "\n" + + "delete recurring INDEX [/r]"; + + public static final String EXAMPLE = + "delete 1" + "\n" + + "delete income 2 /r" + "\n" + + "delete expense 2 /r" + "\n" + + "delete recurring 2"; + private static final Logger logger = Logger.getLogger("Financial Planner Logger"); protected CashflowCategory category = null; protected int index; diff --git a/src/main/java/seedu/financialplanner/commands/DeleteGoalCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteGoalCommand.java index a9860dae07..9b9f550f64 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteGoalCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteGoalCommand.java @@ -13,7 +13,8 @@ public class DeleteGoalCommand extends Command { public static final String NAME = "deletegoal"; - public static final String USAGE = "UNDONE, PLEASE FILL THIS UP!"; + public static final String USAGE = "deletegoal "; + public static final String EXAMPLE = "deletegoal 1"; private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private final int index; diff --git a/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java index 94dead5a00..a5d4637058 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java @@ -13,7 +13,8 @@ public class DeleteReminderCommand extends Command { public static final String NAME = "deletereminder"; - public static final String USAGE = "UNDONE, PLEASE FILL THIS UP!"; + public static final String USAGE = "deletereminder "; + public static final String EXAMPLE = "deletereminder 1"; private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private final int index; diff --git a/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java index d663afded0..adaec2795b 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteStockCommand.java @@ -16,6 +16,15 @@ */ @SuppressWarnings("unused") public class DeleteStockCommand extends Command { + + + public static final String NAME = "deletestock"; + + public static final String USAGE = + "deletestock "; + public static final String EXAMPLE = + "deletestock /s META"; + private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private final String stockCode; diff --git a/src/main/java/seedu/financialplanner/commands/ExitCommand.java b/src/main/java/seedu/financialplanner/commands/ExitCommand.java index d47e5a1214..5076539981 100644 --- a/src/main/java/seedu/financialplanner/commands/ExitCommand.java +++ b/src/main/java/seedu/financialplanner/commands/ExitCommand.java @@ -14,6 +14,8 @@ public class ExitCommand extends Command { public static final String USAGE = "exit"; + public static final String EXAMPLE = + "exit"; public ExitCommand(RawCommand rawCommand) { if (!rawCommand.extraArgs.isEmpty()) { diff --git a/src/main/java/seedu/financialplanner/commands/FindCommand.java b/src/main/java/seedu/financialplanner/commands/FindCommand.java index 97e64f958e..02f9c4e2dd 100644 --- a/src/main/java/seedu/financialplanner/commands/FindCommand.java +++ b/src/main/java/seedu/financialplanner/commands/FindCommand.java @@ -14,6 +14,8 @@ public class FindCommand extends Command { public static final String USAGE = "find "; + public static final String EXAMPLE = + "find coffee"; private final String description; public FindCommand(RawCommand rawCommand) { diff --git a/src/main/java/seedu/financialplanner/commands/HelpCommand.java b/src/main/java/seedu/financialplanner/commands/HelpCommand.java index 4282d7ec35..8dd6f8faf5 100644 --- a/src/main/java/seedu/financialplanner/commands/HelpCommand.java +++ b/src/main/java/seedu/financialplanner/commands/HelpCommand.java @@ -11,7 +11,10 @@ public class HelpCommand extends Command { public static final String NAME = "help"; - public static final String USAGE = "help"; + public static final String USAGE = "help [COMMAND]"; + public static final String EXAMPLE = + "help" + "\n" + + "help budget"; private static final String HELP_MESSAGE_GENERAL = "<> denotes required arguments, [] denotes optional arguments"; @@ -48,15 +51,21 @@ public void execute() throws Exception { ui.showMessage(DELIMITER); for (String name : commandManager.getCommandNames()) { String usage = commandManager.getCommandUsage(name); + String example = commandManager.getCommandExample(name); ui.showMessage("Usage of " + name + ":"); ui.showMessage(usage); + ui.showMessage("Example usage of " + name + ":"); + ui.showMessage(example); ui.showMessage(DELIMITER); } return; } - String commandUsage = CommandManager.getInstance().getCommandUsage(commandName.toLowerCase()); + String commandUsage = commandManager.getCommandUsage(commandName.toLowerCase()); + String commandExample = commandManager.getCommandExample(commandName.toLowerCase()); ui.showMessage(HELP_MESSAGE_GENERAL); ui.showMessage("Usage of " + commandName.toLowerCase() + ":"); ui.showMessage(commandUsage); + ui.showMessage("Example usage of " + commandName.toLowerCase() + ":"); + ui.showMessage(commandExample); } } diff --git a/src/main/java/seedu/financialplanner/commands/ListCommand.java b/src/main/java/seedu/financialplanner/commands/ListCommand.java index 4cc5f2d132..acd6c86a20 100644 --- a/src/main/java/seedu/financialplanner/commands/ListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/ListCommand.java @@ -17,7 +17,11 @@ public class ListCommand extends Command { public static final String NAME = "list"; public static final String USAGE = - "list [income/expense]"; + "list [income/expense/recurring]"; + + public static final String EXAMPLE = + "list" + "\n" + + "list recurring"; protected CashflowCategory category = null; public ListCommand(RawCommand rawCommand) throws IllegalArgumentException { diff --git a/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java b/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java index 80a6e173c5..1d44182820 100644 --- a/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java +++ b/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java @@ -12,7 +12,8 @@ public class MarkGoalCommand extends Command { public static final String NAME = "markgoal"; - public static final String USAGE = "UNDONE, PLEASE FILL THIS UP!"; + public static final String USAGE = "markgoal "; + public static final String EXAMPLE = "markgoal 1"; private final int index; public MarkGoalCommand(RawCommand rawCommand) throws IllegalArgumentException { diff --git a/src/main/java/seedu/financialplanner/commands/MarkReminderCommand.java b/src/main/java/seedu/financialplanner/commands/MarkReminderCommand.java index bdf7f36e7a..443afbba4b 100644 --- a/src/main/java/seedu/financialplanner/commands/MarkReminderCommand.java +++ b/src/main/java/seedu/financialplanner/commands/MarkReminderCommand.java @@ -9,7 +9,8 @@ public class MarkReminderCommand extends Command { public static final String NAME = "markreminder"; - public static final String USAGE = "UNDONE, PLEASE FILL THIS UP!"; + public static final String USAGE = "markreminder "; + public static final String EXAMPLE = "markreminder 1"; private final int index; public MarkReminderCommand(RawCommand rawCommand) throws IllegalArgumentException { diff --git a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java index 30a11e65e3..d0234b0efe 100644 --- a/src/main/java/seedu/financialplanner/commands/OverviewCommand.java +++ b/src/main/java/seedu/financialplanner/commands/OverviewCommand.java @@ -19,6 +19,13 @@ */ @SuppressWarnings("unused") public class OverviewCommand extends Command { + public static final String NAME = "overview"; + + public static final String USAGE = + "overview"; + + public static final String EXAMPLE = + "overview"; private static final CashflowList cashflowList = CashflowList.getInstance(); public OverviewCommand(RawCommand rawCommand) { diff --git a/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java b/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java index 40126e32e9..c61339fe22 100644 --- a/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java @@ -9,7 +9,8 @@ public class ReminderListCommand extends Command { public static final String NAME = "reminderlist"; - public static final String USAGE = "UNDONE, PLEASE FILL THIS UP!"; + public static final String USAGE = "reminderlist"; + public static final String EXAMPLE = "reminderlist"; public ReminderListCommand(RawCommand rawCommand) throws IllegalArgumentException { diff --git a/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java b/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java index d4499f9ba6..97fb9e1cae 100644 --- a/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java +++ b/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java @@ -11,7 +11,9 @@ public class SetGoalCommand extends Command { public static final String NAME = "set"; public static final String USAGE = - "set "; + "set goal "; + public static final String EXAMPLE = + "set goal /g 5000 /l car"; private final String label; private final int amount; diff --git a/src/main/java/seedu/financialplanner/commands/VisCommand.java b/src/main/java/seedu/financialplanner/commands/VisCommand.java index 66bcd13433..6f24ae6629 100644 --- a/src/main/java/seedu/financialplanner/commands/VisCommand.java +++ b/src/main/java/seedu/financialplanner/commands/VisCommand.java @@ -19,6 +19,16 @@ */ @SuppressWarnings("unused") public class VisCommand extends Command { + + public static final String NAME = "vis"; + + public static final String USAGE = + "vis "; + + public static final String EXAMPLE = + "vis /t expense /c pie" + "\n" + + "vis /t income /c bar"; + private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private String type; private String chart; diff --git a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java index 5725494157..3e19ea2537 100644 --- a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java @@ -16,6 +16,13 @@ */ @SuppressWarnings("unused") public class WatchListCommand extends Command { + + public static final String NAME = "watchlist"; + + public static final String USAGE = + "watchlist"; + public static final String EXAMPLE = + "watchlist"; private static final Logger logger = Logger.getLogger("Financial Planner Logger"); /** diff --git a/src/main/java/seedu/financialplanner/commands/WishListCommand.java b/src/main/java/seedu/financialplanner/commands/WishListCommand.java index e3443e5b89..d4427fb344 100644 --- a/src/main/java/seedu/financialplanner/commands/WishListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/WishListCommand.java @@ -9,7 +9,8 @@ public class WishListCommand extends Command { public static final String NAME = "wishlist"; - public static final String USAGE = "UNDONE, PLEASE FILL THIS UP!"; + public static final String USAGE = "wishlist"; + public static final String EXAMPLE = "wishlist"; public WishListCommand(RawCommand rawCommand) throws IllegalArgumentException { diff --git a/src/main/java/seedu/financialplanner/commands/utils/CommandManager.java b/src/main/java/seedu/financialplanner/commands/utils/CommandManager.java index 44f6e72cb7..f165463f89 100644 --- a/src/main/java/seedu/financialplanner/commands/utils/CommandManager.java +++ b/src/main/java/seedu/financialplanner/commands/utils/CommandManager.java @@ -13,6 +13,8 @@ public class CommandManager { public static final String COMMAND_CLASS_USAGE_FIELD_NAME = "USAGE"; + public static final String COMMAND_CLASS_EXAMPLE_FIELD_NAME = "EXAMPLE"; + public static final String COMMAND_CLASS_NAME_FIELD_NAME = "NAME"; private static final String COMMAND_PACKAGE_NAME = "seedu.financialplanner.commands"; @@ -60,6 +62,7 @@ public String getCommandUsage(Class commandClass) throws NoSu } } + @SuppressWarnings("unused") public String getCommandUsage(String commandName) throws NoSuchElementException { try { @@ -69,6 +72,25 @@ public String getCommandUsage(String commandName) throws NoSuchElementException } } + @SuppressWarnings("unused") + public String getCommandExample(Class commandClass) throws NoSuchElementException { + try { + Field exampleField = commandClass.getField(COMMAND_CLASS_EXAMPLE_FIELD_NAME); + return (String) exampleField.get(null); + } catch (ClassCastException | NoSuchFieldException | IllegalAccessException e) { + throw new IllegalArgumentException("Cannot get command example. Is there a bug?"); + } + } + + @SuppressWarnings("unused") + public String getCommandExample(String commandName) { + try { + return getCommandExample(getCommandClass(commandName)); + } catch (Exception e) { + throw new NoSuchElementException(e.getMessage()); + } + } + @SuppressWarnings("unused") public Set getCommandNames() { return nameCommandMap.keySet(); From c936fb5243c66ac643121d68733e6589c3c71cd4 Mon Sep 17 00:00:00 2001 From: YFshadaow Date: Thu, 9 Nov 2023 22:28:27 +0800 Subject: [PATCH 430/518] Remove comment from build.gradle --- build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/build.gradle b/build.gradle index 8b78a0daba..32fa89dc46 100644 --- a/build.gradle +++ b/build.gradle @@ -16,7 +16,6 @@ dependencies { implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.12.0' implementation group: 'org.knowm.xchart', name: 'xchart', version: '3.8.5' implementation group: 'com.google.code.gson', name: 'gson', version: '2.10.1' - // https://mvnrepository.com/artifact/org.reflections/reflections implementation group: 'org.reflections', name: 'reflections', version: '0.10.2' } From 49df5b0d0831c58a101da08f871b1f01d91f3461 Mon Sep 17 00:00:00 2001 From: hshiah Date: Thu, 9 Nov 2023 22:44:11 +0800 Subject: [PATCH 431/518] Fix bugs --- docs/UserGuide.md | 9 ++++++++- .../financialplanner/commands/AddReminderCommand.java | 6 ++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index a22894de0b..3834b8438a 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -870,7 +870,14 @@ window. Sorry for the inconvenience caused. 🥲 | **Delete from watchlist** | `deletestock /s STOCKCODE` | | **Visualization** | `vis /t TYPE /c CHART` | | **Exit program** | `exit` | - +| **Add Reminder** | `addreminder /t TYPE /d DATE` | +| **Delete Reminder** | `deletereminder INDEX` | +| **Mark Reminder as Done** | `markreminder INDEX` | +| **Add Goal** | `set goal /g GOAL /l LABEL` | +| **Delete Goal** | `deletegoal INDEX` | +| **Mark Goal as Achieved** | `markgoal INDEX` | +| **List all reminders** | `reminderlist` | +| **List all goals** | `wishlist` | - Note: Cashflow is referring to an income or expense **Income and Expense types** diff --git a/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java b/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java index 802418273f..d1453bb65a 100644 --- a/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java @@ -12,11 +12,17 @@ public AddReminderCommand(RawCommand rawCommand) throws IllegalArgumentException throw new IllegalArgumentException("Reminder must have a type"); } type = rawCommand.extraArgs.get("t"); + if(type.isEmpty()){ + throw new IllegalArgumentException("Reminder type cannot be empty"); + } rawCommand.extraArgs.remove("t"); if(!rawCommand.extraArgs.containsKey("d")){ throw new IllegalArgumentException("Reminder must have a date"); } date = rawCommand.extraArgs.get("d"); + if(date.isEmpty()){ + throw new IllegalArgumentException("Reminder date cannot be empty"); + } rawCommand.extraArgs.remove("d"); if(!rawCommand.extraArgs.isEmpty()){ String unknownExtraArgument = new java.util.ArrayList<>(rawCommand.extraArgs.keySet()).get(0); From 5d6c5050a77169a42276b6d3b57a663c2be89bcb Mon Sep 17 00:00:00 2001 From: YFshadaow Date: Thu, 9 Nov 2023 22:44:16 +0800 Subject: [PATCH 432/518] Add find and help commands to user guide --- docs/UserGuide.md | 17 +++++++++++++++++ .../financialplanner/commands/FindCommand.java | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index a22894de0b..0ee417e4ec 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -12,6 +12,7 @@ * [Delete income](#delete-income-delete-income) * [Delete expense](#delete-expense-delete-expense) * [Delete recurring cashflow](#delete-recurring-delete-recurring) + * [Find cashflow](#find-cashflow-find) * [List](#list) * [List all](#list-all-list) * [List income](#list-income-list-income) @@ -38,6 +39,7 @@ * [Marking Goal as Achieved](#mark-goal-as-achieved-markgoal) * [Visualization](#visualizing-your-cashflow-vis) * [Exiting the program](#exiting-the-program-exit) + * [Get command help and exmaple usage](#getting-command-help-and-example-usage-help) * [Saving data](#saving-the-data) * [Loading data](#loading-the-data) * [FAQ](#faq) @@ -279,6 +281,13 @@ Balance: -830.00 - Note: Balance displayed above is just an example. Your actual balance may differ. - Note: Date displayed above is just an example. Your actual date may differ. +### Find cashflow: `find` +Finds a cashflow using keywords + +Format: `find ` + +Example of usage: `find buy coffee` + ### List #### List all: `list` @@ -804,6 +813,14 @@ Exits the program. Format: `exit` +### Getting command help and example usage: `help` + +Get command help and example usage. Specify the command to find help and example usage for exactly that command. + +Format: `help [COMMAND]` + +Example of usage: `help budget` + ### Saving the data Data is automatically saved upon exiting the program using the `exit` command. Closing the program without exiting diff --git a/src/main/java/seedu/financialplanner/commands/FindCommand.java b/src/main/java/seedu/financialplanner/commands/FindCommand.java index 02f9c4e2dd..c3f0c5a58e 100644 --- a/src/main/java/seedu/financialplanner/commands/FindCommand.java +++ b/src/main/java/seedu/financialplanner/commands/FindCommand.java @@ -15,7 +15,7 @@ public class FindCommand extends Command { public static final String USAGE = "find "; public static final String EXAMPLE = - "find coffee"; + "find buy coffee"; private final String description; public FindCommand(RawCommand rawCommand) { From d579e32c5547c320ac26a92219adc4d37343bac5 Mon Sep 17 00:00:00 2001 From: YFshadaow Date: Thu, 9 Nov 2023 22:50:29 +0800 Subject: [PATCH 433/518] Fix spacing in BudgetCommand.java --- .../java/seedu/financialplanner/commands/BudgetCommand.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java index 98892c5b12..4a51aa23cd 100644 --- a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java +++ b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java @@ -50,7 +50,7 @@ public BudgetCommand(RawCommand rawCommand) throws FinancialPlannerException { validateBudget(rawCommand); assert budget > 0 && budget <= Cashflow.getBalance() : "Budget should be greater than 0 and less than " + - "or equal to total balance"; + "or equal to total balance"; rawCommand.extraArgs.remove("b"); if (!rawCommand.extraArgs.isEmpty()) { @@ -94,7 +94,7 @@ private void validateCommandFormat(RawCommand rawCommand) throws FinancialPlanne if (!command.equals("set") && !command.equals("update")) { logger.log(Level.WARNING, "Invalid arguments for budget command"); throw new FinancialPlannerException("Budget operation must be one of the following: set, update, " + - "delete, reset, view."); + "delete, reset, view."); } if (command.equals("set") && Budget.hasBudget()) { @@ -117,7 +117,7 @@ private void validateCommandFormat(RawCommand rawCommand) throws FinancialPlanne @Override public void execute() { assert command.equals("set") || command.equals("update") || command.equals("delete") || - command.equals("reset") || command.equals("view"); + command.equals("reset") || command.equals("view"); switch (command) { case "set": From 0543ea400573454bc2d8b41e7af149c271107e4d Mon Sep 17 00:00:00 2001 From: YFshadaow Date: Thu, 9 Nov 2023 22:52:23 +0800 Subject: [PATCH 434/518] Fix usage of add cashflow command --- .../seedu/financialplanner/commands/AddCashflowCommand.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index 643cc040c4..08c4b6691e 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -22,8 +22,8 @@ public class AddCashflowCommand extends Command { public static final String NAME = "add"; public static final String USAGE = - "add income /a AMOUNT /t TYPE [/r DAYS] [/d DESCRIPTION]" + "\n" + - "add expense /a AMOUNT /t TYPE [/r DAYS] [/d DESCRIPTION]"; + "add income [/r DAYS] [/d DESCRIPTION]" + "\n" + + "add expense [/r DAYS] [/d DESCRIPTION]"; public static final String EXAMPLE = "add income /a 5000 /t salary /r 30 /d work" + "\n" + From 56a6742ec75e8ea03b30b46656982c4e428bce69 Mon Sep 17 00:00:00 2001 From: YFshadaow Date: Thu, 9 Nov 2023 23:12:20 +0800 Subject: [PATCH 435/518] Fix incorrect exception message due to invocation target exception casued by reflection usage. --- src/main/java/seedu/financialplanner/utils/Parser.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/utils/Parser.java b/src/main/java/seedu/financialplanner/utils/Parser.java index d0cf6a04ed..b6d78559b6 100644 --- a/src/main/java/seedu/financialplanner/utils/Parser.java +++ b/src/main/java/seedu/financialplanner/utils/Parser.java @@ -6,6 +6,7 @@ import seedu.financialplanner.exceptions.FinancialPlannerException; import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -42,10 +43,14 @@ public static Command parseCommand(RawCommand rawCommand) throws FinancialPlanne try { constructorWithNothing = commandClass.getConstructor(); return constructorWithNothing.newInstance(); + } catch (InvocationTargetException e) { + throw new FinancialPlannerException(e.getCause().getMessage()); } catch (Exception e) { throw new RuntimeException(e); } - } catch (Exception e) { + } catch (InvocationTargetException e) { + throw new FinancialPlannerException(e.getCause().getMessage()); + } catch (Exception e) { throw new RuntimeException(e); } } From 2a25f4827fddb3ba0b7b97dccc84a06cd7fb3242 Mon Sep 17 00:00:00 2001 From: hshiah Date: Thu, 9 Nov 2023 23:56:36 +0800 Subject: [PATCH 436/518] Enhancement of reminder --- .../commands/AddReminderCommand.java | 24 ++++++++++++++++--- .../financialplanner/reminder/Reminder.java | 18 ++++++++------ 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java b/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java index d1453bb65a..a9e4e4d091 100644 --- a/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java @@ -1,13 +1,18 @@ package seedu.financialplanner.commands; + import seedu.financialplanner.reminder.ReminderList; import seedu.financialplanner.reminder.Reminder; import seedu.financialplanner.utils.Ui; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; public class AddReminderCommand extends Command { private final String type; - private final String date; + private final LocalDate date; public AddReminderCommand(RawCommand rawCommand) throws IllegalArgumentException { String typeString = String.join(" ", rawCommand.args); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); if(!rawCommand.extraArgs.containsKey("t")){ throw new IllegalArgumentException("Reminder must have a type"); } @@ -19,10 +24,23 @@ public AddReminderCommand(RawCommand rawCommand) throws IllegalArgumentException if(!rawCommand.extraArgs.containsKey("d")){ throw new IllegalArgumentException("Reminder must have a date"); } - date = rawCommand.extraArgs.get("d"); - if(date.isEmpty()){ + + String dateString = rawCommand.extraArgs.get("d"); + if(dateString.isEmpty()){ throw new IllegalArgumentException("Reminder date cannot be empty"); } + + try { + date = LocalDate.parse(dateString, formatter); + } catch (DateTimeParseException e) { + throw new IllegalArgumentException("Reminder date must be in the format yyyy-MM-dd"); + } + + LocalDate currentTime = LocalDate.now(); + if(date.isBefore(currentTime)){ + throw new IllegalArgumentException("Reminder date cannot be in the past"); + } + rawCommand.extraArgs.remove("d"); if(!rawCommand.extraArgs.isEmpty()){ String unknownExtraArgument = new java.util.ArrayList<>(rawCommand.extraArgs.keySet()).get(0); diff --git a/src/main/java/seedu/financialplanner/reminder/Reminder.java b/src/main/java/seedu/financialplanner/reminder/Reminder.java index d32c683823..a8442e9cb6 100644 --- a/src/main/java/seedu/financialplanner/reminder/Reminder.java +++ b/src/main/java/seedu/financialplanner/reminder/Reminder.java @@ -1,18 +1,22 @@ package seedu.financialplanner.reminder; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.Duration; public class Reminder { private String type; - private String date; + private LocalDate date; private boolean isDone = false; - public Reminder(String type, String date) { + public Reminder(String type, LocalDate date) { this.type = type; this.date = date; } public Reminder(String type, String date, String status) { this.type = type; - this.date = date; + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + this.date = LocalDate.parse(date, formatter); if (status.equals("Done")) { this.isDone = true; } else { @@ -21,16 +25,16 @@ public Reminder(String type, String date, String status) { } public String toString() { String status = isDone ? "Done" : "Not Done"; + LocalDate currentTime = LocalDate.now(); + Duration duration = Duration.between(currentTime.atStartOfDay(), date.atStartOfDay()); return "Reminder " + System.lineSeparator() + " Type: " + type + System.lineSeparator() - + " Date: " + date + System.lineSeparator() + " Status: " + status; + + " Date: " + date + System.lineSeparator() + " Status: " + status + + System.lineSeparator() + " Left Days: " + duration.toDays(); } public void markAsDone() { this.isDone = true; } - public void unmark() { - this.isDone = false; - } /* * Returns a string that can be saved to a file. * Format: type | date | isDone From c9cc53838d31eac80f412e05ab2e2b51cc1fc167 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Fri, 10 Nov 2023 11:46:21 +0800 Subject: [PATCH 437/518] Add list command to UG --- docs/UserGuide.md | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index bbc8adcdc7..27a034c812 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -282,7 +282,11 @@ Balance: -830.00 ### List #### List all: `list` -// TODO +Lists all cashflows. + +Format: `list` + +Example of usage: `list` Example output: @@ -311,7 +315,11 @@ Balance: 1170.00 - Note: Date displayed above is just an example. Your actual date may differ. #### List income: `list income` -//TODO +Lists all incomes. + +Format: `list income` + +Example of usage: `list income` Example output: ``` @@ -332,7 +340,11 @@ Income Balance: 1600.00 - Note: Date displayed above is just an example. Your actual date may differ. #### List expense: `list expense` -//TODO +Lists all expenses. + +Format: `list expense` + +Example of usage: `list expense` Example output: ``` From 3684545d6cb67cd80ad7697e54de5d9bdd3f1ac9 Mon Sep 17 00:00:00 2001 From: hshiah Date: Fri, 10 Nov 2023 11:49:54 +0800 Subject: [PATCH 438/518] Fix date format --- .../seedu/financialplanner/commands/AddReminderCommand.java | 4 ++-- src/main/java/seedu/financialplanner/reminder/Reminder.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java b/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java index a9e4e4d091..ef017a9d69 100644 --- a/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java @@ -12,7 +12,7 @@ public class AddReminderCommand extends Command { public AddReminderCommand(RawCommand rawCommand) throws IllegalArgumentException { String typeString = String.join(" ", rawCommand.args); - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); if(!rawCommand.extraArgs.containsKey("t")){ throw new IllegalArgumentException("Reminder must have a type"); } @@ -33,7 +33,7 @@ public AddReminderCommand(RawCommand rawCommand) throws IllegalArgumentException try { date = LocalDate.parse(dateString, formatter); } catch (DateTimeParseException e) { - throw new IllegalArgumentException("Reminder date must be in the format yyyy-MM-dd"); + throw new IllegalArgumentException("Reminder date must be in the format dd/MM/yyyy"); } LocalDate currentTime = LocalDate.now(); diff --git a/src/main/java/seedu/financialplanner/reminder/Reminder.java b/src/main/java/seedu/financialplanner/reminder/Reminder.java index a8442e9cb6..104d0cbf24 100644 --- a/src/main/java/seedu/financialplanner/reminder/Reminder.java +++ b/src/main/java/seedu/financialplanner/reminder/Reminder.java @@ -15,7 +15,7 @@ public Reminder(String type, LocalDate date) { public Reminder(String type, String date, String status) { this.type = type; - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); this.date = LocalDate.parse(date, formatter); if (status.equals("Done")) { this.isDone = true; From b68d1c2f47f566048f587d880bcdccfe705b97fb Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Fri, 10 Nov 2023 11:50:33 +0800 Subject: [PATCH 439/518] Fix typo --- docs/UserGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 27a034c812..b43441c35e 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -865,7 +865,7 @@ window. Sorry for the inconvenience caused. 🥲 | **Delete cashflow** | `delete INDEX [/r]` | | **Delete income** | `delete income INDEX [/r]` | | **Delete expense** | `delete expense INDEX [/r]` | -| **Delete recurrence** | `delete recurrence INDEX [/r]` | +| **Delete recurrence** | `delete recurring INDEX [/r]` | | **list all cashflows** | `list` | | **list all incomes** | `list income` | | **list all expenses** | `list expense` | From ce4b754f4753f42db0ff1d672a7d810fa84eaddb Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Fri, 10 Nov 2023 11:52:28 +0800 Subject: [PATCH 440/518] Fix incorrect directory in UG --- docs/UserGuide.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index b43441c35e..a2e615ddac 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -601,7 +601,7 @@ the application is not running Example file content of watchlist.json: -![](/images/investments/watchlistjsonexample.png) +![](images/investments/watchlistjsonexample.png) **Editing of watchlist.json** @@ -610,7 +610,7 @@ Incorrect format of JSON file may lead to: - Corrupted file (user will be prompted to repair the file if he wants to) - Deletion of stock entries that are erroneous (Financial Planner has a built-in method to remove stock entries that does not match the format specified above) -- Incorrect information printed by Financial Planner application (eg. changing stock prices directly in JSON file) +- Incorrect information printed by Financial Planner application (e.g. changing stock prices directly in JSON file) **Adding stock** From 0efce8feadb395c63291acccba2b140c5fba8f2f Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Fri, 10 Nov 2023 12:48:24 +0800 Subject: [PATCH 441/518] Update readme and aboutus --- docs/AboutUs.md | 14 +++++++------- docs/README.md | 8 +++++--- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 0b2171b9f9..faf839094d 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,10 +1,10 @@ # About us -Display | Name | Github Profile | Portfolio ---------|:-----------:|:--------------:|:---------: -![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Ryan Chua | [Github](https://github.com/ryan1604) | [Portfolio](docs/team/ryanchua.md) -![](https://via.placeholder.com/100.png?text=Photo) | Neo Min Wei | [Github](https://github.com/NeoMinWei) | [Portfolio](docs/team/NeoMinWei.md) -![](https://via.placeholder.com/100.png?text=Photo) | Frederick | [Github](https://github.com/) | [Portfolio](docs/team/frederick.md) +| Display | Name | Github Profile | Portfolio | +|-----------------------------------------------------|:-----------:|:---------------------------------------:|:---------------------------------:| +| ![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) | +| ![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) | +| ![](https://via.placeholder.com/100.png?text=Photo) | Ryan Chua | [Github](https://github.com/ryan1604) | [Portfolio](team/ryan1604.md) | +| ![](https://via.placeholder.com/100.png?text=Photo) | Neo Min Wei | [Github](https://github.com/NeoMinWei) | [Portfolio](team/neominwei.md) | +| ![](https://via.placeholder.com/100.png?text=Photo) | Frederick | [Github](https://github.com/wwweert123) | [Portfolio](team/wwweert123.md) | diff --git a/docs/README.md b/docs/README.md index bbcc99c1e7..3e632b9310 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,8 +1,10 @@ -# Duke +# Financial Planner -{Give product intro here} +Financial Planner is a Command Line Interface (CLI) application for managing your finances conveniently. +It is optimized for use via the CLI and leverages your expertise in CLI and your ability to type fast and gives +you a one-stop interface to access a plethora of features to manage your finances. -Useful links: +**For more information:** * [User Guide](UserGuide.md) * [Developer Guide](DeveloperGuide.md) * [About Us](AboutUs.md) From cd6c82eaf6ed8ee0702b9947ca2f931242d5fead Mon Sep 17 00:00:00 2001 From: hshiah Date: Fri, 10 Nov 2023 12:51:10 +0800 Subject: [PATCH 442/518] Fix bugs of loading and saving reminder --- .../seedu/financialplanner/commands/AddReminderCommand.java | 4 ++-- src/main/java/seedu/financialplanner/reminder/Reminder.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java b/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java index bfc065b830..20958cbc20 100644 --- a/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java @@ -19,13 +19,13 @@ public class AddReminderCommand extends Command { "addreminder "; public static final String EXAMPLE = - "addreminder /t debt /d 2023.12.11"; + "addreminder /t debt /d 11/12/2023"; private final String type; private final LocalDate date; + private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); public AddReminderCommand(RawCommand rawCommand) throws IllegalArgumentException { String typeString = String.join(" ", rawCommand.args); - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); if (!rawCommand.extraArgs.containsKey("t")) { throw new IllegalArgumentException("Reminder must have a type"); } diff --git a/src/main/java/seedu/financialplanner/reminder/Reminder.java b/src/main/java/seedu/financialplanner/reminder/Reminder.java index 104d0cbf24..8025e1b8ce 100644 --- a/src/main/java/seedu/financialplanner/reminder/Reminder.java +++ b/src/main/java/seedu/financialplanner/reminder/Reminder.java @@ -7,6 +7,7 @@ public class Reminder { private String type; private LocalDate date; private boolean isDone = false; + private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); public Reminder(String type, LocalDate date) { this.type = type; @@ -15,7 +16,6 @@ public Reminder(String type, LocalDate date) { public Reminder(String type, String date, String status) { this.type = type; - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); this.date = LocalDate.parse(date, formatter); if (status.equals("Done")) { this.isDone = true; @@ -28,7 +28,7 @@ public String toString() { LocalDate currentTime = LocalDate.now(); Duration duration = Duration.between(currentTime.atStartOfDay(), date.atStartOfDay()); return "Reminder " + System.lineSeparator() + " Type: " + type + System.lineSeparator() - + " Date: " + date + System.lineSeparator() + " Status: " + status + + " Date: " + date.format(formatter) + System.lineSeparator() + " Status: " + status + System.lineSeparator() + " Left Days: " + duration.toDays(); } @@ -42,6 +42,6 @@ public void markAsDone() { */ public String formatString() { String status = isDone ? "Done" : "Not Done"; - return "R" + " | " + this.type + " | " + this.date + " | " + status; + return "R" + " | " + this.type + " | " + this.date.format(formatter) + " | " + status; } } From 6f23dec7539ecdfbab158297162b00fa9171aefb Mon Sep 17 00:00:00 2001 From: hshiah Date: Fri, 10 Nov 2023 12:58:19 +0800 Subject: [PATCH 443/518] Fix coding style --- .../financialplanner/commands/AddReminderCommand.java | 4 ++-- .../java/seedu/financialplanner/reminder/Reminder.java | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java b/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java index 20958cbc20..95d659bba6 100644 --- a/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java @@ -20,9 +20,9 @@ public class AddReminderCommand extends Command { public static final String EXAMPLE = "addreminder /t debt /d 11/12/2023"; + private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("dd/MM/yyyy"); private final String type; private final LocalDate date; - private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); public AddReminderCommand(RawCommand rawCommand) throws IllegalArgumentException { String typeString = String.join(" ", rawCommand.args); @@ -44,7 +44,7 @@ public AddReminderCommand(RawCommand rawCommand) throws IllegalArgumentException } try { - date = LocalDate.parse(dateString, formatter); + date = LocalDate.parse(dateString, FORMATTER); } catch (DateTimeParseException e) { throw new IllegalArgumentException("Reminder date must be in the format dd/MM/yyyy"); } diff --git a/src/main/java/seedu/financialplanner/reminder/Reminder.java b/src/main/java/seedu/financialplanner/reminder/Reminder.java index 8025e1b8ce..0624b7370f 100644 --- a/src/main/java/seedu/financialplanner/reminder/Reminder.java +++ b/src/main/java/seedu/financialplanner/reminder/Reminder.java @@ -4,10 +4,10 @@ import java.time.format.DateTimeFormatter; import java.time.Duration; public class Reminder { + private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("dd/MM/yyyy"); private String type; private LocalDate date; private boolean isDone = false; - private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); public Reminder(String type, LocalDate date) { this.type = type; @@ -16,7 +16,7 @@ public Reminder(String type, LocalDate date) { public Reminder(String type, String date, String status) { this.type = type; - this.date = LocalDate.parse(date, formatter); + this.date = LocalDate.parse(date, FORMATTER); if (status.equals("Done")) { this.isDone = true; } else { @@ -28,7 +28,7 @@ public String toString() { LocalDate currentTime = LocalDate.now(); Duration duration = Duration.between(currentTime.atStartOfDay(), date.atStartOfDay()); return "Reminder " + System.lineSeparator() + " Type: " + type + System.lineSeparator() - + " Date: " + date.format(formatter) + System.lineSeparator() + " Status: " + status + + " Date: " + date.format(FORMATTER) + System.lineSeparator() + " Status: " + status + System.lineSeparator() + " Left Days: " + duration.toDays(); } @@ -42,6 +42,6 @@ public void markAsDone() { */ public String formatString() { String status = isDone ? "Done" : "Not Done"; - return "R" + " | " + this.type + " | " + this.date.format(formatter) + " | " + status; + return "R" + " | " + this.type + " | " + this.date.format(FORMATTER) + " | " + status; } } From 1059aa13f900c8aee062f584231f90521c745fe8 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Fri, 10 Nov 2023 20:35:59 +0800 Subject: [PATCH 444/518] Fix mistakes --- src/main/java/seedu/financialplanner/utils/Ui.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 9a984de91c..cea4029d88 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -77,14 +77,14 @@ public void printWatchListHeader() { System.out.print(RED + "Daily Low" + RESET); System.out.print(" "); System.out.print("EquityName"); - System.out.print(" "); + System.out.print(" "); System.out.print("Last Updated"); System.out.print(" "); System.out.println(); } public void printWatchListAcknowledgement() { - showMessage("Data provided by Financial Modeling Prep and Alpha Vantage 😊"); + showMessage("Data provided by Financial Modeling Prep and Alpha Vantage =)"); } From 346f3c7a0169894f71e93fef3b84da65160cc908 Mon Sep 17 00:00:00 2001 From: YFshadaow Date: Fri, 10 Nov 2023 22:19:16 +0800 Subject: [PATCH 445/518] Solve slf4j binding warning --- build.gradle | 4 ++++ .../seedu/financialplanner/commands/utils/CommandManager.java | 2 ++ 2 files changed, 6 insertions(+) diff --git a/build.gradle b/build.gradle index 32fa89dc46..5be1c9bbd4 100644 --- a/build.gradle +++ b/build.gradle @@ -17,6 +17,10 @@ dependencies { implementation group: 'org.knowm.xchart', name: 'xchart', version: '3.8.5' implementation group: 'com.google.code.gson', name: 'gson', version: '2.10.1' implementation group: 'org.reflections', name: 'reflections', version: '0.10.2' + implementation group: 'org.slf4j', name: 'slf4j-api', version: '2.0.9' + implementation group: 'org.slf4j', name: 'slf4j-simple', version: '2.0.9' + + } diff --git a/src/main/java/seedu/financialplanner/commands/utils/CommandManager.java b/src/main/java/seedu/financialplanner/commands/utils/CommandManager.java index f165463f89..9f2999a5ee 100644 --- a/src/main/java/seedu/financialplanner/commands/utils/CommandManager.java +++ b/src/main/java/seedu/financialplanner/commands/utils/CommandManager.java @@ -1,6 +1,7 @@ package seedu.financialplanner.commands.utils; import org.reflections.Reflections; +import org.slf4j.simple.SimpleLogger; import java.lang.reflect.Field; import java.util.HashMap; @@ -22,6 +23,7 @@ public class CommandManager { private final Map> nameCommandMap = new HashMap<>(); private CommandManager() { + System.setProperty(SimpleLogger.DEFAULT_LOG_LEVEL_KEY, "ERROR"); Reflections reflections = new Reflections(COMMAND_PACKAGE_NAME); Set> commandClasses = reflections.getSubTypesOf(Command.class); for (Class c : commandClasses) { From 593c2db052022fe413c69108eb2196b8293695e5 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Sat, 11 Nov 2023 16:37:06 +0800 Subject: [PATCH 446/518] Fix UG and DG --- docs/DeveloperGuide.md | 6 ++---- docs/UserGuide.md | 6 +----- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index b891b6c17d..24ec0296e0 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -67,8 +67,6 @@ * [Addressbook-level3](https://github.com/se-edu/addressbook-level3) -{list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well} - ## Design & implementation ### Architecture Diagram @@ -140,7 +138,7 @@ VisCommand's Role: - `/t` Reads the type of cashflow that the user wants to visualize (income/expense) - `/c` Reads the type of visualization tools the user wants (piechart/barchart) -2) Calls the Cateorgizer to sort cashflow (Income/Expense) according to type +2) Calls the Categorizer to sort cashflow (Income/Expense) according to type 3) Calls the Visualizer to display the chart to the user @@ -149,7 +147,7 @@ takes RawCommand as parameter. The RawCommand would provide the arguments (chart for the VisCommand provided. The VisCommand also inherits from the abstract Command class which would provide the execute() abstract method -that would be called in main() +that would be called in main(). Categorizer's Role: diff --git a/docs/UserGuide.md b/docs/UserGuide.md index bbc0235b61..dcb9690b48 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -53,8 +53,6 @@ you a one-stop interface to access a plethora of features to manage your finance ## Quick Start -{TO BE UPDATED WHEN V2.1 IS COMPLETED!!!} - 1. Ensure that you have Java 11 or above installed. 2. Download the latest version of `Financial Planner` from [here](https://github.com/AY2324S1-CS2113-T18-2/tp/releases). 3. Copy the file to the folder you want to use as the *home folder* for Financial Planner. @@ -63,7 +61,6 @@ you a one-stop interface to access a plethora of features to manage your finance ## Features -{Give detailed description of each feature} ### Notes about the command format - Words in `UPPER_CASE` are parameters to be supplied by the user. @@ -873,8 +870,6 @@ window. Sorry for the inconvenience caused. 🥲 ## Command Summary -{Give a 'cheat sheet' of commands here} - | Action | Format | |----------------------------------|------------------------------------------------------------| | **Add income** | `add income /a AMOUNT /t TYPE [/r DAYS] [/d DESCRIPTION]` | @@ -907,6 +902,7 @@ window. Sorry for the inconvenience caused. 🥲 | **Mark Goal as Achieved** | `markgoal INDEX` | | **List all reminders** | `reminderlist` | | **List all goals** | `wishlist` | + - Note: Cashflow is referring to an income or expense **Income and Expense types** From 3c5ddee38cbc5d9cb999effdc9c4090b73845b74 Mon Sep 17 00:00:00 2001 From: hshiah Date: Sat, 11 Nov 2023 17:01:38 +0800 Subject: [PATCH 447/518] Fix bugs --- docs/UserGuide.md | 6 +++--- .../financialplanner/commands/FindCommand.java | 15 +-------------- 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index dcb9690b48..37d856ddb8 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -651,15 +651,15 @@ Adds a reminder to the Financial Planner. Format: `addreminder /t TYPE /d DATE` - `/t` is used to specify the reminder type, which describes what is the reminder used for. -- `/d` is used to give a deadline date to the reminder. +- `/d` is used to give a deadline date to the reminder. The date must be in the format of `DD/MM/YYYY`. -Example of usage: `addreminder /t debt /d 2023.12.11` +Example of usage: `addreminder /t debt /d 11/12/2023` Example output: ``` You have added Reminder Type: debt - Date: 2023.12.11 + Date: 11/12/2023 Status: Not Done ``` diff --git a/src/main/java/seedu/financialplanner/commands/FindCommand.java b/src/main/java/seedu/financialplanner/commands/FindCommand.java index c3f0c5a58e..cd958ea53b 100644 --- a/src/main/java/seedu/financialplanner/commands/FindCommand.java +++ b/src/main/java/seedu/financialplanner/commands/FindCommand.java @@ -34,7 +34,7 @@ public void execute() { ArrayList foundedFinancialList = new ArrayList<>(); ArrayList foundedWatchList = new ArrayList<>(); for (int i = 0; i < cashflowList.list.size(); i++) { - if (cashflowList.list.get(i).toString().contains(description)) { + if (cashflowList.list.get(i).toString().toLowerCase().contains(description.toLowerCase())) { String output = cashflowList.list.get(i).toString() + " | Index: " + (i + 1); foundedFinancialList.add(output); } @@ -48,18 +48,5 @@ public void execute() { ui.showMessage(foundedFinancialRecord); } - for (int i = 0; i < watchList.size(); i++) { - if (watchList.get(i).toString().contains(description)) { - foundedWatchList.add(watchList.get(i).toString() + " | Index: " + (i + 1)); - } - } - if (!foundedWatchList.isEmpty()) { - ui.showMessage("Here are the matching stock records in your stock list:"); - } else { - ui.showMessage("There is no matching stock record in your stock list."); - } - for (String foundedStockRecord : foundedWatchList) { - ui.showMessage(foundedStockRecord); - } } } From 4b8495e192a7c67efc7523317ed06681b23dbf63 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sat, 11 Nov 2023 17:03:04 +0800 Subject: [PATCH 448/518] Fix addstock --- .../java/seedu/financialplanner/commands/AddStockCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java index 8d4f68837f..81462e6b80 100644 --- a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java @@ -28,7 +28,7 @@ public AddStockCommand(RawCommand rawCommand) throws IllegalArgumentException { } logger.log(Level.INFO, "Parsing stockcode from input"); - stockCode = rawCommand.extraArgs.get("s").trim(); + stockCode = rawCommand.extraArgs.get("s").trim().toUpperCase(); rawCommand.extraArgs.remove("s"); if (!rawCommand.extraArgs.isEmpty()) { From 3eda51dd7808468023210ee6e63cf9bcadb77e4f Mon Sep 17 00:00:00 2001 From: hshiah Date: Sat, 11 Nov 2023 17:13:10 +0800 Subject: [PATCH 449/518] Update UG --- docs/UserGuide.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 37d856ddb8..16f2d6a129 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -661,6 +661,7 @@ You have added Reminder Type: debt Date: 11/12/2023 Status: Not Done + Left Days: 30 ``` ### Delete reminder: `deletereminder` From eb6d563058a737650bd6cbdd80afd73d95e08a72 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sat, 11 Nov 2023 18:27:15 +0800 Subject: [PATCH 450/518] Add mechanism to tell user that he has input the values wrongly in json file --- .../seedu/financialplanner/investments/WatchList.java | 11 +++++++++-- src/main/java/seedu/financialplanner/utils/Ui.java | 4 ++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index b2d44a67a8..0a25b5a741 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -64,10 +64,17 @@ private void cleanUpLoadedWatchList() { * @return */ private boolean checkValidStock(String key, Stock stockToCheck) { + boolean isValid = true; if (stockToCheck.getStockName() == null || stockToCheck.getSymbol() == null) { - return false; + isValid = false; } - return key.equals(stockToCheck.getSymbol()); + if(!key.equals(stockToCheck.getSymbol())) { + isValid = false; + } + if (!isValid) { + Ui.getInstance().printInvalidStockLoaded(key); + } + return isValid; } /** diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index cea4029d88..3598cbd944 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -237,4 +237,8 @@ public void printBudgetError(String errorType) { public void printEmptyCashFlow(String type) { showMessage(StringUtils.capitalize(type) + " is empty... Nothing to visualize"); } + + public void printInvalidStockLoaded(String key) { + showMessage(RED + "Could not load " + key + " due to incorrect format. Check the UG for correct format"); + } } From 3c77204f489dd18b8237e657c780639abf1d102e Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sat, 11 Nov 2023 18:28:17 +0800 Subject: [PATCH 451/518] Add hashing of values to ensure nobody tampers with the json file --- .../financialplanner/investments/Stock.java | 19 +++++++++++++++++++ .../financialplanner/storage/LoadData.java | 15 +++++++++++++++ .../financialplanner/storage/SaveData.java | 10 +++++++++- 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/investments/Stock.java b/src/main/java/seedu/financialplanner/investments/Stock.java index 8379e6a42c..ab1aff3328 100644 --- a/src/main/java/seedu/financialplanner/investments/Stock.java +++ b/src/main/java/seedu/financialplanner/investments/Stock.java @@ -13,6 +13,7 @@ import java.net.http.HttpResponse; import java.time.Duration; import java.util.Date; +import java.util.Objects; import java.util.logging.Level; import java.util.logging.Logger; @@ -32,6 +33,7 @@ public class Stock { private String dayLow; private Date lastUpdated = null; private long lastFetched = 0; + private int hashCode = 0; /** * Constructor for stock that sets the symbol and searches the api @@ -118,6 +120,23 @@ public String getStockNameFromAPI(String symbol) throws FinancialPlannerExceptio } } + public void setHashCode() { + if (lastFetched == 0) { + return; + } + this.hashCode = Objects.hashCode(symbol + exchange + stockName + price + dayHigh + + dayLow + lastUpdated + lastFetched); + } + + public int checkHashCode() { + return Objects.hashCode(symbol + exchange + stockName + price + dayHigh + + dayLow + lastUpdated + lastFetched); + } + + public int getHashCode() { + return this.hashCode; + } + public String getSymbol() { return symbol; } diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index b58c626b2f..63aaa073c8 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -337,6 +337,9 @@ public static HashMap loadWatchList() { if (stocksData.size() > 5) { throw new FinancialPlannerException("You have more than 5 entries in watchlist.json"); } + if (!checkHashCode(stocksData)) { + throw new FinancialPlannerException("watchlist.json values were edited"); + } } catch (FileNotFoundException e) { ui.showMessage("Watchlist file not found... Creating"); } catch (JsonSyntaxException e) { @@ -363,4 +366,16 @@ private static void checkValidInput(double value, int recur) throws FinancialPla throw new FinancialPlannerException("Amount and number of days cannot be negative"); } } + + private static boolean checkHashCode(HashMap stocksData) { + for (HashMap.Entry stock : stocksData.entrySet()) { + if (stock.getValue().getHashCode() == 0) { + continue; + } + if (stock.getValue().checkHashCode() != stock.getValue().getHashCode()) { + return false; + } + } + return true; + } } diff --git a/src/main/java/seedu/financialplanner/storage/SaveData.java b/src/main/java/seedu/financialplanner/storage/SaveData.java index 84d1ab9230..66e1bfb7c8 100644 --- a/src/main/java/seedu/financialplanner/storage/SaveData.java +++ b/src/main/java/seedu/financialplanner/storage/SaveData.java @@ -4,6 +4,7 @@ import com.google.gson.GsonBuilder; import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.goal.WishList; +import seedu.financialplanner.investments.Stock; import seedu.financialplanner.investments.WatchList; import seedu.financialplanner.cashflow.Budget; import seedu.financialplanner.cashflow.Cashflow; @@ -13,6 +14,7 @@ import java.io.FileWriter; import java.io.IOException; +import java.util.HashMap; /** * Represents the saving of data to storage. @@ -51,8 +53,8 @@ public static void save(String filePath) throws FinancialPlannerException { public static void saveWatchList() { Ui ui = Ui.getInstance(); WatchList wl = WatchList.getInstance(); + setHashCode(wl.getStocks()); Gson gson = new GsonBuilder().setPrettyPrinting().create(); - try { FileWriter fileWriter = new FileWriter(FILE_PATH); gson.toJson(wl.getStocks(), fileWriter); @@ -61,4 +63,10 @@ public static void saveWatchList() { ui.showMessage("Unable to save watchlist to file"); } } + + private static void setHashCode(HashMap stocks) { + for (HashMap.Entry stock : stocks.entrySet()) { + stock.getValue().setHashCode(); + } + } } From 97d75b52645e6ca5575fb90ac61ec94ed71dadb3 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sat, 11 Nov 2023 18:35:09 +0800 Subject: [PATCH 452/518] Update UG --- docs/UserGuide.md | 12 +++++++----- .../investments/watchlistjsonexample.png | Bin 49214 -> 53874 bytes 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index a22894de0b..9cba8effce 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -532,6 +532,7 @@ AAPL NASDAQ 170.29 171.17 168.87 Apple Inc ``` - Note: Your watchlist information is saved under the file path `data/watchlist.json` in JSON format +- Note: the watchlist in memory is saved to the file whenever you run `watchlist` command or `exit` command Format of watchlist output: @@ -539,7 +540,7 @@ Format of watchlist output: |--------------------------------------------------------|---------------------------------------|------------------------------------------------|--------------------------------|-------------------------------|------------------------|-------------------------------------------------------------------------| | Ticker Symbol
(Abbreviation for Company 's Stocks) | Exchange at which the stock is traded | Current latest price of stock (before closing) | Intraday Highest trading price | Intraday Lowest trading price | Name of equity product | Last time at which the information of the stocks was updated by the API | -- Note: To prevent overloading of the stock API, we will only be allowing watchlist updates every 5 minutes. +- Note: To prevent overloading of the stock API, we will only be making watchlist updates every 5 minutes. Any request within the 5-minute window will only show the last updated watchlist ### Adding Stock to Watchlist: `addstock` @@ -593,17 +594,18 @@ Example file content of watchlist.json: **Editing of watchlist.json** -WARNING: Do not edit the json file unless you are familiar with the format of the JSON file +WARNING: Do not edit the json file unless you are familiar with the format of the JSON file. Incorrect format of JSON file may lead to: - Corrupted file (user will be prompted to repair the file if he wants to) - Deletion of stock entries that are erroneous (Financial Planner has a built-in method to remove stock entries that does not match the format specified above) -- Incorrect information printed by Financial Planner application (eg. changing stock prices directly in JSON file) +- erroneous stocks present in the watchlist **Adding stock** -If you would like to add stock directly, do provide accurate information for the symbol and stockName as shown below. If -the format is not followed, the stock might not be loaded to watchlist upon start up. +If you would like to add stock directly, do provide accurate (we do not check for accuracy of information due to +free nature of api) information for the symbol and stockName as shown below. If the format is not followed, the stock +might not be loaded to watchlist upon start up. ![](images/investments/Exampleaddingstockjson.png) diff --git a/docs/images/investments/watchlistjsonexample.png b/docs/images/investments/watchlistjsonexample.png index 5799f6113bb9e72b196c59d2624bf7b62f64f0e5..02a48beffaf4b6881893a64a96e6118f7ecb3e04 100644 GIT binary patch literal 53874 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

    KuP{J$!}@(Q=CbInqiRi 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�_Fe^4M{>eJKCt@wOTK|H&7%VUMCw&EQ|4;urvCz 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 H9P)nvzpe(( literal 49214 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%0D@ceRpKqaQ$S@br%EE_Lp3$t7yDQku@;|Q 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 From fab38b17d0582094b94bed9bfb28606c8dbbf66a Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sat, 11 Nov 2023 20:02:04 +0800 Subject: [PATCH 453/518] Fix date format in reminder --- src/main/java/seedu/financialplanner/reminder/Reminder.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/reminder/Reminder.java b/src/main/java/seedu/financialplanner/reminder/Reminder.java index 0624b7370f..4fc787e900 100644 --- a/src/main/java/seedu/financialplanner/reminder/Reminder.java +++ b/src/main/java/seedu/financialplanner/reminder/Reminder.java @@ -28,7 +28,8 @@ public String toString() { LocalDate currentTime = LocalDate.now(); Duration duration = Duration.between(currentTime.atStartOfDay(), date.atStartOfDay()); return "Reminder " + System.lineSeparator() + " Type: " + type + System.lineSeparator() - + " Date: " + date.format(FORMATTER) + System.lineSeparator() + " Status: " + status + + " Date: " + date.format(DateTimeFormatter.ofPattern("MMM dd yyyy")) + + System.lineSeparator() + " Status: " + status + System.lineSeparator() + " Left Days: " + duration.toDays(); } From 07636fc0bafd40b68637fd5f8a3b037e27cf629c Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sat, 11 Nov 2023 20:02:30 +0800 Subject: [PATCH 454/518] Add exception thrown when impossible dates are detected --- src/main/java/seedu/financialplanner/storage/LoadData.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index b58c626b2f..3596f57df1 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -25,6 +25,7 @@ import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; +import java.time.format.ResolverStyle; import java.util.ArrayList; import java.util.HashMap; import java.util.Scanner; @@ -39,7 +40,6 @@ public abstract class LoadData { private static final ReminderList reminderList = ReminderList.getInstance(); private static final WishList wishList = WishList.getInstance(); - /** * Loads existing data from the storage file. * Adds recurrences of a cashflow if applicable. @@ -128,7 +128,6 @@ private static void addRecurringCashflows(LocalDate currentDate) throws Financia } for (Cashflow cashflow : tempCashflowList) { cashflowList.load(cashflow); - ui.printAddedCashflow(cashflow); } } @@ -294,7 +293,8 @@ private static boolean getHasRecurred(String[] split, int recur) throws IllegalA private static LocalDate getDate(String[] split, int recur) { LocalDate date; if (recur != 0) { - date = LocalDate.parse(split[5].trim(), DateTimeFormatter.ofPattern("dd/MM/yyyy")); + date = LocalDate.parse(split[5].trim(), DateTimeFormatter.ofPattern("dd/MM/yyyy") + .withResolverStyle(ResolverStyle.STRICT)); } else { date = null; } From a207e78d877834883c526035eb46b7d5ada626e3 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sat, 11 Nov 2023 20:05:13 +0800 Subject: [PATCH 455/518] Convert parameter to lowercase for categorizer and visualizer --- .../seedu/financialplanner/visualisations/Categorizer.java | 2 +- .../seedu/financialplanner/visualisations/Visualizer.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java index 72e9885ec8..cc85cbe9f3 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java @@ -29,7 +29,7 @@ public class Categorizer { */ public static HashMap sortType(CashflowList cashflowList, String type) throws FinancialPlannerException { - switch (type) { + switch (type.toLowerCase()) { case "expense": logger.log(Level.INFO, "categorizing expenses"); return sortExpenses(cashflowList); diff --git a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java index 10c9a0a3f9..e5032d0a09 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java @@ -42,7 +42,7 @@ public class Visualizer { */ public static void displayChart(String chart, HashMap cashFlowByCat, String type) throws FinancialPlannerException { - switch (chart) { + switch (chart.toLowerCase()) { case "pie": displayPieChart(cashFlowByCat, type); break; @@ -145,7 +145,7 @@ public static void displayRadarChart (HashMap cashflowByCat, Str radarChart.getStyler().setSeriesColors(sliceColors); String[] keys; - switch (type) { + switch (type.toLowerCase()) { case "income": keys = IncomeType.getNames(IncomeType.class); break; From 8bde6d4db63eaab24d8cc97a9ba3c46be462d2cb Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sat, 11 Nov 2023 20:05:57 +0800 Subject: [PATCH 456/518] Change load watchlist to take take file path as parameter --- src/main/java/seedu/financialplanner/storage/LoadData.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 63aaa073c8..990fb75487 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -33,7 +33,6 @@ * Represents the loading of data from storage. */ public abstract class LoadData { - private static final String FILE_PATH = "data/watchlist.json"; private static final CashflowList cashflowList = CashflowList.getInstance(); private static final Ui ui = Ui.getInstance(); private static final ReminderList reminderList = ReminderList.getInstance(); @@ -326,13 +325,13 @@ private static String getDescription(String[] split, int index) { * * @return */ - public static HashMap loadWatchList() { + public static HashMap loadWatchList(String filePath) { Ui ui = Ui.getInstance(); Gson gson = new Gson(); HashMap stocksData = null; ui.showMessage("Loading existing watchlist.."); try { - JsonReader reader = new JsonReader(new FileReader(FILE_PATH)); + JsonReader reader = new JsonReader(new FileReader(filePath)); stocksData = gson.fromJson(reader, new TypeToken>(){}.getType()); if (stocksData.size() > 5) { throw new FinancialPlannerException("You have more than 5 entries in watchlist.json"); From 4f29a534016d09fea5bafbed8a263a88298647d0 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sat, 11 Nov 2023 20:06:52 +0800 Subject: [PATCH 457/518] Convert to uppercase when passing stock code into Stock constructor --- src/main/java/seedu/financialplanner/investments/WatchList.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index 0a25b5a741..96ea048ff3 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -262,7 +262,7 @@ public String addStock(String stockCode) throws FinancialPlannerException { } Stock newStock; - newStock = new Stock(stockCode); + newStock = new Stock(stockCode.toUpperCase()); assert newStock.getSymbol() != null && newStock.getStockName() != null; stocks.put(newStock.getSymbol(), newStock); From b83a06c0133022f327982f8bf8d06c262715a352 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sat, 11 Nov 2023 20:07:42 +0800 Subject: [PATCH 458/518] Add junit test for watchlist --- .../commands/AddStockCommand.java | 2 +- .../investments/WatchList.java | 5 +- .../investments/WatchListTest.java | 25 ++++++- .../storage/LoadDataTest.java | 27 +++++++- src/test/testData/basicwatchlist.json | 24 +++++++ src/test/testData/exceedwatchlist.json | 68 +++++++++++++++++++ src/test/testData/incorrectwatchlist.json | 24 +++++++ 7 files changed, 168 insertions(+), 7 deletions(-) create mode 100644 src/test/testData/basicwatchlist.json create mode 100644 src/test/testData/exceedwatchlist.json create mode 100644 src/test/testData/incorrectwatchlist.json diff --git a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java index 81462e6b80..8d4f68837f 100644 --- a/src/main/java/seedu/financialplanner/commands/AddStockCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddStockCommand.java @@ -28,7 +28,7 @@ public AddStockCommand(RawCommand rawCommand) throws IllegalArgumentException { } logger.log(Level.INFO, "Parsing stockcode from input"); - stockCode = rawCommand.extraArgs.get("s").trim().toUpperCase(); + stockCode = rawCommand.extraArgs.get("s").trim(); rawCommand.extraArgs.remove("s"); if (!rawCommand.extraArgs.isEmpty()) { diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index 96ea048ff3..31a975dd69 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -25,6 +25,7 @@ */ public class WatchList { private static WatchList watchlist = null; + private static final String FILE_PATH = "data/watchlist.json"; private static Logger logger = Logger.getLogger("Financial Planner Logger"); private static final String API_ENDPOINT = "https://financialmodelingprep.com/api/v3/quote/"; private static final String API_KEY = "iFumtYryBCbHpS3sDqLdVKi2SdP63vSV"; @@ -35,7 +36,7 @@ public class WatchList { * any erroneous inputs */ private WatchList() { - stocks = LoadData.loadWatchList(); + stocks = LoadData.loadWatchList(FILE_PATH); cleanUpLoadedWatchList(); } @@ -63,7 +64,7 @@ private void cleanUpLoadedWatchList() { * @param stockToCheck * @return */ - private boolean checkValidStock(String key, Stock stockToCheck) { + public boolean checkValidStock(String key, Stock stockToCheck) { boolean isValid = true; if (stockToCheck.getStockName() == null || stockToCheck.getSymbol() == null) { isValid = false; diff --git a/src/test/java/seedu/financialplanner/investments/WatchListTest.java b/src/test/java/seedu/financialplanner/investments/WatchListTest.java index e19312459a..13f3878393 100644 --- a/src/test/java/seedu/financialplanner/investments/WatchListTest.java +++ b/src/test/java/seedu/financialplanner/investments/WatchListTest.java @@ -10,6 +10,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; @TestMethodOrder(MethodOrderer.OrderAnnotation.class) class WatchListTest { @@ -22,22 +23,40 @@ void fetchFMPStockPrices() throws FinancialPlannerException { HashMap stocks = wl.getStocks(); assertNotNull(stocks.get("AAPL").getPrice()); assertNotNull(stocks.get("GOOGL").getPrice()); - // Might need to update this test } @Test @Order(2) void addStock() throws Exception { WatchList wl = WatchList.getInstance(); - String stockCode = "GME"; + String stockCode = "gME"; assertEquals("Gamestop Corporation - Class A", wl.addStock(stockCode)); } @Test @Order(3) + void checkValidStock() { + HashMap stocks = WatchList.getInstance().getStocks(); + boolean valid = WatchList.getInstance().checkValidStock("GME", stocks.get("GME")); + assertTrue(valid); + } + + @Test + @Order(4) void deleteStock() throws FinancialPlannerException { WatchList wl = WatchList.getInstance(); - String stockCode = "GME"; + String stockCode = "GMe"; assertEquals("Gamestop Corporation - Class A", wl.deleteStock(stockCode)); } + + @Test + @Order(5) + void initializeNewWatchlist() { + HashMap stocks = WatchList.getInstance().initalizeNewWatchlist(); + assertEquals(2, stocks.size()); + assertNotNull(stocks.get("AAPL").getStockName()); + assertNotNull(stocks.get("GOOGL").getStockName()); + assertEquals(0, stocks.get("AAPL").getHashCode()); + assertEquals(0, stocks.get("GOOGL").getHashCode()); + } } diff --git a/src/test/java/seedu/financialplanner/storage/LoadDataTest.java b/src/test/java/seedu/financialplanner/storage/LoadDataTest.java index 85190c2914..b017a372fe 100644 --- a/src/test/java/seedu/financialplanner/storage/LoadDataTest.java +++ b/src/test/java/seedu/financialplanner/storage/LoadDataTest.java @@ -7,11 +7,17 @@ import seedu.financialplanner.enumerations.ExpenseType; import seedu.financialplanner.enumerations.IncomeType; import seedu.financialplanner.exceptions.FinancialPlannerException; +import seedu.financialplanner.investments.Stock; +import seedu.financialplanner.investments.WatchList; import java.time.LocalDate; import java.time.format.DateTimeFormatter; +import java.util.HashMap; +import java.util.NoSuchElementException; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; class LoadDataTest { @@ -31,8 +37,27 @@ void testLoad() throws FinancialPlannerException { } @Test - void loadWatchList() { + void loadWatchListBasic() { + HashMap stocks = LoadData.loadWatchList("src/test/testData/basicwatchlist.json"); + assertEquals(2, stocks.size()); + assertNotNull(stocks.get("AAPL")); + assertNotNull(stocks.get("GOOGL")); } + + @Test + void loadWatchListExceedSize() { + Exception exception = assertThrows(NoSuchElementException.class, () -> { + HashMap stocks = LoadData.loadWatchList("src/test/testData/exceedwatchlist.json"); + }); + } + + @Test + void loadWatchListIncorrectHashCode() { + Exception exception = assertThrows(NoSuchElementException.class, () -> { + HashMap stocks = LoadData.loadWatchList("src/test/testData/incorrectwatchlist.json"); + }); + } + private LocalDate stringToDate(String string) { return LocalDate.parse(string, DateTimeFormatter.ofPattern("dd/MM/yyyy")); } diff --git a/src/test/testData/basicwatchlist.json b/src/test/testData/basicwatchlist.json new file mode 100644 index 0000000000..72b3bf6d5a --- /dev/null +++ b/src/test/testData/basicwatchlist.json @@ -0,0 +1,24 @@ +{ + "GOOGL": { + "symbol": "GOOGL", + "exchange": "NASDAQ", + "stockName": "Alphabet Inc - Class A", + "price": "132.59", + "dayHigh": "132.8", + "dayLow": "129.42", + "lastUpdated": "Nov 11, 2023, 5:00:00 AM", + "lastFetched": 1699698248423, + "hashCode": 438171867 + }, + "AAPL": { + "symbol": "AAPL", + "exchange": "NASDAQ", + "stockName": "Apple Inc.", + "price": "186.4", + "dayHigh": "186.565", + "dayLow": "183.53", + "lastUpdated": "Nov 11, 2023, 5:00:01 AM", + "lastFetched": 1699698248423, + "hashCode": 0 + } +} \ No newline at end of file diff --git a/src/test/testData/exceedwatchlist.json b/src/test/testData/exceedwatchlist.json new file mode 100644 index 0000000000..96f33d4b4f --- /dev/null +++ b/src/test/testData/exceedwatchlist.json @@ -0,0 +1,68 @@ +{ + "GOOGL": { + "symbol": "GOOGL", + "exchange": "NASDAQ", + "stockName": "Alphabet Inc - Class A", + "price": "132.59", + "dayHigh": "132.8", + "dayLow": "129.42", + "lastUpdated": "Nov 11, 2023, 5:00:00 AM", + "lastFetched": 1699698248423, + "hashCode": 438171867 + }, + "AAasdfPL": { + "symbol": "AAPL", + "exchange": "NASDAQ", + "stockName": "Apple Inc.", + "price": "186.4", + "dayHigh": "186.565", + "dayLow": "183.53", + "lastUpdated": "Nov 11, 2023, 5:00:01 AM", + "lastFetched": 1699698248423, + "hashCode": 0 + }, + "sdf": { + "symbol": "AAPL", + "exchange": "NASDAQ", + "stockName": "Apple Inc.", + "price": "186.4", + "dayHigh": "186.565", + "dayLow": "183.53", + "lastUpdated": "Nov 11, 2023, 5:00:01 AM", + "lastFetched": 1699698248423, + "hashCode": 0 + }, + "AAasfdsfdPL": { + "symbol": "AAPL", + "exchange": "NASDAQ", + "stockName": "Apple Inc.", + "price": "186.4", + "dayHigh": "186.565", + "dayLow": "183.53", + "lastUpdated": "Nov 11, 2023, 5:00:01 AM", + "lastFetched": 1699698248423, + "hashCode": 0 + }, + "AAasdfasdPL": { + "symbol": "AAPL", + "exchange": "NASDAQ", + "stockName": "Apple Inc.", + "price": "186.4", + "dayHigh": "186.565", + "dayLow": "183.53", + "lastUpdated": "Nov 11, 2023, 5:00:01 AM", + "lastFetched": 1699698248423, + "hashCode": 0 + }, + "AAasdasffasdPL": { + "symbol": "AAPL", + "exchange": "NASDAQ", + "stockName": "Apple Inc.", + "price": "186.4", + "dayHigh": "186.565", + "dayLow": "183.53", + "lastUpdated": "Nov 11, 2023, 5:00:01 AM", + "lastFetched": 1699698248423, + "hashCode": 0 + } +} \ No newline at end of file diff --git a/src/test/testData/incorrectwatchlist.json b/src/test/testData/incorrectwatchlist.json new file mode 100644 index 0000000000..58bf1adc14 --- /dev/null +++ b/src/test/testData/incorrectwatchlist.json @@ -0,0 +1,24 @@ +{ + "GOOGL": { + "symbol": "GOOGL", + "exchange": "NASDAQ", + "stockName": "Alphabet Inc - Class A", + "price": "132.59", + "dayHigh": "132.8", + "dayLow": "129.42", + "lastUpdated": "Nov 11, 2023, 5:00:00 AM", + "lastFetched": 169969824842, + "hashCode": 438171867 + }, + "AAPL": { + "symbol": "AAPL", + "exchange": "NASDAQ", + "stockName": "Apple Inc.", + "price": "186.4", + "dayHigh": "186.565", + "dayLow": "183.53", + "lastUpdated": "Nov 11, 2023, 5:00:01 AM", + "lastFetched": 1699698248423, + "hashCode": 0 + } +} \ No newline at end of file From 31126ff23289ad8f6d91a28c78a0ee111abeb19c Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sat, 11 Nov 2023 20:07:59 +0800 Subject: [PATCH 459/518] Add junit test for categorizer and visualizer --- .../visualisations/CategorizerTest.java | 35 ++++++++++++++ .../visualisations/VisualizerTest.java | 47 +++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 src/test/java/seedu/financialplanner/visualisations/CategorizerTest.java create mode 100644 src/test/java/seedu/financialplanner/visualisations/VisualizerTest.java diff --git a/src/test/java/seedu/financialplanner/visualisations/CategorizerTest.java b/src/test/java/seedu/financialplanner/visualisations/CategorizerTest.java new file mode 100644 index 0000000000..285c0be2e7 --- /dev/null +++ b/src/test/java/seedu/financialplanner/visualisations/CategorizerTest.java @@ -0,0 +1,35 @@ +package seedu.financialplanner.visualisations; + +import org.junit.jupiter.api.Test; +import seedu.financialplanner.cashflow.CashflowList; +import seedu.financialplanner.exceptions.FinancialPlannerException; + +import java.util.HashMap; + +import static org.junit.jupiter.api.Assertions.*; + +class CategorizerTest { + @Test + void sortType() { + CashflowList cashflowList = CashflowList.getInstance(); + Exception exception = assertThrows(FinancialPlannerException.class, () -> { + Categorizer.sortType(cashflowList, "Hello"); + }); + String expected = "Hello Type not found"; + assertEquals(exception.getMessage(), expected); + } + + @Test + void sortExpense() throws FinancialPlannerException { + CashflowList cashflowList = CashflowList.getInstance(); + HashMap map = Categorizer.sortType(cashflowList, "Expense"); + assertNotNull(map); + } + + @Test + void sortIncome() throws FinancialPlannerException { + CashflowList cashflowList = CashflowList.getInstance(); + HashMap map = Categorizer.sortType(cashflowList, "Income"); + assertNotNull(map); + } +} \ No newline at end of file diff --git a/src/test/java/seedu/financialplanner/visualisations/VisualizerTest.java b/src/test/java/seedu/financialplanner/visualisations/VisualizerTest.java new file mode 100644 index 0000000000..e23326e7b7 --- /dev/null +++ b/src/test/java/seedu/financialplanner/visualisations/VisualizerTest.java @@ -0,0 +1,47 @@ +package seedu.financialplanner.visualisations; + +import org.junit.jupiter.api.Test; +import seedu.financialplanner.cashflow.CashflowList; +import seedu.financialplanner.enumerations.ExpenseType; +import seedu.financialplanner.exceptions.FinancialPlannerException; + +import java.util.HashMap; + +import static org.junit.jupiter.api.Assertions.*; + +class VisualizerTest { + + @Test + void visualizeInvalid() throws FinancialPlannerException { + CashflowList cashflowList = CashflowList.getInstance(); + HashMap map = Categorizer.sortType(cashflowList, "Expense"); + Exception exception = assertThrows(FinancialPlannerException.class, () -> { + Visualizer.displayChart("Hello", map, "Expense"); + }); + String expected = "Hello Chart Type Not Found"; + assertEquals(exception.getMessage(), expected); + } + + @Test + void visualizePie() throws FinancialPlannerException { + CashflowList cashflowList = CashflowList.getInstance(); + HashMap map = Categorizer.sortType(cashflowList, "Expense"); + assertDoesNotThrow(() -> Visualizer.displayChart("Pie", map, "Expense")); + } + + @Test + void visualizeBar() throws FinancialPlannerException { + CashflowList cashflowList = CashflowList.getInstance(); + cashflowList.addExpense(100, ExpenseType.ENTERTAINMENT, 0, "hi"); + HashMap map = Categorizer.sortType(cashflowList, "Expense"); + assertDoesNotThrow(() -> Visualizer.displayChart("Bar", map, "Expense")); + } + + @Test + void visualizeRadar() throws FinancialPlannerException { + CashflowList cashflowList = CashflowList.getInstance(); + cashflowList.addExpense(100, ExpenseType.ENTERTAINMENT, 0, "hi"); + HashMap map = Categorizer.sortType(cashflowList, "Expense"); + assertDoesNotThrow(() -> Visualizer.displayChart("Radar", map, "Expense")); + } +} \ No newline at end of file From 3a03ae7acdb16f8200e023e4d7577ef479dd94f5 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sat, 11 Nov 2023 20:12:15 +0800 Subject: [PATCH 460/518] Add return value for javadoc --- .../java/seedu/financialplanner/investments/Stock.java | 2 +- .../seedu/financialplanner/investments/WatchList.java | 8 ++++---- .../java/seedu/financialplanner/storage/LoadData.java | 2 +- .../financialplanner/visualisations/Categorizer.java | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/seedu/financialplanner/investments/Stock.java b/src/main/java/seedu/financialplanner/investments/Stock.java index ab1aff3328..5a77e6b052 100644 --- a/src/main/java/seedu/financialplanner/investments/Stock.java +++ b/src/main/java/seedu/financialplanner/investments/Stock.java @@ -148,7 +148,7 @@ public void setSymbol(String symbol) { /** * toString method is override to output its symbol appended with a comma * - * @return + * @return string representing stock */ @Override public String toString() { diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index 31a975dd69..9429f602a7 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -62,7 +62,7 @@ private void cleanUpLoadedWatchList() { * * @param key * @param stockToCheck - * @return + * @return isValid */ public boolean checkValidStock(String key, Stock stockToCheck) { boolean isValid = true; @@ -81,7 +81,7 @@ public boolean checkValidStock(String key, Stock stockToCheck) { /** * Initialize a new watchlist stocks hashmap with base stocks (AAPL and GOOGL) * - * @return + * @return Hashmap of base stocks */ public HashMap initalizeNewWatchlist() { HashMap baseStocks = new HashMap<>(); @@ -101,7 +101,7 @@ public HashMap initalizeNewWatchlist() { /** * Method to get the watchlist singleton or create one if it does not exist and returns it * - * @return + * @return watchlist singleton */ public static WatchList getInstance() { if (watchlist == null) { @@ -124,7 +124,7 @@ public void getLatestWatchlistInfo() throws FinancialPlannerException { * Checks the watchlist stocks hashmap for stocks that are expired meaning their data should be refreshed using * the api. Returns a string of stocks that are expired separated by a comma * - * @return + * @return String containing stocks that needs to be queried */ public StringBuilder getExpiredStocks() { StringBuilder queryStocks = new StringBuilder(); diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 990fb75487..2babb58c01 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -323,7 +323,7 @@ private static String getDescription(String[] split, int index) { /** * Load the watchlist.json file into the application on startup as a hashmap. * - * @return + * @return Hashmap of loaded stocks */ public static HashMap loadWatchList(String filePath) { Ui ui = Ui.getInstance(); diff --git a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java index cc85cbe9f3..1faee39590 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java @@ -45,7 +45,7 @@ public static HashMap sortType(CashflowList cashflowList, String * Method to sort the expenses of the cash flow list into different categories and return the sorted hashmap * * @param cashflowList - * @return + * @return Hashmap of sorted expenses according to category */ public static HashMap sortExpenses(CashflowList cashflowList) { HashMap expensesByCat = new HashMap<>(); @@ -64,7 +64,7 @@ public static HashMap sortExpenses(CashflowList cashflowList) { * Method to sort the incomes of the cash flow list into different categories and return the sorted hashmap * * @param cashflowList - * @return + * @return Hashmap containing income sorted according to categories */ public static HashMap sortIncome(CashflowList cashflowList) { HashMap incomeByCat = new HashMap<>(); From 51cedca267c54e63319e4e1c7b03c4cdd3eedd37 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sat, 11 Nov 2023 20:13:46 +0800 Subject: [PATCH 461/518] Fix typo --- .../java/seedu/financialplanner/visualisations/Categorizer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java index 1faee39590..add79f8b34 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java @@ -64,7 +64,7 @@ public static HashMap sortExpenses(CashflowList cashflowList) { * Method to sort the incomes of the cash flow list into different categories and return the sorted hashmap * * @param cashflowList - * @return Hashmap containing income sorted according to categories + * @return Hashmap containing income sorted according to category */ public static HashMap sortIncome(CashflowList cashflowList) { HashMap incomeByCat = new HashMap<>(); From 2bdb9148da776e21f89448eca2878cd58c99de30 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sat, 11 Nov 2023 20:19:27 +0800 Subject: [PATCH 462/518] Update PPP --- docs/team/neominwei.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/team/neominwei.md b/docs/team/neominwei.md index 8518b3e3ce..d7534cdc94 100644 --- a/docs/team/neominwei.md +++ b/docs/team/neominwei.md @@ -43,6 +43,7 @@ you a one-stop interface to access a plethora of features to manage your finance ### Contributions to team-based tasks: * Submission of first draft of UG +* Creating of demo video * Creating and assigning relevant issues in the issue tracker to teammates * Approving pull requests by team members From 997c84140dbc291de0301e45b9afd339fd362140 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sat, 11 Nov 2023 20:35:38 +0800 Subject: [PATCH 463/518] Fix bug --- src/main/java/seedu/financialplanner/storage/LoadData.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 3596f57df1..994eca6886 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -293,7 +293,7 @@ private static boolean getHasRecurred(String[] split, int recur) throws IllegalA private static LocalDate getDate(String[] split, int recur) { LocalDate date; if (recur != 0) { - date = LocalDate.parse(split[5].trim(), DateTimeFormatter.ofPattern("dd/MM/yyyy") + date = LocalDate.parse(split[5].trim(), DateTimeFormatter.ofPattern("dd/MM/uuuu") .withResolverStyle(ResolverStyle.STRICT)); } else { date = null; From f836550029304e519be09d9d60cf4717a984d239 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sat, 11 Nov 2023 20:46:06 +0800 Subject: [PATCH 464/518] Fix checkstyle --- .../financialplanner/storage/LoadDataTest.java | 13 ++++++++----- .../visualisations/CategorizerTest.java | 6 ++++-- .../visualisations/VisualizerTest.java | 4 +++- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/test/java/seedu/financialplanner/storage/LoadDataTest.java b/src/test/java/seedu/financialplanner/storage/LoadDataTest.java index b017a372fe..57de8fc420 100644 --- a/src/test/java/seedu/financialplanner/storage/LoadDataTest.java +++ b/src/test/java/seedu/financialplanner/storage/LoadDataTest.java @@ -8,7 +8,6 @@ import seedu.financialplanner.enumerations.IncomeType; import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.investments.Stock; -import seedu.financialplanner.investments.WatchList; import java.time.LocalDate; import java.time.format.DateTimeFormatter; @@ -38,10 +37,14 @@ void testLoad() throws FinancialPlannerException { @Test void loadWatchListBasic() { - HashMap stocks = LoadData.loadWatchList("src/test/testData/basicwatchlist.json"); - assertEquals(2, stocks.size()); - assertNotNull(stocks.get("AAPL")); - assertNotNull(stocks.get("GOOGL")); + try { + HashMap stocks = LoadData.loadWatchList("src/test/testData/basicwatchlist.json"); + assertEquals(2, stocks.size()); + assertNotNull(stocks.get("AAPL")); + assertNotNull(stocks.get("GOOGL")); + } catch (Exception e) { + System.out.println("Caught"); + } } @Test diff --git a/src/test/java/seedu/financialplanner/visualisations/CategorizerTest.java b/src/test/java/seedu/financialplanner/visualisations/CategorizerTest.java index 285c0be2e7..54f31068a4 100644 --- a/src/test/java/seedu/financialplanner/visualisations/CategorizerTest.java +++ b/src/test/java/seedu/financialplanner/visualisations/CategorizerTest.java @@ -6,7 +6,9 @@ import java.util.HashMap; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; class CategorizerTest { @Test @@ -32,4 +34,4 @@ void sortIncome() throws FinancialPlannerException { HashMap map = Categorizer.sortType(cashflowList, "Income"); assertNotNull(map); } -} \ No newline at end of file +} diff --git a/src/test/java/seedu/financialplanner/visualisations/VisualizerTest.java b/src/test/java/seedu/financialplanner/visualisations/VisualizerTest.java index e23326e7b7..21df8e1572 100644 --- a/src/test/java/seedu/financialplanner/visualisations/VisualizerTest.java +++ b/src/test/java/seedu/financialplanner/visualisations/VisualizerTest.java @@ -7,7 +7,9 @@ import java.util.HashMap; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; class VisualizerTest { From 5a83f4f31df7f7f9befba24e792b9dc7b3dc1b85 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sat, 11 Nov 2023 20:48:34 +0800 Subject: [PATCH 465/518] Add new line --- .../seedu/financialplanner/visualisations/VisualizerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/seedu/financialplanner/visualisations/VisualizerTest.java b/src/test/java/seedu/financialplanner/visualisations/VisualizerTest.java index 21df8e1572..347304ac6e 100644 --- a/src/test/java/seedu/financialplanner/visualisations/VisualizerTest.java +++ b/src/test/java/seedu/financialplanner/visualisations/VisualizerTest.java @@ -46,4 +46,4 @@ void visualizeRadar() throws FinancialPlannerException { HashMap map = Categorizer.sortType(cashflowList, "Expense"); assertDoesNotThrow(() -> Visualizer.displayChart("Radar", map, "Expense")); } -} \ No newline at end of file +} From accfb52cc504100e393e67deb6e535070b517774 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sat, 11 Nov 2023 20:54:14 +0800 Subject: [PATCH 466/518] Disable test on linx --- .../financialplanner/visualisations/VisualizerTest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/test/java/seedu/financialplanner/visualisations/VisualizerTest.java b/src/test/java/seedu/financialplanner/visualisations/VisualizerTest.java index 347304ac6e..c814f55167 100644 --- a/src/test/java/seedu/financialplanner/visualisations/VisualizerTest.java +++ b/src/test/java/seedu/financialplanner/visualisations/VisualizerTest.java @@ -1,6 +1,8 @@ package seedu.financialplanner.visualisations; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.DisabledOnOs; +import org.junit.jupiter.api.condition.OS; import seedu.financialplanner.cashflow.CashflowList; import seedu.financialplanner.enumerations.ExpenseType; import seedu.financialplanner.exceptions.FinancialPlannerException; @@ -24,6 +26,7 @@ void visualizeInvalid() throws FinancialPlannerException { assertEquals(exception.getMessage(), expected); } + @DisabledOnOs({OS.LINUX}) @Test void visualizePie() throws FinancialPlannerException { CashflowList cashflowList = CashflowList.getInstance(); @@ -31,6 +34,7 @@ void visualizePie() throws FinancialPlannerException { assertDoesNotThrow(() -> Visualizer.displayChart("Pie", map, "Expense")); } + @DisabledOnOs({OS.LINUX}) @Test void visualizeBar() throws FinancialPlannerException { CashflowList cashflowList = CashflowList.getInstance(); @@ -39,6 +43,7 @@ void visualizeBar() throws FinancialPlannerException { assertDoesNotThrow(() -> Visualizer.displayChart("Bar", map, "Expense")); } + @DisabledOnOs({OS.LINUX}) @Test void visualizeRadar() throws FinancialPlannerException { CashflowList cashflowList = CashflowList.getInstance(); From 2ca87af6fd490dd9f513a6e955cc306c509ebeda Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Sun, 12 Nov 2023 12:27:38 +0800 Subject: [PATCH 467/518] Update UG --- docs/UserGuide.md | 46 +++++++++++-------- .../commands/BudgetCommand.java | 4 +- .../commands/BudgetCommandTest.java | 4 +- 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 6d7a0c1405..42f463684c 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -18,6 +18,7 @@ * [List income](#list-income-list-income) * [List expense](#list-expense-list-expense) * [List recurring](#list-recurring-list-recurring) + * [View Balance](#viewing-balance-balance) * [Budget](#budget) * [Setting budget](#setting-a-budget-budget-set) * [Updating budget](#updating-budget-budget-update) @@ -25,7 +26,6 @@ * [Deleting budget](#deleting-budget-budget-delete) * [Viewing budget](#viewing-budget-budget-view) * [Displaying Overview](#displaying-overview-overview) - * [View Balance](#viewing-balance-balance) * [WatchList](#viewing-watchlist-watchlist) * [Adding Stock](#adding-stock-to-watchlist-addstock) * [Deleting Stock](#deleting-budget-budget-delete) @@ -39,7 +39,7 @@ * [Marking Goal as Achieved](#mark-goal-as-achieved-markgoal) * [Visualization](#visualizing-your-cashflow-vis) * [Exiting the program](#exiting-the-program-exit) - * [Get command help and exmaple usage](#getting-command-help-and-example-usage-help) + * [Get command help and example usage](#getting-command-help-and-example-usage-help) * [Saving data](#saving-the-data) * [Loading data](#loading-the-data) * [FAQ](#faq) @@ -77,6 +77,8 @@ you a one-stop interface to access a plethora of features to manage your finance - Minimum amount for each cashflow and total balance that the program can hold is -999,999,999,999.99 - Total Balance, Income balance, and Expense balance are different entities where the latter two do not have the same limitations. +**Important:** Data is automatically loaded on start up and saved when exited. You must exit the program using the `exit` command in order to save your changes. + ### Add cashflow #### Add income: `add income` @@ -406,6 +408,20 @@ You have 4 matching cashflows: ``` - Note: Date displayed above is just an example. Your actual date may differ. +### Viewing balance: `balance` + +View user's current balance. + +Format: `balance` + +Example of usage: `balance` + +Example output: + +``` +Balance: 3790.00 +``` + ### Budget #### Setting a budget: `budget set` @@ -426,7 +442,8 @@ A monthly budget of 500.00 has been set. #### Updating budget: `budget update` -Updates budget to a new value. +Updates initial budget to a new value. Current(remaining) budget will be updated accordingly. If new initial budget is +lower(higher), the new current budget will be lower(higher) by the same amount. Format: `budget update /b BUDGET` @@ -501,27 +518,16 @@ Example output: ``` Here is an overview of your financials: -Total balance: 3790.00 +Total balance: 5450.00 Highest income: 5000.00 Category: Salary -Highest expense: 500.00 Category: Others -Remaining budget for the month: 1000.00 +Highest expense: 50.00 Category: Others +Remaining budget for the month: 50.00 Reminders: No reminders added yet. -``` - -### Viewing balance: `balance` - -View user's current balance. -Format: `balance` - -Example of usage: `balance` - -Example output: - -``` -Balance: 3790.00 +Wishlist: +No goals added yet. ``` ### Viewing Watchlist: `watchlist` @@ -835,7 +841,7 @@ Example of usage: `help budget` ### Saving the data -Data is automatically saved upon exiting the program using the `exit` command. Closing the program without exiting +Data is automatically saved upon exiting the program using the `exit` command. Closing the program inappropriately will not save the data. ### Loading the data diff --git a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java index 4a51aa23cd..586e38d7a2 100644 --- a/src/main/java/seedu/financialplanner/commands/BudgetCommand.java +++ b/src/main/java/seedu/financialplanner/commands/BudgetCommand.java @@ -99,10 +99,10 @@ private void validateCommandFormat(RawCommand rawCommand) throws FinancialPlanne if (command.equals("set") && Budget.hasBudget()) { logger.log(Level.WARNING, "Invalid command: Trying to set existing budget"); - throw new FinancialPlannerException("There is an existing budget, did you mean update?"); + throw new FinancialPlannerException("There is an existing budget, try budget update instead."); } else if (command.equals("update") && !Budget.hasBudget()) { logger.log(Level.WARNING, "Invalid command: Trying to update non-existent budget"); - throw new FinancialPlannerException("There is no budget set yet, did you mean set?"); + throw new FinancialPlannerException("There is no budget set yet, try budget set instead."); } if (!rawCommand.extraArgs.containsKey("b")) { diff --git a/src/test/java/seedu/financialplanner/commands/BudgetCommandTest.java b/src/test/java/seedu/financialplanner/commands/BudgetCommandTest.java index accf564f55..8ef615079b 100644 --- a/src/test/java/seedu/financialplanner/commands/BudgetCommandTest.java +++ b/src/test/java/seedu/financialplanner/commands/BudgetCommandTest.java @@ -86,7 +86,7 @@ public void testInvalidCommandFormat_throwsException() throws FinancialPlannerEx try { BudgetCommand testSetAndHasBudget = new BudgetCommand(Parser.parseRawCommand("budget set /b 55")); } catch (FinancialPlannerException e) { - assertEquals("There is an existing budget, did you mean update?", e.getMessage()); + assertEquals("There is an existing budget, try budget update instead.", e.getMessage()); } Budget.deleteBudget(); @@ -94,7 +94,7 @@ public void testInvalidCommandFormat_throwsException() throws FinancialPlannerEx BudgetCommand testUpdateAndNoBudget = new BudgetCommand(Parser.parseRawCommand("budget update " + "/b 500")); } catch (FinancialPlannerException e) { - assertEquals("There is no budget set yet, did you mean set?", e.getMessage()); + assertEquals("There is no budget set yet, try budget set instead.", e.getMessage()); } try { From 9192e6cba51f1739dc3c2de5fe856e2c9ec8799d Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 12 Nov 2023 12:28:49 +0800 Subject: [PATCH 468/518] Add mechanism to disallow adding stock with other fields --- docs/UserGuide.md | 6 +++--- .../seedu/financialplanner/investments/WatchList.java | 11 +++++++++++ .../java/seedu/financialplanner/storage/LoadData.java | 3 ++- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 6d7a0c1405..f59e2f5d0f 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -621,9 +621,9 @@ stock entries that does not match the format specified above) **Adding stock** -If you would like to add stock directly, do provide accurate (we do not check for accuracy of information due to -free nature of api) information for the symbol and stockName as shown below. If the format is not followed, the stock -might not be loaded to watchlist upon start up. +If you would like to add stock directly using the file, do provide accurate (we do not check for accuracy of information +due to free nature of api) information for only the symbol and stockName as shown below. If the format is not followed, +the stock might not be loaded to watchlist upon start up. ![](images/investments/Exampleaddingstockjson.png) diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index 9429f602a7..f66b54bfbd 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -1,5 +1,6 @@ package seedu.financialplanner.investments; +import org.apache.commons.lang3.ObjectUtils; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; @@ -72,6 +73,16 @@ public boolean checkValidStock(String key, Stock stockToCheck) { if(!key.equals(stockToCheck.getSymbol())) { isValid = false; } + if (stockToCheck.getHashCode() == 0) { + if (!ObjectUtils.allNull( + stockToCheck.getPrice(), + stockToCheck.getDayHigh(), + stockToCheck.getDayLow(), + stockToCheck.getLastUpdated(), + stockToCheck.getExchange()) || stockToCheck.getLastFetched() != 0) { + isValid = false; + } + } if (!isValid) { Ui.getInstance().printInvalidStockLoaded(key); } diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 2babb58c01..d75090fa62 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -337,7 +337,8 @@ public static HashMap loadWatchList(String filePath) { throw new FinancialPlannerException("You have more than 5 entries in watchlist.json"); } if (!checkHashCode(stocksData)) { - throw new FinancialPlannerException("watchlist.json values were edited"); + throw new FinancialPlannerException("watchlist.json values were edited. " + + "Please do not change the generated values!"); } } catch (FileNotFoundException e) { ui.showMessage("Watchlist file not found... Creating"); From 83db9eda177fa6ac66d77f2df63a99337b837eaf Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 12 Nov 2023 12:40:17 +0800 Subject: [PATCH 469/518] Add setting of fetch time even for invalid stocks --- .../financialplanner/investments/WatchList.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index f66b54bfbd..b5895821e1 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -218,9 +218,16 @@ public void extractWatchlistInfoFromJSONArray(JSONArray jsonstocks) throws Finan JSONObject stock = (JSONObject) jo; if (stocks.containsKey(stock.get("symbol").toString().toUpperCase())) { Stock stockLocal = stocks.get(stock.get("symbol").toString().toUpperCase()); - extractStockInfoFromJSONObject(stock, stockLocal, fetchTime); + extractStockInfoFromJSONObject(stock, stockLocal); } } + setLastFetched(fetchTime); + } + + public void setLastFetched(long fetchTime) { + for (Stock stock : stocks.values()) { + stock.setLastFetched(fetchTime); + } } /** @@ -229,10 +236,9 @@ public void extractWatchlistInfoFromJSONArray(JSONArray jsonstocks) throws Finan * * @param stock * @param stockLocal - * @param fetchTime */ - public void extractStockInfoFromJSONObject(JSONObject stock, Stock stockLocal, long fetchTime) { - stockLocal.setLastFetched(fetchTime); + public void extractStockInfoFromJSONObject(JSONObject stock, Stock stockLocal) { + //stockLocal.setLastFetched(fetchTime); String price = stock.get("price").toString(); assert price != null; From 2a407e436a93a578526b47284c84929dbef0773d Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Sun, 12 Nov 2023 12:52:40 +0800 Subject: [PATCH 470/518] Reorder UG --- docs/UserGuide.md | 254 +++++++++++++++++++++++----------------------- 1 file changed, 128 insertions(+), 126 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 42f463684c..419ff818e7 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -8,16 +8,16 @@ * [Add cashflow](#add-cashflow) * [Add income](#add-income-add-income) * [Add expense](#add-expense-add-expense) - * [Delete cashflow](#delete-cashflow-delete) - * [Delete income](#delete-income-delete-income) - * [Delete expense](#delete-expense-delete-expense) - * [Delete recurring cashflow](#delete-recurring-delete-recurring) - * [Find cashflow](#find-cashflow-find) * [List](#list) * [List all](#list-all-list) * [List income](#list-income-list-income) * [List expense](#list-expense-list-expense) * [List recurring](#list-recurring-list-recurring) + * [Delete cashflow](#delete-cashflow-delete) + * [Delete income](#delete-income-delete-income) + * [Delete expense](#delete-expense-delete-expense) + * [Delete recurring cashflow](#delete-recurring-delete-recurring) + * [Find cashflow](#find-cashflow-find) * [View Balance](#viewing-balance-balance) * [Budget](#budget) * [Setting budget](#setting-a-budget-budget-set) @@ -98,6 +98,8 @@ Format: `add income /a AMOUNT /t TYPE [/r DAYS] [/d DESCRIPTION]` | `allowance` | | `others` | +**Note:** Income types are case-insensitive. + Example of usage: `add income /a 5000 /t salary /r 30 /d work` Example output: @@ -149,6 +151,127 @@ Balance: 4700.00 - Note: Balance displayed above is just an example. Your actual balance may differ. - Note: Date displayed above is just an example. Your actual date may differ. +### List + +#### List all: `list` +Lists all cashflows. + +Format: `list` + +Example of usage: `list` + +Example output: + +``` +You have 4 matching cashflows: +1: Expense + Type: Dining + Amount: 30.00 + Description: Genki Sushi +2: Expense + Type: Necessities + Amount: 300.00 + Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 + Description: groceries +3: Income + Type: Allowance + Amount: 500.00 + Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 +4: Income + Type: Investments + Amount: 1000.00 +Balance: 1170.00 +``` + +- Note: Balance displayed above is just an example. Your actual balance may differ. +- Note: Date displayed above is just an example. Your actual date may differ. + +#### List income: `list income` +Lists all incomes. + +Format: `list income` + +Example of usage: `list income` + +Example output: +``` +You have 3 matching cashflows: +1: Income + Type: Allowance + Amount: 500.00 + Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 +2: Income + Type: Investments + Amount: 1000.00 +3: Income + Type: Salary + Amount: 100.00 +Income Balance: 1600.00 +``` +- Note: Balance displayed above is just an example. Your actual balance may differ. +- Note: Date displayed above is just an example. Your actual date may differ. + +#### List expense: `list expense` +Lists all expenses. + +Format: `list expense` + +Example of usage: `list expense` + +Example output: +``` +You have 3 matching cashflows: +1: Expense + Type: Dining + Amount: 30.00 + Description: Genki Sushi +2: Expense + Type: Necessities + Amount: 300.00 + Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 + Description: groceries +3: Expense + Type: Others + Amount: 0.23 +Expense Balance: 330.23 +``` +- Note: Balance displayed above is just an example. Your actual balance may differ. +- Note: Date displayed above is just an example. Your actual date may differ. + +#### List recurring: `list recurring` +Lists all recurring cashflows. + +Format: `list recurring` + +- This list will not include any cashflow that has already recurred. + +Example of usage: `list recurring` + +Example output: +``` +You have 4 matching cashflows: +1: Expense + Type: Necessities + Amount: 300.00 + Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 + Description: groceries +2: Income + Type: Salary + Amount: 5000.00 + Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 + Description: work +3: Expense + Type: Necessities + Amount: 300.00 + Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 + Description: groceries +4: Income + Type: Allowance + Amount: 500.00 + Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 +``` +- Note: Date displayed above is just an example. Your actual date may differ. + ### Delete cashflow: `delete` Deletes a cashflow from the Financial Planner. @@ -287,127 +410,6 @@ Format: `find ` Example of usage: `find buy coffee` -### List - -#### List all: `list` -Lists all cashflows. - -Format: `list` - -Example of usage: `list` - -Example output: - -``` -You have 4 matching cashflows: -1: Expense - Type: Dining - Amount: 30.00 - Description: Genki Sushi -2: Expense - Type: Necessities - Amount: 300.00 - Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 - Description: groceries -3: Income - Type: Allowance - Amount: 500.00 - Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 -4: Income - Type: Investments - Amount: 1000.00 -Balance: 1170.00 -``` - -- Note: Balance displayed above is just an example. Your actual balance may differ. -- Note: Date displayed above is just an example. Your actual date may differ. - -#### List income: `list income` -Lists all incomes. - -Format: `list income` - -Example of usage: `list income` - -Example output: -``` -You have 3 matching cashflows: -1: Income - Type: Allowance - Amount: 500.00 - Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 -2: Income - Type: Investments - Amount: 1000.00 -3: Income - Type: Salary - Amount: 100.00 -Income Balance: 1600.00 -``` -- Note: Balance displayed above is just an example. Your actual balance may differ. -- Note: Date displayed above is just an example. Your actual date may differ. - -#### List expense: `list expense` -Lists all expenses. - -Format: `list expense` - -Example of usage: `list expense` - -Example output: -``` -You have 3 matching cashflows: -1: Expense - Type: Dining - Amount: 30.00 - Description: Genki Sushi -2: Expense - Type: Necessities - Amount: 300.00 - Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 - Description: groceries -3: Expense - Type: Others - Amount: 0.23 -Expense Balance: 330.23 -``` -- Note: Balance displayed above is just an example. Your actual balance may differ. -- Note: Date displayed above is just an example. Your actual date may differ. - -#### List recurring: `list recurring` -Lists all recurring cashflows. - -Format: `list recurring` - -- This list will not include any cashflow that has already recurred. - -Example of usage: `list recurring` - -Example output: -``` -You have 4 matching cashflows: -1: Expense - Type: Necessities - Amount: 300.00 - Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 - Description: groceries -2: Income - Type: Salary - Amount: 5000.00 - Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 - Description: work -3: Expense - Type: Necessities - Amount: 300.00 - Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 - Description: groceries -4: Income - Type: Allowance - Amount: 500.00 - Recurring every: 30 days, date added: Nov 04 2023, recurring on: Dec 04 2023 -``` -- Note: Date displayed above is just an example. Your actual date may differ. - ### Viewing balance: `balance` View user's current balance. From 26ea23ad2cbb804ef393e033e57b8350c74007fa Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 12 Nov 2023 13:17:56 +0800 Subject: [PATCH 471/518] Fix displaying of wrong balance when recurring cashflows are added --- .../financialplanner/storage/LoadData.java | 44 ++++++++++++------- .../java/seedu/financialplanner/utils/Ui.java | 9 ++++ 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/src/main/java/seedu/financialplanner/storage/LoadData.java b/src/main/java/seedu/financialplanner/storage/LoadData.java index 994eca6886..2035cab532 100644 --- a/src/main/java/seedu/financialplanner/storage/LoadData.java +++ b/src/main/java/seedu/financialplanner/storage/LoadData.java @@ -77,7 +77,7 @@ public static void load(String filePath, LocalDate date) throws FinancialPlanner wishList.load(goal); break; default: - throw new FinancialPlannerException("Error loading file"); + throw new FinancialPlannerException("Error loading file."); } } inputFile.close(); @@ -86,11 +86,11 @@ public static void load(String filePath, LocalDate date) throws FinancialPlanner } catch (IOException e) { ui.showMessage("File not found. Creating new file..."); } catch (IndexOutOfBoundsException e) { - handleCorruptedFile("Empty/Missing arguments detected"); + handleCorruptedFile("Empty/Missing arguments detected."); } catch (IllegalArgumentException | FinancialPlannerException e) { handleCorruptedFile(e.getMessage()); } catch (DateTimeParseException e) { - handleCorruptedFile("Erroneous date format or Wrong position of date detected"); + handleCorruptedFile("Erroneous date format or Wrong position of date detected."); } } @@ -128,6 +128,10 @@ private static void addRecurringCashflows(LocalDate currentDate) throws Financia } for (Cashflow cashflow : tempCashflowList) { cashflowList.load(cashflow); + ui.printAddedCashflowWithoutBalance(cashflow); + } + if (!tempCashflowList.isEmpty()) { + ui.printBalance(); } } @@ -151,7 +155,7 @@ private static void addRecurringCashflowToTempList(LocalDate currentDate } else if (cashflow instanceof Expense) { toAdd = new Expense((Expense) cashflow); } else { - throw new FinancialPlannerException("Error adding recurring cashflows"); + throw new FinancialPlannerException("Error adding recurring cashflows."); } toAdd.setDate(dateOfAddition); addToTempList(tempCashflowList, toAdd); @@ -188,17 +192,17 @@ private static void loadBudget(String[] split) throws IllegalArgumentException { return; } if (initial < 0 || current < 0) { - throw new IllegalArgumentException("Negative values for budget"); + throw new IllegalArgumentException("Negative values for budget."); } if (initial > Cashflow.getBalance() || current > Cashflow.getBalance()) { - throw new IllegalArgumentException("Budget exceeds balance"); + throw new IllegalArgumentException("Budget exceeds balance."); } if (initial < current) { - throw new IllegalArgumentException("Current budget exceeds initial budget"); + throw new IllegalArgumentException("Current budget exceeds initial budget."); } LocalDate date = LocalDate.parse(split[3].trim(), DateTimeFormatter.ofPattern("dd/MM/yyyy")); if (LocalDate.now().isBefore(date)) { - throw new IllegalArgumentException("Current date is before saved date"); + throw new IllegalArgumentException("Current date is before saved date."); } Budget.load(initial, current, date); } @@ -238,11 +242,11 @@ private static Cashflow getEntry(String type, String[] split) entry = new Expense(value, expenseType, recur, description, date, hasRecurred); break; default: - throw new FinancialPlannerException("Error loading file"); + throw new FinancialPlannerException("Error loading file."); } return entry; } catch (IllegalArgumentException e) { - throw new IllegalArgumentException("Erroneous arguments detected"); + throw new IllegalArgumentException("Erroneous arguments detected."); } } @@ -256,9 +260,9 @@ private static Reminder getReminder(String[] split) throws IllegalArgumentExcept entry = new Reminder(type, date, status); return entry; } catch (IllegalArgumentException e) { - throw new IllegalArgumentException("Erroneous arguments detected"); + throw new IllegalArgumentException("Erroneous arguments detected."); } catch (IndexOutOfBoundsException e) { - throw new FinancialPlannerException("There should be three data members for reminder"); + throw new FinancialPlannerException("There should be three data members for reminder."); } } @@ -271,7 +275,7 @@ private static Goal getGoal(String[] split) throws IllegalArgumentException { entry = new Goal(type, amount, status); return entry; } catch (IllegalArgumentException e) { - throw new IllegalArgumentException("Erroneous arguments detected"); + throw new IllegalArgumentException("Erroneous arguments detected."); } } @@ -343,14 +347,14 @@ public static HashMap loadWatchList() { ui.showMessage("Watchlist JSON is corrupted!"); ui.showMessage("Would you like to create new file? (Y/N)"); if (!createNewFile()) { - ui.showMessage("Exiting... Please fix the file"); + ui.showMessage("Exiting... Please fix the file."); System.exit(1); } } catch (FinancialPlannerException e) { ui.showMessage(e.getMessage()); ui.showMessage("Would you like to create new watchlist? (Y/N)"); if (!createNewFile()) { - ui.showMessage("Exiting... Please fix the file"); + ui.showMessage("Exiting... Please fix the file."); System.exit(1); } stocksData = null; @@ -359,8 +363,14 @@ public static HashMap loadWatchList() { } private static void checkValidInput(double value, int recur) throws FinancialPlannerException { - if (value < 0 || recur < 0) { - throw new FinancialPlannerException("Amount and number of days cannot be negative"); + if (value < 0) { + throw new FinancialPlannerException("Amount cannot be negative."); + } + if (value > 999999999999.99) { + throw new FinancialPlannerException("Amount exceeded maximum value this program can hold."); + } + if (recur < 0) { + throw new FinancialPlannerException("Recurring value cannot be negative."); } } } diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index cea4029d88..8b63085fb8 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -141,6 +141,15 @@ public void printAddedCashflow(Cashflow entry) { showMessage("Balance: " + formatBalance(Cashflow.getBalance())); } + public void printAddedCashflowWithoutBalance(Cashflow entry) { + showMessage("You have added an " + entry); + showMessage("to the Financial Planner."); + } + + public void printBalance() { + showMessage("Balance: " + formatBalance(Cashflow.getBalance())); + } + public void printDeletedCashflow(Cashflow entry) { showMessage("You have removed an " + entry); showMessage("from the Financial Planner."); From 38075f2499ce4a3d6f07e81b730da4bc3bfcb3ff Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 12 Nov 2023 13:18:15 +0800 Subject: [PATCH 472/518] Add error handling for recur value exceeding maximum int value --- .../seedu/financialplanner/commands/AddCashflowCommand.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index 08c4b6691e..97f2d93175 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -109,6 +109,10 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException try { logger.log(Level.INFO, "Parsing recur as integer"); recur = Integer.parseInt(rawCommand.extraArgs.get("r").trim()); + } catch (NumberFormatException e) { + logger.log(Level.WARNING, "Value for recur out of bounds"); + throw new IllegalArgumentException("Recur value exceeded maximum value this program can hold. " + + "Please add a different cashflow."); } catch (IllegalArgumentException e) { logger.log(Level.WARNING, "Invalid arguments for recur"); throw new IllegalArgumentException("Recurrence must be an integer."); From 95babe9aee9ab2783123dee5a3939bc1b6dc2f03 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 12 Nov 2023 13:18:21 +0800 Subject: [PATCH 473/518] Update user guide --- docs/UserGuide.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 16f2d6a129..f6a0ce296c 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -76,6 +76,7 @@ you a one-stop interface to access a plethora of features to manage your finance - Maximum amount for each cashflow and total balance that the program can hold is 999,999,999,999.99 - Minimum amount for each cashflow and total balance that the program can hold is -999,999,999,999.99 - Total Balance, Income balance, and Expense balance are different entities where the latter two do not have the same limitations. +- Maximum value for recurrence is 2,147,483,647, the maximum number an `int` can hold. ### Add cashflow @@ -87,7 +88,7 @@ Format: `add income /a AMOUNT /t TYPE [/r DAYS] [/d DESCRIPTION]` - `/a` is used to specify the amount of the income, where an **integer** or **double** is expected. - `/r` is used to denote a recurring income, with the period to the next addition is specified by an **integer** representing the number of `DAYS`. - `/d` is used to give a description to the income, where any **String** is expected. -- `/t` is used to specify the income type, where the list of acceptable types is given below. +- `/t` is used to specify the income type, where the list of acceptable types is given below. The types are case-insensitive. | Income Types | |---------------| @@ -120,7 +121,7 @@ Format: `add expense /a AMOUNT /t TYPE [/r DAYS] [/d DESCRIPTION]` - `/a` is used to specify the amount of the expense, where an **integer** or **double** is expected. - `/r` is used to denote a recurring expense, with the period to the next addition is specified by an **integer** representing the number of `DAYS`. - `/d` is used to give a description to the expense, where any **String** is expected. -- `/t` is used to specify the expense type, where the list of acceptable types is given below +- `/t` is used to specify the expense type, where the list of acceptable types is given below. The types are case-insensitive. | Expense | |-----------------| From 2afa9979fe6c21bd83b48c69e8a7cac973d3ca9d Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 12 Nov 2023 13:39:32 +0800 Subject: [PATCH 474/518] Add error handling for index exceeding max int value --- docs/UserGuide.md | 2 +- .../financialplanner/commands/DeleteCashflowCommand.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index f6a0ce296c..ebb8106977 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -76,7 +76,7 @@ you a one-stop interface to access a plethora of features to manage your finance - Maximum amount for each cashflow and total balance that the program can hold is 999,999,999,999.99 - Minimum amount for each cashflow and total balance that the program can hold is -999,999,999,999.99 - Total Balance, Income balance, and Expense balance are different entities where the latter two do not have the same limitations. -- Maximum value for recurrence is 2,147,483,647, the maximum number an `int` can hold. +- Maximum value for recurrences and indexes is 2,147,483,647, the maximum number an `int` can hold. ### Add cashflow diff --git a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java index 73271c9e1a..30bd22f790 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java @@ -74,6 +74,10 @@ public DeleteCashflowCommand(RawCommand rawCommand) throws IllegalArgumentExcept try { logger.log(Level.INFO, "Parsing index as integer"); index = Integer.parseInt(stringIndex); + } catch (NumberFormatException e) { + logger.log(Level.WARNING, "Value for index out of bounds"); + throw new IllegalArgumentException("Index exceeded maximum value this program can hold. " + + "Please select a different index."); } catch (IllegalArgumentException e) { logger.log(Level.WARNING, "Invalid argument for index"); throw new IllegalArgumentException("Index must be an integer."); From 7b714b09496f560f211a892f139eb9cff66b4fc7 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 12 Nov 2023 13:47:58 +0800 Subject: [PATCH 475/518] Update Junit --- .../financialplanner/commands/AddCashflowCommand.java | 7 ++----- .../financialplanner/commands/DeleteCashflowCommand.java | 7 ++----- .../financialplanner/commands/AddCashflowCommandTest.java | 3 ++- .../commands/DeleteCashflowCommandTest.java | 3 ++- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java index 97f2d93175..7c55edcb00 100644 --- a/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddCashflowCommand.java @@ -109,13 +109,10 @@ public AddCashflowCommand(RawCommand rawCommand) throws IllegalArgumentException try { logger.log(Level.INFO, "Parsing recur as integer"); recur = Integer.parseInt(rawCommand.extraArgs.get("r").trim()); - } catch (NumberFormatException e) { - logger.log(Level.WARNING, "Value for recur out of bounds"); - throw new IllegalArgumentException("Recur value exceeded maximum value this program can hold. " + - "Please add a different cashflow."); } catch (IllegalArgumentException e) { logger.log(Level.WARNING, "Invalid arguments for recur"); - throw new IllegalArgumentException("Recurrence must be an integer."); + throw new IllegalArgumentException("Recurrence must be an integer and be within the " + + "maximum value this program can hold."); } rawCommand.extraArgs.remove("r"); } diff --git a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java index 30bd22f790..69e4e2bebd 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteCashflowCommand.java @@ -74,13 +74,10 @@ public DeleteCashflowCommand(RawCommand rawCommand) throws IllegalArgumentExcept try { logger.log(Level.INFO, "Parsing index as integer"); index = Integer.parseInt(stringIndex); - } catch (NumberFormatException e) { - logger.log(Level.WARNING, "Value for index out of bounds"); - throw new IllegalArgumentException("Index exceeded maximum value this program can hold. " + - "Please select a different index."); } catch (IllegalArgumentException e) { logger.log(Level.WARNING, "Invalid argument for index"); - throw new IllegalArgumentException("Index must be an integer."); + throw new IllegalArgumentException("Index must be an integer and be " + + "within the maximum value this program can hold."); } if (index == 0) { diff --git a/src/test/java/seedu/financialplanner/commands/AddCashflowCommandTest.java b/src/test/java/seedu/financialplanner/commands/AddCashflowCommandTest.java index 4fe59b56b7..d1b428da5c 100644 --- a/src/test/java/seedu/financialplanner/commands/AddCashflowCommandTest.java +++ b/src/test/java/seedu/financialplanner/commands/AddCashflowCommandTest.java @@ -72,7 +72,8 @@ void testIllegalArgumentException() { parseRawCommand("add income /a 1 /t salary /r ")); fail(); } catch (IllegalArgumentException e) { - assertEquals("Recurrence must be an integer.", e.getMessage()); + assertEquals("Recurrence must be an integer and be within the " + + "maximum value this program can hold.", e.getMessage()); } try { AddCashflowCommand testEntry = new AddCashflowCommand(Parser. diff --git a/src/test/java/seedu/financialplanner/commands/DeleteCashflowCommandTest.java b/src/test/java/seedu/financialplanner/commands/DeleteCashflowCommandTest.java index 44b8361938..9295cbad0e 100644 --- a/src/test/java/seedu/financialplanner/commands/DeleteCashflowCommandTest.java +++ b/src/test/java/seedu/financialplanner/commands/DeleteCashflowCommandTest.java @@ -27,7 +27,8 @@ void testIllegalArgumentException() { DeleteCashflowCommand testEntry = new DeleteCashflowCommand(Parser.parseRawCommand("delete a")); fail(); } catch (IllegalArgumentException e) { - assertEquals("Index must be an integer.", e.getMessage()); + assertEquals("Index must be an integer and be within the " + + "maximum value this program can hold.", e.getMessage()); } try { DeleteCashflowCommand testEntry = new DeleteCashflowCommand(Parser.parseRawCommand("delete 0")); From efabe5a4d0473d9d98137604c782819282aa4929 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Sun, 12 Nov 2023 13:51:21 +0800 Subject: [PATCH 476/518] Delete note for income type in UG --- docs/UserGuide.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 419ff818e7..5d29fc9a5a 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -98,8 +98,6 @@ Format: `add income /a AMOUNT /t TYPE [/r DAYS] [/d DESCRIPTION]` | `allowance` | | `others` | -**Note:** Income types are case-insensitive. - Example of usage: `add income /a 5000 /t salary /r 30 /d work` Example output: From 94e1308617cf860000055cbe416e395a5fb13836 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 12 Nov 2023 14:25:04 +0800 Subject: [PATCH 477/518] Last Changes --- .../financialplanner/commands/WatchListCommand.java | 6 +++--- .../seedu/financialplanner/investments/WatchList.java | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java index 3e19ea2537..926e6b405e 100644 --- a/src/main/java/seedu/financialplanner/commands/WatchListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/WatchListCommand.java @@ -25,6 +25,9 @@ public class WatchListCommand extends Command { "watchlist"; private static final Logger logger = Logger.getLogger("Financial Planner Logger"); + protected Ui ui = Ui.getInstance(); + protected WatchList watchList = WatchList.getInstance(); + /** * Constructor for the command to fetch and display watchlist data * @@ -45,9 +48,6 @@ public WatchListCommand(RawCommand rawCommand) throws IllegalArgumentException{ */ @Override public void execute() { - Ui ui = Ui.getInstance(); - WatchList watchList = WatchList.getInstance(); - ui.printWatchListHeader(); try { watchList.getLatestWatchlistInfo(); diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index b5895821e1..4c28b9f879 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -203,18 +203,18 @@ public void fetchFMPStockPrices(StringBuilder queryStocks) throws FinancialPlann /** * Method to extract out required information from the full JSON array received from the API * - * @param jsonstocks + * @param jsonStocks * @throws FinancialPlannerException */ - public void extractWatchlistInfoFromJSONArray(JSONArray jsonstocks) throws FinancialPlannerException { - if (jsonstocks == null) { + public void extractWatchlistInfoFromJSONArray(JSONArray jsonStocks) throws FinancialPlannerException { + if (jsonStocks == null) { throw new FinancialPlannerException("Incorrect API Response Received. Please try again"); } - if (jsonstocks.isEmpty()) { + if (jsonStocks.isEmpty()) { return; } long fetchTime = System.currentTimeMillis(); - for (Object jo : jsonstocks) { + for (Object jo : jsonStocks) { JSONObject stock = (JSONObject) jo; if (stocks.containsKey(stock.get("symbol").toString().toUpperCase())) { Stock stockLocal = stocks.get(stock.get("symbol").toString().toUpperCase()); From 4b44100fa6297711956bd89719c3b8513e261d4e Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 12 Nov 2023 14:25:41 +0800 Subject: [PATCH 478/518] Fix Vis diagrams --- docs/diagrams/vis/categorizerSequence.puml | 2 +- docs/diagrams/vis/visualisationSequence.puml | 1 + docs/diagrams/vis/visualizerSequence.puml | 2 +- docs/images/vis/categorizerSequence.png | Bin 18815 -> 18371 bytes docs/images/vis/visualisationSequence.png | Bin 16221 -> 17465 bytes docs/images/vis/visualizerSequence.png | Bin 19971 -> 19284 bytes 6 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/diagrams/vis/categorizerSequence.puml b/docs/diagrams/vis/categorizerSequence.puml index f413138d0e..55daabc0e8 100644 --- a/docs/diagrams/vis/categorizerSequence.puml +++ b/docs/diagrams/vis/categorizerSequence.puml @@ -7,7 +7,7 @@ autoactivate on participant ":VisCommand" participant "<>\nCategorizer" -":VisCommand"-> "<>\nCategorizer": Categorizer.sortType(cashflowList, type) +":VisCommand"-> "<>\nCategorizer": sortType(cashflowList, type) alt "expense" "<>\nCategorizer" -> "<>\nCategorizer": sortExpenses(cashflowList) diff --git a/docs/diagrams/vis/visualisationSequence.puml b/docs/diagrams/vis/visualisationSequence.puml index df3fce1c41..7137320992 100644 --- a/docs/diagrams/vis/visualisationSequence.puml +++ b/docs/diagrams/vis/visualisationSequence.puml @@ -5,6 +5,7 @@ participant ":Ui" participant "<>\nCategorizer" participant "<>\nVisualizer" +-> ":VisCommand": execute() ":VisCommand"-> ":Ui": printDisplayChartMessages(type) ref over "<>\nCategorizer", ":VisCommand" : sort cashflow entries diff --git a/docs/diagrams/vis/visualizerSequence.puml b/docs/diagrams/vis/visualizerSequence.puml index 35dafb8d74..19fdf7fa1f 100644 --- a/docs/diagrams/vis/visualizerSequence.puml +++ b/docs/diagrams/vis/visualizerSequence.puml @@ -5,7 +5,7 @@ mainframe sd displaying chart participant ":VisCommand" participant "<>\nVisualizer" -":VisCommand"-> "<>\nVisualizer": Visualizer.displayChart(chart, sortedCashFlow, type) +":VisCommand"-> "<>\nVisualizer": displayChart(chart, sortedCashFlow, type) activate "<>\nVisualizer" diff --git a/docs/images/vis/categorizerSequence.png b/docs/images/vis/categorizerSequence.png index 2efd8f7a7a01702cac7a9ea04f39c4b4c1242fb0..44be8a2dc07a3f5bae11a89fd9aa6d87a38d195f 100644 GIT binary patch literal 18371 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 diff --git a/docs/images/vis/visualisationSequence.png b/docs/images/vis/visualisationSequence.png index 4768b5af0f09888cc48cce39d9b1fc5a3f443856..c687d3cbf2c625d908ae01085ec3ab0e4db7167a 100644 GIT binary patch literal 17465 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

    z ze2m5L<|~K)lyGftRLFj{j+C3`m>LuFbQIoXu~8sV6wmFicU3Hen~P(h$yN|2`TzD7 z&FwE7{8je-k5^y*>l-qu>;@SBZrmNn%>VIX%m4M%`u{$K)<*a1WI8zRbz2OE|Nr>C kg@0be`7g)WTW$~$y6jN(#g&r4Z+O5-iOW7O7S;9rKV33r_y7O^ literal 16221 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

    k^D93)Sv?(d_dv~wT9 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 Wf3-LA09nTYVKRsJCQ2W_^#1`z<+K?9 literal 43896 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 TN(}yO0Phb)byP9ZH1PictAjiz From 7a20e0faf922624362cfba18bf829c76c24aaaaf Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 12 Nov 2023 21:01:58 +0800 Subject: [PATCH 488/518] Fix table of content --- docs/DeveloperGuide.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index bcdb83158b..bf87aecd77 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -24,13 +24,13 @@ * [Delete budget](#delete-budget) * [Reset budget](#reset-budget) * [View budget](#view-budget) - * [Product Scope](#product-scope) - * [Target user profile](#target-user-profile) - * [Value proposition](#value-proposition) - * [User Stories](#user-stories) - * [Non-Functional Requirements](#non-functional-requirements) - * [Glossary](#glossary) - * [Instructions for manual testing](#instructions-for-manual-testing) +* [Product Scope](#product-scope) + * [Target user profile](#target-user-profile) + * [Value proposition](#value-proposition) +* [User Stories](#user-stories) +* [Non-Functional Requirements](#non-functional-requirements) +* [Glossary](#glossary) +* [Instructions for manual testing](#instructions-for-manual-testing) ## Acknowledgements From 37375207eb8743f2bc926d13d4c077ee067bf003 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 12 Nov 2023 21:09:40 +0800 Subject: [PATCH 489/518] Add activation diagram --- docs/diagrams/vis/visualizerSequence.puml | 12 +++++++++--- docs/images/vis/visualizerSequence.png | Bin 18267 -> 24817 bytes 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/diagrams/vis/visualizerSequence.puml b/docs/diagrams/vis/visualizerSequence.puml index 41d70463fc..00bb04ce88 100644 --- a/docs/diagrams/vis/visualizerSequence.puml +++ b/docs/diagrams/vis/visualizerSequence.puml @@ -5,18 +5,24 @@ mainframe sd displaying chart participant ":VisCommand" participant "<>\nVisualizer" +activate ":VisCommand" ":VisCommand"-> "<>\nVisualizer": displayChart(chart, sortedCashFlow, type) - - +activate "<>\nVisualizer" alt "pie" "<>\nVisualizer" -> "<>\nVisualizer": displayPieChart(cashflowList, type) + activate "<>\nVisualizer" + return else "bar" "<>\nVisualizer" -> "<>\nVisualizer": displayBarChart(cashflowList, type) + activate "<>\nVisualizer" + return else "radar" "<>\nVisualizer" -> "<>\nVisualizer": displayRadarChart(cashflowList, type) + activate "<>\nVisualizer" + return end - +return hide footbox diff --git a/docs/images/vis/visualizerSequence.png b/docs/images/vis/visualizerSequence.png index c18c9721243ab0c9b88f0e0f117788bf780a8479..69987edebb9c711e72d5f06eeb4b3c9e53f3a45f 100644 GIT binary patch literal 24817 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 LJUXd4== zuC4~guWF9ss}K6T0Y*!}vIn;~fQ{KcSvp;nt6ftG%zw5ipu99mF=!1eNbM{>Xnua< z7$g%sJiHN7@zW(Uj)@ie0E#3cQ7&D&v{tiAzDDE=7nqs}6_8ab-1+Q}x2RmeA);Yo zLYMgFw1STY@W%H@-iVg>Qt`h~D)xte5GrIAO#n51wdvhR=}8XbDfBI0=LkOZvKM7UTS^EHI10mE*KtLdq#Onm;aWm$p&_U6| z@+Dr{TeljAAH~7iwl_tDvO)%(noo~oaD*9d0El{`n2cyrx@))oF3;MS75l^;m~2E3G>EPZFCr$6aa zHz+kkIhX!7LkgVWCy@N_Cer_gP-%--1-Rjn*9!vV^r-N{i(mc}^7)Y`yQdejgCQ3b z)zm7?Mv7PsyRUH$qx_xgojOt=>x~!bOU=I{|NHOTE(isFTwY!Vw=zJ@J)6luYwv5Z zzuRh0y$YHhySlmpS2TMV+<~69t@*>+`elD9c&#@*2FDZPCj+3^}SWEf}lx8{e3u~h&zm32tPMnj1B?X7OIA{DQ zr0?^Oaws)@EK-hT28V0>t`&t>D6{3+Z>$`H%a9*nDiTl>&zdlM6{J*D_u|Eij}|Oe z(+~BC1aVT^Sx)L10lEd(MQ)xLsE}{$|GYMWBs*Ekkh>`-C80=&28y(PT~q;~)bhJl z^qUn8PWHq_UkX2Od`Px# From 2e591a2f4f97012978a38de5b0edddaca12adb80 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 12 Nov 2023 21:22:04 +0800 Subject: [PATCH 490/518] Change back --- docs/DeveloperGuide.md | 1 - docs/diagrams/vis/visualizerSequence.puml | 10 ---------- docs/images/vis/visualizerSequence.png | Bin 24817 -> 23080 bytes 3 files changed, 11 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index bf87aecd77..f5fc754660 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -491,4 +491,3 @@ shows you the welcome screen for the financial planner app 1. Type `exit` into the terminal. 2. Expected: the financial planner will exit with a goodbye message. Under the data newly created data directory, a watchlist.json and a data.txt file will be created - diff --git a/docs/diagrams/vis/visualizerSequence.puml b/docs/diagrams/vis/visualizerSequence.puml index 00bb04ce88..2b4a01feb7 100644 --- a/docs/diagrams/vis/visualizerSequence.puml +++ b/docs/diagrams/vis/visualizerSequence.puml @@ -5,25 +5,15 @@ mainframe sd displaying chart participant ":VisCommand" participant "<>\nVisualizer" -activate ":VisCommand" ":VisCommand"-> "<>\nVisualizer": displayChart(chart, sortedCashFlow, type) -activate "<>\nVisualizer" alt "pie" "<>\nVisualizer" -> "<>\nVisualizer": displayPieChart(cashflowList, type) - activate "<>\nVisualizer" - return else "bar" "<>\nVisualizer" -> "<>\nVisualizer": displayBarChart(cashflowList, type) - activate "<>\nVisualizer" - return else "radar" "<>\nVisualizer" -> "<>\nVisualizer": displayRadarChart(cashflowList, type) - activate "<>\nVisualizer" - return end -return - hide footbox diff --git a/docs/images/vis/visualizerSequence.png b/docs/images/vis/visualizerSequence.png index 69987edebb9c711e72d5f06eeb4b3c9e53f3a45f..39ba05481a0a5b14d62932f3bfe539a5f324dd7d 100644 GIT binary patch literal 23080 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 Date: Sun, 12 Nov 2023 21:47:49 +0800 Subject: [PATCH 491/518] Add manual testing --- docs/DeveloperGuide.md | 82 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index f5fc754660..b1437fe4a3 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -491,3 +491,85 @@ shows you the welcome screen for the financial planner app 1. Type `exit` into the terminal. 2. Expected: the financial planner will exit with a goodbye message. Under the data newly created data directory, a watchlist.json and a data.txt file will be created +3. WatchList Feature + +To test the watchlist feature, you can copy the text below into the watchlist.json file under data directory +``` +{ + "BB": { + "symbol": "BB", + "stockName": "BlackBerry Ltd" + }, + "TSLA": { + "symbol": "TSLA", + "stockName": "Tesla Inc" + } +} +``` +Start Financial Planner app and you should be able to see this output (although prices will differ) +``` +watchlist +Symbol Market Price Daily High Daily Low EquityName Last Updated +BB NYSE 3.64 3.67 3.55 BlackBerry Ltd Sat, Nov 11 2023 05:00:02 +TSLA NASDAQ 214.65 215.38 205.69 Tesla Inc Sat, Nov 11 2023 05:00:00 +Data provided by Financial Modeling Prep and Alpha Vantage =) +``` + +You can then add a stock using the command below +``` +addstock /s NET +``` +You should see a message stating that Cloudflare was added. After running the watchlist command again and exiting the +application, your watchlist output should look like this +``` +Symbol Market Price Daily High Daily Low EquityName Last Updated +BB NYSE 3.64 3.67 3.55 BlackBerry Ltd Sat, Nov 11 2023 05:00:02 +TSLA NASDAQ 214.65 215.38 205.69 Tesla Inc Sat, Nov 11 2023 05:00:00 +NET NYSE 63.08 63.31 61.34 Cloudflare Inc - Class A Sat, Nov 11 2023 05:00:02 +Data provided by Financial Modeling Prep and Alpha Vantage =) +``` + +You can also remove stocks from the command. Run these commands separately +``` +deletestock /s BB +deletestock /s TSLA +deletestock /s NET +``` +After deleting all the stocks and running the watchlist command again, the output should look like this +as you have no more stocks left in your watchlist +``` +Symbol Market Price Daily High Daily Low EquityName Last Updated +Empty Watchlist. Nothing to display... +``` +4. Visualization Feature + +We can use the visualization feature to visualize your income and expenses. + +First we will add some expenses +``` +add expense /a 1000 /t necessities /d Iphone 15 pro max +add expense /a 4 /t others /d cai png +add expense /a 100 /t travel /d JB +``` + +Now we can visualize these expenses using 3 different charts (pie/bar/radar) +``` +vis /t expense /c pie +vis /t expense /c bar +vis /t expense /c radar +``` +You can run the 3 commands separately to see different charts + +We can do the same the income +``` +add income /a 1800 /t salary /d mcd +add income /a 400 /t investments /d Gamestop +add income /a 100 /t allowance /d parents +``` + +Again we can visualize these income using 3 different charts in separate commands (pie/bar/radar) +``` +vis /t income /c pie +vis /t income /c bar +vis /t income /c radar +``` \ No newline at end of file From 587ce36844672581e4a97a3b3d1d9725b30c5594 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 12 Nov 2023 22:22:36 +0800 Subject: [PATCH 492/518] Fix typo --- docs/DeveloperGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index b1437fe4a3..a6142b21dd 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -560,7 +560,7 @@ vis /t expense /c radar ``` You can run the 3 commands separately to see different charts -We can do the same the income +We can do the same for income. Add some entries ``` add income /a 1800 /t salary /d mcd add income /a 400 /t investments /d Gamestop From 67217626b1a23a12f14948e7b04bec885ac131fb Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 12 Nov 2023 22:57:28 +0800 Subject: [PATCH 493/518] Add manual testing --- docs/DeveloperGuide.md | 216 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 216 insertions(+) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index f5fc754660..b6999a8722 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -491,3 +491,219 @@ shows you the welcome screen for the financial planner app 1. Type `exit` into the terminal. 2. Expected: the financial planner will exit with a goodbye message. Under the data newly created data directory, a watchlist.json and a data.txt file will be created + +### Add cashflow + +To test the add cashflow feature, you can use the following command: +``` +add income /a 5000 /t salary /r 30 /d work +``` +You should see the following output: +``` +You have added an Income + Type: Salary + Amount: 5000.00 + Recurring every: 30 days, date added: Nov 12 2023, recurring on: Dec 12 2023 + Description: work +to the Financial Planner. +Balance: 5000.00 +``` +You can also use the following command to test the optional arguments: +``` +add expense /a 1000 /t necessities +``` +You should see the following output: +``` +You have added an Expense + Type: Necessities + Amount: 1000.00 +to the Financial Planner. +Balance: 4000.00 +``` + +### List + +To test the list feature, you can add these test inputs to the program first: + +Make sure there is no existing cashflows in the program in order to achieve the exact outputs below. You can clear the inputs by exiting the program and deleting the data.txt file found in data folder. + +Make sure to add each command line by line. + +``` +add income /a 5000 /t salary /r 30 /d work +add expense /a 1000 /t necessities +add income /a 500 /t investments /d stocks +add expense /a 800 /t insurance /r 365 /d insurance +``` + +After which you can test the following commands: + +Input: `list` + +Output: +``` +You have 4 matching cashflows: +1: Income + Type: Salary + Amount: 5000.00 + Recurring every: 30 days, date added: Nov 12 2023, recurring on: Dec 12 2023 + Description: work +2: Expense + Type: Necessities + Amount: 1000.00 +3: Income + Type: Investments + Amount: 500.00 + Description: stocks +4: Expense + Type: Insurance + Amount: 800.00 + Recurring every: 365 days, date added: Nov 12 2023, recurring on: Nov 11 2024 + Description: insurance +Balance: 3700.00 +``` + +Input: `list income` + +Output: +``` +You have 2 matching cashflows: +1: Income + Type: Salary + Amount: 5000.00 + Recurring every: 30 days, date added: Nov 12 2023, recurring on: Dec 12 2023 + Description: work +2: Income + Type: Investments + Amount: 500.00 + Description: stocks +Income Balance: 5500.00 +``` + +Input: `list expense` + +Output: +``` +You have 2 matching cashflows: +1: Expense + Type: Necessities + Amount: 1000.00 +2: Expense + Type: Insurance + Amount: 800.00 + Recurring every: 365 days, date added: Nov 12 2023, recurring on: Nov 11 2024 + Description: insurance +Expense Balance: 1800.00 +``` + +Input: `list recurring` + +Output: +``` +You have 2 matching cashflows: +1: Income + Type: Salary + Amount: 5000.00 + Recurring every: 30 days, date added: Nov 12 2023, recurring on: Dec 12 2023 + Description: work +2: Expense + Type: Insurance + Amount: 800.00 + Recurring every: 365 days, date added: Nov 12 2023, recurring on: Nov 11 2024 + Description: insurance +``` + +### Delete cashflow + +You are recommended to test this feature after testing the list feature as they share the same test inputs. + +If you have not done so, please follow the instructions to test the list feature [here](#list). + +To test the delete cashflow feature, you can use the following commands: + +Use the list command before each delete command to confirm that the cashflow at the index stated in the delete command matches the expected output. + +Input: `list` followed by `delete 3` + +Output: +``` +You have removed an Income + Type: Investments + Amount: 500.00 + Description: stocks +from the Financial Planner. +Balance: 3200.00 +``` + +Input: `list income` followed by `delete income 1 /r` + +Output: +``` +You have removed future recurrences of this cashflow. +Updated cashflow: +Income + Type: Salary + Amount: 5000.00 + Description: work +``` + +Input: `list income` followed by `delete income 1` + +Output: +``` +You have removed an Income + Type: Salary + Amount: 5000.00 + Description: work +from the Financial Planner. +Balance: -1800.00 +``` + +Input: `list expense` followed by `delete expense 1` + +Output: +``` +You have removed an Expense + Type: Necessities + Amount: 1000.00 +from the Financial Planner. +Balance: -800.00 +``` + +Input: `list recurring` followed by `delete recurring 1` + +Output: +``` +You have removed an Expense + Type: Insurance + Amount: 800.00 + Recurring every: 365 days, date added: Nov 12 2023, recurring on: Nov 11 2024 + Description: insurance +from the Financial Planner. +Balance: 0.00 +``` + +### Recurring cashflow + +You can test the recurring cashflow feature by manually changing your system time. + +First add a cashflow that has a recurrence value. You can use the following example command: + +``` +add income /a 5000 /t salary /r 1 /d work +``` + +Next, exit the program and change the system time to be ahead by the specified days in the cashflow. + +In the case of the example command, you can bring forward the system time by 1 day. + +Finally, start the program again and you should see this output: +``` +You have added an Income + Type: Salary + Amount: 5000.00 + Recurring every: 1 days, date added: Nov 13 2023, recurring on: Nov 14 2023 + Description: work +to the Financial Planner. +Balance: 10000.00 +``` \ No newline at end of file From 85c469fc635b793c11e8f73305c2274bc178a1cb Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 12 Nov 2023 23:01:52 +0800 Subject: [PATCH 494/518] Update manual testing --- docs/DeveloperGuide.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index b6999a8722..8fcee043ea 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -508,6 +508,9 @@ You have added an Income to the Financial Planner. Balance: 5000.00 ``` + +Note: The date displayed will differ based on your system time. + You can also use the following command to test the optional arguments: ``` add expense /a 1000 /t necessities @@ -538,6 +541,8 @@ add expense /a 800 /t insurance /r 365 /d insurance After which you can test the following commands: +Note: The dates displayed will differ based on your system time. + Input: `list` Output: @@ -623,6 +628,8 @@ To test the delete cashflow feature, you can use the following commands: Use the list command before each delete command to confirm that the cashflow at the index stated in the delete command matches the expected output. +Note: The dates displayed will differ based on your system time. + Input: `list` followed by `delete 3` Output: From 0d03642d4331df1898ec0e8444805fea0caf8568 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Sun, 12 Nov 2023 23:31:57 +0800 Subject: [PATCH 495/518] Add manual testing --- docs/DeveloperGuide.md | 104 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 101 insertions(+), 3 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index a6142b21dd..9277e748da 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -491,7 +491,70 @@ shows you the welcome screen for the financial planner app 1. Type `exit` into the terminal. 2. Expected: the financial planner will exit with a goodbye message. Under the data newly created data directory, a watchlist.json and a data.txt file will be created -3. WatchList Feature + +### View Balance + +Test case: `balance` + +Expected: Balance is displayed. Details of balance are shown in the status message. + +### Budget Feature + +1. Setting a monthly budget + +Test case: `budget set /b 100` + +Expected: A monthly budget of 100 is set. Details of the budget are shown in the status message. + +Test case: `budget set /b` + +Expected: No budget is set. Error details shown in status message. + +Other incorrect set budget commands to try: `budget set`, `budget set /b x`, `...` (where x is negative) + +2. Updating budget + +Test case: `budget update /b 300` + +Expected: Monthly budget is updated to 300. Details of the budget are shown in the status message. + +Test case: `budget update /b` + +Expected: Budget is not updated. Error details shown in status message. + +Other incorrect set budget commands to try: `budget update`, `budget update /b x`, `...` (where x is negative) + +3. Resetting budget + +Test case: `budget reset` + +Expected (Current budget is lower than initial budget): Budget is reset. Details of reset budget are shown in status message. + +Expected (Budget has not been spent): Budget is not reset. Error details shown in the status message. + +4. Deleting budget + +Test case: `budget delete` + +Expected (Budget exists): Budget is deleted. Details of deletion are shown in status message. + +Expected (Budget does not exist): No budget to delete. Error details shown in the status message. + +5. Viewing budget + +Test case: `budget view` + +Expected (Budget exists): Budget is displayed. Details of budget are shown in status message. + +Expected (Budget does not exist): No budget to display. Error details shown in the status message. + +### Displaying overview + +Test case: `overview` + +Expected: Displays overview of user's financials. Details of financials are shown in the status message. + +### WatchList Feature To test the watchlist feature, you can copy the text below into the watchlist.json file under data directory ``` @@ -541,7 +604,7 @@ as you have no more stocks left in your watchlist Symbol Market Price Daily High Daily Low EquityName Last Updated Empty Watchlist. Nothing to display... ``` -4. Visualization Feature +### Visualization Feature We can use the visualization feature to visualize your income and expenses. @@ -572,4 +635,39 @@ Again we can visualize these income using 3 different charts in separate command vis /t income /c pie vis /t income /c bar vis /t income /c radar -``` \ No newline at end of file +``` + +### Saving data + +Dealing with missing/corrupted data files: + +Example of a valid `data.txt` file: + +``` +I | 5000.0 | SALARY | 30 | false | 31/10/2023 +E | 50.0 | OTHERS | 0 | false +I | 500.0 | OTHERS | 0 | false +I | 5.0 | OTHERS | 0 | false +E | 5.0 | OTHERS | 0 | false +``` + +The first column specifies the type of data being saved, and the subsequent columns contain the data to be saved. +For example, `I` and `E` represent `income` and `expense` respectively, and there are other types, such as `B` for `budget`. + +For incomes and expenses, the second column represent the amount, which is a `double`. To simulate a corrupted data, you +can change the number in the column to a string for example. + +Example of corrupted `data.txt` file in the third row: + +``` +I | 5000.0 | SALARY | 30 | false | 31/10/2023 +E | 50.0 | OTHERS | 0 | false +I | sdf | OTHERS | 0 | false +I | 5.0 | OTHERS | 0 | false +E | 5.0 | OTHERS | 0 | false +``` + +When starting the program: + +Expected: Data fails to load. Error details shown in status message. Program asks user if he/she wants to create a new file +(by clearing all data) or fix it manually. \ No newline at end of file From 889370d995f2529297b03d7ed7a04b7412ec81e7 Mon Sep 17 00:00:00 2001 From: hshiah Date: Sun, 12 Nov 2023 23:47:16 +0800 Subject: [PATCH 496/518] Finished test and fix bugs. --- docs/team/hshiah.md | 56 +++++++++++++++++++ .../commands/DeleteGoalCommand.java | 2 +- .../commands/DeleteReminderCommand.java | 2 +- .../commands/MarkGoalCommand.java | 2 +- .../commands/MarkReminderCommand.java | 2 +- .../commands/ReminderListCommand.java | 4 +- .../commands/SetGoalCommand.java | 6 +- .../seedu/financialplanner/goal/WishList.java | 9 ++- .../commands/AddReminderCommandTest.java | 8 +++ .../commands/SetGoalCommandTest.java | 46 +++++++++++++++ 10 files changed, 126 insertions(+), 11 deletions(-) create mode 100644 docs/team/hshiah.md create mode 100644 src/test/java/seedu/financialplanner/commands/SetGoalCommandTest.java diff --git a/docs/team/hshiah.md b/docs/team/hshiah.md new file mode 100644 index 0000000000..2af2bd46ee --- /dev/null +++ b/docs/team/hshiah.md @@ -0,0 +1,56 @@ +# Neo Min Wei - Project Portfolio Page + +## Overview + +Financial Planner is a Command Line Interface (CLI) application for managing your finances conveniently. +It is optimized for use via the CLI and leverages your expertise in CLI and your ability to type fast and gives +you a one-stop interface to access a plethora of features to manage your finances. + +## Summary of Contributions + +### Code contributed: [Reposense link](https://nus-cs2113-ay2324s1.github.io/tp-dashboard/?search=neominwei&sort=groupTitle&sortWithin=title&timeframe=commit&mergegroup=&groupSelect=groupByRepos&breakdown=false&since=2023-09-22) + +### Enhancements Implemented: + +* Add Cashflow Feature + * Keep track of total balance + * Ability to set a recurring cashflow +* Delete Cashflow Feature + * Ability to delete a cashflow based on its respective index in overall list, income list, expense list or recur list. + * Ability to delete the recurrence portion of a cashflow, making it a one-time entry only. +* Recurring Cashflow Feature + * Ability to automatically add cashflows based on the system date. +* List Recurring Cashflows Feature + +### Contributions to the UG: + +* Feature guide for add and delete cashflow feature +* Provide quick start guide +* Command summary for add, delete and listing of cashflow + +### Contributions to the DG + +* Acknowledgements of reused code found in add/delete cashflow feature +* Add/Delete Cashflow Feature + * Implementation + * Class Diagram + * Sequence Diagram +* Recurring Cashflow Feature + * Implementation + * Class Diagram + * Sequence Diagram + +### Contributions to team-based tasks: + +* Submission of first draft of UG +* Creating and assigning relevant issues in the issue tracker to teammates +* Approving pull requests by team members + +### Review/ Mentoring contributions: + +* Reviewing of teammates codes in Pull Requests (giving suggestions and improvements) + +### Contributions beyond the project team + +* Reviewed UG & DG of other teams +* Product system and acceptance testing for other teams \ No newline at end of file diff --git a/src/main/java/seedu/financialplanner/commands/DeleteGoalCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteGoalCommand.java index a80d858a85..6835f13770 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteGoalCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteGoalCommand.java @@ -29,7 +29,7 @@ public DeleteGoalCommand(RawCommand rawCommand) throws IllegalArgumentException if (rawCommand.args.size() == 1) { stringIndex = rawCommand.args.get(0); } else { - throw new IllegalArgumentException("Incorrect arguments."); + throw new IllegalArgumentException("Please specify a valid index of goal"); } try { diff --git a/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java index d6807bd853..26cf2ef390 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java @@ -29,7 +29,7 @@ public DeleteReminderCommand(RawCommand rawCommand) throws IllegalArgumentExcept if (rawCommand.args.size() == 1) { stringIndex = rawCommand.args.get(0); } else { - throw new IllegalArgumentException("Incorrect arguments."); + throw new IllegalArgumentException("Please specify a valid index of reminder"); } try { diff --git a/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java b/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java index c18002904f..71e136bf60 100644 --- a/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java +++ b/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java @@ -31,7 +31,7 @@ public MarkGoalCommand(RawCommand rawCommand) throws IllegalArgumentException { if (rawCommand.args.size() == 1) { stringIndex = rawCommand.args.get(0); } else { - throw new IllegalArgumentException("Incorrect arguments."); + throw new IllegalArgumentException("Please specify a valid index of goal"); } try { diff --git a/src/main/java/seedu/financialplanner/commands/MarkReminderCommand.java b/src/main/java/seedu/financialplanner/commands/MarkReminderCommand.java index 3f4ee36501..0df423ff54 100644 --- a/src/main/java/seedu/financialplanner/commands/MarkReminderCommand.java +++ b/src/main/java/seedu/financialplanner/commands/MarkReminderCommand.java @@ -28,7 +28,7 @@ public MarkReminderCommand(RawCommand rawCommand) throws IllegalArgumentExceptio if (rawCommand.args.size() == 1) { stringIndex = rawCommand.args.get(0); } else { - throw new IllegalArgumentException("Incorrect arguments."); + throw new IllegalArgumentException("Please specify a valid index of reminder"); } try { diff --git a/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java b/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java index 867badfde4..e8618b289c 100644 --- a/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java @@ -4,7 +4,7 @@ import seedu.financialplanner.commands.utils.RawCommand; import seedu.financialplanner.reminder.ReminderList; import seedu.financialplanner.utils.Ui; - +import java.util.logging.Logger; import java.util.logging.Level; @SuppressWarnings("unused") @@ -14,7 +14,7 @@ public class ReminderListCommand extends Command { public static final String USAGE = "reminderlist"; public static final String EXAMPLE = "reminderlist"; - private static final java.util.logging.Logger logger = java.util.logging.Logger. + private static final Logger logger = java.util.logging.Logger. getLogger("Financial Planner Logger"); /** diff --git a/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java b/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java index 39cec2573d..6e42ec3ada 100644 --- a/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java +++ b/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java @@ -36,7 +36,7 @@ public SetGoalCommand(RawCommand rawCommand) throws IllegalArgumentException { try { amount = Integer.parseInt(amountString); } catch (IllegalArgumentException e) { - throw new IllegalArgumentException("Amount must be a number"); + throw new IllegalArgumentException("Amount must be a valid integer"); } if (amount<= 0) { @@ -65,8 +65,6 @@ public SetGoalCommand(RawCommand rawCommand) throws IllegalArgumentException { @Override public void execute() { assert amount > 0; - Goal goal = new Goal(label, amount); - WishList.getInstance().list.add(goal); - Ui.getInstance().showMessage("You have added " + goal); + WishList.getInstance().addGoal(label, amount); } } diff --git a/src/main/java/seedu/financialplanner/goal/WishList.java b/src/main/java/seedu/financialplanner/goal/WishList.java index d54d2c4faf..4a75911332 100644 --- a/src/main/java/seedu/financialplanner/goal/WishList.java +++ b/src/main/java/seedu/financialplanner/goal/WishList.java @@ -1,5 +1,7 @@ package seedu.financialplanner.goal; +import seedu.financialplanner.utils.Ui; + import java.util.ArrayList; public class WishList { private static WishList wishList = null; @@ -34,10 +36,15 @@ public void deleteGoal(int index) { int existingListSize = list.size(); int listIndex = index; assert listIndex >= 0 && listIndex < existingListSize; - Goal toRemove = list.get(listIndex); list.remove(listIndex); } + public void addGoal(String label, int amount){ + Goal goal = new Goal(label, amount); + list.add(goal); + Ui.getInstance().showMessage("You have added " + goal); + } + /** * Formats the reminder list into an easy-to-read format to be output to the user. diff --git a/src/test/java/seedu/financialplanner/commands/AddReminderCommandTest.java b/src/test/java/seedu/financialplanner/commands/AddReminderCommandTest.java index 1332b0399d..acc5052c0b 100644 --- a/src/test/java/seedu/financialplanner/commands/AddReminderCommandTest.java +++ b/src/test/java/seedu/financialplanner/commands/AddReminderCommandTest.java @@ -50,4 +50,12 @@ void testIllegalArgumentException() { assertEquals("Reminder type cannot be empty", e.getMessage()); } } + + @Test + void testExcute() { + AddReminderCommand testEntry = new AddReminderCommand( + Parser.parseRawCommand("addreminder /t debt /d 11/12/2023")); + testEntry.execute(); + assertEquals(1, reminderList.list.size()); + } } diff --git a/src/test/java/seedu/financialplanner/commands/SetGoalCommandTest.java b/src/test/java/seedu/financialplanner/commands/SetGoalCommandTest.java new file mode 100644 index 0000000000..dbeed392ee --- /dev/null +++ b/src/test/java/seedu/financialplanner/commands/SetGoalCommandTest.java @@ -0,0 +1,46 @@ +package seedu.financialplanner.commands; + +import org.junit.jupiter.api.Test; +import seedu.financialplanner.goal.WishList; +import seedu.financialplanner.utils.Parser; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; +class SetGoalCommandTest { + protected WishList wishList = WishList.getInstance(); + @Test + void testIllegalArgumentException() { + try { + SetGoalCommand testEntry = new SetGoalCommand(Parser.parseRawCommand("set goal")); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Goal must have an amount", e.getMessage()); + } + try { + SetGoalCommand testEntry = new SetGoalCommand(Parser.parseRawCommand("set goal /g /l car")); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Amount must be specified", e.getMessage()); + } + try { + SetGoalCommand testEntry = new SetGoalCommand(Parser.parseRawCommand("set goal /g -1 /l car")); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Amount must be positive", e.getMessage()); + } + try { + SetGoalCommand testEntry = new SetGoalCommand( + Parser.parseRawCommand("set goal /g 2222222222222222222222222222222222222 /l car")); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Amount must be a valid integer", e.getMessage()); + } + } + + @Test + void testExcute() { + SetGoalCommand testEntry = new SetGoalCommand( + Parser.parseRawCommand("set goal /g 5000 /l car")); + testEntry.execute(); + assertEquals(1, wishList.list.size()); + } +} From c1e591cd33db035c39821fc26aa6d9c810ab2f36 Mon Sep 17 00:00:00 2001 From: hshiah Date: Mon, 13 Nov 2023 03:02:14 +0800 Subject: [PATCH 497/518] Final update --- docs/DeveloperGuide.md | 26 ++++++++++++ docs/diagrams/MarkGoalSequence.puml | 38 ++++++++++++++++++ docs/images/MarkGoalSequence.png | Bin 0 -> 33580 bytes docs/team/hshiah.md | 37 +++++++---------- .../commands/MarkGoalCommand.java | 9 +---- .../commands/SetGoalCommand.java | 2 - .../seedu/financialplanner/goal/WishList.java | 9 ++++- 7 files changed, 88 insertions(+), 33 deletions(-) create mode 100644 docs/diagrams/MarkGoalSequence.puml create mode 100644 docs/images/MarkGoalSequence.png diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 24ec0296e0..c6d70cc8e7 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -21,6 +21,8 @@ * [Delete budget](#delete-budget) * [Reset budget](#reset-budget) * [View budget](#view-budget) + * [Mark Goal Feature](#mark-goal-feature) + * [Sequence Diagram](#mark-goal-sequence-diagram) * [Product Scope](#product-scope) * [Target user profile](#target-user-profile) * [Value proposition](#value-proposition) @@ -332,6 +334,30 @@ The `currentBudget` will be shown to the user through the `Ui`. Example: `budget view` +### Mark Goal Feature + +The mark goal command has 1 compulsory argument `INDEX`. + +Example: +``` +markgoal 1 +``` +Below are the steps that shows the implementation of set goal. + +#### Step 1 +The MarkGoalCommand instance calls `markGoal(INDEX)` function of wish list. +#### Step 2 +Wish list finds the corresponding goal and calls `markAsDone()` function of corresponding goal. +#### Step 3 +The marked goal is then displayed to the user through the Ui. +#### Step 4 +The wish list calls `addExpense(amount, type, label)` function of cashflow list to add corresponding expense. +#### Step 5 +The added expense is then displayed to the user through the Ui. +#### Mark goal Sequence Diagram +Given below is the sequence diagram showing the markgoal mechanism: +![](images/MarkGoalSequence.png) + ## Product scope ### Target user profile diff --git a/docs/diagrams/MarkGoalSequence.puml b/docs/diagrams/MarkGoalSequence.puml new file mode 100644 index 0000000000..3734785faa --- /dev/null +++ b/docs/diagrams/MarkGoalSequence.puml @@ -0,0 +1,38 @@ +@startuml + +participant ":MarkGoalCommand" as MarkGoalCommand +participant ":WishList" as WishList +participant ":Goal" as Goal +participant ":Ui" as Ui +participant ":CashflowList" as CashflowList +participant ":Expense" as Expense + +-> MarkGoalCommand: execute() +activate MarkGoalCommand +MarkGoalCommand -> WishList: markGoal(index) +activate WishList +WishList -> Goal: markAsDone() +activate Goal +return +WishList -> Ui: showMessage(AddGoalMessage) +WishList -> Goal: getAmount() +activate Goal +return amount +WishList -> Goal: getLabel() +activate Goal +return label +WishList -> CashflowList: addExpense(amount, ExpenseType, label) +activate CashflowList +create Expense +CashflowList -> Expense: Expense(amount, ExpenseType, label) +activate Expense +Expense -> Expense: addExpenseValue() +return +CashflowList -> CashflowList: addToList(toAdd) +CashflowList -> Ui: printAddedCashflow(toAdd) +return +return +return + +hide footbox +@enduml \ No newline at end of file diff --git a/docs/images/MarkGoalSequence.png b/docs/images/MarkGoalSequence.png new file mode 100644 index 0000000000000000000000000000000000000000..613186e41da8cad844b6e79de80612b36cd2bc9a GIT binary patch literal 33580 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 0 && index <= WishList.getInstance().list.size(); - Goal goal = WishList.getInstance().list.get(index - 1); - goal.markAsDone(); - Ui.getInstance().showMessage("You have achieved " + goal + System.lineSeparator() + "Congratulations!"); - CashflowList.getInstance().addExpense(goal.getAmount(), ExpenseType.OTHERS, 0, goal.getLabel()); + WishList.getInstance().markGoal(index); } } diff --git a/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java b/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java index 6e42ec3ada..e64026efd4 100644 --- a/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java +++ b/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java @@ -2,9 +2,7 @@ import seedu.financialplanner.commands.utils.Command; import seedu.financialplanner.commands.utils.RawCommand; -import seedu.financialplanner.goal.Goal; import seedu.financialplanner.goal.WishList; -import seedu.financialplanner.utils.Ui; @SuppressWarnings("unused") public class SetGoalCommand extends Command { diff --git a/src/main/java/seedu/financialplanner/goal/WishList.java b/src/main/java/seedu/financialplanner/goal/WishList.java index 4a75911332..8e6b70f0ab 100644 --- a/src/main/java/seedu/financialplanner/goal/WishList.java +++ b/src/main/java/seedu/financialplanner/goal/WishList.java @@ -1,5 +1,7 @@ package seedu.financialplanner.goal; +import seedu.financialplanner.cashflow.CashflowList; +import seedu.financialplanner.enumerations.ExpenseType; import seedu.financialplanner.utils.Ui; import java.util.ArrayList; @@ -45,7 +47,12 @@ public void addGoal(String label, int amount){ Ui.getInstance().showMessage("You have added " + goal); } - + public void markGoal(int index) { + Goal goal = list.get(index - 1); + goal.markAsDone(); + Ui.getInstance().showMessage("You have achieved " + goal + System.lineSeparator() + "Congratulations!"); + CashflowList.getInstance().addExpense(goal.getAmount(), ExpenseType.OTHERS, 0, goal.getLabel()); + } /** * Formats the reminder list into an easy-to-read format to be output to the user. * From 7cc98dc8e278187e41f607e662eb347f993d862d Mon Sep 17 00:00:00 2001 From: Shi Haochen <99376359+hshiah@users.noreply.github.com> Date: Mon, 13 Nov 2023 03:11:52 +0800 Subject: [PATCH 498/518] Update SetGoalCommandTest.java --- .../financialplanner/commands/SetGoalCommandTest.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/test/java/seedu/financialplanner/commands/SetGoalCommandTest.java b/src/test/java/seedu/financialplanner/commands/SetGoalCommandTest.java index dbeed392ee..3886bc3068 100644 --- a/src/test/java/seedu/financialplanner/commands/SetGoalCommandTest.java +++ b/src/test/java/seedu/financialplanner/commands/SetGoalCommandTest.java @@ -36,11 +36,4 @@ void testIllegalArgumentException() { } } - @Test - void testExcute() { - SetGoalCommand testEntry = new SetGoalCommand( - Parser.parseRawCommand("set goal /g 5000 /l car")); - testEntry.execute(); - assertEquals(1, wishList.list.size()); - } } From 57b59615404f3ac46efae4ab4dbe1b6ca4d745e3 Mon Sep 17 00:00:00 2001 From: Shi Haochen <99376359+hshiah@users.noreply.github.com> Date: Mon, 13 Nov 2023 03:12:15 +0800 Subject: [PATCH 499/518] Update AddReminderCommandTest.java --- .../financialplanner/commands/AddReminderCommandTest.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/test/java/seedu/financialplanner/commands/AddReminderCommandTest.java b/src/test/java/seedu/financialplanner/commands/AddReminderCommandTest.java index acc5052c0b..747ba694dd 100644 --- a/src/test/java/seedu/financialplanner/commands/AddReminderCommandTest.java +++ b/src/test/java/seedu/financialplanner/commands/AddReminderCommandTest.java @@ -51,11 +51,4 @@ void testIllegalArgumentException() { } } - @Test - void testExcute() { - AddReminderCommand testEntry = new AddReminderCommand( - Parser.parseRawCommand("addreminder /t debt /d 11/12/2023")); - testEntry.execute(); - assertEquals(1, reminderList.list.size()); - } } From ff4a734817cd74f31510d2d7d01cf6eea6c00417 Mon Sep 17 00:00:00 2001 From: Shi Haochen <99376359+hshiah@users.noreply.github.com> Date: Mon, 13 Nov 2023 10:42:32 +0800 Subject: [PATCH 500/518] Update ReminderListCommand.java --- .../seedu/financialplanner/commands/ReminderListCommand.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java b/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java index e8618b289c..bdad0e6a73 100644 --- a/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java @@ -14,8 +14,7 @@ public class ReminderListCommand extends Command { public static final String USAGE = "reminderlist"; public static final String EXAMPLE = "reminderlist"; - private static final Logger logger = java.util.logging.Logger. - getLogger("Financial Planner Logger"); + private static final Logger logger = Logger.getLogger("Financial Planner Logger"); /** * Constructor of the command to list goals. From 7b3be7be0cf728ef76833050f35a67fd67bafcea Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Mon, 13 Nov 2023 16:13:26 +0800 Subject: [PATCH 501/518] Fix bug in UGDG --- docs/DeveloperGuide.md | 6 +++--- docs/UserGuide.md | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index e134defa6d..1da192f087 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -58,15 +58,15 @@ **Financial Modeling Prep Stock API** - author: Financial Modeling Prep -- source: https://site.financialmodelingprep.com/ +- source: [https://site.financialmodelingprep.com/](https://site.financialmodelingprep.com/) **round() method in Cashflow.java** - author: mhadidg - - source: [https://stackoverflow.com/questions/2808535/round-a-double-to-2-decimal-places]() + - source: [https://stackoverflow.com/questions/2808535/round-a-double-to-2-decimal-places](https://stackoverflow.com/questions/2808535/round-a-double-to-2-decimal-places) **capitalize() method in Cashflow.java** - author: Nick Bolton - - source: [https://stackoverflow.com/questions/1892765/how-to-capitalize-the-first-character-of-each-word-in-a-string]() + - source: [https://stackoverflow.com/questions/1892765/how-to-capitalize-the-first-character-of-each-word-in-a-string](https://stackoverflow.com/questions/1892765/how-to-capitalize-the-first-character-of-each-word-in-a-string) **DG adapted from** diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 5fcfec4395..a15f302f7a 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -78,7 +78,7 @@ you a one-stop interface to access a plethora of features to manage your finance - Total Balance, Income balance, and Expense balance are different entities where the latter two do not have the same limitations. - Maximum value for recurrences and indexes is 2,147,483,647, the maximum number an `int` can hold. -**Important:** Data is automatically loaded on start up and saved when exited. You must exit the program using the `exit` command in order to save your changes. +**Important:** Data is automatically loaded on start up and saved when exited. You must exit the program using the `exit` command in order to save your data. ### Add cashflow @@ -574,6 +574,8 @@ Add a stock that you are interested in monitoring into your personal WatchList Format: `addstock /s STOCKCODE` +- `STOCKCODE` is case-insensitive. + Example of usage: `addstock /s META` Example of output: From ea272b6b6db02449816622f6440754f008d046bd Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Mon, 13 Nov 2023 16:21:29 +0800 Subject: [PATCH 502/518] Update PPP --- docs/team/ryan1604.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/team/ryan1604.md b/docs/team/ryan1604.md index 27a94b1489..059c9b42f5 100644 --- a/docs/team/ryan1604.md +++ b/docs/team/ryan1604.md @@ -43,6 +43,7 @@ you a one-stop interface to access a plethora of features to manage your finance * Set up GitHub team org/repo * Manage releases * Equal share of workflow processes on GitHub (review PRs, maintain issue tracker) +* Submit deliverables on Canvas ### Review/Mentoring contributions: From 730afd0b5207e14c50119b8b7a6a8ebd634580ed Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 13 Nov 2023 17:37:22 +0800 Subject: [PATCH 503/518] Fix broken link --- docs/DeveloperGuide.md | 14 +++++++------- docs/UserGuide.md | 4 ++++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index e134defa6d..b7723f0831 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -26,13 +26,13 @@ * [View budget](#view-budget) * [Mark Goal Feature](#mark-goal-feature) * [Sequence Diagram](#mark-goal-sequence-diagram) - * [Product Scope](#product-scope) - * [Target user profile](#target-user-profile) - * [Value proposition](#value-proposition) - * [User Stories](#user-stories) - * [Non-Functional Requirements](#non-functional-requirements) - * [Glossary](#glossary) - * [Instructions for manual testing](#instructions-for-manual-testing) +* [Product Scope](#product-scope) + * [Target user profile](#target-user-profile) + * [Value proposition](#value-proposition) +* [User Stories](#user-stories) +* [Non-Functional Requirements](#non-functional-requirements) +* [Glossary](#glossary) +* [Instructions for manual testing](#instructions-for-manual-testing) ## Acknowledgements diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 5fcfec4395..433d52bf87 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -812,6 +812,8 @@ Displaying piechart for expense Example of usage: `vis /t income /c bar` +Example of output: + ``` Displaying barchart for income ``` @@ -820,6 +822,8 @@ Displaying barchart for income Example of usage: `vis /t income /c radar` +Example of output: + ``` Displaying radarchart for income ``` From 8cc3fecdc5d2aa2907dd94a104283c786a12e5c2 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 13 Nov 2023 17:44:35 +0800 Subject: [PATCH 504/518] Add fix that you can only add stocks in capital letters using file --- docs/UserGuide.md | 4 ++-- .../java/seedu/financialplanner/investments/WatchList.java | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 433d52bf87..3292f322f6 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -629,8 +629,8 @@ stock entries that does not match the format specified above) **Adding stock** If you would like to add stock directly using the file, do provide accurate (we do not check for accuracy of information -due to free nature of api) information for only the symbol and stockName as shown below. If the format is not followed, -the stock might not be loaded to watchlist upon start up. +due to free nature of api) information for only the symbol (in uppercase) and stockName as shown below. +If the format is not followed, the stock might not be loaded to watchlist upon start up. ![](images/investments/Exampleaddingstockjson.png) diff --git a/src/main/java/seedu/financialplanner/investments/WatchList.java b/src/main/java/seedu/financialplanner/investments/WatchList.java index 4c28b9f879..3240269c8c 100644 --- a/src/main/java/seedu/financialplanner/investments/WatchList.java +++ b/src/main/java/seedu/financialplanner/investments/WatchList.java @@ -67,6 +67,9 @@ private void cleanUpLoadedWatchList() { */ public boolean checkValidStock(String key, Stock stockToCheck) { boolean isValid = true; + if (!key.toUpperCase().equals(key)) { + isValid = false; + } if (stockToCheck.getStockName() == null || stockToCheck.getSymbol() == null) { isValid = false; } From 875b0ab9336380b94f1aaec80aa685f1ad42b0cf Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 13 Nov 2023 18:37:09 +0800 Subject: [PATCH 505/518] Fix broken link --- docs/DeveloperGuide.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index b7723f0831..04b5c70957 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -7,9 +7,9 @@ * [Architecture Diagram](#architecture-diagram) * [Storage Component](#storage-component) * [Design considerations](#design-considerations) - * [Visualization Feature](#visualization-feature-) + * [Visualization Feature](#visualization-feature) * [Class diagram](#class-diagram) - * [Sequence diagram](#sequence-diagram-) + * [Sequence diagram](#sequence-diagram) * [WatchList Feature](#watchlist-feature) * [Class diagram](#watchlist-class-diagram-simplified) * [Sequence diagram](#watchlist-sequence-diagram-simplified) @@ -117,7 +117,7 @@ the data one upon exiting the program with the `exit` command. Option 1 is chosen to prioritise the performance of the program. -### Visualization Feature +### Visualization Feature This feature is implemented with the help of [XChart](https://knowm.org/open-source/xchart/), a simple charting library for Java by Knowm. @@ -168,7 +168,7 @@ the visualizer displays the specified visualization chart by calling the chartin ![](images/vis/visualisationClass.png) -### Sequence Diagram +### Sequence Diagram Overall @@ -803,7 +803,7 @@ Test case: `overview` Expected: Displays overview of user's financials. Details of financials are shown in the status message. -### WatchList Feature +### Using Watchlist To test the watchlist feature, you can copy the text below into the watchlist.json file under data directory ``` @@ -853,7 +853,7 @@ as you have no more stocks left in your watchlist Symbol Market Price Daily High Daily Low EquityName Last Updated Empty Watchlist. Nothing to display... ``` -### Visualization Feature +### Using Visualization We can use the visualization feature to visualize your income and expenses. From 185264299951f56a264dedb4201b987eeb37e029 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 13 Nov 2023 18:48:45 +0800 Subject: [PATCH 506/518] Add about us --- docs/AboutUs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index faf839094d..1f6023dc99 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -3,7 +3,7 @@ | Display | Name | Github Profile | Portfolio | |-----------------------------------------------------|:-----------:|:---------------------------------------:|:---------------------------------:| | ![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) | -| ![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) | +| ![](https://via.placeholder.com/100.png?text=Photo) | Hao Chen | [Github](https://github.com/) | [Portfolio](team/hshiah.md) | | ![](https://via.placeholder.com/100.png?text=Photo) | Ryan Chua | [Github](https://github.com/ryan1604) | [Portfolio](team/ryan1604.md) | | ![](https://via.placeholder.com/100.png?text=Photo) | Neo Min Wei | [Github](https://github.com/NeoMinWei) | [Portfolio](team/neominwei.md) | | ![](https://via.placeholder.com/100.png?text=Photo) | Frederick | [Github](https://github.com/wwweert123) | [Portfolio](team/wwweert123.md) | From a7bbd831812bde8b0aff05b75d2372cbeedb5ea7 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 13 Nov 2023 21:25:37 +0800 Subject: [PATCH 507/518] Fix DG and UG --- docs/DeveloperGuide.md | 128 ++++-------------- docs/UserGuide.md | 8 +- docs/images/cashflow/AddCashflow.png | Bin 0 -> 7559 bytes docs/images/cashflow/List.png | Bin 0 -> 17411 bytes docs/images/cashflow/ListDeleteRecurring.png | Bin 0 -> 7614 bytes docs/images/cashflow/ListExpense.png | Bin 0 -> 10109 bytes docs/images/cashflow/ListIncome.png | Bin 0 -> 10312 bytes docs/images/cashflow/ListRecurring.png | Bin 0 -> 11894 bytes docs/images/cashflow/RecurringIncome.png | Bin 0 -> 7278 bytes docs/images/investments/watchlistMT1.png | Bin 0 -> 28362 bytes docs/images/investments/watchlistMT2.png | Bin 0 -> 36708 bytes docs/images/investments/watchlistMT3.png | Bin 0 -> 11676 bytes docs/images/investments/watchlistOutputUG.png | Bin 0 -> 29842 bytes 13 files changed, 25 insertions(+), 111 deletions(-) create mode 100644 docs/images/cashflow/AddCashflow.png create mode 100644 docs/images/cashflow/List.png create mode 100644 docs/images/cashflow/ListDeleteRecurring.png create mode 100644 docs/images/cashflow/ListExpense.png create mode 100644 docs/images/cashflow/ListIncome.png create mode 100644 docs/images/cashflow/ListRecurring.png create mode 100644 docs/images/cashflow/RecurringIncome.png create mode 100644 docs/images/investments/watchlistMT1.png create mode 100644 docs/images/investments/watchlistMT2.png create mode 100644 docs/images/investments/watchlistMT3.png create mode 100644 docs/images/investments/watchlistOutputUG.png diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index b7c858df45..2c7e8e8a56 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -525,15 +525,8 @@ To test the add cashflow feature, you can use the following command: add income /a 5000 /t salary /r 30 /d work ``` You should see the following output: -``` -You have added an Income - Type: Salary - Amount: 5000.00 - Recurring every: 30 days, date added: Nov 12 2023, recurring on: Dec 12 2023 - Description: work -to the Financial Planner. -Balance: 5000.00 -``` + +![](images/cashflow/AddCashflow.png) Note: The date displayed will differ based on your system time. @@ -572,77 +565,26 @@ Note: The dates displayed will differ based on your system time. Input: `list` Output: -``` -You have 4 matching cashflows: -1: Income - Type: Salary - Amount: 5000.00 - Recurring every: 30 days, date added: Nov 12 2023, recurring on: Dec 12 2023 - Description: work -2: Expense - Type: Necessities - Amount: 1000.00 -3: Income - Type: Investments - Amount: 500.00 - Description: stocks -4: Expense - Type: Insurance - Amount: 800.00 - Recurring every: 365 days, date added: Nov 12 2023, recurring on: Nov 11 2024 - Description: insurance -Balance: 3700.00 -``` + +![](images/cashflow/List.png) Input: `list income` Output: -``` -You have 2 matching cashflows: -1: Income - Type: Salary - Amount: 5000.00 - Recurring every: 30 days, date added: Nov 12 2023, recurring on: Dec 12 2023 - Description: work -2: Income - Type: Investments - Amount: 500.00 - Description: stocks -Income Balance: 5500.00 -``` + +![](images/cashflow/ListIncome.png) Input: `list expense` Output: -``` -You have 2 matching cashflows: -1: Expense - Type: Necessities - Amount: 1000.00 -2: Expense - Type: Insurance - Amount: 800.00 - Recurring every: 365 days, date added: Nov 12 2023, recurring on: Nov 11 2024 - Description: insurance -Expense Balance: 1800.00 -``` + +![](images/cashflow/ListExpense.png) Input: `list recurring` Output: -``` -You have 2 matching cashflows: -1: Income - Type: Salary - Amount: 5000.00 - Recurring every: 30 days, date added: Nov 12 2023, recurring on: Dec 12 2023 - Description: work -2: Expense - Type: Insurance - Amount: 800.00 - Recurring every: 365 days, date added: Nov 12 2023, recurring on: Nov 11 2024 - Description: insurance -``` + +![ListRecurring.png](images/cashflow/ListRecurring.png) ### Delete cashflow @@ -706,15 +648,8 @@ Balance: -800.00 Input: `list recurring` followed by `delete recurring 1` Output: -``` -You have removed an Expense - Type: Insurance - Amount: 800.00 - Recurring every: 365 days, date added: Nov 12 2023, recurring on: Nov 11 2024 - Description: insurance -from the Financial Planner. -Balance: 0.00 -``` + +![](images/cashflow/ListDeleteRecurring.png) ### Recurring cashflow @@ -731,15 +666,10 @@ Next, exit the program and change the system time to be ahead by the specified d In the case of the example command, you can bring forward the system time by 1 day. Finally, start the program again and you should see this output: -``` -You have added an Income - Type: Salary - Amount: 5000.00 - Recurring every: 1 days, date added: Nov 13 2023, recurring on: Nov 14 2023 - Description: work -to the Financial Planner. -Balance: 10000.00 -``` + +![](images/cashflow/RecurringIncome.png) + +Note: The dates displayed will differ based on your system time. ### View Balance @@ -819,27 +749,17 @@ To test the watchlist feature, you can copy the text below into the watchlist.js } ``` Start Financial Planner app and you should be able to see this output (although prices will differ) -``` -watchlist -Symbol Market Price Daily High Daily Low EquityName Last Updated -BB NYSE 3.64 3.67 3.55 BlackBerry Ltd Sat, Nov 11 2023 05:00:02 -TSLA NASDAQ 214.65 215.38 205.69 Tesla Inc Sat, Nov 11 2023 05:00:00 -Data provided by Financial Modeling Prep and Alpha Vantage =) -``` + +![](images/investments/watchlistMT1.png) You can then add a stock using the command below ``` addstock /s NET ``` You should see a message stating that Cloudflare was added. After running the watchlist command again and exiting the -application, your watchlist output should look like this -``` -Symbol Market Price Daily High Daily Low EquityName Last Updated -BB NYSE 3.64 3.67 3.55 BlackBerry Ltd Sat, Nov 11 2023 05:00:02 -TSLA NASDAQ 214.65 215.38 205.69 Tesla Inc Sat, Nov 11 2023 05:00:00 -NET NYSE 63.08 63.31 61.34 Cloudflare Inc - Class A Sat, Nov 11 2023 05:00:02 -Data provided by Financial Modeling Prep and Alpha Vantage =) -``` +application, your watchlist output should look like this + +![](images/investments/watchlistMT2.png) You can also remove stocks from the command. Run these commands separately ``` @@ -849,10 +769,8 @@ deletestock /s NET ``` After deleting all the stocks and running the watchlist command again, the output should look like this as you have no more stocks left in your watchlist -``` -Symbol Market Price Daily High Daily Low EquityName Last Updated -Empty Watchlist. Nothing to display... -``` +![](images/investments/watchlistMT3.png) + ### Using Visualization We can use the visualization feature to visualize your income and expenses. diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 651c0f50c4..6be58f6d4a 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -550,11 +550,7 @@ Example of usage: `watchlist` Example of output: -``` -Symbol Market Price Daily High Daily Low EquityName Last Updated -GOOGL NASDAQ 124.46 125.4 122.75 Alphabet Inc - Class A Tue, Oct 31 2023 04:00:03 -AAPL NASDAQ 170.29 171.17 168.87 Apple Inc Tue, Oct 31 2023 04:00:02 -``` +![](images/investments/watchlistOutputUG.png) - Note: Your watchlist information is saved under the file path `data/watchlist.json` in JSON format - Note: the watchlist in memory is saved to the file whenever you run `watchlist` command or `exit` command @@ -897,7 +893,7 @@ window. Sorry for the inconvenience caused. 🥲 | **list all cashflows** | `list` | | **list all incomes** | `list income` | | **list all expenses** | `list expense` | -| **list all recurring cashflows** | `list recurrence` | +| **list all recurring cashflows** | `list recurring` | | **Set budget** | `budget set /b BUDGET` | | **Update budget** | `budget update /b BUDGET` | | **Reset budget** | `budget reset` | diff --git a/docs/images/cashflow/AddCashflow.png b/docs/images/cashflow/AddCashflow.png new file mode 100644 index 0000000000000000000000000000000000000000..8b780eeeaa8a9da6188537e194fc326743efab2f GIT binary patch literal 7559 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 af0L^_+o7qI4EZ%+7fmeB7aBP{{=WcuYFYRI literal 0 HcmV?d00001 diff --git a/docs/images/cashflow/ListDeleteRecurring.png b/docs/images/cashflow/ListDeleteRecurring.png new file mode 100644 index 0000000000000000000000000000000000000000..68f6ad49a03773094f207c6abc154a2cba22f8a8 GIT binary patch literal 7614 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

    {*rT& zN5g-ZvGyKu|K|?jbCwcsE=--ye{065<2mY<^%lO-%`EOEytA$q>R8Z#B^m9yL1CG%nP zTljZYoV2CaL`mNoE7bmrC_OJncB7Ib>jxjqDUy-P$DfTFlW{W0x~F3rAl4aGR{0!@ zNxmOyz7^Jbp^QM<@wC@-IpwJbpW4_-pEX2C8@>|PG6k^{@-Ua~30qp8O#y0}Bq2Sj zQ{q#pT}lMq)3W#Qi!)E6pK8^1tCF7LP2~FB*5X4&VuQ_PvHIdcc$PP@wl7d^)?5yI zD}Jt9n^Xl-aMjDt$!wZPp<3DjsJEu17{it+J1zu-XOr4L-Q)eZ{QJIR&F){WoB(6~ oKmVh(NC5uwMgqc;&ziKoD==M@$#DEy0=)8>UN*Z_Vdxz5Z?61l@Bjb+ literal 0 HcmV?d00001 diff --git a/docs/images/cashflow/ListIncome.png b/docs/images/cashflow/ListIncome.png new file mode 100644 index 0000000000000000000000000000000000000000..9e6d542601822a062862d82f05a8e83819328b60 GIT binary patch literal 10312 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 MS^G29mflJK4M{tyS^xk5 literal 0 HcmV?d00001 diff --git a/docs/images/cashflow/ListRecurring.png b/docs/images/cashflow/ListRecurring.png new file mode 100644 index 0000000000000000000000000000000000000000..1ecb7d3b8c05bc9456703f902ab8a180f74ad1ba GIT binary patch literal 11894 zcmcJVdpy(c|L~n6AyjfE6^fjaLk=71BuOQa)2da<8p$EXY@J9B>ytvnmJZJ3%$O+| zVWu1=GtzR%Fl>y?=6>t@yYI*2cRzlQ`~E$Czx)2{^>}aZ_jSFl*Y$e6uIu%@u7tB^ zPRMOh+ae+&BIkVa=y?$lu_+M|QH{-#z%MV$9mPaMjP0F|I$ntMpQY2`jE^;OW1=xp z5t~xQmgicV4?*AkBVzoyU^iO*&Iy|jdr$rLP6R)nd31LqQ7U7ws_Nvq?*Wg^*^{hM zVm5bqc|gD=uFneD*!8gZ7Ez#wW-I<4ao)O+3+~^%@yOkU6W>rp=l`FGdV`LgHm>!# zC$LsyjrlY}@U+>X>~&R^^LjUZDYh{PGC8+zH2Sd1Dex)ag|167G4l)B;yDUj#N_{@Y&v#b1QVpXIl^IrEX~GO&=SSrM97nNKf%T zoUMx(k0Y_dJ|wggZi(fs+8RkaCiBM74Tm{`JAzs7gI3bOOsz$zi}Q50UN1mf8poHX z-}QRq5B4)=>rCw^>-B)_{9W<QZc}U~`x-wkbBodpL`CN9Yos_2A(%Y6znO?U7YVeM^94=5|+yhIVgG2M5FLlHk zydvIHXeuL_my?@_1_!!7MUP;#AcrsVGWt|gP;)NdkfY}WP~;d4NetzezRC*mS!z9b zG6nW0CY0ra-OhIng6swyY5tD9^wgiMDy61uQ&}(gfD~uNTj{inWA+ZK>VFk+OFzlU)idhz~Drt$4oTH9#h> zG0pg1e?qp@{vc{`e!v;La5;ag*w8~u1$JjdM1GpZ9>Ssc+c`rbs*hAOcQeHv_FH$nxm9b zN@od>Alc!F=Pr;30wofV6YNN-;&>!9-3`pZwxK_WxjG-)d|vc!Bt+7*tv^g)jk$81 z7=XM{03RE^q}(Hj?O!QeNKj%{gVvMK{))xSmHHdh$$WHA$)d8G8u3YL?u<%lF-tkBi1G2os->QH?GN24 zBJ#p+A5MIb%Yv0C+6bEt%3ITMb)F{ zmP4YnA^dxDrDGH+;@(LhUw);;(=eml&PX0IPM}gdD#aF3*pr+{*(JsAfOgN=NKwJL zEu!{Yn}r3ul}g1yD5Lk@lJ4%oGb%q@&T4H6D<3@vKE8O%9_T`0<*}$en-e2D#oK@H z!2Drp< zCeV(TDo~_IHdkLm)9kzC4rZ zblWzCzRJ|fCw9}%5o)(?%--eo%~Rm<(fWpwAo@5xGFVs42JjCd;j{xd)|WhP+_LR? zIbnT9B}GuNP3d_nzaVcoHtH!a=4HriYE2QN#->%z(Ap@9_ zEUY`LH3W0uIxYkLROTv*@a_ajk#!;^Y34b%xjKEDzthBcI;wF2L8_N)6Qv%;#}cQT#yEZiJN24#?3{FxJ}vOpDastm z2G@E0ptw>`;*|!|CZLPKnN~5puZz*pbuq-UG_O{%^HedyTu=*3ck!5@rb%%=uK+uh z%a!ReQ?Z9T`Vn}Tgul}1w(w~SW}#J?WBTtV4}#FSj=nyGp2K#ONl*RwmkwphJ@U(l z>D5Z7{G5D;teXLksIH>)q4*f@xt8!1VMF9ycu?Eds(S8^{w4z)zh>ZH-3T^uwk)Uq zezb>cV9-dnX zAvdvB$~Ao(*u-%7(`#g`e*cFL{(vKRR#k57hm3c`4nJg3>un3U>TI~Ez4nXvkLp!_ zm`|Np3XPNA{Q(BF9m!)c!Uy9iw=}-@M7*R9b5XU>Ex7>Ax%BYxBmeVl;Fm99Eo+q&>`Q*2CgQP&sLrpMc$H z|8yE2t<%gIA-%z);9KII_JxNZ?X-U|zb`%D(Y5*4M}jP`1-uZ$F9}zUBBt{ej$NI8 z$ntc}%8i8AOtwO4P_^K=l)Kh<1tHwM>taE%vHIR;I z%kGd%Z)X)n{bCe16Q4a%`*7XhlRK;u#l^aP^6INPSH1t2m3Hs zrKfrq(-s00Yu;YgjBET!Sw5JsQV(n(mxX)86tlHnEGW%Pp7|)S&1@YN<`YiMv zvGJ$?FxR2=WgY)cExSu)1sfkdp52S1Fke*vlrB^3fQj=u?Hs}FqdNvWgLBJG(}ek; z{;Gn@!kv56@}B;kl|dk%7)(jNDc8gC^O_NIh>!5{7gr;}vM*)C@T!5j>laoXJFT80 zUog20fh&ygmhuJa->X;rDaOs%&rB@Jbz_#w0+mJW1)Q+0ogSh{-VZRc*6AIOdTBUd zK!W3>FnDxVvy{5M&OfaCwh(4j~FQ;eW{CxHbLNRNKRc+c=@{rFhw+2YZN4Um3~K7`45it`vOiiFYl1Q!WH(I27#ijTA6G|`4^VU2?}B)q%ARkpE;qU(CV~GT9{$W@ z<;Lt(q+W_s`_K1I=+9W;e6DO6JlSo|{xWN_#m6L#B7F^f%Kvhah22giWFQEK8WCUc zG=-q{;Tl2~sW5iq!Q@X-Oy#Q~-CL~?A->5D3PlCSq$DmYvNPSyxjCO^saPwSgH)%v ze<~=;!bIxxOz$qU^{589sp+f>gWdM3s+W{~Rt=xe|MXT4iW1L3ZAHD@Mmm>5A=`@Pl{1)vsY;+jcKP({sF|j}@&RRYBTz zxM{%hT2|C3X?s&n%(h5V)T}X=t+ME4ySQ7Q){ff;25%F*n4I}u?^mq*gH%2-zl<0! zkLU{-T4ApL!T;$t1fNJkmj)IP27(HTrYjfq2+!-BJNaK@jLI<{eR`fQt}0&Fg<{HN zqf3devl7hCXa^TzcsAC_kSgN5T|t58YgmQJr`WfMWKe;Svr|jzaKwOMXx0`#I>et} z%4gRf-+f^E_UrJ!;oPZU{ZI5<}Rb=O{jh!RXy`;S33 z856TPpT6rm?#3miy3aLyAb-h>Ofg%%fGotwoXJHOmIOAik6HKYd6Y3dH9C;%C8@_o zcYUUYwpAWzYQN66LPqrn4xD2c)*@9%26$YjiQ&NG<9=OB5!e&_ey8*Qmu| zGPQW(Sv4y+(>rOl1607?9gb`duDt>GT(x@!_w3ceJqOQ1+V z8>vsY`lb2|P^q>)V`%%y{@o9<5$ie+m=|_@)K6FiT|EjzZDxt%b_EKrI6RqlU^Wv**s zoY)TCO}dVcRZh8Am=?8_#;Uyx5v60B2PDos8lDPWM5}Z5y3x^W$AS;!z2_RD-uy!Y zinH^|4M|^w;}O5D+mS`w=wHV{bXjw&=pT7Pb5foCaHL}v?F5_uB&Glik2#-K8$e3hX$yOJL$*jw;D|ph8;-Raz>|k?(xGgjeI$Z<_;$yB


    IgTY*sK@NlBnXapu+kabobo@DuYzbsI?L{ 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
    |rh$k?}+AS`GN-R9$;r zgHCb-l`G9O6|LCV;Oi_aPHydcl_*@qY6ER!EgGYNMh2PMz3z4%gmK%b$=rj;PmkU8 z*u5WOqyuE$l5WkM+Z=n}J+q{ozrSb|4d+@96w>g(d$^9K za}%E@eA9>|++l=yhlb};lLr*Dq{cpn_vs9mUC2pkQ5uL$Y}To|h8_sD8BU%yoAUu6Omnv<1wCY-vOx`qqK zk*g;8;PmUSs6;`U@r6N`jDcy3-7Ut}@)BmpYd9ij+U0j)x=q{dR%oyF67oB`NJSD> zho+XXynku(v?`{sDpZ@Q4>6}Ru5V6z+z0_ogj&&e#+^NvPg3oH^{e+rEP4g2c4@55 z61uN{!vvPRU?a(Cw^!X}9}aYAu`}?m%n466BdFT;dSz5&Hpq^?qUrrAQ{@EU74+)V zOQe4DI1nnkXzGA|iu*AT1*_Y=y_ZnXxir*YqKVJf;yi;9iNkwa%IZ~tEJHatP1JMS z;&GJU@M98nLk!M-J5JJGL?aALe*QVR0t1sFfg{P(XkW~%93|o;!$8(=SVWr2xXP1y zmEq>#pJ z>QHs#>)Xg5fD!M*>fQMBt7&COgQC>+C*g6b{tgjUY=oQU4*K9BWxM}19uaJk` z+Ff~QdodR%V>d|rdI~4yre-u_ViDKQcCA{uhEOj!YomJP6~ZcWx4o@_E84#svbA~0 zaz%E5+fFC`Wz^4iNnZGR4|0&B4GNP4@&46H`6RrSmB%*MRubd>T5f?m%0ji?!Ri^E zNIb)9TDbD-?c;)IQnSOL`2B6dE?;5L>E3Gv!wtGZ9_dq`dBQ7^bI$XQnnOpBd~En1h~}T_ zVj6PA8EqKbfX;%^1gFLeFV@qrwqkbLCidbQJLq4P1NO z>(Xu<82jJSc}qK$SjFV^O1to%S+J@4d@aFC;i~^~ZS99lWgyRC-Go2cn(M>~UGY=V zpUfb~eg9qw^3Q&ysFZ$}*w}12`LKE&vrJ;%^3YT zhB6rv6FKL7-K;rn>pO8Vb8wLGo!4#wZ`o85P;h5OzkNgVD*C%)Ibp)+e)C$9!v7YIIDxJ7T zQbcWwCmeFn2r2&<%%2R9j}uIKHoKfXb~bQ0!)z|>&~L92Pf9DxzTCR%%nQ{_qza~LAF`Z2nT!tfs_oIc{8*?TDgjT#$hzS#H+JzsDHE5pmxsaW|6eRxUdUkyxtd1MJ z6>5hXhEN7E&2AbiVf>-N^h~mae&pNeZ6#d1;O2x|9B-=$wH&b7UXO7%(-hk8&z5)d zhBw*S+suu=h7xsSN|X#*WJ*6p?)Lw6wylt6&I0Miv~S@${Q{a5M8qsiC!ikqK_IsQ zvoR-gshzA+xmubRn+h1c&!x(UeQJYTy_OqdBlf$%zf~DdqOy{BaY-qPPA*$7jo7mx z_4~9he|K@(IkeKw$52Z$$tJM@xSZ6AC^iED)%}NJ^^OI_tbPxwCf&Z)J1+V@f*;9Z z_qqIqIVVnSdvL@Hy7vR~Efd9hrWAIGNHlA}KPj)WllQMF(JLlfRGBf7B7u*_F; zAl1Xe|6?~Vt#`SX4vb#UBDSvixtP9BylaLrl`QO84@*@P*tQ&lil?F*GT1(|&R5Pg z>*%o%BR{w!BuJoWh9jea634q9Br>E$x6Fj|-Ft`Hex#cYmtO7QS4ofaEHtQr2V6b{ zSF93WcM|2GlEwIOcp{BeL8L)J2ZBeN($XnT*3Sb2Xg7 zcZ4k_e(*T7^F2c14%uBAX?T%cd~i`bOasRYETgbpRkH;}CQ(p-L>fw@0CzMsWTj#n0H^x)cfXJn{?yN%ma^o z&VLVA@8f6{$mA==RK%ct1f^d6eBuJSX{i0*}eZ54M+Gxrd zT;ctwHh=2e@a3G}UXLg0q;b%-vIy#hEFe z_NX|XV#i2O4jUyfeDfAIhM$U?@jskY$tExUs^Rx%y)FMG%{vrx%jt6`UZ8ORg}|Hi z`g)!pqk9WTuqbrs506+qS7|L_e+y8wl_-B2Lf7@$?=BX!@)!?Zb|Gt$(6wuS^!da0 zU2WqI7x2h$c*^cQTyq-sT)r`2&@ZWm@$P<6jF>LEo7-|JmPfMF^7tHd*M-$Gj3{Z` z=A#H^`4@iusUvv7YF|neUh635Q|A4RMp(7ZBFO7td=ho7vsiW9Pof+l*?CZ)lA3_i z`#k()rl3J5Zb0T{B@P{3S29c&tmJ)c2Zn+8o&w25+m;?oN{*xm{<5BmCZbXv9j4ww z$&QVlx8h^Lj3lT~OM|)Ck`rI6dYFWUqje zGC{T67M=6KNQ|}pGN#c*ZpXmdQmJW&^xRpf-qZ9!FzF2LFHkidY3v?;GnW~@u2vi!6@KWLa%85mcbyXu7t$LHa_;Cr+ zCqN-l9);M`Vu9%2I_JUPe6zq`+V}=7U(!UKM=-RHQ}Ft693Gy>Nj2tqFXU7BSsgx< zS>_k4e!Wzb1o)l}^k2wP+t~aIl!QEvyA7zj~g=mE4kQ6jev`uE`C3 zSR^QM@pDswcw3>@x|G1yTb!P)w>}G;h2N$f<@g`a&?U@12#b?1_9c>35$Z;Wm|vq; zm}ABUvjh{BQ>1qvA6&j@GFt94X@O4zT}xDagiU% zK9mLP6GyS4MgxbIH|n^(?S0T+{$EJsR9-{r!mg1KV)?qM=?o$~&lhcp?u{Umnz+QQ z1^Wmx*rn21^tH`8E6;os?8foCyW40TF>M^JNBA}P4~Kkx@rOeWv-*8>8wdyV(aV^% zxc-X(Cb|c;sENAOqZBRM*#)|*RlA1IESMfSA4|i>mr=@gy_Y-oY399lJaeqXpmO53 zZ}<6Bpv+}4!yR}A&*XLxP>-9}CshDCAo`R9uZ|RvQM8it(0a??3?uEH@=<1``RIU< zfAGewQRjLvZ8(BUZo*(FO(47Iafo~#LFjqJcv|5q2wDvs8Kn3C7jfK5=D=EEsp{s4 zE|rVkaU(Dxv^+%Ax-HX`g{n&jW6(9!79ae`UXQ{Z`#e%#iBqrH-S>@Iuvk(p{q*pw z2TIhw4!+t@1hKJ`nck1wyIK?N%HE!xxXe${vAx^;g14Zqw(Ru&P2@6J1Oxi=DUkU5 zMR@Wd-+sB#BxzO*knh(qr1(+C;M*=un$-e)ewBTX_m4$M#vMH#SFuSKO4$cIe&C}W zP((9dAFIYEJz_w=0FyzS5^>AT`umQIR-Z_FjhHIYZGo1e7BzW1{7i+!gMH&Y$O0!0 zxm@5cnBO(zG=AWSafig^hf{nYI!@IG{Vpx;e5re|fN)*f!6&{7zdX4Dr+j5J@oSX7 z81V{%+bdc4wQNO}MC*OOQNm`D(me3n?19VM3z5^By+7^$Lvb5mJ0>A=A~U0EuH0_O zhuC;!F;xX0>?FE8dKu$BYifjp5>+o3O?UbgU_y>0h?E8;&@9d4S`v_g&71A>tH8!A_AFuinw%3s6B@)ZGH$Tpkfd9#VV2f|T z)zGZ|QnGC5i@}y%5ztM)I7=&y{q=xx4wL z1F*hWuG%V_C{y4B!2mMtGt@2pP6A`Tj3g`W5|C6>` zq^+Rvc@ib8taF(zq-!?0a$qwe)2-yRw^v%}tidC@<8| zu%cifdT+$onYER_+`3GQeCgVduFGvX)VJH{u+E4tt0uGT=Jq%(F*H-%$&_JJTdsP* z(kG+@qRWYKV8h0@opR7;5FnFTe)oD&C*&xh(ZF5nMS8;1c9N8xltLUPEh^l&L_Ro>)wvyq%b*Z@bVpxL4emqbjCyn-#)2SK4s8dMT)WhgG!R&3n4T}P-cE42^5s8iG0rQQphX?^dt>Vj*iFxf0`YP$iX3xQAN$EgNGC`Kt{z!p?eNEzJ#@4=Ka|keTnbYoT9#40q0$4r zU|%6@4UT-1FZRhHE{*8Tt3};j%&^>w`ueb`=m@G}JvAen%d=gZhJ}iHw$}?qElP`& zBX^tvDTa!hFD>Yu73sHHd7MYGjxu!A_Y@{8XT5=S0f~uQp-MFBgRY)CC3RCbKXpc# zd#x1wKqiEhN$P7=JPi2vy6VLDAl=Xh-JDpP-l6A<$YsOzR;_8j#Qk*WLF8(FAsj`9 zs~>_ln>Ol9<;yueenbZf)#v6ilJ-+*ka*&ir(d%xiAChi7p8e^G}Cm_yoBzw*c6Xn zxJJKjbqn`|Y=5i$Y9c1|oyf0U_-#7HrZ@aWh_=s5bIrWEHEuhF)-F=du7|U6!ijE@ zV)&#tpgcZqnY+5eo`j>)RxCH%XyeyZ?fI7hV0TuL;mU`CO`TcAvo<*P8u>1)15eIz zXK?8#`n!9KZ7zli%tbA~R?bC1acy`4lW}Uj1W$B4?Z@dBpNCT=MYuuGbNA~MYDLlc zvCF52271!LQn%VAhE6jEE^e;b>=qXf7L4F^yjm;K*DBeG?-XQ$Qz>~Dd>~Zd$qzU9 zJqL{@G?qV3K69rL zm-FAj1Ud81RjR+>;#Di8BTbWsD;NY}U4j#WOo_xf>w(Wwwg)p{zGRzuMszuACTR3A zJ=+bB%zIWt*pS=Ogi&3RPV$aB2_sDXJE@k$(FTBQLD??r)Zha%e`|jOo`P#-PQa1!Bv#%n9s+ZW{{u4ti$6`EV%E}`h^sN{esn+E0Y`4 zGgz8ETMd$WSZ-k+6&-=`LmOYRm*ev}eQ~3!uXRJJeh0GgS%c3f+-l89Pfvq5&L;|Z z056%82MY@G#D`;3?b?(1pmHwUj#8vJaY+RonbTqBac;;BLk5@eu?G*#y8U}c-Y1fy z4n@?@CP3mWT5tR7&^)hjs43IXG>~t#J?#p?>cRX9%9Jh{I+a#G&dC5SzDU%({^eUN z8r+k9WFbYGT@ax@?;!?z@FY>&L;pv6u)1(Fd+4%Vq#5JZRRPZYQclOg041W@*X(Po zdG@)YAO^Z_7#pU>E+}DnYggf^TqaJgs)ho_iKtUkJ2m#)`d!5PAVzARc)ih{O%X4E zm>x$Eciq?M+4fD)XJUK5=D1+QKEiOWU(iH1H(wwT5xe>Q7-A&hrjFWYy6w z4_oqkr~;=eWY$^_P2XIgaBwoEX-%OTq@g9U58W))QQIk&Gzhuo`TV7(y08&&Ydd<} z9hJdf+Z26WMZrKeRwvdXwa1uwRWsU%ftimp)ORT=<49DK!Rz7iislZ9;)k_Da%i zZpC6Ql7HCAw&;-fkk+}_^o>+}wR9z!eJH-g2U=9|>H%O{_)jI(j53;@x-)X8Yxju^ zu@wU7jt;$!VB9$nIfbdXEiL?p(3CVeSV}lg zsS`bYN{C)M$+T7^rSs6P?w5wg4@F|IL66uJ%2sp@Ijpj+B;`UlTwf(B^~QSL+E0@w zq9NPUrl68C38R@)KqUCxxwL=34N-vQ?GMY7G-^87YK^^rchc5bF6hP%;tKUak~MEf zX5sz$4p^VuQ@!&_06W4s8AxbCFm{k*cx-ov>{L7FbE-4|pB-%+%fGj~9yd%um%t2H ztp2iPo@Q%*?6m6aa{vPJzFxA`$11}rAjjihJ`sB-XDf9`3So1=i~(L_bFlL@i)_qc zs8L6xj^LRfvWsUpj^MB?N4GpreiE?_lo>z6{tnF4Ya_2yatVK>ekHVYRB69nn3j-+ zK;O(;M&V<+MTLdF*Oapo6^8fsqF75-GLUasH5W0<`)7@!^cz?)S|ApAlegMTNvQ|E zNkT-M3e~thnpxr>eaQm0p3{77f2N{?HeE~eE0j|j1M?J51U^Mpqk;hv)^+;@DZI6rLw|bgN=*~ zSxY0=R0>w|2x`E}(u%^?gRA(j_n-A`)jPPT75h)EdlEJa_f`+sU}$O@H31UGBlF_b zL4l#BKR^_rAq8$5kYt_a=vYDTV|`dAEP!2Oj)-RXHLSluf6<}wvYA=5^6%!3avO%U{1Ga)Ly z!m79}A$${$sZfk!!rjcM56(&ljVJ25_f|JDL(=;%ncvfsrzeFl+*zPSk+jKFX zRPR<1h)!oO;vyhO;(@^31W)Asu9AbzZ7;m;oK4y8@AE$F=|V8Pc`cv3XDF=bUE+nU zQVwD``kh<5tP`%<@9rE`ZFn;N6kh5%^SPVy66iR$8LRUm5Ip(0!Y8osz^rfT^*!2_$gQr{XmG?$kHkN+WJ{#@hw#>!?Gq1P_>+*)h8*)#!t?k}=ppBM zpl}Z7_VdIkJ?PYgJtwS=G&w5c(C3RXaj(AlVMvj6M;MEu zar0dw%+LS2Fv4@GY%%pM%&<;mO$o2e!AWF5c69boFZ(&4<++2dn%T~KiR;Y zn&Pb6`Q`u_Rv%7H3X6G%s(nYH=ONnEr7oJqEA3Bi1NbG{br2x&EecoT0$#+}+KF#m zK&uwCrj(y#OEF|+>|A-;yX%KHBZ)e@qZ8S-Xu?FaK4x!TlKY zpTydWyL#V_UgyJh@nQz}6%jzZl`>u3#xi>mBFB zyhyIo6Twp6^E?cV2z}-`NAoj*%#O@&W%eE4iYqWlYkae6xv**)apsUt8#2WX*Q$;t zFIPqU140{=@~GV}_|)H8KsvsF2C5%6x2|@EIVeo^H(Z4i4&hM&3pb5%8jb|z`T5d% ziMPH}P6=0^C&?S{e+jfF&fT8uZh1H~Vec;VRLCdZPHH-J+#Jm97IxgKNy7DR-=o@p zm}4!?66tQuuRJCQL4%1-+|9?51;2yuwi=o)#SlHQ+LC2TXRhZqw+XVv10dQ3I1m=;!91j z5j5hTh5dP?wpz7O@4vJC9?8m#SlvIX`7;$E0b&9FJnqj_kr;&K|2-gC3I$W+zXuHE z{y!|^l;YDkCQgkVL4J^Ax5%FrBo{ox)QH4qqDBFIITqyU@L_bjSDuAT8w>GZ@np$1 z-2yDLBs(Wf!v++&<}LniYv2=dS#rJDm5669x4^RpF;ejhb!v7;J40mC-3!|C0<7aZ zbCuBePk~`&vCDjmp+`umw)wL>M>Ur;KG%*3Z1&pcYW#M@kLn3R z&f2Fvxwt9!!vtVe4Kr)1VVT{hakxLJ=HDmzTH@yr^z%%Ca9lMiixy&*3+1~Xj!_KZ zu%wHT&m!**kf1r7$n<@mR^P?rMia$0P;|YHx;re<6f6IFD>n}U_V&2Yg?~9VQNA%Zo@n3Xm{?fP5Ez|alhbr zAH@h$-(Y<%X@6dxIQ!9sI_2*!imoF2cLIZ@0p-$)L!RJ9n93f1UwFM~u=>%A^O3&; z+1MZ+wR-wT{|Dlrvvz-|+@MeGrSIx25Ho*WE(mLG#sBNvfFlqcw?s{1_U$;@?3D&8P_L|B?T832ct%hP*#8mh|}u(Dif!-CQ%8N6D4D01{1l zEF~u^wYRy3M)BhF?rU%-rZ=GG8n0VYzGBI)2|JMIq9t(of-Ov8Z0qfCY=lI0M5$%m zY5YEGJ)^#0L@{rTTjDqgWDg>IY{M}*=i-Sj9tsPupWK&MgGN|egf7WUl1UsbC(p(l z&^if4m1!{g$qg%c+R@Ez+}!{;>2D_k9}9Gdgc)q>3KgF_b5i2jh8hug$oc`LDX3~C zGajK*%m(~G^@2v6P?T(2`pKPpqb|&W0ogg{{~BxUh%0t20eWC?s*TMCbTf$jaZ)TzF5=q477AchQiN9x zvpXh%PH^;Dmg3M`1Rr-mm2kLD-PLT_Of>#z-N?I^Qfz?%Fs2n-Y%7y+cV|cWru_Y* zl6nOSdBc{E)tl0iya$rSwrZI^dXw0T1@jANBuTsO+tqqNfsTE0G?LG|Qwzd#2A-=g zJdMfx>f4$H-|f!gSW-&JCP?@6>uk*{;yP}&&xJ$Od?fEXoSHvss{=8>X2NNq-1f&3X3v zA)z9myHCMaY&Kxfx9mwH83Ay)Pl3cjfksiP_34xFA4bGFg z#s@ICG{+PGiy?sKMPVR>fak7$J|s>(#QU#zd-vIspnUb6JJp^nkI5I_sZ_7^$Em{9 z1FxR_Xl1)@NX_DlM+d*iw|?4ooW}lrzcKoVY^pxmR9oU^ua1?=g9sv|Aym~%(fFhT z!V@nfy%1L@D)z>=gAQ9Q0h|dp%}kvB z?N^3jlQ;brgX8(Mn=(?zL`mGM4SKKE84}1OKEkQRttSvW`vUOQ`ye3@@q&`R6>*iB zgPljZ$wkbm<529E*RG{jk~_{-5#Pn`6v6J)It0tS?X0sc)*_@W7Aa=`qZv8**8CmS zBT5qSPUV(6y=!2Udr1=1u@L~S4EQ}YW@)MA&B?L{)ov&25z5qg{Q&dU4%8TuIFCHwB$8>>baj z64@SAefo_*$fEII>zkqp9q_dG94OaP_Ld`uwICM}c#wY586G9wA=-~?Mi0{3#y6rA zvrMs>3&E*ZbY{zWVO;Nxw%9P@$+iPCy;_(L)w1>Lm6;?Er%Sadi5_?Zw6tH8H{dCw z6#n3S`id(?P=r0H#qfck>7d-0rZB&z|9m2Xk1p2_;RN=+#C)P8m^3_Nc`m3#Sb{;#fN}Nr4qlx zPC0LpnUou!yx7=I`{nBPHaVe9Dy^oQyQ}OEhakAz3+oQ)TFN?LT?8MnU^ZokLoJFwTOLLoT6~(Xae5juW2VZCuX`%3fXw2|r5LFVFUaja zd8FB~ZYU=!vF_;!LiC&wJQ^j^#b4)UnYZ`mDJ$!9QUIf?HoR0m%`@5Ipmzf>vY^mU zRvjFh(8a(LmCAUK2ap|GNmnWjYu}wL*liz~SxmU8MW81xJ`^L|%;=t{N4M&4x3X-T zs{m!va-IBD#bD2cp+UdTdrCCnLjT90Xw2^RkHEG_7X&am{M3;h3RP#hP@&fA!Zi5) z98&UP?5lCn+pOm{mGwN3tQ5AP8&zhtf5eqP^j<0(_ZW@fm>(hwKU)4OH4?zrk&8In z2Bq+FsvvTINVAPO&8piR79~x2{5#vwCpBAJ@0$KdP0c65m=3ut?W>`>=D#j>pR4C)clJw5hr1F!hWDA+<GuEv-r_j@mC3jP%S8>C zq|X{@aHj^x)2|E1Y*DTW(G@VI>iF@wZ{Cdvfgv*I24^BQ;MP8Hh2qbxVhGg30G0co z6d~Y(>W7y_%{}Q@ftAyJ@@7{y{NSM!5;>10t3Y4+%%^{pbO1R3hbKr7qH22RlN;NX z2Rm%0-VBZhRi#G|)i&saW8(hME+M^YS#>m#j~dSHSyx_tYBigv{qa}CdDukHcJ^QU z*+}^wQNgl`TvW_sdQ_t?cC_{uxgpuUDreaiY#AaWgh#KXaTot3>&^% z+KJo5Z;54>=f421xslQ#`b`m>i{#!gO&*eKSyc%Mv0R3Y@)>w0#^S&<0;dUB0Gjhb zKNeNGky9hIo8Bwm@|MDj;Y=tje%3z?c!X5p!4Y3Y4puxR%UQ(bSFnVF-$$We2EX#-JjGcR#M8ld+}rOgj$3+?DCq@*}a4Vch+v4$t(TIO&3Npsk+d5RvX zQ~hN6s6C3XmS#1SVo7?6=FR7jex`s$1~Bpt8y^3t=SNYg~xRc%X37| zT!{VNtRrcQTLg~o4|MVz&(>a$LZHqa4hgg!M}N6&!je|J$0i$HJyMc|q=%|G7#eCq zs{iQ2Ng*AVQL(I<+gZ+NLJScGOuJDb1ht~Kl_h@ zGPc`llT0i=$K3hgY0#GD5sgd=(rNJ@K=9)P7d^S zN~@w852ZT%iykOxT%ZGxbYCa3dx_VqbB2NZNn+`>Uy)X_E@+I@6i<&HgGUZ!Tr!eh zraYG|Sa%KMXDRX*7N}8MG|#r;0@^d;A$xX`sXL-U;dw{?!cm=rCrbiM%`WTV`e5M{ zwuR_Vq)*U17^jZ?fM6kAK%DXY!z#J1Tn`~`9D2qa8!|Y@G?l>4Dr{jqe7S|ziBuZk zv5k|P76s9cze(8tyvv9DaEyKxi$(owo?5bEEYciyS6qx2w-z?c0-(()fx;t$C~7L4vsMD6I=?ZfB9!k;86= z6SIPUwQT{emLYpjc;bZlbe-po-&WJK%OK3_4g7=G=sv|mE1 zr2nH7gh58WRk{6bixEmm$td})6r;9Y*I<=;l9#utrb`>YksfVBk|nT=zd?K?J;t(8 zi8X2V*;bn;8Kv^#Z;c>>#4${Em8cz@ki<|$!9|l(|3EtQFGlA%*?wcMWBIyTfv`t& zrf4M>wz-3x{w_TloWNUNNwa&$8~OvKt*3K`a7gkZA5#s9aZ>LU zd`7Vfafu}UyQ<4I36G_}0hvUacXIzn^al9%F3^){7TNAo%Y@ zR22C4G-Jy1ix;0?yqA^M@i9H@ywxT&%s)}bjfi-S7>tA@V~wXl)P(F%q<5@}0PzJ(0O$_Zmj-{uCwNlt{?ljszHzdgn zzy~3ujKLQCDGu)LV5`#!Sf$rJT!3TimaLn3FUXM#)q@RNP{Fm-4c0QXL{{lD!-L-I zwR{SBVr178GM62{)A6QeDSGXm>v2TEA93+EMx|DIu^fIbfnU6qETI@RG3-bn_bw@t zH@c=b%}0qlJ|71NsD=V+`QD(`6Xg)lr&#!PGDp<-TDgv&U)(kotW@`29c$$6t8t8i z%9D*bA}zxaXqh<~@@5O$-i4<6+;{M|&v@9JZwD61Y@y$+5`pV0UCVGeSrSLArjI`) z5gr2~2PXQ6z+Rv(P$S#5@^_Z^kYkhG{an&0)L#Zo}FdNcH%Z&Urhuj*{N=>N{1I!T!5rJkz ze1L6LyHVti0l8C-nt?%3B(S>+$5>C83=lU<2tu%GST7yhJrh~DeUFrxk5~!3d~qQ5 zsrJ}_^CY=1jIgJu2Jv7?N*y+O{fBmW@ru?w?c%X@J**N&OmnD&Axo_sI6+KVe$lUS zFp9*i242qI=B^!I%q~LbK^V1GEpH!5%y_?zYSb$*h$eZ)EKp{7 zp_b4v$t)bh5zCgy_!MRP14ADpH&q<7#yU=V+Y z*Kesv3__@=fjF;=`=?%zSbYP%Jl?_fVGL};NF@P%(o+EApO^ogwd|qUK|VX!st0DE zbg#L4V&7x7yia2?@KU)4LqEg+h{oV`u(0n4BF+_x=mJ4Lv4V6sfp?SGLL;_-C1L&( zxwd}gd?T>QNVxeT1Dgx*J4KTd3_{0WXxzY@34q`T3)U03zlT3xExNu$*%R4dPFk%I z0a@V2)dx~U?IPi#hVRMnXz#a70y5^#;zsiKY^cers(lUT`q;I$t_%H%{49G{ z8;x7)l_1RFQToc?&u{%JHA1&&vkA6Kq+MbIkSM7Oky?KdCdrL@-A)AsR-go0VEfw6 z_O2|WarNo>GC+g+PLRKA_ zAi2;OFDxasa$Jk8gr>>KxrsWFsv`j`R#!)J@p4(~FpoSlgaioDD}ua`XU7>>dT6Om zqag9x_TDMZz^8{;)5x{rp&|$@(2DNYX})|PeCPmlR=K;rK}&d6pbW30LwsTtnVG0e zO15{a>G>R_82cHp1s+IZ1-Q*Ct9)P&9G-o>&?R@;MAd|L_A?67W&Nyo(4OXCAYA`rNwFnWorX!qVNE}~? zW=#9=_#n&olJ<4FhHcNo_Ct4lMs|flCN2aN@%=wAqFOp{!~mOSz!pE$qx&mtKVm0Z zd^|^FVrDwsvLM-ywb~uzF5k>&Q>4nDR!cm!at|-S%U$cV8F~;RJ+_zk4f(|>CI4Oi z*905b(T}r{Mqy$i+lP$~lVg?>lv6WvHj@TV91gDy!Iobf>sG}-V_lY<&M(HwdkFF( zKahWd%`Lr<>cwD7(Tw!mq4u$z7_{05ue>)1a%c8$nYHNak*IPNf04iO2!%Qh-XV^7 z3>k%2WmzqxI&cY`-93fyjl|xQbaYOIlY)+gThx;iI4s=tqTEeR;|W(CSUyx2@>yEO1(EvBZnF48%pQtWVXfE93Q z{y59zlSTn^Tz;uOEzukgGWVG2$hB(ck>-K=m(aKzDXep4rt-M8S3mw7Pcuf!UwAU` z{_ew>KvWbJN+b5>+~%x}7qw+#8Y+I@U1N&#tiJcAelZF|AG1qz_vJmv8Esi`^1=GKfiIHy7xOVCZX2(wjzCn>e-S=+WglXF$=3(6a2*WIz5Zd z+J$@HiFH-c+pq4maEU-NDQAiDRHEUKG*;|x4#D-4`jja`vgkgZ=$mA!`KKg;NPbwI zJC@fEPDJtiycS+qjOtQ~-si*!okQH^d+9~%hg=?-$AXDlj&L0qYm~&Al(NTgT8q}kxPT;^=sToj=)iO>$MgoHHS!9}|gHP_tz`zm}c~e71 zB}26pzr=E8Ax*yfAbUe(UfcZpWj~X%SvNr(fo2l$!elx(Tn&Q^+j;c(rF4bR{G>y2a;X zC!X$Xsas_37IyA<&Lr0@DYXjl$eY>^dR1BFEPql-Cf;2~RbU1cki#`2{}RrIwuzE& zw&8}U);%RZ7hQfSv8&Z+~^(PmdXK@lW7obhGsns?h?g<9r@4Na=ZrXqSU zhZor~vlsRSX--mgx4H@wB_hqnZ{;vf%D2B-9Jx|FHBkZEhpr;ml^dF*4)1>rX4LC& z>*FCI#~O{jH9LxbnZm4QgY;uzA*}K{Ksw771N2pV%7{OoiJ|!E4s~V+@GUL@+tgzc*QMeXz~&dj z*a^LjJS6kFy{IvY17_cuHg%=(o9iw|trDN-8&NYPu;xWEQ0#($gm@tys-jO4V&(fX z;YyiTq}pSIpfG6Hu^76(Ogcccusw=~eVRMX@#eYpx(%{3?_|PB`)+F2|1m<1Ub6vX zO(kx#Q2I41z#biY^Kb!im@tlOQKB=m@sHKX;eD1a_)}zM3BdPEm{&Ly)Cqg=+ek)_EHr^^0$6PJs+8lt(5_ieks!CtT%c~B~Zb`C`=obAmfiu$c{M-wKDtyhe@C`L}p zh!rB&VU|Jp%s}VqzcXYVOZE!c!{9POjI>33@MqXN5jg;FC|E6zR`A-u-nm7G3k-HW5Y z)@|BCaRZ-nqQ5 zp{+KTa`gU%Q`Z0?S1+VF&J=f(J^l8e1(!ZQ9tYLBLY(rHM2T1p+f$K4U|dW$Py;3K z#$elwEe9(F;R7!PlWf8vg^|?KW)g}E1x%kY4K53pDsvONWqE#5FQY^OkQlNokE)sIsNUGhbFc+E#{ zvFu4inBaovq#W;VsH?%u~w_Nq7` zwVm_1u`-Z0{r>bIXz^4uk`XeyIT}asN#dg~!Y|9+^m#Wz!9=V5GZDYUhM1+pek*5G z{pI$zk5ibd9}i*qc5(h}M$qUT`ht1wDW}H>isXLN$g~#rIh!y#$Sk1i&@URY6RzjA zaxCsdt~DS6n+l*(q01kgO8SyvhlHQ>1dEL$e)Yh>$mw6;Hw5pr%gOLo@$?TFxBetjX62jZm6!BUvpqJjQIzZRTAOqyhvJl&b&V54|EhQ4YidpHgg;3h*@e9&Br-EMo=XPoz*4K8ks*qv zucGs^gEIipdqR7HGa@w;xV@Z_aC*cvzFW|_n~v2bMY*YWwjFaFY49ANc1o@PL$XZC zGHK)sF@3|uMjbq7JD8BpkPv|WK~ujmvvXL$TwqF(eIKqAjS*zITW zAoy2H$98xnp~ZbPQfrzh4}Lv4gh*jrKQuFkyob6uUq%UJHFKUjt&r#oV&% zPuPGc`|KNZLwWgE$$FK&-0f)`ZG0g_`audcf{uYTZZ30`X|z#I(bg~}$X~4;ytjeU zc;(hS2Ugpxi2&NDr+>&%c(a*LSe!6vX~mn;i>B}D)&-PQtulottn#CJgRX>bv4j%K z&2j_DLikJ9m92*tj9;*x!5Z!SOwcG*oF7mFSQ3b%Z%~>~@KELR$?tohqi0mUw}=bfHoVCf0k3oX{gIKpj>bqM&cuXo zUw{5wVTEpdvA75X{(`sn<-#)tkZ35h;5Aj>v?uP_77rTs=B~ zy?5P_w{|$HMMpUP?t|>o?K~48ykrsCZr3zx()!@cESwBXj+cP$OgbvE!Fv{&FAcWb z`kBctxSqHMz*AGAG4XMuPBw_1CD2Hq%BdegJ^U3NoD4cmyYm*xFL-$5BFCRsWc zsM-cT4O$X#|12=Pyfou54|#k}u*1#3l1|p?%T^Q=sUMHYiAxk3t+|%W@8p;b*$ORE zo1`iL4zRGAf8ql_jFnYwK~ACf29`mh#Is2jlc}%7)0qKh)Cli>u;6`a zI@`l->G|UN&u$gQR=ycQA16+zX)k{$5WjxJFP0bMv#d<^T%6>gws_N#MXf((pHVWQ zzwg6Z5{Oi{2=`h1IkRB471E!%X+MoqJ8|Pc-bvBqq^M`Sfh|FY7R?3+pCX|KcrMTF zm5{V8QvK2+E5Mo8ysQ-~@*!`p^EbRMjAgJR*>8w0vG_?=-LXbnZf=u_9xdPpdLSUk zxtynN$TMmPys_zmHaf)w;Sxf8Nyl|&3EAB3=VAmf>iJmR)N`TBSptr{If$*^+oeg?YDwemoKwDO=7=DTn(X6R4H!|yizM4}`L{Krev(Dd!kM4Sxmp)FBZB=h@~e-Qk~e?SuDKB){vxqhcZ zE{7126vf24HR*GAg(i)7wX{wN{M7DA3`fse z>EQMP`6g>&GmW-(0F)!j7++s#{JW>fk%9d?ctzYa3sHYdoHYytiYca<o4@H^z8*NhacgWx-E&ui(-XOr3v!YY44B4g znXoz~@Z~Xg-#7H*TSnpP8G3ycIR=^SY(473*|n=J>Z-(@}8^|4T<+|H9;Pe z?eq~Yu+42Hp}2Mpui>N#r2NgJmiNvPuKjgc{3oP78`q%a%^vy^6Ze&Ve@UU5%XR_A zKV~J(d2urL66`tCYsT$k=uKo@lfmZ)vzqGjW@}NlpjmD+XkS3fGwJF`@*&708fa)o z-?5Ax_H5EKbcQKWSgmLRUG#g$vg`b=o;$3`Qk&huCdjQT2vpug;@go(Fj?+V8X=Hx z;pR7*W}8=U^LG;ou<}SnPa-jspKg|6$Z6RQ3~pk3+bp=<#__+fIh3x(@ECBZHpm-0 zOm+lC3O`nvq@g443Ut_|Yxtl=Hyrm1wNR`%6MeCJPE<)*8mNT5Z$Otq7TZaTRYCj8 z=9hp;+sHs z=zWlC*`mEd1a);m|bZW4UTPcq?;FtsfHM5y|p2$AZ*{2&(e*X4no}= z*qlornp$_WX({o<%7$kLpD3%8Q|ZYgR#NBgC2b${K(oxqwe3N}0W8i;|6uH(Y?8!} zLw=hWJ*)t%g1VWuzBO@1MS^7oX)-&W{u9>WqY0hx3VP=cLW#mh6aBJt->jTaxbCuU zSBhA1zH;AuLXiTzX<8cKV|P9P7(RePYW#puJum4BlV!OCD19Qg$gM=ywR8T8O$8|$ z-KJ*k6KkHKEp)^Xr$SB!2{oMU_!+kdtp<9L)kpw>)D>BgYZuw_&mPPCZa#vV*vag! zd&F^SgEzc-_w#)s3n;LlhMK{@s1)4n%@I=Qe+--SUaI5vmku!j;+Lzkse+IQi%;|R zw1%*-J#EAW*Q^b}Rl>#Fy$*QBcZBVpIit8I6J>d)gQryp{w&8~%@24=|5$jkjAnnN`^j#VeW zBPp0`-Oe&3Q%W4*<%}eUILYenV(l^Y5)<4gvR53)UnR#o(T6 z`@+*+$bAp(vR^y&V4K#z=&Vm8}?-57N3Rvx_XACxCVIrc*s2FkOBt~cM z`asaKZrw@piObLO^b3i~{bTacy3Ozs!q5;*I518 zayj2hl-4C84dJMdDrJ=Amkz0`Gll!jD1)CEAs1D3wP6tDKbrTX23}{i;M^BfL&8_j zwX8&O&N&%hE}{DvO3cB*XkX~>(}{_O2qy~DG2m7xKm-SRL8 zPE*}F>SvwIP&+idD>^q^p}cUIo~_{1=(nM6vh%a0I3FE(11k%(a5hfCRBn`X6Y;7L z20{^2u0y_h@z+#Ah48JPy!xzx(n{Izs7iX_nUQ`}Z3;+~4cs;m8gg%SWEAAbmfG4s zy_Wm*(4`Scqitml#Kj_&V}E*Od=m5?V^=8Ae5)?g;`#aAr>z*!bJJ)@JGv2^OMN{x z-3)_Og72*d3Rucc{r1!ZS4AEEbR=97aQUspv8L`NtnKi$| zB<}K;Bfc`F8Js@Lw>@B%gjs|%7l!9X#jh;CZmU|*1Y63)`Qv&IJ!G=b@4I5bMlz9I zO%p9nuikIz0|sMl;2P~--auNyh^C`wEc%+1A|SXc+s-_WAV>=C)E=1=fGCGp1KIJ} z?NfMN3@$JtkEcBUxNrWR!DM1u-5BZPq~uBhqc74# z^OUM-q^p?VhLe6Biu_5af@G&KoTEndGO%j8D}?48POiVM*$rb8*dVzfeOvXKKl&!O z?nPpsTp+z9My9jSnOC*yi~8(SC~q(u;}roroRZ3rH*YWb($SGiie+xdDVam*WOgz{_EU$&PdcV)>#o*8m7}TRlBRmI zB&0(7^AMw@+-Sd=v2Nj*a{X$SZ`p+v6G{CSioN1FW0MEsdWxc>TM* zSp=Z15-_i5D6?w#M-%uRvJ?De!?*tU|C2J)>Y=0Q|2ISK&kFnhid6p>504T+`#--8 zc)q)(c|dVVq&DQifpnHqQK-%KaQXXs^^cxPE&gaZyIX8*Acsl{>pblc32*GEN+qdBX48$=eq*Z0r{v3Z{jF zaDvTT!NpPluvjW%ohjSbp%+<{q>1<;^wc<4KHgfd&W76osgE{G--EJ0T+h)lOYUzZ zx5ahY&`qEI`~aNb;(ECd@=&~p=NQ{KO`jQfO_BFz%r8zdD8_W!ZA&3~>C|g;Uh{$P z(q8M)>izb6kwh*udE1_npJbT%6JB?!am6tyWoxC8w$WaMkbl$V5}J3oW~^Cpk6`Ep zqWmB`soxpl_08Ep;1i5>td&bYALKPrp%w*=- zC~sfFb|E0-6kB`oKtm)G$5iW4SDb3hW$?1P+CKkH#I)p z|Bc#~jYDU0@PV158;;VC@~S;1Ya^L)+v6N%+#gw8tiCu4mAXe#B>#CcmiB>}sQmW* zQQ|B_09Mh0mhE|aI!y#=xkD9P73k~qY{|WOJ)2-a2G=!$eboo34|Yql@4;W>%ss|v zmqAVnpMm&OBxzm?iSOMA2%<1qb!s3PDto+_{CdwBpin zc)?hgzVVM0TBWvnM2Tdb3vt*zC4_m|SB?HYhTd3~Ca6zDJrt#Xyz$+d9 zR;Z~=c)TmD`kT{6h5`sxPSv2F($7l!tlbjviC4himusklHZAs5@`dmDhuN!*1|2a= z)m}77?ILdtM|QcoI!dBfTpP!gWF5byBEl8|wHfyp*1&7Zn$vfHFG-C?U^)PYC$$+q z2wlJA`!%O}#NS>KHkCi7ALD+k8=CQ9>*yC)o)~_Ndx&zocvFnJLj$VMxp!v-LS|?F zyi!R3$nH3Ob$k!DgrIB8^F@q|?0z^QGt@}>;=oMg>p~FmeGRr`Tv}IIPrh`pczXH+ zQ(lG0>qJ%h&Cr?oIdj|}K+kH0gU(#@`s&`RI4_!7j~7W#Ygm@(-$0CBot}$Sm^Ba5)!Ah~}$}ei5AInxzmZk@!au9#+Rvl872-`CI%# zbB#C}m!?mJO$IxEmTIWfoJP9}r5EfObzaA|Y+3>#IyZq>6-%>GI35#rYGC(2RZ7~H zOH>^7yg3&Pl4hAnK=IM}O_~PFWTGv92}NnVw1mV#6@E@P6Qw5lIpU7>iz+gakh8Z< z4HT{%i5e7}%NbhX#j`RFzM#CJU2J&nJG;OO1isKFSScfnqJJ$r2SU4#bB#?5fNjBeOaCowZ0m68hEi{7X{Cx>La>P4!lid6xoEs>ubMFJx!vwR1St2?O8&Cues9HCr3kh>7q-|$=|EPtg=ZwTP!f=lBWy)H%F}b< zq1aFbY-xRV+T{{)KhKD|<;n=yrx8Ag zI13 zHUu{#vfN$_E#?Jr;g-WBWDs7tSO21n%4xE*b6@7R80CB5@w+!NT4l#9oNE-l7jOaN zcN=G>l|o|g+Gj#v&>A`QON_VW&-ZzqMDfUyfWmD?%7M;koWlzS*NHLxecw}MjPnEF zWv@ra*1^9JwL1V`%ZH4MebTMXlEmmvf#=E#Un;X5IF4&2)T~rzH6sS}@JCV4LO)8x z`UN{2#>_M0@LU+vivbSwQ}=xycE>$%AI+aKVsau8_~K>SyK*wbBPfaOaqqTu*b&|G zx8-Z&Ac99=FyS5KRzZ=J&T12H|CG9O=4N*^pmh-r=|Vk(S0AbANiZLL7?=QVo7Tc& zYNqW{A*HVDq}%D{O*3@wPJ^?4!pkUklmG?%!%=fPfY^f_9`=C}c* zH}C~uZVj6{a+EbOtO#g(LWi%(4cWy*VNPueyIsuhi;jmAvC-mjrek7&H+2i|$0m=3 z@O_hFikp)g|!Icexz% z?3B`rfk*x%&&``zRGkPqT1^~vZK>s&BcLfOOYc9~-ZKE_p~b{{sXdP*2VUzY^lW$l zh1Np6{ZX3_yRll@u}(cY6jT1g>sfO~v&UjdK%Bh_W0y5AS`n5RR(?Ls%ino%VP=c} zZ1%%Iw+zV%%s}6D)^&#x^l?bC7;OaOrJsbpOd&~N;Oy?;N~`T8*ID~nxc3cTGv^zF zB|Y--VuD2Pj;C@sDG9ZIoKnJr7e|~}P7uAMnNrHd*-wM0=VbiY$Nli3v686?bgj;_ z-!~qi)HJc^r|mfm{@dI?GaMAEIDC3{Z;1%Y8Z{~)cwhB`Jwl1&R-|HtlXpwXk{B3D zs1Z|WxZST2uJrT@{LKhHnU1e}=D!P!R`_{;g_yV685N*gwX({$M|z9qib9dZjw?Ym zW)*@D{N_!blE_7;z-^K0PdzepY93N;HtBm*W)899<$)zdQts5uXpAs z*UL-Afa6#Rmy+s&;LF7&+ZE+^x9(eRrC$*E%MM|?)UJD+^abQfEQY%d1wv-Fkf^Vl zzp+c@m47# zUt7giAZ4R`f_r5xY2dDCY%4fV)C}PCM>Z&y zS@a-4BiB5irU<>KRT(ZrNQ7IwL|X<4`s^ONhoSVKLJr;6HKxdqx>yxr{KFF-&B?MM z=#1WtEE3f+fek1`E&MDZl`=B*QPnRv75#NHP)7Kl0yIf2r%zew5&4jjZwyi+Pv}T| z7fi#VGFANf_s=Fm+NtU~{j-r~vt=2sgS`K9$mJn8V6J);7 zXNB|$`(3?&i@-1GxdtjmcXj%;{vsu?S1R!<^3iXhmbdG3>|C~HG=tys zH=XhpL4fkzWH>41xF(JZac^2?aLKARyYbJ`P5Kl`F}rx%cxv=VWpdrcId060cSY`@ zM@>a#o4hh!B>~QAGs#;&$JzKWE8&5{*qa#M9E^K7wxiy0{1#ri`kNbt6Z;z%spC}Y z3AW48FfRc^b)za}RL3Upj-dFGG03mx8ea=8^X?b8#V;>v;J zM(ZxA+S!S*neOT)94N^VnkWQC=|k7=R3s`cUTl^9L*1Ad(BrLoCsJctpaJ>72E4rG z@9H*}jUp_NWsrJJ_R4i*@QC_Ppj7b4NCp@{ePrE02%1rEzouTYmD<=29fLMCAq|?? zOXRN0k|QZ=4si2SDwkcVtwL}UjY(dR>9 zlyZAxji4{8?Hyz`4V)c0CRZ+8t88N|d)oM*9E*^5xW+Ydp4s>ooXxSGt@*Pa%H77n zr${0)d_==-J>OS|6TNLDIFUw38p|AX{J->O-)viiqzdP0eonk&a59#sVH5ZX&LxdC z2_b==?x{RP^1R{*;s3iahg|D?noYE0M607c9pB`7R=k zB0iswywk_x#r2C2-SXeL+CjrNxut()HO1?nw`CQMz45&~aSa5|1u&lhO*%L_({ko9+BO%P#a9Uk0JcC*vna&y>CtGFM|x3)FktI zV{O=jyk!4oG&R;ZrO1d#;y4_E*9u9cxf+F>?=EmQeLgm$_9~+?Vr(;`v}kW!8EUwX}dfWPoW^6zJHp=5g)ZI}Vvm$))f2t#keu% zeslWUS!p$dA3RHCVU4-Z>0^GX@j?f3uh@WG&4knF+=ODjdzirQ`_0w$MdSWA5zPAz zMKC_SdVGbL0|N&wKL^saE?r--+_u~Ow*!?jga}TKn9kY|3F6K^t`1OuewmU~h10Jx#$ zFAt+pQU8+Q^BS zdbqWtbHU2P&c2SgKnRB1z7X`dOa_IS|C*?^IyUAf5s?xD$o=yQ(Nz@DuU5&1wl2iV zyiix_a!TxDw_9*~ow_@kGBw*j&tJ%}mj-%y(Lss{i~lKo#ztI49_uLem;fVxPD#0~ z`X+o^#Ng2|ii@rvm*c#4e+{d1#e*rOV@;a!&C#gf-Ks`^PIbB&3STUJMN#*=fQ*7| zXZk(ZJpv;kFRLAS=?i80naxd))A=BE@IehBsUa=7k@%EmuW&J+u-6FU%2M@jxLv>0 zEakp254VgVP9K61+{&?kFR<#Y{-hlkAbphsObgJCtrp9j=38oHS)un*;fCNCSXs*b z>^zt2xoqL#MZqdyz5jEn^U#}#G0i%Vy@6ET&9hVB9lc@zFA%yZEkkhVD?dkLwD}3I zjs)_+Vv^kV!KHFeF?nJh%(d-323BtmY5{Au!r7D z;H+*sl#wwuxBV!1mm?3Xl7-heRIU`wBvek1_X))o#!G}uG?XTD#Owa1m7IX&AtJcJ z$3YM`BKS6g&?TR`9#QDK9nj9Kzbg07+2o+s^|k{&A&3-NOtR}MWR@V~)BtkRkyKky zjlR(#HwM+>cvR3gTEbjyTe#vam2d2sU8H}oT{BB@%z|UjPJ+! zn3RH-Yi6ftG=w=)VChhXJev!#qQ++qBQ&cFVr2Q5-kTI-ELPOxZl$*J_{hlix>P#SGIJT7-C>%n4JX`BHeYG7>4L{AWT z!xV#$$lu53=trV49DS3yK+@f;w0m6uE&{xrHs+22ur0sp`Cn|3)1))jIE0q?-8MyP zOh34SB7qO@ z7?@sBf3tf~_;}Q?CbB>TAOiI>70R#-!dFY5FVWHd-RJV)%_zLVMkV3k$n@(E91RIv zpt%2)$i-kW0cI>bs^%YoqXR5XP8j%U! zS!sD3;Ow=WdnmunJE7q4h<~*TSy@s@W&*>R<|iHtvf9|o4}HXrtSSt1schRyO~yy= zC4Yt-HnM=TOJP6S{BM4vuN!;4$QDIepId>qCL`1SHOOROG57f+j-SOy`W(pM%^>Da z@2mK5%pd1pt!rDG-#h;czpA-J4&OdhLDJAnkpa)>BYo*+XJ3e%o4M{(^1!Y0G{y~x zwbe5uRQeKA+5~$HVL)IZ@d=sDxqO=9IFDx**C*(MX!p5-oZ5>RtU&P0R&)WAnRP50 z7Xo~W#ok*no7#Buvq%=pI^`j_={h($&lfi8agtNK?KBBJS}7>&Dv}TB;WOv#W+zf= zZ)7Rgr;{`b&ctU#H)<+t`z`~HDpid#{o&_rgPOj8pD*!!zVQ%}8yB&;(UD-?_bq<4Rbbw@&?3;TIP-OZb%vjE3lJ!=uVKLF~3lHNT zDptaOIWN_8!1#x7(j3!=!=CB?3nAAW zkn*<}o02-iekVj;+fay5B9^f6s|SfmAuE{;{8WOjrFGOnm?E4v!nhJVTE9_gp|%E)LTa>l9L zVyj1dI9m^bq=?O(eLL@wTh3k4onoqou2W)+g4C_t_jtw+8(<+l$vwJ__9Y&h2A2b_ zJT|w)sgy{6Z`8$uM(=q z&vkwZhaI{lJ0wOw6L!+NBsTo@2k@jb6pJLGM`&V|QRQ!u zmJ?QKPStI-?jFwO(z>1wL4;a647J@O0=t)@vFxt%ba>pK^WL}!KUnJ6vsT&N-ZYE-b0ZZl;*(1n&5!5G zh8-^WvU~R6>{`Ta*m%872{Uo1VOjhEF?;OLOm@*w1P0N!;)qVy!(t3|>z8g*y<&WG2wH+$ZSv?BojmM8~oCB?G= zn&w{71at|7B+nDab^1s6eMcdbUsC@>8P1m1U$hr+|8fm2q)}M{r)xRnQ=_C$a0bB% zkKi3bfY4+QsogX6YhAc!EM!O1NW@{qN7~-n_a5Mm45yoPLmqks&h3j;=@so_CCO9j~UVeYt^^tVx ztt_SAbCLYqh%EWNES`gu+%GZ%XOd2#*aeizHsI1UmiE`+w*J5I+Z@A!s*lsxo;3V> zG%jh}Fw!`7Oo0_C3x_`_F&PFw-s1Li;ryG4_1j@wdkQ~quzWXdD*P;thZd6bg1+Xn zy+6uY{#cPuG13{?+kYP?JzIbbE4$fz{A)4VBPij9F_4<@<*5b5_MP$D;`Z;p`1eKs zMg9JN#QXmD2V~)G(G=shV2Mu*Y91m8HoYFr!6VzJPF?Yy0gu2F`=N+wzjYGMma)WS zo4$tmxXV}CIivWYe|Jg!$UM;-jM2NMjiAPC*Za#Rd-w@Xd8)auu6<$?tpUZ2`Kf^y zHAguo*O7?86aHQ+b!vo=feSzdK%O|{^B<~H@Ez9NirrYJ2L(lJh7W zF|uDk*qj zZdfFLOT|%fQijL;i$*0c>rpipzR!B;2(e|%GN0o&X`A{7lB8;&pKngmE5D@jqu!=6 z(pjDA0U87Ys}F4O*&-=w@cTB-*!3g3xmf$9hz2|`z?H4bht|c`l928e|i6B>OsXS@h`qy4fub> zmoZeOrR;zEZvxk2atTSlB52BCabHReG@RLYkltdi3tL zAs^u6aa&v}uWdb55-g!AXPg(RC)AXLIL zkJRB3QX*Qz7|te79M*VbO4`;zR#M50%DvAayat(bRHv2cUlbaOtWFWycSlIhV4~GT z3D0~qVl<4d&NWJ%VZ+O>dFxbyKG4zx^^$e*UX3$KNS!9v@%*3x%pxcy#s!`0KDd6p zb(gh8Q$&-Va$jUzew~j`qy)W7pBu$vA5WCPk$ePSid!nBvhdq$dTPE@o#Gv3)C-fz zj*?=V+nnSh0J8Gp4{d6nb;n@dv^S!LVcc;T5G6j3EIvBx;dj{{?OUdtQiQ&IW@bZ) zhCIPrp#kDiac@;KUsQiG3@O8sr;g@n?&wy=A|XpnbP?;;a)l2BRk`OMA7Ayj1%uYuP%X2$gJ2rVkl$RHoed*S%L@+A<6wt~UVWfg6}!C9_eijaqjrI&+B4 z(I3cZ(+?ILA}&7JAvFEN6YPLnkzT*{8GBz>mNavG5Y(3F`vx-3dToG_PIEE|tmT1C38c(^P&(9+EV{X28lkvP3WmZ4!ica@C`nESe+~dyZFO8%)z_!`* zbuDA>4ag(S4u>P$9O6GFhVImo#7sqi(_d8NUnABiJlsrxSZ@k{-C9xT|D2Alv}4o{ zbR(XK0*u9}M5hA~pE#K3jt^*O3RFD?LpAgFz*}ZNY;*0pw}fToAkxzwa-rv(r7w1u43AfK+4xk?NGt?ZgUfW+&|{U zzm~{A1%|${!{Yj!H-4bZNrgEFLSZ2ui*R|#IUb~Jto97{&WSa8Xh)B4d6MuVMO&fW zjG$wE+6d!hN4lzVY-hDX4`Oa^8D+(cW~zIMbr<>xBG{P=5OFu(nxL5DnTOo;}Oc9 z4Z(I|b~W{06*}Nl`TyeWEra6Rwyx0#?hXNh26uvMAh>%&aCdiT+}(l&3l@Sk4vo88 zAR)LkjeA3I`+Dzv&iT&!R^5O1-k)7v^;Gw>=A3J;F~%G#NG@L+ym>Hisr|$5^ZomN z<(2*x<`nMxP0q}GCqkeG;&l|WY{-vA%X0YaXyonsjlB<|@yiHKH$jb@#_t{9rLv-R zNz^N)FX`yC`koYYOv(HyY_YD%V73sWtTA)EA4G-Cs@RG{;%_`{3OWNyCr}+p#?iBe2k$2}8gUFPQW?hneE9Dbne*#v-G1c#HQD>Gczje-qHCGIYDMfcKehR`BuM*g^HGq&W zawHkx%4$Iqz$Ohwn|nLB?N947m3bd;T$Dz<@34!ehziI~nC7}X=Vn%f%SEu$d>*YZ zc0lwb=Eu^SAVW!a?7~uS3nx_dnsN$X^(kLG1eh($I4KMo4AqtR)O5|Oaj(brVc9I(|IOD&$uD%F+T6)A42{7+vY-y}0C3+Kz zJr>`L^fvANo^YxO0Eu>70*d|K$G3W7P1yKVOeyck7dCUQzr_k9dIBEzr0ReSy8=*m zXl6#4K#J95W=eT&gFBMuF|XI|pcI8n&GuW+=Y^w^ZR_hC8sy8zpFZYKq=MrZA8DHc z$QUj;{2-LV&)&h@J zm|vWRXNJ|cX|={HVHQ}afa{Y|hNO;%kp4P3il2%lvR@9J@lq1Rp-_{<-@oat7zw8@ zM9wVvr!%N8#-1)plxt-(tVo*T!x+#$FY)uu*Nb{&{UFs9!5#FEH)Drqip3Qg#chTW zS%^#iTo7jP$boCRdZFYf8ylR{V-zfw@+fJjW(hx@JF9Dm#bU-K+0tok~QF=~a~xm7&?WR~BY5 zxEv~jPGkB3S($rI-BQoeqobJ+RSbml_25&?9^^(nad9cOGx{by&y&&h_)>3tc~}RL z9^^wiIc2MIOT$_8&bdUgZh}+tFBUXMTbKC%!!Dar(oqa={PD*y6ptL6b!22;j)NK= zS=bgKFH3jWWDFze2Irf0vPV#;zdwwO?^a;}!)b?qNI4E z+%suCKdSSKN7vgT*t1p&lWCP5_(L?(1 zK2BKBfgLFqPOMAPoR!q#bSt7pNlJlZqelm1`HlIM1->+jgOK z`pR;QZw4NSo3y~x?g-9C-+vlc4*Uj}Lu?c>uyiN1WKaX?&NeNz>f{s@rNJZMrq3>= zOak!@*4R{#(M-<3Wsxb+VtrG&nN*!khyBV0>b98=xbuP2d8v@&6e*B-l((S>@U z{+kIm419z;)xZ@%A^#$&H~x#HhHLT?0o@}S5>BW&R>WP|B*W5Sl3HK|Q9-k}rxClo ziPwKo)E~~cwEjg=>vB4e2~1K5FCq1FXSOdUGt0?0xyS5@+ECsHpMLq{ZUm8h89t-4 zad2S^4C;->VR{uU7bwY%wKkBjEV}m?_$n=p!?jgpY1E3zpuE8ARJ3_Aa9|ucv(DZg zHNJi7>)|bO$8inuBh^6X`--AXT#!K^ym9<3*~(%$2k%}&aNnGjm-o|aVy{ew=^AHR zbEwEoM5PS&-ABGTu};{??6<9~otYR^MDwnH z!H8L(wp!7va$$mK0wtP{vA@2z6-%VLn6)Z_^Dxa1o4z|~(kS_Ggu580@_e_^r1fvd zv-Pz5yt;`1+CW4U*xU`#S6D6o30*(OS2t^cMSlRJCHAOEynNze!f=E0bLBBZ#{;@Y zcn0o}nd}>EbF5ENp#H%Pgz`t*+#9Xng481Q(wVOUBBWtLQ?FU@%Mfn4dJDlB=}AF3 zt21ZVzIr#%=k8Aa=a`E7Yal8YDJ^m+LSHiGOJ)qh4=7ELTz_7j>Hp&IX4tvQQ^bZb(u*lPSj*m2_N0T-d}0VR4$LfR1B2`kamAom8_m|aKY zS4d0u9erQAhnoT8nDDo=gHK!!gyAfj-SpF$$*wQEl@bcM6usDd7=*-B%)dIN!GhMc za)Epa^Q>#q88Lw5P0ZmqoZN`WLZ*0Ze(H}zW!W$AG(vZbhhR4jFCQFHs4fP}5QLdr zWrqdmjhm=6Eg#EAjZHog9*`X*Q@+2xSCh{I#*;3}GEn&Z+{PS6cLsJqGEzC{4JISz zd+dh^5lzE5C?xcmQ7P=b2BT$&8B-B5Rf?&KJYrWBOjW?=QL0aR0&C)^NsYz7`_l6+ z`HkCM(E;T9Ptkqp8>ew@UUnOF{0s^uwocvaG{Jak-ZQ9S zQJs@5ND+R8+Na^oj_AUH#G9f&ioIoyz4tJ3Q6*tzSyTj}y4faQ2PFH_@g&V~Vzbl! zyz4sS8?}Doy3HZw)&#>us2`FyUS z=DZyh9aQ-hFO(1WIf)%PfH}gfmmdSWc?VjcSv)Z~-J=U+pBP>rLevk(?m<#!M3elO zOq3q_Y^>xiVCFiUgg>?bKW!n5&r-(CFpLZ5n$ui5h>%JV^L=d!LU5*!4>TBB$ATWL z@gOjF5Idj&>gWXAGY2mhX$-exs5lJz=5km@QkTnBoOxe9F5#<&Qgw+=WEyWmqRfKM z&@h?mt&J^%E}QO?1R-OT5|(*B!w+7Lo$vN+CdaQiDVpu$jTF_NB8qhudl>Y(<+S{u+~^5JH&uO_=wm`j z6FK`fPL@c#cH`5}MyJSZP&YLs%=9+j)pTe6(NmY-qGzeT^$>l~{7T<8F8d``5@pU$ zedp~mTRLiDPAZ>nt!B+PbdeL`;n-<-*aLkbgA(EO|FUsx_MGWW{ z+K(2n0*}89GA1m6GEOcx;;3~xs zAt*0}T`zv}oSZCk;;RG%mA=CXkl*S{|H>5h^!N^x2adNUe_R6g$*B195SwT{1CmefQ_o`qWhy1SN8=7Pty)Z*T z*PZ#eB`JU0L(OfVjN=n4E;omn1za_4$@1NILphV5oTCE^0`j_u&tc03km=~707Nd! zzOAxGu<*%Wi1?smg%NMi>-+Ykoj3^kk#0~gYwQ*ab3`77$BiX!>-R}jepUdGd@@we zvCwZcgD3wjwNNjzt^CfB)zsWBK8U8%btjw!bbQ69?`Rt9EZd2XG2DSe-A%k7gVl-u zsd;Lf->Xs>M0qY1%4%S9;%8fF5|LNt3Pdl_Y^#t|b7dgVZ`NH0m{CKRb&2CU{4g8q zcWG;XfF+rYY|Y-3O6=U?Y`y(4aVN&z8(w)M!^S*?I0;HMnV0m6-d{(}_N3rI1WDWP84e=0LYkn;pP-DCI;CFue%6WHl8lX?Btbf74wyKm+*Qr9Q)SQ_#i(-wIV8LyKUFR!C2u31Sj-ya>Y;-`w6P%2er5LWWh| z{Mv?S#=8Z!43t8H2$Dk2@Q~Yr+HG;qZk?{5S!@w)QR!S6VJfrB>|e1q1RBWM z^!)gRz)q~Ythl1SQ``JnD8f5(BPR;o`5Wx0sufI7pW|q&mXC5?uho}6Lpx}O)tLcWWGejTLQ$PHn|ke;l^Hq#EMV(4tqb8M(hm0)VZ}R}~TPx`t|y%!zuTBDZR& z%tsuCPTIoUUT$i^8*_Or3FH{r38OA;sk-yezsZ8L{HO2f?~=^=j|7BY#0(dhx@}U7 z9W!D(KW$bD|L{L#Otris*O`k-(tN!m#$wHR`vnbf##>5nxaP7hv^rQ{(nr|Ou=`Hu z4N~ph!%HyXR)433`0v#~geZ{tSu&=W60Az79sR`jcBjPgv(5%e7tF~#c%4_ zf*fK zw&|@g_*-cWug?F(UG^LwPVI^8#T@UOfhDmU`Gg_8rX147ug3|M15p%CBh8knF=>9j znnX#%#CWy&3OCR4-BqwUSYeX)i87rk&fOfx!@F@ohd3O3^kKjOTV_p}O(DsiAWtIl z2xTzQ-&6yr(5Lgk3q@hzfsg`A(xDm2m5_R2h`eS#D^82LlzNuAs*l!;gv%hF9VMF$ z4j)EQsX!3rfO>o~WgC>9zBl)iGYe#0FSWVhUVe{Z{F~3L6a7IdiUYSJa=!-YH`ljz zp#|?ZlUePJpObwa+Fx;XeNM26UI}gkD`ye)KL(Yn$3{_G3|K3Ol|N<4F2qL5^%V?0 zJVyQU;ZfM9-!OL)d-{?Sjut_ioqchWxhZ_z?X(!I7V+orj%-kc5cmfMz*u+a0o8NE zg^{u2uPM2>X5*Fggrh!tn>if3_M4vnTJ?Rwr@~}jUkQlAK!o-fVthi_kxMG;-S4#L zVdf*F6Z$Tzfn!$q6xg@*{iQN*yLv|e^3|{X8QvSTVtDCxq?Rh7F;>_`Xd4*)9e4G~ z{EP3X)hV_SBsPzEL}mSpsJ2TDOsm(mU;bT65=-a}^$#MrH>Vw%suOQfY#x!WCmMg? zm%f3E%8_hblB4|^GkZ#NvrTKB(`7FA3KQy0LIiXuU#G1S28HqG5jtYf!t+bBf~%{a z)=IiN93gqkH^TYrq73OR4?T2$rgE8W@br{wBM|BM#Z1j^-e8y+2dXzGe_&hM+RXN2 zl-({Z%gXhO{iXnYUY<46ih|O)&5L$q-(e=zkaKonTa*k=1*lyp3MIg1@* zzkQ6ayKl0p?Dd7Bvm6domdj%p2*Ys-g(D#^^nOY)sIOv*VH7iLXPRT100X~!6NU*3 zF#06sZ?~1R>_4G`%2)SeKd@qU8{@kAry;8%yFpz|mytfUNnRIzB?U%LT?@MX)Jc@= z=i7NBO%WaaQ4&Xg$Rv^uebk!e&M*M2YsSU#eGhDm}olZ!ce|OC+>55E`3VMifu_GUWAy$ILHcAVW7#b)3dZ z{A58ncuC9&o(8NAfs*u3j7t4_5!#Uhv!;sRRGsLZ-^G^@`;OZivLPAc;_gn|Hi2H?ObxAUhPV+#p(3-Y80;2=KzsU)^J<6glL>j}+?Q&_mAcR&?ERp*y3g2Gc%pMZaCwBF7{zYC4G;{?hmTcEKIR3DxW^lS4zhrlHGA0< zTqkEBwcOHb{0YM;Cm)PV##lspcpq(m&Bf-o#kC@Y4)S2WdgyGBGW99{6JP z0vv=g(`4dv1n77p6o(PfQ7)g!u+pO9UH6>`gtDpF+r{dWyBG5D84)~r5sd%u$zoQd z9kTj^wbLx}&KSwN;Ey=t6nLO$%ZS=S40~h@UG2;+Gr-S(ds)M_abAsor7Rel-mNDD zRO2Dkbx=WKb#*wcUGtHh`%U+d3Hckny&*kfHx#F;>M8}%(g~%?p!{nL;J>W3 z$NzH0{_k01%l|!VT>rmEp7kXEt)}?rId!c6TYHf4zs$K=75|qxcLv@63qPZe&A^wU z6FF))sjiLQ_v%ZsMwE7>zDvSILFbNUpfs9wgei)O?~se+FN!KIlB)hJ8}^8#Q-j=a zUXf#J2eJ6MNHGCRr0hqXv$?+Ght~otRgsxh`2l?CeXX}dI+x<1=Bf<8bJx(5qCYgO zpEsT=Fj(cVVE6&Fr1j>b_<}_9n;#PhRaJax#;|gT2i9%yMO+WS=yxCiCR)|fWCT!H>Xn91KXf}H4y^fQtg&JiMrW1$Z zSjhUH4Gk}SOd}1S_@?%G<#$mDFM^;pDFSkZYT6B7iG$McGvh??+NR!n>KnvDX0Er- zCF8@CZCbg109eBxJse1%=9^!!JdG?xPhKpPZ%`&es&8+i*ixdi7%*VlGv6qs+)q(t zhQ4v$*&%e!+oe#5d5hovK@oerbGFJR?+)p6UNDlBM;22N?S<$bilB74{>VEV{yAgJ z#l_3E?Y$+L@8R5~>h@^%eX zc`->*v|H|q|LP9$brVGQ_Gm@!ZfAHL3v`cd<%S&vwz)EZj$KD%K){K%>!_YQHG zFCb53LGmm~!nF9MbM~t0rRh8nN<8HP|0$$WgghUf_YjQ|gZd6r3S8P<88*Wvpaj6z zIQgCgfcwF~y;Xv>E|T8Pov?+XCX8WXSB9e~)JEVRo8euZVkm00rq3=f7e~b!wzk?Kpf%L% z3gB0D6le5q8`TvXPf6!IS02Nlqkpu>n5^-eDvFaqvaoz zNhv1noJR$R%!#qeDaqNm8 zvQ{}wawr-~B5vM}z_3-Q24Gd6yF181e}#?;c)7gH#dk^M7{y|Bk=wu|+19c$R!0&Z zt+l0SDHsBR3s7uocr(~I-YlIqDxt$fm-aQ1y{>raWyLoqx$%f}Xe2#&PvT>)=GWt2 zrx!hH7Yyd5h?}mspvlMiI1?QPHRzYrBGVfv2j0cUq$tYe$-4`p0wjId5B!EWxnO8{ zqO=!(BP6I34t-~3#;`^xk5?wZOxBPra^T5I%Gio85C(6TqVT)TOLl20SeVs~eumx` z7jXHV1}{bhtld1A*IV7QMxJ~S&W}01a96C`1Wyum++MJq5*!}AnaZ3lWlL$=kNY>O zvTR0j@f$PK z0-A~bE#B|fbx&a>QGPvfsP{In0ER(ujuQ3ds9kU|1j_*L$ay_IeB&^x(U9H8EkIO3 zP)dY)0GVM*5F(LBY<3J3EIaZTN<%-9!_2x5P-_#WI51Ra(}$&NvPBA?h74p&F!qZt zzJ2r~CSS8LUK)SP=bN-Z89O$GQOy@HaY%!N0>@YaBAC}dCy1l{{PA7gsq#3-?JTpJ2~1ESA?0yU6u}}W`2m4q zcMI~Y94Gx{B5>;_%3+|JZKB`9A$m@9^AK16o+OR(v`|Fqw|HFGQeAn08kzH|SIp&f zS1VO*vI}9*5fi=mN@I5SwpwE8hqJjt>0C8&;WSInQ`t@b#-D>UH%?N=8$3qMJRhH7 z?@x}C8qq!i;U=wEB*&_JSExVsVO9rpDh_q)LtQa0mp7d-9&5ZGiNDHrAt?a>QcT%opY#$gkocr{uU@NUtJZrL_!*on>|IU?q;q?-HH;yuPWe!M%CAAd{&QfcR?I1Ji;GhfrZ%F(dyMfI!UgH??)s?7eXnnQ+Y_W<`hAKE7nC*?Djy71`% zxDj*a$7FQ6B9j4X;3p3Yr@?LuhOa*PHwfz{Jl0zf;|6HT`=nZF;9ED2?%}NlcdKPV zL`P97(BNO*TfZQ8VYnSW;t}f29^Iu#Ohl9lC8(c|D!c#ayV3|)afRRk zKPH0@nf-z&h8J!GF!F{|>MGw-TJ#Z;Wg#KiA02K-KT8Bs@cJWi~F8R|vZ zCia+^Xecl6$A$FN`6R1FoS}=A>@eTNO{tOL_JNj)Jf)5d*NRK5*%Bam#D&4=@H4g9 zPWdtMcPhvHkVg0Y8F}LRJti&j1>Le19?0j;RYE^P82{&9O#;8-$Fs?vY~ydR9lw|Z z!NC_--0vZ?SK@e} zqp%iH60wNg4V%5-!=V>G$K8lgYe+u2r2F4UtN1WXlmoa#ns&n28^Bu4rwSo4a?-N7 zu#!PcMDn)}8E@Hrio9i(DLA%IwoqOd?0OWs0p_2w`Xy%55u0; zjSl!YG%8k)O=90g_v52Hjl9^X4No}r<3({}#}Z8jTspq@RSwpAH!%v3gnt(}ytk`k z=-P3FrxJGtjCoY1m*kHd722^Y{M z&x99<)!j@LS9IW|H#yn_-H@Md_i5J(^cGmtjBwt9HMA2;{4kWF_pgkknsgIq1C;lC zMH9RqWpNp%8{k3#NZC`n&G)sK)UjglpFLW7aS_QTU~a=c2}Ql%ek;{)^yOKTs!RaC zH|( z%HtmljNF8`9oNI5BoBYcBAv-U`og>jGPIyREjI0x{M1Az^5Sw2Izx+9Y(>~*ISg>)c)#| zi?8%Sy=M0fgaGR#FX;ZlX;$t{v~>U*>rn($xGV261xBy<8+JpaDm#H!40WLS zBVNE+DQ8#jSye~0b{LWX#_I4vMw$zoTzJypR|Us=5Q&-SOtrV9YMwBAp6gICk+sKM zdm*=x-sdH)jmU2w4`=+Q-t^BKx^No`u1JnVuuzYXm2n6{*Vri$7*PNiI|Gks7eRAd zp=*a`MuY2g58r9zft;}?cIrSO5f@Zg&&nk*T_ebOpnt|+3<}!HftW;MVr7r1| zIq@w_Oj%QtgOrGiH%zme8wtUfKG~T``zzlo=(Ce0Rd5iHUS13WW6;Vb~%5Yo)w z{usS;tQL@a;^Yl~o#H<46H(bX1ki!eQ4n8H5rZCzl0WA~v8Keba18d^a9~Y7Ov}aP zT%-$Dt5VKaniBd1xf$3R@KRvxEj(JBrJ*W{A$YXuk4FBt~y0l$kaLO4Q03n*i; zVj%3Tw9=N3*{A?gN**4;;s%Z2?ob!HoBN_aU(u1+TZ;+@@R6~>o4tg9T)FEBTvr*hwGrUoe=sX)>uz8gXRF8|@p{lfm z4V;H46J0axZekm<2dc))NZT-?(H3!K4eFSbZvGN+Z21fy@bfZ*zzDcjJER;6-rgX7 zTl9eIv7+i^pox5K0J&z3f(iWn+FT#ZUPh zV6Zq=u;db2fJB;hrs3Al93%rd;8poH2D-H>3Or-GODvrsQmp&IZZQV9fK`w%K4mj>BSlj5CdaJi~BAQHMEN4T!Mc7+z$Lha)!f_HG0cLfVvv zo&yG5;a2?}RxtK@rN2w8QTPTc4~DWS5RCe!USKjjH5rfRnLBaV8hyk0BV#s)7~O(= zjIhuU*KGx2HuIsX^3$uI74RwisE4f9^(ckDE%RR^1K$7W2;w?n<+j-VbsztSLO@3{ z<`bpdJA*}JXa6jmSLn4TDK9GzxJzO>w*wRxGDvFP0^t2YXq>}~Z_NRKSD`h*ZE-3j zB1Z`(w{eWW(5w9z8XYg1?h?qmJ-kJJx0~(0dX!?q2%0P%L8o(D&Z5XI7gH z5!j@3kOM+eizm`_lkHjp*LYa=eB38+cqKnzqB#rp`@+mbtbitMSEn;uF1{9PydU0e zdf&%FC-(Z_e&h|cGSp5F$DE)O<&R%GR0R8BG~tvzovJ^OZ`wHTRYV@tfQhX60V?g>b-$+b*x>wY5JI}==G%+qrb})kmp{k~kKi7JT7CDT zmgJS_GEK@K2At1m&PG0nOlxqA=B51iF5$!&fVa9WM6y4>+7^9~pYqA99hk-am3~R6 zE25Sm$O=LbF8{9(5QQ!Nq_{H4ghRPIz5Bhd1&$kt6n>$R{cHVozvnM1_WdP3AX0on z40`(;^G$8D!$}+b%!7*3C1zve+Ly=OyV(|Oo|)(390hCJIE0(opa}AR? zjqR+b>l0aUn+o*XVc{JgPNCo7SrZDnG<#Z#BPROY#h>Mpz6Kg>HvB!W37_X*v%g!X zG;JjvaBN1&q=-LnFO<{RM~Cl_p>iIMjLc3ER4`=GMVPGQ8RoD{pxBcb^{>r;$pr>l zkCohrSPZz@=cI?eQcoC=;M4FyjXkn|Ogo5kqXM4o^+O2X83d5ME1MTD_*mZ&^!r<( z%{*2K6UtmO!pk*|%T(1Q;>;9!?3QZG)3SWX_oL5X=ekXWvjhU<0nIFu*0_F4A&Z>w z%q0r0pet0sY-}aOia-xVP;XH$8r|@w1-%Z=@@llRF=WiD%r(|5p1$hGNw50Y6o^16 zCYpWSXujrxj;rRUI1zUl%R4^j4nM0q;>XKR%j%eg-(Cjifp2X|y{{d!P|MappAm{U zVhq4|JeEJY3kI6-Ghy+?;%W!OZ;m{sy*0%ZSp-ViBAqW6>~=Fu1ph7#`Y3@j3u||z z_@_v&K5>__T@iU9TgV1Bl|HAa|awy$Mjn0oNT^~a9A%>D`zvAeL2N%qC1g4wPZ+y<{;>SP7gSGo#E|E(%WbGcOBaKy$(pL_patwj+@V6Sq6O+S!r;AoJvpDOo! z!OaWG+jQKHXYy(`(T{;7(U)5CDK!3%RMZ+On|^{MAv(Z!0=0j*)9URIcO5NgfKc_* z>Q~K*pK{K*f{Q$q(|2_yO zlNSHtLKqz0@JWjYNrJYfVUKFBt!ZR#axMT^OmbrI;|QSd#bzOk!h9OeC@h~eOLYN6 zImfb@fa<&{@IceiMqxe)HybB9RQL1sr` z>Q+zbZ&4`%T^Kb?TV+h^wDtiSjOxkNCO4=FBCLxT_`FZBww@gPic?MwkGIsM%9L@r zv?Sxcv=sg1um$N{R`6f4g0jhfWChQ!%Gk>-nU1xT?<47ni#_}^7QyoWRw#VO9#*^> zH^Fyq@&V> z>?xYj8^oL*(>%(?V~O?R$34KVpcvHOUpYb@+D*6;Me~O$iSi~j$9*>lOW=wn1pUsm zxf_C0hCm6Zj(doPicXqt5XZoi)>R@JQ>W#e>iNKM_|#)S0oP0r0h!gX^83>k)Vi96 zVv&y9xSEp>r`5%B8H?_^+LU4{n2dJ@JpUy-P|Raj^=GB?f{)k)QMbQLoUl$Uaw&~c zbixv;-?HdeG-dfE8H&aw{#U1@BYMA;JHXukLZ?9dMN23UoOv|dww$!_!xMv|zBdD2 z!kEI}wHM2t#)CfQGmf9hn06tv^9w32U(9Y}k^Eep;efY$R|Cx+&JG-2!+G{9d*$bK zc#@)JhbIF})7j<33}Yy?K68JJd|e zLZPdUpDitvhuGWwiDbJ$Ue$RpbR$3Dmnt$f=YHy3P<{4wN01~u(!#n0-+7^MA-kyN zdUSLI=?N)=9M%Orx*y`}*7~g&q_fY)J3})yp?gjXn0X+Qi1@1T)?+o)Bc6(N*u#mS zR^89el8a(cFZcRmz)|H`|m4jB49Iv=JHWtgKZ?^Nf zx?-33R^9|Q>{W-Nr-ucguKVud)5~JoR4gWJ9t+o&sU(4V0VGYDV6!qbvAY|VNM}A1 zfZm%}Z;HX~kfbaUTbXZt7Z&K$G=#SrU8-Ld9lD8+n})cz=yGmXAcUZW^3WrKx&wTn}R5wmT zFoK|=*Y|Y-jna-J*4nDOwf-f95&v+6z83p<7;gC_aPNwwudC(;#ix%f=%o^KC$>aK z{Z*vQo?jm2re)+8J6c|5Q^E7p&E|Mgi@xU4A$8Ig#jn{7fu+A5>XMZCbhLsj-dzIq z;eoY#2st$Edn~BeQMMV|H#2APch%ObbbR?T(9;CJ?5uhKWZuI00C}I^LO?x|=(RIh zU_8b|LLWE?CEL9J-Uz(C{jq8jyQ2z)O^BG5gIr{xpk{TW0(8+pWcVO5R`RP$P+m8!4}X**`tnMy|iEG76myOKj{Dm@pWk>BZ+)Po4GBkIU6k+-&MORL!+5$*gz8Ir-yo zG{SD$J47B@;sq>Nmb72g7xP0jy|A8Isj!~|?2*>!q-cCYv<>Lt7t4CpdZCYt#P4+B z#&_iO?N#FbF%pjb<8oL#bcQ=paTp1?WB}$aj=fty=-XUQ){HvDmOVS~Bv~Ja+mQdF zl7>LT_^M?Tt|LfJj^heue4Q9J*>qCs9fjoEYYMM#1%||cJ!h*j4%MGJl2~%Kqh|}d z%t@w)znwj;k{~(fNvXWSFNbgVC4^P2mo@=6q|Rbbk##fkd(O_`>{DG54Kvf3eLD3s zha)NJc>r+gc_y6dJ0UwZIhs^lnddjLZ+uMqQED-I{JAASPbA9uYtrKS7LQoqL-6j$ zRRJRsYcCrNX90?LlxziJ(338?i^DE5bzy;o>$mW|$G-or@aEY1$JJiMFXMzx-w5R6 zGBpx=S3CAH!^z0`lES+o{0@@m010DVSI_><&h;Oy%PaK1%;4bmOQFVi75&o6Z4%;1Rsx<&hD&9sZ9^5ijbbS8&U%MDus zXP`dxzs$?c2B{D-B*euM3Z^Y9jXGs<2Iiyw=hqgz(801Y0kh%#&j=F0fd4Nj{QrNI z1nVf&?_TET@O?PDY-yAI=l1Yqm!>LQATQ3Vsv3O7@g$9DaRtE)VXbMnCp?{`1FsHQ zWbJ_++e$I7&habma6QHK^*xk#ncj?@v^6cu@ zg_{M_7{vFi**8yA2sKH%v0#G?5zr~oSa|O;g^}C(EyTY#OEv7Jy<($IcOA0-@vr=I zc4^Td)QLOmp)iW7u0Ya5O&S}*D8#F!I6d-3Ocw&jg~H*sq=sRT1B~rXQ$jza=}2&u z!YXi;p9sW{=^|2gzj=C`&Mk%md=0@jM#(%3C{i{I*RQJUe)o?mB>p=-=)^eOUI$CW z%~RLd9k&t*&Q0!KSpElmuKGH42=LZv6r3HazKdlbOjxFYk7*^mg3AN7pes6_&c4{yUT#Q-% zjHTlp=nonDzyA*RIus4u_@~G8jNSm>29I^v$Ug<@3ns$~xQ5t(5$6Rie2(f^^nr0t zT4xDSicv2U8Ct%?6iB+D{>F-#cD4+kbI$mZ&L@WRDs5wy4`ujJ7@(B>&wBd6Nw`s@ zsZi$^9at-P3^K$UL>A94>`O6~y5A{sQKvQhwOs1D31_7#;gwy`xO_&CM~R=oR`@bp z3GN8h6SyJ|iz*NgpMbh_1R$w6t{Z_<8wj=^Gjy+}F{nAwRXULb@<-~>x>NP4Iyqsp z+Kublmv9ZeiJHNvty%ezLU}+p5{0Lz%N~fgrBbPR>4?t&+6^?)*}UmtD5j{yxZbEA zyrcMAYBQiP=md$Sw#ZW>@9}en%ik*VT*yhn%}?J}32GxIoweTorFAh~X5Ct5QX+}m z_*}*=#w)ihaF^IG3Z>I7{cN|(eLvruGHUVz!!U2R)ATE28yHNC~q!!gnL4_?in zmf9;Dt`43Z*Yly_IJiCEbQLa?;4s_KunmZCqV9glif{Le6ces3)J6Oam;n8 zT-_O9F@XJU7(H2ax36oiT-Qxhj2d*)tucetX|COrcr9x%4SADQ-buF~>=QtjUnim5 zkM-t=<12DO_)r0r*s;^H#@M+nBn*9(*eAj6Nv$q}7vyjHVT(*Pt2wpWMr(dM&c=1* zZ9;X}2ZZCU#y~#14fV0vALfrphdz#l3*z^YW&sUZyOqLLfWeBxd53vQ=b#EC3Sn*S zY4WQgBL0n)yI)D=A+n_C!g{0jdF1#;Q3VS)okQteOv1JioUZp zeZGh97>sTRxnr8FX7z#w0imCPQ7Xg)CR#>bwvmZh7Ff5wl4;_ZMD<8s5piQl%r=j#%6uz6HxS5qxBiaoT z9XRb|_DBN{hGOq_RO4&vvFz{QADHu4Y6L<&>`8;ey2eH-)vBwM`Crta|aA7}`hijB@7m3?Fmt)MU>UkT}r?RSt}10OJ_olSCvD zm0neyJ{X7SdY$CyvzErw%9j%lZ+&_G#8^56%LcP@FnQ|I{qA(HxGb3tXg!qhC~8a4VV4M$6jktRgl}hebl? z$H|Oqx5vKi?J9921V_Q&q*-#rb`R_Pwjvn4l`U%ds}i6JPy(DK^g<4^TfU8bu}w#qWHeJ zg!YwBOkWNkkxw@rGccf;H)h)=%0Aw55vdl$X>sz2glypbIz>vue8<&#=*QS! zyQ%cmwUbr0CB+_p3idn_OhpBBOykzTSLe}zoO!HWP1L>Rvn#Btm)5K`w+$Pe&^B#f-@~L#LEJ&`oi@ry!6Jq2$$Bim;hNX`IxXnywcUjI6JJ=2 za)hz{Dg^T++|5cwNh4DEqG`5hf-d;k; zwx|0WvlBfidkzQPAxhsS^eE8ogHp@VL#10_@m#nPS{d;L1F>s!?ZaxAV!gCL;*Ag2 zQrxWq!l0iiR`BA$UZ2-~Tr*BGVwu=$om17u*feC@BAZ*!94-%{6ST__IJ%m^f-uoC zNP<{`C4JvuS=Ir2b39fg3Y30$y}N2wuO?^(txXZf|7&?B&;S#y?jMj0zSNklf-GRC zG%S$VYr##pZ&Evd;kOPrJm-AxM}8RgahLkyTwz-`+{M!N;Gr{p|Q32p6 zm|+L(x$l52J!bw#kZPX+$0v*2Aa1vOG zNF3p3D#wBx8E*^;SQsPkS8ms_=PZfY?4bjH3WTiTiJ$5uMI7kWk?T1WSvm!Ec#V-2 zX!tLf6}p}6Oovya@?$sjX@3OWUiO&TLlg=-6t0R$RC-l>kJrM#oU?09cN`z82T@|R zB$)L$2$Yk@;ehU@%sVYk%g>aeBUHb73TQumv0P>PRiI(Wc=?|oM&}4^*21gE>Xww3 zx>Ds146a=evhK?;g#D&;h6k`JrqYJ1MP(<=1Ef>m`BFksxvgWHv+!5oRmu2Y?@pA% z>lS{C$sFd)HRxR^xpR`>w((CIi{GD{K+uan=8) zm~;PUdXM9HS1nYIxgBXLr6gI&!)@}wTvyY>5}BkGJI!sfv*xm#NN7bJDYs0d+013G zVU|nd*s$c7*p5pbWVVRpuJh$okMrmsIG-OsKfWKI_v`a|y&s?FM;>6wFy-nZ{i3Ji zeag&Tmy;Vvoe)UteYJoLV9~2{+x7Npg!o42Wi_6T@)Sf&M%q9vb zmNuz`Ul1nK+fswRcQd96&#g2FgRnQpH7MW}j-5xugch3)nzOmmD*FNZX~mPOx=dYZ zfim{Gy8qup4-ehKkzz)TITN1g`oS9 zM91r~mwmf*>vfDa_aC!@0L9wdONqUpv|rm@k@z-wG3~nP`(hti?jEKAs-M^tQ<#vW ztROUMfg|od2Bw$LzV35&+U`fT3g;iZ&7x`Hrm!}i=Z@n2`eiAw{GW#HylM`(J20Nk^*oG2i$`4^(X_69>(8|_CT|pIWn7G1 zdsrTya>slPrz%aZ_-}@|^dbM(0qFDdq=QJwCw!4uZniKMUx2IkB=@j4q71M23~V1Q zZA?SO92+v$ze!ILs5Lu{1~RJyLT-1pljUjheOZHBS+ym8KA?gl-5M^&jC`(V2vkO* zzm({+_PsiO;y2p}i?d~hk};uZQysXp&BZVR-|8`Xr@UGg)c8=xh_;VKz#{p$iOTeQ zKf5?-)=Qdk&xc1F$U80Um>0A%Dal)UafW~#9PLAx2#*V*7};8T08jqL`Bno3ufXC6 z6pHa&v;YP+FedWAR02@JKaf>5#{i_Kb^SYfv`L$b>fd^C=}Ya;sLe>Cw5e|yLqbKO zF)CHI?Qxpl<&(NCIF}8ZX=@CrDh}Q!9`A$JhSMevc>!KE-ElhSL6Nd}SrfZ@o5Au~ zsJy8|LL*w;By>D~De`{x05q`oPH2RG!(VGU;1bsTC)E=sfoDuel*eD2LyX6!9@uuc z-rYf>nt0cKaV=?bg6$y0`*JpzSY$T*OCc=f13B*`UmPbl_@=O>M&d<6D~{ZZKlwb% zzlpJkN!?=U5z5ho%mI=T*6PIgFmk&RFEKe8PZ7XSbN literal 0 HcmV?d00001 diff --git a/docs/images/investments/watchlistMT3.png b/docs/images/investments/watchlistMT3.png new file mode 100644 index 0000000000000000000000000000000000000000..ecd344381ca2d3c010b54de4f33f7f20ee44ae8f GIT binary patch literal 11676 zcmcI~bx_;S+ii=KltS_1#Vxc@+&xez5+t~_xNC7M6bb|@#k~!s1b26*P^`r*xI=J) z-+bkLfA8FxJ9GcIcmGH-lg(y7yU%m>Ip=Joy4q`eTq@iL4<6tvDS|W~Jir2?Kg$9h zp@Qq`X>8NkTtW!}Y1r=)Bjg^g5Wa?X_4m?XxKp~C3O>S1 zMn)Y6BdMuZc^~;F@=O~EE>%ky8}A>K0-FZBbisc7*IkNC`=wU-e%4mjR&_Oe60>Qu z_e)LApf5@mR-Y*!M`rzKmGWm6^Erv}M)dphWwR}Mcd@YwJ_r5V7Tf#ouo?epu(+^D z+j1*iT-Z!Q*U7*5&yL2MeO*$rmms7z7>V9#D#btKyh!XeZx87mylu$>8v-Vgp zyl=;%`-2t2`RkUuhq=?`JlK0EwEbCbm!CL`+td)tc3uC~0>GA2t~z}8RvmXv?$G+< z{m-4TiMR72&ptU`Rz&E7GQOu$IEYY1vrWlX_ziXLUKa2iDE1`#*+OIAF&UKReT6YS zjEqu2^>De22a2t1TVh=a_T^&b4GkYexy6AAGJ`aAl&TEZkSpUa4s+=pS*J z$Fbgb37;RKol0=1ZORl_(_OiDv{ApA)(a0R)sM?>pzPPT2$6v*DS&-S;8hq?S`NE~ z+KyT?PFw7DE^Eac?2S#HODBTWboAaOq0 zm>3z;7Qa6~o>N=d$`<|3b?mO~bCmYGH7Bc}yp>h^Y(*Ct7|etnRg@8t%*OHKc}h-8 zU&5bV+PiZGZ?_x2lWLs2os;q(55+H*P;52xokdQ&WOP|$@GnEktTBS`vW_fZjG|3=%SjW^@`NsBVwWJm2B-%Ug`f;W z#N)0*n@CMRe*GzSNO#3gLiXto-y!9E7(2n#^|$^=D4T9)c?&z0wycK_^HUG(RoD9! zVmvn(?9Anrimq%$0MXgaIQzrXA=0%JmbcnIjBcLazh1@?QD3mqdlKdFh_sK0q(MD3 zygCf#d{-*FYuEN4i-c>oNNVtyip?KssX%V@Ohbyc)27qX!cHz(PyuohcRyayDn)H! zUKU==R8rj--ufEVC_^X`ephHMX1mnFp^;E;4eF5MBn-~(ceWPe0%5ry{k$`lGe zLd;nc^7n&!`o1y)xu_j*;3%8SW|~l(rd-;AKffypzOGwjyJmRrtKm*EbKP3M$Ybg$ zA|cB*LyQb&eSyO{rHgjlwG-G(>|e-C5wq^SoZQrTrE&C_hYhGOcJ#0}v*&O;vd9f~ zxApi3LcD9{&58ZrPoM(X+KdE!$e%6hA-T2&d%+mpHtGFYr}B0nT?*VVtY4BFMlTVO_{ZsHl-;q_(2u?+=$JcaczYvx(>O<{-%S0`dCi@uQL{$O zz5wHZpyLbt5WzhwCJ9|y@ecKh44i4h?#PXegu+)!0F9zph;2$#?1D^tK^6d9S5#H} zr1i(U&~ayJ^?M1FnrbIfK}dE`cZNo}BrsvpLB73uI%n9-UjO81nrnwDd*Of_AU+?h zIPo|mu?F)YYr_7%@UtJ`fWqtdu`yOKM%HJJ#xmY+{KN{%ZKPB#LG)NSldo60j|f#R zu+2~3Q=FGpwa9~jd`n}}pU-r@u(do&wDs3XdLRxS_h2S9&%rUjasxa%SNQtN#!!bN zg)aDyS;j>fw)ut|d#OWI=j;sfz%7?dTG{fa4N35|XwyUf)>lNkBY7~({)pP$0=QIW z==%wZ@6C0*l>1&W?sXp1EZBP@$`D1RNO+?o=p-9!&YUaplzPmq{oF(1lofbdD|gq- zJjMF$zz#V3NweYz!pobnb}>6?y}h~Trg3fn6by=o{zy>LOWM}kbbFfv|ExqAhLTcE zs<#v(F{|OBmf|eymJ*m;Hr)Xpk@tw$R9&|!rOBf%eq1%oiSFQ5=&yR~38QD=s_(t1 z9w$ZmedZU{7qjS8ctM{OnI)slYQXT8Dx^OrMZk6jB`?o%XDvs2r)L;RH(4UnVuzo& zHo=0bV5N(J6_YmMA_SoUKoy}jL~2|c$^Pv6#+{E?OC;{)WKQ$T9P`sn?!%j&C#eUS z((6zANF-a>IyVw}F5K(V#hX6aHMJ&H#=SMrwrVxh`kq))f4L&jx>H(1T?TYL*!H_= zETeR-D&xGqSQ3w2xPA!cp5R>HREB)le%`xD0zTT+m0G$KYU}K7=Yf=H?wcMz$7}QZ zlr3lNaz9sxva_L^)Xr{42{|8~{nF+y=%u*yXKHDD5J2ToleEJe%rB+jSZnbTBF=NuCv082!`n%=*<$ zRf^fK`{!TOV2V`N zz@rAE6wTqfeC-opi%$D(K{+$meOZo^i z-FatojTf8?Grg*vJ&h94;K99bbqcK(>=>;k>%b&|#g&>_P8x|^2PT+JymHCmLTJU#k%dMn?pSWQEd< zanCsZgm0@(s6plx<+}igCq{~Qn zAAWYZWm1ESGqtu{XJ&M*b!k9afXMg^-LIW%>zo&so4!Zzss{hB9hjZn{Aw@W-)H$10?SBY9EOtSB#{FOZ^%akN@I+I32Ar&=s9tRfx>JW|b3>f$o33c656k_DiXW{wDx)t|QGU~N+PwCof?@wQ55CNCXr4`69 zxcLK*9gv|mcXq2^>_K{i$3WsOUzYTCtVT1ckwE*nV)6}y^m$J;fId6cxbt9W-)7-Y z%vc#>wdrS)?xNAw1X+I-rwTJ;6)eMg$Wgt@i1B|Wzo1*2{28ho9v0l(UhElLiPtx7=PbN_3d~cx5RdUz-(Hc2$WM;HJQ&0RAJQ9 zF#YGpQ|2Ej!?EM8;#vyQZXy<&)29A_FhGq-Fs51+xA&mmTZbzXRrecwqqq@@f- z^uHTx!`FLPmumHX`&lTBO^p&GsO~iV8sagrkO@!ih4v;kO#K#&T4mnZ)w2v3YDK_i zOWFB&LX>~?%`w7Gp8B(PAE_HF@zN2@ncG$vIo-k)qvc_r%@Wn8h@jiSZ!>|BHOW=X zz(!6;S)RhmtTf>j^@fSoAcBS$osV?_q~KBt^<2@`qn>x(uLwf|3I$%`CJON5!F7_9 zOP+qTr6%#T;C>_fvlK+3{rDq_)rVCU*KKo~ykzFdc_s^xH0-C%vujO# z%ey8T3#$Y2>-ik4Rg7m=)u#P_M9n*Yme38)##hSk4XRfTIr6^As3s<3f|WrK+uf=g zcY_rf@5*V=$zbu_(p)@9fC|#b>+Zo3=m6{r^U1DeOHzzAoU!{E=waJYm+gpYHp#SN%x71U!WZDS(y|=9^Fc3oVBo62ePQ$ zIDb>}=ow*WQ(lB#ZBX7v^oya_V~bLVw8V62y{QkS;_>tai#1c54J|LfRb2zk{rlfy zlAPwpVkGB9X48o!UPmhnDZ-gz7X~vkrWt(#6O#6~Tw4bz`lYi)Ug8r?K~Z^P8t;g* z^h3(CjP-b40WroYQC`|J;sr9$pYr{xL?F}o@6B92x{Qk1EEPgQrO{vDsj}*pnF3oT zW0|lURG3H9MRsXjvHwxVRDA^peyG=-x8CZ;rR0X})gz7ISx$d<}!|jM9++k)|3_C@*?nC!f0uX9O)f9`AaXi;#G zjEAdaB(IQ^-+dyYt`$k1kekUjdUmEUp#3ru`(D_q-r<$l7t1Mlpg0*=M99U4t&b7-{gedY9pkRg1gMh{{?=RiS zGJ>Uw%KCzS^5LW&{LX++8$!bAirgHmqbSzDD+%&d=JI1XT*qly`zs`QFVQ>hIibv>2gxywJ|5lPfRxH+vB4IvrJYR z^vLkkvw|4eeiJJDi4dC5JXvBMwuJg4>d)Q2$8K^cs-I_hR z_Zj}V(vHyWQqX@r?UkUtv<(Z8CN57R4>5iwUY(Wp?i&rkwFg_`z8xJw$?64%h85)W z(>DoI*#h-y*4_NWW?{qB#M_AAsbo zFreVPuV=&ajrhrF0Od6JXBJ1|;CmNbw>2cVp*c_i7x&q#1@#{_U;}$dy>FbnRlWjD zRv#hDr11_hVmVAAk;B^(37!6q7hPJ`e(#iN7$mFz(JYdLtTJSe_vW=ZbD8B}w;)zeZ94X^dQFK~9qMNTiw!WSGmA&w4}l1qn2We64X6k)X^>ax|DrW_IG zhD~BJS4BJOPOp)&+=_GFK-;#UnU})u7aXlb9ijUzzn>^W`mdd(?0bw5Ucyph_AwF7 z2?wCCSl2EiQ$`)3Z0Y;&Mw884T~W?-t2?E@;jB}fC(bOIC+`M4YyHGoB1b^rAwReL=;lRX(av`%Y*$<142szlG@#X(9?7 zhe5K3TLGxkxsvcDPgn>aa2!p>))Ib|FWRD_-!oOW5-+n@MtpYMO|w=A8wT~fCy-tD z-FccyJ|+(NA(6YHLynj1Xh6pFW)&2Gj+MPh_~^zlRwZJtu#^prY{OD)47a?3wNP3HYT(eCx0kkLo4!_TH7~&1=WU zSG;_qRw}QH92`0BP9LI&>$GcjD(*8aRh6-JeR-G5NZp_|AeJkn@eTb*#VzHJf=ugi zQw9fJ<*|^|PYMr>by%NIaf_#|4E@DRhvDpPhc6dzjw^?pgR9>WBIZ;nb^eHQ)aHA1 z+JfI8V#HQJ-pA@hg7~c+yEx&rfnMX0xEvMun20tR#L?gimQm7&2>r0Ei^b)$KTX1; zlcB)D7YTB?Fk1Asv+F*fyD-c3orJ=O?Kd03;v$+qW`n{OUAwXqKYuEQvF<(hhNd|8 zco*{I>WrZBUtjtJtX8pELtcD0HLB4?dKX&Xi_4(Zj^aM7oZzeoP42f1R^%8ee1O6X zLlq?-3D(D-_!3|@n}AH;i1u2%xwfVZ_-KnlkL{cQFwt#_e+m>aD@l)W!1wBx``6~Q zJCHnONT14~n7V`3@H}^vBIFmV_u491gS)g3sAPkRY@m^{(2?SV&_pAIJtjf01oS6= z&71{zJS%&&=8kD6FbSWwZ&Q%>5}quGdkqaelP9iBUQUqO!?Y3MhzH^z3i}cUauAif z3J&v@*NgSOCoi9#V9yR?_(!b?`WSK%ldU+rg}_$LaCe-jHJUmqqD>60t5ZSp4r$`o z-4R!`k%~%DuQdZ1Crx?X6vATBqjlUy0}k#dx$41MlMZ@DFc^EjkwX!{FEcTIDi2j$ z|42$Fak&oP!@Ehr@5ufysbNikbxi>1S=5^n{i318vK~%lI%$=%-1pnVTT?4yABLZ1 z|K`Z_$&;f^n5tiv%Fr!j8(m)*=Q38g<2o;@n1%1OuGScXyX~2tf)gu76X4UM_i7@` znaFN!*0RGzw_5=duvGh26vE5`oGeF~0g_jN2`>kPS@VGpyID0f!lMw)eJPtj$Hk1w z08(!9RJi&kMh=OJqk?7~g_N@)k50*$N74b(Kpt7>}M*O{(2w@nJhWT(CEC za-kvk3ji!U)mDdgT^+QBcuoCKJd4dO;X{Q-GYM!|{KNh1pJJveDEq6J1_PpV**g8x zeOLe>A?Nv6B{`>4)RG$t&?yiI_@(B43gZ|UQETUPe0)wYk^po`4|TZ zp1azY=qk}HfLsh$_q3#dgatB=rYbB+T??{UUmRu@PPUc(s$47_E z+?N60ls6!ZG%TK;+Sd-ZIBUOa9x`VlWBK_;M5G{I0{oyTT<5n8r^dHBTDS6y8X@`9 zkC(}*=hVmMaPQr4w64kBp?#@Do2D-?D z$<#JWyE33}ZpOGYDnwc2d{)BG3g}=5cQf}$6=hd%GZ`a;hj$ePkDN~`%jXQZe4NBn zlRk5$6zLMP_whT){2BZLM_qq$*c_hk-QmU(eb%WbhgThINmZU4HHlsp z&=ooAnvbw|)7cjt){)r{brd(FtW{a=T7ft{=ZF}~cC?xt%{R2c=JIPMf^p)4y>^Y} zIVbq`vo6^A_4PLyytHi5;%u&x*+{Vw#Om%(6HAYaA)H6AP8R%bR_v;Vv^;-D3F_75 ziJz@DY0y+VG+AX0H7Zr^$;BOBosEn&Sr6_34`cc#DB@Ojt`3X5kUc+9?4tZmmk>7K z+I^o8{*vKX>6Bn36wjgMpd>^j(#y2`B5H)RFEsO`OIs1c-7g#sl+AU^o3Ea?&g2NvTQaBk$w{a=cB&_ zVyag2E`V?y`Lh13uKk*|1CA>6?Uhl2+#%8vX0`|Dv?E|}@g{C1=v@lBe1%u!SjU;8 z_d3bxwfgE6XPM4>$1v&xlnXjK7uVxQLO#K#EESYlPmeB76Hl zm6=rjbGy=S%lqP4@Kk5j$Ck#C2QIrUzud|le?@iw%w?ds7pLG$k$Y7xgt5DCMZ~d= z%jk0M4R~%uvhFMQYML_GE=I;rfEprUAwzt*T7bjp7iu z=Gc1()`Ip%&5QBi^PR3*d%fvmYX+%;uE1!Ld$2QD;m=p`CmlD7vC2wMALfx}d^oF% zwh{ZXmD=s{aS;?Iwy*xoQUKcMF29sPn6Hlj^Ju&?c9zB3xG$=uX&V@-R>kcdSk)JG zN-FK6+u1#IKAS)leW7s}<}b7SrUvP^7lTigm+OzfSn2T3bI6aVXVML$+e(Xi+Jw@k z+R9C-JB@~$BR1L+Ene>MR3wAKZd+%Zb?=HT@=JQSfxx3Ud=HelBTHbD6aLPA2#AA+ z`d)wUqK(v&J?i$&;~8)6yZihV?Wn68zapQUtL4LaUlF3|@QN~%rOUw-Z+h7TQdhjkq zO5YzLA`(>mX`c3T1w_CJ>Sj+D%;Re*1>O77_y)F;F*5es z^&#|ASvIbDhX0CjbgJ z2(XFbpK)+Mrj}PXZC!N#c=e?qfrN~sKaK5D*@RhuAZQNqk(-bIP9X=&_K#}w>EUAp ztOVJcf;3s)QJ5pKV`Ti@=O$*7r0_eG=A{x$cDOgxYvJR_G*2jZm+d+T6vbj1HayKX zqNu3wi99x;BJIe%t^~sR?G(0}Al-l6pHnmxrajt)!V1##F@Qy6A@FE$BIB29_RnVMK7z_v~QW3>He$s-aPYGo8~{@m1K>eyW#R4uIn zskc@l{x828^yL3+QvYjdn|%C#?|=V~q21_vm}Q|}{#oKtx6Q(PQh%A}uyrMLmFau3 zdFXT6AHU5Iva>=n;AdcQi&o2%7(}hM>&RT+VoBDWGiW*}Lkna^s~@-K?YG2}8(3`oC4@a&j z;{_O&qh=2eD&3bbxxD=L5F&Pp)jKw0Ik`&e>87Xqfu*OocOaVwrH1!54+ldUT%*g4 zHUxP)tk*u*IHPIb|28dQFvP$9&anUDp9==hhKE2sdDu8xQD+R8Z0;YJXQ}9L3byEP ze0>Rp{iPqv=4NnrSl?`gV3L7rx)$1n(f0u2h~J{!Y+tn3n(-0f?M=|pvoY1oqp`ei zRC6Kck_<=bNlyMV{8oNjPpi8Fg1Zt9TcmLBvoT*;un1Sb z-T=1q;)E3jWM*lssB^Ir#m5)}ngxKfoC9ERgt_0tZ%IYP0efnG5~@m&Q!mD9uSbE# zyGa4R-$2-Jjs7)YO;1l+<^bZeu@Mk$N}*Y_(6Y5}y>QmU%uuOB6E|mmn3ewFeqAlJ zZeWh0eL$tpH_J7@#rJB2_Kld}bD5>ldYeAsn8Bfth>iogKn>9z!)OmSwhH`F2-~ z<)cE9AQov_d6xpuLrJ=IPlC&U9#=GD`|!bW9ndlsmt^L*{JPtd%OTU=Jr;0a1sZi- zr`HjTxV5`hu?=@d=-BhhIg2G$qALJ;9G)Dy&H;s^i^*F(o@2t+k4+`Fj9M5oM+{g- zlE8t;yIsQDmsituK^Ys`F1ins6LsEZEwYPrO0-^&7c3p2&;J`J51kGOS~v58}s zTKHH#LqCyq?wkGvUf=qJD8qM&&zE%B^@JH%Sr;{uzqL7-6S?|hr!9LDn^vf$PtIA& zaCcW^rMdMc;E+7H$+WD2_T3yfV(I3flbFn@S{HoZAO{p(8jU5pty{9sfsf7v`AX*V zO00fPA4JAyAGLR_lKqw7V{WS^u+BSRQL(89MkzD!2N8rRC%Q~w>+9oSwAm2pGu_jG z&0+cG13ivb;S!s#Tpd8An!ND60GTmRl3DE-$pq(`xw%ip3Z_ z(gP#DUZJh}1+5*truXCw@*AH0x;rl|bCv7p*Q7ZaA$+PZLtpv1QnS1<*QU~0qK1nn zD3$Cm1`V=yNEYF(8}+w_!UxJvEmUvy(j+eo&@$VJ)0FmyJgbI*V(m$Pc|)2y?ZR7S zgRuT)8j$U;TGt5^FdyQIA>`Luj2@3f?9wsT5Gbr62knMPI=Q)Zm4aUyp%G#ATXUb1 zRL1UZ*PDqK%$ED4O;?N;^Td5;Aw!$!OG7c(EWmN2nyH05cb1i^ci~rzUWoUp8t+b? zv)$%jxbGYYukHAK_Yyx`^OpZBhO6i6Q{aR$ii$pzjBg-r+FEx>pdQi?;CjC0U)PgD z$%Z%vl)Uxo&CEb^LX^z;;b{ss~n%SuJM%08XLth}E1( z8@Ax2qQ65%C zuS3eKU$wMn)+yo|%TD(VX2Jsds0Q8Higr-g@JK<^>gPpde9=*R!hZ*t6-;)7ip&Wu zXocW$w4ojB$3qV~w3nE*O5aNHn})@fCV%`$ovtg7e&F8~m0&FV>kLBQDsTfa&@}Jq zbS+VbIZQQX$AkYL!PI*1VBgdR*4cx2S^dm85x6d`C!;Hw*gr4KV$js2={Tvz*0|0v+1nUItwRlUFY$ zIObn08|qVq{PJR{8h52O2#%Kc$zIEi5&FTg0d^CRF{e3iDJ+4HAPFbp_oaHI5iVY` zP*(JW6QUcv9;%>+|0u?~%Ad*CS-$5wyj0F5=-u<906L_CMk|(|;ZmMt$+g9$VpjjSYulSf$f? z$sJ2g0`%7KlN@DBqI5+WL2#9BQQmRxAuR>y1Moqj*+3%Yvp^iE<6@C`Cxq!$e1l#1 z<>I}2x;-RxtpMXiR&a4xGdq0bl#*rJ>|V%k7^8iw8AxFl<$yV`w{R$=%2?l7(Oh&s zJTVsX^-c!MQ{V+quSyB+l|mnQYl=ACdES~GZ2qaWf5G0jpFY$`h!$l26OrU4{({fx zzg9hp-=>TJ+Q}R)b+3?+an0_cgL7qD0C*axwm=)684x#5OE6Dab{Z%pZXEkpHL+#x z!l%LW;WO0<^xD0UP=q?QJ_}CK7V}}yvuGbNo!c_oN=!fhkA?yO5~i)`sj0D}e#UWU zHiVXw_O8EvE8^8vE1F@_bl|#bT9xJhxq1KTTn<2!kYg|gqpU}7(&Fm3I&@C6^%RGE zvmc#TSa;3RC2B-=!br$U|6V^vGP=xwop2)rT19e-6=nvWp8pm9=p?T~j>-07wyY*C zBE$0s|E?7S@D9-6d0}LTY(ay+=t(460mCJVpah;X9iC(P=cCEE{7ul%{1t(nrtCwV zY}!!7c$W|IQfHt?htWpUVb>^OBmJ?jQcZr3AV{LG=+`}Xo_UrP1KJes__6OVN=|+) zz=MzYFG_BFg2T!+%fOvUsohK_qwCy-Y=yh;J;hLq66JHG(}xRv&MFeZUl!wT4|@N` zHl@;WVm#2Yu@hC;+*A=U`ojV4X?d`}VKueksmitrU-2Cn>yBAs>C-QN7Y57?pOz4*680!-v`PM~)cc{DnQ1`jP0a>q!u zK^c(Da~N@tSJ~bCe-^WcnW^%U9bmJt4|2^W z>!P`sLD~k=s~&P9hy`0`FI?T3-zPYJ`Sg~JC^=lo1w8cFw?k!L#B|(C_2Dj28!M#}U;`XJ_ z-tT_jGxN=v^T#|zTWeic>?>_mJZx(0M~@!iy;M`ud-Mnmf_m+W`3&{f z?fu&GM~~i`zEqMo@V7#??dZ_XW^aK%+7APsMG#?zGZTGOf36P&sv_gn($Rj}7!Bjp z!;YWy-9%AT3GU?e+9bF#;u%%|TEh|_>-!8_oV9K**9za|9L&r7l3A1q{?>Asmv4T@ z5X8Zp91%03_MG^e)rbg9p71{hvlZWb2 zDhnutg}Ww^bl@g1qscQlcgVD-?p^Aw%qdbS?aMcks}v}xmF|1~^WB)bFdi5{pbk6V z)vwC!NO0k%rD}E3?NT{v4$(yX&`006=pNOvwr;(4cd;BfpTeObE&EuG;_FS5Evev< zX!eRjz@zaX?>ixEwxDroAULZErswRP1VOakOmlp17-b7wG0Y2pLGkUTNeyz=Ju~z0 zi&>{4pzx-Y!1pVf{4voCoRbtWy%q~|UP6#GoV*QjeeL(As+>RfTZL-;kh9aqOr*lq zr$Pn}PS(#;g%#%EwMw35*?GIY(pN!;QB2n?b4yf>t$S`!OnM&~^gHQWzR9b9b)`yg z!FOEQZ90fjPd&`gd=rQN04q-2+IlW?|DBU!{pBaMTeVNIx)G~-R)RSWvTmilZ^&>? zHcol9RPP+i+*ODkr?jIzgbsZRED0J^5|)PFFoZbwAQyDDp|^ir2RM^qhh2dq+M)5k zHE*tp4L-jZwvrKMn5}$E!G5`S^ZV`nnqbKnyz#B}{!f!&jU2`pei9Ykuwjx@N~tvG z)A_B=wDo1=C7T`2au2SGX0yjF2;dG1aKpt|H_p$8R2X9$r-B)gtFNHILIBM3M}!aE zD8j%9d$~--1xfeeCb121`-!A;)1%mgjPmnSIZGz+cx=87b8`^>2ylu8dU(*^%yQMb zg-4=?2JUi$9-8F<(+!k*NsW;tS zxHngZl%a6sfFL~7u49eE`B2VAMZlH?7RMN~d0E^G$VduxegXBGI#XYbJ0XgYp^Y_g{4)BK2GN)H2fk}kUCJB`)g=L-E3pkaqI9KiHh{p}U4i8MqsUjpaip5+J!`&mjT z>4Be4&$?u+VFy~PiO;O@?MG}Zc)e%x3Mj zvR;6(t>w72WUEQBj&j-;YcjT){-Nq0w^(v>CIebS955$5TXM*??gdp}F1X7ug(9T- z+zwZ9tso4y@M+U)EDS=kC5Q%2{l4Dwppkwo*M%cN0#$yY$@4^! z!fK%h_i`78wU=Fem2s)u@TY5K9Sf5%Z#_lF1iVNF(Gh$II($KFhTAm*nbZ7(8 zM;FDhn#;1ylF`Rb4 zisrc1x%$Fn*=q4|@VJ+xsDG`x8zySKq4vknD&nQXFUhsU8)Ip~x3f5X&q6m|_tv*s z#>r{J-pRK9j$IvIdc92aJ|Z&kLPJqq$=0j;Rj^L@TS)Y4wQS-hN0CzG&%*1dXKY#k zCCom?dkafSr^7cH>6fNhiqkwCMuGq~>;orVn3%!BZywV;GXr{3hKz6vnEHW_#~mBg z1pUqsudGFwQ;sT%^Qm8jxQvEO{}!x%M!2-8=)-CR_JnTzn-DCMctcuEJL>!1FFmf@ z;8GJ;>Gr{2s|>?`E{)spJ4Q8?>Zb1cluVws>PPbYz7u25>Gr?0r{ z_b4xgCn&^YD6?JmCvZln=QhxK^#Uq7;F107H$imwj^F7!_@`I<|A?nz0t+L19agsr zNmF6g(iBQ&h>nEzfnX4d}tP5-p5ThmNdSutco5+k#xEl z_!eLFCIo)jOT4s{Z$eh#+?|H8?k{-9!fq|o|8!lKR0(H@qMky=o22pWr7(Sa2>7u1 zoXOIU_G#tP`sR@#B^n6#qMb+=k&vXye-x+VPAfyP`-%CoQJoOJ3#Wn&O*GnS>qKtM ziT+8@0s?ww5HKRie2RV-E7UgzO<4{F%^}phr3C5-ko(V|RLKUmKEA zx2uh+Vhs1PPgetT%Uk*Y{%3!>xyuRZ!Ehj1N+S+UlNuc>~IJxScqE~SK*2zxiMDBrT) zB~NXCvygqf=XXl`C%1^$kNoj7Q?`v~x!om^9l>V-m!S$^LSq(QBSCSGv8N@$k2MI? zte_|Gwj$ZrJoqnS#~66~XT7Cbb-78&gmK^EXka^EyqhC~kWSnS`1;$d#4tFWK7D0| z1lJphj+5N4iAxIJH+m-4IiD-~SUnmVy8SWx`$N~= z^d}o?u0sTvMSfLaTdObq(ovy2DnZsAvE`&lo^i=0;*5-wCQm1WAV3q*wL#Rn-H*0* zY!O50{DE1UlIN(WH-Y>rjtG+-F@h!s(!~N?cI@{yQ?X-R+Tg~~1*KZ3n_8Uw^2d%+ zFV3W;9FV&7v#{QftE__`{Ur<_P4-~-qd=9@D3Wbud|3VHqKWHuVp3m0qup&3-OT;R zjQ6;!O$F3Q3zIcJrka&?IN%&{kidLvk({(27AU8d6W1X|y5`yF8j$pn+Xx*tbK{6S zy9ejm<$@|3B$&uLc)7X`z1Kdzrn;#eyqrfT5N78g3f2AEW4+aPdJzL)$C2A3{>0~L z=}c8)BJ$pn$gH#*jnj~Mm4ovXH^24a{qeogeQiCqK59ck%ySn>0a@yqoK4uZ z+^5VAiRKW~E~-BuJ%EwSPms)N>=e^?6}_pr=d%$r4;4vtrSz8pQ;0P%-Qw)&qa7DB znM0EW-HvwH7F`WSQg-|bor1NUfueWmbyg@OkQuh+!3&&X$5cYmSgtHRJ zlCF$~uWIJ_@nL?hLiWlmUGhwvd*hbE@>TCvce(2FYIz+cYmrrMvsKpmcO)uq<2`tc zxVl%Y{fPFWv^;3uy+7OMSh36wdjaXJ*8FV?6_Sa-kkWnrnF70m<<4VI2JHde9QByd zz|031CjQdiAH5P^-6R8d zeY2`z`Yf{&H!NAX-2O}DY2U{Q5{{ZM@_inlp>z96rh`xgmCO&*=C_(^>WLYaFu?aA z8qj__CvmO2S_uI?Ra=z~;W{7<{CzWC;X_`@4-EDqF(;%yLxufDoFNkxz;542ftxT< z0XJ7Qnfj&guJTa)VD=^)kY6icP-Q#82vCmd2Qjjd7l+j+#EtfiN73ds z)I4ROP`d-c0ZCtuNN@cV1^bG4Y1|`h%*~iW__XC?^Ssj)D@+Urcq4fRJFOH zEA?qt*(dV|p+8db3Q7#TigV{R!t!k7QS!rD9&d|=srNjLw#|?=wAl`O5t)XGZVihC zU=L>JHA=}uYOtxlgsJPl#dI7$P^`BJnmC~E99aM%P5rHf;tl1#6on1*6GcaFO|)<% zhw3aW$$%UBc6+^RwB;N*LK|!egRW-0!e#?SWu(>_c4-(?dl#3bqO zv80E`r6JmCaz;ttyrR6i3BeY5c(Ubmb(P=T6BbEw6>NSjNzN1ONcTj9lox{yNx zR@rVPAp`F-j_E}YtWMqv&CI{K^xA;htvxUhs{}(0~*w64dT5T4F5MPI3sG+2Gh6KcMN5tKX zF+0fEU}5Y5E&Wg@wHkeiE||zMOK_2pFV5pH9>RrcVaP*492WBAU{+MmX3`=o^>{yn z3MGzXt7$zu$OQEw} zD*Ey;H-?ar##U;mA6ci2GKbfozC-=|&t(&%E>fgqGonTT*QDK!yZgA*1niEuPsz`W zzPjZ6L+-F{rzSuxbar|AwU~g-8rxwUK$5g`_Ja&_AjaB4vR`*WG;;Ra7Chg6$`3Kv zw@V0V^!t!L@ve1$X;f}J^9S#1M~)1gh$Ss~oJ|_3MACYO>4khDexg)D2>CDjWsOvF z_nIM^!o4bgqdJ<#3pg5WkTkd=&&wwK+X3Ud(5^IE5Mhz7H~+-@srdH>CuL_Ebk zhaZJrj3(ez;obA~XAgl2B+n#titaTK4X)fLzko!|BdRY{*FRfqB#omkm?bXKcXkVL z?1WvetkDlhkUPpRQ>YaDzSRw+#^1H)THLHOKJedlxx!oned0ATU9qARb#DPCd8aZT zq&}Xn=yLrUe(?osLpoGbY?arbF^?Pqe>|O4`_#m-nP41R4AKKer{+cSD?lZ!SY_$W zY*~y11(lDQgD4JiRdYGnQ&Uas=hLT;&e$~_m5>GYAKVG{#0`Slf9^9)g*am^)s&55 z)N$cfn?7G7Wp<~-A%~Ss#C`~pfT@qizCr$4Ny;SnBm@U5pD103glc zm@3`1id(lkR=Z9Gl0`c~sOw~$SiLTE=qYqG5+}(T^S#y5UIHA_ioAK0MATypgIc+< zU_;IM-su!K)6czn%NPw=uf0!?$L%$aOD{7GKAS+-)Dp+LJ`Z_$@Cj264ZOWw`iQZP z4Z1*~<=k=CHT_sH+wL~8fRKP9pI|{s(b)}477nT6E_$THtmwhh^61WtO!D;X@&G5n zn_bKyt^JOU->4XCPlx$c`NH7Gzlfyu#E23Ul8RV#k%~-R?u0Lhi84s0!^><+%UX^c zPM!_L@vmq3T&;0?UN4DT!AR6Sk*R61h89=lZ8IY~ZCy?1hlVI-ile$0K(!tvA;Sh7 zPAc;LSR>N^CObeT4$|Vyx-L3I^{~O{7nDw&lEtG94T#3+)#(2^#CB%!(VTy{*!iyI z%mg5kuU^bzipp9<_`PNCYb`E0BI1(-yPgG!0K5B~AnSALF0`VyJxQ#W`2m;>+K@{% z?RditQ#PdvlU^<1pt-1(>3Qr!V!GREua$AwdNSQOAPYG4gU#Q2XPY4VDTHC{(>b(x z5!YHHKi-b{1+e;DImXaP5c1Wd&ZIZcDDT9Z)95(g@LRBMEn^8UQ4E4i+s;@hnOVJF zyi;=PEZJW@eok9N4_krA_E@bMbed9p<(%#Ci_Fha- zmy*}C=}Ud~CvKy`Gw6`i19i9%p`n(`uodh5luM#+nSVut{y5x zKrp!wINK#(N&yz9Yt(b;OHS9%SCb;}0kb$pC3u|jrtUF1Di`$JA$_2l&^4LI zD)X=S{#dO~Fm;W2xuJe>3@~t)T^RzsoQ(C!Tpy4b0t;iDPK|Z$0Ri;~WeIR;(MnvTWnWahz7Jy!rrg%nidb<# zD>!9|P#GUJsq_6NrKoWN+XTfXtX7C&P@t`AC1%8msc95G-Tgwd=8?-FFDoojx5MVA0hrH@I3{IqpH>F(OUHFyVl zCZq`dA$Lae=O7UVBZ@V|W|P{<>VqFq_9+3==qap5*LO_wwk^)aLR!rWOnUoGs2n+B zySL1hp2ex-5IvyBeL*{BW72^pi@ABcehzq5XUGx4|57&TQxla1UmYF6Mnb4pj1z4) za^#UOrcn;7a3b(Ln867Rg$|IBgg!qxttD!nHqgGp>`oIWg*0vk?P)5SgoZE#HCk>0 zXpW{9QDdpZ6S>%o$Ly7nbz)tvm&`#>;5%_%Bbn{qC{fjx#|NEJ1w_!6$=6F~73Tt? zOIyBAp{akSSK(PcC68TP5KpWvnQq0Oue(S`7_pr6mU&!S_@gyEW|7`Q?D6o0>)d&| z2%iV#I;MGub*`}b`{8$$w@}@OJsxhQVVt)fLw?YSrEfQHTtvrMogSX!)!bFuIayof z^*74kMLx>}j}qTG)vY>|m(>{p^MH3K-NcBN)&{U`o6Xn_g8;HFx^zA+@~8^{G)KG0u&5h(>{k zm5`b^$@yIivb-Q>0_Iz1%h~*8Ri-KesG%124x_Et^3Op8lh5kmcET&&TdI8A8iamr z@J{P??Z@6$ib3r4eQ{gvrKA`p46fCe>VIe5+!dlC8 zZ2BI>$8|NO^4#Lxv|d4KV|oLV1C!{6`TEAMEpU7LZLAH1wb_b6qSn#N=COvbU9}L7 z&fdjGv$ayF36j8g9%)BTn;#b{K)M?2g?r937s;E5ffJ$P;mg(<<7)tvsJ1|Hgv<85 zpiqNU%KD&mI)-qA-tCXE~v_zItmUQJ{#CCGl-w-nVGPsZkRQUjjd3< z*pRluuRm^)ouU;6UXDt)cbGBF1q(5QhJjYMZtvZ%JqMEgbelPom{o6AIWn`Z$Xx>) zc#-&qQLM4YoF>a3w!BY~5l{vn;^Bu#AlZdqOjpbd(q}XVUZ&=97y_QfA~B=!D+KO| zBArAF9WT+@jW~@wTa0D$?;jV5fkCQ1B7l0a)sr8>4t?__B` zn4IeCGGm)bG_S&6!Si@kzHh`{{CfEnyKVNAe}zjbBxKpo?YQZO%(Z&$ z$XHeYY~?7xKIxm+kSbvX92LaxG+g-FuM)fqJjJQXubhE-v3AJLo7pvSIlZAA#NHwk&sxC9ck3?TI?U`J>FHecSLwJM`+^UP)4v7HCLfvkCUHp0Q zYsVT?$N1`H0#;>(aW6ht)psDH-4hTv?t+Ow3|u68(oc_L>@>@#k|4c+K*5qrasBd; zc$k)WmvT-k6^B`?fJZM$Pez-K%aLkDni!LN#x7W>zx8OF+Ii-8m@V@16sk0-lm#-!LM8X<6oHa7 z&UQmxZ1wURoSOuw`VicDJN`Hn@3+6nG^}vM_jl*+LpB);v0!d5vyo}WsHAm8B|MsA zwrM%?NSTW|@1|cZ}SpwUWCbx7?~{865H+wi+Rl zb%$gEg6@ZCkxhb8j{0)EsX774J!r1-Qc_pht#y`OgVm@8DuVLz1#)^vQ1Dsp0)4Mv zinsrb196X^_Lr(_Y%A1Yy|yIA9B209YMaeU>mg<^HiNR&=UEim&V@dzl^`I84Fy2g z`kA}DL?lp6WSiPH{!-^7vHYr z;d^OP`9r)6@{QQhz_gmo@En5fqK{VOC?)l)O|l_p$2WPa18V=OJyge^s3gVkD8?{? zovK5KboI?wxH~-i{cHfvq0ziXs2g|wnAW;elfRxaN|PPvsTOW|p&-tJ*)7XQ1`#)$ zu52Q3y8w3|;#dHc2+@vV9!s2`Zp6pG3Mf@{dp_p`*uB9j(vC#p)JvfeLkKFYr@oRM z9alPabc(;~AUB$?P+thNTrI{LX+KaR;w@*v3^O6}TEiqpvyFG|E&HM1kDFOl!Icy0 zS%06$h`Ba{j~ZB8&CLvuc$R7FcH2g0KZ(2C@P^ELJ~l?B|Gqb~4J$e-Z$}Hwq2_Da z_+UZ=g!~3UNOfEjw?X`p_ zjv5{j;8=aiyAASQl|a$-cW*?uLSrw*&bsyoNucf{CenR&BA~n-{8kc|y^mbt_b_=V%x7EYiLdjEp9dTB=uGcZ`44 zF-h|4E}41;+V3Aa=B9n?deG1dzKqd;6X+?0+`5g5_eEZ7h_3GKJq$*{Qto4jCJB1( z@yTaE=?{cGW%dONKjGDt;azl1-<1d{K%gF zE%I1(+RO#KLZ~zY(e=@ZZw_=~RjXBf-9$Zq-R)Z1QW`c?W|cY%*l2Ki_0BkcNLvJZ zFAdZDO`yllCT9WY7i4$3@OQ~Gw&>KD$qF8swbL%N@2@^5$1l^UAJs6?aIp5tx>;x> zsliYG=B8T82ZP+`1}?#Y`sz)j9!tv6^NvRk7A5^1J3g0MD$?~)h>{&1O%F7cc#R`) z)LU%^gol2DzTo?-%|O_jm{Svq`LJ z`++YbDzJ<(WuQE8P%)p|a}&a91MSc|`KwO~}}0|Sm~5>p6zu!8SZ*`bZf?mJ;$ zYOc@Et+RZ+JlSQ8&oegvN=y@mh)a~ZZ=6&09ZK3Rf&qgqqg~WfqhWIR2u>j`W9nMG zD09>`R`q8R@SZ{!C7wPp26BikTNj!1#=dBarcnNZ;%Ohk+dOFeANfgj2R%v z3ByQU;OeL1$EFEt>J-+gQ`dqjcczml=qOH-3EH2S((n?Q(q&DnN%=i-$ zYJ8A3)4f4SPs>733ouPDC!vGq*LsIN$Ew|1;UxBw^^Vl^l|!LIrEXmVCCU31d2q*& zdLPwvg@i16O>e;M=P)};*+K>n;OlpB_;ML`tC%(mtd55n?w7A!4t1 z+~&S@eA{I&JULz1TtF7gFKcsh&jja9p!r;AefN{ckAcXUg58&(nPc`|8W9!j;}W{$ zO}@C^(UrQx`ja)k5@npYWTw!DW(Pk!7Fy5v*!FSDi5QX@!z_HE19bR}-hAD^ABXL= zzd@Y695-z-ynG+q z9$W~%^7@67^ouv?18r1r!%?d1XZLw-C5EC+=7ylSY`*%j{I#G_y(Q`9NuBIU3#q07 zt?{Wldx^hR3#r6^tQPW*pJGhq16&wZkK zsInzZpaml%XG8WcEsL%%w83iO&G>01nM3%BQz&f{{elM8jL0^Nkt26pO;(8=K)Aew z#nF%uIP4sI%M*K{UFdoR;k$=A6}Ssxlg*uK9QC*QPt4S>R4Lt3gwwkNQ$??a*-Y|c z9x64#SN?UQ?q0*Hjn7d2n4TV_60{AkZ--#pIi?;4`}p%@@?VIQZPQs9UE3XGEfV;W zm-k0jro85AUxWGnh-5_jqCjQk7z*T2OYvS_@kn;HY%a6DOBVM=!7qN`PVx6WkADWX zAmy>sfkcvhMeBHTK#(UIzmW`8&krQp*!D=jQHn|0vgC*F$AO3plE)jfxma~GD0LNBG% zqWvAP|7!xDb zc7T4M@Hd$Bk!yd9gpOw)t64WnY{nRBVunY7@&)ov6id?RIH>LS?qD3MOtSgE=k%ntgWJy%8W^MfnQppV3K1i1NH<95S&^G$2#KlZ%UWl@vXG5 zI4nHn00_BAhCxgfk>za0cV56(-qs)<`f=fSjU8h8@T3^0$-;wbY}@V|0TEpD*+0)& z*=gXrj2r;+D0IR8c9UWyLkr>x)!0a8c4o4N;V+6a3LSQ&M3gA~*_z!MItK2nYDeqP zn3&t($50`Ps+X3zZ)3!YOulGpJt3<2Fma$fe)HKQP?Z{AI=g>9XC4^H!rX!%P*;Tw>x z+moEI*D$=#OYx!xsrkx>zut(piTQgSG7qiyUY!g-!_JvF-bS}N-bpOlQjpO@0|7`v z(G-a_STF5~z2ypO^seVNSJa@%=KKpj5nBvOH}BtN(KYbA=|qHuQO*m8V#V=w^df(G zt5LL3IQG0Uj)$tvUwcnhif{aRdXUH4RF5YEO3BQ;dY`rPCP?gOe0sG%Cv<6l10fME zbU_5GS9787L9))vMV^8`Vk-4>FfZ)3jq1wXrLM=b_``N5Bxv_c<6SH<(&@_Nu3TFcsqOjo;an&=mWPAR2xS%<=PH&*{#ocjBe>ml#>!#CmrHh4B* zxuuLV+V}~~#LaErCM>e}WGg!2jJ?M_czSaAE|#i`9O-K;&kFZ|g#@-X2N)K-4TwPv zoj*Cx33$QF>*YJrCq|bcEDb@l1ya}KdkMM`%!m(uU*>)!>7GlRdTsEWKqG{ku7>Ko zecEX&ko-v~IlNB#{k$ctku@@vF69@lpFTk=n)*UN;^i@f6yk=AdYIPm*mGZ1W^Vx+ zPQ0wQs_cc>JTi067#YzRu zu>C{5h^guw-$*96thf8gr4a=h@r6$HLAhTDiQ=H~W(IkB6$4tCm$wKK2=Y@_YW(Nn z=M%LyqbH#zA~w_vDmF9A`(emRxH$eyRQ~K9^diHtt_VKtC3))v~mh{%`LX{ z&3hi)gp-_R22AqA>6WTFcl{W_NLcQOkrAmYotqyj5d({bYcWgJn4Ixm2UY+XGM4U# z|N0~Rdip=Ik}BzgS0;pWtRB#j6{{z%>-$y<3sFare<=U|-5f>|dxCsG=WozkOHR#%5w~of+!@9hHc(edKxwV< z@H&O~Co4=gLob(r@4Zz*=V;{s6V0Hgu8srdX}p{j(UV7e^E#a^!ss82_#MV#43kdo zMB)v<7t6kuslv+Jk`@dY#o_Rx!!%lb+_-S?A#k4RTStjU=J3V`)&3yeEUK7pg;0y8 zjmN({L*aa~wBeuH@<=9HJv=oSiEHI!;&5Il)^LO(e^8%Yq9W)GclWCw#Lt4GpZP3O zZ;&JAFm0JrIh%`>uavC*=@(pUi{ESEk|bEU3maTe@{ zv-V-rWO`>SGp`jd+=lj-7l|0eo3}9_D~SiTdna(N!n;Ya_}ZNRO@D`Dx=sCHsVWvw^o zBtHC;(N}&yp-Q}?{A|n7U-OG{zvBao$m}cgQ8~MdU+5Mx|A4u1^UeP-d;spyE+#(E zaYW9*;%RhLt8@e$APr~Lpqm+S)=V+`^vhPljPMWQKzL3)YnE50 zintL?#k5g*jz4bJo-WC_5rvYPYD$sX3dY75luM)9o{F)VY@MIhXyR-}SBD)fwJfP>5@vTM#zpRy&NCgug3TKMjs(}tTqQ;})n(0r~M zc`NWZ{<0ONd^c`R%1FxGn`9<UTCanXj-o7ayuoBIlgLP*lf*E3~=@I z`3)_K)+?xcy^}c`zMWk9Ty}ETWmw@-n^BCM5%YN?D4ZTk z(J;*NX*IX8jPx1dSCB(^#CI_?|5_);)BoE#0nlYY&1h@LU?r%Q0uV=cejzERCnXce zaZ{AR%_^qmF{y(JjemOXW2yExue<~C`6U5_JWNKWeH6A$JnK7DtF59gQf@lqpi+sc z+lH{Lv{ zHg>vuQ;DNxFWf!ZB9l6c_6{ppTzN)vjYp`*lMo55dSF_897U`sG6v*6`6^x5-zQ6% z_50!t`M5qO?A<(B&iO}Pqrrg;I6z3gslD}et!1}NK9#2juFXv{Ih2-lL=!&MaQDts;dU6FhlB<#%s9yae^_GMVS1`F5(tp%5Wref& zSuwSU7qI$>KT07%MY6+QtO#=}gX|upLJCw&ji(*pM9mI^TnsR;%$VTqKshi*bTZ*c zy|RZIpLU28xB(}{%{dSSGByXpf}?j?y|IRe9tHk8nFjBDv{PYOlfA}kf7(1-v#)H( z=9Lwo)!O_GWXq#%T@u z9&P4FVPun7WERE6D@QUn5Zmxry2dztmrF})j!=Pam3$7Zk)G_Qya-AzjQ_yGKJ-&J z%!G}MQ0DvNJuQM&u1g^M8%HsZYwUg2e=4PBDLp*_LpP{0!lakKLx}g?SJTGjYD&4d zKmoL`o859u7O5B{E}h0KC<4Grl8?)1)4Sza+*9cAsPXg809p#0U`qNh{$6LSKpp4ItHs=>@u_Hc9eTz`x34*A8RV;%U9 z;qeYRxsEd#F(knOZb8l?oSmQ5y?zwb-z`#)4Lg-KqCKROaO?mMFym3e+iO!6HX{jh z+3t4=Wd|$eN>$d*hx9n8%K1$iLL2iufjK*vDz9hcQic{P`lXY(koLfF7!}Gd1B_rP z+|J`=6QZf+vCo^I&=CvQ&#;QTxuLXRGkW<>7RrA4Xm2@RG3rRNR)TXGh9^PHpqsvD zJoe}5#5`8mL1YZ4;=U8abvgvUy%RG(0pt{$%K)kI7hsb1p+;6-Jp}#;? zSA@i}jwPz_DWJH=At%b^vBGtPy>F1ObUT7XsL@h(c_er^Fyv$y!@6eu0Xu^L=My(z zpw1hOgfzZ9k6-ZAff7T=RYpC7VEc~dtwGGGU#=Ca*Df`zNI*WQ^;UA;8gX4KbO?*C z*{q2g?1(vT!pcoM60pMm4^#|8VbO{(fXz1|H${q7mYA>OfqydHy3ALm9qL;iG04k5 z-IZK%a3W#w9vbs(??6fK1rdjX@{Kf=ptdxV&6x#)hUhIAmk8cH7miB@D{)4n_Kx=; znixpt30lQmeBq~%H+rtTMxIuW?{5w}T{B%Zx-#BLT=7|{K6qYYr8l5ckL4(9aA2fN zg$2U^m_Dk~0s(JN^{PzImm}2O6MU{a8B3pzi9*I`O0?Z+wNsc3lrdKR2)e&T;(jDe zUyBd++U+=Q2X6*8O5*XIq{-)tMIhn+7v z>8`vD$$$iiIJJljjMR?yL{YMxj6({RztzS*hQ}MynHe-h#4$WEWBY?zU1g;4RTV0U zTI10uTA@DJ!!Z1o5;Nn1OjwAC;vu@Oqb9+F^lM!2#nrn@Ei+-_;_EcgCnBrB3Wxas zqw=po5vQaUxo~8T)uiJlGw1^{{4O(_Mm1ikH7|mlPYvlx$=c_E{|#s)L1<4I`ELUV ztg7fYNcUxop%=&~(OMe*df__7~yf5IZkJvz?ec>NvS7|fqU7;A`Zg)WFE#;yt`n5K=>k{qUUI;2H) zB-sj^#EvGEki?LN)By}pXG!_IF>ix;|TKsLf z%bg6U-?7U=&C;jeVIeJrp2JNPH>h*O<`)o?)_bTT)2HkYq@d+%5Wg2-}z1~ zYlWQ<)vgh@y2E^Y+AS=;%{h7BmNpmXNLL-9O=m?_-QUVyrdInH&AzWZkc~1QC%VM4 zLZGOKE@l5c>{VmC&XT@(6EVB)>k{d%6WOb)=dou9fsuOioF;}#lWX}c-%nzTPO2mn zn8DhQ#?$kbD1`!wB$jXebi0!gUq{b+zf6!coL_=8+#b~%T^6?VJiR;nz^uzs*olEs zsJ7?Ys3NI8a1wr`x8=6-45Od`#SI&)2Vuuu^ej5(Z_gcq%U#;-?L)R*PCI+TbBaMv zN}qV7-`#atc{WXBGhr3POl8F`JCZ}H<3~dKS#gl4dfoa>epa4r4JTEt)DVP2fo#>~ zVdc`8ECue@)4pPsWD6jhhtyun@uk2 zvBYp zG38yTgNl63$X$9ys{48B^NlZtzh?};XBv*7q$zrpPf0~ZsOGUoUpUGvUHI&<0q=y` z;4S+2R>_aRAP(Fp>{QR~WQyLmr_W!wWyraSbN*~$7b z*GNKU-e7B7LnPC~FTliRq}2{zZ-*d^&0A_|Rt7v-aX2!+s~-7ZV7Jk>b6Q^3* zZAYwP$1Og*2hSSkTWMBOchDkQ`0n)tJY5)om8VzX!$DVN7x{{Zrv#a;p|5JaGb1;z z(}eC`SoUB64?P}&SjvXEM_O*rTKh(%e7%_c-3IGYder}FX9c_+NykkR35ycp0d5%` z*C~z1qqGj~EpgqE$DLUrPVxtrK&vn@aMo%O1DgxV>u_*L=9V=kT5f%c#-AkF*6bT1oeHE7Smue>T83;odNEz^de-O5MY{_V-;_L?{yL0k<)z;! zrK0knJHE*j*N0Z#(vZ%VwkdqVkKxEN@G8!CG2OiV3p7Pw^!7c67-GxDaCFTLTzPO{ z_SS%~dZ8jndz1SYiYRDq?%;_A!PJSuIuj)QE!yIJ2%=Y(mLn56>U)-*0$s-V{t-vRB*;dqWTD-c@M`vHlUPC7(SBBX>Q)A;8Js(J2g z;JF8h?3WTv``7$h=lD8SJjvaYgjKKm-)XXuT^HQdazs_W18x_J@lB&KPVXwqmQN3} z)8Whvx%8HOvdaWiWT!9d2Z>=ugSj*3b36`@u0%tH)?AR8~Q1<9W0qBrtdB|y&P4> z>X|c0W}iv<)XWXM)-ov38Y~pMD#h{2Bp98)7+z*<4-ToJT-g)t#&!?z5N_gpx9t>6|>UOpRg6@sEG zj&^8UKYTbW5s;7q@9g+px_zZk9VS+y2_N{c*z4j&*PIKWo79@K;fh<90DU+m~@qxp}Bq%O~T zhTHdIB;!|}yyH$5DWCJH-$>2>kUD>sA|wY~o1JM4E+fa{UMN*}yAp57{JAb58}fld z-`oGrg*Mpr=A*4+v}0WXT~UhM%G7}A#>>>vte{Oqlccrr#Xr@P2>vbVCTztI%HS4G zu>#sEVMkd&Vys!xAMKHTi$?ie)@@0NN)K;h>5SbAN4ol%Q5z+gqUMnUHxrUcUXiW5EEP z|L{Uw>R+=-``dr4Egp0U6?o%Ip^1vzh~i|%m~ou{qm32*pW9dd&-Qot-(SW6IV3Y| z-2>HGOfTbxDp!pjdhOrR1g@NK3=$LE!0zX`T!!M%SgIUJn~rD&Z13)cbA&@iQO1|! zv-);H&@tsd%UY$5w5!V9RrkC8@w(JYnTTCd9^6?XJeVw zUR1r!PCBtCWx^a-zy~M&wb+baEYZ10>pcyvE8lmD#==&R&l97kk`ZuNh$vT|cV4;n z{hN^JPrHkp^C{n)Dr{MW+Bv(p^1@w@qXxGVuPJXt$2udPts&3}a1U_)zsk-!D$2L( z_XY}x0>e-WNJ&dcNlQz2NsJ8L-7qL1(uky_5)KVR_ee{FbjN@+44nh#*5~=1^S;k} z);jC_J!{s?y7#{Jz2kFz_q#V)%FV>d|BY;!v?ef*CaTwYR8U`)SC=o*P0K)6Rb5Tm zS}>NkqfXB^-W)}re233~ksU}QBJylCr|jca4~*n}+I!vxYUQbRckDf4IGg$u1tv13 z7ARqmV_epU-M+3X!U|v>UXqf%Qy|#^NP`HT#jxk{Ull1zUp$zO3LALas|8Ip1}3%l zHUOuFdItj94SoHlC#xjuV$K+gv?pDFOhm)a?a@c^{>vilTnRPY{l;*vfaZtb3AM8? zJ+BDcr={Y?-YH@hO#NK&<2W;y-tRL%Fl|31u$0did!N|kV&C3gIjvkTcW z$1@X~Lj><`5|CL>adLN}L^=LOUrfEcm_DH&+4MJb@Buv{u+NaWI<#6LU)CLBGD|AG zz_-ZB2r`Ao94Vi4c5i29FfM#|p8YZ? z=CZlpkSfYOz44*9-`Jz0V9`u`md9s#ULrti?cUd-b^=`vpC4|&2;_+-dh-NOk`37R zJ+SGdmpv^_h$Vhb{{Aq`ma0a}z39inwW*eq{_AVCK~R=v+9%*5FpGvZ^WJdQa^8cm z4+`xGg=%)AStp-~QfLf(f%$&m%o{sV!tk##Rs`RS&rk@E$X6n52HiSX+4g<2+fl@X@{dcx4i@6p4OF<*%=r0 zbY-vS@_JX=#9D0}_=TBw|C=v4e$2>j((M!fnAK}j7~*G)V0}Ts;5Xkj#KRY3S%aV2 zn>G0EgeT!WO=#6Ua0B*S+@Y7)A6TR+?>}IXe6H(Ss0oz82|BiYNs#;)8En_vXh#yJ ztt1Ufxn$zzIlN?6 zqA+9#cr`v>)Q%U|{%x@TB_X|EKwVwVYWb`!(4fdkMN=&yrY23XDkUg%18kr-2 zH<9e_w@-SD=imf?T6_q3_(x=7xc)luQ$-t|=>-2b)>;1I1VZAqk2C2R>(4bOuTB_1 z2;GPj6~51LQiRYlP8}KQUtde47)ZaDx2d_S1}RA(*A^Sg=qU6qIrxa^?M7TezCtT% zEUY=GD-ZEa|;_0m2lK4G9Ut=I|IZr}+=yQ;r93WViGDz%9}c`#(z74aE2 ztUXRr^qPg~sUVSLK4m=j7r!qmAAgE3kem~pm=FWWQJ+ft^vv6|>vzo|RurkKG77yT zgRDCGZ;9_$R>Td$;qLrMKvxJSY*svYYC~)kXC5N?P_{9}H`??I8+8K=gxKsR53yi! zlC>18PH8W=8pl-cfUUjENI-nYaypftB;0(T;G!OxCTu!oLQBa z9;W+y+!Jc?Q!{eME?sMuat%LE=Gh4A0jWnefVw9z(V${{-aY%p&d?E~Bwh8R>0q1P-yAR=39pRZznQ zM`K)CZ<2c6qHC=EUiFh$T~crZ1%;9nnz?evpfKTV`&JI;Y+7%a_W7|fx$w?MJrfMm zn5D19M zcph@v$#!LvdGY;`-uM?-Q6wfJ7(tI!~1~_j4woBN=x$ zJ2co~&ze{Fdqm7u>GIet4`nYGyqCGP?Ej5WJexFGF#D@_%6{J~8Q# zqz5-_2sN4p_V+gIQoqk^@2Bfh(Ky0U_@JAFy9-zB2XpL_hiQLCL&u`#&~c z(+s$+HT+b`hJHLXr0iSno$ELIc-hR5e2-phi;=zeNeM2%TSWF-2mzBywRTuX!5{gX zC+|PbS34Hp16qJygWqj4tQJ~d^{YG!s(Sy@uN54VA`mghN+Q85z7huLH^tYle~)24 zYWXyb_c1QW4tDujU!_Rn8LP?qudF;D6DajRU_|(=d)+?sb@F}pnl{3k){p6*7BwoE zv~=9bdw?4c6U7qek4d1}#k;g$&U=(&oTz|9LAxn^<*g6009S=VFSYYt5Z$eZUWo~) zykOLlv7t@X;l6f#Bl2YQqzfWvMfOLFOzEnINEF7w-nw_7;q)W=Y_Y%(_YzBYwtZ!m z9KREr{&bcN@HQK8O*q-N|0?hB^=1{j(bwgH^_>>=lJt9W&;+_;oTthGKfM0(5VKb| z5MRq{V(nkM-hnhUIFE4vzZ`x#pp-`3sA`o_Bxf)|=q%*;_67)ZyQ zTCO#NIf2&L7b-{m!gyTvN;itn)`Ab)+WVyYgnNBWchiMW({C1qzpQDItZAhe^k}|S z>^*E_3KU9MIY?VGGl!}EjuR!nTw>3dpO304xt6;{i`W!&?Bb)G&W#t|zhbwbuA)~o za&VyNgk3yZh&FD${?5p|Ega#i3hRg&N&h)v4cwd#cop7&?nuovsrwb!>VDDMpd^9) z{kL8KpAYELqx|}9fWX$x{PL=FYSY4}&j;%INHBm7bOp3*m0k`*F^x^lpbkaiOKk%E zqH?#a6%?os7C@EYXZ)RBr(?CsH1M>6pk5z2W47lRKt3Py=%lU`w*fn#b87?qQ!PeD zabT(NT(=f#JiAwwmq(K_z&y1Rvwtzh^`!Xx;G|l_D`LX)#O9a$)*EhCnioR9;orBf z2#Ov#qRZBpt4W0R(4dyrn9oy~HMYX~>5%=72*|$AE=ew(zeglVgH?atgaSLCyde<_V`kR(0AlGTMP&6rD*7?=1lw5{p+ z4s&3E(uvzMosDd}yCUz_SM2rp_(B%Tv67$(KQW7}HlrmG=+x>TmKK!Px+=7l90Umb zyOQ+K1h|WCmR<+bx1 zlzYL9EQ0sfIIvCZ0*Z`+SsZaY*NoKb5#?gfX2Z23g9D%0HQP&~`iZy6c};xf=rpL9 zP6fLsJu>}ItzQ)QXbivn6mDi$=S7iz1(_|AeB#>~+|5lc;*lczI4gB~caHU|kg+}d>ikVIWEFup7e&U|&&vxC7Q%1Q^?mC&NaTxY z9BQHz?X^N0z4ts8vR*Kft3xfLJ0TID*XhE@FPLG9=@d&R#N9KepjpUBoQ`ZLwQ$bo zSJy4NSSJqH_;F$6F06;V9JzXkUtrAjefz0}|0UVWf)oLg-a^|;wXIbheu}KDKr11s zoPfXC0ltlvQXZ6IqbE+~K$0@NcG6(dDq@K`(N}+p};cRGCzErfg3h6FM z!V+>q=SR6%_fDcQ?AK!0GT@Vp1j4g9t}+@nLc1##S^BG6jTtvK9Bm|2H#LY!7hM0G zT9HbFd1!S&j7X@?yh3wFP!I**Mm&jT(`3;#)pNm*oNJcDMomu2yy=frp<~ta-i;Z% z(kkV+^8BnEWmg#}ySnR}P?~2t7$>TPO^;;X{a>`Co#Uy82MYI&Z)G}u)2A9FSlVxf zVM#m}UmhtO8in1ffkWOVDxXk8=1Y9Jf+~eTVb#|K*QCZTOAN~ojN4hy+iSG8DU-WK zwq_8raz*9Gwwpfk=49ypE4;K~H6z9Op!d3t++!J~e$l3=D9(jt-;6!FnP;r5q2IwW z3MH@B`a~?KJ+qY(;IfqR`Er8-6=y|-__iXU^d$!)L793rzHdoOGmRzcBrYH4LnN*7 zgoI|)QxWK!{BrX1$8UJ%mFu!Lr1$xexj+&t0_X(Y*SEu&Ol@)Sx|98Cs(iwH{K2EZ z4YOg>ZIRY+MUb{(AT$4uXyqXm0D3SY1(Xg$i+2L|&RC=qs|6#p15evPPun?sPPLgp z3VKCE%$~V`4ujv%g~#Dtb0FrLaM`Qri*P5USsa;)WA+MSrf(Q1;rEz!D=3S6{&4LS zMR0R*XJGc>RkS;{2^8{BiKTF7beBMX7z&8nLH5k)1tZ53mQqj!qS(t5WJ{3#)FG6t;fp}Cp0)sfU6a0`pG~8yM13b)_{%M+ zHRR$cL45n$g3$}XBao(!7@hr|!~xQX0tHMOnJZ|M$#Bw6zq>rxc9VD@x^gp+r4;*(}yP926#_(>qwZ8^Q_mU_x zh1Z<3=OWja^ou^%IP0hBN=12Cp$KumkAOvwfEYpzuxSjVH0w)JSUVG-Labfv86-As+1Qwd=^D12%0kIrTTgQxSsR;_tUqwvQ{_m>kTg69*2W+4!@tpyt73pv<^Ew zw41DLn{D{qn=76>K9@0W0HMbyajy1=P zstHBMFJ-ybONZZK;OgD6-@T3MbVDm+=PjHJvt)1C*zHn(6 zMcgFUl%*ThHRF%)Rh=oSgde-!>7#ftRL8HM%CSR#RZ&OT^i-N%y;koS(w9J9k)d?x zo1j?M3}3>BjpCkc)fT*V>xj1!qR41x^)??vJ+&(=lK2qvz^v|Nl}2zbQQ?se4RB9# z=?CPErCouHOhy|=`k81g<~RH99>h_(=Dl*p8u#gnSTt{ny7g9JbX1v`$9b5x29(|> zz%OcxiL>H*$`$!rq3`vyU}(}Iq?=7;btg!??0VscHL`?|ghYD8Tk=hMG?f6dYqr;# zlI2&l=*r&Q{iAE1632J$@P!~<0;E0ed~N+j zEmZ$c7L(W`Wlf@}Q0NsG#3SofXGdD8a0#PJ!K?354PjVOOqAx;+l-21_!d%=Z_f^@6XGu*$z zUXNXG=^c6}IuO#{7miyE6h>^K&uNsXqCMVlyJIW}9qcQ@vKy6a$Y zy{tjK*NVrNAvb>9FdKthrWO%9$twLW7zJ1zCU%bx8(ei`$}p7{nG!9XtTkxRO4@AC zc~5X$KI`8vkO`#pv^vSSAY-(Xh!r}vQR(d7k8w!3Weju7U;4rGG)6n3%SJso`& z!RzK+@*SZWJYA+-RO-QttGc&$%iXUEo@EmvNiDP99M5$E6)(hlbr1_v_D!W|zYABtT{UqAQV5dKLc3r#+L}_W zV;}WeUU@xr)!=pw>dew{|0sOQp82-Aw9LI>x7|ffH0uEDJ@s01%T)gbfEexXrfRiDeD+plpJAq+U-Hw@`n#=`Hi)l&5^sY*p>QWg$5 zW~wgrBc~6_MF(5c5uqt>*mI{GYRdh8=5?@M>ldsPranijhiS|1%Gr&voaujG47jFg z-AcCKB6vGCCx7;kN-oFdEAv9legsZ&o}^jTW0PXCB?0sI0R~@ed^5f3G(7O`e4oPX z2!@x{3kC1l$lYpKXcjn~oH>!B;iD(z%jJGykSewB?Z`acn=m-0kGHHbKCaexbU!;F z;F*VAcuQh`?7C2|Dh96&e~dppz7;33%uVWJ_K;rZuQAzW7tgZB4^D9d{OLs(YUa7b zY&G5e`OY?CE6LjX`na!4)qaZPg=#a5^{hqJ;caL<(I`8Fu~t(mOY4}^z37u?MnYRl zu8Ga^QQ`@Vrk7>7GeVy~8Fl=!SCl+fj%)nDrEIB@R4z=?KwXs3J4O;w9{0A{vUU9A znU2Gq7aq^De^=u^Vj|+32@38d>5I{$r1(7IWQ73`PiqqHNTTwzm7?3jB0N37Nw#xTx38)JyHC zn&hUDB2cQm!Cg6gb}Vo0>Qm8{c7Iq8WTcfPAaNu`b5D9?O3%n2;06bwwH1#o4n6Fa zv{vX^bTY3{$$rN?PZxIE=R0NX7DhsPHA}fpbFf#1u2*qcim|F(fTPgPsJC!Jt=Ut= zGTNR2A}Ktxes?wc{L=beCNuo@z#A2by(6hWnrpA*>f@#ED-kiID=GU`JTh^l_89Kn z=kNbWdt9Cq!cws|PceR@KQuQTxg+d>LY){tR2J`W?Si!_{6-9N37nGnoa|L++^@YS zC=_R9jyG@6r<|!5UzST+c(&#>4#%K>3-k$&b0%fpKVxfd4p4E}8wg6`vJrhW#8@=B z7=gR#*wiwM;xsYwKbIL>zMY-?pvGXQ4BWus|9;{S^3^x#z}wb3WXUbdZu0Wh;O~GI zOI-q1BsQx84_P&D3CGL#-F1-F5$n?_6}bO3g>fYHNIN@mzoR{hCSw5EIeLtm94o`~ zjag_xWy0DfbgRAH(Vwg^I%Jt4=DU`D9ub%l{_V=lle29=KpVbYFPt!_Ru{ODSU(G- zd7eNCVHW#M-FGFMI4OEa49{_Eh}OB zP7Z0|!&!o622P(tiK0!a;Dt7pvuJ$UuUoh11Z+-aZSSB4%iP+U^r}jqa2M36k;llc4FE`7YhQvVS87;l0Ef^;LSs_ksK0Q1{0_<@D&ngj>2M-xa z!HBAlQq=tv4lwEerffOXj=xiR<;| z;;njGAT~DWg`RS?jn-0^k@9^bZ-(ohgG)#%8`@POWTg6b_9{_lEC33G^^R)x9u6S={d^Ca_4@eki3{({Q>taVuyAb`4C}O$`xS0R zV_H{)<$_6L4LEhADYFbHn;RDmZo7J z`FkJLOP1X1`anBMcfTo{+)Oc3FWkRItgEI1Ss!JeFm|2ne~NcMwaULrow9?KWj>N^ za6u@c_p<6(d#84P9kfxTovUzhrm!*k+vkmvIk+GWQS8J;|HqL(1Lfe~B* z5&7c>T>0n0!84iRi+wkWEumrIb7ED?wf(jlRrJ?2ng_+-$SLKyAuT8}px{;_>v7w( z$T5rs+C94(mw#VTSoj|!>AHe_lmWCv~kLAL0 zp=&~DHY|ZAkq_9D(0k`8ntgM~=&Wy6GH+2G*dqY^oSckSFp;txFdz4lEm&`;I!~0sOAre~M4=|A+X*bBh1az)1Yh?F_yDxt+oMKd1NQ|GAxE>d$tD z|2n<@|M(kc>9HCvpakSojoBygy?^Ou=mbZ1DQTaqk<)((e6T%^fof}Q5&DT;Dw$Y3XqIZixyT{nwk17f-Y2L-@C#i_ia=kB>C>HEMthg7}vBGrOYbBfoTf2OMk-rJd z6e6s3P1p2s+-{`Q5BHF!sxPdXT49mqSiY8brT|Ubnuzg6FCJiRRY^;ynIBi`5$ZX* zTu?ir$5orG_cSKYjlOPV3KGaI2B0*9N#MgakFXn$$&{Zaq@&Hnwt1FkyS#yo2wv2f zd@~zKngA8gqA}x`Ug>pvAozY+INv)_cuf7;88@_lD)1A9X&;<}PDFEq6Zh|G3mkQX z%@v&_TLGcIy{z7r%$c(O;zG5x`rYnORru1#DK3;Ww(Dak5X;LHv(Z$0GRccMUM!3z zHl%S2m&u0CW{Axth7MJ#(CNji&S?r^PPxP^D#Vvu4}%YxPu?6oGXNDnZMm7pxr$Ee z%?cxiM12kOMN|9TKobOZj2;Lh@pv&j^jRgiw7Rm3JpL5l>Uj6HQN_r-FrgO@GZD^b zZ+2;T6;opbV5?!L!Z;iUk^6eI_{|LGX zVcAjn<*#r`D;Nq*uqk`q(LsN)NX7rS{vG<+9=0}{J=XsDB9rgP`G-li-cMf;wqBHahP2AeQ0?QPNOjXf?PIw&st78#A7T!o|x?wJAsQl4%O`mfSjKLS=W=aSnU|PCdGm*cb^nL&rN9cp9029#WL!+Q49`06J}tH)>)qqHVoZiaJuJTxlQm26+#xK^ zjLJKG~WOnNh72=L-zYd{SQV4oNPd zu*4Q&QD$Sn-|A2f+uSBi!o)KniK;TKdCcLtqNCI56Fq^q`MD;hgwJWp>BYODvyETn^E$;SP z<6V_d%IF!f(>)=e|D>$sU&{I1Hi@W$P`|C&G}tgTWN-+MQvr+4%a_nf`D1i~%C0@S z#b5HlU$zJlhk0q4syDZ#3-8A$%uK$z@DY%F(ih6LC*idBGS$m)SA5#Ek@Tqk;$gj zR6~vcMTZKW7zpu{VCVE?*iSEQqwtxfE<0+&Wf9O}aG4&1m1P~3X;2@;Zl`R1A=S6) zRAWf>!(s1i&@GM?Bhk)Zh^r^~CS&M_ewQcK7_Bm@tmBF$>(A_gKsjg2DJRX8N>j~G zV`fE8druq3X9ZA57Ljuik`O03_NB;}X0x$ex=i&P%BOmN_cWbxFl+r}u<#J{;%AST zrX`tX@FkzbWf+jLgky13I72ML=VoS*Nd+MQvu5?6mV zqJs6NmMf{iFWTT^neB5VhkYaKu#3#@OanP}sF-6Gj5ECPMW4D;oJ@^67TMNXR}CcO zq=G-K$n7HfZybU$l$$}d?YbR;DXm{=1#Z6aC!k0}bbsphcKU7o1vz{rLaT~@c1xRY zF=}qQe|k7(=wVm2vdLIt{0Cdx^B?J5o0D&mr2dQeevAV&l150XB)!K1py~lcqydgH zq?Xj(YDhj$-PCuhL|`~fNMuFJ;iwq~C%LO$d^%|snycCLSZA|qyGAELg-cxBEWnwW z-s4gRewCAD3WOkOHRbXHL5|z8UFYL**`Wu}^1@KTJLx8`4PO)%d5B!%_ke7bg^SCv zA{34UiHKfpZf)z5|kYb*lv@Rm)Qb4OrywoLLMgm#3u7Y@|-{#U~_SG(qOQ8LLo84 zcJ3lCN|)hH$+~|9LJM_wcuje9PbRGYxrCN;KE6z-{PHNeN1ZP}w-2zJ&9xHf@9b$wkbv0PdPbai*6S+qoS zix)R;q?In^`t%3v{nfZ{c)}|J6B>T^0z03h#XqgZ z!*LE)hW6R{Ex+S|ggjPiD=Nx~UNx-BfTHfZVFu$e!+*oi6524KrbY5jb^h%}!rR_n zdH=G^Hk5>5h!PU=DZ^H;s^$}>sb9W`$Uhpe=IEY1xpk?qaK!w=Pn0S8u}G19>1;G0 z4IC{d&ey(elx1|Ae!3KQ`cHHWXA&o=s>nlzLd9`Qdy7H^s=YnC;Mnfm|0dLj`E8#>NKbniiunSB>@ITAA*cBOdDm41d*}*`6C6fASVIKbQ!u6~g zOUI&atJuNE-QA!>W%2E>Jx56pYtV1;a*n~`Y(+&zc#u#O_BohNFdCpRyJjw@Z2GD2ks%1 zRPu#d@4EZon&cP`drS^B1kA^?{dsUr%*Gu>%g{0Q-27;MC2Po5w$LGiWP zBYN63q)Th?^gBHiEV?;VHvf226Z3p1C-k^TBPfHUqQN;fsVro%s~w^09jk=>s>D+e%4NTGz&7Z( z6uJSWAMjJwJ4}{@lX=KoSuE8!Dbd+!{kJaW?W!^dC}!ALE+9+%Y@#m1WuD{jLt7ys z*0eNqNGEOy)nmAz1bh)lUATT3>v|+2!Hr17L6cwbyKx)oQbj2x6VbrS&cCm+1YiLZ zlF>$d_*x5#9#$}6Ec(~O4ialWu7MIE@A5?0d~083Q7aDob+DW!*=2y*N7sJ&J<8bl64d&YunlzC{}s=fz1Km$`1|GMv;MfRND*q>5Go( zuD(A@FV45IRABhPtY3wCeEZujd`R(HoZ>#}{6kz~z%&>W7K1fVC4| z_K)bQ4@QuTlkd`$$+ZgWr4PX}`$;BPN3~*))S|S;Z;LlWO)ltKHPet}GFnAMRTV#1 zdO|b9SC}9u`0WGD{E|1Sz&@h9wEJF)z5t~w9635@3}X?Gb$<9BThGS;CiA%7Al=YJ z`hQ2voej}S-Sz>IbTlSv=3VHC*re`8q>lG)P_xiv~&3y(e@J9~BH z4L-i~yeIzl+2-Oc+e7VOU(gUBa|xJdSxQ=|sGQv-^Go2K6Q|Bjp=@N^Efobex%E1+ zv#1JQ0y#n_7&V>kIhK3?7c0XG{q}Q3aY0j~r+ZvKd6P4lR=RIfJeP~7mRy{3K2wQq zy?Jn%7Mmx}B$6Lt3ZD9Gfi*`Nydb61h3yHN91hOY!rVku+0!r0$htAQa@0I>3W>?r zsb-+}@x{Kg7lq)DY`Zz2l^z%Fg2ry?UT_yKaQVT%FA4KUzAKRmoy;TY`D2hT@sx6B zzfEx{Q{L^-TdeikhrXVeo(id~zas%IF-3;bvFe0P>$|xyY{Fa5_b+uSu_Y#USz&xW z1h+HGMJ8;F@Oy=Or36 zTU`I|Lj&ByD-%#ctp_l=_Mj9Q-GxjS0YJ>P{+Zpkni86#=Cab5ErI Date: Mon, 13 Nov 2023 21:28:14 +0800 Subject: [PATCH 508/518] Fix --- docs/DeveloperGuide.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 2c7e8e8a56..bac6737f79 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -584,7 +584,7 @@ Input: `list recurring` Output: -![ListRecurring.png](images/cashflow/ListRecurring.png) +![](images/cashflow/ListRecurring.png) ### Delete cashflow @@ -769,7 +769,7 @@ deletestock /s NET ``` After deleting all the stocks and running the watchlist command again, the output should look like this as you have no more stocks left in your watchlist -![](images/investments/watchlistMT3.png) +![!](images/investments/watchlistMT3.png) ### Using Visualization From 1e59dfffa92e3e58db8a1c038217a048adbe6065 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 13 Nov 2023 21:53:18 +0800 Subject: [PATCH 509/518] fix typo --- docs/DeveloperGuide.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index bac6737f79..34a2b901d0 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -748,7 +748,8 @@ To test the watchlist feature, you can copy the text below into the watchlist.js } } ``` -Start Financial Planner app and you should be able to see this output (although prices will differ) +Start Financial Planner app and you should be able to see this output (although prices will differ) after running the +watchlist command ![](images/investments/watchlistMT1.png) From 6bff288c2086afa2ee5d0fb3b660df16d3510662 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Mon, 13 Nov 2023 22:41:17 +0800 Subject: [PATCH 510/518] Fix bug in UG --- docs/UserGuide.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 651c0f50c4..d0d0079945 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -670,9 +670,9 @@ Example output: ``` You have added Reminder Type: debt - Date: 11/12/2023 + Date: Dec 11 2023 Status: Not Done - Left Days: 30 + Left Days: 28 ``` ### Delete reminder: `deletereminder` @@ -688,8 +688,9 @@ Example output: ``` You have deleted Reminder Type: debt - Date: 2023.12.11 + Date: Dec 12 2023 Status: Not Done + Left Days: 29 ``` ### Mark reminder as done: `markreminder` @@ -705,8 +706,9 @@ Example output: ``` You have marked Reminder Type: debt - Date: 2023.12.11 + Date: Dec 12 2023 Status: Done + Left Days: 29 ``` ### View Goal List: `wishlist` From 3a324b77b64ccee25d34602703c21e32bad6b5e3 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Mon, 13 Nov 2023 23:00:19 +0800 Subject: [PATCH 511/518] Add fix --- docs/DeveloperGuide.md | 7 ++++--- docs/UserGuide.md | 6 ++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 34a2b901d0..f90da63065 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -139,6 +139,7 @@ This feature was implemented with the help of three different classes. They are namely: Visualizer, Categorizer, VisCommand (Inherits from abstract Command Class) VisCommand's Role: + 1) Read the parameters of the vis command entered by the user - `/t` Reads the type of cashflow that the user wants to visualize (income/expense) - `/c` Reads the type of visualization tools the user wants (piechart/barchart) @@ -211,10 +212,10 @@ The watchlist class keeps a record of the stocks that the user is interested in private HashMap stocks; ``` -1. When its method `getLatestWatchListInfo()` is invoked, it calls `getExpiredStocks` to get the list +1. When its method `getLatestWatchListInfo()` is invoked, it calls `getExpiredStocks()` to get the list of stocks that has expired and should be renewed with latest info. -2. With the list of expired stocks, it calls `fetchFMPStockPrices` which connects to Financial Modeling API to retrieve -the latest stock prices and calls `extractWatchListInfoFromJSONArray` to update the stocks in the Hashmap +2. With the list of expired stocks, it calls `fetchFMPStockPrices()` which connects to Financial Modeling API to retrieve +the latest stock prices and calls `extractWatchListInfoFromJSONArray()` to update the stocks in the Hashmap with the latest stock data. ### Stock diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 6be58f6d4a..e5e01a4f0a 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -645,12 +645,14 @@ Example of output: Here is your reminder list: 1. Reminder Type: debt - Date: 2023.12.11 + Date: Dec 11 2023 Status: Not Done + Left Days: 28 2. Reminder Type: loan - Date: 2023.12.18 + Date: Dec 18 2023 Status: Not Done + Left Days: 35 ``` ### Add reminder: `addreminder` From e4f7d1e49ab3b984bd9135f86cd0dd89daa2597f Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Mon, 13 Nov 2023 23:20:56 +0800 Subject: [PATCH 512/518] Update add cashflow explanations --- docs/DeveloperGuide.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 34a2b901d0..52d2f16259 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -250,11 +250,11 @@ are corrupted. ### Add Income/Expense Feature -The add income/expense command has 2 compulsory arguments `/t` and `/a` and 1 optional argument `/r`. +The add income/expense command has 2 compulsory arguments `/t` and `/a` and 2 optional argument `/r` and `/d`. Example: ``` -add income /a 100 /t salary /r 30 +add income /a 100 /t salary /r 30 /d work ``` Below are the steps that shows the implementation of add income/expense. @@ -266,16 +266,16 @@ addIncome() or addExpense() instantiates an Income or Expense object respectivel Example: ``` switch (category) { - case INCOME: - cashflowList.addIncome(amount, incomeType, recur); - break; - case EXPENSE: - cashflowList.addExpense(amount, expenseType, recur); - break; - default: - ui.showMessage("Unidentified entry."); - break; - } +case INCOME: + cashflowList.addIncome(amount, incomeType, recur, description); + break; +case EXPENSE: + cashflowList.addExpense(amount, expenseType, recur, description); + break; +default: + ui.showMessage("Unidentified entry."); + break; +} ``` #### Step 2 The instantiated income/expense then updates the overall balance through addIncomeValue() or addExpenseValue(). From 9c15ad8c8d5850e0685f525d5e727189f10c95bf Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 14 Nov 2023 00:31:36 +0800 Subject: [PATCH 513/518] Fix bug --- src/main/java/seedu/financialplanner/utils/Ui.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 1e9198f1d8..3cabdf3735 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -62,7 +62,11 @@ public void exitMessage() { } public String input() { - return scanner.nextLine().trim(); + if (scanner.hasNextLine()) { + return scanner.nextLine().trim(); + } + System.exit(1); + return ""; } public void printWatchListHeader() { From bdb553ad029ad5edae0dd1397bdb7da5fe7e6afe Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 14 Nov 2023 01:11:42 +0800 Subject: [PATCH 514/518] Fix bug --- src/main/java/seedu/financialplanner/FinancialPlanner.java | 2 +- src/main/java/seedu/financialplanner/utils/Ui.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/financialplanner/FinancialPlanner.java b/src/main/java/seedu/financialplanner/FinancialPlanner.java index f841b4b29b..bb1790a008 100644 --- a/src/main/java/seedu/financialplanner/FinancialPlanner.java +++ b/src/main/java/seedu/financialplanner/FinancialPlanner.java @@ -53,7 +53,7 @@ public void run() { Command command = null; while (!(command instanceof ExitCommand)) { - input = ui.input(); + input = ui.userInput(); try { command = Parser.parseCommand(input); command.execute(); diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 3cabdf3735..5e84c07486 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -62,6 +62,10 @@ public void exitMessage() { } public String input() { + return scanner.nextLine().trim(); + } + + public String userInput() { if (scanner.hasNextLine()) { return scanner.nextLine().trim(); } From c4a964a0faa9084f1744dcbed79c4a6d6f94dfc9 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Tue, 14 Nov 2023 11:12:14 +0800 Subject: [PATCH 515/518] Final Final FInal Final changes --- docs/UserGuide.md | 4 ++-- .../investments/watchlistSequence.puml | 4 +++- docs/images/investments/watchlistSequence.png | Bin 18629 -> 19126 bytes .../investments/WatchList.java | 6 ++---- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index e5e01a4f0a..dbf0c61187 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -561,8 +561,8 @@ Format of watchlist output: |--------------------------------------------------------|---------------------------------------|------------------------------------------------|--------------------------------|-------------------------------|------------------------|-------------------------------------------------------------------------| | Ticker Symbol
    (Abbreviation for Company 's Stocks) | Exchange at which the stock is traded | Current latest price of stock (before closing) | Intraday Highest trading price | Intraday Lowest trading price | Name of equity product | Last time at which the information of the stocks was updated by the API | -- Note: To prevent overloading of the stock API, we will only be making watchlist updates every 5 minutes. -Any request within the 5-minute window will only show the last updated watchlist +- Note: To prevent overloading of the stock API, we will only be making watchlist updates every 10 minutes. +Any request within the 10-minute window will only show the last updated watchlist ### Adding Stock to Watchlist: `addstock` diff --git a/docs/diagrams/investments/watchlistSequence.puml b/docs/diagrams/investments/watchlistSequence.puml index 658a46bed1..e8b79b0309 100644 --- a/docs/diagrams/investments/watchlistSequence.puml +++ b/docs/diagrams/investments/watchlistSequence.puml @@ -12,7 +12,9 @@ activate WatchListCommand WatchList -> WatchList : getExpiredStocks() activate WatchList return queryStocks - WatchList -> WatchList : fetchLatestWatchListInfo() + WatchList -> WatchList : fetchFMPStockPrices() + activate WatchList + return return WatchListCommand -> Ui: printStocksInfo(watchlist) activate Ui diff --git a/docs/images/investments/watchlistSequence.png b/docs/images/investments/watchlistSequence.png index ae0c638996fe7e9394aece41159494a9576160d6..c1f961b6b5d444eb6e0b5db8e37347ff8151091e 100644 GIT binary patch literal 19126 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�nJ*3=KK8ispe*4(g{109i(MTw9xsA|wGhSUVWkO?VYgY2I|DcVA#Hsz z<)r&eYB+=Yo(=c(5+PT4HLCG3uSt6fNLQUwE>=^!8*^YSL192aPVN#l9F#G3?w2d; z>oYd^sFlHyn~f&#cg%7s-p9na{{Bw zs;uDOs;qPZ&W&OEF3Dqbx8x;I&~3Zc*48>?KAIV3X}-}n7O~cv>-@U+BM55MmV{?A zwg8;AeMa#%Roxk(VlJD2BJgOHowvZl=JK5lAC1YGnHeBB0zIWwm`}%4>Qd#o;U?=Q z?wfUy!5&jnl$V!Rv`{+@dJ^l3JB_Gg=sJVx80rba35=i320vC>pK zE>h8PJ~?FnCT4%wzw0KJ{Wl+^a}ofkfY-Z+BfGGvGZZOz>L-9cmCaT~7jFR8)t7Gs z6?*>iJZ8Kul#q&Zym+Zl&QM=}8HohZ-atue5`Y2aJ9kC}`tVL44zCWxcZ=R!Pv(tz z94_0+4%kz&qOt>dn%LS*n$# zRVgXsAa-JlY%sTcypLvSHPYThCVhEKWovO^Vc%H#`x!F_0M5b1#Z^^R-BHi3jReJO zBpVx>a5|5-mMM1Q=VfHP&bD%e!{ye2d%(88z{HP|<0(I&^^K2hrMroIplysSkD+jnrpvI?WqlqBISo(=o3Nqf0jg0~5-`m^! z_3KS|mZ!BCHH3!lAQ69Sn~gf{2DabLn=fj9z4rGnP+I?}a|a(XcX;Qssi)C^2LbgF zl)QQqrF}Sc5Rb0zc74_NU_VAj&-Qc*)w68J3fr9_CQc>cZL&HEn7cfFC*d)&J8jzE zoZpsqX4dcM1*c7~a^8>u6;SuJ=#g8pvbG$+n|V)LTl)$CQqf16hcw(SegF>-FJ+s= z$14WDyY9K}B7OvUtQ!z5qaE(TI6#+`+7+Wdw#=5Z;y!5@QnB^m)c6qs$;(*MOq_}& zQmD!y^w@`LG!M6M?osShW^qV17Q^gQ?<2kc|M#RFJA03LxONAA+G}d|H{F65n`1F5 zjPDbfJz0Nqfd62dXE^Sm?A-q|w^Rah|IgOKJ30#o(Dm5dV#W3YeaRd?_HJJvI1s0< zpnevM6uIH@)MPj#eG3gg#VL8=sg6d;fkGxBKFMFV_G7QSi!@EByRLxw-eC z`9%5p9)ADqH#Mr%e>Sf9-L{-f4{GSL;Q{)dP>C81f=Y;AzMKRCBE2wd8dU7B_=!WF zd+s0dcS+_iMnJ)`we_B}T!*VhQqYe0zGUN-kOnfe>C{QZo&5a#J_-3}HwTURT~7bO z`>E4bZfns%Hi9x$c}scWgQ|ucfVRg4q>I^XL6qmu2ak!+k*tCO0ztc#tU3G(IBa%yMp@H$MVOA15_kdzaxJM zwwLO^ewM?wr++U4t{F@L-QQ;bhs|GO0oI0>a=e83kHMyg77A^PPD8niPqoCiG&aHn z>D=7h+S=McMP~=FkeIU4Ku2Sau{c1LQ{OSTE=$2jnSt_mM^UlMMJJ(of%~q%2yrr9 zO_O<&I!d1^o47wS|z39WaQ9NbI1ld|n^Gokf2VQsS%dBU+IR zSc{w+jG3|yu{oD=tZ-MFBCTOr225C6PkvC94hXLEBUM$yb2MXo>d~<4FyZ6{fZDXx z)KX5LfM|b9{oR!II&A2g{8*l0Q`CS}6)L-IaTk~dN^Dogz5%eM&+m|}S@;2RK;`s^alh< z0y&@GIE=7kXKKyT$ah2SE(}*_^>oNar2J}CO}ndsfU!{*biN^H`H3xdY#0f<0Kzmq zZOjd-(Z@YEc0*Agn*^Q!w*aX5P3~MzZ?+z09jXt%rg77Wn-+49D*@?zM}xs>{4JW9O2mnPGYWunllfu{0JxyyP-W0Sd5&#SAKzwQ7|Q?>FR0#!euuBtv52NDyx*6_ zxHVh;6zG7N;h;iS-_*o3)X7;03>#Qo%sXvxdOpvjgE{SIISUVPN{}>Jt%~l9hk}B8 zcD56d%&Hi$-pod|nXqv`efCViYFJxCL#|;}66-`P z7MC+3JSU4SI8|)+n*kOkU^zIdq{-9N4W6I5u=F&7-Er59e0br^mkMh&cacDlBOJIu?#wVqmXX_)neQX?=4j&TtmKi`!M=cqQT z*TDSrpJof!Ghz~ZRAy%V^& zGiSWEI;p*tY7*gaxXHjrGbMcBXZQh1vfzX%KBcFl(^gTDGHqbcd>0nh6v@NF!SM+M z>1MNR{*jYL1AS+$)a(@PSe4Q3XJ_Ky;~tpdhSgHeS7RM9D(Aw16!x%ZIx6w5h~K-& z(DA$vAAGA)GTG%=zzB_#n$oIy8!QKkIBeTnf%B=H)a!jx-3F~y`3>NN(RnRAH92X@ zbr0s9*kL`5E!o){hHe98ZF$&bi3u6!vKYx{Mj5?w z?wj&olZ5d*`6T<~=~c7CX=82D(Mb9|&i zvFLxMq7b{6OHMSgfI~Sm8?0x5c(LyX4C8Cw-#pXeQnnW8H!h?vpDWzC)9T`Bp#hY1 zAc9TzVS3n#Jtf>{{VT2??XXN7msYhF@<13W&~JxjZ1SllTD1X9J{< zz&CF)m)4=3ga?lR?v#YLmw=nK2ACbzfCNi=;X0(l-EY|x+wpr1v?r7U+EbS>g8`!0 z`V*FQS;6Z+KHBLmoiM!wT&NjTuU@@UQBl$UAuTNpfXFTogY$MOw>>Ci#fWEInD>*X zasy6Jn=jU{%;mnLfL6w*9>aY|x51mT6uECb4dNWV%((mO*Du%|Q zJb&^e#hvx!0wz(N6INo|Q3G3bm-8o(*>qa#2}0yi^N$GrvW7*L%AoXj=r?lRE}2Nx(V z&sc%giyR~8?Q3anPWuqtWQsdb2>@|aBD9EpK{&IB)Vz#wtP7#1rnX*Z2$4VWr^EYShcCb}?wTZju$K5e%Hy!={|55>1tkDs9d(TV z+hWd<0*s(Qd70uGah~IVLgSBngVAOeHKT_gKv`r3T93Jvx~)V~B*YHGur4FPzF*ha z>-vEMcsU&S_H1lyfc7=U;M*K=!>g*3?A*B|hpzAUnuuec!f=7p%uO4YTC-{)7;PeS z=mnkoM8*H*5m>RX+omEQgP_a8q_sQKjxEGTv4^z^7Mb-lMM zK;QK<=WYgN%J=Un>F7kCkN*TJO7PV80NV2iV8-toaa~gcX_y*V6_}%mRzZ|OgS&dq zZIzx@NJvV0`j570dmnZHTGCzuiT8VKW9!%0X03EuSC_#KEtz;xvb>Uo2MgP>(1ACE;b z>Xxl5cXyTskImRE?!3Ibj05X#R^RSNGj_+@x4(lo`uO34u||m7u%~z0+7IC7VYQe_ z6&y4vvFn%VRb()PiaNG-7ds!#D6R2J?)_vI6%xYjy1fkMAkPUA2x235*fmzx1Sc_S z-XEB?c+6d3^urbf)0N``eSM#zFuOffN)gvR{XxsY*04*EKdJckV^G!A4~}2o#pG-; zyP~=ZCj@zUJB6UL)|>MhmUBcL2Ll0RB{?e2MsbHl?T-&XIsUXiI!@)Dw^72QE&d}7gBFv1)7k1&p9DfpT(9Cvu;fNxy4 z%B=!qhb&qrP)*>{s~iMvBz{y}QJ<<1MRXmaC@@EROwt2itl3B$Xe?vx$w2n9-@N=Y zAzbt%d1Q=@o^leTJer!Zvf8A4+lm?UM-`d_p(sMi~A8)Z+J#psA}nJ`#JL^GpiwbN`r#bZ|gl5F-=Q z4VD#P`BW_iEg3c~;LYmtK?~R74Q+`4x7kiML!~f=Zu3 z^K4X|9WX|Je)gke3fPj+Xf!aTjWg72q^GA7oIH6wTIn>X8WgMo7ud>Fwjm-%nwD=+ zctH|WO0)`$$@1&Yx>i6Sk5vrr#tp4~Q1naa8){$#4LXh|tp$za z-i3z#u3y(XXffO8nhX!LL(t31)*;ve0kD^K3ZcUH8_oRo&viOQxPk;34NZThD$5t_ z7Xjx6!zTmyCb83`5p|q5@!hj zCLkC8N&1hWqQBapxu?MQ6ZpIAWIjPa?gzEBNPY`VP|Kzxkp)7?Ehwb*qTt5>N}J9z z2}p^Xt<~}L2^2@Z;F4x=wmDPuzG{YhyF3{7{gR&<>I|?Y8 zk1KQVH=WlBW?$`NMIek=Qc+Q1O`nXr0E+=273{|MIG-bd@eq7Ud`ZUu0LaaKuHDMv zC~!(|5hu*JgTlOc)xRHOlm0^BQS=95Bjt>8%V7@;(24*4&X*+1q2eVA%Rik&mxqdx zRjKFyG#Moz>-V(eu|Jf=Im*eE?-$uOt=PWR11B)vu^j8(34eg$NX2$BB|whU5;(St zYPKrXT%D>*(xlfC@~#%!AGH^>2DjQSe%C%?eALZW*^Pp~0{2)aU`zPh0$KiL%4yk( z4F@9mga{Vz<*slV0-3$k4)=xwO%(#Ejzri20OBF<=(nig9(>}c$Ibc z&m?wI{&eGEo234B)M>%~(@>^`1vn7g|M}~2hLe!(&=ilO4nr&){?i}1MTx~+)!5VV fzxxe4ei(vLh1at2wsTD2<`6j`vb58T`0Rz6@`&Zqs?yXDJqa}0ZoIc&V_gZ`H)sO3aDUoAG&mBb|5XZzs1s@;~ z*vAkEtanGS;WrdCt#9Bj2BeSz@|p2-O9M?UBtk^fNb`j{Qd8r?Q_BlFNaS-#C{X7Jj-96_CGwkHCWaybO5vNm90$`S_c;jZ<7f10ezgR+Y@| z7n$7^ghd3IRPW~8DQAzViX1H9ASED0rg|H#4s~+mWTjss%(|v|ZS9S_=5^8{GSmsu z#0R=Di767%!-P(+o5*GY`C1K%SBAsleXo_=P+YUfF=2?GSy63$NP6q|rRvJO2 zF*!xv=Sr)wG#C&%d~M%COt(HB~F&`)_lP zR*9dcF%z{Z=eQ3k&aPV7YqX*+lQ_L@V{6wpf5&h|ZCqedt=ixu|EqHGgbSHRl-0Lr zj+~RedRVrWdi>7S;h(3BGt@b)93*qA&V@N2i8rSe7R^0ffi1IJs=>VJ)HjqXv%AN7l4QDZsbEXvY2?AKiyN*iN}L+__-npch$<@2?%oK}zj zD|>m1M7pqR#z{OGcZYL4{p4+9lUl@6=XuVz^|_(v6p8Dt`z&Vi`hO^G?aZ02z8V_C zL|OboGZ*}YIM#pQ04i;)6QJW#GNrzUGNRzl>EkUeExc@A6_5^#IyjNF7zv|`> zW4kaO&2d}=q6g1(l>Qq@i``atzn(N1Cj_Vk7Up{UBbbj7C;t0r5XZ3s;nNG)m@nLM znnM=X*Vm7KZo-WE`P}}fqfZ2`clYPtliKCu=jWg4t|(aR3-GW~>mhJE zqaDbtxZR~+BgO#t6O57~uJvE*W-8dO7z;*iZ7-SnaTr%^haV0<+HWK47nsM+$tgT= zp4WzyLQ20!&Ji=4d8Usz7pmw``t9Fvc7_ivc^Yny4M)y#HC7L)?T)DV?05#VT{dep zV>VNwXfHVgFKcf-_6=D)na|6d#G8OX2BvX-H|*YOj^g8cTI$o55SE25*wx4Bq~Jt` zj~wamX;IYp{(d2;_qEjH0=uCf94V)-y*&0q-tcE}yQyi$xJXT3yjsCeuScU~^+FM= z{{6XMyu56O%8%_-;RMU1ELE4Bh(8f{goudOcJu4E8|{wmYHBAaC{mvPOs3%4Rk%Oz zE6=w&U8R;|ZdxBi%)7Ik@>JV!Tu^glWh}_wa=7wQxk`wb@l=~(Ujf?Qu6DYb3cViH zkG2b2xYnXC;$gS4y_E7zt>7E_6oP8N&2psbNS~LKLLORR^^DqfBIbb&4WrJ)sH$nc z-GvVeJJGqh9;H%oLslK!t*-q$*9mCUyUj->I=44k^PgAOi+8*{EuQ|YB40I4 z&ujM)!p7cX)T{eM?$tp0_Hgf5-;y^SyB6~XU1$~d9|F} zcpQaSczE4N)m0=(`2AMvqp>%{sB6qgb`TNMU1s*TvnYp0XWzO_HH7fvoOIQ!kvBoF z&RACsp)c~;m5U85CtJpnJbdF$9@ZJfPiN4LY(G1HBH#bf;ECm4lbPlalDBN*PKN%O z)%JeH7E9vX4*6W)Y|kO@emoSIWJvOe?7r;Yvl}cb(xe@w=pp*k4F?%;^p5ubxVms; zb2f8Tw*g=19I`lF^0DR}$)7ovmnr%CDcX6DafXUIN_C{W#t}wevEfK8y*QpT)CFT8 zg)elon|NW}d_6bn^%B?C;_()Yf#w*edN=Ji){w~g-rSQOA#?BbgSD6fJJR$E8WkOX zv~PKLgphQ}*WfVn2K+NxCcl^8l+yfKTzz~x_|O}&yDwHISM2QUwy)ldmPs}2zBTkF z7Y`TrTws^hHWe*rf!yIXxRizNJ+) z+LAW6_6FH)DW}2yKIk*i!Vx8kwWaz33cg+MAO0EfkC-lSa?)NLx;%t(T8Z3{tLQIK zm8wIZ&6)T;qL!8`repa)ug2PQ&;85Gm_;}IAy(%#k(Y8?WM|lQ`u7&N0aiA)yiFx+d;l! zr?Xxdz1dE{w>8aHRT32(v^m1mOe-CvK5bqv>Ag|yh3M|Z2QPghpbC%eV&Hl7mdL@Q)$p5vSGRkl6xq(7f{rXTJ7b+UkT=!w7GMzA^B z#Dv0pj<-@Rxg6a;jM}cq^;T28b6eJWA|eYyuV8`4oos2TV0VRZM7V5lp#sGp6;dPE z!~cBN)pdt&d;Z8s$PBvrDnWCzwk+!0!?o4c`WqTtrW++~Li{WN&eZcLdC`o^@@}`JRg45R`YkqcoFDO_jpR3fOkRTbA zY8DtzPo8{ca5ILaWxV{|4#7HPRu+@N8yeeN1!%QwUbonMP1m=PCL}ZM>$>$tlWvHZ z$9if?WRYsSQN4T#jj59f`fTNF47Iz%o}MR8e6%5+PB0bspDr%0&+0EB>WbuAgOquk zcwv{AyCD!gWvR5_GaDt!2wAX5kabo2O}C|{!Csb-9`!N_?;*1Nm~$ePbCzm%UVW;q z5gEs;)9@k7w7(;L#`ak-&5zvPv?+v~o|WSAP|lGv(W6P^7nQQ~=#mz?Q__C4=$h#& ztgxh?Ys1g3vRbT)syfT^v=)V4JIy+-M+JySHdHPdPR`NSysW>SI`(8m$X+SRM8L>r zZ^ZzXQRpqp-3RU1*w`DJ?+L}<%<<>U4owjoVh<7twT*rI;k+eQuhYc5l~OOIzZPcr zcEV}dRb#rIFk`8@qg3ut3u#d8)gjR=icK1ei}bgyCs<_|_utEyB<5L`MWN6T0fhpQ zOX-gi51+aISo~108~0-6{ZWG!`ci4f^wVS>(Pn;>cQd?nsh-8D2d)pgq2IZ>MoiIh z!}i@2lAAlpW_V8g9=THZ5|cqP#Gc{TK_={$JhpQ}TCf`L%qLqe^Pw}%jX(DRrj$*; zIW{*o5>&lryVk4S;}~N&+0qphkh2;gPdDBkJyq`il#|+)27l9S%dT# zSEkmOQ@AWm^jY!%Y3wbJ8l=$Y<$Kj+b53F?*bypl(d_UDywa-g)O^c++^IFIBT9 zNeykKE+}}ZAS;whY4yiknYrEMYmY;WO`X>rpS$n4%aIJSYZf~o~doxQ`9y)ezo+&AX)5-js5@vHW;P>_s z5b)6vZ(YLIr?N$U=3e$6q>M{k2y+mvxuZmWI%|vOPVc=i_017f*Up)pbw$5=O6zGg zvDK>Plrcwgj{J%>iKn}@H=57gJc^I6%l$%w6`jIlh#i?8Bdf0*n9~{~b1{@=gpMri zYYfC0HfJc;O+}I_mvl$ECGqyXeL`6m_efPybcN-@g(OM;bb>S2Qzjz~2QfRJqyKXg z&rymv)jUMD9crV7ZFlu!Yc6A~)tbX-Q)8H#332P!Do^c(5$Ro^&Q`;fXf>>d!Qp(n zfq|>aQVB$%fpPM-?vT5&e-Hsq+)w*|Ln{si-Veucp}j%>f6Ik}CQEZI8}OAmfK+vp z8|Q}Zk4~l~x>vU^?KvZ*=um3#vf#d|jMrmX-!SBaXg` z;4Ktcs-8KrISwSNyx%?oL$i5!b}U6-^K@^nWF00t-{9e^(wQ+=lBUl=R)05d)w{rE zrJC?1UrrR_oZ+nD8~x(4i;Rvdli~X_E(Z7D%@9HhaHJ-y$>R6@=UzSNxkE!8M0aw zg7ZF%&T)A-l;n;g^SJ%cc+~|S%W>TMrwKU+ZdtL4N>g%Tea8Fed;G_vZGT_70k?+w zZWdS(rU+a#`Zpe#z8R0ElLPzO8R>qFRB2gTthW$A{euM_PD)&q%K3yL_9C7w{u0S~=brR#Q{s zYub^dJ{=gGo16RbqR3GzD2m>Z-JqqXk2W2vb0((Jl1jM5+&xEBtD7AM9EwpT`*Y{L zFV{l7YxA#$qml>@+&n@`BA9n)ePM{hxUaUVs;aW`NnJf3I#)Tv=+voGkUlpi;}UUs zWMySJ47(mGDvC*cIy%ZW=~SnieRVaGB*lZ0$I954M+`0G_;-RcT3n-}>0{e90{Bq8 zw6t%wq9lAj`S{#=R!(SAKR-Vo_b73ZmoS4%! zDW6#eHn!C8aHq~x^%Siiu@yXbHytnB-})1CUpQHGo5G(}yqA-g*V5Leqork~L-97I z>9<2o{h;9nBO@adlScqKyTN!<1c7N2&9kYtghz?05t5nQAC`KuOdV8KraM!Tl0I~5 zEKjz&bwUv6VciR)XJn+fsrL|I(|UQ_WUv%}bU4_;3ca%iD|vlfQC|K_K!8NuY;Vp| zRD*K50kxb?Q@EJC{ONYr&!0bsgj^{4rd8|nU8j*o%ag@)R6+{}fr!StW>(C5p8I8z z#av%)WEn1_Y+Hh|2r*bUjw1OCw)14kQLTt*#$!DpkilUC=>QVjP9(`n->PJ1_y12MFIXU_GoLyMF zyLq_g&fm%BQlNWm5&l*46a|<0bWc`FD_p>I?m+xeT}`eo)VO&4x)JPwO&_csCYBl647o;}kQ`{?6S*-rBG@^O(@*rEm5_O{P4StHlc%)wPq zL7@W&*kq)nzjm;#{F=?(c-%qy`-ll?^zX}L%^U>H@%u}w%}GD<#j7VX*< zXCC;CC8x~e$J0OipSgM6Iggo==Rs00-z(sk%E0x6nDp@XmY96ywk%D8y*2PBc}zSy zlSI6iX`H1Hnjh`Vu>S8K?k*GmdR2ixBG$jM5iWAD@5=S-qv^rHQ3YZ%@)Z>? zyr#F18+AIrwSo%8jU2x}>*3~Rz1C|nLAQ2)x$qUv{>^8eOtKAbFbSUjQC~mToxzl{ zwKDbS{{8zrvsaoDuRo#M0}iI_$APdU@n0`rzKnC2$e{6S8Iaqmn$D3LZ%&X(X+6y+`4t^+BJijuC(hV^5wnRv3;JQ-7}lOIVYO6Ava_v zKpaw#lUuJ$$|XaQL_$F!DV$?IQ%UQ%ouHJKZ8r6VPK4>|Rq`8J5-_B(x$54=19p-Mm~#4LX%I~lJegkccvRE=L;CtH#Ie#xG2n~*P=6A`SA>ss)oOWKfB>X zQ$($5vIc&h#%eFk&Ls9~(H^kTwn~!4f3{aYB`GPX0(n2;o;R(8PoZ1y@Q<8WqOic z`JU(g;pQab>sxaL9KGsFN?pmCHT2?Q$)+Z~md&o6B0yQkGJ?X@R0?_bu(B^a`--F2 zN#^*kCr+H0zV|^Ykh82t@!>;KIaAiUU_L4ml9GT(&Bo85ww}G0Q1djy@i1|u|5Tp! zTCxz1Ku+snDjR0qrc1039z5u?p5tNV-JUP`{;c8?za2wGE?vpw_|Km|y9Ah{aS9SS zjLME>i0N@`%;wCwOKCM&xlp|SBAa^hX&nYn#N9eCbx8WLsbgmLZ=}m{L_LeZC5)r* zU1~C9C2LPq8ymUC%-k?XgoTAwtE+T64f1JiAQ#8&+gXzS?BypXk~u|;UOuu)0B@};O&@|O=f%j;snOMOWF!=JqfBIxbee2Ew7NZ| zEn)>&tKE^oHfcZS=IVz%FF2~Qk|QqQc}_+W%8M5!y-hdj^?Q4PEJ`|fbj1BM8S;^8 zLa-2COH%;~?e6X#$YnvvXV;@ZqjEY&^WnpX!^6Y#m&~?;nbnI)q`5zS{#?p4RQ@jP za#@mkNoK`NB_&ns$OnQL*Mh@APs=G8+AC>Io=T}|R87}7eo`OqWQPDRrFc30s01|CI+jCpX ze^O9X^hmG1x0jb>z^#uK4Mv*T-EgH*Pv*zju+EgHL-M8YPaWr)FN{M$Fo_@Ou3mMs z?xEz_2gmpM>LqWkt7J1rWyYJ97=9|3ln7kDH(F1(?&%f8V}1JcX;y!C)jTVff99wu zaJqz;Phu_0pTl@`?&aq%U*4a)84Gvfv0A=mGKgy$86J*{hsV-gkGO4WYTBJ)EbaED z%i5ln+ zav6iOW97L~ZS3caJlTw%PKJ*Z&;Kl$c&uY6$ZlHa!}6^0t57ZNv&G>mfcIy_?+}PI zVr22j+#zZ=2UjNQipIeaKfY;gBa5LJkbC!^V^X=gL+TjiOJg_tCYib~^bS>5M zNoRC#GDn}%`ThdnSeHc_kezW+$CB+yp*=vZWpeI^UERCCvL10@LyFl{n~#qVq%7id zY~$U=1+C8f2}vN(i^O&0S#wzAFO-wB>EYw!UlexNY5x}3J#qj}fkS&fdBFcc%AJxY zTRNE6;oyhux`BwJcWMYW$LqYa12o`=5dC^IS|^5MkF5W>B%+NxoDS-T$qSUSCZy5t_Fn=9 zXLcNOzZPMun3esaf^+YYdKY(Ok`CNsoag@I$F(zDYSMDYB-K1Joh2XpC0tj_5BTy0 zqV)9fQzY;2#qE#w~P zpSBx^w08Y*W>S2-`*3J@_$3}5+qQVcYvGcurn8gbCr_T_jd38fCA<}o<8%1Ez~eKe zG6RC8&lukK;dHTDJ-VEx_0!p?A*9Ib>Z43F@XBohvN=Yc`i$!Tz)PZlcTr1)u73w1 zL)7a^eEwDvBm?98jmTBTKu9Q1lQf2jczb*2uo<&`Cvy12Y0$yEDleg`+E@AUqOa#> zqH5me?$#V?Jk%M)T&~&S^1(7U$bqA*T&Z!B_bd+|JJ%8|bFmA*KUOwMiYagTBr4H0 z>|R=GDzen&L@MKD(}h8y(Qvs+*gH_*a9YgTtk0|GQ{Om!O<{h}jfvG7HWDz2IJE*h z5QA6e`s)J#OO>;cS5myMDc)uBJ=RkA;>A__%;@H!A7BjJ&euo&A-5%)-FB?ex< z*j%2d@SrNNT+)(~k`fj^WU80;s{JYBwdIYmVA-<7=xCtiHILM6%eMG7hCPv_v9Tm{ zQo~Y48d_RGe5gK6lkuovJFD5AtoCmz7afhw0I6Y3#T6y8}gzF(Cy@bzHTHGeBK_ zd;#G^w>9>Z>8I?+c~)L)>J9S7c`Nb-b~`|Gegvj!E4fVf<~-^yFc~UOomFRdRr92k zd|62=y1$`R*|GxPADH#~mYT-BpdbW#w-*-PDd57z#bu5f<6Ky2SCe&yhM~nir1{ZgCjr4TlnGb;%c7~m41+E?<>|y`{cm4V- z(3>8y7dM|2BC0Rly5%F!Tr0N0%wj4Rcp`6j$IxMa`*H-U>s|OpFi8KL2D9;RCn#rV z8L!_r86NREO%{J$zwxwM+|wT+f2+LET?7964<0;?AMMKXrSuEXt_z?Ji;i}&Fao^O z)Vw?=u(m}_Oufm{^^ucYS3NK|sncNS}yV3$E;d3k%w;t$O2`cFDdgwja|aqG8Td%?Rk zoszpGE6sBg24By+8q;LCFh(*|;h`-hP7AfCdFC&8rR!dTxv^Rv zFQVc@PItiSzDw14LY(T0NmAQ!{FURaac5Fyex>$|fS#iVrxmFN%!{~La&7d7|Hc+w zL_|cG@H@SZBx<=@*fq@B;^N}>?;lUuseMAdYZ){2T zw_$1S37@d;5F)Xo9Wj`sR4!kIxNztfvPOS|B>;AD>dcuboSQ|xv^e&HAtZP96BXo( zKrgSAMD%9j!otGF#sWzq7V?cxwo!y@>@{K>H@j89$tFfR)wIV&TFyylOXln7x8dqj|^7P1;^uk zeC~T0$L8%{Aa8hgC2@CE(4S%cX4Acd-`LF&IY=F;qo~*!D;Kx9I@1kMo0)lQ(aG5v za&cR+6?O~jfxwxSr^{4PP`G8eILvO?1w8T811x(Ym@a4QHvB_ssvjN-3JLKuAf5nA z;d~iGay~tGexhF*F>nDhGkW55XL)z54G`x+YK#{6F^PL0{{T5@z<=_3+2hOa_X!~> zJo|NryR=R--nnbf52-6MdXBS&1`y@Rr4mY8q5@NQXIS?iXSQ*dzgBNIvL zeTJnvLPmQXgqi0w?;BkII}sv1cTOoUQREICH~*%{Jq*`lsAo2z2F-`W#7T-xr(vMl z>+1GMmg$(^P5ts|>$vr`bU77){rQXIE-8Htx{Xx0FcS1wD1@nqh>6uQj3}6jx|C{X zYP^}~=;)lCoG=_XH#a~8O7flrWsYP}GOQ_X?+ilI<^S-{*U9jV?Ko=<;Y`49>fGKhy5o&16>u70> zZY+&e*^T;Y%f~D5moJXgG&eUZI>P`;OG`fxNrE&3qYk#)yt0&Hm=*ZtOS(a4@>~Jh z?uXw^PdaI>x|Ws}03#4An@)%^q$)R3>p0t(p2Qb-Y|#NF;rsXRJ!;w?RrP+;>6>3k zfV4zSN|Xavy4;3QaZlp2ik^yIUK+RPx2-Vv^a|)I>ziZb=@xUUqnC_&v*qsJXGZOA z7dal5icNxQ`*U2jD!^DqK9=%e?<#bLpP-4LTKCIf}9 zDl0{`^gZr!Y0pVEN;jPxz4Si_MbjRkVAvxRezS<4o0ysbUed5DHFQ%-SVrcf3>^^h z!WmF7L6%_l4@>w>9gMk#RQ$5og*V7_1sH@Og+ep1!hz7 zu@k_u2BnfcD7b`$f;TZja+DOEs_lwg7dxh04zikzxotXXv)ZYhngNKNzuKk0y@0dA zZ83X31(f)WC09^yZfGkhDXFSbQkcNZfKab4WiF_MvohW|7cryQaGOlc(o|OK*#ixRb0K(zshfI{ z4qs?t0!C5I2>3iK0+THhujBY%+)p6p&8`rN7@cT3=GF(d{r$Bz$(nR~@Gb`J9}GeJ zhW|g(>K~~1X=LW`P9{Lf8*rSqOPE1NHIHna4GiJe&v%yg!inCV>(0 z9QSwac>v`TG?Ri5M8C^a9mZ#I8k5)uk~oI%x3MZnx3Iq7eSHtpS^DqAYHEDE0fWbg8S_^ zh3{X1UR@&QixsT-VgjBQPUMH=AVeWQCJJ3DK8pZU1iu_~t*oqstp}Y0Q6ZH(n_*9k z_d0->7d2~4PG(KdJpv@+{rfi$qu+(~k9+=|h1A@alQB_x8*_Ab7%v{=3^2)y{m&eg z{%3*z?^W1oAOB@8q=+ZKS9xEo*jE?+tZ)khsK0IY_VyrNKc$Cg7xjW21 z$R$SBef7@Z4|vWWIsWFaAQZwGMaEBJ3jj0#>^ z5=8Q~in6l2t=XJqPiuOsfkLePJDW3`y=^q2>3jS?RCy!UUmQnBVDP~GBV`J>KG<$7 zjvSO2roMiQEhzg}JYP$)+u4MYDVbb-R^!bVn8nMqw1*BKc7FXjK_#b6v!j3o>rv|# zbL!atQl?*9oX(UDNJ^(8yZY#xL3cW1e^$D-uI_}(iHqlM>ao2Tu5>%Ylq?C4PDf5W z&|*?dc2Z^SX58nJeHyu5MXA@H?@KRwr$#jO|3hPVb6p%%2q+|Dl9NAi-e(!1h?EKx zKV=Eh=fgR7Ws||7ArK?4GBAL&Q_}C;xXLDJzv}Djy8&9JL0_)#rJ~H%&sSu1j`5d+ z_5tOdgs_zr=gcd@MbPuMUobVY64jh-&=KliSJ=%@YOl8~kPQ9{Dy9DzG`?5|J8X3ORSCqPvt#oG5&UAc0_m&?Kk+TGA3k+Alo zz2nCMs(=;Q`SUizl_!Sekz;*O+d_9shD9^Nm;0ecB1FkIl^j^)Bxq>Nj&zztbvsF} zJwrAbJ4%(xnQ`um@8O>@;ybMGz62v#u1t1tH>mo67BjAzW0j=D2*pc$baVqQO7QV? z>hfGa-^Gj1pw$Bk6UU6MAHwmyzo%!3G=ByfpM;isp_D{SOswYys02z62+7&qLGJFY zNol@~hwndIF@CA@*%ZFgom8DhhuZ=I0%G$%wm*wsYyI$JAzvr;T#!E$mtBYczZ%>6(qh|px4m&4WMHyiL`u+%lz z(HtF#|Et(X&eaAHlV{MFPj~QhJx(_uTQlfNb>&u6RKzIVszDSM*^(VdK4EP=Jq8qS zQE>7yWTn52>B1-<_YBs9St*y<>;I;@`@c1K@q*P1EJ$1^KRvl=05EXSPHME4nx=HhYDMiI|X(+j{ldS|$%Bw(PRG zMSa$W-^6%+Apm+2we;2OWM}Q|XXWl7T(bBR76retKZpApKcC|sCZ+@xiz7vs#RT+* zNs|GR-(@Ry)Ezf3DC%SHQKbm~121JV1Ehbt+-(){A9ouc`~{yfnGp5^HRUha`GBU} z{3W@O4p;BQ-+B(CGqKFZo~n^S|Bi!+(tSQ7fN>N`{e&iOF}~ z`y`n>oby-y8NP!K@BlqMJsTSvJG*>dd4VJEiS+)J8lHVVeH^GNv{d#XcNOaPTDXej zpI0=5tAHE2zkRC*swe2S&}^BL{rEhq=GgkV1EudEO9Z{z9k5Qbb8`o9r@BW&`3~10 zxN!Cu!v6Hx3t&oE;2}cy?%hMJ#Hp2)moIkl=rn`?w6#L1ju^wfj`5+hq|tWRl|sMj$ltt8g?HE5;KG@I z-tB+aCQ!%kOE5qGr-vaC{TfYq)aKO_36CQ)}kBuVZC4A71MLBL8~*-H-1qw=(F(0HY9VVhF8|sZqFE_?y+xO zJ7;jXld<G-~Ba8K=WpReb+kr(_d2rH*zo-u3~ue_bLH8 zi9!^y9L_=iLh;FM9(DvGbMGik>EEL?doG0P0}a$YGsD4N6aqf|)3}D2z4o^~k8y7O z=ZC?&e|->Or1*1Y#^POY@VIy64(k4Yml2*!kKP^>&_A)(lWlf2VtIYYV+zNjBSl;K z!GlkIQ&>jzHEb-iZ0}yI*EtiC-6fMJ#zxq@9#2McVq79~z6}lcjiAyphpelqsdya*$V zJB)?MFAke(4s`)nNS=1;kC9AM+cCh5Fjk)1Y7ty`(>GC~#X)R^yoo1(B zFGk53>depxg{b93)8$w}OtYn~wzd{p%s2eGzzw#zv(|6inf&_gISW?DTQ7!1B_!Y= z#d=GOYz(d4=0p^C_zdVRpk}ak)kDb-#}R4+Kurfq5E~y4KDAKJxL!RVm#G5zw<-Ky zT)f$pYk4DXAeZh2u9zRCU%|vOc=y2rSuJ-{GNz{<`mJ(i$ga2UP&D=Q^t^q0wChX3 z#c&>`IN6Y4SbaS|VvbTeq4PkeW}r#)$7KTjR)I1XBVQG{wXR&^+iCg)-#y9PVImt1 z*S9y80C*(Q<^nDHSj?eF(OO%CLLXcrPo*B5VTjBnc1*XLO2`1#YO%FyI2+E>toLND zFRyEtl2+FWO!eey`8K}pP%Wfr_X6t;ys6(NjoOq=2HV#z_!^Rf+%ZmxwdrJDy!_`Z z;CNUNJ8@|kiuIpNk_SyiPLvG7(^zvL+@x{j=CYBy`FY7!yuvw5bMc~Y!p!NjXDj>s zzXor+Xy}yL^D9S$hnJR>ea~<_n_5lA{NxV&Jb%ud@Z_a*p!y^mPijE{Utmt0I5!*) zvjb-Xu;T|NpnhDrdNpjamNNTaiv&+jymXNcIgBhTR@ixQ_@9B*e2qlxc^n?Fa9Xd% z$Hfx)eKC6`lk(z$WkP)XFw;bvk2qsWTJN}UQ18=b6&pB*;p0i9@~icdZHWS%z2Y5t z6oJfGK*0GKY*B3=PDx@4FfokP88EaZ=B;*J^x(d`3dSMmYW$Etg)#TtU}ZI*?Xlcm zHyH|2X^VQ2`tDH4WVj1>9_ESh6sZ5&K@!as8Q$!btq)!3-}|bPPzj_zkS6S`~#nSkCC$@Cz@X0?vw#FtTjx8csHx{ zwg)7J$3L@YK_i+ygHe4Use zkmA=SKi2HoG#kK*LAw+z1TP-!C-GM3u$*HzxTV)Zzsk;Is>gLC0NCooRE+ZDAad%cOMGJ z#7{K-7>)*B0CI{hb37K>1I>X@xUK{=PuOpg`kh!fhvJpe zj@A&Ug}snW#h6w|Ir;ZGFd|f~)`mDE>DFsTdF}R?>}nAn6$SMpqs^xUMyNHn-=4>SQ6srYG5kdcXbCz)e~3fR1I3o{qklz0Ot zFavO11q}@1O@96Q&S9`L51i#jTN^CkU4M^F0q0Kb9Wb{e9mgDhB^AVc8FLkw5~EOe zXa)%$pHCxi(q=^#e>%|JDWt|&^gg)!9Vc^WQW7(mba;7r`S{eRaO(IsTk$T@WEKLQ z*&oa{iP9ZdfLIiI7wSl8Rv*WYx(N7xl0|husZ=J1+Ll&;&d!PPLRY%s)_^0iu&{7> zY3ZFyq<1iP8r&E$Mupc8b0(13U@a8l5F;TKYMwfdulWHikfNnCBZ(HBXD4oC!OSyW z7}t)IPw=^WJkfR z*v}_ZrI?4nk_DF0cOD+v4?YG25XJ!4AOb2hKZ5rv3LKw>_EO{OH3Uj>19Nl%@Bd;k zC8s+6E@k&bQj{Me^E@w@)BhWZIRFj+&lwJk;O`k_&5s8?pZ3WI%##0U7j+_@*mrua z*8ogxZEVbRe0Q{_7q?x%M`46cBb||)%OsS`KCYQZzJd16(Vrv$~Qt4-v&-_ zP=9PUmpcnke5M%r>7Yk**!A7Jo$mf!;qrd;u0?WH=70F$t4sk{kE(#PVfu!4ouG(_ zXX7^&uH>ogwu$NYM>CA>d;Dsk*Y_FM(L~R1q@v=yG%QzWP@R zB1hcUW{J5{{bbKH=+y}Ph01PS9r`8`2$$bP;w_+dl7%it`suBNlMyuj?i0;XVAR|O zr8l5^G?7)_GFqk%C&;f z-kAN0P)T6>Co$^6MFxhqf)4J$yDCaclXj_W=8M4FS1BqcW;vI)R=Ey+eo%ey9omS= zN27Q8Ud{E(<=HqpJCiSk5VIK8f+I51K>sy7_t5Mh403Vu{SHr-+YgnhQFn54|1 ztCycB2*p$rpJl!PKeukJgJ-B#@xg=Qe8M#7JjKU0`$)jF519VaA_9 z$26U~H_KwGZ3bNF7{b(B32qfzpc_z(?fro9Pw|%+ILfS5k)GSWHv8Pr~0pN zZQV$_SQ+BYjf;r(_h}*BvoGEfXZ-+*%+^0r&6u1S;2-o|YClj5bku-_T6{Tg9&lpqn;C zU2%Xsa6njGkjIYGfysjtF`^kw(;t~k-#9rn^jbjcxzv@!Qf{Yr&Q4?%sBuTlzNq6a ze-;XCS6A0sF;LSSv%yH@ZVg>$!Jzo~YqKo9d=xtel%7E2j-*g%4%S){bE;dJcj5ed zc0fvSGYbFJFZcVOg&;V36ny=Yb92(Io^P+1j*gC|8}|pv6N1n=dUFjjr3MPRlhc|| zH$=;X0hj0q6Y<#V^~6n%^1$kWqp3$0no4KSzFeJFgh8QxnLWhrLT5*J4Aa@E_f0_F zb!OMY4C=>kKcv9?7{#gxWcq2xUngop&i$t@Lr1+=E)sc$W@f&G76-CEia1kX&&cO| z`n+>o$m@^1qx5@*;tmbg;juC3*z>Nm$Zq$lNbmIp#yjD#MVQ=lU!F3RDd}ELc@kVT zAH}zG1;o2+*W71Il2cN66jk@UfMCo#Dkh|%amg!We0&@tt$$|m>*_0j$vcK65e`R) ziH*C{6UJ)Xx}q>}kLYj$yFhb&W@aXcR};?;EsxYzK#|^%gFuAHD?kyZpm0`>T1k%Z z92-3~wR)jF7G#;HQ}`xkCq-=G{|2!KxrMwPdaTSJL-0z0n>K;um72=dyL9jx%vk{# zbrQ6P$?i)C77J*aFk>u{ah|s(F-?9&g9qpA zDUwPw=C|j*m;L#MIsLIh+FSap2d-NgKUrC(=*j;$uvA73q$dQzn);j6U^I9J6duUS zgPkRNaPX-u{NBbjlhZW}Oaq$E-#FtXsJt%3np@a zz~zg@SyqiBf_KRRR%Ap6WCL!J^|W2jtHDgO%lr4EM~htEzOAmU4ZkA9?yry(s1J>L z|4sFFet-4l?zYoIu_^%YpS`>i9%r$FZHt|qorcDNJDdc-vBK)^u@1Sz_BB8Ej)y7j z**eyjo25NPp;ay@EPR)t1w%ysgeTgGi3yCTU&F$vPf1lMdR%`c{p$c)F|Lv-DEotR za3G@)FYvg1LB$~i;>_M*GH}wsq=9q+V#gmyvs~l+*^@C*CJsGEyaR4srY8I-boWCH z{@%el;FA}m`@E46^Pgu}Y;FeLpYD%*i#c-w?DUVY!Z+y@i)NSmA7@$Myv)|aos1Za zE`&e~yr*g>SuEX65xD set: stocks.entrySet()) { Stock currentStock = set.getValue(); - if (currentStock.getLastFetched() + fiveMin < currentTime) { + if (currentStock.getLastFetched() + tenMin < currentTime) { queryStocks.append(set.getKey()); queryStocks.append(","); } @@ -241,8 +241,6 @@ public void setLastFetched(long fetchTime) { * @param stockLocal */ public void extractStockInfoFromJSONObject(JSONObject stock, Stock stockLocal) { - //stockLocal.setLastFetched(fetchTime); - String price = stock.get("price").toString(); assert price != null; stockLocal.setPrice(price); From 80da84b42be090956c11f9ac677da9376abbef3b Mon Sep 17 00:00:00 2001 From: YFshadaow Date: Tue, 14 Nov 2023 14:30:42 +0800 Subject: [PATCH 516/518] Add project portfolio page --- docs/team/yfshadaow.md | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 docs/team/yfshadaow.md diff --git a/docs/team/yfshadaow.md b/docs/team/yfshadaow.md new file mode 100644 index 0000000000..5a5b14f867 --- /dev/null +++ b/docs/team/yfshadaow.md @@ -0,0 +1,40 @@ +# Ren Zhengdao - Project Portfolio Page + +## Overview + +Financial Planner is a Command Line Interface (CLI) application for managing your finances conveniently. It is optimized for use via the CLI and leverages your expertise in CLI and your ability to type fast and gives you a one-stop interface to access a plethora of features to manage your finances. + +## Summary of contributions + +### Code contributed: [RepoSense link](https://nus-cs2113-ay2324s1.github.io/tp-dashboard/?search=YFshadaow&breakdown=true) + +### Enhancements implemented: + +* Refactor of code during multiple phases +* Switch from normal class structure to singleton to reduce long methods +* Command manager feature to auto-scan for command classes +* Introduction of RawCommand class to separate command parse and validation +* Separation of command usages/example usages into individual classes +* Use of reflections to further optimize and clean code +* General code enhancements and improvements + +### Contributions to the UG: + +* Guide for help/list/find commands +* Ensure consistency of UG with help command + +### Contributions to the DG: + +### Contributions to team-based tasks: + +* Review and approve teammates' PRs +* Give suggestions to teammates' code +* Fix bugs related to testing/logging + +### Review/Mentoring contributions: + +* Reviewed teammates code (giving suggestions and improvements) + +### Contributions beyond the project team: + +* Reviewed UG & DG of other teams. \ No newline at end of file From be447065c443d1cc04edef799e5a9da4a0c87bba Mon Sep 17 00:00:00 2001 From: YFshadaow Date: Tue, 14 Nov 2023 16:03:14 +0800 Subject: [PATCH 517/518] Update aboutus page --- docs/AboutUs.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 1f6023dc99..71fd5f1ef8 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -7,4 +7,5 @@ | ![](https://via.placeholder.com/100.png?text=Photo) | Ryan Chua | [Github](https://github.com/ryan1604) | [Portfolio](team/ryan1604.md) | | ![](https://via.placeholder.com/100.png?text=Photo) | Neo Min Wei | [Github](https://github.com/NeoMinWei) | [Portfolio](team/neominwei.md) | | ![](https://via.placeholder.com/100.png?text=Photo) | Frederick | [Github](https://github.com/wwweert123) | [Portfolio](team/wwweert123.md) | +| ![](https://via.placeholder.com/100.png?text=Photo) | Zhengdao | [Github](https://github.com/YFshadaow) | [Portfolio](team/yfshadaow.md) | From 878b5acb0e74fb17628eef0c291d2dbe69502940 Mon Sep 17 00:00:00 2001 From: YFshadaow Date: Tue, 14 Nov 2023 16:08:59 +0800 Subject: [PATCH 518/518] Remove the non-existing John Doe from AboutUs.md --- docs/AboutUs.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 71fd5f1ef8..453fba8f18 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -2,7 +2,6 @@ | Display | Name | Github Profile | Portfolio | |-----------------------------------------------------|:-----------:|:---------------------------------------:|:---------------------------------:| -| ![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) | | ![](https://via.placeholder.com/100.png?text=Photo) | Hao Chen | [Github](https://github.com/) | [Portfolio](team/hshiah.md) | | ![](https://via.placeholder.com/100.png?text=Photo) | Ryan Chua | [Github](https://github.com/ryan1604) | [Portfolio](team/ryan1604.md) | | ![](https://via.placeholder.com/100.png?text=Photo) | Neo Min Wei | [Github](https://github.com/NeoMinWei) | [Portfolio](team/neominwei.md) |

    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 From fadf08824105158d2c02bb9f5a8c435121e49e0c Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 12 Nov 2023 14:30:04 +0800 Subject: [PATCH 479/518] Add watchlist feature to DG --- docs/DeveloperGuide.md | 66 ++++++++++++++++++ .../investments/watchlistClassDiagram.puml | 40 +++++++++++ .../investments/watchlistSequence.puml | 23 ++++++ .../investments/watchlistClassDiagram.png | Bin 0 -> 31458 bytes docs/images/investments/watchlistOutput.png | Bin 0 -> 27765 bytes docs/images/investments/watchlistSequence.png | Bin 0 -> 31270 bytes 6 files changed, 129 insertions(+) create mode 100644 docs/diagrams/investments/watchlistClassDiagram.puml create mode 100644 docs/diagrams/investments/watchlistSequence.puml create mode 100644 docs/images/investments/watchlistClassDiagram.png create mode 100644 docs/images/investments/watchlistOutput.png create mode 100644 docs/images/investments/watchlistSequence.png diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 24ec0296e0..d003691e45 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -177,6 +177,72 @@ Visualizer (`displaying chart` ref from overall sequence diagram above) ![](images/vis/visualizerSequence.png) +### Watchlist Feature + +The watchlist in financial planner is similar to that of other common watchlist online. +It contains a list of stocks that the user watches with an eye toward taking advantage of prices. It allows +users to track real time data on the stocks that they are interested in. + +Simply type `watchlist` into the command line without any arguments and the watchlist will be displayed. + +Example Output: + +![](images/investments/watchlistOutput.png) + +Below are the various classes involved in the implementation of watchlist. + +#### WatchlistCommand + +1. The WatchlistCommand instance calls the `getLatestWatchListInfo()` method from the watchlist class to update the +stocks data in the watchlist. +2. It then calls the `printStocksInfo()` method of the Ui class to print out the watchlist. +3. Finally, it calls the static `saveWatchList()` method of the SaveData class to save the watchlist info to +watchlist.json. + +#### Watchlist + +The watchlist class keeps a record of the stocks that the user is interested in using a hashmap as shown. +``` +private HashMap stocks; +``` + +1. When its method `getLatestWatchListInfo()` is invoked, it calls `getExpiredStocks` to get the list +of stocks that has expired and should be renewed with latest info. +2. With the list of expired stocks, it calls `fetchFMPStockPrices` which connects to Financial Modeling API to retrieve +the latest stock prices and calls `extractWatchListInfoFromJSONArray` to update the stocks in the Hashmap +with the latest stock data. + +### Stock + +Stocks class objects are the values that make up the stocks hashmap in the watchlist. They cache the stock data obtained +from the API as attributes of the class. + +``` +private String symbol; +private String exchange; +private String stockName; +private String price; +private String dayHigh; +private String dayLow; +private Date lastUpdated = null; +private long lastFetched = 0; +private int hashCode = 0; +``` + +Shown above is a complete list of attribute of the stock class. + +`lastFetched` and `hashCode` are attributes that are not related to the stock financial data. +`lastFetched` is used for caching validity checking and `hashCode` is used to tell whether saved values on disk +are corrupted. + +#### Watchlist Class Diagram (Simplified) + +![](images/investments/watchlistClassDiagram.png) + +#### Watchlist sequence Diagram (Simplified) + +![](images/investments/watchlistSequence.png) + ### Add Income/Expense Feature The add income/expense command has 2 compulsory arguments `/t` and `/a` and 1 optional argument `/r`. diff --git a/docs/diagrams/investments/watchlistClassDiagram.puml b/docs/diagrams/investments/watchlistClassDiagram.puml new file mode 100644 index 0000000000..72254b5a3b --- /dev/null +++ b/docs/diagrams/investments/watchlistClassDiagram.puml @@ -0,0 +1,40 @@ +@startuml +'https://plantuml.com/class-diagram +skinparam classFontColor automatic + +Class Ui #Cornsilk { + +printStocksInfo(watchlist: WatchList) +} + +Class WatchList #Cornsilk { + +getLatestWatchlistInfo() + +getExpiredStocks() : StringBuilder + +fetchFMPStockPrices(queryStocks : StringBuilder) + +extractWatchlistInfoFromJSONArray(jsonStocks: JSONArray) +} + +Class WatchListCommand #HoneyDew { + +execute() +} + +Class SaveData #LightPink { + +saveWatchList() +} + +Class Stock #LightBlue { + +getStockNameFromAPI(symbol: String) + +setHashCode() + +checkHashCode() +} + +WatchListCommand .right.> SaveData +WatchListCommand -right-> "1" Ui +WatchListCommand --> "1" WatchList +WatchList --> "0..5" Stock + +note right: attributes are shown in DG + +hide Circle +skinparam classAttributeIconSize 0 + +@enduml \ No newline at end of file diff --git a/docs/diagrams/investments/watchlistSequence.puml b/docs/diagrams/investments/watchlistSequence.puml new file mode 100644 index 0000000000..c852ca62e7 --- /dev/null +++ b/docs/diagrams/investments/watchlistSequence.puml @@ -0,0 +1,23 @@ +@startuml + +participant ":WatchlistCommand" as WatchListCommand +participant ":WatchList" as WatchList +participant ":Ui" as Ui +participant "<>\nSaveData" as SaveData + +-> WatchListCommand: execute() +activate WatchListCommand + WatchListCommand -> WatchList: getLatestWatchlistInfo() + activate WatchList + WatchList -> WatchList : getExpiredStocks() + activate WatchList + return queryStocks + WatchList -> WatchList : fetchLatestWatchListInfo() + return + WatchListCommand -> Ui: printStocksInfo(watchlist) + WatchListCommand -> SaveData: saveWatchList() + +return + +hide footbox +@enduml \ No newline at end of file diff --git a/docs/images/investments/watchlistClassDiagram.png b/docs/images/investments/watchlistClassDiagram.png new file mode 100644 index 0000000000000000000000000000000000000000..420bc93f5b71d8d82511389fcb60c8619b64bd2c GIT binary patch literal 31458 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 A6#xJL literal 0 HcmV?d00001 diff --git a/docs/images/investments/watchlistOutput.png b/docs/images/investments/watchlistOutput.png new file mode 100644 index 0000000000000000000000000000000000000000..5c92c9072efddd09f2a51cbd38d6210224300103 GIT binary patch literal 27765 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 literal 0 HcmV?d00001 diff --git a/docs/images/investments/watchlistSequence.png b/docs/images/investments/watchlistSequence.png new file mode 100644 index 0000000000000000000000000000000000000000..b1d1bad2dda093df433aecacec35ebc10056d1f0 GIT binary patch literal 31270 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 literal 0 HcmV?d00001 From 3612cc8315044e3c429f5fd667b60a5b93adac83 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 12 Nov 2023 14:37:07 +0800 Subject: [PATCH 480/518] Add to table of contents --- docs/DeveloperGuide.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index d003691e45..bcdb83158b 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -10,6 +10,9 @@ * [Visualization Feature](#visualization-feature-) * [Class diagram](#class-diagram) * [Sequence diagram](#sequence-diagram-) + * [WatchList Feature](#watchlist-feature) + * [Class diagram](#watchlist-class-diagram-simplified) + * [Sequence diagram](#watchlist-sequence-diagram-simplified) * [Add Income/Expense Feature](#add-incomeexpense-feature) * [Class Diagram](#add-incomeexpense-class-diagram) * [Sequence Diagram](#add-incomeexpense-sequence-diagram) From 36e7556d4b02f4b97e98b8a552e8ef806fc23a4f Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 12 Nov 2023 14:53:29 +0800 Subject: [PATCH 481/518] Update PPP --- docs/team/frederick.md | 5 ----- docs/team/wwweert123.md | 4 ++++ 2 files changed, 4 insertions(+), 5 deletions(-) delete mode 100644 docs/team/frederick.md diff --git a/docs/team/frederick.md b/docs/team/frederick.md deleted file mode 100644 index 6ddbda5256..0000000000 --- a/docs/team/frederick.md +++ /dev/null @@ -1,5 +0,0 @@ -I am Frederick - -Hello - -I am from this team! \ No newline at end of file diff --git a/docs/team/wwweert123.md b/docs/team/wwweert123.md index 94d84a4a31..745a2e7da4 100644 --- a/docs/team/wwweert123.md +++ b/docs/team/wwweert123.md @@ -36,6 +36,10 @@ you a one-stop interface to access a plethora of features to manage your finance * Implementation * Class Diagram * Sequence Diagrams +* Watchlist Component + * Implementation + * Class Diagram + * Sequence Diagram * Value Proposition * User Profile * USer Stories From e19808b2205c4a60807ecb5681d40d1fc16606fd Mon Sep 17 00:00:00 2001 From: hshiah Date: Sun, 12 Nov 2023 14:56:05 +0800 Subject: [PATCH 482/518] Fix bugs --- .../commands/AddReminderCommand.java | 6 ++- .../commands/DeleteGoalCommand.java | 5 +- .../commands/DeleteReminderCommand.java | 5 +- .../commands/FindCommand.java | 1 - .../commands/MarkGoalCommand.java | 16 ++++-- .../commands/MarkReminderCommand.java | 16 ++++-- .../commands/ReminderListCommand.java | 4 ++ .../commands/SetGoalCommand.java | 17 ++++++- .../commands/WishListCommand.java | 4 ++ .../commands/AddReminderCommandTest.java | 50 +++++++++++++++++++ 10 files changed, 110 insertions(+), 14 deletions(-) create mode 100644 src/test/java/seedu/financialplanner/commands/AddReminderCommandTest.java diff --git a/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java b/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java index 95d659bba6..d8546cf160 100644 --- a/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java @@ -30,7 +30,7 @@ public AddReminderCommand(RawCommand rawCommand) throws IllegalArgumentException throw new IllegalArgumentException("Reminder must have a type"); } type = rawCommand.extraArgs.get("t"); - if(type.isEmpty()){ + if(type.trim().isEmpty()){ throw new IllegalArgumentException("Reminder type cannot be empty"); } rawCommand.extraArgs.remove("t"); @@ -39,7 +39,7 @@ public AddReminderCommand(RawCommand rawCommand) throws IllegalArgumentException } String dateString = rawCommand.extraArgs.get("d"); - if(dateString.isEmpty()){ + if(dateString.trim().isEmpty()){ throw new IllegalArgumentException("Reminder date cannot be empty"); } @@ -63,6 +63,8 @@ public AddReminderCommand(RawCommand rawCommand) throws IllegalArgumentException @Override public void execute() { + assert type != null; + assert LocalDate.now().isBefore(date); Reminder reminder = new Reminder(type, date); ReminderList.getInstance().list.add(reminder); Ui.getInstance().showMessage("You have added " + reminder); diff --git a/src/main/java/seedu/financialplanner/commands/DeleteGoalCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteGoalCommand.java index 9b9f550f64..b46fce3be7 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteGoalCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteGoalCommand.java @@ -31,7 +31,7 @@ public DeleteGoalCommand(RawCommand rawCommand) throws IllegalArgumentException index = Integer.parseInt(stringIndex); } catch (IllegalArgumentException e) { logger.log(Level.WARNING, "Invalid argument for index"); - throw new IllegalArgumentException("Index must be an integer"); + throw new IllegalArgumentException("Index must be a valid integer"); } if (index <= 0) { @@ -39,7 +39,7 @@ public DeleteGoalCommand(RawCommand rawCommand) throws IllegalArgumentException throw new IllegalArgumentException("Index must be within the list"); } - if (index > WishList.getInstance().list.size() + 1) { + if (index > WishList.getInstance().list.size()) { logger.log(Level.WARNING, "Invalid value for index"); throw new IllegalArgumentException("Index exceed the list size"); } @@ -53,6 +53,7 @@ public DeleteGoalCommand(RawCommand rawCommand) throws IllegalArgumentException @Override public void execute() { + assert index > 0 && index <= WishList.getInstance().list.size(); Goal goalToDelete = WishList.getInstance().list.get(index - 1); WishList.getInstance().deleteGoal(index - 1); Ui.getInstance().showMessage("You have deleted " + goalToDelete); diff --git a/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java index a5d4637058..6588550cc5 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java @@ -31,7 +31,7 @@ public DeleteReminderCommand(RawCommand rawCommand) throws IllegalArgumentExcept index = Integer.parseInt(stringIndex); } catch (IllegalArgumentException e) { logger.log(Level.WARNING, "Invalid argument for index"); - throw new IllegalArgumentException("Index must be an integer"); + throw new IllegalArgumentException("Index must be a valid integer"); } if (index <= 0) { @@ -39,7 +39,7 @@ public DeleteReminderCommand(RawCommand rawCommand) throws IllegalArgumentExcept throw new IllegalArgumentException("Index must be within the list"); } - if (index > ReminderList.getInstance().list.size() + 1) { + if (index > ReminderList.getInstance().list.size()) { logger.log(Level.WARNING, "Invalid value for index"); throw new IllegalArgumentException("Index exceed the list size"); } @@ -52,6 +52,7 @@ public DeleteReminderCommand(RawCommand rawCommand) throws IllegalArgumentExcept @Override public void execute() { + assert index > 0 && index <= ReminderList.getInstance().list.size(); Reminder reminderToDelete = ReminderList.getInstance().list.get(index - 1); ReminderList.getInstance().deleteReminder(index - 1); Ui.getInstance().showMessage("You have deleted " + reminderToDelete); diff --git a/src/main/java/seedu/financialplanner/commands/FindCommand.java b/src/main/java/seedu/financialplanner/commands/FindCommand.java index cd958ea53b..5d4b319a63 100644 --- a/src/main/java/seedu/financialplanner/commands/FindCommand.java +++ b/src/main/java/seedu/financialplanner/commands/FindCommand.java @@ -32,7 +32,6 @@ public void execute() { Ui ui = Ui.getInstance(); WatchList watchList = WatchList.getInstance(); ArrayList foundedFinancialList = new ArrayList<>(); - ArrayList foundedWatchList = new ArrayList<>(); for (int i = 0; i < cashflowList.list.size(); i++) { if (cashflowList.list.get(i).toString().toLowerCase().contains(description.toLowerCase())) { String output = cashflowList.list.get(i).toString() + " | Index: " + (i + 1); diff --git a/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java b/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java index 1d44182820..8d171404c8 100644 --- a/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java +++ b/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java @@ -8,12 +8,16 @@ import seedu.financialplanner.goal.WishList; import seedu.financialplanner.utils.Ui; +import java.util.logging.Level; +import java.util.logging.Logger; + @SuppressWarnings("unused") public class MarkGoalCommand extends Command { public static final String NAME = "markgoal"; public static final String USAGE = "markgoal "; public static final String EXAMPLE = "markgoal 1"; + private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private final int index; public MarkGoalCommand(RawCommand rawCommand) throws IllegalArgumentException { @@ -25,25 +29,31 @@ public MarkGoalCommand(RawCommand rawCommand) throws IllegalArgumentException { } try { + logger.log(Level.INFO, "Parsing index as integer"); index = Integer.parseInt(stringIndex); } catch (IllegalArgumentException e) { - throw new IllegalArgumentException("Index must be an integer"); + logger.log(Level.WARNING, "Invalid argument for index"); + throw new IllegalArgumentException("Index must be a valid integer"); } - if (index == 0) { + if (index <= 0) { + logger.log(Level.WARNING, "Invalid value for index"); throw new IllegalArgumentException("Index must be within the list"); } - if (index > WishList.getInstance().list.size() + 1) { + if (index > WishList.getInstance().list.size()) { + logger.log(Level.WARNING, "Invalid value for index"); throw new IllegalArgumentException("Index exceed the list size"); } rawCommand.extraArgs.remove("i"); if (!rawCommand.extraArgs.isEmpty()) { String unknownExtraArgument = new java.util.ArrayList<>(rawCommand.extraArgs.keySet()).get(0); + logger.log(Level.WARNING, "Invalid extra arguments found"); throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); } } @Override public void execute() { + assert index > 0 && index <= WishList.getInstance().list.size(); Goal goal = WishList.getInstance().list.get(index - 1); goal.markAsDone(); Ui.getInstance().showMessage("You have achieved " + goal + System.lineSeparator() + "Congratulations!"); diff --git a/src/main/java/seedu/financialplanner/commands/MarkReminderCommand.java b/src/main/java/seedu/financialplanner/commands/MarkReminderCommand.java index 443afbba4b..1fc3a281c7 100644 --- a/src/main/java/seedu/financialplanner/commands/MarkReminderCommand.java +++ b/src/main/java/seedu/financialplanner/commands/MarkReminderCommand.java @@ -5,12 +5,16 @@ import seedu.financialplanner.reminder.ReminderList; import seedu.financialplanner.utils.Ui; +import java.util.logging.Level; +import java.util.logging.Logger; + @SuppressWarnings("unused") public class MarkReminderCommand extends Command { public static final String NAME = "markreminder"; public static final String USAGE = "markreminder "; public static final String EXAMPLE = "markreminder 1"; + private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private final int index; public MarkReminderCommand(RawCommand rawCommand) throws IllegalArgumentException { @@ -22,25 +26,31 @@ public MarkReminderCommand(RawCommand rawCommand) throws IllegalArgumentExceptio } try { + logger.log(Level.INFO, "Parsing index as integer"); index = Integer.parseInt(stringIndex); } catch (IllegalArgumentException e) { - throw new IllegalArgumentException("Index must be an integer"); + logger.log(Level.WARNING, "Invalid argument for index"); + throw new IllegalArgumentException("Index must be a valid integer"); } - if (index == 0) { + if (index <= 0) { + logger.log(Level.WARNING, "Invalid value for index"); throw new IllegalArgumentException("Index must be within the list"); } - if (index > ReminderList.getInstance().list.size() + 1) { + if (index > ReminderList.getInstance().list.size()) { + logger.log(Level.WARNING, "Invalid value for index"); throw new IllegalArgumentException("Index exceed the list size"); } rawCommand.extraArgs.remove("i"); if (!rawCommand.extraArgs.isEmpty()) { String unknownExtraArgument = new java.util.ArrayList<>(rawCommand.extraArgs.keySet()).get(0); + logger.log(Level.WARNING, "Invalid extra arguments found"); throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); } } @Override public void execute() { + assert index > 0 && index <= ReminderList.getInstance().list.size(); ReminderList.getInstance().list.get(index - 1).markAsDone(); Ui.getInstance().showMessage("You have marked " + ReminderList.getInstance().list.get(index - 1)); } diff --git a/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java b/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java index c61339fe22..dc88ca24ac 100644 --- a/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java @@ -20,6 +20,10 @@ public ReminderListCommand(RawCommand rawCommand) throws IllegalArgumentExceptio public void execute() { Ui ui = Ui.getInstance(); ReminderList reminderList = ReminderList.getInstance(); + if (reminderList.list.isEmpty()) { + ui.showMessage("You have no reminders."); + return; + } ui.showMessage("Here is your reminder list:"); ui.showMessage(reminderList.toString()); } diff --git a/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java b/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java index 97fb9e1cae..10b7d2b98a 100644 --- a/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java +++ b/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java @@ -22,16 +22,30 @@ public SetGoalCommand(RawCommand rawCommand) throws IllegalArgumentException { if (!rawCommand.extraArgs.containsKey("g")) { throw new IllegalArgumentException("Goal must have an amount"); } + + String amountString = rawCommand.extraArgs.get("g"); + if (amountString.trim().isEmpty()) { + throw new IllegalArgumentException("Amount must be specified"); + } try { - amount = Integer.parseInt(rawCommand.extraArgs.get("g")); + amount = Integer.parseInt(amountString); } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Amount must be a number"); } + + if (amount<= 0) { + throw new IllegalArgumentException("Amount must be positive"); + } + rawCommand.extraArgs.remove("g"); if (!rawCommand.extraArgs.containsKey("l")) { throw new IllegalArgumentException("Please specify the content of the goal"); } label = rawCommand.extraArgs.get("l"); + + if (label.trim().isEmpty()) { + throw new IllegalArgumentException("Please specify the content of the goal"); + } rawCommand.extraArgs.remove("l"); if (!rawCommand.extraArgs.isEmpty()) { String unknownExtraArgument = new java.util.ArrayList<>(rawCommand.extraArgs.keySet()).get(0); @@ -41,6 +55,7 @@ public SetGoalCommand(RawCommand rawCommand) throws IllegalArgumentException { @Override public void execute() { + assert amount > 0; Goal goal = new Goal(label, amount); WishList.getInstance().list.add(goal); Ui.getInstance().showMessage("You have added " + goal); diff --git a/src/main/java/seedu/financialplanner/commands/WishListCommand.java b/src/main/java/seedu/financialplanner/commands/WishListCommand.java index d4427fb344..4d9c533673 100644 --- a/src/main/java/seedu/financialplanner/commands/WishListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/WishListCommand.java @@ -20,6 +20,10 @@ public WishListCommand(RawCommand rawCommand) throws IllegalArgumentException { public void execute() { Ui ui = Ui.getInstance(); WishList wishList = WishList.getInstance(); + if (wishList.list.isEmpty()) { + ui.showMessage("You have no wish list."); + return; + } ui.showMessage("Here is your wish list:"); ui.showMessage(wishList.toString()); } diff --git a/src/test/java/seedu/financialplanner/commands/AddReminderCommandTest.java b/src/test/java/seedu/financialplanner/commands/AddReminderCommandTest.java new file mode 100644 index 0000000000..0e2dc91e35 --- /dev/null +++ b/src/test/java/seedu/financialplanner/commands/AddReminderCommandTest.java @@ -0,0 +1,50 @@ +package seedu.financialplanner.commands; + +import org.junit.jupiter.api.Test; +import seedu.financialplanner.reminder.ReminderList; +import seedu.financialplanner.utils.Parser; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; + +class AddReminderCommandTest { + protected ReminderList reminderList = ReminderList.getInstance(); + + @Test + void testIllegalArgumentException() { + try { + AddReminderCommand testEntry = new AddReminderCommand(Parser.parseRawCommand("addreminder")); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Reminder must have a type", e.getMessage()); + } + + try { + AddReminderCommand testEntry = new AddReminderCommand(Parser.parseRawCommand("addreminder /t debt")); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Reminder must have a date", e.getMessage()); + } + + try { + AddReminderCommand testEntry = new AddReminderCommand(Parser.parseRawCommand("addreminder /t debt /d 11/12/2020")); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Reminder date cannot be in the past", e.getMessage()); + } + + try { + AddReminderCommand testEntry = new AddReminderCommand(Parser.parseRawCommand("addreminder /t debt /d 2023/12/12")); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Reminder date must be in the format dd/MM/yyyy", e.getMessage()); + } + + try { + AddReminderCommand testEntry = new AddReminderCommand(Parser.parseRawCommand("addreminder /t /d 11/12/2023")); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Reminder type cannot be empty", e.getMessage()); + } + } +} From 86e7b72a05fe119440e5a22de95f7fe169f3378f Mon Sep 17 00:00:00 2001 From: hshiah Date: Sun, 12 Nov 2023 15:00:45 +0800 Subject: [PATCH 483/518] Fix checkstyle --- .../commands/AddReminderCommandTest.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/test/java/seedu/financialplanner/commands/AddReminderCommandTest.java b/src/test/java/seedu/financialplanner/commands/AddReminderCommandTest.java index 0e2dc91e35..1332b0399d 100644 --- a/src/test/java/seedu/financialplanner/commands/AddReminderCommandTest.java +++ b/src/test/java/seedu/financialplanner/commands/AddReminderCommandTest.java @@ -27,21 +27,24 @@ void testIllegalArgumentException() { } try { - AddReminderCommand testEntry = new AddReminderCommand(Parser.parseRawCommand("addreminder /t debt /d 11/12/2020")); + AddReminderCommand testEntry = new AddReminderCommand( + Parser.parseRawCommand("addreminder /t debt /d 11/12/2020")); fail(); } catch (IllegalArgumentException e) { assertEquals("Reminder date cannot be in the past", e.getMessage()); } try { - AddReminderCommand testEntry = new AddReminderCommand(Parser.parseRawCommand("addreminder /t debt /d 2023/12/12")); + AddReminderCommand testEntry = new AddReminderCommand( + Parser.parseRawCommand("addreminder /t debt /d 2023/12/12")); fail(); } catch (IllegalArgumentException e) { assertEquals("Reminder date must be in the format dd/MM/yyyy", e.getMessage()); } try { - AddReminderCommand testEntry = new AddReminderCommand(Parser.parseRawCommand("addreminder /t /d 11/12/2023")); + AddReminderCommand testEntry = new AddReminderCommand( + Parser.parseRawCommand("addreminder /t /d 11/12/2023")); fail(); } catch (IllegalArgumentException e) { assertEquals("Reminder type cannot be empty", e.getMessage()); From 579a5e1f7b30ef42bf5795b76c9e74096527027a Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Sun, 12 Nov 2023 15:36:22 +0800 Subject: [PATCH 484/518] Update Diagrams --- .../investments/watchlistSequence.puml | 4 ++++ docs/diagrams/vis/categorizerSequence.puml | 6 ++++-- docs/diagrams/vis/visualizerSequence.puml | 4 ++-- docs/images/investments/watchlistSequence.png | Bin 31270 -> 18629 bytes docs/images/vis/categorizerSequence.png | Bin 18371 -> 20693 bytes docs/images/vis/visualizerSequence.png | Bin 19284 -> 18267 bytes 6 files changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/diagrams/investments/watchlistSequence.puml b/docs/diagrams/investments/watchlistSequence.puml index c852ca62e7..658a46bed1 100644 --- a/docs/diagrams/investments/watchlistSequence.puml +++ b/docs/diagrams/investments/watchlistSequence.puml @@ -15,7 +15,11 @@ activate WatchListCommand WatchList -> WatchList : fetchLatestWatchListInfo() return WatchListCommand -> Ui: printStocksInfo(watchlist) + activate Ui + return WatchListCommand -> SaveData: saveWatchList() + activate SaveData + return return diff --git a/docs/diagrams/vis/categorizerSequence.puml b/docs/diagrams/vis/categorizerSequence.puml index 55daabc0e8..d9ba69154f 100644 --- a/docs/diagrams/vis/categorizerSequence.puml +++ b/docs/diagrams/vis/categorizerSequence.puml @@ -7,14 +7,16 @@ autoactivate on participant ":VisCommand" participant "<>\nCategorizer" +activate ":VisCommand" + ":VisCommand"-> "<>\nCategorizer": sortType(cashflowList, type) alt "expense" "<>\nCategorizer" -> "<>\nCategorizer": sortExpenses(cashflowList) - return + return expenseByCat else "income" "<>\nCategorizer" -> "<>\nCategorizer": sortIncome(cashflowList) - return + return incomeByCat end return sortedCashflow: Map diff --git a/docs/diagrams/vis/visualizerSequence.puml b/docs/diagrams/vis/visualizerSequence.puml index 19fdf7fa1f..41d70463fc 100644 --- a/docs/diagrams/vis/visualizerSequence.puml +++ b/docs/diagrams/vis/visualizerSequence.puml @@ -7,7 +7,7 @@ participant "<>\nVisualizer" ":VisCommand"-> "<>\nVisualizer": displayChart(chart, sortedCashFlow, type) -activate "<>\nVisualizer" + alt "pie" "<>\nVisualizer" -> "<>\nVisualizer": displayPieChart(cashflowList, type) @@ -17,7 +17,7 @@ else "radar" "<>\nVisualizer" -> "<>\nVisualizer": displayRadarChart(cashflowList, type) end -return + hide footbox diff --git a/docs/images/investments/watchlistSequence.png b/docs/images/investments/watchlistSequence.png index b1d1bad2dda093df433aecacec35ebc10056d1f0..ae0c638996fe7e9394aece41159494a9576160d6 100644 GIT binary patch literal 18629 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 diff --git a/docs/images/vis/categorizerSequence.png b/docs/images/vis/categorizerSequence.png index 44be8a2dc07a3f5bae11a89fd9aa6d87a38d195f..f0ca65a100a53ea0c9bd37f22b6b640856ee2804 100644 GIT binary patch literal 20693 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 WWAC&T^uQZ^5W@Tt4^nwmUi~k(EB^uj literal 18371 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 LJUXd4== zuC4~guWF9ss}K6T0Y*!}vIn;~fQ{KcSvp;nt6ftG%zw5ipu99mF=!1eNbM{>Xnua< z7$g%sJiHN7@zW(Uj)@ie0E#3cQ7&D&v{tiAzDDE=7nqs}6_8ab-1+Q}x2RmeA);Yo zLYMgFw1STY@W%H@-iVg>Qt`h~D)xte5GrIAO#n51wdvhR=}8XbDfBI0=LkOZvKM7UTS^EHI10mE*KtLdq#Onm;aWm$p&_U6| z@+Dr{TeljAAH~7iwl_tDvO)%(noo~oaD*9d0El{`n2cyrx@))oF3;MS75l^;m~2E3G>EPZFCr$6aa zHz+kkIhX!7LkgVWCy@N_Cer_gP-%--1-Rjn*9!vV^r-N{i(mc}^7)Y`yQdejgCQ3b z)zm7?Mv7PsyRUH$qx_xgojOt=>x~!bOU=I{|NHOTE(isFTwY!Vw=zJ@J)6luYwv5Z zzuRh0y$YHhySlmpS2TMV+<~69t@*>+`elD9c&#@*2FDZPCj+3^}SWEf}lx8{e3u~h&zm32tPMnj1B?X7OIA{DQ zr0?^Oaws)@EK-hT28V0>t`&t>D6{3+Z>$`H%a9*nDiTl>&zdlM6{J*D_u|Eij}|Oe z(+~BC1aVT^Sx)L10lEd(MQ)xLsE}{$|GYMWBs*Ekkh>`-C80=&28y(PT~q;~)bhJl z^qUn8PWHq_UkX2Od`Px# literal 19284 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 Date: Sun, 12 Nov 2023 16:18:49 +0800 Subject: [PATCH 485/518] Update javadoc --- .../commands/AddReminderCommand.java | 9 +++++ .../commands/DeleteGoalCommand.java | 9 +++++ .../commands/DeleteReminderCommand.java | 9 +++++ .../commands/FindCommand.java | 9 +++++ .../commands/MarkGoalCommand.java | 9 +++++ .../commands/MarkReminderCommand.java | 9 +++++ .../commands/ReminderListCommand.java | 19 ++++++++++- .../commands/SetGoalCommand.java | 9 +++++ .../commands/WishListCommand.java | 20 ++++++++++- .../seedu/financialplanner/goal/Goal.java | 27 +++++++++++++++ .../seedu/financialplanner/goal/WishList.java | 19 +++++++++++ .../financialplanner/reminder/Reminder.java | 33 ++++++++++++++++--- .../reminder/ReminderList.java | 17 ++++++++++ 13 files changed, 192 insertions(+), 6 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java b/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java index d8546cf160..6bc4130931 100644 --- a/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java +++ b/src/main/java/seedu/financialplanner/commands/AddReminderCommand.java @@ -24,6 +24,12 @@ public class AddReminderCommand extends Command { private final String type; private final LocalDate date; + /** + * Constructor for the command to add a reminder. + * + * @param rawCommand The input from the user. + * @throws IllegalArgumentException if erroneous inputs are detected. + */ public AddReminderCommand(RawCommand rawCommand) throws IllegalArgumentException { String typeString = String.join(" ", rawCommand.args); if (!rawCommand.extraArgs.containsKey("t")) { @@ -61,6 +67,9 @@ public AddReminderCommand(RawCommand rawCommand) throws IllegalArgumentException } } + /** + * Executes the command to add a reminder. + */ @Override public void execute() { assert type != null; diff --git a/src/main/java/seedu/financialplanner/commands/DeleteGoalCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteGoalCommand.java index b46fce3be7..a80d858a85 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteGoalCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteGoalCommand.java @@ -18,6 +18,12 @@ public class DeleteGoalCommand extends Command { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private final int index; + /** + * Constructor of the command to delete a goal. + * + * @param rawCommand The input from the user. + * @throws IllegalArgumentException if erroneous inputs are detected. + */ public DeleteGoalCommand(RawCommand rawCommand) throws IllegalArgumentException { String stringIndex; if (rawCommand.args.size() == 1) { @@ -51,6 +57,9 @@ public DeleteGoalCommand(RawCommand rawCommand) throws IllegalArgumentException } } + /** + * Executes the command to delete a goal. + */ @Override public void execute() { assert index > 0 && index <= WishList.getInstance().list.size(); diff --git a/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java b/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java index 6588550cc5..d6807bd853 100644 --- a/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java +++ b/src/main/java/seedu/financialplanner/commands/DeleteReminderCommand.java @@ -18,6 +18,12 @@ public class DeleteReminderCommand extends Command { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private final int index; + /** + * Constructor of the command to delete a reminder. + * + * @param rawCommand The input from the user. + * @throws IllegalArgumentException if erroneous inputs are detected. + */ public DeleteReminderCommand(RawCommand rawCommand) throws IllegalArgumentException { String stringIndex; if (rawCommand.args.size() == 1) { @@ -50,6 +56,9 @@ public DeleteReminderCommand(RawCommand rawCommand) throws IllegalArgumentExcept } } + /** + * Executes the command to delete a reminder. + */ @Override public void execute() { assert index > 0 && index <= ReminderList.getInstance().list.size(); diff --git a/src/main/java/seedu/financialplanner/commands/FindCommand.java b/src/main/java/seedu/financialplanner/commands/FindCommand.java index 5d4b319a63..c7f4dd41b7 100644 --- a/src/main/java/seedu/financialplanner/commands/FindCommand.java +++ b/src/main/java/seedu/financialplanner/commands/FindCommand.java @@ -18,6 +18,12 @@ public class FindCommand extends Command { "find buy coffee"; private final String description; + /** + * Constructor of the command to find cashflow. + * + * @param rawCommand The input from the user. + * @throws IllegalArgumentException if erroneous inputs are detected. + */ public FindCommand(RawCommand rawCommand) { this.description = String.join(" ", rawCommand.args); if (!rawCommand.extraArgs.isEmpty()) { @@ -26,6 +32,9 @@ public FindCommand(RawCommand rawCommand) { } } + /** + * Executes the command to find. + */ @Override public void execute() { CashflowList cashflowList = CashflowList.getInstance(); diff --git a/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java b/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java index 8d171404c8..c18002904f 100644 --- a/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java +++ b/src/main/java/seedu/financialplanner/commands/MarkGoalCommand.java @@ -20,6 +20,12 @@ public class MarkGoalCommand extends Command { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private final int index; + /** + * Constructor of the command to mark a goal as achieved. + * + * @param rawCommand The input from the user. + * @throws IllegalArgumentException if erroneous inputs are detected. + */ public MarkGoalCommand(RawCommand rawCommand) throws IllegalArgumentException { String stringIndex; if (rawCommand.args.size() == 1) { @@ -51,6 +57,9 @@ public MarkGoalCommand(RawCommand rawCommand) throws IllegalArgumentException { } } + /** + * Executes the command to mark the goal. + */ @Override public void execute() { assert index > 0 && index <= WishList.getInstance().list.size(); diff --git a/src/main/java/seedu/financialplanner/commands/MarkReminderCommand.java b/src/main/java/seedu/financialplanner/commands/MarkReminderCommand.java index 1fc3a281c7..3f4ee36501 100644 --- a/src/main/java/seedu/financialplanner/commands/MarkReminderCommand.java +++ b/src/main/java/seedu/financialplanner/commands/MarkReminderCommand.java @@ -17,6 +17,12 @@ public class MarkReminderCommand extends Command { private static final Logger logger = Logger.getLogger("Financial Planner Logger"); private final int index; + /** + * Constructor of the command to mark a reminder as done. + * + * @param rawCommand The input from the user. + * @throws IllegalArgumentException if erroneous inputs are detected. + */ public MarkReminderCommand(RawCommand rawCommand) throws IllegalArgumentException { String stringIndex; if (rawCommand.args.size() == 1) { @@ -48,6 +54,9 @@ public MarkReminderCommand(RawCommand rawCommand) throws IllegalArgumentExceptio } } + /** + * Executes the command to mark the reminder. + */ @Override public void execute() { assert index > 0 && index <= ReminderList.getInstance().list.size(); diff --git a/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java b/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java index dc88ca24ac..0d8a022ca7 100644 --- a/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java @@ -5,6 +5,8 @@ import seedu.financialplanner.reminder.ReminderList; import seedu.financialplanner.utils.Ui; +import java.util.logging.Level; + @SuppressWarnings("unused") public class ReminderListCommand extends Command { public static final String NAME = "reminderlist"; @@ -12,10 +14,25 @@ public class ReminderListCommand extends Command { public static final String USAGE = "reminderlist"; public static final String EXAMPLE = "reminderlist"; - public ReminderListCommand(RawCommand rawCommand) throws IllegalArgumentException { + private static final java.util.logging.Logger logger = java.util.logging.Logger.getLogger("Financial Planner Logger"); + /** + * Constructor of the command to list goals. + * + * @param rawCommand The input from the user. + * @throws IllegalArgumentException if erroneous inputs are detected. + */ + public ReminderListCommand(RawCommand rawCommand) throws IllegalArgumentException { + if (!rawCommand.extraArgs.isEmpty()) { + String unknownExtraArgument = new java.util.ArrayList<>(rawCommand.extraArgs.keySet()).get(0); + logger.log(Level.WARNING, "Invalid extra arguments found"); + throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); + } } + /** + * Executes the command to list the reminders. + */ @Override public void execute() { Ui ui = Ui.getInstance(); diff --git a/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java b/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java index 10b7d2b98a..39cec2573d 100644 --- a/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java +++ b/src/main/java/seedu/financialplanner/commands/SetGoalCommand.java @@ -17,6 +17,12 @@ public class SetGoalCommand extends Command { private final String label; private final int amount; + /** + * Constructor for the command to set a goal. + * + * @param rawCommand The input from the user. + * @throws IllegalArgumentException if erroneous inputs are detected. + */ public SetGoalCommand(RawCommand rawCommand) throws IllegalArgumentException { String labelString = String.join(" ", rawCommand.args); if (!rawCommand.extraArgs.containsKey("g")) { @@ -53,6 +59,9 @@ public SetGoalCommand(RawCommand rawCommand) throws IllegalArgumentException { } } + /** + * Executes the command to set a goal. + */ @Override public void execute() { assert amount > 0; diff --git a/src/main/java/seedu/financialplanner/commands/WishListCommand.java b/src/main/java/seedu/financialplanner/commands/WishListCommand.java index 4d9c533673..7b979f2d7e 100644 --- a/src/main/java/seedu/financialplanner/commands/WishListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/WishListCommand.java @@ -5,6 +5,9 @@ import seedu.financialplanner.goal.WishList; import seedu.financialplanner.utils.Ui; +import java.util.logging.Level; +import java.util.logging.Logger; + @SuppressWarnings("unused") public class WishListCommand extends Command { public static final String NAME = "wishlist"; @@ -12,10 +15,25 @@ public class WishListCommand extends Command { public static final String USAGE = "wishlist"; public static final String EXAMPLE = "wishlist"; - public WishListCommand(RawCommand rawCommand) throws IllegalArgumentException { + private static final Logger logger = Logger.getLogger("Financial Planner Logger"); + /** + * Constructor of the command to list goals. + * + * @param rawCommand The input from the user. + * @throws IllegalArgumentException if erroneous inputs are detected. + */ + public WishListCommand(RawCommand rawCommand) throws IllegalArgumentException { + if (!rawCommand.extraArgs.isEmpty()) { + String unknownExtraArgument = new java.util.ArrayList<>(rawCommand.extraArgs.keySet()).get(0); + logger.log(Level.WARNING, "Invalid extra arguments found"); + throw new IllegalArgumentException(String.format("Unknown extra argument: %s", unknownExtraArgument)); + } } + /** + * Executes the command to list the goals. + */ @Override public void execute() { Ui ui = Ui.getInstance(); diff --git a/src/main/java/seedu/financialplanner/goal/Goal.java b/src/main/java/seedu/financialplanner/goal/Goal.java index e7eac78a6a..69ce515587 100644 --- a/src/main/java/seedu/financialplanner/goal/Goal.java +++ b/src/main/java/seedu/financialplanner/goal/Goal.java @@ -5,11 +5,24 @@ public class Goal { private final int amount; private boolean isDone = false; + /** + * Constructor for a goal. + * + * @param label The description of the goal. + * @param amount The amount of the goal. + */ public Goal(String label, int amount) { this.label = label; this.amount = amount; } + /** + * Constructor for a goal. Used for loading from a file. + * + * @param label The description of the goal. + * @param amount The amount of the goal. + * @param status The status of the goal. + */ public Goal(String label, int amount, String status) { this.label = label; this.amount = amount; @@ -20,12 +33,20 @@ public Goal(String label, int amount, String status) { } } + /** + * Formats the goal into an easy-to-read format to be output to the user. + * + * @return The formatted goal. + */ public String toString() { String status = isDone ? "Achieved" : "Not Achieved"; return "Goal " + System.lineSeparator()+ " Label: " + label + System.lineSeparator() + " Amount: " + amount + System.lineSeparator() + " Status: "+status; } + /** + * Marks the goal as done. + */ public void markAsDone() { this.isDone = true; } @@ -36,6 +57,12 @@ public String getLabel() { public int getAmount() { return this.amount; } + + /** + * Formats the goal into an easy-to-read format to be output to the user. + * + * @return The formatted goal. + */ public String formatString() { String status = isDone ? "Achieved" : "Not Achieved"; return "G" + " | " + this.label + " | " + this.amount + " | " + status; diff --git a/src/main/java/seedu/financialplanner/goal/WishList.java b/src/main/java/seedu/financialplanner/goal/WishList.java index 612a501cbc..d54d2c4faf 100644 --- a/src/main/java/seedu/financialplanner/goal/WishList.java +++ b/src/main/java/seedu/financialplanner/goal/WishList.java @@ -14,10 +14,22 @@ public static WishList getInstance() { return wishList; } + + /** + * Loads a goal to the wish list from file. + * + * @param goal The goal to be added. + */ public void load(Goal goal) { list.add(goal); } + + /** + * Deletes a goal from the wish list. + * + * @param index + */ public void deleteGoal(int index) { int existingListSize = list.size(); int listIndex = index; @@ -25,6 +37,13 @@ public void deleteGoal(int index) { Goal toRemove = list.get(listIndex); list.remove(listIndex); } + + + /** + * Formats the reminder list into an easy-to-read format to be output to the user. + * + * @return The formatted reminder list. + */ public String toString() { String result = ""; for (int i = 0; i < list.size(); i++) { diff --git a/src/main/java/seedu/financialplanner/reminder/Reminder.java b/src/main/java/seedu/financialplanner/reminder/Reminder.java index 0624b7370f..78cd0c09ee 100644 --- a/src/main/java/seedu/financialplanner/reminder/Reminder.java +++ b/src/main/java/seedu/financialplanner/reminder/Reminder.java @@ -1,5 +1,7 @@ package seedu.financialplanner.reminder; +import seedu.financialplanner.exceptions.FinancialPlannerException; + import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.time.Duration; @@ -9,11 +11,24 @@ public class Reminder { private LocalDate date; private boolean isDone = false; + /** + * Constructor for a reminder. + * + * @param type The description of the reminder. + * @param date The deadline of the reminder. + */ public Reminder(String type, LocalDate date) { this.type = type; this.date = date; } + /** + * Constructor for a reminder. Used for loading from a file. + * + * @param type The description of the reminder. + * @param date The deadline of the reminder. + * @param status The status of the reminder. + */ public Reminder(String type, String date, String status) { this.type = type; this.date = LocalDate.parse(date, FORMATTER); @@ -23,6 +38,12 @@ public Reminder(String type, String date, String status) { this.isDone = false; } } + + /** + * Formats the reminder into an easy-to-read format to be output to the user. + * + * @return The formatted reminder. + */ public String toString() { String status = isDone ? "Done" : "Not Done"; LocalDate currentTime = LocalDate.now(); @@ -32,13 +53,17 @@ public String toString() { + System.lineSeparator() + " Left Days: " + duration.toDays(); } + /** + * Marks the reminder as done. + */ public void markAsDone() { this.isDone = true; } - /* - * Returns a string that can be saved to a file. - * Format: type | date | isDone - * Example: "Reminder: Birthday | 2020-10-10 | false" + + /** + * Formats the reminder into a standard format to be saved into a text file. + * + * @return The formatted reminder. */ public String formatString() { String status = isDone ? "Done" : "Not Done"; diff --git a/src/main/java/seedu/financialplanner/reminder/ReminderList.java b/src/main/java/seedu/financialplanner/reminder/ReminderList.java index 94ebd7e19a..5d3f9d32e2 100644 --- a/src/main/java/seedu/financialplanner/reminder/ReminderList.java +++ b/src/main/java/seedu/financialplanner/reminder/ReminderList.java @@ -13,9 +13,20 @@ public static ReminderList getInstance() { return reminderList; } + /** + * Loads a reminder into the reminder list. + * + * @param reminder The reminder to be loaded. + */ public void load(Reminder reminder) { list.add(reminder); } + + /** + * Deletes a reminder from the reminder list. + * + * @param index The index of the reminder to be deleted. + */ public void deleteReminder(int index) { int existingListSize = list.size(); int listIndex = index; @@ -24,6 +35,12 @@ public void deleteReminder(int index) { list.remove(listIndex); } + + /** + * Formats the reminder list into an easy-to-read format to be output to the user. + * + * @return The formatted reminder list. + */ public String toString() { String result = ""; for (int i = 0; i < list.size(); i++) { From 63f576555faa4dae6a123cf6c5c2d15f784faf4f Mon Sep 17 00:00:00 2001 From: hshiah Date: Sun, 12 Nov 2023 16:23:32 +0800 Subject: [PATCH 486/518] Fix checkstyle --- .../seedu/financialplanner/commands/ReminderListCommand.java | 3 ++- src/main/java/seedu/financialplanner/reminder/Reminder.java | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java b/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java index 0d8a022ca7..867badfde4 100644 --- a/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java +++ b/src/main/java/seedu/financialplanner/commands/ReminderListCommand.java @@ -14,7 +14,8 @@ public class ReminderListCommand extends Command { public static final String USAGE = "reminderlist"; public static final String EXAMPLE = "reminderlist"; - private static final java.util.logging.Logger logger = java.util.logging.Logger.getLogger("Financial Planner Logger"); + private static final java.util.logging.Logger logger = java.util.logging.Logger. + getLogger("Financial Planner Logger"); /** * Constructor of the command to list goals. diff --git a/src/main/java/seedu/financialplanner/reminder/Reminder.java b/src/main/java/seedu/financialplanner/reminder/Reminder.java index 78cd0c09ee..4b68eedaa7 100644 --- a/src/main/java/seedu/financialplanner/reminder/Reminder.java +++ b/src/main/java/seedu/financialplanner/reminder/Reminder.java @@ -1,6 +1,5 @@ package seedu.financialplanner.reminder; -import seedu.financialplanner.exceptions.FinancialPlannerException; import java.time.LocalDate; import java.time.format.DateTimeFormatter; From d8b6e07848b9cf7c5667d05c0a4764dac80d4c06 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Sun, 12 Nov 2023 19:13:53 +0800 Subject: [PATCH 487/518] Add activation bars to sequence diagrams --- .../cashflow/AddCashflowSequence.puml | 15 ++++++++++++++- .../cashflow/AddRecurringSequence.puml | 14 ++++++++++++++ docs/diagrams/cashflow/RecurSequence.puml | 12 +++++++++++- docs/images/cashflow/AddCashflowSequence.png | Bin 43896 -> 48203 bytes docs/images/cashflow/AddRecurringSequence.png | Bin 32996 -> 36969 bytes docs/images/cashflow/RecurSequence.png | Bin 33673 -> 40470 bytes 6 files changed, 39 insertions(+), 2 deletions(-) diff --git a/docs/diagrams/cashflow/AddCashflowSequence.puml b/docs/diagrams/cashflow/AddCashflowSequence.puml index 1b69eec33d..51edcba9b4 100644 --- a/docs/diagrams/cashflow/AddCashflowSequence.puml +++ b/docs/diagrams/cashflow/AddCashflowSequence.puml @@ -15,9 +15,16 @@ alt income CashflowList -> Income: Income(value, type, recur, description) activate Income Income -> Income: addIncomeValue() + activate Income + return + return CashflowList -> CashflowList: addToList(toAdd) + activate CashflowList + return CashflowList -> Ui: printAddedCashflow(toAdd) + activate Ui + return return else expense @@ -27,12 +34,18 @@ else expense CashflowList -> Expense: Expense(value, type, recur, description) activate Expense Expense -> Expense: addExpenseValue() + activate Expense + return + return CashflowList -> CashflowList: addToList(toAdd) + activate CashflowList + return CashflowList -> Ui: printAddedCashflow(toAdd) + activate Ui + return return end return - hide footbox @enduml \ No newline at end of file diff --git a/docs/diagrams/cashflow/AddRecurringSequence.puml b/docs/diagrams/cashflow/AddRecurringSequence.puml index e6cde521c2..5a8ee0c968 100644 --- a/docs/diagrams/cashflow/AddRecurringSequence.puml +++ b/docs/diagrams/cashflow/AddRecurringSequence.puml @@ -7,18 +7,32 @@ participant ":Expense" as Expense loop current date is after or equals next recurring date LoadData -> Cashflow: setHasRecurred(true) + activate Cashflow + return alt income create Income LoadData -> Income: Income((Income) cashflow) + activate Income + return LoadData -> Income: setDate(dateOfAddition) + activate Income + return LoadData -> LoadData: addToTempList(tempCashflowList, toAdd) + activate LoadData + return else expense create Expense LoadData -> Expense: Expense((Expense) cashflow) + activate Expense + return LoadData -> Expense: setDate(dateOfAddition) + activate Expense + return LoadData -> LoadData: addToTempList(tempCashflowList, toAdd) + activate LoadData + return end end diff --git a/docs/diagrams/cashflow/RecurSequence.puml b/docs/diagrams/cashflow/RecurSequence.puml index 5ec9f4c49e..d8fed6561b 100644 --- a/docs/diagrams/cashflow/RecurSequence.puml +++ b/docs/diagrams/cashflow/RecurSequence.puml @@ -24,7 +24,17 @@ end end loop for each cashflow in tempCashflowList LoadData -> CashflowList: load(cashflow) - LoadData -> Ui: printAddedCashflow(cashflow) + activate CashflowList + return + LoadData -> Ui: printAddedCashflowWithoutBalance(cashflow) + activate Ui + return +end + +opt tempCashflowList is not empty + LoadData -> Ui: printBalance() + activate Ui + return end return hide footbox diff --git a/docs/images/cashflow/AddCashflowSequence.png b/docs/images/cashflow/AddCashflowSequence.png index 7d0c4997b3b75eda20d044dc370f5de9b7388f19..1052417aa6025b3270ab8ef5ae0b4b6ca636e68a 100644 GIT binary patch literal 48203 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

k~GS%GQF4n=lW{TTc9GK;;*Qsw$@Ih$wVkSK3EZ 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 cia*j Date: Tue, 24 Oct 2023 19:27:30 +0800 Subject: [PATCH 203/518] Add acknowledgement for sources used by Frederick --- docs/DeveloperGuide.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index de0c0f4bb6..8c85e942b9 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -1,6 +1,21 @@ # Developer Guide ## Acknowledgements +**Xchart (A Simple Charting Library for Java)** +- author: KNOWN +- source: https://knowm.org/open-source/xchart/ + +**JSON Simple (simple Java toolkit for encoding and decoding JSON)** +- author: Yidong Fang (Google Code) +- source: https://code.google.com/archive/p/json-simple/ + +**Apache Common Langs 3** +- author: Apache Commons +- source: https://commons.apache.org/proper/commons-lang/ + +**Alpha Vantage Stock Market API** +- author: Alpha Vantage +- source: https://www.alphavantage.co/ {list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well} From a45215efa03cc5b8a382f5996e8863c5634a9136 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Tue, 24 Oct 2023 19:27:45 +0800 Subject: [PATCH 204/518] Add description for visualization feature --- docs/DeveloperGuide.md | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 8c85e942b9..89bb2ad42a 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -36,13 +36,33 @@ Demo: output -![](C:\Users\puach\Documents\Y2S1\CS2113\tp\docs\images\vis\Screenshot%202023-10-24%20113526.png) +![](C:\Users\puach\Documents\Y2S1\CS2113\tp\docs\images\vis\visOutput.png) This feature was implemented with the help of three different classes. +They are namely: Visualizer, Categorizer, VisCommand (Inherits from abstract Command Class) -Class Diagram +VisCommand's Role: +1) Read the parameters of the vis command entered by the user +- `/t` Reads the type of cashflow that the user wants to visualize (income/expense) +- `/c` Reads the type of visualization tools the user wants (piechart/barchart) + +2) Calls the Cateorgizer to sort cashflow (Income/Expense) according to type + +3) Calls the Visualizer to display the chart to the user + +Categorizer's Role: +According to the cashflow type (Income/Expense) arugment passed in, the Categorizer sorts the +specified cashflow entry according to type using a Hashmap which is returned and used by the Visualizer + +Visualizer's Role: + +According to the chart type (Pie/Bar) argument and the Hashmap obtained from the categorizer passed in, +the visualizer displays the specified visualization chart by calling the charting library Xchart. + +Class Diagram +![](C:\Users\puach\Documents\Y2S1\CS2113\tp\docs\images\vis\visualisationClass.png) ## Product scope ### Target user profile From abac801dc6610f4bb5d4e02736db135b90556b33 Mon Sep 17 00:00:00 2001 From: wwweert123 Date: Tue, 24 Oct 2023 20:15:39 +0800 Subject: [PATCH 205/518] Add printing of message using ui singleton when visualizing cashflow --- .../java/seedu/financialplanner/commands/VisCommand.java | 6 ++++++ src/main/java/seedu/financialplanner/utils/Ui.java | 4 ++++ .../seedu/financialplanner/visualisations/Categorizer.java | 2 +- .../seedu/financialplanner/visualisations/Visualizer.java | 2 +- 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/financialplanner/commands/VisCommand.java b/src/main/java/seedu/financialplanner/commands/VisCommand.java index acfefeecbc..79cf05c80d 100644 --- a/src/main/java/seedu/financialplanner/commands/VisCommand.java +++ b/src/main/java/seedu/financialplanner/commands/VisCommand.java @@ -2,6 +2,7 @@ import seedu.financialplanner.exceptions.FinancialPlannerException; import seedu.financialplanner.list.CashflowList; +import seedu.financialplanner.utils.Ui; import seedu.financialplanner.visualisations.Categorizer; import seedu.financialplanner.visualisations.Visualizer; @@ -35,8 +36,13 @@ public VisCommand(RawCommand rawCommand) throws IllegalArgumentException { @Override public void execute() throws FinancialPlannerException { + Ui ui = Ui.getInstance(); + assert !chart.isEmpty(); assert !type.isEmpty(); + + ui.printDisplayChart(type, chart); + Visualizer.displayChart(chart, Categorizer.sortType(CashflowList.getInstance(), type), type); } } diff --git a/src/main/java/seedu/financialplanner/utils/Ui.java b/src/main/java/seedu/financialplanner/utils/Ui.java index 0d5346b8ca..445307b991 100644 --- a/src/main/java/seedu/financialplanner/utils/Ui.java +++ b/src/main/java/seedu/financialplanner/utils/Ui.java @@ -130,4 +130,8 @@ public void printDeleteBudget() { public void printResetBudget() { showMessage("Budget has been reset to " + Budget.getInitialBudgetString() + "."); } + + public void printDisplayChart(String type, String chart) { + showMessage("Displaying " + chart + "chart for " + type); + } } diff --git a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java index fa957b190f..cbdaa2417c 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Categorizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Categorizer.java @@ -24,7 +24,7 @@ public static Map sortType(CashflowList cashflowList, String typ logger.log(Level.INFO, "categorizing income"); return sortIncome(cashflowList); default: - throw new FinancialPlannerException("Type not found"); + throw new FinancialPlannerException(type + " Type not found"); } } diff --git a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java index 7181d9fcd0..739c652cee 100644 --- a/src/main/java/seedu/financialplanner/visualisations/Visualizer.java +++ b/src/main/java/seedu/financialplanner/visualisations/Visualizer.java @@ -30,7 +30,7 @@ public static void displayChart(String chartType, Map cashFlowBy displayBarChart(cashFlowByCat, type); break; default: - throw new FinancialPlannerException("Chart Type Not Found"); + throw new FinancialPlannerException(chartType + " Chart Type Not Found"); } } From 46f08fe1df842f6d9a3e2a66e809e49bc1061e96 Mon Sep 17 00:00:00 2001 From: ryan1604 Date: Tue, 24 Oct 2023 20:32:08 +0800 Subject: [PATCH 206/518] Fix error in storage diagram --- docs/diagrams/Storage.puml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/diagrams/Storage.puml b/docs/diagrams/Storage.puml index f363171d35..ee31f8eece 100644 --- a/docs/diagrams/Storage.puml +++ b/docs/diagrams/Storage.puml @@ -5,8 +5,8 @@ skinparam ClassBackgroundColor STORAGE_COLOR package Storage as StoragePackage { Class Storage -Class "{abstract]\nLoadData" as LoadData -Class "{abstract]\nSaveData" as SaveData +Class "{abstract}\nLoadData" as LoadData +Class "{abstract}\nSaveData" as SaveData Class CashflowList Class Budget Class Cashflow From 371a4be0a130b7a04e282c65ffeb8c393aed42d6 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Tue, 24 Oct 2023 21:01:11 +0800 Subject: [PATCH 207/518] Add Cashflow class diagram --- docs/CashflowClassDiagram.png | Bin 0 -> 27529 bytes docs/CashflowClassDiagram.puml | 28 ++++++++++++++++++++++++++++ docs/Style.puml | 5 +++++ 3 files changed, 33 insertions(+) create mode 100644 docs/CashflowClassDiagram.png create mode 100644 docs/CashflowClassDiagram.puml create mode 100644 docs/Style.puml diff --git a/docs/CashflowClassDiagram.png b/docs/CashflowClassDiagram.png new file mode 100644 index 0000000000000000000000000000000000000000..0cd604f053c926622cf81c472701e18b3fd50207 GIT binary patch literal 27529 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 literal 0 HcmV?d00001 diff --git a/docs/CashflowClassDiagram.puml b/docs/CashflowClassDiagram.puml new file mode 100644 index 0000000000..8df6112081 --- /dev/null +++ b/docs/CashflowClassDiagram.puml @@ -0,0 +1,28 @@ +@startuml +'https://plantuml.com/class-diagram +skinparam classAttributeIconSize 0 +hide empty members +!include style.puml +skinparam ClassBackgroundColor STORAGE_COLOR + +Class "{abstract]\nCashflow" as Cashflow +Class Expense extends Cashflow +Class Income extends Cashflow +Class Ui +Class CashflowList { + +addIncome(double, IncomeType, int) + +addExpense(double, ExpenseType, int) +} +Class AddCashflowCommand #FFFFFF + +enum "<>\nExpenseType" as ExpenseType +enum "<>\nIncomeType" as IncomeType + +AddCashflowCommand -left-> "1" Ui +AddCashflowCommand --> "1" CashflowList +CashflowList --> "*" Cashflow +CashflowList ..> Income +CashflowList ..> Expense + + +@enduml \ No newline at end of file diff --git a/docs/Style.puml b/docs/Style.puml new file mode 100644 index 0000000000..a08bc22c02 --- /dev/null +++ b/docs/Style.puml @@ -0,0 +1,5 @@ +!define LOGIC_COLOR #3333C4 +!define LOGIC_COLOR_T1 #7777DB +!define LOGIC_COLOR_T2 #5252CE +!define LOGIC_COLOR_T3 #1616B0 +!define LOGIC_COLOR_T4 #101086 From e9b34745a291deb58c999b29946bc642bd096279 Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Tue, 24 Oct 2023 21:02:19 +0800 Subject: [PATCH 208/518] Add Cashflow sequence diagram image --- docs/AddCashflowSequence.png | Bin 0 -> 33365 bytes docs/AddCashflowSequence.puml | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 docs/AddCashflowSequence.png diff --git a/docs/AddCashflowSequence.png b/docs/AddCashflowSequence.png new file mode 100644 index 0000000000000000000000000000000000000000..83a606b9519500aed86be5eb84424df60be2dee3 GIT binary patch literal 33365 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 AddCashflowCommand: execute() -AddCashflowCommand -> CashflowList: getInstance() AddCashflowCommand -> Ui: getInstance() +AddCashflowCommand -> CashflowList: getInstance() alt income create Income AddCashflowCommand -> Income: addIncome(amount, incomeType, recur) From ed48bd06fb1058ff32ae61558b3970bcb25cdbfa Mon Sep 17 00:00:00 2001 From: NeoMinWei <> Date: Tue, 24 Oct 2023 21:20:51 +0800 Subject: [PATCH 209/518] Update sequence --- docs/AddCashflowSequence.png | Bin 33365 -> 40300 bytes docs/AddCashflowSequence.puml | 19 +++++++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/docs/AddCashflowSequence.png b/docs/AddCashflowSequence.png index 83a606b9519500aed86be5eb84424df60be2dee3..56a6148bbbadef1d5065273f84bed87a21e2aa0a 100644 GIT binary patch literal 40300 zcmd43cQ}@R_&1R!a=Whg^?sk{Yn_*;jFd1oCLtyQfxs3O5tKt9&>ay7w0oz} z;43pp_5<)2jnzFBD;@L4_9lAzRtRA|Gd)XfD?Qz-5ACl$va)*ogoBasv5B^sm9?n} zgO0hWO=BG?0&y(IP(j7&*Vhrp;B)N4OXVfa%Ws}3olxHF7Q2c4E+N^&6Z_J$r!T8( zxbK|2mM4n5ab|x{qxUwZ#KU046vC~ZCdMXf&b)q=i^8udtlq{*6lO186ZA+7Q;aL) z;CNGnd!evW=yu+P2hjq=Iuz}F6iKZ{CJdKTd9|i+5%V{#2)Lu}zvp94Oh;FVC8qlL z3^T_|o~}Nke&q~_>f0ir=!qZ#jaR!$B))m_`AX-$t)K4v{8nw0^sB)0{)dMA1ngY_ zclnpr^0_PpwVOOGH*>!yY5O7V_7&H$dLlclzRc8yFnjvd$(A$@fo}?~p!M!b;e?tXtSrvafqQ+2)4e zx$6yI<8uVR=a3CqZeH)wTd#3yp7R*kxQ*b>Lkgu{Lh4miZBh;|#q872Ti>~UfVj?V4Q|4Sw?@RDoz|6HACiCQe3RixbYVt!lzGQ3Fw5M0&@@n(BH{r8;f4?u61kc|=mc-ka#3kD?=Hb`li#IgC_V%Ns4H%8U z=X`nTQ7H8^nUuCBy01!gE!H5jEVa+^{)2_t9a};JgP{9%7$?_v?8m3Lk2=N z2F!En)ub_Ck07EG99mJk5rO#dmJPLQ`0k5@qy8Dqa9s-Zw~R6p*Fd(V!FEs;7Z0!a z!52;yIve|$bXx+3*L&MDCR1z2Lfy61ho6ZPBBn3BVRDT(_)0_3*xhZrvVw($Wv=}t z+fcsOAjwT_m zJaYJPXXcq)DfCevcLIxz_ZVHCgZ)D3MqKczM>sFjr?40d5lKYt@3tBu$o$x{9;<&V z-HaA`&>i~eyZ=eIkNiF%L;aU=J@K##s`|ZgjE?_r{E_T&yb1Ty^2+IAx6+gyCfk$i z9oK(cVOxx1GBCSj_OLGdQHww8kOJ58>(}41bhIYhCPK;%xNGg|#po1yH$(61HoeMx z=eWf0lk~V-X^)1P=dl9uL#K-xtq2)b1-2FChqr8BD%`Tz-x(TGS6AQJI&q2Tx+dYB z%!u0*b(w>UF&Uq>tA}`->*`V>BYk{)5)Ftd(rGk4+RP1R=}=ZUsM##+2W^vb*=_cj zmld1zh>_Db+_xikYG4qOQi|ESNZNjiydtPe(Mb1u(w)lv?XE@_mwo>_vjK;b7`7}X zCfkQk<79kDnYD37W@h4bX2z1m+q6Vc_h9K2CBos?b2tw5=1|rw%4*-jeOQSz*Nfcy zN{&s)Y?Ny?<%NzR)vP|cyXB3J&PiydIQ;O3s$V#ht#w8YlAXqoU?N!y6YvsQ$N>9A0x!KG=)Dtf; zJ9|mBz5lXYdZqn*za)+?0X7j!oNaKjyunwN2PZ1dk?+VX4DKbTwzo&Tyzj}1pO0+! zR<1I)^!IolI}}&CyV`c4BB=aYG1jOzHHMaoY}1IaPi|UfNNcLD6Q0sdF4d94z2x4S z$vj4*_|eYD=~e9wsfv58Pli6Bmy|l62|InXEd%vkMm^g$AI_giRvL-hpm)#`6;WBA zjFpUtxZfB_k4v(>;F|H~3VXh2fbhX`Fr|K@Q$_Xod9q3>?!d5}93=8WDf{L5SM=h+ zAMB=+PYKsl`|{2U5@D_t+q(9Z9pvCUP2HSKf1{YqTEuM3v$nF5=s5%Y3)91@`57*r#j_Dvxg6%RNQrD8z*_^w?SFQ*M2-wcmv82LURI;!-@na&J zUd=w7ufkv!u<2H^L(<&mQoHo<1*T`f{q8gqyTeU^eXjSSHJk3&Q?>afUnsB<*3W0Z z!K#knH@$!9UBncp=J}-Zl}Km<^~P)B9kkLfujJd4WJjqAUteZ2tnylu=D954i%BLl z6=T}BF1NMTHFUebe50%_)t$_E$*1hCA+2!6)~ln4;{-TBt76EMi^6<5KsFy=yzxOEqvNJU+UZ1 zx3WIBlk`ce>}k5XV;0LS!}%Sw%Bi-lskxAkw}-!vIqGBZF_Js_E_9|-uC;x*?}+JV zUUI%I$uIUX@w;w`DMdL4ev&I;-!A*zKP*LG&#L2nklXSW#=85O_@(v;zO9*E_|#PK z-Y(kYfk*NUc6P;VdUaGe9JtE4a#1OettuyJ7`0`@M!2k}Zxh{FOzgPTaB-(!KZub)K^;IyV(*H1DugVoHjHXV-X2cO3gH z@U?OGh4obnm&GqB4%>Z~R>uYF@uUlzcPf2(HEG(1l%qW!J{);bU9ODo!XOs9Ao)s1G3JXc;_7U>hk#k?}eBTl&c8 z150;zca!A`m6bgUDgpzWW~PQ#+|AI@o`o_SH`c*kR@OT+>O0T-PIgDYgA;m3-1uGNnfXBXohB zQqa*e&t)_5($DqgCDtlw+?AinHO$D$?!=q;@|<#}E8_r)>=m}h&*+P7_WF8zLmyIc zZ&%=4B(;zG0_{y@^sa|XW>%IqS@qYus|g+X>5S?7Gg=;JHVSR#c&G0FSa6l5aauf2 zQcCSb)I9zi11C|3&1F|YJAUx&6U#U9drz8t9R;d2UyXFcZDUYIpb@BuCE{dAX|?}Pmm;aJlJz}+A$s6-^0Me<$3UB z*PC%&zP=@v@;YUr&BCB}-Dr(8L;C@4U3V5^npW9Xn7L*0{!&duH{}k}jz0Nir>Bp^c!ATP4Ub8I%u^8qh2J-LYJR1TvDQd_4FIIlN zd`shJ8R-*ifCRdvR|>$W_MT(Y%XfG__V*R-rhtRWfF5xg!>Vfu`upf zw3$rkRxrJ~s`NntDI8FwpP%RnvG5!Fy4gic*AFU1&Cv%wt_3Q5&?xeYY<+ejOJRR^ zC1W3&(4#zA@*3Nry|0~}Qm1YSk-XPi8D~_>Gin&Ln@n%1ucy3idCl?B*SF_c99BOG zJdGeMS!r}!Wob*0R2Tc0J3TW~px=;~W}(t8Pt5r;^R^?W(_CJWiFIT6i8VoUkC7lK zH>>UP=asfy-&B41GMrv8;*QQ~J#G2?Wd8pCQxj(PEheLtI@%}hCtnER42m?3pm*m` zdJyi8l162AXjce*EGi1?kXTprH({{ne;swc_E-DKuKKD-+2)FnU(UnsDfL|YZ02=%=E36y>b6t z@2W?)f3U5?&bssL-CIlkVLMF4viu7St3uay+nGw0vv#g&1O-qs%1jvC<7G7Jd~db* zLUF#Q^4^rlA^4&~X$l1q?l4!rrW32NU;HjwJCuoa1P@*}?cP~(*&6Et zoOtSh%Yz!ap>D%v#^R#Id$e5 z0zofh<AOgReBB2kp zuG6F^n_^6g2Iul^-R5Zi5#dAn7lw~F(UW7~xG`^PU?5E9>+Bv896T{PnqxI3*LjtK zf`W=_GFZ#S&s2gzqwuEF=3`1qO5h~s=H@~873JkT+mqy-4|=lo28wMH1+1*@@qp_&pOppHZCtOpC#rH6coI|Zh4)C zrmm{$MF*o=?kmf|!BR)*C?3gU7GrftF&}YpaddQaQped_Vo8+Jk^T9m>Z+=jJD_V< zS5{^Y4mzz!;^5%W$e8c%@5Al$T1_^0q$=xi#<8qTcl3R#seTZxiB{pU@Mkh; zv|1R9aCRHaHEc8O%h%J>>*?;6!PLdp|MreQWMQ%;HrppTJ39I*8(U#yWLOx{m{dxf zN2J}zX(NL3=g(ibKyke>JUpC$UQOn}xHC<5`X)0oa(Ui|h;@FbjFg0g=gGK4e!AGC zo4lNy%BhoZWZcB$CBnbW^%XGQ|9CxJ@oL}Z_S#I~`6}j(`GJ7;n}Ot@YxG3rGQA{* zttJu4#m>%Nq*dlJ5=0YoWp-wU)3i4i(=~zwb@~Do-m)=M-MV#)nmW0#P-WYV`!F8#C%;u?) zk=BpaGsnh4`l9id_KV|aXCaVW(Q40A0GsB<%p~hZG+F(}yS0&w$NBh4m;ce)D z+$(g3e_b^6ft}Fw>Vb}cPPBJT4>6!DCmfb#BLycXCnKYjTqW`4l@-{voI2I7S68j3 zbWj&~O(a~+LPlD}v?HYhj?_KhFtJu&G5AwbQW8X`3JVG~Qdvgkswt{;E+TLZe2QET zKH24o2Q!RT``{_jMzB%rEnZ_+s|%%9&yVXD9V5H@@(ke}kzFeI0k=!IiC$7sJjCbE zYnz)djE=69V=>w}I_C7-KwW`D*Voe{`$&gWR9ILT&^QMNhg=wJ+i4Q1aG<^#g^!2R zRCB^3A~>xkGi?_%mCAH#-YhOIp2Q|BEG~}XuolaYs`9?*;qES@$H&K~ub;4V7LNMQ znr$S_oylitm+SuTqO6Fz^V85eb<6bCm6V|Cbmg1&MR3}>tTeFl^YcUbjIC7F)RZFg z^`G=37k>Z#y@rN{)wap>!opCQ>jCVn`=t(w8;?g!hCY@0_((?aIOm%U^d`$EHaE+3 z^4_bUmQM(0fAaF$Xu5iV?vAIgue7*$eNz(-7S>EltcTy(-=#eZx>Y2Xy=7m%X)acL zZ2W{kU-lrCajTJ-7^eD(q~kr%a1k96M_`~Q3OD+R5W7i7ilT`%v`|B3)up^LwpPUKKS#PsV&do`dVqd!Xy*JM|O|G@c>jEto z7Z*HGL*J1~!)`LpOkz%(Q+=37|Ja7c#)LX}yjd)(aY^t*k1xGM==%`^nviKY!ZmNX zxq}(*XJ==NNlEFawzRa2IEJSxXSft@9r%wx!FN}b$4!)qT9=cT2Qg>RZWLRIeBNW= zwMLFUHWCjH&xaDK*L^3YrmrNX+S+7_n7o5l!{sN`;!SAG&>s-|wcPP-c(}MD zv$GPH=ZhvHjoXvXpO6`No+0kw=(sRgS{xU5ot1T?zvzhq>E+8)V`J7U+JYj<{bR#jDr5w|`)ar}5;VWA1g z5Oqk}z5?^IClha4Tja*x-}6?%2?+_w&(FVi@1DtpXxu=6S_lQoBhVN4N#AjMb!xc6 z<6ter)p@N$`68Xl_wV07PdA0Lw?Q+jdltwa#$x)>w2viXpFqc(fZoK!q?=w;TDnOz z;6~OuUZ*uE?`Zs;%nsD(d!+iOfS@4i?zALPcx#htR9KZf}Hkjx_G5h!X+Tr1yZ zGRjDy zX1m#+j3?QK5%P^rj+l3*g`}n$L#c#o^-_;SAP7!*;vp1-V{-KBgBTbX0y(LjM}jC3 zZt?shKM)&?$7rs*OTDyA+zg`p0}fv;@kDd;?C9=;){+zNF@G- z$I*={xsT4*hZ1vG+3jyl+`W6Z*m@@4sDsAF7w=z?z8#y+%x13Fdhz?0!NEabq?~q( z(S^tU_>Cw4o`fF6s5L)4JUlZ1|f;9QH%)tml&-B6A54(Jv3%78>6GJ}GHb zXedp3hd+o%pPY9Z-`yhT=Dxpu3Bfn;46f60}*LMd(6hlcpk18?H< zQ}m0lsf;`63=Ad!>CX-n2X`!VXOVMpmGD15IX^$2C>7y9XRtI^h zB^6i~8P1UM^w-vU_R8bX$qVkN$7g`75@L+ zy%0&%**Ui^qNw5_z!9)H*HS6`f3$rel8*hl1Qc6!pS{}qf3kleI;3q_#?gMEwYS8A z|9cx4LS|3bK!@S&FAX4`AOHV99Sn?Es)lMs50oyTm2)EVoY?cp)v2}$51fM;tpijk zW>Cre{N>Bjjwtpg3Bb++Pf$N+G3~ViY{aogUk&u8ySqD6-5&r)zzxZVb9;MxvG3oj z*aIX%d0^#$wWyGCIDzYtF58B~(p6P^GMcj;sTb#xKo7{u%F2!L_4SqWi2I93MU=NB zBqVUKvkyR@0~!sL6Zn`eHv;ik_=&8TnAalj522&$h7xkO>%)Ccn^~$4Mb10x0NpB? z0|zm&u4{4 z58_KpN)n_Z)UXfAU(g-a9NAbQ5W|@=%Jv-|Kh8uVJA&xd>7f1wjy4Jre2(7F@6Or<&!5JXe9tiV7zloOLNz@j05knklHwwN@ zJUib20q8Y+{`}d^%`G$Y<}gX(Pl@MOeV4&j>0e!3JaziCA&9X+ZLbfFD*V)=evz4W zAq%*+2;9WYgar40{d{x^a9Y6Sgo8lB{;gxJeIL4Vq+a1bYlc7VFaFcHK#=-NdO4J+ zq)-1_8~b%Fza+Q6iItA$%I4B&n^6v+w2joN?_ZwBDoEb_5U|;MFvKY_V&tt*v6>;?RHgq7HV2 zdj*`eT(&4UUvt{di;x1eKqO%s-L~N1gRk{&E}_GgwU@;a<0tx{8;qij?!Fv~OQn1+kGP!~Wc zO>*m@AT-pevazu-1;7E*6B7m?s?E>uj|FSBPJvjnw6qkHI6gPG2Wr)+K0pW0acyFS ze1zUy5hW`I9fgF11WJd_&V9iDd07Po3j@U)NLpnpk?;q}h2JdTdhZ=wFK8%%)XEu} z0|}Buy*40Qq-lzTYdI~wNKK_h!upQ6?yp4Qm^ajjGnNYO<$Qf~&0>TO*EyxJ&Rt-l zO`2Eo1)SFHY9AuN1cAhDZEaJh_ZKU00ADL9DM5=5qy}84%B0;lIXOug<>Zf|ObaC| zQUGYFwd5w?H|J$#*#rEe&S@RbC|UM8>xoBqA(;Iv0*+(7i3YJ}z}EiG0<}m>K0w+u zq21(UM+Nb z*{0;=yXF7rDDyZa}sB-T$MW9yin#n|Cg!Nymqtk&m0Z6>&_2r6k zik-=lP&|XNk%SNLD{JclnP;Z(CV=H8W!lWCX|I6pCf_jL5SAPs87Vb}q5-C`bb2XH z8w0kq4nT7| zfE^aWYOcv0>$&31_{r|kC{3zWe|ty>8*F{a7l5joRkxa4_n)lKswx3Yi+c9#*_Y=S z^7b`vh)vYVJ)Zy@QMi2N%5DSekPI*Is;)z|n~z>u(v#`Voj^=_wcKb+5s|N3D-+(J zHsF6x+MUg5f@dAv%0QD!VX**%NJvRR1D0l99Rke(tFP5K z$?+{)*}=YJ1eJw94)1Ozw3*end3n~pB;2scQ0KWmIg$-U$bftI#sTj-0*eazWsgDY zl3U;(=`S$X0&?`IqpwfB_3oI$EwgEo>y6Nd7JBoN_j!NA)&>%U*7K5gjDcz}&dJ@l=O? zUCmaVf}6%-LP94wUu(JUDFToNece<>(ldu+$tz5;atr`|(3wNpQTVMIDG|>2X>-Iz z@*(ev=BR~y%@hjlUq0j;k3)QDL)h{puuxwHx8e3tJ-kg67QxoD5CkIjo>r*UkFV#a z&Uc+-02jbt8|4BV3-0Njt)wnKc4@>C;Mnia(nG%v=70uD8Ld53M&0U7=!mZR9mciX zhVnk>q(L8jiCw(3RWYPrw!9BO9}c*9hKEi1Yrb2d8P8hek&5rYzWfGDkcau zLn6*c+E*OEWNlN^LSI2fu2Mx1!~IY{KeF_68_x)iA-P$Q9iU(NVNPo$&*(v;%mnaj5yHD5I})l+nUr9=p8=ucYqTBzi#NoaLBYW}QdCqjX5D$l%Fsv*D?pQh zF2Aub6qS97Ia(k8E7d;9Z`+54TDzI7#RVA&t3||4qpYkfW|@L+Zq_`8t#P2h zU$}Tt-X4M)?Jxb0&%C`oRxsou?&(nnz~z?^Irk$bQD3Y{=uMqS-7Tj&jsRZ8;OkNq zA5tbd@En4!H?B-H$=B(2;gtGAJwInThq8Ub0Dj0&M!D`6Ek$C>QkF;A*P7Ap^jixx zz4)bJ?quV!(IeOFRcf zy#pAWRE8$>p{ihD4#vjD>r2K^iw%+cq}SNld%k>$8GH^EOG|r%j-DR-)Tzf77BTKt zV|5qAZi3~8(s))^02*7 zbJEhj0X4~Y2JzQjtk)YVX_ijS2dy$5n^_f(cJM!_*G%f31P>^!7tKg;UcCOxNX6fV!6VOLNe+4W79VuxaFk?J|e+>vL=tcyvzqs#3p;TF(KPYWG zCGACg{NorHU2Sliv8#N@z)PTmspxr}C3eqv;Kdp94IdxBvQ9w%{W74fkG2a^sQ@>j zCJ*GBhDjYD5wMrQl&0clmUmF%py{o`ljh3bVY{ zPoT;7+6w7BUL-7K%7@^!ytJ2m4I@a%y6o5IW` z4q}rO0PoWaUk*spF*06^jD8nqkP}%vD|?w|1GDL#rKKetoHM?X&#svOfqzU(h(ORi zHE{!m>sH@oV(bn14@2Zh(AqSdXtM}na=|2#){)ep-rDUgB($FgYB8INf1$3n*03$1 z0o1&*t#P6$oofWl5X`va{qwM~e_xhIlesWUbSh6)Q*%(=yp&>#E69lQS@LjX8{5-abXxGN)P|q_Odp|KhZ)R72r1=8) z%0@vDbU;qgW_TV_L7Y_uT(?lMkYB)v{oJ77vCo1~^(H~#xB!hCT1=DP8+3#l&F{ip z=+rmZD2KUTtLADZ5f1OYb0t_k0UOO{rIuDy*-j}1K~FI76rl((FD6; zcR@K9`FX24k&m}^E%coORX5$mU#s^b;>Jualqny`6R;iCYItjGm_hO@9>dgUoQabN`7}fuZ z}Edw(25;nH_zU!JLjvl$LAzd0L?`}5n!0c0Qd#N!*)Md4M@9B#mk5>g%k zRS9e8qJ~J>6DLjpO!x0p<9ebc1STWGC*Wv7?gL*+Bq;M$Y2?f*D@>1D7-{8|u?=4Ru-UpI48`+!K4AbP^Ahkf}-yWQJBHib9)YZFq^gwqn0A zC%Z(yUs{R@?JeD}Z$YINHI@V~Aew}sEAi*bK)6R&?72ud8^+lyV9b_7$z7FzEGT7I(K+ARuX$!V19@ATgK`AYn;_vCJ*ikeYXW7y!^| z=(V!A7)=am0?#~l$8{6` zKiR!{4#2-Zefk8RAii%>GxV0_Wy{XfCy48~fe;!Ed}KDgbmdA3pi*Fi@+YZCX;;tMgrL`+glGC&d<&$ks3A><0x_5V9=9v5QU)0zN_oF zj9557zpH82htmJ`iiwV#!NDoBT_8b%*D*Ucm;Ctq=VPG>`c0AagVV(epJKrmRnG1J z?Ng20X){x5sMhTmdUs+4NWey&X{r_$w~!#pikniM&N@rYQsHd;&MqL$jL*N~IKM9;W~1JtteLoY#~R1>E8CGvZY-f|HUg9@ zK^uUgN&IYVHhr>OzGey4{W*l%=dtZT)cODCF#A_h$FYV+sEqWN*fUAW1C%_+a-IgB zQk@dDaqBd2NGlxM+j@0@pFi^{p%k6zDLl%)PLP!rp62G}0;f#jvYEYP+z){5)hl47 z{?K%GD{y#qk+e!_(N<&NSoeiS9^IF}lW#z4j;}8cXh;EVoC_rtG*z6iGtz+~!1-(# z@H<47TJ{m;ZSCCsF@PInIG&$AeOkb0NAt<%~0m3?X4{ssAz*RlT!__9%>5h zv*Qiwa+HZi;e5V1^5m7&d=$_K*x~eX*XF3Mu!Av9Y$e+SrVe+Y>dUjNCi3 zGGgDz$YP3Z^m6o1oKU_-PTBg2kk#zAVXL@7WB=PLk(rO}g)wA2TTM&|j(Se7qV~wQ z+S(XHFI;4%r_@1WvqF(}#mW4SW&<2*@j)DTxRk}#1rQHYYQiTVkc(gB1O#LXA%XYq zUBG;y+sR@VpZ=)dKuAM*;|9!G*{_UeEkmTLYJ-iUnCTgA;^PBvJ{hUMNoU@7`)Oxh7+-E`*KFvM^rTlg zL_#?m!ncG9%(xBJd$IHyAh&JU{?)IX%9!P$;PtA87g%^y{&ID`-aEy^=d(|E;!Sh? zvo8OjV<#9Exghr7H#$B8oAa}t%;4aS z*7zC_dEFBda(Cc z3RAtq?G|Vy0!7@^)YRL{%bl<-!FA(xz^|#0(*rz9?pS(~YS0e3xYSfr^14p&=e;#tKXXCN2@7>|z+BqoJdd zSlx`G`T%jzY~C}JRw8g}F0ekZ#jCHcuWC4+u<-Tmu<`o<$1xu+Nf;nP^1P5<)s+)^`!rlT{ zw9pU8Ovl}mGeruYBaGR290HLEl3~yi2nUzb#75%u7QYYYayXoD;xp*IZ{tjVL z`S{XOXRFn)7u&of4luq)OG}#qYMk9nI$Mmog|g%N?gHcL!IH0ZH%+_*E32*2{;-EP zxsYHlBwNvm!i3$`<6dHYuxY;iH^8J*M^G7dq+HnR>g#g^@+s!omNo{hgBa!iYyOQU6u;aL$F?_fDS;3iqf6OJptNG9+Ku`-}F1DJ&1*S|wqB+dn*qi;` z2!npq(z)(X+Cnj;L;B!WB`GZ}EfxY$G=#-8)N^PwjUFr5)(U|Hsryi{MIauXsFH+O zC@U-LlBDDx$Q}`W8uGEQiky5hsy1- zU{ow0#Yyf=Jk(0zYoT<%)Os?{9RgOehKV=qaFoP`k`WfIA#4^=#YoG z`946TociT49D!%2hAYutf9d|ec_92gM=nGj{=aEl^H~j_2epM72S=aq>;C_~m+$14 z+-SkJfs{_Q!tTtJ?pti5aKufV>o=~mz8Y+@jouFZY@uQ zpZ^Ou{&9IXic=}mUwjn*>vpEy0HwBujRVQ@X|JiNNlZu(BUC5@S7?#+VACURd9Gln zv98Wv;r4IJcV}yB3($SUEgc~ThmWhbnn`}KP=po}M$)x2*OJfyg8k%var|rQnGc>q zz_}re^+hNETaK@gmh@EHOK$bdiHobOuQ#ssr+|22Zq4CjMDwLzALmw&qHdQ2qluB9 zYGRivsd+L%9qp;B6LSg!|E$Nw#icyOeacgQd6n82lGFZ{lt_;wyJ0Cdn*W!6ek>TA za-i#coPi&zk5aeYy}c)oAJ^5_&#nVFaqlQ9wY`0oh($sqNNjDSk{!VO3#^Ncq0IF? zJw*_|gII^&8l(J&kyu9Hohs3T5Pd_?lLu%X=!g?6c(l~An**Bh!>v0AJ#*x zi;AiZqtz}j%Czv`4naOc0GV^`$?_<15uCb{Cr|RMck2M&;kIA?0Re`()ug+a87Q7Nj^cU3 zUY==qUKRkY`~Pba_(w@a-Joui+vT?WA)=rV=MY7=uPW8>a7gUa0jX z)~;W>E(P_it}tzPJj`6~V+Zx@7{qCEu^epDZb9po6cyD@jg}PaDpNg_D=?7z5dFV& z=34XF(S<^wZG8X@!QfApnDQE==t@(qAi?F~R!-@tj|!Gn?oE2nXAFcK38e{?l0 zy1wZ;3eTl;iu3Z#2Z$M`);Li}{nJ9nUxuu2asvo>svd#lhJo=3 z33BYLtjdY5*8nU#?5%Yr1AXa+$yUr_9bZgoc>{rwzya}Jb0s>z=1QKO{PVm9;!Z$z znCd<#4vr2E*;Liy;v_ZXse25C5+;pCJ2Hcru1s^5~TA~QCAc4mJNi}q$MC%s@xUt`ygBk9q{fiss2zpwev0TFI9**;y^K%&wH(Cewkxp3Z)Kf?>8#J=c}o%W-;l82(iaB@7}7sn3sZd3q1#i8mda*U!jx? zt=wMS*zoo8dN>9VTiK{IjX!h7l!|gMLG9N;f)94?(-rD@cU%MbJ}s7KK%GHj_!Kyc z>1wK~%tu+VG#{yh;3)+NQcLBhtlp_|jA@91QJHC)YuBF9sE)K#&r&cmchuHS!F8>! zR#a5LN7NGD9XPE2>~Htrlt_5+AI~d?VJhkX*_gt@O^7Y0E&KBBpL0nSkw_jC?8?we zjJ}av0y!+05xC~db*UuupI>oP0@Ol$ z^=D7aMFZxEI7BV{4KDDh7%6YheL_k4@Dn3`t;Bw=)0Sm0AqDqU zx86fU153&E13Ck|VB*nWNzq$0sEUJ-RyHcEIW2>M3M`=Dk3H~UoU>>3W1x&io{B&u z9IE6$MWKqTX!Lky_8&ifbZ~IEW+gyet;Z7dQ#699OVqQ?D~Bck&QHqpf(2ST-G6t= zg~3tTHORyzss2CREl*R=(_Idp(fZdi{ci(!G~BPeyu3hABTGl7mN{;GutQ>1l!{Du zbWuqJoI02wcs6#e}gQ|LGf zg&UWd^y3l}#Ys;1j9U6)Ls160W z(CcWaYvkndI9xKrgD{2&x-%vw=5=hodKzbDwDw~fA6$QebQJ1=Yp40zvXSyS=4 z2!;99_7x=7f*C|mC8Buv(sbl)WFqwa8YbgZeWk|pEd2>oaYZ4AtsWiH%nIj}2ZGz}TW*1$T4>5^bZEdmFG&*&lWrEaL! zKa9p8qERMP~_|(jKZ<9 z@u6*qAg`c6T14al&N0L<9qEqOK%_3~S(q$R9pQ4>wJXJl@(%#NJqH$0OGQQGgqV9; zB<|rTYRHQgh$v@vKu(#T@2ft*mn2&IL}x zVjqnJ@sAx%r5?t%6Y=lt?e0!bSx+`Ubsk{4diBBX=F$i`H6!E3;^HLCQ~8yC?F=}w zlD!43Al>Ez=1;MF^pA>yDGBN^qEvJrmfAj9HxDZ#Tqb8Pm%hPKk(f&8;JI69gmsO9ufR1jwquR#nb;qI{)mh$Bd|d)?^5IZGtGxci{*yCfPGEOFHm9 z_yP?USlAJYqa#Myhr<8)M*#ZaXEJlXLe1p=CUA#*@O>z;ASzUN<}WIoefZU@)ng<$ zeDqbn+Xjlnr|Dyy$EAGLG23wp+Vo#cxnuS!4ESV)mJ%KVNbs`-95VBya(*j_Vt~y^ ztNcNP^!qVSyvo9oQM7is3ysxBO$!li2+AKov80R)b1A7etGA>;-8%CRnt0SQ)s_fv zFdBkUTwo}00M|wmAks>Lx=J^SpLQrcdew-a%5?_6pXx$J2)e>~?DqgPKB(oT04aqw z4)S#Z{v_n($Ho+~H(+7ihH(x5c>H)c@4=`1wAv~TTzh$ALwM4Cy5?v>DOwL3_)$;N zXM5$Y9tnPZ?xUy8r#q?_jgDtt`MXcNK6Cg{yUX<{`y`ZZ@BC8FM>qZkYK!O3@Lf=3 zd!?|)>Vf#rvLXe)s%O z`e#vy4_?9W`LE3Ysm|QzAand9-TWc3d=Sdi{rf)daQ^PqiXVdYlyu}lLDTqXC90OH ztf?7^M6N-ub{8_qLZKmJFz?u!LL=`W>F&U6V|1-S(+APvR=>vh&qXR!@xx2fT3^3D zW0-#W)4~1@#KS;k7bCTM09nmD*dSsLRXV8pSHn;wkaTFy@J6si2#J^3EscPe%3E^p z1ndxA2)`MoOWDHDKza;fVnv08GLs5M`awqnVq(U$a%&fDj$R+(FPwS=Wm3FyZXGVz zvFOg3-nHa3)bE$8`(mXz1$3#c9fD-}G;<$7KbPl2i>O5U>Z5lBmR3AOQOw zMgc+Iw<3xSeE$PL7!k9P0`xp3WN65T-?9tGi;FU%9a`PL1D~SLjokjx#pnbe5&(3A z@Rv6ph$4gp z7xmlTWZxLmsf*w!x+rrxj@?apnHo!&kUWOl%5jF{IRCTG3)usB^h=V=z{1I^f1fR9h3X zgf8{!)hRJ?I8+d2!b5v2xA)JBG=?QMud3uPfekJA0!+5kJGill=WuZaJn#<(+-gxT zemGA;A~n@8Ft7(*FU|k`4+zv>w|@h(Ig+7wVuDt$pn542nMEY8s|$=dO0K;;OYE>T zaxdi!Hum0Rtgi~X!!00Kjdjr70KX_ie}GnCWyu(A;&CS9BFpbNIRPAm4DAv0Zf2;H z0FyrosF;z_w7fJJO4D6hu6k>r-h+M?&j<3+eT&@p*?*34Q(`JAh$goWp@zNp0d;?L zSfeqXIs`eBU@gMtJ8|-4wpbkpK&SRv017}5g@=7lT#erb6Ti+0{~bUG+zS`RMn)dS z1;8eHhN)1yPH`SGejpGYXd_>IG2WK=&td zcmqn=gNE*UfxYG>naEfw(U5nTV7teWlQJ9O_pQT@T3hW-><+v-#hiH2$LP^Tj^`I; zlJDBsX=tkaf?q1I7V1Y;?6CeoNCER2%G-t)Ye+S}Ufr6A%5hkV$`Se3*m%=41u3R0 z$TjUmd%<-O0ai%(Dx$Z|h(t+6p{GfgX*x&`r_TwdsAcF9EWsj?8_hHB!sL`&hBw(9 z8SJu&(uQE3;Ez*Hc=l0o*T96l+(SH89maZ8G;}Av;=vk_-&}{y#bMYt?I321=v!Le zW_B6zq~zJ()Zsu(zeO_xP{<7CkdC^i7GL~X>s?Ki->?rMgB_@^lk@Zbn4h@O0Kguh zQvDsC6rZL@9l0&}P|TC*_HF<10yqV42$@rWg()Ny3a!yGlb|x5hg%snyzm{=6_hX( zDmMz+tn5?5Ob5>kv`Th%c5EJ>TUU6P7{x~4gdxNrefUfJso8&BcQD$Ith zKN=%AO&Dimb+e%-61W9U_i#6Yc9G*Cl)MC6f6C5bZJNUDTPBg$tdbUZUhpoL?eF)p zzQOycd{_q`FpD+GQd?xt7J^}-REDzE8^CY3gm(xG?XR;=lQA;-zNehC{r>r>e1b&F z6mLSJe)&*~H|kNaf67$&1eQ3GdLY{)1^ZB{5B$%4oY%Xdr8NYHO;(AB(}wN@`Fg-O zQY75Z&krcstaPHGTC9VY@GM!xK91F+kK$5N36=ms;7vPJHqA6+Tx5va&fr5?_1}Z{ zVm`^JH?=4vOjv^d2`?SsW@17K+A!Q;4fLb~@|`m8VzJZH)4jdDAzLJ_8styP?F=4{ zO^!_B?iD01CGoq&L`v&0IFiEMAbP>LVP+X0;QXY-GU3#=|Esm{j?1zA|Gu(CR!I^` z+9eufG*oEsy=f1l+@+yml_-^#v?=YOAuSn6Tct@v!)Vc@l%Dr_U0L7pJipiP_1u5l zyu>xm^E{5@^Lek&oWBb^I@XS`LZvTtwSkHLnEA+xZ=OTQuwCExK>XBNCofK$OP$h- z*Rx0;8oPc@TjL+w_Zb2sT9&sh+IJ-?2u?6uj_eVOX_Cp6W}R3=9cEZNeo!gMg=J^Q zanqCQOS&X>(X5Y}`&{;>N2Jcx@-F>=Vfwj=*#iS3E*}g(mk5s4o4ZHoUe@wiur#dS z`jmm8VQ6U!O~&oD57#c+`=bzawmONWcuBka2ne8t;g;&{ZARrarKE$W_Uze` zPKCWGyeP4XAl^)m3J*utg+3+5MuivB0LC=S)U-4}h3)*dCp&U39iugz#aSC07`S!m z)(qF`YeKAwO>#IB9nhw-GrlmzHSJa|;*I*~g5jHrdLmqC4nEq`#sjzUXZO ziIT?>Xc;G3l33KMxrfPEinFDZF?dg7qiVOX?i$&yy* znp~&*WZ42}E7i*QV2J5hgoHG{@hP7mYcIc>wu!;C=LQyM{N$-qU(mxhYk$ytM*vS$ zUzRO-C@10z3Fl!83-+rwwj*@`a(x))LO$D57c!p4r%ob$ySdjZ^wc_Zwp8?cAVG$l zXe2H!4o7?1gJ)d5Hnrr-ysSf%bZsTa+K)bgpyc+IceAU$Y1UZlApD;ERu>1ikdAl< zFB@NYgjGmpaIQz_K}yQD-ftiN{ig@MMM}{u+VY5`vz+{L$_8Gpa+NJN=E24-2+zr0 zw+9kg0$bbKi>86KXG!HvS`OW!f4CHz$~bTP2~^Mj&+ZnAh8M~7zO+PTk87mRNwT)@ zR@ez-MMLXl4eF<=)(_a)`@iw4^jfvHoQ|r!oytP_%guVCMo>hU@g?&#W zC`SWsmR^+9$hklsiB#y^bXyrBUXndt=2;6>-RgysitUN9&MiWc?PqCL=e?R)sSew$ zbRU-Sl^dYiH0~r<$JjGG=lsNK-%TuK;(eA)l`l?Cx@h3Xfi&Ato`ja=qlNWB2s_3f6c<|MRVefoDSLm;}J0A*9n*yjg90sv`B z3RT1M9uk-CO_3_zg_E1B8M$ba_{=OVb0-Szd%UMh_gzFAsr6VEZRAqP%nI`A$*V+s z5Q>Y$qT-G(1pf2a&tH{)+WKp?|9bMtt9S9595)ivMx|{HtC{@YR$gS9BlbBiufW#} z-&X$d{7^Q9`Q1rEoY+#E)yeNpcKRV_io+{(e%pIX#ezndX(O>Ayj0iKg$DOobN4a(i=|{WX?Zox*Cbo_t_{<%J9us0C)!3-01IF*LzEp(oWg)-m#tjC?jBDucx%cna zH`M=t)R*MWj2r+2DUq$T@XA+JSF5!l>8OXYaoWr-tB5M^z-EdKTCwCLoHD5uP8yVV z#~G2@mF>e!)0}@e=Im%yn~|F$UK1r>g%jrx>?o1d-wP5Fq+jR7RMyowo<0p)RIBW0 zj9x7Ek*$G&X}gH;Laj286%iRB0;zDOjmrLt6*(cPORI0v-QYaK%`?>J%Mo(}%H<+0 z<@-I#1MmVG+OnK@ZjobQ6p9OQ4asGOw*UHyartgYe}Tg9q_%b&_6*PxKAK^mYL6T# zE-v=*_9oa$r7*pT3g28fZ?g3B71<(sN}}W0;JXfpaamCUWbw$ zU06Rfaa5`vR&=`o9=kFfVc_MZK-BdF@2|U9#gSK&;%{ zF@WnG#q^E)d`bN=#A2QZ`FW#oS+&x2f+8YxH8iA|+hK4ES@|`XbFCwU)9d(cmLKh?Uj!p%+yM47(>w*r3wz4faH?rx~rthh9EH8l@e;|gs=1Z2XGEW_f%p`BZ- z8uP9T@ekBFn|5ro66Fdyi{OVm7N|{5J&zF;$JqhYOr`qh)!Q^lfzi>?it#?w1la$y zQ6H^)NUx6g$p=&HPk9TKds^;PG9>XmMfVCWIy?)ig6Qat#9D8jzt%q7OHf3;| zPnXTjeumR3U7$hlIb%W4epdm_?gUYJw;`O8*WdZ9>7T;>8P408tCvg*+Y#c=8dk3- zq~RkaoyWr!hF27lmAI`5Qs+GuO_%lQN)BvaknASH_$X-k&pP%+v5(lxE~Iu_7CKC^mC2 zPWCui`{W7hu3f6SrtB{`)=C&YZd`Uv;b%>2C3>D11o1Jq9-aik3d?1WIMtGHgUyBXX)nN z31ZQ;X_062%`Gb0hyS*1d;H`{&!r7Ufdiq-y(Wk>&l3jjUmh)W5cG~LV4y#rG6uLy z=Idvl6xX-}`Os#CrgohwKcR|a11S1*XJJ2<4u%WE{{D?MQ6Z#(fHBa(o$W=*U#@CCnt;5`mge=rGm!=rBNv! zDmwf%I8jTKtsZ4q^!Cx!bT5At_@=ld>K*R4xjBNyC!0U;3I`RFsYBs+kXygpgcdZQw_0O>Y26A?99 zGz8!j*j4+uAD%xXy@>z#0BPVQ}aYdT8`s(*xg~7 zhhzja)MyttO~rIe|5wSvu7392>8Yu=f|6V~6mD$Q#ucgSa2h67ckQbUX4rKgki}xbur)(schbz6x(kjUSXI=_$zARN z+iVDH^rX1w8_=7ou_$PRKHs%>!+8>Cj?zfe)-?2LoX}yO=hY63w*~rc-~_zqh|V;$ zj6v?I6-1|eJ3zPY3sPToCZFxeY$2puO_kaD8F{>jeV7cp?%2}2{;=PE6*X#qLm z38gXb?Xcn*ddj&r#u%s*m{FB5{gCeIdxlLn!i$IA53bl}fRG~4oo;2{=K?H1hJ<^r zM8$ICA<(i;3nLGIS%*)KvrFl%=$L7Uf z-kOzh-F`J_Y+u9-n-5pqB-)fgac8xn(;rqn)zwT~PUqT7GdDeug|LqnK3;n`;d>HK zx4lrPxSe##I}bHyHRILE^h2-e4S9NwXW1Jgp_c}sW6rNXa!^f=nBt&*KQlLjI+;Xt zv`M6CmqoW-t9AFNsi`$scOf=EI zN=YuS)g+xAc;bG5X?jC|8n#ScYyLWQfS$x1h4y~=vSlW^FWTDnaB?O?`-U$B{f6rW zN`Dngl$VPivNDif^xp44-Gc@OPBz5}Q6=(wirG{3bFpZfQabWix9)%X{Q2|1Kw3%4 z@;H682U^`^8Ax_K)Yb44FmyF9YT)}_)h_VLcuS=3iEO3303MH{MDeRmI&hvUd!5oY z5=nH;&kOiP_%w;<-S!0yNl+Z~8UJu{7&YEhF);hJ3yP;}uB-m-JD-l{lX)+2Qv!Z?BL?sQ-6G7T2trS0Dy~@ zNb0Y@j%zaPgwHYiu#r>0Y@&^kw~um%jh3`$>QF_?_PI@$5>2$7s>i5x^Cp zw4o|ryAi&ORg_-8`3;!5W=(d)0w8Tb$#CEc@8-ji>l^}-jsin@NiNJu4OzXty;Iag zI#1Ch!}aUeKP@j$wpHx!EF7!hFH6sKbpBb)pD%?HXlNdn(MBta@QOVn1RI#D->!_k z3hp)SOoJ4UC)?lojvZO(c-%cWGIHSkdo2TlbdQCD)Q}zd{JQZx1j0tH)iX0fi3cQ& zH=+Mr4twI!>geif#)w#vI)is`b{vCZpkGh^M&Z^Sw(m7J!i52^QA@swwoKG2nE@NS zwZtu^BR$(ehOBzZb#-(YC?Q_EBVuBsuF_LcQ9<5scANlv z|M{o_`8oCF(cAhqB|xjdv$(jqof&#L0m$8a0>(i|Y+OIa`^?PFVuZ|zTRzC20DR01 z>t)H*`^fa`3Q;0KiaU%Sl%Tr9mW?z-z&xwnv?D~YW1tT<)G{h{b%fwUH=C;k5pBOhd^V+!K6*`T3dE0qfWVTK3=%0L;6YkiTIe`$-@Xl*2op0i zf`(c5IN958gy<0Woscca$5*GOa?8mJTGWcTjBcOs9C|67+B+$6^-c|IoqQisUGkuO zPD}$X0&O7Io;~5!aMJ-q;^pSPRS8y2!llrmdwgOd(M2~xlH2^Ctf{@8l`x8vBYq6_ zAgchrG*vce85jNI`vy6b@v74^W6#-E967wgQ8IEj4s_~1N>c89@mpD6M*!LonhRRpgN?Vtv$DGOe?GglOevaM@c(wz zps_f%k{yCdZsZ{Bapsb8BvF8eh_%>Zj7Reu=+0z`cLB#1_3?2d zZ6Lb>ecT{F@9#31=o&~IXKIF6kR3q{S!%OaHy0ZR{pAnOW0~pc*`LEpSvpd&Da5bC z4AoSzNUOK}lm_PI5Y?|qlOzJTvLXA5Q|3^sVr&%>ta9oP!T)YZWw2i(2pEe9qB0b!umwWPI3b z-rmW;$VmB6sG#gJQJx@tT3bs?4E8^ya;-``i^7}J5bNqi$$Ji^;clHxJ6cfe=A+oP zQp65EU+Y#{sX9H54%Zw8ryMXgvPXT|)aN?O@CzduC8aRi!9xR9|47iY)t9=h{->XA z`sCc?y2zP{wiWKv2R1T`$0}mInAhI0)XF@|u`}Bp5}+7Yo6fE|5ARYp+p^BLaCz<^VrLIe+-7AIGSH4 zTcXHQT)AZ-n_+5#h21F3XYt?UVU}Ldk?ZV4`wv=E4JBFGM!6`Ym74W|QsDY*&zO}> zFBdgBD?i#{8QVCBCHCz_?2ql998I@^8i|JBq><4UO|>vhEjh+Wu8nN<;5!=z>Gb;; z-PVr!zS?<1CW?;fw8N_0HvY0G^NC!GQpx@HLoWl8XTr;B@ASfAF5a%MEY=ZQFTl*) z)sbrq^DB_$Do)y*g2I^ zvH;^+&VGB>Iydt?9}A*x{)**gR?yF%EBta%=%4o62{dPMp+U5#KxisjARHE;%HhKZ>(kcINDh02bR*zRYCeQXPS`?K!PXx1 z2*J=qs&eh#eGi}yQLyKvre0}{a*f=1^n7OpuCHETKX|?pjgCb54WJEBvJ(=roX_|T zn}3~#qYO&Ap8kG4EiLx8_7&ZiYo)vG625fJmBzHhirDYn);)sWPnE`8?8=2vUOHy| z{L#Iq;w~!!+sJqO8lxfN&?}Ok;9T7=CG})_+(j)05)I7EQQ%g0NL*Yx`SRE#GLNvO zx#PIu|9bKka}Snl2GJ35kUnl;Q|eo)kC_chN~_$LsWu#?Au9V_eP}YTvpgb(9z0GC z4pzt4?8uss@kTlh^3{Xhah=5#1HdU8iZo6L7SkWWNEs<)EqMu=Au#W1g8ioHVv>kAFo*0Zj<<)m~zYGJQOpB(I z?5%2V-|+ES_N`k@$6tvhRnQ&gVr{BH^S?DNV}utFwy;_!eYCjeTE*#a-*)JS)p}T0 zNn=H$ed;0CjaFORMRWW6`=``+f=eeqi%W_dt2*D<&8MWBB^MRUQ6_Wz z+GZZaV{xoM9Iz!eYNl(Dt!tNXkjN)&E%fyC_3sm9X=fSA0!5DdlX;!Eb1I^V8Jma- zk^7bN`v}W+cj*_LLx5vmwCL+vH&&u#x{K)cj)GNjCwdX5j$jF(J19w_r$rab(|+)! z4M%;mWy_nPsSinN9)V>?b!|dKQtEJ!N?t+^`a5VTtQvOqyiwp#(%NfLD_CD&eznI1u=~|LclI&>Be5EgAg4jHQdPBg=DDYlS((WWPx}{N5^KdvF|4Y~ z)A(C|+DQb4R+d$WdCW-5`SX_wop~O^oRjllDr?TwIObBMh`d~NlEPGh|E2;IT?glW zTwr!7A7Gvnu_Ttzx}@dvXgC+?njyK~Pj;i*hjB3OE3vQmpLDU|sDI=CQ&yE4yZq-C#djAP!s)5r-9OOA?Wjd-xEI z*+fv#LaT%6wd*(zwWtBQY>21jyJ{mT^#o^yJu~L;WO^_D|yGR)C>N`=)jCjjXc-h|z31?@|`Z zDT~f_4VkMUs9FgIN-y+$0r~Yv607H1Lv_;Gu8kDldR*c^cC!!F7@VSi-Y%*?+g7~0 zqh#f^xBtpI-~Q_dUwBEx>yw$M^NBkL_p!{g-1u0lw@$Y&{{4x`H=9cS=3&y6qx1WT2>gO`D^D5t3P0ERz6XEEQ?mL-9Nrm*pEzt>Y( zxqMS4Vho8p_D1$M1&#w+nx<|DguDwcBpi_j$j_2Vi;j)WLLrhti|E(+wl@L=uskn# zse=2;|K$?rZ*dZ&{eZ=$Nn`WO`CypZ4qG~vpWuX=t=h%nb_ z_2C3!loNz)8E3U+|NS+Y{GH;32SJ>oF)4tk5>O+S;1h0ngah8b4Wbqyxlj%BbI517 z{_pzYDU_g!^4iixS=;?Fsws5erWwchVwL&OW* z2cfX^MMXzHj}?E;u9@d_@y}kB0)bd<(0lUW*wZVuwY9fyZKKv9b3|u8b8c3foQ6FU zc2)Uver)(=Re^suwk4dbF^G0Tj}3~^bfQ@bTRDPo{_Jg$gRY_$h47nGQ1c+dyt5r8 zSbO$SYyh7TFu`|;J1sR8n-Qi(*@Ic`pM(1SI*X!%Tb#7~z!Xpsm5A$Xd|>BatULLn zqr0~p`(QDGcD0CcH(X5ejPmg`35OaOb1FiFt*=Y&j?`#;xt3BEQ`yY&l1L2mAlD{xH-@~~vx z!)3%)u5g4odu_&1Pok}pM_ada@#4F0pPmnyDHbNs=Wu7`mI$PosBZ#ug%Yb!Euw$; zP3bH6dw{+GWb@Z++IR7Fctk{sjY5hqn^INa42~;ndg^>U!nYVRwk*ro#MTUqU449p z5UD1Pc*|RCR~l9$h!$2UQ^|pf+)yWE9_&kc5! z#lE>IWWBD=NL7`^+U~wthzKO4mDNI7qg#?}xI&Uru4{QK#$YrNJ69z4tIJP`^BDVB z+!3fkLZl#1MAjgHAaI7dTWw$5p;1(mQIwazEyF>q%Kz3Oi8ut{5a6MF;>T!JvJ4+m$801ykz%oElrbrsHFSq~(b9s|khlApu$Rav&ae(0R;gR^^E zYUYGXTfKQU9LX)PX}MB#<=VA7a$zED{)uL0W)1Y%_{|Xo03kj8D$-5%yx9@)i^`sGw zKYP>6)0_Mg4EFNCQP@+tc8o;YBp@q&P@`G>*9knhe^4e$;1_~Ua(?)r@!8RiGwnel zPbt_rrRbuP|Lf04r>tb6j!~LT5=jL9)w`53|GU@8{?=@ z5t5uPmUI0(>`jPSvNimlp!J9N3fj`e6Pvbe{o@7x0KKg?uzSxU91`(ps{jtv)Tozn zEL)dUTYhaP^MAM&&h1bz&rKGTISzMrfM(dav%$$;U9wwa=bN?pWG-ky^Ed3Z3Qs8Y z>IU9Krb(P4e$3(z;2H}NzHs5fao01!2fIV&c@Q{=9xjxLays~AM_2Po&=;NqQPqxX z_ONYNYMfsaWa-R9HOvG&%JssinP-s}xh}$j&n`pf3mprQQ~<=nf@>!fAnXHgw{ZO4 z6Ih|Bokdh>or5K!4J0i~Db+h!Zb@9)D`#tRS9xe}Hv848{1nT@T@q-3g`)qx_T~Rp zzX`7@R-Ajkrt;Ul`RmdW)m;uNZJvwcBPE03b{YJ6&v?;_$$|Ts1rgY zLt_mMI$GMXXY9h?p|^YgJl0r6CC;Pg0b{rreCI%pT8iUNgS7G@s!-K|w7X>CBQ<#; zt9M*E-;b8>Wq0Hg-~2OV=r;n2q|euS183ZR+}r8F^0?L>`@ zw^gF=DsiuwuAD<(~j&0+)@B^6A z!m!8Ld$v;=$mxkUZl5tH4s#QU(xp5CNNro<%*@$ViF$lT*r2Li&AU7A9p6;yh{*lj zvbw?SM9Km;QWw-*pm&1QdM57Rh2#UEZ>mNU<-K3sLWCqiX!Q}h^bJR%ek9*)No z=DNeWV_9Dz2u%Yg1y?Hh(uHF7ft0yi!SDB3{4kdU!G!WHJo!b72(^TeA6YGtnVcLq z4O+Efd)@W0u=nrYu~_1bp-sWW8o!B+n>M{dYcW~;0d)jSH$w72;P5NLQ}_MzQ6lu8 z#?xocBz1CSRpCfZ-qYV&u9nyTl?;5Q4$_b$3hry0%9CXpq;C%dAuZ%+L_i5@O9gEf zOvD2_2Fm0j#z@X0Ym0NO8hHF64FBu3OVW%D3VH`L3W;XiNHfeo{tA=(F1_BD7>DT5 z*2*{_l7j;=pwWofCnSlWlPwtT+sNzS9QDzo7^j$fi%bJnM(3V7I>nTrN-~BSm`G9m|Q!){Rs1??B8Afseg!~aslOB7THGxAe^J@u$V5 z9Q7B)!DTPSHT}7N{B!U@%0>jL*axebye?OSs+%OiNkLA&qq&O>Fig=#{Ibne3JXoF zoJLs8?DGlSr zhUFv`%Zt*Ce_%Tm96@JmD3XU|@wEMZU>i-iRu(HU82j6v`|C;Ng!=&r=DTO-M5sa( z@F?y7w*$Jxd0odiL=2oQ&O+z;{yc#Ge_<{EuTvV3)SnR2ud-nc<)Z(3km)FpSCObM z3|W}ja3`}R^FvPZ-M!HEJdfU=lqsB?nOR>|MIZqlbF*h?>v$c|#yEzya2YM5GCCR==JgF*h0#bbic&D6{VZ^7B!^`STl5!GS^z ze;#gbgto@GPj+C^F=Qmiahl?w`qslF{PCxZAv6K}S{`P~!nKdo9LXdt!K-xhVh7t} zvk&Vd1UYzk9UAL-aJ6gPv10#)vA1Pp*0FM#6eF#G1Av;IhBpW_LV%0Z80=Uk|l~6Tr zvoV2SV?Sah@OEAwO*b%1dS9d*U1f*;8S|lDh3)*ea@k=P$^>?$sE_a7*<)DDO~fS@ z&a^@!09BFYT9?%Su>#h1O`{R86ulwQ1v=hUS@0u@?mND0Z&?uXfqAvIQV^8I0c3OR2gl$dX_I=)@84g`?fr0}~a z3-Q3f6zsqgvM{+Ne)|a%HmSFF6k+eQI7ub3xuJ+rpS*k*laK!d$8}t{TL@{wm5`e^ zQ&Y7SZ4!4;D~t{`A#nzhrz_H)rCE4B!D^SejIrxeyM-ta>k|*2Xz{bDM@yNrT@R;? zz@~2PzGU^5bh~-GE9O5$iLgn1xut`W@~+9F1zNZB{q=l<&7a|wa;Fgjf0=!3bTk