diff --git a/build.gradle b/build.gradle index 87ff2528c39..c94805dc2ec 100644 --- a/build.gradle +++ b/build.gradle @@ -71,7 +71,7 @@ dependencies { } shadowJar { - archiveName = 'PalPay-v1.4-alpha.jar' + archiveName = 'PalPay-v1.4.jar' destinationDir = file("${buildDir}/jar/") } diff --git a/docs/AboutUs.adoc b/docs/AboutUs.adoc index 48e44be6ac8..d057ea9c6de 100644 --- a/docs/AboutUs.adoc +++ b/docs/AboutUs.adoc @@ -13,7 +13,7 @@ We are a team based in the http://www.comp.nus.edu.sg[School of Computing, Natio === Bertrand Tan image::berttwm.png[width="150",align="left"] -{empty} [https://github.com/berttwm[github]] [<>] +{empty} [https://github.com/berttwm[github]] [<>] Role: UI + Responsibilities: SceneBuilder @@ -23,7 +23,7 @@ Responsibilities: SceneBuilder === Ding Yu Chen image::dingyuchen.png[width="150",align="left"] -{empty}[http://github.com/dingyuchen[github]] [<>] +{empty}[http://github.com/dingyuchen[github]] [<>] Role: Tester + Responsibilities: Testing @@ -43,7 +43,7 @@ Responsibilities: Ensuring proper coding standards === Park Ye Won image::yewon0303.png[width="150",align="left"] -{empty}[http://github.com/yewon0303[github]] [<>] +{empty}[http://github.com/yewon0303[github]] [<>] Role: Deliverables and Deadlines + Responsibilities: Ensure project deliverables are done on time and in the right format @@ -53,7 +53,7 @@ Responsibilities: Ensure project deliverables are done on time and in the right === Wallace Lim image::wallacelim97.png[width="150",align="left"] -{empty}[http://github.com/wallacelim97[github]] [<>] +{empty}[http://github.com/wallacelim97[github]] [<>] Role: Team Lead + Responsibilities: Overall project coordination diff --git a/docs/DeveloperGuide.adoc b/docs/DeveloperGuide.adoc index 38908a8bad4..cafb98280ff 100644 --- a/docs/DeveloperGuide.adoc +++ b/docs/DeveloperGuide.adoc @@ -7,6 +7,7 @@ :imagesDir: images :stylesDir: stylesheets :xrefstyle: full +:experimental: ifdef::env-github[] :tip-caption: :bulb: :note-caption: :information_source: @@ -39,6 +40,11 @@ In particular, the intended audience of this document will be the students takin _PalPay_ is a CLI application targeted for users who have poor financial management skills. The users should also prefer typing over mouse inputs. It allows the users to keep track of daily financial transactions, as well as set a budget for a time duration to achieve long-term financial success. Additionally, users can keep a ledger of lending and borrowing of money with others so that the users can keep track of the flow of their money. +Below is the Graphical User Interface (GUI) of PalPay: + +.PalPay's GUI +image::dg_gui_example.png[] + == Setting up Refer to the guide <>. @@ -74,7 +80,7 @@ The rest of the App consists of four components. Each of the four components -* Defines its _API_ in an `interface` with the same name as the Component. +* Defines its <> in an `interface` with the same name as the Component. * Exposes its functionality using a `{Component Name}Manager` class. For example, the `Logic` component (see the class diagram given below) defines it's API in the `Logic.java` interface and exposes its functionality using the `LogicManager.java` class. @@ -85,9 +91,9 @@ image::LogicClassDiagram.png[] [discrete] ==== How the architecture components interact with each other -The _Sequence Diagram_ below shows how the components interact with each other for the scenario where the user issues the command `delete 1`. +The *_Sequence Diagram_* below shows how the components interact with each other for the scenario where the user issues the command `delete 1`. -.Component interactions for `delete t1` command +.Component Interactions for `delete t1` Command image::ArchitectureSequenceDiagram.png[] The sections below give more details of each component. @@ -143,23 +149,15 @@ image::ModelClassDiagram.png[] *API* : link:{repoURL}/src/main/java/seedu/address/model/Model.java[`Model.java`] -// TODO: check accuracy? The `Model`, * stores a `UserPref` object that represents the user's preferences. -* stores the Bank Account data. -* exposes an unmodifiable `ObservableList` and `ObservableList` -that can be 'observed' e.g. the UI can be bound to this list so that the UI automatically updates when the data in the list change due to user command. +* stores the User State data. +* exposes an unmodifiable `ObservableList`, `ObservableList`, `ObservableList` and `ObservableList` +that can be 'observed'. + +For example, the UI can be bound to these lists so that the UI automatically updates when the data in the lists change due to user commands. * does not depend on any of the other three components. -//[NOTE] -//As a more OOP model, we can store a `Tag` list in `Address Book`, which `Person` can reference. -//This would allow `Address Book` to only require one `Tag` object per unique `Tag`, instead of each `Person` needing their own `Tag` object. -//An example of how such a model may look like is given below. + -//+ -//image:BetterModelClassDiagram.png[] - -//TODO: update [[Design-Storage]] === Storage Component @@ -183,6 +181,8 @@ Classes used by multiple components are in the `seedu.addressbook.commons` packa This section describes some noteworthy details on how certain features are implemented. // tag::transaction[] +// tag::transaction1[] + === Transaction: `in` / `out` The `Transaction` abstract class allows user to input income and expense statements. Both `in` and `out` transactions requires the mandatory `Amount`, `Description` and `Date` fields to be appended. There is an optional `Category` field which can accept one or more input depending on the user specifications. @@ -194,10 +194,32 @@ The `in` transactions will increase the `BankAccount` balance amount whilst the ==== Current Implementation +// end::transaction1[] + +Given below is an example usage of how `in` behaves at each step. `out` command follows a similar logic flow. + +**Step 1**. The user executes `in $/200 n/coke d/10102019` to input a new income of $100 on 10th November 2019 under the *category* GENERAL. + +**Step 2**. Upon executing the command, `LogicManager` uses `MainParser#parse` to parse this input from the user. + +**Step 3**. `MainParser` determines which command is being executed and creates `InCommandParser` to further parse the input. + +**Step 4**. `InCommandParser` parses the argument and checks the validity of arguments. If it is invalid, an exception is thrown. +Else, it returns a `InCommand`. + +**Step 5**. `LogicManager` uses `InCommand#execute()` to add a new `InTransaction`. + +**Step 6**. `BankAccount` then calls `InTransaction#handleBalance()` to increase its balance amount by $200. + +**Step 7**. `InCommand` uses `Model#commitUserState()` to save the latest state of the application. It then +returns a `CommandResult` to the `LogicManager` and the result will be displayed to the user. + +// tag::transaction2[] + The sequence diagram below illustrates how PalPay handles the command input `in $/200 n/coke d/10102019`. The arguments are parsed into the logic component where the subsequent model objects are created. -.Sequence diagram for executing an `InCommand` -image::InSequenceDiagram.png[] +.Sequence Diagram for Executing an `InCommand` +image::InSequenceDiagram.png[pdfwidth=70%] The `in` and `out` transaction follows the same logic flow after they are parsed. @@ -211,7 +233,7 @@ Given that the `BankAccount` balance initially starts with 0 dollars. * The Activity Diagram shown below will provide a visual representation of the two routes a Transaction object can take. .Activity Diagram for In and Out Transactions -image::InActivityDiagram.png[] +image::InActivityDiagram.png[pdfwidth=70%] ==== Design Considerations @@ -243,17 +265,17 @@ that deal with `Ledger` implements the `LedgerOperation` interface. + ** Only `Out` Transactions can affect `Budget`. ** The activity diagram below shows how and when a `Transaction` object affects `Budget`. -.Activity diagram for Out Transaction affecting Budget -image::OutbudgetActivityDiagram.png[] - +.Activity Diagram for Out Transaction Affecting Budget +image::OutbudgetActivityDiagram.png[pdfwidth=70%] +// end::transaction2[] // end::transaction[] // tag::set[] === Set Budget Feature: `set` The `Budget` class allows the user to set a budget for a given time period for a category, if specified. -The user is allowed to set multiple budgets, but duplicate budgets (budgets with the same identity in terms of *amount*, *date* and *tag*) are not allowed. +The user is allowed to set multiple budgets, but duplicate budgets (budgets with the same identity in terms of *amount*, *date* and *category*) are not allowed. Upon setting the budget, making `OutTransaction` will deduct the amount from relevant budgets in the list. The detailed implementation of the process of updating the budget is explained further below in <>. @@ -268,14 +290,14 @@ A `Budget` stores an *initial amount*, *amount* (the current amount), *deadline* There is a need for a `Budget` to store both *initial amount* and *amount* as it allows for percentage of budget remaining to be calculated. + Shown below is the class diagram of `Budget` class: -.Class diagram of Budget class +.Class Diagram of Budget class image::BudgetClassDiagram.png[] Displaying the percentage remaining improves the user experience greatly as our target user is a `visual person who wants to see how much budget he has left in each category so as to cut down on spending as necessary` -as specified in <>. Hence, taking a quick glance at the `Budget card` allows the user to -determine how much of budget he has left, as well as be alarmed by the red font colour to spend less if he has overspent beyond the budget set. + +as specified in the <>. Hence, taking a quick glance at the `Budget card` allows the user to +determine how much of budget he has left, as well as be alarmed by the red font color to spend less if he has overspent beyond the budget set. + A snippet of the code which calculates the percentage of budget left is shown below: @@ -284,30 +306,61 @@ public String displayPercentage() { double percentage = this.amount.divideAmount(this.initialAmount) * 100; if (percentage < 0.00) { percentage = 0.0; // should not display a negative percentage + } else if (percentage > 100.00) { + percentage = 100.0; // should not display a percentage greater than 100% } return String.format("%.2f%% remaining", percentage); } ``` -Moreover, as our user is a visual person, PalPay makes use of colour to display different messages. +Moreover, as our user is a visual person, PalPay makes use of color to display different messages. For instance, budget is displayed in red to alert the user that he has overspent beyond the set budget. + Shown below is an example of an overspent budget: -.Example of an overspent budget +.Example of an Overspent Budget image::overspentBudget.png[] When setting a new `Budget`, existence of a duplicate budget is checked through a sequence of checks. The activity diagram below shows the activity diagram of setting a new budget: -.Activity Diagram of successfully setting a new Budget + +[[Duplicate-budget-check]] +.Activity Diagram of Setting a New Budget Successfully image::SetBudgetSimpleActivityDiagram.png[] As shown, a new budget cannot have the same *initalAmount*, *deadline* and *categories* as any other existing budget in budget list. Allowing existence of duplicate budgets will crowd the interface of `Budget` tab, which prevents the user from getting a quick overview of his budget status. Hence, a duplicate check is essential -in providing a pleasing user experience. + +in providing a pleasing user exp. + + +==== Example of Usage + +Given below is an example usage of how `set` behaves at each step. + +**Step 1**. The user executes `set $/100 d/31122019 c/shopping` to set a new budget of $100 until 31st December 2019 under the *category* shopping. + +.User Inputs `set $/100 d/31122019 c/shopping` +image::set_dg_1.png[] + +**Step 2**. Upon executing the command, `LogicManager` uses `MainParser#parse` to parse the input from the user. + +**Step 3**. `MainParser` determines which command is being executed and creates `SetCommandParser` to further parse the input. + +**Step 4**. `SetCommandParser` parses the argument and checks if it is valid. If it is invalid, an exception is thrown. +Else, it returns a `SetCommand`. + +**Step 5**. `LogicManager` uses `SetCommand#execute()` to add a new budget. + +`SetCommand` uses `ModelManager#has(Budget)` to check if it is a duplicate of an existing budget +in the `UniqueBudgetList` as shown above in <>. + +**Step 6**. `SetCommand` uses `Model#commitUserState()` to save the latest state of the application. It then +returns a `CommandResult` to the `LogicManager` and the result will be displayed to the user at the end. + +.New Budget Successfully Created +image::set_dg_2.png[] + ==== Design Considerations @@ -327,25 +380,51 @@ This feature allows the user to pay for a certain item or make a transaction on Refer to the <> for usage details. ==== Current Implementation - The `split` command is an abstraction of `LendMoney` class. + Given a list of *shares* and *people*, each person is assigned an *amount* based on the corresponding positional share and the total amount given to `split` command. + A `LendMoney` instance is created for each person and executed. -.Class diagram for operations that deal with Ledger -image::LedgerOperationDiagram.png[] -.Activity diagram for creating a `Split` object -image::SplitBehaviour.png[] +Below shows how a typical command from the user is executed by the program. + +.Sequence Diagram for Executing a `SplitCommand` +image::Split.png[] + +**Step 1**: User enters `split $/200 n/a n/b n/c a/desc` into the command line to split *$200* among *a*, *b* and *c*. + +**Step 2**: Upon executing the command, `LogicManager` uses `MainParser#parse()` to parse the input from the user. + +**Step 3**: `MainParser` determines that user input is an instance of a `SplitCommand` and creates a `SplitCommandParser` +to further parse the input. + +**Step 4**: `SplitCommandParser` parses the command and checks if fields like amount and names are valid. +If all fields are valid, it returns a `SplitCommand`. Else, an error is thrown to the result box and the execution +terminates. + +**Step 5**: `LogicManager` uses `SplitCommand#execute()` to update the balances of `Ledger` and people involved in the +transaction. + +**Step 6**: `SplitCommand#execute()` calls `Model#add()` to add the user input into the user history. +Within the function call, the actual update of balances is handled in `Ledger#handleOperation()`. + +**Step 7**: `SplitCommand` calls `Model#commitUserState()` after executing to save the latest state of the application. + +**Step 8**: A `CommandResult` is then returned to the `LogicManager` which is then displayed to the user. + + +.Activity Diagram for Creating a `Split` Object +image::SplitBehaviour.png[pdfwidth=60%] ==== Design Considerations +Below shows how the classes involved with `Ledger` interact with each other. + +.Class Diagram for Operations that Deal with Ledger +image::LedgerOperationDiagram.png[pdfwidth=60%] + Current implementation of `Split` class encourages code reuse by abstracting the delegating the task of rebalancing to another class. + However, this introduces coupling as the behavior of `Split` is now inexplicably tied to `LendMoney`. -.Sequence diagram for executing a `SplitCommand` -image::Split.png[] - // end::split[] //tag::receive[] @@ -358,10 +437,37 @@ The balance in the `Ledger` and the balance of the sender is updated accordingly The `receive` command creates `ReceiveMoney` class that handles the transfer of fund from another person to the user. +How `receive` relates to the rest of the `Ledger` classes can be inferred from the +class diagram above. + In the `handleBalance` method of `ReceiveMoney`, it will find the correct person in the `Ledger` by name, or create a new `Person` with given *name* if it is not already in the `Ledger`. + Balance of the user and the sender is then updated accordingly. +Below is an example usage scenario for how `receive` would behave. + +**Step 1**: User enters `receive $/200 n/a` into the command line to settle up *$200* from *a*. + +**Step 2**: Upon executing the command, `LogicManager` uses `MainParser#parse()` to parse the input from the user. + +**Step 3**: `MainParser` determines that user input is an instance of a `ReceiveCommand` and creates a `ReceiveCommandParser` +to further parse the input. + +**Step 4**: `ReceiveCommandParser` parses the command and checks if fields like amount and names are valid. +If all fields are valid, it returns a `ReceiveCommand`. Else, an error is thrown to the result box and the execution +terminates. + +**Step 5**: `LogicManager` uses `ReceiveCommand#execute()` to update the balances of `Ledger` and the person in the +transaction. + +**Step 6**: `ReceiveCommand#execute()` calls `Model#add()` to add the user input into the user history. +Within the function call, the person in `Ledger` is found and his/her outstanding balance is updated in `Ledger#handleOperation()`. + +If he is not already inside the `Ledger`, a new `Person` is created with the same name. + +**Step 7**: `SplitCommand` calls `Model#commitUserState()` after executing to save the latest state of the application. + +**Step 8**: A `CommandResult` is then returned to the `LogicManager` which is then displayed to the user. + .Code snippet of `handleBalance` in ReceiveMoney ``` public class ReceiveMoney extends Payment { @@ -387,7 +493,7 @@ public abstract class Payment extends Transaction implements LedgerOperations { ``` //end::receive[] -// tag::project[] +// tag::project1[] [[Implementation-Projection]] === Project Feature: `project` @@ -421,7 +527,32 @@ Projections on budgets are made by first projecting the _user_'s balance amount Then, it compares the _user_'s projected balance amount at the point of the budget's deadline, with the budget's amount. A surplus is indicated when the former is greater than the latter, and a deficit is indicated when the former is smaller than the latter. +// end::project1[] +Given below is an example usage scenario and how the project command executes at each step. + +**Step 1**. The user launches the application. + +**Step 2**. If the user does not have at least *5* transactions, he / she adds transactions until +there are sufficient transactions to project upon. Then, the user executes the `project` command. + +**Step 3**. Upon executing the command, `LogicManager` uses `MainParser#parse()` to parse the input from the user. +**Step 4**. `MainParser` determines which command is being used and creates `ProjectCommandParser` to further parse +the input from the user. + +**Step 5**. `ProjectCommandParser` parses the argument and checks if a valid date and category was provided. + + +* If an invalid date or category was provided, or if no date was provided, `ProjectCommandParser` throws an exception and terminates. + +* Otherwise, it returns a `ProjectCommand`, which contains a `Date` and possibly a `Category` specified by the user. + +**Step 6**. `LogicManager` uses `ProjectCommand#execute()` to project the user's balance and budget states at the time +of the specified `Date`. + +**Step 7**. `ProjectCommand` uses `Model#commitUserState()` to save the latest state of the application. It then +returns a `CommandResult` to the `LogicManager` and the result will be displayed to the user at the end. + +// tag::project2[] ===== Activity Diagram The activity diagram below depicts how a projection is made. @@ -457,12 +588,37 @@ normal equation method will be used in place of the gradient descent algorithm, a set number (e.g. 500) of transactions. ==== Design Considerations -// end::project[] +// end::project2[] +// tag::display1[] === Display Feature: `display` This feature provides a graphical view of an existing projection to the _user_. + ==== Current Implementation +// end::display1[] +Given below is an example usage scenario and how the display command executes at each step. + +**Step 1**. The user launches the application. + +**Step 2**. If the user does not have any existing projections, he / she creates one or more projections. +Then, the user executes the `display` command. + +**Step 3**. Upon executing the command, `LogicManager` uses `MainParser#parse()` to parse the input from the user. + +**Step 4**. `MainParser` determines which command is being used and creates `DisplayCommandParser` to further parse +the input from the user. + +**Step 5**. `DisplayCommandParser` parses the argument and checks if a valid type and index was provided. + + +* If an invalid type or index was provided, or if no type or index was provided, `DisplayCommandParser` throws an exception and terminates. + +* Otherwise, it returns a `DisplayCommand`, which contains a `Type` and an `Index` specified by the user. + +**Step 6**. `LogicManager` uses `ProjectCommand#execute()` to display the specified `projection` in a +new window. + +**Step 7**. `DisplayCommand` returns a `CommandResult` to the `LogicManager` and the result will be displayed to the user at the end. +// tag::display2[] The following activity diagram depicts how the `display` command is executed. .Activity Diagram of the Display Command @@ -474,8 +630,7 @@ a sequence diagram is provided below. .Sequence Diagram of the Display Command image::DisplaySequenceDiagram.png[] - -// end::display[] +// end::display2[] // tag::view[] === View Feature: `view` @@ -523,6 +678,23 @@ This feature allows the user to delete an existing transaction, budget, ledger o * The delete feature is facilitated by the Logic and Model components of the application. * The delete feature works for `Transaction`, `Budget`, `Ledger` and `Projection` entries. + +Given below is an example usage of how `delete` behaves at each step. + +**Step 1**. The user executes `delete t1` to delete the first entry from the transaction list. + +**Step 2**. Upon executing the command, `LogicManager` uses `MainParser#parse` to parse this input from the user. + +**Step 3**. `MainParser` determines which command is being executed and creates `DeleteCommandParser` to further parse the input. + +**Step 4**. `DeleteCommandParser` parses the argument and checks the validity of arguments. If it is invalid, an exception is thrown. +Else, it returns a `DeleteCommand`. + +**Step 5**. `LogicManager` uses `DeleteCommand#execute()` to delete either the `Transaction`, `Budget`, `Ledger` or `Projection` from their respective unique lists. + +**Step 6**. `DeleteCommand` uses `Model#commitUserState()` to save the latest state of the application. It then +returns a `CommandResult` to the `LogicManager` and the result will be displayed to the user. + * The following activity diagram summarizes what happens when a user executes a `delete` command: .Activity Diagram for `delete` command @@ -551,45 +723,73 @@ image::DeleteActivityDiagram.png[] // end::delete[] // tag::update[] +// tag::update1[] + === Update Existing Entry Feature: `update` -This feature currently allows users to update `Transaction` or `Budget` entries. The user is unable to perform this feature on `Ledger` operations. The rationale for this will be further explained in **Aspect 2**. The user is currently unable to perform this feature on `Projection` operations as it will be further implemented in future updates. +This feature currently allows users to update `Transaction` or `Budget` entries. The user is unable to perform this feature on `Ledger` operations. The rationale for this will be further explained in <>. The user is currently unable to perform this feature on `Projection` operations as it will be further implemented in future updates. ==== Current Implementation +// end::update1[] + * The update feature is facilitated by the Logic and Model components of the application. * The parameter requirements differs for the type of entry: ** `Transaction` type requires at least one of it's `Amount`, `Description`, `Date` or `Category` fields to be updated. ** `Budget` type requires at least one of it's `Amount`, `Date` or `Category` fields to be updated. ** `Project` type requires it's `Date` and `Category` fields to be updated (Future implementation). * At least one valid parameter must be changed when executing an `update` command. (i.e. `update b1` will result in an error as no fields are being changed). + +**Step 1**. The user executes `update t2 $/200` to update the second entry's amount, from the transaction list, to $200 . + +**Step 2**. Upon executing the command, `LogicManager` uses `MainParser#parse` to parse this input from the user. + +**Step 3**. `MainParser` determines which command is being executed and creates `UpdateCommandParser` to further parse the input. + +**Step 4**. `UpdateCommandParser` parses the argument and checks the validity of arguments. If it is invalid, an exception is thrown. +Else, it returns a `UpdateCommand`. + +**Step 5**. `LogicManager` uses `UpdateCommand#execute()` to update either the `Transaction` or `Budget` from their respective unique lists. + +**Step 6**. `UpdateCommand#execute()` uses the `UpdateTransactionDescriptor` class to create a new instance of a transaction or budget with the appended variables. + +**Step 7**. `Model` from `UpdateCommand` then changes the necessary fields of this entry. + +**Step 8**. `UpdateCommand` uses `Model#commitUserState()` to save the latest state of the application. It then +returns a `CommandResult` to the `LogicManager` and the result will be displayed to the user. + * The following activity diagram summarizes what happens when a user executes an update command: .Activity Diagram for `update` -image::UpdateActivityDiagram.png[] +image::UpdateActivityDiagram.png[pdfwidth=70%] +// tag::update2[] ==== Design Considerations The `update` feature allows one or more fields of a Transaction or Budget to be updated. (e.g. `update t1 $/2` and `update t1 $/2 d/10102019` will both work as intended). -More often than not, users do not need to change an entire Transaction or Budget entry. This will minimize inputs for users if they do not require every single parameters of a Transaction or Budget to be changed. +More often than not, users do not need to change an entire Transaction or Budget entry. This will minimize inputs from users if they do not require every single parameters of a Transaction or Budget to be changed. + +// end::update2[] ===== Aspect 1: Update requires `TYPE+INDEX` as one of its parameter * **Alternative 1 (current choice):** takes in `TYPE+INDEX` to decide whether to update an item from Transaction, Budget or Projection list. (e.g. `delete b1` deletes item index 1 from budget). -** Pros: Requires lesser user steps to be taken before executing a `update` command. -** Cons: Requires three unique lists to be utilized instead of 1. (e.g. the `UniqueTransactionList` stores Transaction items and the `UniqueBudgetList` to store Budget items). +** Pros: Requires lesser user steps to be taken before executing an `update` command. +** Cons: Requires 2 unique lists to be utilized instead of 1. (e.g. the `UniqueTransactionList` stores Transaction items and the `UniqueBudgetList` to store Budget items). ** For example, when a new command is executed, we must remember to update both `HistoryManager` and `VersionedAddressBook`. * **Alternative 2:** Change to **Transaction**, **Budget** or **Projection** mode and keying in only index (e.g. `update 1 ..`). ** Pros: Requires only one unique list required to store all operation types. ** Cons: Requires additional user step to switch between modes before executing a updating command. +// tag::update3[] +[[Aspect2]] ===== Aspect 2: Update can not edit Ledger Operations -* **Alternative 1 (current choice):** Update Command only works with `Transaction`, `Budget` and `Projection` Operations. +* **Alternative 1 (current choice):** Update Command does not work with `Ledger` operations. ** Pros: Intuitive implementation and execution for the user. ** Cons: Requires excessive user operations. -*** The user has to first delete the `Ledger` operation that he/she wishes to change, followed by inputting the `Ledger` operation with the amended fields back into PalPay. +*** The user has to first delete the `Ledger` operation that he/she wishes to change, followed by inputting the `Ledger` operation with the amended fields back into _PalPay_. * **Alternative 2:** Update Command to also work with `Ledger` operations. ** Pros: Requires only one user command to append or change `Ledger` entries. ** Cons: Results in convoluted implementation and user experience. This will also hinder future permeability of the `Split` feature. @@ -603,8 +803,9 @@ Currently the update feature has not been implemented for `Projection` operation The activity diagram below will provide a visual representation of the possible user routes using the `update` command after this enhancement has been implemented. -.Activity Diagram for future `update` -image::UpdatefutureActivityDiagram.png[] +.Activity Diagram for Future `update` +image::UpdatefutureActivityDiagram.png[pdfwidth=70%] +// end::update3[] // end::update[] // tag::sort[] @@ -619,7 +820,7 @@ The `sort` command is facilitated by the Logic and Model components of the appli The following sequence diagram shows how the sorting of transactions work when the user enters `sort date/d`. .Sequence Diagram for `sort date/d` -image::SortSequenceDiagram.png[] +image::SortSequenceDiagram.png[pdfwidth=80%] ==== Example of Usage @@ -628,12 +829,12 @@ Given below is an example usage of how `sort` behaves at each step. **Step 1**. The user launches the application and views an unsorted list of transactions. .Initial State of PalPay -image::sort_dg_1.png[] +image::sort_dg_1.png[pdfwidth=80%] **Step 2**. The user now executes `sort date/d` to sort the transactions in the order of descending date. .User Inputs `sort date/d` -image::sort_dg_2.png[] +image::sort_dg_2.png[pdfwidth=80%] **Step 3**. Upon executing the command, `LogicManager` uses `MainParser#parse()` to parse the input from the user. @@ -650,14 +851,14 @@ invalid, `SortCommandParser` throws an exception and terminates. Else, it return **Step 8**. `SortCommand` uses `SortCommand#sortTransactionHistory()` to sort the transactions. -**Step 9**. `SortCommand` uses `Model#setTransactions()` to store the sorted transactions and `Model#commitUserState()` to +**Step 9**. `SortCommand` uses `Model#set()` to store the sorted transactions and `Model#commitUserState()` to save the latest state of the application. **Step 10**. `SortCommand` returns a `CommandResult` to the `LogicManager` and the result will be displayed to the user at the end. .After Sorting of Transactions -image::sort_dg_3.png[] +image::sort_dg_3.png[pdfwidth=80%] ==== Design Considerations @@ -749,6 +950,7 @@ Given below is an example usage scenario and how the undo/redo mechanism behaves The `VersionedUserState` will be initialized with the initial user state, and the `currentStatePointer` pointing to that single user state. +.Initial State image::UndoRedoState0.png[pdfwidth=50%, align="center"] **Step 2**. The user executes `delete t5` command to delete the 5th transaction in the transaction list. @@ -756,12 +958,14 @@ The `delete` command calls `Model#commitUserState()`, causing the modified state `delete t5` command executes to be saved in the `userStateList`, and the `currentStatePointer` is shifted to the newly inserted user state. +.After `delete t1` Command image::UndoRedoState1.png[pdfwidth=50%, align="center"] **Step 3**. The user executes `in $/10 n/Allowance d/07112019` to log a new transaction. The `in` command also calls `Model#commitUserState()`, causing another modified user state to be saved into the `userStateList`. +.After `in $/10 n/Allowance d/07112019` Command image::UndoRedoState2.png[pdfwidth=50%, align="center"] [NOTE] @@ -773,6 +977,7 @@ executing the `undo` command. The `undo` command will call `Model#undoUserState( `currentStatePointer` once to the left, pointing it to the previous user state, and restores the user state to that state. +.After `undo` Command image::UndoRedoState3.png[pdfwidth=50%, align="center"] [NOTE] @@ -784,6 +989,7 @@ If so, it will return an error to the user rather than attempting to perform the Commands that do not modify the user state, such as `list`, will usually not call `Model#commitUserState()`, `Model#undoUserState()` or `Model#redoUserState()`. Thus, the `userStateList` remains unchanged. +.After `list` Command image::UndoRedoState4.png[pdfwidth=50%, align="center"] **Step 6**. The user executes `clear`, which calls `Model#commitUserState()`. @@ -791,10 +997,12 @@ Since the `currentStatePointer` is not pointing at the end of the `userStateList the `currentStatePointer` will be purged. We designed it this way because it no longer makes sense to redo the `in $/10 n/Allowance d/07112019` command. This is the behavior that most modern desktop applications follow. +.After `clear` Command image::UndoRedoState5.png[pdfwidth=50%, align="center"] The following sequence diagram shows how the undo operation works: +.Undo Sequence Diagram image::UndoSequenceDiagram.png[] NOTE: The lifeline for `UndoCommand` should end at the destroy marker (X) but due to a limitation of PlantUML, @@ -973,35 +1181,20 @@ _{More to be added}_ [appendix] == Glossary +[[api]] +API:: +Application Programming Interface + + [[mainstream-os]] Mainstream OS:: Windows, Linux, Unix, OS-X -[[private-contact-detail]] -Private contact detail:: -A contact detail that is not meant to be shared with others - -[appendix] -== Product Survey - -*Product Name* - -Author: ... - -Pros: - -* ... -* ... - -Cons: - -* ... -* ... [appendix] == Instructions for Manual Testing -Given below are instructions to test the app manually. +Given below are instructions to test the application manually. [NOTE] These instructions only provide a starting point for testers to work on; testers are expected to do more _exploratory_ testing. @@ -1023,23 +1216,145 @@ Close the window. .. Re-launch the app by double-clicking the jar file. + Expected: The most recent window size and location is retained. +=== Adding an In Transaction + +. Adding an in transaction with the command: `in` + +.. Prerequisites: + +.. Test case: `in $/1000 n/Allowance d/11112019` + +Expected: An in transaction will be added into the list of transactions in the Transaction tab. + +.. Test case: `in $/0 n/Allowance d/11112019` + +Expected: No transaction is added. Error details will be shown in the status message. + +.. Other incorrect `in` commands to try: `in $/10.001 n/Allowance d/11112019`, `in $/1000 n/Allow@nce d/11112019` +(Contains non-alphanumeric characters). + +Expected: Similar to previous. + +=== Adding an Out Transaction + +. Adding an out transaction with the command: `out` + +.. Prerequisites: + +.. Test case: `out $/10 n/KFC d/11112019` + +Expected: An out transaction will be added into the list of transactions in the Transaction tab. + +.. Test case: `out $/0 n/KFC d/11112019` + +Expected: No transaction is added. Error details will be shown in the status message. + +.. Other incorrect `out` commands to try: `out $/10.001 n/KFC d/11112019`, `out $/10 n/KFC d/32112019` +(Date is invalid). + +Expected: Similar to previous. + +=== Adding a Budget + +. Adding a budget with the command: `set` + +.. Prerequisites: + +.. Test case: `set $/1000 c/Shopping d/31122019` + +Expected: A budget will be added into the list of budgets in the Budget tab. + +.. Test case: `set $/1000 c/Shopping d/01012019` + +Expected: No budget is added. Error details will be shown in the status message. + +.. Other incorrect `set` command to try: `set $/-10 c/Shopping d/31122019` (Amount is negative). + +Expected: Similar to previous. + +=== Adding a Split Ledger + +. Adding a split ledger with the command: `split` + +.. Prerequisites: + +.. Test case: `split $/1000 n/Amy n/Betty a/HaiDiLao` + +Expected: An overall ledger with 4 individual ledgers will be added into the list of ledgers in the Ledger tab. + +.. Test case: `split $/1000 n/Amy n/Betty` + +Expected: No ledger is added. Error details will be shown in the status message. + +.. Other incorrect `split` command to try: `split $/1000 n/Amy n/Betty a/HaiDiLao s/1 s/2 s/3 s/4` +(Greater number of shares than number of people). + +Expected: Similar to previous. + +=== Adding a Receive Ledger + +. Adding a receive ledger with the command: `receive` + +.. Prerequisites: + +.. Test case: `receive $/20 n/Albert` + +Expected: An overall ledger with an individual ledger will be added into the list of ledgers in the ledger tab. + +.. Test case: `receive $/20 n/A|bert` + +Expected: No ledger is added. Error details will be shown in the status message. + +.. Other incorrect `receive` command to try: `receive $/20.001 n/Albert` (Amount cannot have more than +two decimal places). + +Expected: Similar to previous. + +=== Switching Tabs + +. Switching tabs with the command: `view` + +.. Prerequisites: + +.. Test case: `view budget` + +Expected: Switches to budget tab if user is in another tab. Else, user remains in budget tab. + +.. Test case: `view budg3t` + +Expected: Remains in current tab. Error details will be shown in the status message. + +.. Other incorrect `view` command to try: `view loans` (Loans tab does not exist). + +Expected: Similar to previous. + +=== Deleting an Entry + +. Deleting an entry with the command: `delete` + +.. Prerequisites: + +.. Test case: `delete t1` + +Expected: First transaction is deleted from the list. Balance in the footer will be updated. + +.. Test case: `delete t0` + +Expected: No transaction is deleted. Error details shown in the status message. Balance remains the same. + +.. Other incorrect `delete` commands to try: `delete`, `delete t1000` (When size of the list of transaction +is smaller than 1000). + +Expected: Similar to previous. + +=== Updating an Entry + +. Updating an entry with the command: `update` + +.. Prerequisites: + +.. Test case: `update t1 $/1000` + +Expected: First transaction in the list is updated. Balance will be updated as well. + +.. Test case: `update t0 $/1000` + +Expected: No transaction is updated. Error details shown in the status message. Balance remains the same. + +.. Other incorrect `update` commands to try: `update`, `update i/Invalid` (Invalid prefix). + +Expected: Similar to previous. + +=== Sorting the Transactions + +. Sorting the transactions with the command: `sort` + +Prerequisites: -=== Deleting a Person +.. Test case: `sort amount/a` + +Expected: Transaction list will be sorted from smallest amount to greatest amount. Balance remains the same. -. Deleting a person while all persons are listed +.. Test case: `sort amount` + +Expected: Transaction list remains unchanged. Error details shown in the status message. -.. Prerequisites: List all persons using the `list` command. -Multiple persons in the list. -.. Test case: `delete 1` + - Expected: First contact is deleted from the list. -Details of the deleted contact shown in the status message. -Timestamp in the status bar is updated. -.. Test case: `delete 0` + - Expected: No person is deleted. -Error details shown in the status message. -Status bar remains the same. -.. Other incorrect delete commands to try: `delete`, `delete x` (where x is larger than the list size) _{give more}_ + - Expected: Similar to previous. +.. Other incorrect `sort` commands to try: `sort`, `sort date` (Order not stated). + +Expected: Similar to previous. === Viewing Help Window diff --git a/docs/DeveloperGuide.html b/docs/DeveloperGuide.html new file mode 100644 index 00000000000..7f92da063d9 --- /dev/null +++ b/docs/DeveloperGuide.html @@ -0,0 +1,2947 @@ + + + + + + + +PalPay - Developer Guide + + + + + +
+ +
+

1. Introduction

+
+
+

1.1. Purpose

+
+

This document describes the architecture and system design of PalPay. +It is a living document that evolves throughout the design and implementation for each release. +Each release will have an edition of the document, and the current edition of the document is for the first public release of the application.

+
+
+

This document aims to cover the high-level system architecture and design. +It is segmented into two major parts: software design, including system architecture, and design implementation. +The software design illustrates the main software components that operate and support the main system architecture. +Essential details such as the user stories, use cases, and the Non Functional Requirements are included at the back of this document.

+
+
+
+

1.2. Audience

+
+

This document is written for software engineers who desires a deeper insight of the system architecture and design of this application - PalPay. +In particular, the intended audience of this document will be the students taking on the roles of the developers, designers, and software testers of PalPay from CS2103T - Software Engineering.

+
+
+
+

1.3. Description

+
+

PalPay is a CLI application targeted for users who have poor financial management skills. The users should also prefer typing over mouse inputs. +It allows the users to keep track of daily financial transactions, as well as set a budget for a time duration to achieve long-term financial success. Additionally, users can keep a ledger of lending and borrowing of money with others so that the users can keep track of the flow of their money.

+
+
+

Below is the Graphical User Interface (GUI) of PalPay:

+
+
+
+dg gui example +
+
Figure 1. PalPay’s GUI
+
+
+
+
+
+

2. Setting up

+
+
+

Refer to the guide here.

+
+
+
+
+

3. Design

+
+
+

3.1. Architecture

+
+
+ArchitectureDiagram +
+
Figure 2. Architecture Diagram
+
+
+

The Architecture Diagram given above explains the high-level design of the App. +Given below is a quick overview of each component.

+
+
+

Main has two classes called Main and MainApp. +It is responsible for,

+
+
+
    +
  • +

    At app launch: Initializes the components in the correct sequence, and connects them up with each other.

    +
  • +
  • +

    At shut down: Shuts down the components and invokes cleanup method where necessary.

    +
  • +
+
+
+

Commons represents a collection of classes used by multiple other components. +The following class plays an important role at the architecture level:

+
+
+
    +
  • +

    LogsCenter : Used by many classes to write log messages to the App’s log file.

    +
  • +
+
+
+

The rest of the App consists of four components.

+
+
+
    +
  • +

    UI: The UI of the App.

    +
  • +
  • +

    Logic: The command executor.

    +
  • +
  • +

    Model: Holds the data of the App in-memory.

    +
  • +
  • +

    Storage: Reads data from, and writes data to, the hard disk.

    +
  • +
+
+
+

Each of the four components

+
+
+
    +
  • +

    Defines its API in an interface with the same name as the Component.

    +
  • +
  • +

    Exposes its functionality using a {Component Name}Manager class.

    +
  • +
+
+
+

For example, the Logic component (see the class diagram given below) defines it’s API in the Logic.java interface and exposes its functionality using the LogicManager.java class.

+
+
+
+LogicClassDiagram +
+
Figure 3. Class Diagram of the Logic Component
+
+

How the architecture components interact with each other

+
+

The Sequence Diagram below shows how the components interact with each other for the scenario where the user issues the command delete 1.

+
+
+
+ArchitectureSequenceDiagram +
+
Figure 4. Component Interactions for delete t1 Command
+
+
+

The sections below give more details of each component.

+
+
+
+

3.2. UI Component

+
+
+UiClassDiagram +
+
Figure 5. Structure of the UI Component
+
+
+

API : Ui.java

+
+
+

The UI consists of a MainWindow that is made up of parts e.g.CommandBox, ResultDisplay, PersonListPanel, StatusBarFooter etc. +All these, including the MainWindow, inherit from the abstract UiPart class.

+
+
+

The UI component uses JavaFx UI framework. +The layout of these UI parts are defined in matching .fxml files that are in the src/main/resources/view folder. +For example, the layout of the MainWindow is specified in MainWindow.fxml

+
+
+

The UI component,

+
+
+
    +
  • +

    Executes user commands using the Logic component.

    +
  • +
  • +

    Listens for changes to Model data so that the UI can be updated with the modified data.

    +
  • +
+
+
+
+

3.3. Logic Component

+
+
+LogicClassDiagram +
+
Figure 6. Structure of the Logic Component
+
+
+

API : +Logic.java

+
+
+
    +
  1. +

    Logic uses the BankAccountParser class to parse the user command.

    +
  2. +
  3. +

    This results in a Command object which is executed by the LogicManager.

    +
  4. +
  5. +

    The command execution can affect the Model (e.g. adding a transaction).

    +
  6. +
  7. +

    The result of the command execution is encapsulated as a CommandResult object which is passed back to the Ui.

    +
  8. +
  9. +

    In addition, the CommandResult object can also instruct the Ui to perform certain actions, such as displaying help to the user.

    +
  10. +
+
+
+

Given below is the Sequence Diagram for interactions within the Logic component for the execute("delete t1") API call.

+
+
+
+DeleteSequenceDiagram +
+
Figure 7. Interactions Inside the Logic Component for the delete t1 Command
+
+
+ + + + + +
+
Note
+
+The lifeline for DeleteCommandParser should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram. +
+
+
+
+

3.4. Model Component

+
+
+ModelClassDiagram +
+
Figure 8. Structure of the Model Component
+
+
+

API : Model.java

+
+
+

The Model,

+
+
+
    +
  • +

    stores a UserPref object that represents the user’s preferences.

    +
  • +
  • +

    stores the User State data.

    +
  • +
  • +

    exposes an unmodifiable ObservableList<BankAccountOperation>, ObservableList<Budget>, ObservableList<LedgerOperation> and ObservableList<Projection> +that can be 'observed'.
    +For example, the UI can be bound to these lists so that the UI automatically updates when the data in the lists change due to user commands.

    +
  • +
  • +

    does not depend on any of the other three components.

    +
  • +
+
+
+
+

3.5. Storage Component

+
+
+StorageClassDiagram +
+
Figure 9. Structure of the Storage Component
+
+
+

API : Storage.java

+
+
+

The Storage component,

+
+
+
    +
  • +

    can save UserPref objects in json format and read it back.

    +
  • +
  • +

    can save the Bank Account data in json format and read it back.

    +
  • +
+
+
+
+

3.6. Common Classes

+
+

Classes used by multiple components are in the seedu.addressbook.commons package.

+
+
+
+
+
+

4. Implementation

+
+
+

This section describes some noteworthy details on how certain features are implemented.

+
+
+

4.1. Transaction: in / out

+
+

The Transaction abstract class allows user to input income and expense statements. Both in and out transactions requires the mandatory Amount, Description and Date fields to be appended. There is an optional Category field which can accept one or more input depending on the user specifications. +The in transactions will increase the BankAccount balance amount whilst the out transactions will reduce the BankAccount balance amount.

+
+
+

In Transactions represent the income statements inputted into Palpay.

+
+
+

Out Transactions represent the expenditure statements inputted into Palpay.

+
+
+

4.1.1. Current Implementation

+
+

Given below is an example usage of how in behaves at each step. out command follows a similar logic flow.

+
+
+

Step 1. The user executes in $/200 n/coke d/10102019 to input a new income of $100 on 10th November 2019 under the category GENERAL.

+
+
+

Step 2. Upon executing the command, LogicManager uses MainParser#parse to parse this input from the user.

+
+
+

Step 3. MainParser determines which command is being executed and creates InCommandParser to further parse the input.

+
+
+

Step 4. InCommandParser parses the argument and checks the validity of arguments. If it is invalid, an exception is thrown. +Else, it returns a InCommand.

+
+
+

Step 5. LogicManager uses InCommand#execute() to add a new InTransaction.

+
+
+

Step 6. BankAccount then calls InTransaction#handleBalance() to increase its balance amount by $200.

+
+
+

Step 7. InCommand uses Model#commitUserState() to save the latest state of the application. It then +returns a CommandResult to the LogicManager and the result will be displayed to the user.

+
+
+

The sequence diagram below illustrates how PalPay handles the command input in $/200 n/coke d/10102019. The arguments are parsed into the logic component where the subsequent model objects are created.

+
+
+
+InSequenceDiagram +
+
Figure 10. Sequence Diagram for Executing an InCommand
+
+
+

The in and out transaction follows the same logic flow after they are parsed.

+
+
+

The difference between in and out transactions is that the handleBalance() method called in the BankAccount results in an addAmount operation for the inTransaction and a subtractAmount operation for the OutTransaction class.

+
+
+
Example
+
+

Given that the BankAccount balance initially starts with 0 dollars.

+
+
+
    +
  • +

    in Transaction of $1000 will increase the BankAccount balance from $0 to $1000.

    +
  • +
  • +

    out Transaction of $250 will subsequently decrease the BankAccount balance from $1000 to $250.

    +
  • +
  • +

    The Activity Diagram shown below will provide a visual representation of the two routes a Transaction object can take.

    +
  • +
+
+
+
+InActivityDiagram +
+
Figure 11. Activity Diagram for In and Out Transactions
+
+
+
+
+

4.1.2. Design Considerations

+
+
    +
  • +

    To prevent repetitive code implementation, the Transaction abstract class is used to facilitate income and expenditure logging. Transaction is an abstract class which contains the default constructor and commonly used variables. InTransaction and OutTransaction extends the Transaction class as they typically store an amount, date, description, and a set of categories. +A code snippet of the Transaction abstract class is shown below.

    +
  • +
+
+
+
+
public abstract class Transaction {
+
+    protected Amount amount;
+    protected Date date;
+    protected Description description;
+    protected final Set<Category> categories = new HashSet<>();
+
+    public Transaction(Amount amount, Date date, Description description) {
+        this.amount = amount;
+        this.date = date;
+        this.description = description;
+    }
+
+
+
+
    +
  • +

    The balance in BankAccount and the balance in Ledger are considered two separate identities, both being encompassed under the UserState class. +Therefore user operations that deal with BankAccount implements the BankAccountOperation interface, while operations +that deal with Ledger implements the LedgerOperation interface.

    +
    +
      +
    • +

      This allows us to achieve polymorphism by overloading methods in Model to handle the different operations correctly.

      +
    • +
    • +

      This reduces code coupling as there are different models to handle different balance amounts.

      +
    • +
    +
    +
  • +
  • +

    A Transaction entry can affect a Budget which has similar categories and is within the same time period. The activity diagram bellow will further clarify this flow.

    +
    +
      +
    • +

      Only Out Transactions can affect Budget.

      +
    • +
    • +

      The activity diagram below shows how and when a Transaction object affects Budget.

      +
    • +
    +
    +
  • +
+
+
+
+OutbudgetActivityDiagram +
+
Figure 12. Activity Diagram for Out Transaction Affecting Budget
+
+
+
+
+

4.2. Set Budget Feature: set

+
+

The Budget class allows the user to set a budget for a given time period for a category, if specified. +The user is allowed to set multiple budgets, but duplicate budgets (budgets with the same identity in terms of amount, date and category) are not allowed. +Upon setting the budget, making OutTransaction will deduct the amount from relevant budgets in the list. +The detailed implementation of the process of updating the budget is explained further below in Current Implementation.

+
+
+

4.2.1. Current Implementation

+
+

The set command is an extension of parent Command class, facilitated by the Logic and Model components of the application, PalPay
+Given an amount and date, a new Budget is set for the user.
+Upon setting a new budget, a BudgetCard is created and displayed in a list in the application window till the date set by the user.

+
+
+

A Budget stores an initial amount, amount (the current amount), deadline, categories. +There is a need for a Budget to store both initial amount and amount as it allows for percentage of budget remaining to be calculated.
+Shown below is the class diagram of Budget class:

+
+
+
+BudgetClassDiagram +
+
Figure 13. Class Diagram of Budget class
+
+
+

Displaying the percentage remaining improves the user experience greatly as our target user is a +visual person who wants to see how much budget he has left in each category so as to cut down on spending as necessary +as specified in the User Story. Hence, taking a quick glance at the Budget card allows the user to +determine how much of budget he has left, as well as be alarmed by the red font color to spend less if he has overspent beyond the budget set.

+
+
+

A snippet of the code which calculates the percentage of budget left is shown below:

+
+
+
+
public String displayPercentage() {
+    double percentage = this.amount.divideAmount(this.initialAmount) * 100;
+    if (percentage < 0.00) {
+        percentage = 0.0; // should not display a negative percentage
+    } else if (percentage > 100.00) {
+        percentage = 100.0; // should not display a percentage greater than 100%
+    }
+    return String.format("%.2f%% remaining", percentage);
+}
+
+
+
+

Moreover, as our user is a visual person, PalPay makes use of color to display different messages. +For instance, budget is displayed in red to alert the user that he has overspent beyond the set budget.

+
+
+

Shown below is an example of an overspent budget:

+
+
+
+overspentBudget +
+
Figure 14. Example of an Overspent Budget
+
+
+

When setting a new Budget, existence of a duplicate budget is checked through a sequence of checks. +The activity diagram below shows the activity diagram of setting a new budget:

+
+
+
+SetBudgetSimpleActivityDiagram +
+
Figure 15. Activity Diagram of Setting a New Budget Successfully
+
+
+

As shown, a new budget cannot have the same initalAmount, deadline and categories as any other existing budget in +budget list. Allowing existence of duplicate budgets will crowd the interface of Budget tab, +which prevents the user from getting a quick overview of his budget status. Hence, a duplicate check is essential +in providing a pleasing user exp.

+
+
+
+

4.2.2. Example of Usage

+
+

Given below is an example usage of how set behaves at each step.

+
+
+

Step 1. The user executes set $/100 d/31122019 c/shopping to set a new budget of $100 until 31st December 2019 under the category shopping.

+
+
+
+set dg 1 +
+
Figure 16. User Inputs set $/100 d/31122019 c/shopping
+
+
+

Step 2. Upon executing the command, LogicManager uses MainParser#parse to parse the input from the user.

+
+
+

Step 3. MainParser determines which command is being executed and creates SetCommandParser to further parse the input.

+
+
+

Step 4. SetCommandParser parses the argument and checks if it is valid. If it is invalid, an exception is thrown. +Else, it returns a SetCommand.

+
+
+

Step 5. LogicManager uses SetCommand#execute() to add a new budget.
+SetCommand uses ModelManager#has(Budget) to check if it is a duplicate of an existing budget +in the UniqueBudgetList as shown above in the above diagram.

+
+
+

Step 6. SetCommand uses Model#commitUserState() to save the latest state of the application. It then +returns a CommandResult to the LogicManager and the result will be displayed to the user at the end.

+
+
+
+set dg 2 +
+
Figure 17. New Budget Successfully Created
+
+
+
+

4.2.3. Design Considerations

+
+

Currently, Budget does not extend from Transaction although the two behave in a similar way. +There is an aggregation between Budget and Transaction as the two can exist independent of each other, +although an effect on one may also cause an impact on the other. +The current design was chosen over the former design of inheritance as there is a stark difference in the two +in a way that Budget does not affect the balance of the user’s bank account directly while Transaction does. +Hence, by Liskov Substitution Principle, inheritance is not a suitable design.

+
+
+
+
+

4.3. Split Feature: split

+
+

This feature allows the user to pay for a certain item or make a transaction on behalf of his friends. +Refer to the UserGuide for usage details.

+
+
+

4.3.1. Current Implementation

+
+

The split command is an abstraction of LendMoney class.
+Given a list of shares and people, each person is assigned an amount based on the corresponding positional share and the total amount given to split command.
+A LendMoney instance is created for each person and executed.

+
+
+

Below shows how a typical command from the user is executed by the program.

+
+
+
+Split +
+
Figure 18. Sequence Diagram for Executing a SplitCommand
+
+
+

Step 1: User enters split $/200 n/a n/b n/c a/desc into the command line to split $200 among a, b and c.

+
+
+

Step 2: Upon executing the command, LogicManager uses MainParser#parse() to parse the input from the user.

+
+
+

Step 3: MainParser determines that user input is an instance of a SplitCommand and creates a SplitCommandParser +to further parse the input.

+
+
+

Step 4: SplitCommandParser parses the command and checks if fields like amount and names are valid. +If all fields are valid, it returns a SplitCommand. Else, an error is thrown to the result box and the execution +terminates.

+
+
+

Step 5: LogicManager uses SplitCommand#execute() to update the balances of Ledger and people involved in the +transaction.

+
+
+

Step 6: SplitCommand#execute() calls Model#add() to add the user input into the user history. +Within the function call, the actual update of balances is handled in Ledger#handleOperation().

+
+
+

Step 7: SplitCommand calls Model#commitUserState() after executing to save the latest state of the application.

+
+
+

Step 8: A CommandResult is then returned to the LogicManager which is then displayed to the user.

+
+
+
+SplitBehaviour +
+
Figure 19. Activity Diagram for Creating a Split Object
+
+
+
+

4.3.2. Design Considerations

+
+

Below shows how the classes involved with Ledger interact with each other.

+
+
+
+LedgerOperationDiagram +
+
Figure 20. Class Diagram for Operations that Deal with Ledger
+
+
+

Current implementation of Split class encourages code reuse by abstracting the delegating the task of rebalancing to another class.
+However, this introduces coupling as the behavior of Split is now inexplicably tied to LendMoney.

+
+
+
+
+

4.4. Settle Up Feature: receive

+
+

This feature allows another person to send money to the user.
+The balance in the Ledger and the balance of the sender is updated accordingly.

+
+
+

4.4.1. Current Implementation

+
+

The receive command creates ReceiveMoney class that handles the transfer of fund from another person to the user.

+
+
+

How receive relates to the rest of the Ledger classes can be inferred from the +class diagram above.

+
+
+

In the handleBalance method of ReceiveMoney, it will find the correct person in the Ledger by name, +or create a new Person with given name if it is not already in the Ledger.
+Balance of the user and the sender is then updated accordingly.

+
+
+

Below is an example usage scenario for how receive would behave.

+
+
+

Step 1: User enters receive $/200 n/a into the command line to settle up $200 from a.

+
+
+

Step 2: Upon executing the command, LogicManager uses MainParser#parse() to parse the input from the user.

+
+
+

Step 3: MainParser determines that user input is an instance of a ReceiveCommand and creates a ReceiveCommandParser +to further parse the input.

+
+
+

Step 4: ReceiveCommandParser parses the command and checks if fields like amount and names are valid. +If all fields are valid, it returns a ReceiveCommand. Else, an error is thrown to the result box and the execution +terminates.

+
+
+

Step 5: LogicManager uses ReceiveCommand#execute() to update the balances of Ledger and the person in the +transaction.

+
+
+

Step 6: ReceiveCommand#execute() calls Model#add() to add the user input into the user history. +Within the function call, the person in Ledger is found and his/her outstanding balance is updated in Ledger#handleOperation().
+If he is not already inside the Ledger, a new Person is created with the same name.

+
+
+

Step 7: SplitCommand calls Model#commitUserState() after executing to save the latest state of the application.

+
+
+

Step 8: A CommandResult is then returned to the LogicManager which is then displayed to the user.

+
+
+
Code snippet of handleBalance in ReceiveMoney
+
+
public class ReceiveMoney extends Payment {
+    @Override
+    public Amount handleBalance(Amount balance, UniquePersonList peopleInLedger) {
+        Person target = super.handleTarget(peopleInLedger);
+        target.spend(amount);
+        return balance.addAmount(amount);
+    }
+}
+
+public abstract class Payment extends Transaction implements LedgerOperations {
+    protected Person handleTarget(UniquePersonList peopleInLedger) {
+        Person personInvolved = person;
+        if (peopleInLedger.contains(person)) {
+            personInvolved = peopleInLedger.get(person).get();
+        } else {
+            peopleInLedger.add(person);
+        }
+        return personInvolved;
+    }
+}
+
+
+
+
+
+

4.5. Project Feature: project

+
+

This feature allows users to project their balance amount and budget statuses based on past income and outflows as manifest in their +TransactionHistory by using the command project DATE [CATEGORY].

+
+
+

4.5.1. Current Implementation

+
+

The project command is facilitated by the Logic and Model components of the application, PalPay.

+
+
+

The sequence diagram below demonstrates how the project DATE [CATEGORY] command is handled by the application. +If a CATEGORY is not specified by the user, it will be set as GENERAL by default.

+
+
+
+ProjectCommand Sequence Diagram +
+
Figure 21. Sequence Diagram of the Project Command
+
+
+
Projection by Date
+
+

When projecting by date alone, all transactions in the user's transaction list will be taken into account, +regardless of their categories. On the other hand, only budgets without categories (thus belonging to the +GENERAL category by default) will be projected upon.

+
+
+
+
Projection by Date and Category
+
+

When projecting by date and category, all transactions tagged by the specified category will be taken into account. +Similarly, all budgets tagged with the specified category will be projected upon.

+
+
+
+
Budget Projections
+
+

Projections on budgets are made by first projecting the user's balance amount at the point when the budget was set. +Then, it compares the user's projected balance amount at the point of the budget’s deadline, with the budget’s amount. +A surplus is indicated when the former is greater than the latter, and a deficit is indicated when the former is smaller +than the latter. +Given below is an example usage scenario and how the project command executes at each step.

+
+
+

Step 1. The user launches the application.

+
+
+

Step 2. If the user does not have at least 5 transactions, he / she adds transactions until +there are sufficient transactions to project upon. Then, the user executes the project command.

+
+
+

Step 3. Upon executing the command, LogicManager uses MainParser#parse() to parse the input from the user.

+
+
+

Step 4. MainParser determines which command is being used and creates ProjectCommandParser to further parse +the input from the user.

+
+
+

Step 5. ProjectCommandParser parses the argument and checks if a valid date and category was provided.

+
+
+
    +
  • +

    If an invalid date or category was provided, or if no date was provided, ProjectCommandParser throws an exception and terminates.

    +
  • +
  • +

    Otherwise, it returns a ProjectCommand, which contains a Date and possibly a Category specified by the user.

    +
  • +
+
+
+

Step 6. LogicManager uses ProjectCommand#execute() to project the user’s balance and budget states at the time +of the specified Date.

+
+
+

Step 7. ProjectCommand uses Model#commitUserState() to save the latest state of the application. It then +returns a CommandResult to the LogicManager and the result will be displayed to the user at the end.

+
+
+
+
Activity Diagram
+
+

The activity diagram below depicts how a projection is made.

+
+
+
+ProjectActivityDiagram +
+
Figure 22. Activity Diagram of the Project Command
+
+
+
+
Graphical Representation
+
+

A graphical representation of the user's projections may be rendered using the display command.

+
+
+
+
+

4.5.2. Future Enhancements

+
+
Polynomial Regression
+
+

For simplicity of logic and design, the current implementation performs linear regression (via gradient descent), +projecting user balance and budget states using a best-fit straight line. Ultimately, income and spending trends +may not be best represented by a straight line, but rather by a polynomial equation. In future updates, the projection +feature will choose a value, n, and perform a n-th degree polynomial regression, such that the user’s balance +and budget states can be more accurately projected.

+
+
+ + + + + +
+
Note
+
+Currently, the GradientDescent class implements feature scaling and mean normalisation. Although this +is not entirely necessary for the current implementation (which uses linear regression), it is meant +for optimizing polynomial regression in future updates. +
+
+
+
+
Normal Equation
+
+

Currently, the gradient descent algorithm is used to plot the projection graph, which is used for predicting the +user's balance and budget states at specified point in time. For smaller data sets, analytically computing the +normal equation to find the best-fit line graph may have result in a faster runtime. In future updates, the +normal equation method will be used in place of the gradient descent algorithm, for projections with less than +a set number (e.g. 500) of transactions.

+
+
+
+
+

4.5.3. Design Considerations

+ +
+
+
+

4.6. Display Feature: display

+
+

This feature provides a graphical view of an existing projection to the user.

+
+
+

4.6.1. Current Implementation

+
+

Given below is an example usage scenario and how the display command executes at each step.

+
+
+

Step 1. The user launches the application.

+
+
+

Step 2. If the user does not have any existing projections, he / she creates one or more projections. +Then, the user executes the display command.

+
+
+

Step 3. Upon executing the command, LogicManager uses MainParser#parse() to parse the input from the user.

+
+
+

Step 4. MainParser determines which command is being used and creates DisplayCommandParser to further parse +the input from the user.

+
+
+

Step 5. DisplayCommandParser parses the argument and checks if a valid type and index was provided.

+
+
+
    +
  • +

    If an invalid type or index was provided, or if no type or index was provided, DisplayCommandParser throws an exception and terminates.

    +
  • +
  • +

    Otherwise, it returns a DisplayCommand, which contains a Type and an Index specified by the user.

    +
  • +
+
+
+

Step 6. LogicManager uses ProjectCommand#execute() to display the specified projection in a +new window.

+
+
+

Step 7. DisplayCommand returns a CommandResult to the LogicManager and the result will be displayed to the user at the end. +The following activity diagram depicts how the display command is executed.

+
+
+
+DisplayActivityDiagram +
+
Figure 23. Activity Diagram of the Display Command
+
+
+

For a more concrete illustration of how the display command is handled by PalPay, +a sequence diagram is provided below.

+
+
+
+DisplaySequenceDiagram +
+
Figure 24. Sequence Diagram of the Display Command
+
+
+
+
+

4.7. View Feature: view

+
+

This feature allows the user to switch between the different tabs of the application.

+
+
+

4.7.1. Current Implementation

+
+

The view command is facilitated by the MainWindow, MainTabPanel, ViewCommandParser and ViewCommand.

+
+
+

Given below is an example usage of how view behaves at each step.

+
+
+

Step 1. The user launches the application and views the transaction tab.

+
+
+

Step 2. The user now executes view budget to switch to the budget tab.

+
+
+

Step 3. Upon executing the command, LogicManager uses MainParser#parse() to parse the input from the user.

+
+
+

Step 4. MainParser determines which command is being used and creates ViewCommandParser to further parse the input +from the user.

+
+
+

Step 5. ViewCommandParser parses the argument and checks if it is valid. If it is +invalid, ViewCommandParser throws an exception and terminates. Else, it returns a ViewCommand that contains a Tab.

+
+
+

Step 6. LogicManager uses ViewCommand#execute() to switch to the budget tab.

+
+
+

Step 7. ViewCommand returns a CommandResult to the LogicManager with the Tab. LogicManager then +returns the CommandResult to MainWindow.

+
+
+

Step 8. MainWindow checks if there is a need to switch Tab. If there is, MainWindow uses +MainWindow#handleSwitchTab() to switch tab. Else, MainWindow does nothing.

+
+
+

The following activity diagram shows the flow of the view command.

+
+
+
+ViewActivityDiagram +
+
Figure 25. Activity Diagram for View
+
+
+
+
+

4.8. Delete Transaction Feature: delete

+
+

This feature allows the user to delete an existing transaction, budget, ledger or projection entry from their respective lists.

+
+
+

4.8.1. Current Implementation

+
+
    +
  • +

    The delete feature is facilitated by the Logic and Model components of the application.

    +
  • +
  • +

    The delete feature works for Transaction, Budget, Ledger and Projection entries.

    +
  • +
+
+
+

Given below is an example usage of how delete behaves at each step.

+
+
+

Step 1. The user executes delete t1 to delete the first entry from the transaction list.

+
+
+

Step 2. Upon executing the command, LogicManager uses MainParser#parse to parse this input from the user.

+
+
+

Step 3. MainParser determines which command is being executed and creates DeleteCommandParser to further parse the input.

+
+
+

Step 4. DeleteCommandParser parses the argument and checks the validity of arguments. If it is invalid, an exception is thrown. +Else, it returns a DeleteCommand.

+
+
+

Step 5. LogicManager uses DeleteCommand#execute() to delete either the Transaction, Budget, Ledger or Projection from their respective unique lists.

+
+
+

Step 6. DeleteCommand uses Model#commitUserState() to save the latest state of the application. It then +returns a CommandResult to the LogicManager and the result will be displayed to the user.

+
+
+
    +
  • +

    The following activity diagram summarizes what happens when a user executes a delete command:

    +
  • +
+
+
+
+DeleteActivityDiagram +
+
Figure 26. Activity Diagram for delete command
+
+
+
+

4.8.2. Design Consideration

+
+
    +
  • +

    The delete keyword is followed by a TYPE+INDEX parameter.

    +
    +
      +
    • +

      Transaction entries takes in t as its TYPE parameter.

      +
    • +
    • +

      Budget entries takes in b as its TYPE parameter.

      +
    • +
    • +

      Ledger entries takes in l as its TYPE parameter.

      +
    • +
    • +

      Projection entries takes in p as its TYPE parameter.

      +
    • +
    +
    +
  • +
  • +

    The index parameter refers to the entry number within the TYPE entry’s view tab.

    +
  • +
  • +

    Example: delete t5 deletes the 5th entry from the list of transactions if that particular entry exists.

    +
  • +
+
+
+
Aspect: Delete requires TYPE+INDEX as one of its parameter
+
+
    +
  • +

    Alternative 1 (current choice): takes in TYPE+INDEX to decide whether to delete an item from Transaction, Budget, Ledger or Projection list. (e.g. delete b1 deletes item index 1 from budget).

    +
    +
      +
    • +

      Pros: Requires lesser user steps to be taken before executing a delete command.

      +
    • +
    • +

      Cons: Requires four unique lists to be created instead of 1. (e.g. the UniqueTransactionList stores Transaction items and the UniqueBudgetList to store Budget items).

      +
    • +
    • +

      For example, when a new command is executed, we must remember to delete both HistoryManager and VersionedAddressBook.

      +
    • +
    +
    +
  • +
  • +

    Alternative 2: Change to Transaction, Budget, Ledger or Projection mode and keying in only index (e.g. delete 1)

    +
    +
      +
    • +

      Pros: Requires only one unique list required to store all operation types.

      +
    • +
    • +

      Cons: Requires additional user step to switch between modes before executing a updating command.

      +
    • +
    +
    +
  • +
+
+
+
+
+
+

4.9. Update Existing Entry Feature: update

+
+

This feature currently allows users to update Transaction or Budget entries. The user is unable to perform this feature on Ledger operations. The rationale for this will be further explained in Section 4.9.2.2, “Aspect 2: Update can not edit Ledger Operations”. The user is currently unable to perform this feature on Projection operations as it will be further implemented in future updates.

+
+
+

4.9.1. Current Implementation

+
+
    +
  • +

    The update feature is facilitated by the Logic and Model components of the application.

    +
  • +
  • +

    The parameter requirements differs for the type of entry:

    +
    +
      +
    • +

      Transaction type requires at least one of it’s Amount, Description, Date or Category fields to be updated.

      +
    • +
    • +

      Budget type requires at least one of it’s Amount, Date or Category fields to be updated.

      +
    • +
    • +

      Project type requires it’s Date and Category fields to be updated (Future implementation).

      +
    • +
    +
    +
  • +
  • +

    At least one valid parameter must be changed when executing an update command. (i.e. update b1 will result in an error as no fields are being changed).

    +
  • +
+
+
+

Step 1. The user executes update t2 $/200 to update the second entry’s amount, from the transaction list, to $200 .

+
+
+

Step 2. Upon executing the command, LogicManager uses MainParser#parse to parse this input from the user.

+
+
+

Step 3. MainParser determines which command is being executed and creates UpdateCommandParser to further parse the input.

+
+
+

Step 4. UpdateCommandParser parses the argument and checks the validity of arguments. If it is invalid, an exception is thrown. +Else, it returns a UpdateCommand.

+
+
+

Step 5. LogicManager uses UpdateCommand#execute() to update either the Transaction or Budget from their respective unique lists.

+
+
+

Step 6. UpdateCommand#execute() uses the UpdateTransactionDescriptor class to create a new instance of a transaction or budget with the appended variables.

+
+
+

Step 7. Model from UpdateCommand then changes the necessary fields of this entry.

+
+
+

Step 8. UpdateCommand uses Model#commitUserState() to save the latest state of the application. It then +returns a CommandResult to the LogicManager and the result will be displayed to the user.

+
+
+
    +
  • +

    The following activity diagram summarizes what happens when a user executes an update command:

    +
  • +
+
+
+
+UpdateActivityDiagram +
+
Figure 27. Activity Diagram for update
+
+
+
+

4.9.2. Design Considerations

+
+

The update feature allows one or more fields of a Transaction or Budget to be updated. (e.g. update t1 $/2 and update t1 $/2 d/10102019 will both work as intended).

+
+
+

More often than not, users do not need to change an entire Transaction or Budget entry. This will minimize inputs from users if they do not require every single parameters of a Transaction or Budget to be changed.

+
+
+
Aspect 1: Update requires TYPE+INDEX as one of its parameter
+
+
    +
  • +

    Alternative 1 (current choice): takes in TYPE+INDEX to decide whether to update an item from Transaction, Budget or Projection list. (e.g. delete b1 deletes item index 1 from budget).

    +
    +
      +
    • +

      Pros: Requires lesser user steps to be taken before executing an update command.

      +
    • +
    • +

      Cons: Requires 2 unique lists to be utilized instead of 1. (e.g. the UniqueTransactionList stores Transaction items and the UniqueBudgetList to store Budget items).

      +
    • +
    • +

      For example, when a new command is executed, we must remember to update both HistoryManager and VersionedAddressBook.

      +
    • +
    +
    +
  • +
  • +

    Alternative 2: Change to Transaction, Budget or Projection mode and keying in only index (e.g. update 1 ..).

    +
    +
      +
    • +

      Pros: Requires only one unique list required to store all operation types.

      +
    • +
    • +

      Cons: Requires additional user step to switch between modes before executing a updating command.

      +
    • +
    +
    +
  • +
+
+
+
+
Aspect 2: Update can not edit Ledger Operations
+
+
    +
  • +

    Alternative 1 (current choice): Update Command does not work with Ledger operations.

    +
    +
      +
    • +

      Pros: Intuitive implementation and execution for the user.

      +
    • +
    • +

      Cons: Requires excessive user operations.

      +
      +
        +
      • +

        The user has to first delete the Ledger operation that he/she wishes to change, followed by inputting the Ledger operation with the amended fields back into PalPay.

        +
      • +
      +
      +
    • +
    +
    +
  • +
  • +

    Alternative 2: Update Command to also work with Ledger operations.

    +
    +
      +
    • +

      Pros: Requires only one user command to append or change Ledger entries.

      +
    • +
    • +

      Cons: Results in convoluted implementation and user experience. This will also hinder future permeability of the Split feature.

      +
      +
        +
      • +

        Ledger operations such as split includes many repeated fields (i.e. multiple Persons and shares list).

        +
      • +
      • +

        Will require several conditional user inputs to differentiate between the various repeated entities that the user wishes to amend.

        +
      • +
      +
      +
    • +
    +
    +
  • +
+
+
+
+
+

4.9.3. Future Enhancements

+
+
Update feature for Projections
+
+

Currently the update feature has not been implemented for Projection operations. In future iterations of PalPay, the update feature should work seamlessly with Projection operations, similar to that of Transaction and Budget operations

+
+
+

The activity diagram below will provide a visual representation of the possible user routes using the update command after this enhancement has been implemented.

+
+
+
+UpdatefutureActivityDiagram +
+
Figure 28. Activity Diagram for Future update
+
+
+
+
+
+

4.10. Sort Feature: sort

+
+

This feature allows the user to sort their transactions by amount or date, in ascending and descending order.

+
+
+

4.10.1. Current Implementation

+
+

The sort command is facilitated by the Logic and Model components of the application.

+
+
+

The following sequence diagram shows how the sorting of transactions work when the user enters sort date/d.

+
+
+
+SortSequenceDiagram +
+
Figure 29. Sequence Diagram for sort date/d
+
+
+
+

4.10.2. Example of Usage

+
+

Given below is an example usage of how sort behaves at each step.

+
+
+

Step 1. The user launches the application and views an unsorted list of transactions.

+
+
+
+sort dg 1 +
+
Figure 30. Initial State of PalPay
+
+
+

Step 2. The user now executes sort date/d to sort the transactions in the order of descending date.

+
+
+
+sort dg 2 +
+
Figure 31. User Inputs sort date/d
+
+
+

Step 3. Upon executing the command, LogicManager uses MainParser#parse() to parse the input from the user.

+
+
+

Step 4. MainParser determines which command is being used and creates SortCommandParser to further parse the input +from the user.

+
+
+

Step 5. SortCommandParser parses the argument and checks if it is valid. If it is +invalid, SortCommandParser throws an exception and terminates. Else, it returns a SortCommand.

+
+
+

Step 6. LogicManager uses SortCommand#execute() to sort the transactions in the order of descending date.

+
+
+

Step 7. SortCommand uses ModelManager#getBankAccount() to get the current bank account and uses +BankAccount#getTransactionHistory() to get the list of transactions of the user.

+
+
+

Step 8. SortCommand uses SortCommand#sortTransactionHistory() to sort the transactions.

+
+
+

Step 9. SortCommand uses Model#set() to store the sorted transactions and Model#commitUserState() to +save the latest state of the application.

+
+
+

Step 10. SortCommand returns a CommandResult to the LogicManager and the result will be displayed to the user +at the end.

+
+
+
+sort dg 3 +
+
Figure 32. After Sorting of Transactions
+
+
+
+

4.10.3. Design Considerations

+
+
Aspect: Sorting of the Bank Account
+
+
    +
  • +

    Alternative 1 (Current Choice): Creating a comparator for each area to be sorted.

    +
    +
      +
    • +

      Pros: Easy to implement.

      +
    • +
    • +

      Cons: Users can only sort by comparators that have been implemented. +Developers have to create a new comparator class to sort a new area.

      +
    • +
    +
    +
  • +
  • +

    Alternative 2: Users can define the area to be sorted.

    +
    +
      +
    • +

      Pros: Extremely flexible for the users as they are not limited to the number of areas to be sorted.

      +
    • +
    • +

      Cons: Difficult to implement.

      +
    • +
    +
    +
  • +
+
+
+
+
+
+

4.11. Filter Feature: filter

+
+

This feature allows the user to filter the list of transactions by category, description, month and/or year.

+
+
+

4.11.1. Overview

+
+

The FilterCommandParser implements Parser with the following operation:

+
+
+
    +
  • +

    FilterCommandParser#parse(): This operation will take in at least one String input from the user that represents +different fields delimited by a whitespace. All transactions that contains all fields will be displayed in the +transaction tab.

    +
  • +
+
+
+
+

4.11.2. Current Implementation

+
+

The filter command is facilitated by the FilterCommandParser and FilterCommand of the application. +PalPay filters the list of transactions by checking if the specified fields exist in the transaction.

+
+
+

For instance, the command filter c/breakfast m/11 y/2019 would display a list of transactions that were made during +breakfast in November 2019.

+
+
+

The following class diagram depicts the relations of the FilterCommand, FilterCommandParser and its related classes.

+
+
+
+FilterClassDiagram +
+
Figure 33. Class Diagram for Filter
+
+
+

Given below is an example usage scenario and how the filter mechanism behaves at each step.

+
+
+

Step 1. The user launches the application and views an unfiltered list of transactions.

+
+
+

Step 2. The user now executes filter c/breakfast m/11 y/2019 to filter the list of transactions.

+
+
+

Step 3. Upon executing the command, LogicManager uses MainParser#parse() to parse the input from the user.

+
+
+

Step 4. MainParser determines which command is being used and creates FilterCommandParser to further parse +the input from the user.

+
+
+

Step 5. FilterCommandParser parses the argument and checks if category, description, month or year exists. +If all field are not present, FilterCommandParser throws an exception and terminates, as depicted in the following +activity diagram. +Else, it returns a FilterCommand that contains a TransactionPredicate.

+
+
+

Step 6. LogicManager uses FilterCommand#execute() to update the list of transactions that satisfies the +given TransactionPredicate.

+
+
+

Step 7. FilterCommand uses Model#commitUserState() to save the latest state of the application. It then +returns a CommandResult to the LogicManager and the result will be displayed to the user at the end.

+
+
+

Below is an activity diagram shows the process of invoking the filter command.

+
+
+
+FilterActivityDiagram +
+
Figure 34. Activity Diagram for Filter
+
+
+
+
+

4.12. Undo / Redo Command Feature: undo/redo

+
+

4.12.1. Current Implementation

+
+

The undo/redo mechanism is facilitated by VersionedUserState. +It extends UserState with an undo/redo history, stored internally as an userStateList and currentStatePointer. +Additionally, it implements the following operations:

+
+
+
    +
  • +

    VersionedUserState#commit() — Saves the current user state in its history.

    +
  • +
  • +

    VersionedUserState#undo() — Restores the previous user state from its history.

    +
  • +
  • +

    VersionedUserState#redo() — Restores a previously undone user state from its history.

    +
  • +
+
+
+

These operations are exposed in the Model interface as Model#commitUserState(), Model#undoUserState() +and Model#redoUserState() respectively.

+
+
+

Given below is an example usage scenario and how the undo/redo mechanism behaves at each step.

+
+
+

Step 1. The user launches the application for the first time. +The VersionedUserState will be initialized with the initial user state, and the currentStatePointer +pointing to that single user state.

+
+
+
+UndoRedoState0 +
+
Figure 35. Initial State
+
+
+

Step 2. The user executes delete t5 command to delete the 5th transaction in the transaction list. +The delete command calls Model#commitUserState(), causing the modified state of the user state after the +delete t5 command executes to be saved in the userStateList, and the currentStatePointer is shifted +to the newly inserted user state.

+
+
+
+UndoRedoState1 +
+
Figure 36. After delete t1 Command
+
+
+

Step 3. The user executes in $/10 n/Allowance d/07112019 to log a new transaction. +The in command also calls Model#commitUserState(), causing another modified user state to be saved +into the userStateList.

+
+
+
+UndoRedoState2 +
+
Figure 37. After in $/10 n/Allowance d/07112019 Command
+
+
+ + + + + +
+
Note
+
+If a command fails its execution, it will not call Model#commitUserState(), so the user state will +not be saved into the userStateList. +
+
+
+

Step 4. The user now decides that logging the transaction was a mistake, and decides to undo that action by +executing the undo command. The undo command will call Model#undoUserState(), which will shift the +currentStatePointer once to the left, pointing it to the previous user state, and restores the user state +to that state.

+
+
+
+UndoRedoState3 +
+
Figure 38. After undo Command
+
+
+ + + + + +
+
Note
+
+If the currentStatePointer is at index 0, pointing to the initial user state, then there are no previous +user states to restore. The undo command uses Model#canUndoUserState() to check if this is the case. +If so, it will return an error to the user rather than attempting to perform the undo. +
+
+
+

Step 5. The user then decides to execute the command list. +Commands that do not modify the user state, such as list, will usually not call Model#commitUserState(), +Model#undoUserState() or Model#redoUserState(). Thus, the userStateList remains unchanged.

+
+
+
+UndoRedoState4 +
+
Figure 39. After list Command
+
+
+

Step 6. The user executes clear, which calls Model#commitUserState(). +Since the currentStatePointer is not pointing at the end of the userStateList, all user states after +the currentStatePointer will be purged. We designed it this way because it no longer makes sense to redo the +in $/10 n/Allowance d/07112019 command. This is the behavior that most modern desktop applications follow.

+
+
+
+UndoRedoState5 +
+
Figure 40. After clear Command
+
+
+

The following sequence diagram shows how the undo operation works:

+
+
+
+UndoSequenceDiagram +
+
Figure 41. Undo Sequence Diagram
+
+
+ + + + + +
+
Note
+
+The lifeline for UndoCommand should end at the destroy marker (X) but due to a limitation of PlantUML, +the lifeline reaches the end of diagram. +
+
+
+

The redo command does the opposite — it calls Model#redoUserState(), which shifts the currentStatePointer +once to the right, pointing to the previously undone state, and restores the user state to that state.

+
+
+ + + + + +
+
Note
+
+If the currentStatePointer is at index userStateList.size() - 1, pointing to the latest user state, then +there are no undone user states to restore. The redo command uses Model#canRedoUserState() to +check if this is the case. If so, it will return an error to the user rather than attempting to perform the redo. +
+
+
+
Aspect: How Undo and Redo Executes
+
+
    +
  • +

    Alternative 1 (current choice): Saves the entire user state.

    +
    +
      +
    • +

      Pros: Easy to implement.

      +
    • +
    • +

      Cons: May have performance issues in terms of memory usage.

      +
    • +
    +
    +
  • +
  • +

    Alternative 2: Individual command knows how to undo/redo by itself.

    +
    +
      +
    • +

      Pros: Will use less memory (e.g. for delete t1, just save the transaction being deleted).

      +
    • +
    • +

      Cons: We must ensure that the implementation of each individual command are correct.

      +
    • +
    +
    +
  • +
+
+
+
+
Aspect: Which Data Structure to Support the Undo/Redo Commands
+
+
    +
  • +

    Alternative 1 (current choice): Use a list and a pointer to store the history of user states.

    +
    +
      +
    • +

      Pros: Easy for new Computer Science student undergraduates to understand, +who are likely to be the new incoming developers of our project.

      +
    • +
    • +

      Cons: Need to manage the list and pointer carefully as the pointer has to point to the correct position in +the list at all times. +For example, when a new command is executed, we must remember to update both userStateList and currentStatePointer.

      +
    • +
    +
    +
  • +
  • +

    Alternative 2: Use two stacks. One stack stores the commands to undo and the other stores the commands to redo.

    +
    +
      +
    • +

      Pros: Do not need to manage a pointer for the stacks.

      +
    • +
    • +

      Cons: Need to manage both stacks carefully. For instance, when a command is popped from the undo stack, it needs to +be pushed into the redo stack.

      +
    • +
    +
    +
  • +
+
+
+
+
+
+

4.13. Logging

+
+

We are using java.util.logging package for logging. +The LogsCenter class is used to manage the logging levels and logging destinations.

+
+
+
    +
  • +

    The logging level can be controlled using the logLevel setting in the configuration file (See Section 4.14, “Configuration”)

    +
  • +
  • +

    The Logger for a class can be obtained using LogsCenter.getLogger(Class) which will log messages according to the specified logging level

    +
  • +
  • +

    Currently log messages are output through: Console and to a .log file.

    +
  • +
+
+
+

Logging Levels

+
+
+
    +
  • +

    SEVERE : Critical problem detected which may possibly cause the termination of the application

    +
  • +
  • +

    WARNING : Can continue, but with caution

    +
  • +
  • +

    INFO : Information showing the noteworthy actions by the App

    +
  • +
  • +

    FINE : Details that is not usually noteworthy but may be useful in debugging e.g. print the actual list instead of just its size

    +
  • +
+
+
+
+

4.14. Configuration

+
+

Certain properties of the application can be controlled (e.g user prefs file location, logging level) through the configuration file (default: config.json).

+
+
+
+
+
+

5. Documentation

+
+
+

Refer to the guide here.

+
+
+
+
+

6. Testing

+
+
+

Refer to the guide here.

+
+
+
+
+

7. Dev Ops

+
+
+

Refer to the guide here.

+
+
+
+
+

Appendix A: Product Scope

+
+
+

Target user profile:

+
+
+
    +
  • +

    has a need to manage a significant number of transactions

    +
  • +
  • +

    prefer desktop applications over other types

    +
  • +
  • +

    can type fast

    +
  • +
  • +

    prefers typing over mouse input

    +
  • +
  • +

    is reasonably comfortable using CLI apps

    +
  • +
+
+
+

Value proposition: manage contacts faster than a typical mouse/GUI driven app

+
+
+
+
+

Appendix B: User Stories

+
+
+

Priorities: High (must have) - * * *, Medium (nice to have) - * *, Low (unlikely to have) - *

+
+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PriorityAs a …​I want to …​So that I can…​

* * *

data-oriented person

see an overview of my transactions in an intuitive graph

gain insights at a glance

* * *

new user

see usage instructions

refer to instructions when I forget how to use the App

* * *

student

input my spending into different categories

manage my expenses better

* * *

visual person

see how much budget I have left in each category

cut down on spending as necessary

* * *

student with many friends

split the bill with my friends

know how much I should payment for a meal

* * *

student who forgets to payment his debt on time

be reminded to payment my debt before the deadline

stop incurring interests

* *

patriotic Singaporean who travels to JB often

easily calculate how much Ringgit to bring

enjoy my holiday with insufficient money

* *

thrifty person

see how my savings or spending will project into the future

plan my budget

*

user who forgets to save money

be incentivized me to save money

be motivated to not overspend/save money

+
+

{More to be added}

+
+
+
+
+

Appendix C: Use Cases

+
+
+

(For all use cases below, the System is the PalPay and the Actor is the user, unless specified otherwise)

+
+

Use case: Add an income

+
+

MSS

+
+
+
    +
  1. +

    User requests to add an income amount.

    +
  2. +
  3. +

    PalPay adds the income amount.

    +
    +

    Use case ends.

    +
    +
  4. +
+
+
+

Extensions

+
+
+
    +
  • +

    1a. +Amount entered by the user is invalid.

    +
    +
      +
    • +

      1a1. PalPay shows an error message.

      +
      +

      Use case resumes at step 1.

      +
      +
    • +
    +
    +
  • +
+
+

Use case: Delete expense

+
+

MSS

+
+
+
    +
  1. +

    User requests to view spending.

    +
  2. +
  3. +

    PalPay shows the list of expenses since beginning of time.

    +
  4. +
  5. +

    User requests to delete an expense.

    +
  6. +
  7. +

    PalPay deletes the specified expense.

    +
    +

    Use case ends.

    +
    +
  8. +
+
+
+

Extensions

+
+
+
    +
  • +

    1a. +User specified days passed since.

    +
    +
      +
    • +

      1a1. PalPay shows the list of expenses since the time period specified.

      +
      +

      Use case resumes at step 3.

      +
      +
    • +
    +
    +
  • +
+
+
+

{More to be added}

+
+
+
+
+

Appendix D: Non Functional Requirements

+
+
+
    +
  1. +

    Should work on any mainstream OS with JDK 11 or above installed.

    +
  2. +
  3. +

    A user with above average typing speed for regular English text should be able to accomplish most of the tasks faster using commands than using the mouse.

    +
  4. +
  5. +

    Upon user input, PalPay should execute tasks (and display results) within 1 second.

    +
  6. +
  7. +

    Users should have (and be able to specify) default options such that they can issue minimal commands for common tasks.

    +
  8. +
  9. +

    Should be quick and efficient, with each user session lasting no longer than 3 minutes to effectively manage his current financial state.

    +
  10. +
  11. +

    Should not make users feel defeated, but rather empowered in managing their finances.

    +
  12. +
+
+
+
+
+

Appendix E: Glossary

+
+
+
+
API
+
+

Application Programming Interface

+
+
+
+
+
+
Mainstream OS
+
+

Windows, Linux, Unix, OS-X

+
+
+
+
+
+
+

Appendix F: Instructions for Manual Testing

+
+
+

Given below are instructions to test the application manually.

+
+
+ + + + + +
+
Note
+
+These instructions only provide a starting point for testers to work on; testers are expected to do more exploratory testing. +
+
+
+

F.1. Launch and Shutdown

+
+
    +
  1. +

    Initial launch

    +
    +
      +
    1. +

      Download the jar file and copy into an empty folder.

      +
    2. +
    3. +

      Double-click the jar file
      + Expected: Shows the GUI with a set of sample contacts. +The window size may not be optimum.

      +
    4. +
    +
    +
  2. +
  3. +

    Saving window preferences

    +
    +
      +
    1. +

      Resize the window to an optimum size. +Move the window to a different location. +Close the window.

      +
    2. +
    3. +

      Re-launch the app by double-clicking the jar file.
      +Expected: The most recent window size and location is retained.

      +
    4. +
    +
    +
  4. +
+
+
+
+

F.2. Adding an In Transaction

+
+
    +
  1. +

    Adding an in transaction with the command: in

    +
    +
      +
    1. +

      Prerequisites:

      +
    2. +
    3. +

      Test case: in $/1000 n/Allowance d/11112019
      +Expected: An in transaction will be added into the list of transactions in the Transaction tab.

      +
    4. +
    5. +

      Test case: in $/0 n/Allowance d/11112019
      +Expected: No transaction is added. Error details will be shown in the status message.

      +
    6. +
    7. +

      Other incorrect in commands to try: in $/10.001 n/Allowance d/11112019, in $/1000 n/Allow@nce d/11112019 +(Contains non-alphanumeric characters).
      +Expected: Similar to previous.

      +
    8. +
    +
    +
  2. +
+
+
+
+

F.3. Adding an Out Transaction

+
+
    +
  1. +

    Adding an out transaction with the command: out

    +
    +
      +
    1. +

      Prerequisites:

      +
    2. +
    3. +

      Test case: out $/10 n/KFC d/11112019
      +Expected: An out transaction will be added into the list of transactions in the Transaction tab.

      +
    4. +
    5. +

      Test case: out $/0 n/KFC d/11112019
      +Expected: No transaction is added. Error details will be shown in the status message.

      +
    6. +
    7. +

      Other incorrect out commands to try: out $/10.001 n/KFC d/11112019, out $/10 n/KFC d/32112019 +(Date is invalid).
      +Expected: Similar to previous.

      +
    8. +
    +
    +
  2. +
+
+
+
+

F.4. Adding a Budget

+
+
    +
  1. +

    Adding a budget with the command: set

    +
    +
      +
    1. +

      Prerequisites:

      +
    2. +
    3. +

      Test case: set $/1000 c/Shopping d/31122019
      +Expected: A budget will be added into the list of budgets in the Budget tab.

      +
    4. +
    5. +

      Test case: set $/1000 c/Shopping d/01012019
      +Expected: No budget is added. Error details will be shown in the status message.

      +
    6. +
    7. +

      Other incorrect set command to try: set $/-10 c/Shopping d/31122019 (Amount is negative).
      +Expected: Similar to previous.

      +
    8. +
    +
    +
  2. +
+
+
+
+

F.5. Adding a Split Ledger

+
+
    +
  1. +

    Adding a split ledger with the command: split

    +
    +
      +
    1. +

      Prerequisites:

      +
    2. +
    3. +

      Test case: split $/1000 n/Amy n/Betty a/HaiDiLao
      +Expected: An overall ledger with 4 individual ledgers will be added into the list of ledgers in the Ledger tab.

      +
    4. +
    5. +

      Test case: split $/1000 n/Amy n/Betty
      +Expected: No ledger is added. Error details will be shown in the status message.

      +
    6. +
    7. +

      Other incorrect split command to try: split $/1000 n/Amy n/Betty a/HaiDiLao s/1 s/2 s/3 s/4 +(Greater number of shares than number of people).
      +Expected: Similar to previous.

      +
    8. +
    +
    +
  2. +
+
+
+
+

F.6. Adding a Receive Ledger

+
+
    +
  1. +

    Adding a receive ledger with the command: receive

    +
    +
      +
    1. +

      Prerequisites:

      +
    2. +
    3. +

      Test case: receive $/20 n/Albert
      +Expected: An overall ledger with an individual ledger will be added into the list of ledgers in the ledger tab.

      +
    4. +
    5. +

      Test case: receive $/20 n/A|bert
      +Expected: No ledger is added. Error details will be shown in the status message.

      +
    6. +
    7. +

      Other incorrect receive command to try: receive $/20.001 n/Albert (Amount cannot have more than +two decimal places).
      +Expected: Similar to previous.

      +
    8. +
    +
    +
  2. +
+
+
+
+

F.7. Switching Tabs

+
+
    +
  1. +

    Switching tabs with the command: view

    +
    +
      +
    1. +

      Prerequisites:

      +
    2. +
    3. +

      Test case: view budget
      +Expected: Switches to budget tab if user is in another tab. Else, user remains in budget tab.

      +
    4. +
    5. +

      Test case: view budg3t
      +Expected: Remains in current tab. Error details will be shown in the status message.

      +
    6. +
    7. +

      Other incorrect view command to try: view loans (Loans tab does not exist).
      +Expected: Similar to previous.

      +
    8. +
    +
    +
  2. +
+
+
+
+

F.8. Deleting an Entry

+
+
    +
  1. +

    Deleting an entry with the command: delete

    +
    +
      +
    1. +

      Prerequisites:

      +
    2. +
    3. +

      Test case: delete t1
      +Expected: First transaction is deleted from the list. Balance in the footer will be updated.

      +
    4. +
    5. +

      Test case: delete t0
      +Expected: No transaction is deleted. Error details shown in the status message. Balance remains the same.

      +
    6. +
    7. +

      Other incorrect delete commands to try: delete, delete t1000 (When size of the list of transaction +is smaller than 1000).
      +Expected: Similar to previous.

      +
    8. +
    +
    +
  2. +
+
+
+
+

F.9. Updating an Entry

+
+
    +
  1. +

    Updating an entry with the command: update

    +
    +
      +
    1. +

      Prerequisites:

      +
    2. +
    3. +

      Test case: update t1 $/1000
      +Expected: First transaction in the list is updated. Balance will be updated as well.

      +
    4. +
    5. +

      Test case: update t0 $/1000
      +Expected: No transaction is updated. Error details shown in the status message. Balance remains the same.

      +
    6. +
    7. +

      Other incorrect update commands to try: update, update i/Invalid (Invalid prefix).
      +Expected: Similar to previous.

      +
    8. +
    +
    +
  2. +
+
+
+
+

F.10. Sorting the Transactions

+
+
    +
  1. +

    Sorting the transactions with the command: sort

    +
  2. +
+
+
+

Prerequisites:

+
+
+
    +
  1. +

    Test case: sort amount/a
    +Expected: Transaction list will be sorted from smallest amount to greatest amount. Balance remains the same.

    +
  2. +
  3. +

    Test case: sort amount
    +Expected: Transaction list remains unchanged. Error details shown in the status message.

    +
  4. +
  5. +

    Other incorrect sort commands to try: sort, sort date (Order not stated).
    +Expected: Similar to previous.

    +
  6. +
+
+
+
+

F.11. Viewing Help Window

+
+
    +
  1. +

    Requesting help from PalPay

    +
    +
      +
    1. +

      Prerequisites: None

      +
    2. +
    3. +

      Test case: help
      +Expected: A help window pops up that displays the URL of PalPay’s User Guide and a Copy URL button.

      +
    4. +
    +
    +
  2. +
+
+
+
+

F.12. Saving Data

+
+
    +
  1. +

    Dealing with missing/corrupted data files

    +
    +
      +
    1. +

      Delete the file at .\data\bankaccount.json.

      +
    2. +
    +
    +
  2. +
+
+
+
+
+
+ + + diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index f8a1ac72192..30e80e54da6 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -21,6 +21,10 @@ By: `AY1920S1-CS2103T-W12-3` Since: `SEPT 2019` Licence: `MIT` PalPay is for those who *prefer to use a desktop app for managing personal finances*. More importantly, PalPay is *optimized for those who prefer to work with a Command Line Interface* (CLI) while still having the benefits of a Graphical User Interface (GUI). If you can type fast, PalPay can get your finance management tasks done faster than traditional GUI apps. + +.PalPay's Graphical User Interface +image::dg_gui_example.png[] + This User Guide is written for the users of PalPay as an introductory document of the application. You are strongly encouraged to read this document before using the application to enjoy the full functionality of the application. Ready to start your journey to financial freedom? @@ -41,10 +45,9 @@ Example: Typing *`help`* and pressing kbd:[Enter] will open the help window. . Some example commands you can try: * `view transaction` : shows list of your transactions. -* `in $/100 n/mother d/31102019 c/allowance` : adds an income to your personal finance of *100* dollars with -the category *mother* and the description *allowance*. -* `out $/3 n/pie d/19112019 c/food` : adds an expenditure to your personal finance of *3* dollars with -the category *food* and the description *pie*. +* `in $/100 n/allowance d/31102019 c/mother` : adds an allowance from "mother" with value "$100" to PalPay. +* `out $/3 n/pie d/19112019 c/food` : adds an expenditure to your personal finance of "3" dollars with +the category "food" and the description "pie". * `exit` : exits the app . Refer to <> for details of each command. @@ -52,22 +55,48 @@ the category *food* and the description *pie*. [[Features]] == Features -=== Transactions +=== Transaction +The _Transaction_ feature represents the bread and butter logging of incomes and expenditures. +PalPay will tabulate and display the overall balance to give users a better insight on their spending and saving habits. + +_Transactions_ consists of: + +. `in` : logs an income statement +. `out` : logs an expenditure statement === Budgets +The _Budget_ feature represent the budget to be set until a stipulated deadline for a certain category. +As you make transactions of particular category, the budget with the same category will be adjusted accordingly. + +_Budget_ command consists of: -=== Ledgers +. `set` : creates a budget for a category -=== Projections -By using the _Projections_ feature, you can project your: +=== Ledger +The _Ledger_ feature allows you to track outstanding balances when you +split a bill with your friends and when they pay you back. + +_Ledger_ commands consist of: + +. `split` : splits a bill between friends +. `receive` : logs a single payment from a friend + +=== Projection +By using the _Projection_ feature, you can project your: +The _Projection_ feature allows you to project your: . Account Balance . Budget Deficits / Surpluses +_Projection_ commands consist of: + +. `project`: casts and stores a projection of your future balance and budget states +. `display`: renders a graphical depiction of a specified projection + These projections are cast upon a specified `DATE`, and optionally, a specified `CATEGORY`. Upon casting a projection, it is automatically stored and thereafter accessible through the _Projection_ tab via the `view` -command (see <>). +command (see <>). [[Commands]] @@ -88,26 +117,30 @@ Example: If the command specifies `$/AMOUNT n/ITEM`, `n/ITEM $/AMOUNT` is also a * Parameters that need to be concatenated together are represented as `PARAM+PARAM`. + Example: `TYPE+INDEX` refers to joining `TYPE` and `INDEX` together without a space, such as `t1`. -*Parameter Restrictions* : - +[[Parameter-constraints]] +* *Parameter Constraints* : ++ [width="100%",cols="30%,20%,<50%",options="header",] |======================================================================= -| Parameter | Prefix | Restriction +| Parameter | Prefix | Constraints | AMOUNT | $/ | - a valid amount between 0 and 1000000 dollars exclusive + - a valid amount up to 2 decimal places | DATE | d/ |- a valid date with the format DDMMYY in the Gregorian calendar | DESCRIPTION | n/ | - a valid description with alphanumeric chacracters | CATEGORY | c/ | - a valid category with alphanumeric characters without space +| SHARES | s/ | - a valid positive integer | TYPE | | - a valid type containing one character + `t` : Transaction + `b` : Budget + `l` : Ledger + `p` : Projection -| INDEX | | - a valid entry number in the list +| INDEX | | - a valid entry number in the list + + |======================================================================= ==== +// tag::in[] [[In]] === Logging Income : `in` @@ -115,14 +148,12 @@ Have an income that you need to log down? PalPay accepts all income inputs throu ==== Command Syntax -Format: `in $/AMOUNT n/ITEM d/DATE [c/CATEGORY]` +Format: `in $/AMOUNT n/DESCRIPTION d/DATE [c/CATEGORY]...` **** -* `AMOUNT` accepts the value of this income. The `AMOUNT` value must be non-negative, non zero and lesser than 1,000,000. -* `ITEM` accepts the description of this income. -* `DATE` accepts accepts the date of this transaction -* `CATEGORY` accepts the CATEGORY for this income. An in` Transaction can be created without `CATEGORY` inputs. -* `in` updates the Bank Account with a net positive amount (e.g. `in n/work $/1000 d/10102019` will **increase** Bank Acount balance by $1000) + +* `CATEGORY` accepts the categories for this income. An `in` Transaction can be created without `CATEGORY` inputs. +* `in` updates the user's overall balance with a net positive amount (e.g. `in n/work $/1000 d/10102019` will **increase** overall balance by $1000). **** ==== Example Usage @@ -132,17 +163,16 @@ Format: `in $/AMOUNT n/ITEM d/DATE [c/CATEGORY]` in $/120 d/31122019 n/work . Logging income -* Inputs an income of $120 with description set to 'work' and date set on 31/12/2019. -* The income has not utilized the optional `CATEGORY` field. -* Initial balance (red box in Figure 1) has a value of $0. +* Inputs an income of "$120" with description set to "work" and date set on "31/12/2019". +* Initial balance (red box in Figure 1) has a value of "$0". + .Income Logging Example 1 image::in_ug_1.png[] + . Income added -* The income is added to the empty *Transactions* tab. +* The income is added to the _Transaction_ tab. * The added income is given a `GENERAL` category. -* Balance has increased from $0 to $120 (red box in Figure 2). +* Balance has increased from "$0" to "$120" (red box in Figure 2). + .Sample Income 1 Added image::in_ug_2.png[] @@ -152,17 +182,17 @@ image::in_ug_2.png[] in $/500.50 n/allowance d/01012020 c/parents . Logging income -* Inputs an income of $500.50 with description set to 'allowance' and date set on 01/01/2020. -* The income includes `parents` under the `CATEGORY` field. -* Initial balance (red box in Figure 3) has a value of $120. +* Inputs an income of "$500.50" with description set to "allowance" and date set on "01/01/2020". +* The income includes "parents" under the `CATEGORY` field. +* Initial balance (red box in Figure 3) has a value of "$120". + .Income Logging Example 2 image::in_ug_3.png[] + . Income added -* The income is added to the bottom of the *Transactions* tab. -* The added income tagged under `parents` category. -* Balance has increased from $120 to $620.50 (red box in Figure 4). +* The income is added to the bottom of the _Transaction_ tab. +* The added income is tagged under `parents` category. +* Balance has increased from "$120" to "$620.50" (red box in Figure 4). + .Sample Income 2 Added image::in_ug_4.png[] @@ -173,6 +203,10 @@ image::in_ug_4.png[] * `in $/250.50 d/29022020 n/mom c/family` * `in $/120 d/31122019 n/helping friend` +//end::in[] + +//tag::out[] +//tag::out1[] [[Out]] === Logging Expense : `out` @@ -180,41 +214,40 @@ Have you recently made an expenditure that requires logging down? PalPay accepts ==== Command Syntax -Format: `out $/AMOUNT n/ITEM d/DATE [c/CATEGORY]` +Format: `out $/AMOUNT n/DESCRIPTION d/DATE [c/CATEGORY]...` **** -* `AMOUNT` accepts the value of this expenditure. The `AMOUNT` value must be non-negative, non zero and lesser than 1,000,000. * Users should not input negative values into `AMOUNT` (i.e. `out $/-100 ...`) as PalPay has already accounted for the difference between incomes and expenditures. -* `ITEM` accepts the description of this expenditure. -* `DATE` accepts the date of this transaction -* `CATEGORY` accepts the CATEGORY for this expenditure. An `out` Transaction can be created without any `CATEGORY`. -* `out` will update the Bank Account with a net **negative** amount (e.g. `out n/milk $/2 d/10102019` will **decrease** Bank Acount balance by $2) +* `CATEGORY` accepts the categories for this expenditure. An `out` Transaction can be created without any `CATEGORY`. +* `out` updates the user's overall balance with a net **negative** amount (e.g. `out n/milk $/2 d/10102019` will **decrease** overall balance by $2) **** -==== Important Details: +==== Important Details -* Note that `out` transactions differ from `in` transactions in the display amount. The `in` transactions are characterized by the *positive* value within their display box whilst the `out` transactions are characterized by the *negative* values in their display box. The difference can be observed in the example usage below. -* `out` Transaction will affect the remaining amount of `Budget` entries with similar categories within the same time period (Refer to <>). +* Note that `out` _Transactions_ differ from `in` _Transactions_ in the display amount. The `in` entries are characterized by the *positive* value within their display box whilst the `out` entries are characterized by the *negative* values in their display box. The difference can be observed in the example usage below. +* An `out` command will affect the remaining amount of `Budget` entries with similar categories within the same time period (Refer to <>). -==== Example Usage +==== Example Usages + +//end::out1[] ===== Example 1 + out $/5 d/01012020 n/burger . Expenditure logging -* Inputs an expenditure of $5 with description set to 'burger' and date set on 01/01/2020. -* The expenditure has not utilized the optional `CATEGORY` field. -* Initial balance (red box in Figure 5) has a value of $620.50. +* Inputs an expenditure of "$5" with description set to "burger" and date set on "01/01/2020". +* Initial balance (red box in Figure 5) has a value of "$620.50". + .Expenditure Logging Example 1 image::out_ug_1.png[] + . Expenditure added -* The expenditure is added to the bottom of the *Transactions* tab. +* The expenditure is added to the bottom of the _Transaction_ tab. * The amount value of the expenditure box should display a negative value (see Figure 6 entry 3). -* The added expenditure is given a `GENERAL` category. -* Balance has decreased from $620.50 to $615.50 (red box in Figure 6). +* The added expenditure is given a "GENERAL" category. +* Balance has decreased from "$620.50" to "$615.50" (red box in Figure 6). + .Sample Expenditure 1 Added image::out_ug_2.png[] @@ -224,54 +257,55 @@ image::out_ug_2.png[] out $/1000 n/maintenance d/02012020 c/car c/transport . Expenditure logging -* Inputs an expenditure of $1000 with description set to 'maintenance' and date set on 02/01/2020. -* The income includes `car` and `transport` under the `CATEGORY` field. -* Initial balance (red box in Figure 7) has a value of $615.50. +* Inputs an expenditure of "$1000" with description set to 'maintenance' and date set on 02/01/2020. +* The income includes "car" and "transport" under the `CATEGORY` field. +* Initial balance (red box in Figure 7) has a value of "$615.50". + .Expenditure Logging Example 2 image::out_ug_3.png[] + . Expenditure added -* The expenditure is added to the bottom of the *Transactions* tab. +* The expenditure is added to the bottom of the _Transaction_ tab. * The added expenditure is tagged under `car` and `transport` category. -* Balance has decreased from $615.50 to -$384.50 (red box in Figure 8). +* Balance has decreased from "$615.50" to "-$384.50" (red box in Figure 8). * The negative value of the balance indicates that the total spending amount outweighs the total savings amount. + .Sample Expenditure 2 Added image::out_ug_4.png[] +//tag::out2[] [[UG_OUT_EXAMPLE3]] ===== Example 3 out $/100 n/pants d/02012020 c/clothes . Expenditure logging -* Inputs an expenditure of $100 with description set to 'pants' and date set on 02/01/2020. -* The income includes `clothes` under the `CATEGORY` field. +* Inputs an expenditure of "$100" with description set to "pants" and date set on "02/01/2020". +* The income includes "clothes" under the `CATEGORY` field. + .Expenditure Logging Example 3 -image::out_ug_5.png[] +image::out_ug_5.png[pdfwidth=70%] + . Budget with similar categories and time period. -* Entry 3 of the `Budget` tab has `clothes` under its `CATEGORY` field. -* Entry 3 of the `Budget` tab has a deadline set to `01/01/2021`. +* Entry 3 of the _Budget_ tab has `clothes` under its `CATEGORY` field. +* Entry 3 of the _Budget_ tab has a deadline set to "01/01/2021". + .Budget with 'clothes' category -image::out_ug_6.png[] +image::out_ug_6.png[pdfwidth=70%] + . Expenditure added -* The expenditure is added to the bottom of the *Transactions* tab. +* The expenditure is added to the bottom of the _Transaction_ tab. * The added expenditure has a date set to `02/01/2020`. * The added expenditure is tagged under the `clothes` category. + .Sample Expenditure 3 Added -image::out_ug_7.png[] +image::out_ug_7.png[pdfwidth=70%] + . Budget entry updated -* Remaining amount of entry 3 of the `Budget` tab has decreased from $1000 to $900. +* The remaining amount of entry 3 of the _Budget_ tab has decreased from "$1000" to "$900". + .Budget entry updated -image::out_ug_8.png[] +image::out_ug_8.png[pdfwidth=70%] ===== Example Commands: @@ -280,22 +314,34 @@ image::out_ug_8.png[] * `out $/29 d/29022020 n/taxi c/transport` * `out $/12 d/31122019 n/burger` +//end::out2[] + +//end::out[] + +// tag::set[] + [[Set]] + === Setting a Budget : `set` You can set a budget for a particular category until a certain date, given it is not already present in the budget list. A duplicate budget is a budget with the same `AMOUNT` and `DATE` and `CATEGORY`. + If you attempt to do so, you will receive an error message: `This budget already exists`. + -Format: `set $/AMOUNT d/DATE c/CATEGORY` +==== Command Syntax + +Format: `set $/AMOUNT d/DATE [c/CATEGORY]...` **** -* `AMOUNT` input accepts the new budget amount to be set. This amount must be non-negative, non-zero and -less than 1,000,000. +Parameters follow the same restrictions as highlighted in <>. + + +* `AMOUNT` input accepts the budget amount to be set. * `DATE` input accepts the deadline to be set. It cannot be a date in the past. -* `CATEGORY` accepts the CATEGORY for the budget. A budget can be created without `CATEGORY` inputs in which case, the budget will automatically be assigned `GENERAL' category. +* `CATEGORY` accepts the CATEGORY for the budget. +A budget can be created without `CATEGORY` inputs in which case, the budget will automatically be assigned `GENERAL' category. **** +==== Important Details Let's say you want to restrict your spending for a certain category until a certain deadline. PalPay allows you to set a budget and serve as a reminder to show how much of the budget set you have left until the deadline (inclusive). You will be more self-conscious of your spending and minimise your spending by setting a budget. + @@ -306,8 +352,26 @@ To set a new budget: + 3. If the budget already exists in the budget list, the result box will display the message `This budget already exists`. + 4. Now you can see the newly set budget in the budget list. -As you make an *OutTransaction* of a particular `CATEGORY`, your budgets with the same `CATEGORY` will be adjusted -to display the remaining amount of budget. Other budgets in the list belonging to different `CATEGORY` will not be adjusted. +As you log an expenditure of a particular `CATEGORY`, your budgets with the same `CATEGORY` will be adjusted +to display the remaining amount of budget. Other budgets in the list belonging to different `CATEGORY` will not be adjusted. + + +For example, you went out with your friends and bought a cup of Gong Cha. +Before you log your spending, your budget list looks like this: + +.Budget List before Executing OutTransaction +image::approachingBudget.png[] + +You then type in the command `out $/5 c/BBT c/friends n/gong cha d/11112019`. + +.New OutTransaction Command +image::newOutTransaction.png[] + +Your budget list now shows the updated budgets. Observe how Budget 3 is not affected because it does not belong to the relevant *category*. + +.Updated Budget List +image::budgetAffected.png[] + + Budget will not take into consideration past *OutTransaction* when calculating the remaining budget. Remember, you are setting a budget from TODAY till the stated `DATE` (inclusive)! + @@ -328,7 +392,7 @@ Examples: * `set $/100 d/010120120 c/BBT` * `set $/300 d/29022020 c/shopping` - +// end::set[] // tag::split[] @@ -339,29 +403,31 @@ Split a bill with your friends + Format: `split $/AMOUNT n/NAME1 a/DESCRIPTION [d/DATE] [n/NAME2]... [s/SHARE]...` ==== -* `DESCRIPTION` encompasses more details for the bill being split. User can make use of this -field to determine nature of bill. +* `DESCRIPTION` is prefixed with `a/`, unlike for other commands * `[SHARE]` defines portion of bill to be paid by each person -** if no shares are given, `amount` will be split evenly across all people, including user -** user is included in the bill if number of shares is *1* more than number of people -*** user's share will be the first listed share +** if no shares are given, `AMOUNT` will be split evenly across all people, including user +** you are included in the bill if number of shares is *1* more than number of people +*** your share of the bill will be the first listed share ** each person's share is assigned in order *** i.e. last person's share is the last share listed -** shares cannot be negative numbers ==== +CAUTION: Shares can be 0 but result is not guaranteed to be meaningful + ===== Ledger GUI .Sample Ledger Graphical User Interface -image::LedgerUI.png[] +image::LedgerUI.png[pdfwidth=60%] -This is how the *Ledger* looks when you switch to the *Ledger* tab. + +This is how the _Ledger_ looks when you switch to the splits tab. + The left shows the people who has unresolved balances with you, while the right lists -all transactions that have to do with the *Ledger*. + -*Ledger*'s balance is separate from the *BankAccount*. It is displayed in the same position, +all transactions that have to do with the _Ledger_. + +_Ledger_'s balance is separate from PalPay's balance. It is displayed in the same position, at the bottom right corner. -==== Example Usage: +NOTE: `split` *does not* include how much you spent into the _Ledger_ balance. + +==== Example Usage * `split $/1000 n/Amy n/Betty n/Catherine n/Dan a/haidilao` @@ -369,17 +435,17 @@ at the bottom right corner. . Enter appropriate command into the command line. + -.Splitting evenly -image::SplitEven1.png[] +.Input for Splitting Evenly +image::SplitEven1.png[pdfwidth=60%] + . Result is displayed accordingly + -.Splitting evenly (result) -image::SplitEven2.png[] +.Amy, Betty, Catherine and Dan owes $200 each +image::SplitEven2.png[pdfwidth=60%] + -For an even split of $1000, each person pays $200. Therefore *Ledger* shows $200 on the tab of each person. -*Ledger* balance does not include the amount spent by the user. In this bill, the user is owed $800 in total -from the rest of his friends. Therefore *Ledger* balance is -$800, as shown in the bottom right. +For an even split of $1000, each person pays $200. Therefore _Ledger_ shows $200 on the tab of each person. +_Ledger_ balance *does not* include how much you spend. In this bill, one is owed $800 in total +from the rest of his friends. Therefore _Ledger_ balance is -$800, as shown in the bottom right. * `split $/100 n/Albert n/Bernard n/Clement s/2 s/1 s/7 a/kbbq dinner` @@ -387,23 +453,25 @@ from the rest of his friends. Therefore *Ledger* balance is -$800, as shown in t . Enter appropriate command into the command line. + -.Splitting unevenly -image::SplitUneven1.png[] +.Input for Splitting Unevenly +image::SplitUneven1.png[pdfwidth=60%] + . Result is displayed accordingly + -.Uneven split results -image::SplitUneven2.png[] +.Display of Correctly Assigned Amounts +image::SplitUneven2.png[pdfwidth=60%] ++ +Since the number of shares is equal to the number of people listed, you are not included in the splitting of the bill. // end::split[] // tag::receive[] [[Receive]] === Receiving Money from a Friend : `receive` -Receives money from 1 friend + +Receives money from a friend + Format: `receive $/AMOUNT n/NAME1 [d/DATE] [a/DESCRIPTION]` -==== Example usage: +==== Example Usage * `receive $/20 n/Albert` @@ -411,17 +479,18 @@ Format: `receive $/AMOUNT n/NAME1 [d/DATE] [a/DESCRIPTION]` . Enter appropriate command into the command line. + -.Receive payment -image::Receive1.png[] +.Input for Receiving $20 from Albert +image::Receive1.png[pdfwidth=60%] + . Result is displayed accordingly. + -.Receive payment result -image::Receive2.png[] +.Result of Payment from Albert +image::Receive2.png[pdfwidth=60%] + -Albert is removed from the *Ledger* since he no longer owes any money. *Ledger* balance is also updated accordingly. +Albert is removed from the _Ledger_ since he no longer owes any money. _Ledger_ balance is also updated accordingly. //end::receive[] +//tag::project[] [[Project]] === Projecting Future Balance and Budgets : `project` @@ -433,7 +502,7 @@ Format: `project d/DATE [c/CATEGORY]` If a `CATEGORY` is not specified, it will be set as `GENERAL` by default. `GENERAL` projections project upon *ALL* transactions, regardless of their categories. -==== Example Usage: +==== Example Usage . `project d/22072020` @@ -497,31 +566,94 @@ image::project3.png[] .The project earlier seen in <> has been automatically deleted. image::project4.png[] +===== Valid Budget Start Dates and Deadlines +A projection will only project upon budgets with deadlines set before or equal to the projection `DATE`. An example +is depicted below: + +. Suppose there is currently a general _Budget_ with a deadline set for 28th November 2019 ++ +.Two _Budgets_ with dates 20112019 and 28112019 in the "GENERAL" category +image::project5.png[] ++ + +. If a general _Projection_ is cast to 20th November 2019, it will contain +the _Budget_ with deadline 20112019 but not 28112019, +since the projection's `DATE` is earlier than 28112019. + ++ +.The _Projection_ only contains the _Budget_ with deadline 20112019 +image::project6.png[] + +===== Backward Projections +While it is possible in PalPay, projecting your balance amount backwards in time is not guaranteed to +produce sensible results. It is generally not advisable to do so. +//end::project[] + +[[Display]] +// tag::display1[] === Display a Projection Graph: `display` -Display a graphical representation of a `projection` in a new window. +Display a graphical representation of a _Projection_ in a new window. Format: `display PROJECTION_ID` ==== Example Usage -. Type *display PROJECTION_ID* into the command box and press kbd:[Enter]. +. Type *display PROJECTION_ID* into the command box and press kbd:[Enter]. For instance: + -image::display1.png[] +**** +display p1 +**** + . A new window containing a graphical representation of the specified projection will pop up. + -image::display2.png[] +image::display2.png[pdfwidth=50%] + If there are any budgets associated with the projection, a corresponding graphical representation of the budget will be additionally displayed. + image::display3.png[] -+ +==== Interpreting the Projection graph +// end::display1[] + +Here is a typical projection graph. + +.A typical projection graph +image::project7.png[] + +// tag::display2[] + +* *The X-Axis* + +The X-Axis denotes your balance in dollars ($). + +* *The Y-Axis* + +The Y-Axis denotes the number of days from now, with today being Y = 0. + +* *Red Points* + +The red points on the graph each represent your account balance (denoted by the X-value) +at a particular point of time (denoted by the Y-value). + +* *Blue Line Graph* + +The blue line graph represents the projection line, with each point along it representing +a prediction of your account balance (denoted by the X-value) +at a certain point of time (denoted by the Y-value). + +* *All Other Coloured Line Graphs* + +All other coloured line graphs represent various budgets which fall within the `CATEGORY` and `DATE` range +of the `PROJECTION`. Each of these line graphs have three parts: +**** +.A budget line graph with its parts labelled by a green, blue and yellow box each +image::project8.png[] +. The line in the green box denotes the budget amount in dollars ($). + +. The line in the blue box denotes the budget's duration lifetime in days. + +. The line in the yellow box denotes the budget's projected deficit or surplus. +**** ==== Usage Constraints -===== Valid Projection ID +===== Valid Projection Index * A `Projection` with `PROJECTION_ID` must exist. Attempting to display a non-existent `PROJECTION` will result in the following error message: **** @@ -536,6 +668,8 @@ graph is open, lest the behaviour of PalPay become unpredictable. + Consequently, a `display` command should *ALWAYS* be followed by closing the projection graph window, before any other actions are performed within _PalPay_. +// end::display2[] + [[View]] // tag::view[] === Switching Tabs : `view` @@ -550,22 +684,26 @@ Format: `view TAB` * `TAB` input only accepts `transaction`, `budget`, `ledger` and `projection` in v1.4. It is case-insensitive. **** -==== Example Usage: +==== Example Usage You do not have to use your mouse in PalPay to switch tabs anymore. . By default, you are in the `transaction` tab. + +.Transaction Tab image::view1.png[] + . Simply type *view budget* in the command box and press kbd:[Enter]. + +.User Input image::view2.png[] + . You can now view your budgets. Easy! + +.Budget Tab image::view3.png[] +// end::view[] [[Delete]] // tag::delete[] @@ -579,31 +717,33 @@ Deletes the specified Transaction, Budget, Ledger or Projection from PalPay. + Format: `delete TYPE+INDEX` **** -* `INDEX` refers to the target item number. (Items are sorted starting from the **latest** input added). -* `TYPE` accepts either `t` (Transaction), `b` (Budget), `l` (Ledger) or `p` (Projection). (e.g. `delete b1` refers to deleting a *Budget* of index 1). +* `TYPE` accepts either `t` (Transaction), `b` (Budget), `l` (Ledger) or `p` (Projection). (e.g. `delete b1` refers to deleting a _Budget_ of index 1). * `TYPE+INDEX` requires the TYPE and INDEX to be placed in sequential order (e.g. `delete b 1` or `delete 1` or `delete 1b` will not work). -* You can only delete an existing transaction or budget. Nothing will be deleted if the transaction or budget of `INDEX` does not exists. * Example: `delete t1` will delete the first transaction from the list of transactions. **** -==== Important Details: +==== Important Details -PalPay deletes items based on the entry index of the target item. You can only delete a maximum of 1 entry per command. (i.e. `delete t1 t2 b1` or `delete t1 t2` will not work) +* PalPay deletes an item based on the entry index of the target item. You can delete a maximum of 1 entry per command. (i.e. `delete t1 t2 b1` or `delete t1 t2` will not work) +* You can only delete an existing _Transaction_ or _Budget_. Nothing will be deleted if the _Transaction_ or _Budget_ index does not exists. -==== Example Usage: +==== Example Usage Deleting the 5th entry of the transactions list . Note the index of the entry you want to delete. In this example, *entry 5* is the field we will be deleting. + +.Delete Transaction Command image::delete_ug_1.png[] + -. Since we are deleting a *Transaction* entry of index 5, we will input `t` into our `TYPE` field and `5` into our `INDEX` field. +. Since we are deleting a _Transaction_ entry of index 5, we will input "t" into our `TYPE` field and "5" into our `INDEX` field. + +.Delete Transaction Input image::delete_ug_2.png[] + . Success message will be displayed upon successful deletion. + +.Delete Transaction Successful image::delete_ug_3.png[] ===== Example Commands: @@ -613,7 +753,13 @@ image::delete_ug_3.png[] * `delete l2` * `delete p4` +//end::delete[] + [[Update]] + +//tag::update[] +//tag::update1[] + === Updating Finance : `update` Did you make a mistake in one of your entries? Perhaps you over counted that expenditure you made. PalPay provides you with an `update` feature which helps you change specific fields within your entries. @@ -622,94 +768,108 @@ Did you make a mistake in one of your entries? Perhaps you over counted that exp The `update` feature has different implementations for different entry types. The conditions for the `update` feature is as follows. -Format (Transactions): `update TYPE+INDEX [$/AMOUNT] [d/DATE] [n/ITEM] [c/CATEGORY]` + +Format (Transactions): `update TYPE+INDEX [$/AMOUNT] [d/DATE] [n/ITEM] [c/CATEGORY]...` + -Format (Budget): `update TYPE+INDEX [$/AMOUNT] [d/DATE] [c/CATEGORY]` + +Format (Budget): `update TYPE+INDEX [$/AMOUNT] [d/DATE] [c/CATEGORY]...` + Format (Ledger): Cannot be updated + Format (Projections): Cannot be updated **** -* `AMOUNT` accepts a non-negative, non zero value lesser than 1,000,000. -* `ITEM` accepts the description of this entry. -* `DATE` accepts the date of this entry. -* `CATEGORY` accepts the CATEGORY for the entry. * At least one `AMOUNT`, `DATE`, `ITEM` or `CATEGORY` fields must be entered. You can input more than 1 of the mentioned fields (e.g. `update t1 $/100 n/milk`). -* `INDEX` refers to the target item number. (Items are sorted starting from the **latest** input added). -* `TYPE` only accepts either `t` (Transaction) or `b` (Budget). (e.g. `update t1 ..` refers to updating a *Transaction* of index 1). +* `TYPE` only accepts either `t` (_Transaction_) or `b` (_Budget_). (e.g. `update t1 ..` refers to updating a _Transaction_ of index 1). * `TYPE+INDEX` requires the TYPE and INDEX to be placed in sequential order (e.g. `update b 1 ..` or `update 1 ..` or `update 1b ..` will not work). -* You can only update an existing transaction, budget or projection. Nothing will be updated if the entry of index `INDEX` does not exists. -* Example: `update t1 $/3000 d/10102019` will update the first transaction from the list of transactions by changing it's *Amount* to $1000 and *Date* to 10/10/2019. +* Example: `update t1 $/3000 d/10102019` will update the first transaction from the list of transactions by changing it's `AMOUNT` to "$1000" and `DATE` to "10/10/2019". **** -==== Important Details: +==== Important Details * `update` requires at least one field to be updated. (e.g. `update t1 $/20 d/10102019 n/milk` and `update t1 $/10` will both be accepted). +* You can only update an existing transaction, budget or projection. Nothing will be updated if the entry of "index" `INDEX` does not exists. * `Ledger` and `Projection` do not have an update function. If you need to change specific fields within a ledger or projection entry, you should delete the target entry and recreate a new entry with your desired fields. -* You cannot change an `in` Transaction to an `out` Transaction or vice versa. -* Changing an expenditure's (`out` Transaction) category field to that of a Budget's entry will reflect changes on that particular Budget entry as well. (Further explained in <>) +* You cannot change an `in` _Transaction_ to an `out` _Transaction_ or vice versa. +* Changing an expenditure's (`out` _Transaction_) category field to that of a Budget's entry will reflect changes on that particular Budget entry as well. (Further explained in *Example 3* below). + +[NOTE] +Changing the *categories* of an `out` _Transaction_ entry with similar categories to that of a _Budget_ entry will reflect changes on the budget's remaining amount in version 2.0. + +//end::update1[] [NOTE] -Changing the categories of an `out` Transaction entry with similar categories to that of a `Budget` entry to reflect changes on the budget's remaining amount will be incoming in version 2.0. +Changing an expenditure's (`out` _Transaction_) *date* field to a date within the date period of a _Budget_ entry will reflect changes on the budget's remaining amount in version 2.0. ==== Example Usage ===== Example 1: -Updating a *Transaction* entry. +Updating a _Transaction_ entry. -. Identify the index number of the entry you want to edit. In this case, we will be using entry 3. +. Identify the *index number* of the entry you want to edit. In this case, we will be using entry 3. + +.Transaction List Containing Entry 3 image::update_ug_1.png[] + -. Put `t` as your `TYPE` input and key in the fields you want to change. In this case, we will only be changing the amount of the transaction. +. Put "t" as your `TYPE` input and key in the fields you want to change. In this case, we will only be changing the `AMOUNT` of the transaction. + +.User Input for the Update Example 1 image::update_ug_2.png[] + . Success message will be displayed upon successful update. Fields will now be updated accordingly. + +.Success Message for the Update Example 1 image::update_ug_3.png[] ===== Example 2: -Updating a *Budget* entry. +Updating a _Budget_ entry. -. Identify the index number of the entry you want to edit +. Identify the *index number* of the entry you want to edit + +.Budget Tab Containing Entry 1 image::update_ug_4.png[] + -. Put `b` as your `TYPE` input and key in the fields you want to change. In this case, we will be changing both the date and amount of this Budget. +. Put "b" as your `TYPE` input and key in the fields you want to change. In this case, we will be changing both the `DATE` and `AMOUNT` of this _Budget_. +When you update the amount of a budget, the budget will be re-initialised. + +.User Input for the Update Example 2 image::update_ug_5.png[] + . Success message will be displayed upon successful update. Fields will now be updated accordingly. + +.Success Message for the Update Example 2 image::update_ug_6.png[] [[UG_UPDATE_EXAMPLE_3]] ===== Example 3: -Updating a *Transaction* entry which has the same category field as a *Budget* entry. +Updating a _Transaction_ entry which has the same category field as a _Budget_ entry. -. Identify the index number of the *Transaction* entry you want to edit. +. Identify the *index number* of the _Transaction_ entry you want to edit. + -image::update_ug_7.png[] +.Transaction Sharing a Category with a Budget +image::update_ug_7.png[pdfwidth=70%] + -. Notice that a *Budget* entry has the same category field as the *Transaction* entry mentioned above. (*Budget* entry 2). +. Notice that a _Budget_ entry has the same `CATEGORY` field as the _Transaction_ entry mentioned above. (_Budget_ entry 2). + -image::update_ug_8.png[] +.Budget Sharing a Category with the Target Transaction +image::update_ug_8.png[pdfwidth=70%] + -. Put `t` as your `TYPE` input and key in the fields you want to change. In this case, we will be changing only the amount of this *Transaction*. +. Put "t" as your `TYPE` input and key in the fields you want to change. In this case, we will be changing only the `AMOUNT` of this _Transaction_. + -image::update_ug_9.png[] +.User Input for the Update Example 3 +image::update_ug_9.png[pdfwidth=70%] + -. Success message will be displayed upon successful update. Fields of the *Transaction* entry will now be updated accordingly. +. Success message will be displayed upon successful update. Fields of the _Transaction_ entry will now be updated accordingly. + -image::update_ug_10.png[] +.Success Message for the Update Example 3 +image::update_ug_10.png[pdfwidth=70%] + -. Remaining amount of the *Budget* entry will also be updated accordingly. +. Remaining amount of the _Budget_ entry will also be updated accordingly. + -image::update_ug_11.png[] +.Automatic Update of Relevant Budget +image::update_ug_11.png[pdfwidth=70%] + +//tag::update2[] ===== Example Commands: @@ -717,6 +877,9 @@ image::update_ug_11.png[] * `update b2 $/300` * `update t4 $/30 d/12102019` +//end::update2[] +//end::update[] + [[Sort]] // tag::sort[] === Sorting Transactions : `sort` @@ -735,7 +898,7 @@ Format: `sort PREDICATE/ORDER` * `ORDER` accepts only `a` or `d` which represents ascending and descending, respectively. **** -==== Example Usage: +==== Example Usage Do you want to know what is the latest transaction you made? No need to scroll all the way down anymore. PalPay has made it simple for you. @@ -743,14 +906,17 @@ has made it simple for you. . By default, your transactions are sorted from the earliest transaction you entered to the latest transaction you entered. + +.Unsorted Transaction List image::sort1.png[] + . Simply type *sort date/d* in the command box and press kbd:[Enter]. + +.User Input for Sort Command image::sort2.png[] + . Great! You can now see the latest transactions you made. + +.Sorted Transaction List image::sort3.png[] // end::sort[] @@ -776,20 +942,23 @@ Format: `filter [n/DESCRIPTION] [y/YEAR] [m/MONTH] [c/CATEGORY]...` `transport` and `allowance` that occurred in 2019. **** -==== Example Usage: +==== Example Usage Imagine that you wanted to find out what you spent on shopping in October 2019. . By default, PalPay shows your all your transactions you have made. + +.Unfiltered Transaction List image::filter1.png[] + . Simply type *filter c/Shopping m/10 y/2019* in the command box and press kbd:[Enter]. + +.User Input for Filter Command image::filter2.png[] + . You will now see the list of transactions you have made while shopping in October 2019. Hurray! + +.Filtered Transaction List image::filter3.png[] // end::filter[] @@ -812,7 +981,7 @@ Format: `undo` `sort` / `filter` / `update` / `delete` / `clear` / `list` **** -==== Example Usage: +==== Example Usage Suppose you want to update your allowance you received in October 2019 to $800 but you accidentally update the GrabTaxi ride instead. Without going through the trouble of updating the same transaction again, you can simply perform the @@ -820,14 +989,17 @@ ride instead. Without going through the trouble of updating the same transaction . Here, you can see the wrong update you just made. + +.Transaction List Containing Erroneous Transaction image::undo1.png[] + . Simply type *undo* in the command box and press kbd:[Enter]. + +.User Input for Undo Command image::undo2.png[] + . As you wish, your command has been undone. + +.Erroneous Transaction Has Been Undone image::undo3.png[] // end::undo[] @@ -846,21 +1018,24 @@ Format: `redo` * Once you exit PalPay, you cannot redo the previous undo(s). **** -==== Example Usage: +==== Example Usage Suppose you want to undo your last update but you accidentally undo twice instead. You can simply perform the `redo` command to revert the changes. Just follow these three simple steps. . Here, you can see the extra undo you just made and the GrabTaxi ride is back at $800. + +.Transaction List Containing Erroneous Transaction image::redo1.png[] + . Simply type *redo* in the command box and press kbd:[Enter]. + +.User Input for Redo Command image::redo2.png[] + . Great! Your transaction is back to normal. + +.Success Message for Redo Command image::redo3.png[] // end::redo[] @@ -922,14 +1097,16 @@ There is no need to save manually. Example: `in $/100 n/allowance d/11112019 c/income` * <> : `out $/AMOUNT n/ITEM d/DATE [c/CATEGORY]` + Example: `out $/20 n/coke d/19112019 c/drink c/lunch` -* <> : `set $/AMOUNT d/DATE c/CATEGORY` + +* <> : `set $/AMOUNT d/DATE [c/CATEGORY]...` + Example: `set $/100 d/10102019 c/food` -* <> : `split $/AMOUNT n/NAME1 [n/NAME2]... [s/SHARE]...` + -Example: `split $/100 n/Albert n/Bernard n/Clement s/2 s/1 s/7` +* <> : `split $/AMOUNT n/NAME1 a/DESCRIPTION [d/DATE] [n/NAME2]... [s/SHARE]...` + +Example: `split $/1000 n/Amy n/Betty n/Catherine n/Dan a/HaiDiLao` * <> : `receive $/AMOUNT n/NAME` + Example: `receive $/20 n/Albert` -* <> : `project DURATION` + -Example: `project d/22072020` +* <> : `project DATE CATEGORY` + +Example: `project d/22072020 c/Food` +* <> : `display PROJECTION_ID` + +Example: `project p1` * <> : `view TAB` + Example: `view transaction` * <> : `delete TYPE+INDEX` + diff --git a/docs/UserGuide.html b/docs/UserGuide.html new file mode 100644 index 00000000000..5f74f37986c --- /dev/null +++ b/docs/UserGuide.html @@ -0,0 +1,2612 @@ + + + + + + + +PalPay - User Guide + + + + + +
+ +
+

1. Introduction

+
+
+

PalPay is for those who prefer to use a desktop app for managing personal finances. +More importantly, PalPay is optimized for those who prefer to work with a Command Line Interface (CLI) while still having the benefits of a Graphical User Interface (GUI). +If you can type fast, PalPay can get your finance management tasks done faster than traditional GUI apps.

+
+
+
+dg gui example +
+
Figure 1. PalPay’s Graphical User Interface
+
+
+

This User Guide is written for the users of PalPay as an introductory document of the application. +You are strongly encouraged to read this document before using the application to enjoy the full functionality of the application. +Ready to start your journey to financial freedom? +Jump to Section 2, “Quick Start” to get started. +Enjoy!

+
+
+
+
+

2. Quick Start

+
+
+
    +
  1. +

    Ensure you have Java 11 or above installed in your Computer.

    +
  2. +
  3. +

    Download the latest PalPay.jar here.

    +
  4. +
  5. +

    Copy the file to the folder you want to use as the home folder for your finance manager.

    +
  6. +
  7. +

    Double-click the file to start the app. +The GUI should appear within a few seconds.

    +
  8. +
  9. +

    Type your command in the command box and press Enter to execute it.
    +Example: Typing help and pressing Enter will open the help window.

    +
  10. +
  11. +

    Some example commands you can try:

    +
    +
      +
    • +

      view transaction : shows list of your transactions.

      +
    • +
    • +

      in $/100 n/mother d/31102019 c/allowance : adds an income to your personal finance of 100 dollars with +the category mother and the description allowance.

      +
    • +
    • +

      out $/3 n/pie d/19112019 c/food : adds an expenditure to your personal finance of 3 dollars with +the category food and the description pie.

      +
    • +
    • +

      exit : exits the app

      +
    • +
    +
    +
  12. +
  13. +

    Refer to Section 4, “Commands” for details of each command.

    +
  14. +
+
+
+
+
+

3. Features

+
+
+

3.1. Transaction

+
+

The Transaction feature represents the bread and butter logging of incomes and expenditures. +PalPay will tabulate and display the overall balance to give users a better insight on their spending and saving habits.

+
+
+

The Transactions are split into:

+
+
+
    +
  1. +

    in : income

    +
  2. +
  3. +

    out : expenditure

    +
  4. +
+
+
+

These transactions requires the mandatory AMOUNT, DATE and DESCRIPTION fields to be filled. Additionally, The transactions can take in one or more CATEGORY tags.

+
+
+
+

3.2. Budget

+ +
+
+

3.3. Ledger

+
+

The Ledger feature allows you to track outstanding balances when you +split a bill with your friends and when they pay you back.

+
+
+

Ledger commands consist of:

+
+
+
    +
  1. +

    split : split a bill between friends

    +
  2. +
  3. +

    receive : log a single payment from 1 friend

    +
  4. +
+
+
+
+

3.4. Projection

+
+

By using the Projections feature, you can project your:

+
+
+
    +
  1. +

    Account Balance

    +
  2. +
  3. +

    Budget Deficits / Surpluses

    +
  4. +
+
+
+

These projections are cast upon a specified DATE, and optionally, a specified CATEGORY. Upon casting a +projection, it is automatically stored and thereafter accessible through the Projection tab via the view +command (see View).

+
+
+
+
+
+

4. Commands

+
+
+
+
+

Command Format :

+
+
+
    +
  • +

    Words in UPPER_CASE are the parameters to be supplied by the user.
    +Example: For in $/AMOUNT n/ITEM d/DATE, AMOUNT, ITEM and DATE are parameters which can be used as +in $/300 n/concert d/19112019.

    +
  • +
  • +

    Items in square brackets are optional.
    +Example: n/ITEM [c/CATEGORY] can be used as n/coke c/drinks or as n/coke.

    +
  • +
  • +

    Items with …​ after them can be used multiple times including zero times.
    +Example: [n/NAME]…​ can be used as   (i.e. 0 times), n/Amy, n/Amy n/Betty etc.

    +
  • +
  • +

    Parameters can be in any order.
    +Example: If the command specifies $/AMOUNT n/ITEM, n/ITEM $/AMOUNT is also acceptable.

    +
  • +
  • +

    Parameters that need to be concatenated together are represented as PARAM+PARAM.
    +Example: TYPE+INDEX refers to joining TYPE and INDEX together without a space, such as t1.

    +
  • +
+
+
+
    +
  • +

    Parameter Constraints :

    + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ParameterPrefixConstraints

    AMOUNT

    $/

    - a valid amount between 0 and 1000000 dollars exclusive
    +- a valid amount up to 2 decimal places

    DATE

    d/

    - a valid date with the format DDMMYY in the Gregorian calendar

    DESCRIPTION

    n/

    - a valid description with alphanumeric chacracters

    CATEGORY

    c/

    - a valid category with alphanumeric characters without space

    TYPE

    - a valid type containing one character
    +t : Transaction
    +b : Budget
    +l : Ledger
    +p : Projection

    INDEX

    - a valid entry number in the list

    +
  • +
+
+
+
+
+

4.1. Logging Income : in

+
+

Have an income that you need to log down? PalPay accepts all income inputs through the in command. Inputting an in command will increase the overall balance value. Your income statements have the added option to be tagged under one or more categories. You can do so by including the [c/CATEGORY] parameter in your command line. All uncategorized incomes will be tagged under the GENERAL category.

+
+
+

4.1.1. Command Syntax

+
+

Format: in $/AMOUNT n/DESCRIPTION d/DATE [c/CATEGORY]…​

+
+
+
+
+
    +
  • +

    CATEGORY accepts the categories for this income. An in Transaction can be created without CATEGORY inputs.

    +
  • +
  • +

    in updates the user’s overall balance with a net positive amount (e.g. in n/work $/1000 d/10102019 will increase overall balance by $1000).

    +
  • +
+
+
+
+
+
+

4.1.2. Example Usage

+
+
Example 1
+
+
+
in $/120 d/31122019 n/work
+
+
+
+
    +
  1. +

    Logging income

    +
    +
      +
    • +

      Inputs an income of $120 with description set to 'work' and date set on 31/12/2019.

      +
    • +
    • +

      The income has not utilized the optional CATEGORY field.

      +
    • +
    • +

      Initial balance (red box in Figure 1) has a value of $0.

      +
      +
      +in ug 1 +
      +
      Figure 2. Income Logging Example 1
      +
      +
    • +
    +
    +
  2. +
  3. +

    Income added

    +
    +
      +
    • +

      The income is added to the empty Transactions tab.

      +
    • +
    • +

      The added income is given a GENERAL category.

      +
    • +
    • +

      Balance has increased from $0 to $120 (red box in Figure 2).

      +
      +
      +in ug 2 +
      +
      Figure 3. Sample Income 1 Added
      +
      +
    • +
    +
    +
  4. +
+
+
+
+
Example 2
+
+
+
in $/500.50 n/allowance d/01012020 c/parents
+
+
+
+
    +
  1. +

    Logging income

    +
    +
      +
    • +

      Inputs an income of $500.50 with description set to 'allowance' and date set on 01/01/2020.

      +
    • +
    • +

      The income includes parents under the CATEGORY field.

      +
    • +
    • +

      Initial balance (red box in Figure 3) has a value of $120.

      +
      +
      +in ug 3 +
      +
      Figure 4. Income Logging Example 2
      +
      +
    • +
    +
    +
  2. +
  3. +

    Income added

    +
    +
      +
    • +

      The income is added to the bottom of the Transactions tab.

      +
    • +
    • +

      The added income tagged under parents category.

      +
    • +
    • +

      Balance has increased from $120 to $620.50 (red box in Figure 4).

      +
      +
      +in ug 4 +
      +
      Figure 5. Sample Income 2 Added
      +
      +
    • +
    +
    +
  4. +
+
+
+
+
Example Commands:
+
+
    +
  • +

    in $/100 d/01012019 n/errand c/work c/company

    +
  • +
  • +

    in $/250.50 d/29022020 n/mom c/family

    +
  • +
  • +

    in $/120 d/31122019 n/helping friend

    +
  • +
+
+
+
+
+
+

4.2. Logging Expense : out

+
+

Have you recently made an expenditure that requires logging down? PalPay accepts all expenditure inputs through the out command. Inputting an out command will decrease the overall balance value. Your expenditure statements, just like the income statements, have the added option to be tagged under one or more categories. You can do so by including the [c/CATEGORY] parameter in your command line. All uncategorized incomes will be tagged under the GENERAL category.

+
+
+

4.2.1. Command Syntax

+
+

Format: out $/AMOUNT n/DESCRIPTION d/DATE [c/CATEGORY]…​

+
+
+
+
+
    +
  • +

    Users should not input negative values into AMOUNT (i.e. out $/-100 …​) as PalPay has already accounted for the difference between incomes and expenditures.

    +
  • +
  • +

    CATEGORY accepts the categories for this expenditure. An out Transaction can be created without any CATEGORY.

    +
  • +
  • +

    out updates the user’s overall balance with a net negative amount (e.g. out n/milk $/2 d/10102019 will decrease overall balance by $2)

    +
  • +
+
+
+
+
+
+

4.2.2. Important Details:

+
+
    +
  • +

    Note that out transactions differ from in transactions in the display amount. The in transactions are characterized by the positive value within their display box whilst the out transactions are characterized by the negative values in their display box. The difference can be observed in the example usage below.

    +
  • +
  • +

    An out Transaction will affect the remaining amount of Budget entries with similar categories within the same time period (Refer to Section 4.2.3.3, “Example 3”).

    +
  • +
+
+
+
+

4.2.3. Example Usage

+
+
Example 1
+
+
+
out $/5 d/01012020 n/burger
+
+
+
+
    +
  1. +

    Expenditure logging

    +
    +
      +
    • +

      Inputs an expenditure of $5 with description set to 'burger' and date set on 01/01/2020.

      +
    • +
    • +

      The expenditure has not utilized the optional CATEGORY field.

      +
    • +
    • +

      Initial balance (red box in Figure 5) has a value of $620.50.

      +
      +
      +out ug 1 +
      +
      Figure 6. Expenditure Logging Example 1
      +
      +
    • +
    +
    +
  2. +
  3. +

    Expenditure added

    +
    +
      +
    • +

      The expenditure is added to the bottom of the Transactions tab.

      +
    • +
    • +

      The amount value of the expenditure box should display a negative value (see Figure 6 entry 3).

      +
    • +
    • +

      The added expenditure is given a GENERAL category.

      +
    • +
    • +

      Balance has decreased from $620.50 to $615.50 (red box in Figure 6).

      +
      +
      +out ug 2 +
      +
      Figure 7. Sample Expenditure 1 Added
      +
      +
    • +
    +
    +
  4. +
+
+
+
+
Example 2
+
+
+
out $/1000 n/maintenance d/02012020 c/car c/transport
+
+
+
+
    +
  1. +

    Expenditure logging

    +
    +
      +
    • +

      Inputs an expenditure of $1000 with description set to 'maintenance' and date set on 02/01/2020.

      +
    • +
    • +

      The income includes car and transport under the CATEGORY field.

      +
    • +
    • +

      Initial balance (red box in Figure 7) has a value of $615.50.

      +
      +
      +out ug 3 +
      +
      Figure 8. Expenditure Logging Example 2
      +
      +
    • +
    +
    +
  2. +
  3. +

    Expenditure added

    +
    +
      +
    • +

      The expenditure is added to the bottom of the Transactions tab.

      +
    • +
    • +

      The added expenditure is tagged under car and transport category.

      +
    • +
    • +

      Balance has decreased from $615.50 to -$384.50 (red box in Figure 8).

      +
    • +
    • +

      The negative value of the balance indicates that the total spending amount outweighs the total savings amount.

      +
      +
      +out ug 4 +
      +
      Figure 9. Sample Expenditure 2 Added
      +
      +
    • +
    +
    +
  4. +
+
+
+
+
Example 3
+
+
+
out $/100 n/pants d/02012020 c/clothes
+
+
+
+
    +
  1. +

    Expenditure logging

    +
    +
      +
    • +

      Inputs an expenditure of $100 with description set to 'pants' and date set on 02/01/2020.

      +
    • +
    • +

      The income includes clothes under the CATEGORY field.

      +
      +
      +out ug 5 +
      +
      Figure 10. Expenditure Logging Example 3
      +
      +
    • +
    +
    +
  2. +
  3. +

    Budget with similar categories and time period.

    +
    +
      +
    • +

      Entry 3 of the Budget tab has clothes under its CATEGORY field.

      +
    • +
    • +

      Entry 3 of the Budget tab has a deadline set to 01/01/2021.

      +
      +
      +out ug 6 +
      +
      Figure 11. Budget with 'clothes' category
      +
      +
    • +
    +
    +
  4. +
  5. +

    Expenditure added

    +
    +
      +
    • +

      The expenditure is added to the bottom of the Transactions tab.

      +
    • +
    • +

      The added expenditure has a date set to 02/01/2020.

      +
    • +
    • +

      The added expenditure is tagged under the clothes category.

      +
      +
      +out ug 7 +
      +
      Figure 12. Sample Expenditure 3 Added
      +
      +
    • +
    +
    +
  6. +
  7. +

    Budget entry updated

    +
    +
      +
    • +

      Remaining amount of entry 3 of the Budget tab has decreased from $1000 to $900.

      +
      +
      +out ug 8 +
      +
      Figure 13. Budget entry updated
      +
      +
    • +
    +
    +
  8. +
+
+
+
+
Example Commands:
+
+
    +
  • +

    out $/100 d/01012019 n/milk c/food c/drinks

    +
  • +
  • +

    out $/29 d/29022020 n/taxi c/transport

    +
  • +
  • +

    out $/12 d/31122019 n/burger

    +
  • +
+
+
+
+
+
+

4.3. Setting a Budget : set

+
+

You can set a budget for a particular category until a certain date, given it is not already present in the budget list. +A duplicate budget is a budget with the same AMOUNT and DATE and CATEGORY.
+If you attempt to do so, you will receive an error message: This budget already exists.

+
+
+

Format: set $/AMOUNT d/DATE [c/CATEGORY]…​

+
+
+
+
+

Paramters follow the same restrictions as highlighted in parameter constraints.

+
+
+
    +
  • +

    AMOUNT input accepts the budget amount to be set.

    +
  • +
  • +

    DATE input accepts the deadline to be set. It cannot be a date in the past.

    +
  • +
  • +

    CATEGORY accepts the CATEGORY for the budget. +A budget can be created without CATEGORY inputs in which case, the budget will automatically be assigned `GENERAL' category.

    +
  • +
+
+
+
+
+

Let’s say you want to restrict your spending for a certain category until a certain deadline. +PalPay allows you to set a budget and serve as a reminder to show how much of the budget set you have left +until the deadline (inclusive). You will be more self-conscious of your spending and minimise your spending by setting a budget.

+
+
+

To set a new budget:
+1. Type set and enter the relevant details (amount, deadline, category) in the format given above.
+2. The result box will display the message New budget successfully set.
+3. If the budget already exists in the budget list, the result box will display the message This budget already exists.
+4. Now you can see the newly set budget in the budget list.

+
+
+

As you make an OutTransaction of a particular CATEGORY, your budgets with the same CATEGORY will be adjusted +to display the remaining amount of budget. Other budgets in the list belonging to different CATEGORY will not be adjusted.

+
+
+

For example, you went out with your friends and bought a cup of Gong Cha. +Before you log your spending, your budget list looks like this:

+
+
+
+approachingBudget +
+
Figure 14. Budget List before Executing OutTransaction
+
+
+

You then type in the command out $/5 c/BBT c/friends n/gong cha d/11112019.

+
+
+
+newOutTransaction +
+
Figure 15. New OutTransaction Command
+
+
+

Your budget list now shows the updated budgets. Observe how Budget 3 is not affected because it does not belong to the relevant category.

+
+
+
+budgetAffected +
+
Figure 16. Updated Budget List
+
+
+

Budget will not take into consideration past OutTransaction when calculating the remaining budget. Remember, you are setting a budget +from TODAY till the stated DATE (inclusive)!

+
+
+

If you overspend beyond a set budget, the overspent budget will be displayed in red. +Shown below as budget index 3 is an example of an overspent budget:

+
+
+
+overspentBudget +
+
Figure 17. Overspent Budget
+
+
+

As the day you have set for the budget approaches, the countdown placeholder as well as the percentage remaining placeholder +will turn to red when the number of remaining days reaches 3 and below. +Shown below as budget index 4 is an example of a budget approaching its deadline:

+
+
+
+approachingBudget +
+
Figure 18. Budget approaching deadline
+
+
+

Examples:

+
+
+
    +
  • +

    set $/100 d/010120120 c/BBT

    +
  • +
  • +

    set $/300 d/29022020 c/shopping

    +
  • +
+
+
+
+

4.4. Splitting a Bill with Friends : split

+
+

Split a bill with your friends
+Format: split $/AMOUNT n/NAME1 a/DESCRIPTION [d/DATE] [n/NAME2]…​ [s/SHARE]…​

+
+
+
+
+
    +
  • +

    DESCRIPTION encompasses more details for the bill being split. User can make use of this +field to determine nature of bill.

    +
  • +
  • +

    [SHARE] defines portion of bill to be paid by each person

    +
    +
      +
    • +

      if no shares are given, amount will be split evenly across all people, including user

      +
    • +
    • +

      user is included in the bill if number of shares is 1 more than number of people

      +
      +
        +
      • +

        user’s share will be the first listed share

        +
      • +
      +
      +
    • +
    • +

      each person’s share is assigned in order

      +
      +
        +
      • +

        i.e. last person’s share is the last share listed

        +
      • +
      +
      +
    • +
    • +

      shares cannot be negative numbers

      +
    • +
    • +

      shares can be 0 but result is not guaranteed to be meaningful

      +
    • +
    +
    +
  • +
+
+
+
+
+
Ledger GUI
+
+
+LedgerUI +
+
Figure 19. Sample Ledger Graphical User Interface
+
+
+

This is how the Ledger looks when you switch to the Ledger tab.
+The left shows the people who has unresolved balances with you, while the right lists +all transactions that have to do with the Ledger.
+Ledger's balance is separate from the BankAccount. It is displayed in the same position, +at the bottom right corner.

+
+
+
+

4.4.2. Example Usage:

+
+
    +
  • +

    split $/1000 n/Amy n/Betty n/Catherine n/Dan a/haidilao

    +
    +
    +
    $1000 is split equally between Amy, Betty, Catherine, Dan and the user.
    +
    +
    +
    +
      +
    1. +

      Enter appropriate command into the command line.

      +
      +
      +SplitEven1 +
      +
      Figure 20. Splitting evenly
      +
      +
    2. +
    3. +

      Result is displayed accordingly

      +
      +
      +SplitEven2 +
      +
      Figure 21. Splitting evenly (result)
      +
      +
      +

      For an even split of $1000, each person pays $200. Therefore Ledger shows $200 on the tab of each person. +Ledger balance does not include the amount spent by the user. In this bill, the user is owed $800 in total +from the rest of his friends. Therefore Ledger balance is -$800, as shown in the bottom right.

      +
      +
    4. +
    +
    +
  • +
  • +

    split $/100 n/Albert n/Bernard n/Clement s/2 s/1 s/7 a/kbbq dinner

    +
    +
    +
    $100 is split with Albert owing $20, Bernard owing $10 and Clement owing $70.
    +
    +
    +
    +
      +
    1. +

      Enter appropriate command into the command line.

      +
      +
      +SplitUneven1 +
      +
      Figure 22. Splitting unevenly
      +
      +
    2. +
    3. +

      Result is displayed accordingly

      +
      +
      +SplitUneven2 +
      +
      Figure 23. Uneven split results
      +
      +
    4. +
    +
    +
  • +
+
+
+
+
+

4.5. Receiving Money from a Friend : receive

+
+

Receives money from 1 friend
+Format: receive $/AMOUNT n/NAME1 [d/DATE] [a/DESCRIPTION]

+
+
+

4.5.1. Example usage:

+
+
    +
  • +

    receive $/20 n/Albert

    +
    +
    +
    Transfers $20 from Albert to user. If Albert is no longer owe or is owed money, he will be removed from the Ledger.
    +
    +
    +
    +
      +
    1. +

      Enter appropriate command into the command line.

      +
      +
      +Receive1 +
      +
      Figure 24. Receive payment
      +
      +
    2. +
    3. +

      Result is displayed accordingly.

      +
      +
      +Receive2 +
      +
      Figure 25. Receive payment result
      +
      +
      +

      Albert is removed from the Ledger since he no longer owes any money. Ledger balance is also updated accordingly.

      +
      +
    4. +
    +
    +
  • +
+
+
+
+
+

4.6. Projecting Future Balance and Budgets : project

+
+

Cast a projection on your future balance amount and budget statuses based on your transaction history.

+
+
+

Format: project d/DATE [c/CATEGORY]

+
+
+ + + + + +
+
Note
+
+If a CATEGORY is not specified, it will be set as GENERAL by default. GENERAL projections project +upon ALL transactions, regardless of their categories. +
+
+
+

4.6.1. Example Usage:

+
+
    +
  1. +

    project d/22072020

    +
    +
    +
    Projected balance: $955.80
    +
    +
    +
  2. +
  3. +

    project d/01012020 c/Food

    +
    +
    +
    Projected balance: $188.04
    +You are on track to meeting your budget of $600 by 08122019, with a surplus of $484.32!
    +
    +
    +
  4. +
+
+
+
+

4.6.2. Usage Constraints

+
+
Command Format
+
+
    +
  • +

    CATEGORY must be preceded by its tag c/. +A violation of any of the above will produce the following error message:

    +
  • +
+
+
+
+
+

Invalid command format!
+project: Project future balance based on past income/outflow.
+Parameters: d/DATE [c/CATEGORY]
+Example: project d/12122103 c/Food

+
+
+
+
+
+
Date Values
+
+
    +
  • +

    DATE input must be set in the future. +A violation of this constraint will produce the following +error message:

    +
  • +
+
+
+
+
+

Invalid command usage!
+Date must be set in the future.

+
+
+
+
+
    +
  • +

    DATE cannot be more than 720 days from the day of projection.
    +A violation of this constraint will produce the following error message:

    +
  • +
+
+
+
+
+

Projections should be a maximum of 2 years (730 days) from now.

+
+
+
+
+
+
Minimum Number of Transactions
+
+
    +
  • +

    There must be a minimum of 5 transactions in total, or in the specified CATEGORY +for a projection to be successfully cast. +Should the requirement above be unmet, the following error message will be produced:

    +
  • +
+
+
+
+
+

There are no transactions in [CATEGORY]. It is impossible to cast a projection.

+
+
+ + + + + +
+
Note
+
+[GENERAL] will be displayed in place of [CATEGORY] if a CATEGORY is not specified. This is due to +the auto-casting of uncategorised projections to the GENERAL category as explained here. +
+
+
+
+
+
    +
  • +

    Should the number of transactions in a projection fall below 5, it +will be automatically deleted, as shown below:

    +
    +
      +
    1. +

      Suppose there are 5 transactions, and a GENERAL projection, which projects upon them.

      +
      +
      +project1 +
      +
      Figure 26. Five transactions under the projection tab
      +
      +
      +
      +project2 +
      +
      Figure 27. A projection which is cast based on the 5 transactions above
      +
      +
    2. +
    3. +

      If a transaction being deleted causes the number of transactions being projected upon to fall below 5, +the corresponding projection will automatically be deleted.

      +
      +
      +project3 +
      +
      Figure 28. The fifth transaction has been deleted.
      +
      +
      +
      +project4 +
      +
      Figure 29. The project earlier seen in Figure 19 has been automatically deleted.
      +
      +
    4. +
    +
    +
  • +
+
+
+
+
Valid Budget Start Dates and Deadlines
+
+

A projection will only project upon budgets with deadlines set before or equal to the projection DATE. An example +is depicted below:

+
+
+
    +
  1. +

    Suppose there is currently a general BUDGET with a deadline set for 28th November 2019

    +
    +
    +project5 +
    +
    Figure 30. Two budgets with dates 20112019 and 28112019 in the "GENERAL" category
    +
    +
  2. +
  3. +

    If a general PROJECTION is cast to 20th November 2019, it will contain +the budget with deadline 20112019 but not 28112019, +since the projection’s DATE is earlier than 28112019.

    +
    +
    +project6 +
    +
    Figure 31. The projection only contains the budget with deadline 20112019
    +
    +
  4. +
+
+
+
+
Backward Projections
+
+

While it is possible in PalPay, projecting your balance amount backwards in time is not guaranteed to +produce sensible results. It is generally not advisable to do so.

+
+
+
+
+
+

4.7. Display a Projection Graph: display

+
+

Display a graphical representation of a projection in a new window.

+
+
+

Format: display PROJECTION_ID

+
+
+

4.7.1. Example Usage

+
+
    +
  1. +

    Type display PROJECTION_ID into the command box and press Enter.

    +
    +
    +display1 +
    +
    +
  2. +
  3. +

    A new window containing a graphical representation of the specified projection will pop up.

    +
    +
    +display2 +
    +
    +
    +

    If there are any budgets associated with the projection, a corresponding graphical +representation of the budget will be additionally displayed.

    +
    +
    +
    +display3 +
    +
    +
  4. +
+
+
+
+

4.7.2. Interpreting the Projection graph

+
+

Here is a typical projection graph.

+
+
+
+project7 +
+
Figure 32. A typical projection graph
+
+
+
    +
  • +

    The X-Axis
    +The X-Axis denotes your balance in dollars ($).

    +
  • +
  • +

    The Y-Axis
    +The Y-Axis denotes the number of days from now, with today being Y = 0.

    +
  • +
  • +

    Red Points
    +The red points on the graph each represent your account balance (denoted by the X-value) +at a particular point of time (denoted by the Y-value).

    +
  • +
  • +

    Blue Line Graph
    +The blue line graph represents the projection line, with each point along it representing +a prediction of your account balance (denoted by the X-value) +at a certain point of time (denoted by the Y-value).

    +
  • +
  • +

    All Other Coloured Line Graphs
    +All other coloured line graphs represent various budgets which fall within the CATEGORY and DATE range +of the PROJECTION. Each of these line graphs have three parts:

    +
  • +
+
+
+
+
+
+project8 +
+
Figure 33. A budget line graph with its parts labelled by a green, blue and yellow box each
+
+
+
    +
  1. +

    The line in the green box denotes the budget amount in dollars ($).

    +
  2. +
  3. +

    The line in the blue box denotes the budget duration (i.e. the number of days from its inception to +its deadline)

    +
  4. +
  5. +

    The line in the yellow box denotes the projection deficit or surplus, at the point of its deadline.

    +
  6. +
+
+
+
+
+
+

4.7.3. Usage Constraints

+
+
Valid Projection Index
+
+
    +
  • +

    A Projection with PROJECTION_ID must exist. +Attempting to display a non-existent PROJECTION will result in the following error message:

    +
  • +
+
+
+
+
+

The projection index provided is invalid.

+
+
+
+
+
+
Static Graph Rendering
+
+
    +
  • +

    Projection graphs do not update automatically when a new Transaction or Budget is +added or removed. Instead, they are statically rendered upon the display command.

    +
    + + + + + +
    +
    Note
    +
    +Due to the static nature of projection graphs, commands should NOT be executed while a projection +graph is open, lest the behaviour of PalPay become unpredictable.
    +Consequently, a display command should ALWAYS be followed by closing the projection graph window, before +any other actions are performed within PalPay. +
    +
    +
  • +
+
+
+
+
+
+

4.8. Switching Tabs : view

+
+

Want to switch tabs without using your mouse? You can switch to another tab with the view command.

+
+
+

4.8.1. Command Syntax

+
+

Format: view TAB

+
+
+
+
+
    +
  • +

    TAB input only accepts transaction, budget, ledger and projection in v1.4. It is case-insensitive.

    +
  • +
+
+
+
+
+
+

4.8.2. Example Usage:

+
+

You do not have to use your mouse in PalPay to switch tabs anymore.

+
+
+
    +
  1. +

    By default, you are in the transaction tab.

    +
    +
    +view1 +
    +
    +
  2. +
  3. +

    Simply type view budget in the command box and press Enter.

    +
    +
    +view2 +
    +
    +
  4. +
  5. +

    You can now view your budgets. Easy!

    +
    +
    +view3 +
    +
    +
  6. +
+
+
+
+
+

4.9. Deleting Finance : delete

+
+

Deletes the specified Transaction, Budget, Ledger or Projection from PalPay.

+
+
+

4.9.1. Command Syntax

+
+

Format: delete TYPE+INDEX

+
+
+
+
+
    +
  • +

    TYPE accepts either t (Transaction), b (Budget), l (Ledger) or p (Projection). (e.g. delete b1 refers to deleting a Budget of index 1).

    +
  • +
  • +

    TYPE+INDEX requires the TYPE and INDEX to be placed in sequential order (e.g. delete b 1 or delete 1 or delete 1b will not work).

    +
  • +
  • +

    Example: delete t1 will delete the first transaction from the list of transactions.

    +
  • +
+
+
+
+
+
+

4.9.2. Important Details:

+
+
    +
  • +

    PalPay deletes items based on the entry index of the target item. You can only delete a maximum of 1 entry per command. (i.e. delete t1 t2 b1 or delete t1 t2 will not work)

    +
  • +
  • +

    You can only delete an existing transaction or budget. Nothing will be deleted if the transaction or budget of INDEX does not exists.

    +
  • +
+
+
+
+

4.9.3. Example Usage:

+
+
+
Deleting the 5th entry of the transactions list
+
+
+
+
    +
  1. +

    Note the index of the entry you want to delete. In this example, entry 5 is the field we will be deleting.

    +
    +
    +delete ug 1 +
    +
    +
  2. +
  3. +

    Since we are deleting a Transaction entry of index 5, we will input t into our TYPE field and 5 into our INDEX field.

    +
    +
    +delete ug 2 +
    +
    +
  4. +
  5. +

    Success message will be displayed upon successful deletion.

    +
    +
    +delete ug 3 +
    +
    +
  6. +
+
+
+
Example Commands:
+
+
    +
  • +

    delete t1

    +
  • +
  • +

    delete b3

    +
  • +
  • +

    delete l2

    +
  • +
  • +

    delete p4

    +
  • +
+
+
+
+
+
+

4.10. Updating Finance : update

+
+

Did you make a mistake in one of your entries? Perhaps you over counted that expenditure you made. PalPay provides you with an update feature which helps you change specific fields within your entries.

+
+
+

4.10.1. Command Syntax

+
+

The update feature has different implementations for different entry types. The conditions for the update feature is as follows.

+
+
+

Format (Transactions): update TYPE+INDEX [$/AMOUNT] [d/DATE] [n/ITEM] [c/CATEGORY]…​

+
+
+

Format (Budget): update TYPE+INDEX [$/AMOUNT] [d/DATE] [c/CATEGORY]…​

+
+
+

Format (Ledger): Cannot be updated

+
+
+

Format (Projections): Cannot be updated

+
+
+
+
+
    +
  • +

    At least one AMOUNT, DATE, ITEM or CATEGORY fields must be entered. You can input more than 1 of the mentioned fields (e.g. update t1 $/100 n/milk).

    +
  • +
  • +

    TYPE only accepts either t (Transaction) or b (Budget). (e.g. update t1 .. refers to updating a Transaction of index 1).

    +
  • +
  • +

    TYPE+INDEX requires the TYPE and INDEX to be placed in sequential order (e.g. update b 1 .. or update 1 .. or update 1b .. will not work).

    +
  • +
  • +

    Example: update t1 $/3000 d/10102019 will update the first transaction from the list of transactions by changing it’s Amount to $1000 and Date to 10/10/2019.

    +
  • +
+
+
+
+
+
+

4.10.2. Important Details:

+
+
    +
  • +

    update requires at least one field to be updated. (e.g. update t1 $/20 d/10102019 n/milk and update t1 $/10 will both be accepted).

    +
  • +
  • +

    You can only update an existing transaction, budget or projection. Nothing will be updated if the entry of index INDEX does not exists.

    +
  • +
  • +

    Ledger and Projection do not have an update function. If you need to change specific fields within a ledger or projection entry, you should delete the target entry and recreate a new entry with your desired fields.

    +
  • +
  • +

    You cannot change an in Transaction to an out Transaction or vice versa.

    +
  • +
  • +

    Changing an expenditure’s (out Transaction) category field to that of a Budget’s entry will reflect changes on that particular Budget entry as well. (Further explained in Section 4.10.3.3, “Example 3:”)

    +
    + + + + + +
    +
    Note
    +
    +Changing the categories of an out Transaction entry with similar categories to that of a Budget entry to reflect changes on the budget’s remaining amount will be incoming in version 2.0. +
    +
    +
  • +
+
+
+
+

4.10.3. Example Usage

+
+
Example 1:
+
+

Updating a Transaction entry.

+
+
+
    +
  1. +

    Identify the index number of the entry you want to edit. In this case, we will be using entry 3.

    +
    +
    +update ug 1 +
    +
    +
  2. +
  3. +

    Put t as your TYPE input and key in the fields you want to change. In this case, we will only be changing the amount of the transaction.

    +
    +
    +update ug 2 +
    +
    +
  4. +
  5. +

    Success message will be displayed upon successful update. Fields will now be updated accordingly.

    +
    +
    +update ug 3 +
    +
    +
  6. +
+
+
+
+
Example 2:
+
+

Updating a Budget entry.

+
+
+
    +
  1. +

    Identify the index number of the entry you want to edit

    +
    +
    +update ug 4 +
    +
    +
  2. +
  3. +

    Put b as your TYPE input and key in the fields you want to change. In this case, we will be changing both the date and amount of this Budget. +When you update the amount of a budget, the budget will be re-initialised (reset to 100%).

    +
    +
    +update ug 5 +
    +
    +
  4. +
  5. +

    Success message will be displayed upon successful update. Fields will now be updated accordingly.

    +
    +
    +update ug 6 +
    +
    +
  6. +
+
+
+
+
Example 3:
+
+

Updating a Transaction entry which has the same category field as a Budget entry.

+
+
+
    +
  1. +

    Identify the index number of the Transaction entry you want to edit.

    +
    +
    +update ug 7 +
    +
    +
  2. +
  3. +

    Notice that a Budget entry has the same category field as the Transaction entry mentioned above. (Budget entry 2).

    +
    +
    +update ug 8 +
    +
    +
  4. +
  5. +

    Put t as your TYPE input and key in the fields you want to change. In this case, we will be changing only the amount of this Transaction.

    +
    +
    +update ug 9 +
    +
    +
  6. +
  7. +

    Success message will be displayed upon successful update. Fields of the Transaction entry will now be updated accordingly.

    +
    +
    +update ug 10 +
    +
    +
  8. +
  9. +

    Remaining amount of the Budget entry will also be updated accordingly.

    +
    +
    +update ug 11 +
    +
    +
  10. +
+
+
+
+
Example Commands:
+
+
    +
  • +

    update t1 $/20 n/coke c/drinks d/12122019

    +
  • +
  • +

    update b2 $/300

    +
  • +
  • +

    update t4 $/30 d/12102019

    +
  • +
+
+
+
+
+
+

4.11. Sorting Transactions : sort

+
+

Have you ever wonder which is the most expensive transaction you ever made? +Or which is the latest transaction you made? Fret not! +You can now sort your transactions according to date or amount.

+
+
+

4.11.1. Command Syntax

+
+

Format: sort PREDICATE/ORDER

+
+
+
+
+
    +
  • +

    PREDICATE accepts only date or amount. It is case-insensitive.

    +
  • +
  • +

    ORDER accepts only a or d which represents ascending and descending, respectively.

    +
  • +
+
+
+
+
+
+

4.11.2. Example Usage:

+
+

Do you want to know what is the latest transaction you made? No need to scroll all the way down anymore. PalPay +has made it simple for you.

+
+
+
    +
  1. +

    By default, your transactions are sorted from the earliest +transaction you entered to the latest transaction you entered.

    +
    +
    +sort1 +
    +
    +
  2. +
  3. +

    Simply type sort date/d in the command box and press Enter.

    +
    +
    +sort2 +
    +
    +
  4. +
  5. +

    Great! You can now see the latest transactions you made.

    +
    +
    +sort3 +
    +
    +
  6. +
+
+
+
+
+

4.12. Filtering Transactions : filter

+
+

Here at PalPay, you do not need to scroll through your history of transactions to find out what you spend two months ago. +PalPay gives you the power to filter your transactions to solve that problem.

+
+
+

4.12.1. Command Syntax

+
+

Format: filter [n/DESCRIPTION] [y/YEAR] [m/MONTH] [c/CATEGORY]…​

+
+
+
+
+
    +
  • +

    YEAR accepts only integers from 1900 to 9999.

    +
  • +
  • +

    MONTH accepts only integers from 1 to 12.

    +
  • +
  • +

    All transactions with at least one CATEGORY in the [c/CATEGORY]…​ input will be displayed.

    +
  • +
  • +

    Example: filter c/transport c/allowance y/2019 will display transactions with transport, allowance, or +transport and allowance that occurred in 2019.

    +
  • +
+
+
+
+
+
+

4.12.2. Example Usage:

+
+

Imagine that you wanted to find out what you spent on shopping in October 2019.

+
+
+
    +
  1. +

    By default, PalPay shows your all your transactions you have made.

    +
    +
    +filter1 +
    +
    +
  2. +
  3. +

    Simply type filter c/Shopping m/10 y/2019 in the command box and press Enter.

    +
    +
    +filter2 +
    +
    +
  4. +
  5. +

    You will now see the list of transactions you have made while shopping in October 2019. Hurray!

    +
    +
    +filter3 +
    +
    +
  6. +
+
+
+
+
+

4.13. Undoing the Last Command : undo

+
+

Did you accidentally delete a transaction? Do not panic! PalPay lets you undo your previous commands with just one +word, undo.

+
+
+

4.13.1. Command Syntax

+
+

Format: undo

+
+
+
+
+
    +
  • +

    Once you exit PalPay, you cannot undo the previous commands.

    +
  • +
  • +

    Below are the commands that are undoable:

    +
    +
      +
    • +

      in / out / set / split / receive / project / +sort / filter / update / delete / clear / list

      +
    • +
    +
    +
  • +
+
+
+
+
+
+

4.13.2. Example Usage:

+
+

Suppose you want to update your allowance you received in October 2019 to $800 but you accidentally update the GrabTaxi +ride instead. Without going through the trouble of updating the same transaction again, you can simply perform the +undo command. Just follow these three simple steps.

+
+
+
    +
  1. +

    Here, you can see the wrong update you just made.

    +
    +
    +undo1 +
    +
    +
  2. +
  3. +

    Simply type undo in the command box and press Enter.

    +
    +
    +undo2 +
    +
    +
  4. +
  5. +

    As you wish, your command has been undone.

    +
    +
    +undo3 +
    +
    +
  6. +
+
+
+
+
+

4.14. Redoing the Last Command : redo

+
+

Made an extra undo by mistake? Do not worry! PalPay lets you redo your previous undo(s) with just one word, redo.

+
+
+

4.14.1. Command Syntax

+
+

Format: redo

+
+
+
+
+
    +
  • +

    You can only redo undo commands.

    +
  • +
  • +

    Once you exit PalPay, you cannot redo the previous undo(s).

    +
  • +
+
+
+
+
+
+

4.14.2. Example Usage:

+
+

Suppose you want to undo your last update but you accidentally undo twice instead. +You can simply perform the redo command to revert the changes. Just follow these three simple steps.

+
+
+
    +
  1. +

    Here, you can see the extra undo you just made and the GrabTaxi ride is back at $800.

    +
    +
    +redo1 +
    +
    +
  2. +
  3. +

    Simply type redo in the command box and press Enter.

    +
    +
    +redo2 +
    +
    +
  4. +
  5. +

    Great! Your transaction is back to normal.

    +
    +
    +redo3 +
    +
    +
  6. +
+
+
+
+
+

4.15. Clearing All Entries : clear

+
+

Do you want to start PalPay from a clean slate again? The clear command lets you do that!

+
+
+

4.15.1. Command Syntax

+
+

Format: clear

+
+
+
+
+

4.16. Listing All Entries : list

+
+

After filtering your transactions, you can use the list command to see all of your transactions in PalPay again.

+
+
+

4.16.1. Command Syntax

+
+

Format: list

+
+
+
+
+

4.17. Viewing Help : help

+
+

Did you forget how to use the in command? Fret not! You can easily find the link to this User Guide with the +help command. Simply copy and paste the URL into your browser to access our User Guide.

+
+
+

4.17.1. Command Syntax

+
+

Format: help

+
+
+
+help +
+
+
+
+
+

4.18. Exiting the Application : exit

+
+

Finishing using PalPay for the day? You can use the exit command to close PalPay.

+
+
+

4.18.1. Command Syntax

+
+

Format: exit

+
+
+
+
+

4.19. Saving the Data

+
+

PalPay data is saved in the hard disk automatically after any command that changes the data.
+There is no need to save manually.

+
+
+
+
+
+

5. FAQ

+
+
+

Q: How do I transfer my data to another Computer?
+A: Install the app in the other computer and overwrite the empty data file it creates with the file that contains the data of your previous Bank Account folder.

+
+
+
+
+

6. Command Summary

+
+
+
    +
  • +

    In : in $/AMOUNT n/ITEM d/DATE [c/CATEGORY]
    +Example: in $/100 n/allowance d/11112019 c/income

    +
  • +
  • +

    Out : out $/AMOUNT n/ITEM d/DATE [c/CATEGORY]
    +Example: out $/20 n/coke d/19112019 c/drink c/lunch

    +
  • +
  • +

    Set : set $/AMOUNT d/DATE [c/CATEGORY]…​
    +Example: set $/100 d/10102019 c/food

    +
  • +
  • +

    Split : split $/AMOUNT n/NAME1 a/DESCRIPTION [d/DATE] [n/NAME2]…​ [s/SHARE]…​
    +Example: split $/1000 n/Amy n/Betty n/Catherine n/Dan a/HaiDiLao

    +
  • +
  • +

    Receive : receive $/AMOUNT n/NAME
    +Example: receive $/20 n/Albert

    +
  • +
  • +

    Project : project DURATION
    +Example: project d/22072020

    +
  • +
  • +

    View : view TAB
    +Example: view transaction

    +
  • +
  • +

    Delete : delete TYPE+INDEX
    +Example: delete t1

    +
  • +
  • +

    Update : update TYPE+INDEX [$/AMOUNT] [d/date] [n/ITEM] [c/CATEGORY]
    +Example: update b1 $/100 c/transport

    +
  • +
  • +

    Sort : sort PREDICATE
    +Example: sort amount

    +
  • +
  • +

    Filter : filter [n/DESCRIPTION] [y/YEAR] [m/MONTH] [c/CATEGORY]…​
    +Example: filter c/transport c/allowance y/2019

    +
  • +
  • +

    Undo : undo

    +
  • +
  • +

    Redo : redo

    +
  • +
  • +

    Clear : clear

    +
  • +
  • +

    List : list

    +
  • +
  • +

    Help : help

    +
  • +
  • +

    Exit : exit

    +
  • +
+
+
+
+
+ + + diff --git a/docs/[CS2103T-W12-3][PalPay]DeveloperGuide.pdf b/docs/[CS2103T-W12-3][PalPay]DeveloperGuide.pdf new file mode 100644 index 00000000000..d48f4b5eb99 Binary files /dev/null and b/docs/[CS2103T-W12-3][PalPay]DeveloperGuide.pdf differ diff --git a/docs/[CS2103T-W12-3][PalPay]UserGuide.pdf b/docs/[CS2103T-W12-3][PalPay]UserGuide.pdf new file mode 100644 index 00000000000..2c47f6a78c3 Binary files /dev/null and b/docs/[CS2103T-W12-3][PalPay]UserGuide.pdf differ diff --git a/docs/diagrams/ArchitectureSequenceDiagram.puml b/docs/diagrams/ArchitectureSequenceDiagram.puml index 700af8a6ef1..07299253a93 100644 --- a/docs/diagrams/ArchitectureSequenceDiagram.puml +++ b/docs/diagrams/ArchitectureSequenceDiagram.puml @@ -13,13 +13,13 @@ activate ui UI_COLOR ui -[UI_COLOR]> logic : execute("delete t1") activate logic LOGIC_COLOR -logic -[LOGIC_COLOR]> model : deleteTransaction(t1) +logic -[LOGIC_COLOR]> model : delete(t1) activate model MODEL_COLOR model -[MODEL_COLOR]-> logic deactivate model -logic -[LOGIC_COLOR]> storage : saveBankAccount(bankAccount) +logic -[LOGIC_COLOR]> storage : saveUserState(userState) activate storage STORAGE_COLOR storage -[STORAGE_COLOR]> storage : Save to file diff --git a/docs/diagrams/LedgerOperationDiagram.puml b/docs/diagrams/LedgerOperationDiagram.puml index 8fc6eab2a47..8a7742ea0e0 100644 --- a/docs/diagrams/LedgerOperationDiagram.puml +++ b/docs/diagrams/LedgerOperationDiagram.puml @@ -6,9 +6,9 @@ skinparam classBackgroundColor MODEL_COLOR Package Ledger <>{ +Class Ledger Package Transaction { Interface LedgerOperation <> -Class Ledger Class Transaction <> @@ -32,8 +32,8 @@ Class HiddenOutside #FFFFFF 'UniquePersonList UniquePersonList ---"*" Person -Transaction --- Amount -Transaction --- Date +Transaction ---"1" Amount +Transaction ---"1" Date 'ledger operation Ledger o--> LedgerOperation diff --git a/docs/diagrams/LogicClassDiagram.puml b/docs/diagrams/LogicClassDiagram.puml index 44f2c885f61..e9b025fa5d6 100644 --- a/docs/diagrams/LogicClassDiagram.puml +++ b/docs/diagrams/LogicClassDiagram.puml @@ -8,7 +8,7 @@ package Logic { package Parser { Interface Parser <> -Class BankAccountParser +Class MainParser Class XYZCommandParser Class CliSyntax Class ParserUtil @@ -35,8 +35,8 @@ Class HiddenOutside #FFFFFF HiddenOutside ..> Logic LogicManager .up.|> Logic -LogicManager -->"1" BankAccountParser -BankAccountParser .left.> XYZCommandParser: creates > +LogicManager -->"1" MainParser +MainParser .left.> XYZCommandParser: creates > XYZCommandParser ..> XYZCommand : creates > XYZCommandParser ..|> Parser diff --git a/docs/diagrams/ModelClassDiagram.png b/docs/diagrams/ModelClassDiagram.png new file mode 100644 index 00000000000..0e9d3d8a529 Binary files /dev/null and b/docs/diagrams/ModelClassDiagram.png differ diff --git a/docs/diagrams/ModelClassDiagram.puml b/docs/diagrams/ModelClassDiagram.puml index 9bdc61fd471..e5e11c3830c 100644 --- a/docs/diagrams/ModelClassDiagram.puml +++ b/docs/diagrams/ModelClassDiagram.puml @@ -85,6 +85,7 @@ HiddenOutside ..> Model 'read only implementation Ledger .up.|> ReadOnlyLedger +Ledger ---"1" UniquePersonList BankAccount .up.|> ReadOnlyBankAccount 'UserPrefs .up.|> ReadOnlyUserPrefs diff --git a/docs/diagrams/Split.puml b/docs/diagrams/Split.puml index 097da6c6c26..33114a2306a 100644 --- a/docs/diagrams/Split.puml +++ b/docs/diagrams/Split.puml @@ -19,7 +19,7 @@ participant ":LendMoney" as LendMoney MODEL_COLOR end box -[-> LogicManager : execute("split $/200 n/Amy n/Bob n/Cameron") +[-> LogicManager : execute("split $/200 n/a n/b n/c a/desc") activate LogicManager LogicManager -> MainParser: parseCommand("split $/200 n/Amy n/Bob n/Cameron") diff --git a/docs/diagrams/SplitBehaviour.puml b/docs/diagrams/SplitBehaviour.puml index bf9167ec5d0..10302435a74 100644 --- a/docs/diagrams/SplitBehaviour.puml +++ b/docs/diagrams/SplitBehaviour.puml @@ -1,17 +1,21 @@ @startuml -(*) --> "check input" -If "shares.length == name.length?" then ---> [Yes] "set user's share to 0" ---> "create split" ---> (*) -else - if "share size is 1 more than name?" - --> [yes] "user's share is the first" - --> "create split" - else - --> "throw error" - endif -Endif --->(*) +start +:User executes Split command; +:SplitCommandParser parses and validates user input; + +if() then ([Valid input]) + +:Creates SplitCommand containing List of shares and people; +:Calculates Amount for each Person; +:Update balance for each Person; +:Update balance for Ledger; +:Commit UserState; + +else([else]) +:Throw ParseException; +endif + +stop + @enduml diff --git a/docs/diagrams/StorageClassDiagram.puml b/docs/diagrams/StorageClassDiagram.puml index 23d373f30f1..57242de3e90 100644 --- a/docs/diagrams/StorageClassDiagram.puml +++ b/docs/diagrams/StorageClassDiagram.puml @@ -6,22 +6,26 @@ skinparam classBackgroundColor STORAGE_COLOR Interface Storage <> Interface UserPrefsStorage <> -Interface BankAccountStorage <> +Interface UserStateStorage <> Class StorageManager Class JsonUserPrefsStorage -Class JsonBankAccountStorage +Class JsonUserStateStorage StorageManager .left.|> Storage StorageManager o-right-> UserPrefsStorage -StorageManager o--> BankAccountStorage +StorageManager o--> UserStateStorage JsonUserPrefsStorage .left.|> UserPrefsStorage -JsonBankAccountStorage .left.|> BankAccountStorage -JsonBankAccountStorage .down.> JsonSerializableBankAccountStorage -JsonSerializableBankAccountStorage .right.> JsonSerializableTransaction -JsonSerializableBankAccountStorage .left.> JsonSerializableBudget -JsonSerializableTransaction ...> JsonAdaptedCategory +JsonUserStateStorage .left.|> UserStateStorage +JsonUserStateStorage .down.> JsonSerializableUserState +JsonSerializableUserState .down.> JsonAdaptedBankAccountOperations +JsonSerializableUserState .left.> JsonSerializableBudget +JsonSerializableUserState .right.> JsonAdaptedLedgerStorage +JsonSerializableUserState .down.> JsonAdaptedProjection +JsonAdaptedBankAccountOperations .left.> JsonAdaptedCategory +JsonAdaptedLedgerStorage .right.> JsonAdaptedLedgerOperations +JsonAdaptedLedgerOperations .down.> JsonAdaptedPerson JsonSerializableBudget ...> JsonAdaptedCategory @enduml diff --git a/docs/diagrams/UiClassDiagram.puml b/docs/diagrams/UiClassDiagram.puml index 678f6f698df..55fdbe35f23 100644 --- a/docs/diagrams/UiClassDiagram.puml +++ b/docs/diagrams/UiClassDiagram.puml @@ -13,6 +13,7 @@ Class HelpWindow Class ResultDisplay Class StatusBarFooter Class CommandBox +Class MainTabPanel package { Class TransactionListPanel @@ -42,10 +43,11 @@ UiManager -down-> MainWindow MainWindow --> HelpWindow MainWindow *-down-> CommandBox MainWindow *-down-> ResultDisplay -MainWindow *-down-> TransactionListPanel -MainWindow *-down-> BudgetListPanel -MainWindow *-down-> LedgerListPanel -MainWindow *-down-> ProjectionListPanel +MainWindow *-down-> MainTabPanel +MainTabPanel *-down-> TransactionListPanel +MainTabPanel *-down-> BudgetListPanel +MainTabPanel *-down-> LedgerListPanel +MainTabPanel *-down-> ProjectionListPanel MainWindow *-down-> StatusBarFooter StatusBarFooter -[hidden]down-> CommandBox diff --git a/docs/diagrams/drawio/FilterClassDiagram.drawio b/docs/diagrams/drawio/FilterClassDiagram.drawio index 42eb1e36973..1ce2fe56d30 100644 --- a/docs/diagrams/drawio/FilterClassDiagram.drawio +++ b/docs/diagrams/drawio/FilterClassDiagram.drawio @@ -1 +1 @@ -7Vxtb9s2EP41BroBDfRiWfZHx3lZgWTp6m7tPg20xdhqZdGT6CTer99RIvVCUpaSWLbbqCha8URS0vHhc8c70j17snq6jtB6eUs8HPQsw3vq2Rc9yzL7xhD+Y5JtKnFdNxUsIt/jlXLB1P8Pc6HBpRvfw3GpIiUkoP66LJyTMMRzWpKhKCKP5Wr3JCg/dY0WWBFM5yhQpV98jy5T6dAxcvlv2F8sxZNNg9+Zofn3RUQ2IX9ez7Lvkz/p7RUSffH68RJ55LEgsi979iQihKZXq6cJDphuhdrSdlcVd7P3jnBIGzVw0XyGHLc/xI49Gszeixd7QMEGi28YBNDZuec/wOWCXfbcczSLaYRA9+6FqACPKdZRm03IaoVANfzOLJLryj0kKqJbMSzxo78KUAil8yVdBSA04fKehHTKKxlQni/9wLtBW7JhKogpDIkonS9J5P8H9ZFoDLcjygFoO6w3PwgmJCARCEKSPitrNGWd8cdEOIZmH4WqzUx0g2IqXoUEAVrH/ix5OVZlhaKFH54TSsmKVxJfdVV4co4b6JXBCXuitkBM2v/Kn/PrAM1wcJ7hT/oGGCzyHRe6N5I/2R0Bc6HQK7TyAzZ7/8KRh0Ik9JxqyjR4WdchCvxFCLI5KAZH2TgWQclx+oAjip8KIg7Sa0xWmEZbqMLvDlyOS04o5igtPuaz0xzwKsvCzBwIUuCEsMh6zicFXPB50XSOmJo5Al9p4Cc831D8LiHEX0AgzxMJz/DxtIzl8jDxsdNAUug4wPesB6ZIH+hrzMWUrFlnazT3w8VNUuein0s+cQUx0ePSp3gKcvZOj0DnICPQ332QoGzpex4OExRSRNEsm2Vr4oc00apzDn9B9xPjzOk58F0TKJt5Gf6y6hGAJWS68BMUYJgljzimenxU0lI9YjhCYDI3Qog1eD1C0OLKHP0xcj9/djfX0fj6W3AXvzeV4cYeGBleBHUsyYKEKLjMpdJUz+vcEDagCUK+YUq3fBqiDSVl/OAnn34tXP/NujozwPym5Ysn3ndS2IpCCB/8tVhI21mOKOftklLe0BszcwvFWUAYNTIRI7LCYz7iyAeVMipIZJV0EJNNNMcVCLD52AFfL3AdTJimd4IkwgGi/kPZ3OsgkDSFb0TbQgWO/bznj0yQs1XfKbOV3ZfQlHaYYyt7s5cRkq0abRgD0HhmcA9rSGFOdYb0NA1p5nlWG1LL1tCkObRa4sm+zuNk1nRyd3s7/v3iny93n8CCjEEypRFYr86MvtiM2s82o8I81uFjH2ZUfd0qR+v2cjodX1/+8yf7t8PGkbDhWMfEhlWDjemfkwlcdug4Ejrc4eHQoTUsIw1AZI8891+Fi1LwpTOv+Gw0GpQ841q3GEoN3N4qJUvua9np1S82DP1YFJTvaHQvZM9zh3N/VzgRhn3mlBulvjyvVwxASa6ybUr+iNpV+vFKVy9wnHeorn41n/AId6g/4XgT0I5ODkgnptE/Mp+YlWGffzcoiN/dzb7hOeVAmRESYBR2EDkkREST40FE55So0XNrgFZM6YFa+sCWevdsaIS43GRnuFx5EiyqYxydbLzd7sIEpxomKFtl4TrVBVNFlH7/E8uu4N41Q/i71L3n1Pu5I92mpLubxJrH2u1m8GiPd/sKPEoBUMGDXRi04zfuTZZXHa4mWzTS5RPbIrjKnKKG4HbH9juyexbZ9RtDpzoiqoVKa2Rn2cqYPzezWACHh+JlIjcbzHngtmJyrzb7F3ryBG/AAyKHyUa6kMXs7cpgVlJCMae4EwBHThmahlNipJEl4aSQMlQaZ7SUuWsS9ppGYyre4lChGEs1458jFMZoTn0SfoywB3xEcWfHOzsuMu3yviBNCMDWuqJmW5Zck4xPLTkFw/TuHIXfx/M5jAS9W+MIMWB3IaM9GnRrHwZdD5l+W4ipSmV1gcXTQYnTlFha4xV1hfCetYknYBIXJNp+CGPfw7zk41jiGrBnwDVMo5YhmnSYOiqm3IaY6u8BUzff7dsHl5rjLx/if58GXwkdP74faCHFDNUViWqQ1GGnOXYUSDSGU3Wyw2xKSFZL4HF3gecCx/PIXzOgdOg5QfQIn+No6BnuQs8tLCGWHW5OEDeOmoU/LG7UXT0F3PwNKOlgc4KwcZuusfYAG733rCYQhROsoKELJ73VcJIp570HqpN12MymPVDgeYhjRGLrY1ZIDwQ94zwQWSdsVU4IVA5R7QZHMX/3HKZXj+5IAcVs3f/sjY39cke2vIiriKU/+6yRoX/hqvdS6ru2BNLXHU7Sj566Vvi1BSOcUYFshldgPJOZoTOy5dlSpB9nP6xijepZRXvmprVQ0vCopFI8WNhsO3WDU4bqqUeRPdx3xlBM5FrOstpJLSpTeiAdNzRfyll9u6ajPXGWI+UrneEBKGh0HMzvNogy25Sy8ZUTxqyZMI3MbNPTB3uHqz20y3RoNEOZmvaWTZmcoanA/XPhmh1lkZ6zL7xq17lqtF89UH7KFrNmFbnbYjoyEemCnS1ZTP1oqEldtlN70W0q/LlWj69Crbx6zFz+Q6we9bBVWaSDbQfbGtgOjw5bS4Gt5nBLIcV0GudZOoz/OBg3jo7x1+/ifcXvA4nlcJOVcrvBQOWsc82SfFcquri82UEs+w8aSscJ7JbWzUpw0q2J9Zmvq2+b+40N6sdE3fRrnJ29ocWOHB7UcZPu8H57ix3nx6Gm3RTzUuraIzUNm1JTxS84vJaaZMM3aoma5MzZyNlNNfJ7OYegGnW/2xunGs0K9bBUoyaGVmzvzxseEkfdKnHYITlOcujndExHTdn/OL9Tacv+nrubtOX6o0OQtrrj642TtiY+c1CG0JxV3mKkhhTfzoiMWuNsKOa/Bp9Oqfwn9+3L/wE= +7Vxtc5s4EP41nsndTDK8GGM+Os7LdSa59Or02n7qyEaxaTDygZzY/fUngcSLJAxODE4bMpkMWiQBq0fPrnal9MzxcnMdgtXiFrnQ7xmau+mZFz3DcEyD/KWCbSLoD+1EMA89NxHpmWDi/YRMqDHp2nNhVKiIEfKxtyoKZygI4AwXZCAM0XOx2gPyi09dgTmUBJMZ8GXpF8/Fi0Q6tLRM/hf05gv+ZF1jd6Zg9jgP0Tpgz+sZ5kP8k9xeAt4Xqx8tgIuecyLzsmeOQ4RwcrXcjKFPVcvVlrS7KrmbvncIA1yrgQ1mU2DZ/SG0TGcwPeUv9gT8NeTfMPBJZ+eu90Qu5/SyZ5+DaYRDQHRvX/AK5DH5OnKzMVouAVENuzMNxbpiD7GK8JYPS/TsLX0QkNL5Ai99ItTJ5QMK8IRV0kh5tvB89wZs0ZqqIMJkSHjpfIFC7yepD3hjcjvEDICmRXvzfH+MfBQSQYCSZ6WNJrQz9pgQRqTZR65qPRXdgAjzV0G+D1aRN41fjlZZgnDuBecIY7RklfhXXeWenOGG9ErhBF1emyMm6X/pzdi1D6bQP0/xJ3wDGSz0CHPda/FPeofDnCv0Ciw9n87ef2HoggBwPSea0jVWVnUIfG8eENmMKAaG6TjmQclw+gRDDDc5EQPpNURLiMMtqcLuDmyGS0YoupMUn7PZqQ9YlUVuZg44KTBCmKc9Z5OCXLB5UXeO6Io5Qr5Sgxs4W2N4EvPhH0QgzhMBz+TjcRHLxWFiY6eAJNexDx9oD1SRHqGvERNjtKKdrcDMC+Y3cZ2Lfib5xBRERc8LD8MJkdN3eiZsTmSI9PfgxyhbeK4LgxiFGGAwTWfZCnkBjrVqnZNfovuxdmb1LPJdY1LWszL5pdVDApaA6sKLUQDJLHmGEVbjo5SWqhHDEEImcy2EGIPXIwTMr3TnH8e+v7fX1+Ho+od/F53q0nBDlxgZViTqWKA5CoB/mUmFqZ7VuUF0QGOE/IAYb9k0BGuMiviBGw9/zV1/o12dabbNyhcb1ndc2PJCQD74a76QtDMsXs7axaWsoTui5pYUpz6i1EhFlMhyj/kIQ4+olFJBLCulgwitwxksQYDJxo7w9RxWwYRqeidIQugD7D0Vzb0KAnFT8o1gm6vAsJ/1/JEKMrbqW0W2MvsCmpIOM2ylb/YyQjJlo03GgGg8NbjtGlIypzpD+jYNaep5lhtSw1TQpD40GuLJvsrjpNZ0fHd7O/r74vuXu0/EgoyIZIJDYr06M/piM2rubUa5eazCxyHMqPy6ZY7W7eVkMrq+/P6Z/u2wcSRsWMYxsWFUYGPyeTwmlx06joQOe9geOpSGxVEARPTIM/+Vuyg5Xzr1is8cZ1DwjCvdYlKq4fbW8XHVa4u6fm5O+ZZC91y2nzuc+bvcidDMM6vYKPHlWb18AEpwlU1d8EfkrhJtSF29wHHeqcuq1XzMI8yh/gSjtY87OmmRTnStf2Q+0UvDPv+tgR+d3E1/wBlmQJki5EMQdBBpEyK8yfEgonJK5Oi5MQBLqnRfLn2gS70HOjRcXGyyM1wuPYksqiMYvtl4u9mFCd5qmKBolbnrVBVM5VH6w08ss4R7VxThJ4l7z6j3viPduqS7m8Tqx9rNevBojnf7EjwKAVDOg10YtOM35k0WVx22IlvkqPKJTRFcaU5RQXC7Y/sd2e1Fdv3a0CmPiCqh0hjZGaY05vtmFnPgcEG0iOV6jTlPuC2f3KvM/gWuOMFr8ADPYdKRzmUxe7symKWUkM8p7gTAkVOGumYVGMkxBJzkUoZS45SWUndNwF7daEzJW7QVijFkM34fgiACM+yh4GMIXcJHGHZ2vLPjPNMu7gtShABMpSuqN2XJFcn4xJJjYphOzkHwOJrNyEjguxUMAQV2FzI6oEE3DmHQ1ZDpN4WYslRWF1h8Oyix6hJLY7wirxBOaZtoTEziHIXbD0HkuZCVPBgJXEPsGeEaqlFD4006TB0VU3ZNTPUPgKmbR/P2ycb66MuH6L/N4CvCo+fTgRJS1FBdobACSR12joodXa9LSEZD4LF3gecCRrPQW1GgdOh5g+jhPsfR0DPchZ5bsoRYdLh5g7ix5Cx8u7iRd/XkcPONoKSDzRuEjV13jXUA2Ki9ZzmByJ1gCQ1dOOm9hpN0Me89kJ2sdjOb5kCCZxvHiPjWx7SQHAja4zwQA0QxIVA6RJU7Hvn8PXCYXj66IwQU03X/3hsb+8WOTHERVxJL3/uskaZ+4bL3kurbpgDS1x1OUo+evFb4swEjnFKBaIaXxHjGM0NlZIuzJU8/1mFYxXCqWUV55qaxUNLwqKSSP1hYbzv1blZRH3rkycNDJwz5PK6kLKOZzKI0owfCaUP9pZTVNys6OhBlWUK60hq2wEDOcSCfIhetYu+9iFyRbArJ+NL5olfMl1pWtnS/bdNwNYdmkQ21eiiTs96iJRMTNCW43xeu6UkW4TmHwqtymSsH++Xz5L+twbREIlLFOhsymOrRkHO6dKP2vNtT2C0eSxePqcffxuJRDVuZRTrYdrCtgO3w6LA1JNgqzrbkMkxv4zhLh/FfB+Pa0TH++k28r/j3QHw5XGel3HosML8C35V4zq9mdvJI4zFD4TSB2dC6WYpN2hWhPv119U39sKFB9SDJe361s7N3tNgRo4MqblKd3W9usWP9OtRUERh8IXW9nJqGdamppWBLXzR8TkPUJCbOHGs31YjvZbVBNfJ2t3dONYoVartUI+eFlnTrzzseEkveKdHukBwnN/RbOKZOXfbXG2H/vUnbFP09ezdpi/WdNkhb3vD1zklbEZ9plSEUR5W3EMghxfczIk5jnE2K2T+DT6ZU9g/3zcv/AQ== diff --git a/docs/images/ArchitectureSequenceDiagram.png b/docs/images/ArchitectureSequenceDiagram.png index 5b03c3638cf..e61f48a88d4 100644 Binary files a/docs/images/ArchitectureSequenceDiagram.png and b/docs/images/ArchitectureSequenceDiagram.png differ diff --git a/docs/images/BudgetClassDiagram.png b/docs/images/BudgetClassDiagram.png index 63090f45328..54049c57b5c 100644 Binary files a/docs/images/BudgetClassDiagram.png and b/docs/images/BudgetClassDiagram.png differ diff --git a/docs/images/DisplayActivityDiagram.png b/docs/images/DisplayActivityDiagram.png index f4bbd36402b..536c4da646a 100644 Binary files a/docs/images/DisplayActivityDiagram.png and b/docs/images/DisplayActivityDiagram.png differ diff --git a/docs/images/DisplaySequenceDiagram.png b/docs/images/DisplaySequenceDiagram.png index 802e7eeae63..c524312f697 100644 Binary files a/docs/images/DisplaySequenceDiagram.png and b/docs/images/DisplaySequenceDiagram.png differ diff --git a/docs/images/FilterClassDiagram.png b/docs/images/FilterClassDiagram.png index dadaa2b593c..89190a13e47 100644 Binary files a/docs/images/FilterClassDiagram.png and b/docs/images/FilterClassDiagram.png differ diff --git a/docs/images/LedgerOperationDiagram.png b/docs/images/LedgerOperationDiagram.png index e7639260bf9..e6b124bef19 100644 Binary files a/docs/images/LedgerOperationDiagram.png and b/docs/images/LedgerOperationDiagram.png differ diff --git a/docs/images/LedgerUI.png b/docs/images/LedgerUI.png index 585eaa4c686..0515ba7b2de 100644 Binary files a/docs/images/LedgerUI.png and b/docs/images/LedgerUI.png differ diff --git a/docs/images/LogicClassDiagram.png b/docs/images/LogicClassDiagram.png index d1a05cbf2b6..28069221dfe 100644 Binary files a/docs/images/LogicClassDiagram.png and b/docs/images/LogicClassDiagram.png differ diff --git a/docs/images/ModelClassDiagram.png b/docs/images/ModelClassDiagram.png index 193ab2ea6d7..36cde2e6128 100644 Binary files a/docs/images/ModelClassDiagram.png and b/docs/images/ModelClassDiagram.png differ diff --git a/docs/images/ProjectActivityDiagram.png b/docs/images/ProjectActivityDiagram.png index 5bce3721c6b..483db49a156 100644 Binary files a/docs/images/ProjectActivityDiagram.png and b/docs/images/ProjectActivityDiagram.png differ diff --git a/docs/images/ProjectSequenceDiagram.png b/docs/images/ProjectSequenceDiagram.png index 06d82fede43..3ba46bd75b5 100644 Binary files a/docs/images/ProjectSequenceDiagram.png and b/docs/images/ProjectSequenceDiagram.png differ diff --git a/docs/images/Split.png b/docs/images/Split.png index 8358909ffae..58e2fc79a71 100644 Binary files a/docs/images/Split.png and b/docs/images/Split.png differ diff --git a/docs/images/SplitBehaviour.png b/docs/images/SplitBehaviour.png index 7a516b24fa7..52dddea15ef 100644 Binary files a/docs/images/SplitBehaviour.png and b/docs/images/SplitBehaviour.png differ diff --git a/docs/images/SplitEven1.png b/docs/images/SplitEven1.png index 19be3acd2ac..f001bdbc3f6 100644 Binary files a/docs/images/SplitEven1.png and b/docs/images/SplitEven1.png differ diff --git a/docs/images/SplitEven2.png b/docs/images/SplitEven2.png index 9c9dcbc2fc1..563267fe6d6 100644 Binary files a/docs/images/SplitEven2.png and b/docs/images/SplitEven2.png differ diff --git a/docs/images/SplitUneven1.png b/docs/images/SplitUneven1.png index 81713a02b0e..fd023c03c8e 100644 Binary files a/docs/images/SplitUneven1.png and b/docs/images/SplitUneven1.png differ diff --git a/docs/images/SplitUneven2.png b/docs/images/SplitUneven2.png index f66b099d047..097cb8d4848 100644 Binary files a/docs/images/SplitUneven2.png and b/docs/images/SplitUneven2.png differ diff --git a/docs/images/StorageClassDiagram.png b/docs/images/StorageClassDiagram.png index d83646b2b2f..3989f2f88b3 100644 Binary files a/docs/images/StorageClassDiagram.png and b/docs/images/StorageClassDiagram.png differ diff --git a/docs/images/Ui.png b/docs/images/Ui.png index 66f94b2dbae..813317ffa9a 100644 Binary files a/docs/images/Ui.png and b/docs/images/Ui.png differ diff --git a/docs/images/UiClassDiagram.png b/docs/images/UiClassDiagram.png index d25a1e63e04..36d9a8ecad9 100644 Binary files a/docs/images/UiClassDiagram.png and b/docs/images/UiClassDiagram.png differ diff --git a/docs/images/approachingBudget.png b/docs/images/approachingBudget.png index 3510e80e5ca..0aa21009cfb 100644 Binary files a/docs/images/approachingBudget.png and b/docs/images/approachingBudget.png differ diff --git a/docs/images/budgetAffected.png b/docs/images/budgetAffected.png new file mode 100644 index 00000000000..2e2da8b8919 Binary files /dev/null and b/docs/images/budgetAffected.png differ diff --git a/docs/images/dg_gui_example.png b/docs/images/dg_gui_example.png new file mode 100644 index 00000000000..813317ffa9a Binary files /dev/null and b/docs/images/dg_gui_example.png differ diff --git a/docs/images/display1.png b/docs/images/display1.png index bae62f946fa..acd22d4aaae 100644 Binary files a/docs/images/display1.png and b/docs/images/display1.png differ diff --git a/docs/images/display2.png b/docs/images/display2.png index 5107fef39d7..92577e72231 100644 Binary files a/docs/images/display2.png and b/docs/images/display2.png differ diff --git a/docs/images/display3.png b/docs/images/display3.png index 45c81860bf1..bc7d709aa4a 100644 Binary files a/docs/images/display3.png and b/docs/images/display3.png differ diff --git a/docs/images/filter1.png b/docs/images/filter1.png index 302e37e8215..48d199a83c3 100644 Binary files a/docs/images/filter1.png and b/docs/images/filter1.png differ diff --git a/docs/images/filter2.png b/docs/images/filter2.png index 571e4ee6309..e8025bb404f 100644 Binary files a/docs/images/filter2.png and b/docs/images/filter2.png differ diff --git a/docs/images/filter3.png b/docs/images/filter3.png index b4fed39fddb..111a07f44d5 100644 Binary files a/docs/images/filter3.png and b/docs/images/filter3.png differ diff --git a/docs/images/newOutTransaction.png b/docs/images/newOutTransaction.png new file mode 100644 index 00000000000..4c75db0ca58 Binary files /dev/null and b/docs/images/newOutTransaction.png differ diff --git a/docs/images/project1.png b/docs/images/project1.png index f53f9e749ef..6656537c03d 100644 Binary files a/docs/images/project1.png and b/docs/images/project1.png differ diff --git a/docs/images/project2.png b/docs/images/project2.png index cc1e55c81fc..19e532db2de 100644 Binary files a/docs/images/project2.png and b/docs/images/project2.png differ diff --git a/docs/images/project3.png b/docs/images/project3.png index b55a0e29613..884ee8fe8fb 100644 Binary files a/docs/images/project3.png and b/docs/images/project3.png differ diff --git a/docs/images/project4.png b/docs/images/project4.png index 20875bc6faa..424312dd09e 100644 Binary files a/docs/images/project4.png and b/docs/images/project4.png differ diff --git a/docs/images/project5.png b/docs/images/project5.png new file mode 100644 index 00000000000..a4297617568 Binary files /dev/null and b/docs/images/project5.png differ diff --git a/docs/images/project6.png b/docs/images/project6.png new file mode 100644 index 00000000000..b1c37da4fe5 Binary files /dev/null and b/docs/images/project6.png differ diff --git a/docs/images/project7.png b/docs/images/project7.png new file mode 100644 index 00000000000..059390b8eaf Binary files /dev/null and b/docs/images/project7.png differ diff --git a/docs/images/project8.png b/docs/images/project8.png new file mode 100644 index 00000000000..db200b56107 Binary files /dev/null and b/docs/images/project8.png differ diff --git a/docs/images/redo1.png b/docs/images/redo1.png index 4c4021034d0..5318b536f5c 100644 Binary files a/docs/images/redo1.png and b/docs/images/redo1.png differ diff --git a/docs/images/redo2.png b/docs/images/redo2.png index 21012f03c54..aceb0d9927e 100644 Binary files a/docs/images/redo2.png and b/docs/images/redo2.png differ diff --git a/docs/images/redo3.png b/docs/images/redo3.png index 995e29f4db7..20c84844293 100644 Binary files a/docs/images/redo3.png and b/docs/images/redo3.png differ diff --git a/docs/images/set_dg_1.png b/docs/images/set_dg_1.png new file mode 100644 index 00000000000..e92150c015b Binary files /dev/null and b/docs/images/set_dg_1.png differ diff --git a/docs/images/set_dg_2.png b/docs/images/set_dg_2.png new file mode 100644 index 00000000000..340cf94dc67 Binary files /dev/null and b/docs/images/set_dg_2.png differ diff --git a/docs/images/sort_dg_1.png b/docs/images/sort_dg_1.png index e3bbda4145a..4298bde5321 100644 Binary files a/docs/images/sort_dg_1.png and b/docs/images/sort_dg_1.png differ diff --git a/docs/images/sort_dg_3.png b/docs/images/sort_dg_3.png index 47b9ad811ca..ecd3951afba 100644 Binary files a/docs/images/sort_dg_3.png and b/docs/images/sort_dg_3.png differ diff --git a/docs/team/Berttwm.html b/docs/team/Berttwm.html new file mode 100644 index 00000000000..cd4f61accf6 --- /dev/null +++ b/docs/team/Berttwm.html @@ -0,0 +1,1103 @@ + + + + + + + +Bertrand Tan - Project Portfolio + + + + + +
+
+

Project: PalPay

+
+ +
+
+
+

Overview

+
+
+

This portfolio documents my contributions to PalPay, a software engineering project under the module, +CS2103T Software Engineering. My Team and I were tasked to morph an existing software application into a functional desktop application, written in Java, to better suit our intended target issues and audiences.

+
+
+

PalPay is a financial tracking application activated through a Command-Line-Interface (CLI). Our intended target audience being computing students who lack a centralized platform for financial management and planning.

+
+
+

For the project, my main role was to develop the Transaction feature. +This feature represents the fundamental user logging and tracking capabilities that other features of this application subsequently depends on.

+
+
+
+
+

Summary of contributions

+
+
+
    +
  • +

    Code contributed: RepoSense

    +
  • +
  • +

    Major enhancement: Implemented the Transactions tab and the features subsumed under it.

    +
    +
      +
    • +

      What it does: Allows users to input and log their expenditure and income statements. PalPay will also display an overall transaction balance to give users an overall sensing of their financial habits.

      +
    • +
    • +

      Justification: This feature fulfills the primary goal of the application which is to provide users a platform to store and log all their financial statements in a fast and intuitive manner.

      +
    • +
    • +

      Highlights: This feature requires constant integration with all existing major features of PalPay (i.e. out Transaction to affect budget if certain conditions are met). This requires constant cross-examination with other features and reimplementation of the codebase to ensure optimal functionality. This also requires a broad familiarity with the entire code base at all points during the development phase.

      +
    • +
    +
    +
  • +
  • +

    Minor enhancement:

    +
    +
      +
    • +

      Implemented and handled code base throughout for Update feature and UpdateTransactionDescriptor to function with all different major features.

      +
    • +
    • +

      Handled parser checks for the Amount variable for incorrect or potentially program-breaking cases. (i.e. Maximum parsed amount can only contain a value of 999,999)

      +
    • +
    +
    +
  • +
  • +

    Other contributions:

    +
    +
      +
    • +

      Project management:

      +
      +
        +
      • +

        Managed issue tracker of the group’s repository

        +
      • +
      • +

        Handled external team bug catches. (Issues : +#176, +#166, +#151, +#145, +#132, +#109)

        +
      • +
      • +

        Reviewed and merged pull requests. (Pull requests: +#251, +#234, +#147, +#122, +#101, +#79)

        +
      • +
      +
      +
    • +
    • +

      Enhancements to existing features:

      +
      +
        +
      • +

        Comprehensive Unit and Integration Tests (Pull requests: +#211, +#99)

        +
      • +
      • +

        Refactored Name model object to Description model object (Pull requests: +#111)

        +
      • +
      • +

        Implemented and integrated Update class (Pull requests: +#211, +#108, +#101)

        +
      • +
      +
      +
    • +
    • +

      Documentation:

      +
      +
        +
      • +

        Reformatted the User Guide for a more sequential flow.

        +
      • +
      • +

        Wrote the details for the following commands in the User Guide.

        +
        +
          +
        • +

          In

          +
        • +
        • +

          Out

          +
        • +
        • +

          Update

          +
        • +
        • +

          Delete

          +
        • +
        +
        +
      • +
      • +

        Created UML diagrams to help in the explanation of in / out, update and delete commands in the Developer Guide.

        +
      • +
      • +

        Included Aspect cases under Design Considerations in the Developer Guide.

        +
      • +
      +
      +
    • +
    • +

      Community:

      +
      + +
      +
    • +
    +
    +
  • +
+
+
+
+
+

Contributions to the User Guide

+
+ +++ + + + + + +

Given below are snippets of sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users.

+
+

Logging Expense : out

+
+

Have you recently made an expenditure that requires logging down? PalPay accepts all expenditure inputs through the out command. Inputting an out command will decrease the overall balance value. Your expenditure statements, just like the income statements, have the added option to be tagged under one or more categories. You can do so by including the [c/CATEGORY] parameter in your command line. All uncategorized incomes will be tagged under the GENERAL category.

+
+
+

Command Syntax

+
+

Format: out $/AMOUNT n/DESCRIPTION d/DATE [c/CATEGORY]…​

+
+
+
+
+
    +
  • +

    Users should not input negative values into AMOUNT (i.e. out $/-100 …​) as PalPay has already accounted for the difference between incomes and expenditures.

    +
  • +
  • +

    CATEGORY accepts the categories for this expenditure. An out Transaction can be created without any CATEGORY.

    +
  • +
  • +

    out updates the user’s overall balance with a net negative amount (e.g. out n/milk $/2 d/10102019 will decrease overall balance by $2)

    +
  • +
+
+
+
+
+
+

Important Details

+
+
    +
  • +

    Note that out Transactions differ from in Transactions in the display amount. The in entries are characterized by the positive value within their display box whilst the out entries are characterized by the negative values in their display box. The difference can be observed in the example usage below.

    +
  • +
  • +

    An out command will affect the remaining amount of Budget entries with similar categories within the same time period (Refer to Example 3).

    +
  • +
+
+
+
+

Example Usages

+
+
Example 3
+
+
+
out $/100 n/pants d/02012020 c/clothes
+
+
+
+
    +
  1. +

    Expenditure logging

    +
    +
      +
    • +

      Inputs an expenditure of "$100" with description set to "pants" and date set on "02/01/2020".

      +
    • +
    • +

      The income includes "clothes" under the CATEGORY field.

      +
      +
      +out ug 5 +
      +
      Figure 1. Expenditure Logging Example 3
      +
      +
    • +
    +
    +
  2. +
  3. +

    Budget with similar categories and time period.

    +
    +
      +
    • +

      Entry 3 of the Budget tab has clothes under its CATEGORY field.

      +
    • +
    • +

      Entry 3 of the Budget tab has a deadline set to "01/01/2021".

      +
      +
      +out ug 6 +
      +
      Figure 2. Budget with 'clothes' category
      +
      +
    • +
    +
    +
  4. +
  5. +

    Expenditure added

    +
    +
      +
    • +

      The expenditure is added to the bottom of the Transaction tab.

      +
    • +
    • +

      The added expenditure has a date set to 02/01/2020.

      +
    • +
    • +

      The added expenditure is tagged under the clothes category.

      +
      +
      +out ug 7 +
      +
      Figure 3. Sample Expenditure 3 Added
      +
      +
    • +
    +
    +
  6. +
  7. +

    Budget entry updated

    +
    +
      +
    • +

      The remaining amount of entry 3 of the Budget tab has decreased from "$1000" to "$900".

      +
      +
      +out ug 8 +
      +
      Figure 4. Budget entry updated
      +
      +
    • +
    +
    +
  8. +
+
+
+
+
Example Commands:
+
+
    +
  • +

    out $/100 d/01012019 n/milk c/food c/drinks

    +
  • +
  • +

    out $/29 d/29022020 n/taxi c/transport

    +
  • +
  • +

    out $/12 d/31122019 n/burger

    +
  • +
+
+
+
+
+
+

Updating Finance : update

+
+

Did you make a mistake in one of your entries? Perhaps you over counted that expenditure you made. PalPay provides you with an update feature which helps you change specific fields within your entries.

+
+
+

Command Syntax

+
+

The update feature has different implementations for different entry types. The conditions for the update feature is as follows.

+
+
+

Format (Transactions): update TYPE+INDEX [$/AMOUNT] [d/DATE] [n/ITEM] [c/CATEGORY]…​

+
+
+

Format (Budget): update TYPE+INDEX [$/AMOUNT] [d/DATE] [c/CATEGORY]…​

+
+
+

Format (Ledger): Cannot be updated

+
+
+

Format (Projections): Cannot be updated

+
+
+
+
+
    +
  • +

    At least one AMOUNT, DATE, ITEM or CATEGORY fields must be entered. You can input more than 1 of the mentioned fields (e.g. update t1 $/100 n/milk).

    +
  • +
  • +

    TYPE only accepts either t (Transaction) or b (Budget). (e.g. update t1 .. refers to updating a Transaction of index 1).

    +
  • +
  • +

    TYPE+INDEX requires the TYPE and INDEX to be placed in sequential order (e.g. update b 1 .. or update 1 .. or update 1b .. will not work).

    +
  • +
  • +

    Example: update t1 $/3000 d/10102019 will update the first transaction from the list of transactions by changing it’s AMOUNT to "$1000" and DATE to "10/10/2019".

    +
  • +
+
+
+
+
+
+

Important Details

+
+
    +
  • +

    update requires at least one field to be updated. (e.g. update t1 $/20 d/10102019 n/milk and update t1 $/10 will both be accepted).

    +
  • +
  • +

    You can only update an existing transaction, budget or projection. Nothing will be updated if the entry of "index" INDEX does not exists.

    +
  • +
  • +

    Ledger and Projection do not have an update function. If you need to change specific fields within a ledger or projection entry, you should delete the target entry and recreate a new entry with your desired fields.

    +
  • +
  • +

    You cannot change an in Transaction to an out Transaction or vice versa.

    +
  • +
  • +

    Changing an expenditure’s (out Transaction) category field to that of a Budget’s entry will reflect changes on that particular Budget entry as well. (Further explained in Example 3 below).

    +
  • +
+
+
+ + + + + +
+
Note
+
+Changing the categories of an out Transaction entry with similar categories to that of a Budget entry will reflect changes on the budget’s remaining amount in version 2.0. +
+
+
+
Example Commands:
+
+
    +
  • +

    update t1 $/20 n/coke c/drinks d/12122019

    +
  • +
  • +

    update b2 $/300

    +
  • +
  • +

    update t4 $/30 d/12102019

    +
  • +
+
+
+
+
+
+
+
+

Contributions to the Developer Guide

+
+ +++ + + + + + +

Given below are snippets of sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project.

+
+

Transaction: in / out

+
+

The Transaction abstract class allows user to input income and expense statements. Both in and out transactions requires the mandatory Amount, Description and Date fields to be appended. There is an optional Category field which can accept one or more input depending on the user specifications. +The in transactions will increase the BankAccount balance amount whilst the out transactions will reduce the BankAccount balance amount.

+
+
+

In Transactions represent the income statements inputted into Palpay.

+
+
+

Out Transactions represent the expenditure statements inputted into Palpay.

+
+
+

Current Implementation

+
+

The sequence diagram below illustrates how PalPay handles the command input in $/200 n/coke d/10102019. The arguments are parsed into the logic component where the subsequent model objects are created.

+
+
+
+InSequenceDiagram +
+
Figure 5. Sequence Diagram for Executing an InCommand
+
+
+

The in and out transaction follows the same logic flow after they are parsed.

+
+
+

The difference between in and out transactions is that the handleBalance() method called in the BankAccount results in an addAmount operation for the inTransaction and a subtractAmount operation for the OutTransaction class.

+
+
+
Example
+
+

Given that the BankAccount balance initially starts with 0 dollars.

+
+
+
    +
  • +

    in Transaction of $1000 will increase the BankAccount balance from $0 to $1000.

    +
  • +
  • +

    out Transaction of $250 will subsequently decrease the BankAccount balance from $1000 to $250.

    +
  • +
  • +

    The Activity Diagram shown below will provide a visual representation of the two routes a Transaction object can take.

    +
  • +
+
+
+
+InActivityDiagram +
+
Figure 6. Activity Diagram for In and Out Transactions
+
+
+
+
+

Design Considerations

+
+
    +
  • +

    To prevent repetitive code implementation, the Transaction abstract class is used to facilitate income and expenditure logging. Transaction is an abstract class which contains the default constructor and commonly used variables. InTransaction and OutTransaction extends the Transaction class as they typically store an amount, date, description, and a set of categories. +A code snippet of the Transaction abstract class is shown below.

    +
  • +
+
+
+
+
public abstract class Transaction {
+
+    protected Amount amount;
+    protected Date date;
+    protected Description description;
+    protected final Set<Category> categories = new HashSet<>();
+
+    public Transaction(Amount amount, Date date, Description description) {
+        this.amount = amount;
+        this.date = date;
+        this.description = description;
+    }
+
+
+
+
    +
  • +

    The balance in BankAccount and the balance in Ledger are considered two separate identities, both being encompassed under the UserState class. +Therefore user operations that deal with BankAccount implements the BankAccountOperation interface, while operations +that deal with Ledger implements the LedgerOperation interface.

    +
    +
      +
    • +

      This allows us to achieve polymorphism by overloading methods in Model to handle the different operations correctly.

      +
    • +
    • +

      This reduces code coupling as there are different models to handle different balance amounts.

      +
    • +
    +
    +
  • +
  • +

    A Transaction entry can affect a Budget which has similar categories and is within the same time period. The activity diagram bellow will further clarify this flow.

    +
    +
      +
    • +

      Only Out Transactions can affect Budget.

      +
    • +
    • +

      The activity diagram below shows how and when a Transaction object affects Budget.

      +
    • +
    +
    +
  • +
+
+
+
+OutbudgetActivityDiagram +
+
Figure 7. Activity Diagram for Out Transaction Affecting Budget
+
+
+
+
+

Update Existing Entry Feature: update

+
+

This feature currently allows users to update Transaction or Budget entries. The user is unable to perform this feature on Ledger operations. The rationale for this will be further explained in Aspect 2: Update can not edit Ledger Operations. The user is currently unable to perform this feature on Projection operations as it will be further implemented in future updates.

+
+
+

Current Implementation

+ +
+
+

Design Considerations

+
+

The update feature allows one or more fields of a Transaction or Budget to be updated. (e.g. update t1 $/2 and update t1 $/2 d/10102019 will both work as intended).

+
+
+

More often than not, users do not need to change an entire Transaction or Budget entry. This will minimize inputs from users if they do not require every single parameters of a Transaction or Budget to be changed.

+
+
+
Aspect 2: Update can not edit Ledger Operations
+
+
    +
  • +

    Alternative 1 (current choice): Update Command does not work with Ledger operations.

    +
    +
      +
    • +

      Pros: Intuitive implementation and execution for the user.

      +
    • +
    • +

      Cons: Requires excessive user operations.

      +
      +
        +
      • +

        The user has to first delete the Ledger operation that he/she wishes to change, followed by inputting the Ledger operation with the amended fields back into PalPay.

        +
      • +
      +
      +
    • +
    +
    +
  • +
  • +

    Alternative 2: Update Command to also work with Ledger operations.

    +
    +
      +
    • +

      Pros: Requires only one user command to append or change Ledger entries.

      +
    • +
    • +

      Cons: Results in convoluted implementation and user experience. This will also hinder future permeability of the Split feature.

      +
      +
        +
      • +

        Ledger operations such as split includes many repeated fields (i.e. multiple Persons and shares list).

        +
      • +
      • +

        Will require several conditional user inputs to differentiate between the various repeated entities that the user wishes to amend.

        +
      • +
      +
      +
    • +
    +
    +
  • +
+
+
+
+
+

Future Enhancements

+
+
Update feature for Projections
+
+

Currently the update feature has not been implemented for Projection operations. In future iterations of PalPay, the update feature should work seamlessly with Projection operations, similar to that of Transaction and Budget operations

+
+
+

The activity diagram below will provide a visual representation of the possible user routes using the update command after this enhancement has been implemented.

+
+
+
+UpdatefutureActivityDiagram +
+
Figure 8. Activity Diagram for Future update
+
+
+
+
+
+
+
+ + + diff --git a/docs/team/[CS2103T-W12-3][Ding YuChen]Portfolio.pdf b/docs/team/[CS2103T-W12-3][Ding YuChen]Portfolio.pdf new file mode 100644 index 00000000000..c032b32a740 Binary files /dev/null and b/docs/team/[CS2103T-W12-3][Ding YuChen]Portfolio.pdf differ diff --git a/docs/team/berttwm.adoc b/docs/team/berttwm.adoc new file mode 100644 index 00000000000..21a9bb67daa --- /dev/null +++ b/docs/team/berttwm.adoc @@ -0,0 +1,129 @@ += Bertrand Tan - Project Portfolio +:site-section: AboutUs +:imagesDir: ../images +:stylesDir: ../stylesheets +:experimental: +ifdef::env-github[] +:tip-caption: :bulb: +:note-caption: :information_source: +:warning-caption: :warning: +endif::[] + +== Project: PalPay + +== Overview + +This portfolio documents my contributions to PalPay, a software engineering project under the module, +CS2103T Software Engineering. My Team and I were tasked to morph an existing software application into a functional desktop application, written in Java, to better suit our intended target issues and audiences. + +PalPay is a financial tracking application activated through a Command-Line-Interface (CLI). Our intended target audience being computing students who lack a centralized platform for financial management and planning. + +For the project, my main role was to develop the _Transaction_ feature. +This feature represents the fundamental user logging and tracking capabilities that other features of this application subsequently depends on. + + +== Summary of contributions + +* *Code contributed*: https://ay1920s1-cs2103t-w12-3.github.io/publish-RepoSense/#search=&sort=groupTitle&sortWithin=title&timeframe=commit&mergegroup=false&groupSelect=groupByRepos&breakdown=false&tabOpen=true&tabType=authorship&tabAuthor=dingyuchen&tabRepo=AY1920S1-CS2103T-W12-3%2Fmain%5Bmaster%5D[RepoSense] + +* *Major enhancement*: Implemented the `Transactions` tab and the features subsumed under it. + +** What it does: Allows users to input and log their expenditure and income statements. PalPay will also display an overall transaction balance to give users an overall sensing of their financial habits. + +** Justification: This feature fulfills the primary goal of the application which is to provide users a platform to store and log all their financial statements in a fast and intuitive manner. + +** Highlights: This feature requires constant integration with all existing major features of PalPay (i.e. `out` Transaction to affect `budget` if certain conditions are met). This requires constant cross-examination with other features and reimplementation of the codebase to ensure optimal functionality. This also requires a broad familiarity with the entire code base at all points during the development phase. + +* *Minor enhancement*: +** Implemented and handled code base throughout for Update feature and `UpdateTransactionDescriptor` to function with all different major features. +** Handled parser checks for the `Amount` variable for incorrect or potentially program-breaking cases. (i.e. Maximum parsed amount can only contain a value of 999,999) + +* *Other contributions*: + +** Project management: +*** Managed issue tracker of the group's repository +*** Handled external team bug catches. (Issues : +https://github.com/AY1920S1-CS2103T-W12-3/main/issues/176[#176], +https://github.com/AY1920S1-CS2103T-W12-3/main/issues/166[#166], +https://github.com/AY1920S1-CS2103T-W12-3/main/issues/151[#151], +https://github.com/AY1920S1-CS2103T-W12-3/main/issues/145[#145], +https://github.com/AY1920S1-CS2103T-W12-3/main/issues/132[#132], +https://github.com/AY1920S1-CS2103T-W12-3/main/issues/109[#109]) + +*** Reviewed and merged pull requests. (Pull requests: +https://github.com/AY1920S1-CS2103T-W12-3/main/pull/251[#251], +https://github.com/AY1920S1-CS2103T-W12-3/main/pull/234[#234], +https://github.com/AY1920S1-CS2103T-W12-3/main/pull/147[#147], +https://github.com/AY1920S1-CS2103T-W12-3/main/pull/122[#122], +https://github.com/AY1920S1-CS2103T-W12-3/main/pull/101[#101], +https://github.com/AY1920S1-CS2103T-W12-3/main/pull/79[#79]) + + +** Enhancements to existing features: + +*** Comprehensive Unit and Integration Tests (Pull requests: +https://github.com/AY1920S1-CS2103T-W12-3/main/pull/211[#211], +https://github.com/AY1920S1-CS2103T-W12-3/main/pull/99[#99]) + +*** Refactored `Name` model object to `Description` model object (Pull requests: +https://github.com/AY1920S1-CS2103T-W12-3/main/pull/111[#111]) + +*** Implemented and integrated `Update` class (Pull requests: +https://github.com/AY1920S1-CS2103T-W12-3/main/pull/211[#211], +https://github.com/AY1920S1-CS2103T-W12-3/main/pull/108[#108], +https://github.com/AY1920S1-CS2103T-W12-3/main/pull/101[#101]) + + +** Documentation: +*** Reformatted the User Guide for a more sequential flow. +*** Wrote the details for the following commands in the User Guide. +**** In +**** Out +**** Update +**** Delete +*** Created UML diagrams to help in the explanation of `in / out`, `update` and `delete` commands in the Developer Guide. +*** Included **Aspect** cases under **Design Considerations** in the Developer Guide. + +** Community: +*** Reported bugs and suggestions for other teams in the module. (Examples: +https://github.com/AY1920S1-CS2103T-T13-1/main/issues/223[T13-1 #223], +https://github.com/AY1920S1-CS2103T-T13-1/main/issues/222[T13-1 #222], +https://github.com/AY1920S1-CS2103T-T13-1/main/issues/221[T13-1 #221], +https://github.com/AY1920S1-CS2103T-T13-1/main/issues/220[T13-1 #220], +https://github.com/AY1920S1-CS2103T-T13-1/main/issues/219[T13-1 #219], +https://github.com/AY1920S1-CS2103T-T13-1/main/issues/216[T13-1 #216]) + +== Contributions to the User Guide + + +|=== +|_Given below are snippets of sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users._ +|=== + +include::../UserGuide.adoc[tag=out1] + +include::../UserGuide.adoc[tag=out2] + +include::../UserGuide.adoc[tag=update1] + +include::../UserGuide.adoc[tag=update2] + + +== Contributions to the Developer Guide + +|=== +|_Given below are snippets of sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project._ +|=== + +include::../DeveloperGuide.adoc[tag=transaction1] + +include::../DeveloperGuide.adoc[tag=transaction2] + +include::../DeveloperGuide.adoc[tag=update1] + +include::../DeveloperGuide.adoc[tag=update2] + +include::../DeveloperGuide.adoc[tag=update3] + + + diff --git a/docs/team/berttwm.pdf b/docs/team/berttwm.pdf new file mode 100644 index 00000000000..6ad0c253e9f Binary files /dev/null and b/docs/team/berttwm.pdf differ diff --git a/docs/team/dingyuchen.adoc b/docs/team/dingyuchen.adoc index ce82e79311b..83725e0479f 100644 --- a/docs/team/dingyuchen.adoc +++ b/docs/team/dingyuchen.adoc @@ -32,11 +32,8 @@ Our application aims to solve this pain point by providing a simple way to keep ** Highlights: The `Ledger` tab has a split screen user interface, for the user to keep track of unpaid dollars and each transaction recorded between friends. -The `Ledger` will only display people with outstanding balances on the left side of the screen, while -transactions are listed on the right. - -.The Ledger Interface -image::LedgerUI.png[] +The `Ledger` will only display people with outstanding balances on the *left* side of the screen, while +transactions are listed on the *right*. (See below) * *Minor enhancement*: added checks and improved error messages for handling `Amount`. diff --git a/docs/team/dingyuchen.html b/docs/team/dingyuchen.html new file mode 100644 index 00000000000..12668dd834a --- /dev/null +++ b/docs/team/dingyuchen.html @@ -0,0 +1,1007 @@ + + + + + + + +Ding YuChen- Project Portfolio + + + + + +
+
+

1. Overview

+
+
+

This portfolio documents my contributions to PalPay, a software engineering project under the module, +CS2103T Software Engineering. PalPay is an expenditure tracking application. +The user interacts with it using a CLI, and it has a GUI created with JavaFX. It is written in Java, and has about 10 kLoC

+
+
+

For the project, my main role was to implement the Split features, which allow the user to record +when bills are split between friends and when they settle up.

+
+
+
+
+

2. Summary of contributions

+
+
+
    +
  • +

    Code contributed: RepoSense

    +
  • +
  • +

    Major enhancement: Implemented the Ledger tab and functions associated with it.

    +
    +
      +
    • +

      What it does:

      +
      +
        +
      • +

        Allow user to split a bill easily between people. This can be by shares, or evenly, with or without including the user.

        +
      • +
      • +

        Allow individuals to settle up.

        +
      • +
      +
      +
    • +
    • +

      Justification: In our target demographic, many express that keep track of transactions between friends. +Our application aims to solve this pain point by providing a simple way to keep track of debts.

      +
    • +
    • +

      Highlights: The Ledger tab has a split screen user interface, for the user to keep track +of unpaid dollars and each transaction recorded between friends. +The Ledger will only display people with outstanding balances on the left side of the screen, while +transactions are listed on the right. (See below)

      +
    • +
    +
    +
  • +
  • +

    Minor enhancement: added checks and improved error messages for handling Amount.

    +
  • +
  • +

    Other contributions:

    +
    +
      +
    • +

      Project management:

      +
      +
        +
      • +

        Authored and assigned multiple issues. (Issues: +#226, +#199, +#197, +#136 +)

        +
      • +
      • +

        Reviewed and merged pull requests. +(Pull requests: #70, +#133)

        +
      • +
      • +

        Fixed numerous bugs. (Examples: +#186, +#185 +)

        +
      • +
      +
      +
    • +
    • +

      Enhancements to existing features:

      +
      +
        +
      • +

        Refactor Transactions into Operations, such that the Model can be overloaded +to achieve polymorphism. (Pull requests: #95)

        +
      • +
      • +

        Refactor VersionedBankAccount into VersionedUserState that allows for the integration of the Ledger +class, without associating the balances of BankAccount and Ledger. +(Pull request: +#133)

        +
      • +
      • +

        Wrote comprehensive unit test cases for the Split and Receive commmands and parsers. +(Pull requests: #70, +#114, +#202, +#205)

        +
      • +
      +
      +
    • +
    • +

      Documentation:

      +
      +
        +
      • +

        Reformatted the User Guide for a more sequential flow.

        +
      • +
      • +

        Wrote the details for the following commands in the User Guide.

        +
        +
          +
        • +

          Split

          +
        • +
        • +

          Receive

          +
        • +
        +
        +
      • +
      • +

        Created UML diagrams to help in the explanation of split and receive commands in the Developer Guide.

        +
      • +
      +
      +
    • +
    • +

      Community:

      +
      + +
      +
    • +
    +
    +
  • +
+
+
+
+
+

3. Contributions to the User Guide

+
+ +++ + + + + + +

Given below are sections I contributed to the User Guide. +They showcase my ability to write documentation targeting end-users.

+
+

3.1. Splitting a Bill with Friends : split

+
+

Split a bill with your friends
+Format: split $/AMOUNT n/NAME1 a/DESCRIPTION [d/DATE] [n/NAME2]…​ [s/SHARE]…​

+
+
+
+
+
    +
  • +

    DESCRIPTION is prefixed with a/, unlike for other commands

    +
  • +
  • +

    [SHARE] defines portion of bill to be paid by each person

    +
    +
      +
    • +

      if no shares are given, AMOUNT will be split evenly across all people, including user

      +
    • +
    • +

      you are included in the bill if number of shares is 1 more than number of people

      +
      +
        +
      • +

        your share of the bill will be the first listed share

        +
      • +
      +
      +
    • +
    • +

      each person’s share is assigned in order

      +
      +
        +
      • +

        i.e. last person’s share is the last share listed

        +
      • +
      +
      +
    • +
    +
    +
  • +
+
+
+
+
+ + + + + +
+
Caution
+
+Shares can be 0 but result is not guaranteed to be meaningful +
+
+
+
Ledger GUI
+
+
+LedgerUI +
+
Figure 1. Sample Ledger Graphical User Interface
+
+
+

This is how the Ledger looks when you switch to the splits tab.
+The left shows the people who has unresolved balances with you, while the right lists +all transactions that have to do with the Ledger.
+Ledger's balance is separate from PalPay’s balance. It is displayed in the same position, +at the bottom right corner.

+
+
+ + + + + +
+
:information_source:
+
+split does not include how much you spent into the Ledger balance. +
+
+
+
+

3.1.2. Example Usage

+
+
    +
  • +

    split $/1000 n/Amy n/Betty n/Catherine n/Dan a/haidilao

    +
    +
    +
    $1000 is split equally between Amy, Betty, Catherine, Dan and the user.
    +
    +
    +
    +
      +
    1. +

      Enter appropriate command into the command line.

      +
      +
      +SplitEven1 +
      +
      Figure 2. Input for Splitting Evenly
      +
      +
    2. +
    3. +

      Result is displayed accordingly

      +
      +
      +SplitEven2 +
      +
      Figure 3. Amy, Betty, Catherine and Dan owes $200 each
      +
      +
      +

      For an even split of $1000, each person pays $200. Therefore Ledger shows $200 on the tab of each person. +Ledger balance does not include how much you spend. In this bill, one is owed $800 in total +from the rest of his friends. Therefore Ledger balance is -$800, as shown in the bottom right.

      +
      +
    4. +
    +
    +
  • +
  • +

    split $/100 n/Albert n/Bernard n/Clement s/2 s/1 s/7 a/kbbq dinner

    +
    +
    +
    $100 is split with Albert owing $20, Bernard owing $10 and Clement owing $70.
    +
    +
    +
    +
      +
    1. +

      Enter appropriate command into the command line.

      +
      +
      +SplitUneven1 +
      +
      Figure 4. Input for Splitting Unevenly
      +
      +
    2. +
    3. +

      Result is displayed accordingly

      +
      +
      +SplitUneven2 +
      +
      Figure 5. Display of Correctly Assigned Amounts
      +
      +
      +

      Since the number of shares is equal to the number of people listed, you are not included in the splitting of the bill.

      +
      +
    4. +
    +
    +
  • +
+
+
+
+
+

3.2. Receiving Money from a Friend : receive

+
+

Receives money from a friend
+Format: receive $/AMOUNT n/NAME1 [d/DATE] [a/DESCRIPTION]

+
+
+

3.2.1. Example Usage

+
+
    +
  • +

    receive $/20 n/Albert

    +
    +
    +
    Transfers $20 from Albert to user. If Albert is no longer owe or is owed money, he will be removed from the Ledger.
    +
    +
    +
    +
      +
    1. +

      Enter appropriate command into the command line.

      +
      +
      +Receive1 +
      +
      Figure 6. Input for Receiving $20 from Albert
      +
      +
    2. +
    3. +

      Result is displayed accordingly.

      +
      +
      +Receive2 +
      +
      Figure 7. Result of Payment from Albert
      +
      +
      +

      Albert is removed from the Ledger since he no longer owes any money. Ledger balance is also updated accordingly.

      +
      +
    4. +
    +
    +
  • +
+
+
+
+
+
+
+

4. Contributions to the Developer Guide

+
+ +++ + + + + + +

Given below are sections I contributed to the Developer Guide. +They showcase my ability to write technical documentation and the technical depth of my contributions to the project.

+
+

4.1. Split Feature: split

+
+

This feature allows the user to pay for a certain item or make a transaction on behalf of his friends. +Refer to the UserGuide for usage details.

+
+
+

4.1.1. Current Implementation

+
+

The split command is an abstraction of LendMoney class.
+Given a list of shares and people, each person is assigned an amount based on the corresponding positional share and the total amount given to split command.
+A LendMoney instance is created for each person and executed.

+
+
+

Below shows how a typical command from the user is executed by the program.

+
+
+
+Split +
+
Figure 8. Sequence Diagram for Executing a SplitCommand
+
+
+

Step 1: User enters split $/200 n/a n/b n/c a/desc into the command line to split $200 among a, b and c.

+
+
+

Step 2: Upon executing the command, LogicManager uses MainParser#parse() to parse the input from the user.

+
+
+

Step 3: MainParser determines that user input is an instance of a SplitCommand and creates a SplitCommandParser +to further parse the input.

+
+
+

Step 4: SplitCommandParser parses the command and checks if fields like amount and names are valid. +If all fields are valid, it returns a SplitCommand. Else, an error is thrown to the result box and the execution +terminates.

+
+
+

Step 5: LogicManager uses SplitCommand#execute() to update the balances of Ledger and people involved in the +transaction.

+
+
+

Step 6: SplitCommand#execute() calls Model#add() to add the user input into the user history. +Within the function call, the actual update of balances is handled in Ledger#handleOperation().

+
+
+

Step 7: SplitCommand calls Model#commitUserState() after executing to save the latest state of the application.

+
+
+

Step 8: A CommandResult is then returned to the LogicManager which is then displayed to the user.

+
+
+
+SplitBehaviour +
+
Figure 9. Activity Diagram for Creating a Split Object
+
+
+
+

4.1.2. Design Considerations

+
+

Below shows how the classes involved with Ledger interact with each other.

+
+
+
+LedgerOperationDiagram +
+
Figure 10. Class Diagram for Operations that Deal with Ledger
+
+
+

Current implementation of Split class encourages code reuse by abstracting the delegating the task of rebalancing to another class.
+However, this introduces coupling as the behavior of Split is now inexplicably tied to LendMoney.

+
+
+
+
+

4.2. Settle Up Feature: receive

+
+

This feature allows another person to send money to the user.
+The balance in the Ledger and the balance of the sender is updated accordingly.

+
+
+

4.2.1. Current Implementation

+
+

The receive command creates ReceiveMoney class that handles the transfer of fund from another person to the user.

+
+
+

How receive relates to the rest of the Ledger classes can be inferred from the +class diagram above.

+
+
+

In the handleBalance method of ReceiveMoney, it will find the correct person in the Ledger by name, +or create a new Person with given name if it is not already in the Ledger.
+Balance of the user and the sender is then updated accordingly.

+
+
+

Below is an example usage scenario for how receive would behave.

+
+
+

Step 1: User enters receive $/200 n/a into the command line to settle up $200 from a.

+
+
+

Step 2: Upon executing the command, LogicManager uses MainParser#parse() to parse the input from the user.

+
+
+

Step 3: MainParser determines that user input is an instance of a ReceiveCommand and creates a ReceiveCommandParser +to further parse the input.

+
+
+

Step 4: ReceiveCommandParser parses the command and checks if fields like amount and names are valid. +If all fields are valid, it returns a ReceiveCommand. Else, an error is thrown to the result box and the execution +terminates.

+
+
+

Step 5: LogicManager uses ReceiveCommand#execute() to update the balances of Ledger and the person in the +transaction.

+
+
+

Step 6: ReceiveCommand#execute() calls Model#add() to add the user input into the user history. +Within the function call, the person in Ledger is found and his/her outstanding balance is updated in Ledger#handleOperation().
+If he is not already inside the Ledger, a new Person is created with the same name.

+
+
+

Step 7: SplitCommand calls Model#commitUserState() after executing to save the latest state of the application.

+
+
+

Step 8: A CommandResult is then returned to the LogicManager which is then displayed to the user.

+
+
+
Code snippet of handleBalance in ReceiveMoney
+
+
public class ReceiveMoney extends Payment {
+    @Override
+    public Amount handleBalance(Amount balance, UniquePersonList peopleInLedger) {
+        Person target = super.handleTarget(peopleInLedger);
+        target.spend(amount);
+        return balance.addAmount(amount);
+    }
+}
+
+public abstract class Payment extends Transaction implements LedgerOperations {
+    protected Person handleTarget(UniquePersonList peopleInLedger) {
+        Person personInvolved = person;
+        if (peopleInLedger.contains(person)) {
+            personInvolved = peopleInLedger.get(person).get();
+        } else {
+            peopleInLedger.add(person);
+        }
+        return personInvolved;
+    }
+}
+
+
+
+
+
+
+
+
+ + + diff --git a/docs/team/johndoe.adoc b/docs/team/johndoe.adoc deleted file mode 100644 index f39e76e49b2..00000000000 --- a/docs/team/johndoe.adoc +++ /dev/null @@ -1,72 +0,0 @@ -= John Doe - Project Portfolio -:site-section: AboutUs -:imagesDir: ../images -:stylesDir: ../stylesheets - -== PROJECT: AddressBook - Level 3 - ---- - -== Overview - -AddressBook - Level 3 is a desktop address book application used for teaching Software Engineering principles. The user interacts with it using a CLI, and it has a GUI created with JavaFX. It is written in Java, and has about 10 kLoC. - -== Summary of contributions - -* *Major enhancement*: added *the ability to undo/redo previous commands* -** What it does: allows the user to undo all previous commands one at a time. Preceding undo commands can be reversed by using the redo command. -** Justification: This feature improves the product significantly because a user can make mistakes in commands and the app should provide a convenient way to rectify them. -** Highlights: This enhancement affects existing commands and commands to be added in future. It required an in-depth analysis of design alternatives. The implementation too was challenging as it required changes to existing commands. -** Credits: _{mention here if you reused any code/ideas from elsewhere or if a third-party library is heavily used in the feature so that a reader can make a more accurate judgement of how much effort went into the feature}_ - -* *Minor enhancement*: added a history command that allows the user to navigate to previous commands using up/down keys. - -* *Code contributed*: [https://github.com[Functional code]] [https://github.com[Test code]] _{give links to collated code files}_ - -* *Other contributions*: - -** Project management: -*** Managed releases `v1.3` - `v1.5rc` (3 releases) on GitHub -** Enhancements to existing features: -*** Updated the GUI color scheme (Pull requests https://github.com[#33], https://github.com[#34]) -*** Wrote additional tests for existing features to increase coverage from 88% to 92% (Pull requests https://github.com[#36], https://github.com[#38]) -** Documentation: -*** Did cosmetic tweaks to existing contents of the User Guide: https://github.com[#14] -** Community: -*** PRs reviewed (with non-trivial review comments): https://github.com[#12], https://github.com[#32], https://github.com[#19], https://github.com[#42] -*** Contributed to forum discussions (examples: https://github.com[1], https://github.com[2], https://github.com[3], https://github.com[4]) -*** Reported bugs and suggestions for other teams in the class (examples: https://github.com[1], https://github.com[2], https://github.com[3]) -*** Some parts of the history feature I added was adopted by several other class mates (https://github.com[1], https://github.com[2]) -** Tools: -*** Integrated a third party library (Natty) to the project (https://github.com[#42]) -*** Integrated a new Github plugin (CircleCI) to the team repo - -_{you can add/remove categories in the list above}_ - -== Contributions to the User Guide - - -|=== -|_Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users._ -|=== - -include::../UserGuide.adoc[tag=delete] - -include::../UserGuide.adoc[tag=dataencryption] - -== Contributions to the Developer Guide - -|=== -|_Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project._ -|=== - -include::../DeveloperGuide.adoc[tag=undoredo] - -include::../DeveloperGuide.adoc[tag=dataencryption] - - -== PROJECT: PowerPointLabs - ---- - -_{Optionally, you may include other projects in your portfolio.}_ diff --git a/docs/team/joloong.adoc b/docs/team/joloong.adoc index 8bcb67ae2aa..3cb1aea64ca 100644 --- a/docs/team/joloong.adoc +++ b/docs/team/joloong.adoc @@ -41,6 +41,9 @@ to make changes to it. This enhancement affects existing commands and commands t I need to ensure the commands are undoable and redoable, and that there are no conflicts to the existing data in the application. +** Credit: Took some inspiration from https://se-education.org/addressbook-level4/[Address Book 4] to aid in the +development. + * *Minor enhancement*: ** *View* command for users to switch tabs without the need of a mouse to click another tab. This meets the needs @@ -68,6 +71,7 @@ https://github.com/AY1920S1-CS2103T-W12-3/main/pull/205[#205]) *** Wrote the details for the following commands in the User Guide. **** View / Sort / Filter / Undo / Redo / Clear / List / Help / Exit *** Wrote user stories in the Developer Guide. +*** Wrote the instructions for manual testing in the Developer Guide. *** Created UML diagrams to help in the explanation of view, sort and filter commands in the Developer Guide. ** Community: diff --git a/docs/team/joloong.html b/docs/team/joloong.html new file mode 100644 index 00000000000..8a64accc1a2 --- /dev/null +++ b/docs/team/joloong.html @@ -0,0 +1,1149 @@ + + + + + + + +Joel Loong - Project Portfolio + + + + + +
+
+

Project: PalPay

+
+ +
+
+
+

Overview

+
+
+

This portfolio documents my contributions to PalPay, a software engineering project under the module, +CS2103T Software Engineering. For this module, we were provided with a working software application which we +could enhance or morph to suit our target audience.

+
+
+

PalPay is a student application that effectively tackles the problem of the lack of a centralised platform to +manage their finances. Hence, PalPay provides the ability to easily track their expenses and manage their finances.

+
+
+

For the project, my main role was to develop the undo and redo feature for the application. Additionally, +I was tasked to develop the view, sort and filter features.

+
+
+
+
+

Summary of contributions

+
+
+
    +
  • +

    Code contributed: RepoSense

    +
  • +
  • +

    Major enhancement: Implemented the ability to undo and redo previous commands.

    +
    +
      +
    • +

      What it does: Undo command allows the user to undo all previous commands one at a time. Redo command reverses +preceding undo command.

      +
    • +
    • +

      Justification: It gives users the ability to easily rectify their mistakes in commands. Hence, it improves +the user experience and a more convenient way of self-correction.

      +
    • +
    • +

      Highlights: This requires a thorough understanding of the starting infrastructure of the application in other +to make changes to it. This enhancement affects existing commands and commands to be added in future. In addition, +I need to ensure the commands are undoable and redoable, and that there are no conflicts to the existing data +in the application.

      +
    • +
    • +

      Credit: Took some inspiration from Address Book 4 to aid in the +development.

      +
    • +
    +
    +
  • +
  • +

    Minor enhancement:

    +
    +
      +
    • +

      View command for users to switch tabs without the need of a mouse to click another tab. This meets the needs +of the target audiences who prefer using the command line.

      +
    • +
    • +

      Sort command for users to sort their lists of transactions in PalPay.

      +
    • +
    • +

      Filter command for users to filter their lists of transactions to reduce the need of scrolling through their lists.

      +
    • +
    +
    +
  • +
  • +

    Other contributions:

    +
    +
      +
    • +

      Project management:

      +
      +
        +
      • +

        Managed the biweekly project releases on GitHub.

        +
      • +
      • +

        Managed the issue tracker of the group repository.

        +
      • +
      • +

        Reviewed and merged pull requests.

        +
      • +
      +
      +
    • +
    • +

      Enhancements to existing features:

      +
      +
        +
      • +

        Wrote comprehensive unit and integration test cases for the application’s logic and model. +(Pull requests: #70, +#114, +#202, +#205)

        +
      • +
      +
      +
    • +
    • +

      Documentation:

      +
      +
        +
      • +

        Reformatted the User Guide for a more sequential flow.

        +
      • +
      • +

        Wrote the details for the following commands in the User Guide.

        +
        +
          +
        • +

          View / Sort / Filter / Undo / Redo / Clear / List / Help / Exit

          +
        • +
        +
        +
      • +
      • +

        Wrote user stories in the Developer Guide.

        +
      • +
      • +

        Wrote the instructions for manual testing in the Developer Guide.

        +
      • +
      • +

        Created UML diagrams to help in the explanation of view, sort and filter commands in the Developer Guide.

        +
      • +
      +
      +
    • +
    • +

      Community:

      +
      +
        +
      • +

        Reported bugs and suggestions for other teams in the module. (Examples: +#219, +#220, +#222, +#229)

        +
      • +
      • +

        Provided tips and help to other students in the module. (Examples: +#70, +#79, +#110)

        +
      • +
      +
      +
    • +
    • +

      Tools:

      +
      +
        +
      • +

        Managed the initial set up of the group repository on GitHub.

        +
      • +
      • +

        Integrated Travis CI, Coveralls, Netlify and RepoSense into the group repository.

        +
      • +
      +
      +
    • +
    +
    +
  • +
+
+
+
+
+

Contributions to the User Guide

+
+ +++ + + + + + +

Given below are sections I contributed to the User Guide. +They showcase my ability to write documentation targeting end-users.

+
+

Switching Tabs : view

+
+

Want to switch tabs without using your mouse? You can switch to another tab with the view command.

+
+
+

Command Syntax

+
+

Format: view TAB

+
+
+
+
+
    +
  • +

    TAB input only accepts transaction, budget, ledger and projection in v1.4. It is case-insensitive.

    +
  • +
+
+
+
+
+
+

Example Usage

+
+

You do not have to use your mouse in PalPay to switch tabs anymore.

+
+
+
    +
  1. +

    By default, you are in the transaction tab.

    +
    +
    +view1 +
    +
    Figure 1. Transaction Tab
    +
    +
  2. +
  3. +

    Simply type view budget in the command box and press Enter.

    +
    +
    +view2 +
    +
    Figure 2. User Input
    +
    +
  4. +
  5. +

    You can now view your budgets. Easy!

    +
    +
    +view3 +
    +
    Figure 3. Budget Tab
    +
    +
  6. +
+
+
+
+
+

Undoing the Last Command : undo

+
+

Did you accidentally delete a transaction? Do not panic! PalPay lets you undo your previous commands with just one +word, undo.

+
+
+

Command Syntax

+
+

Format: undo

+
+
+
+
+
    +
  • +

    Once you exit PalPay, you cannot undo the previous commands.

    +
  • +
  • +

    Below are the commands that are undoable:

    +
    +
      +
    • +

      in / out / set / split / receive / project / +sort / filter / update / delete / clear / list

      +
    • +
    +
    +
  • +
+
+
+
+
+
+

Example Usage

+
+

Suppose you want to update your allowance you received in October 2019 to $800 but you accidentally update the GrabTaxi +ride instead. Without going through the trouble of updating the same transaction again, you can simply perform the +undo command. Just follow these three simple steps.

+
+
+
    +
  1. +

    Here, you can see the wrong update you just made.

    +
    +
    +undo1 +
    +
    Figure 4. Transaction List Containing Erroneous Transaction
    +
    +
  2. +
  3. +

    Simply type undo in the command box and press Enter.

    +
    +
    +undo2 +
    +
    Figure 5. User Input for Undo Command
    +
    +
  4. +
  5. +

    As you wish, your command has been undone.

    +
    +
    +undo3 +
    +
    Figure 6. Erroneous Transaction Has Been Undone
    +
    +
  6. +
+
+
+
+
+
+
+

Contributions to the Developer Guide

+
+ +++ + + + + + +

Given below are sections I contributed to the Developer Guide. +They showcase my ability to write technical documentation and the technical depth of my contributions to the project.

+
+

Sort Feature: sort

+
+

This feature allows the user to sort their transactions by amount or date, in ascending and descending order.

+
+
+

Current Implementation

+
+

The sort command is facilitated by the Logic and Model components of the application.

+
+
+

The following sequence diagram shows how the sorting of transactions work when the user enters sort date/d.

+
+
+
+SortSequenceDiagram +
+
Figure 7. Sequence Diagram for sort date/d
+
+
+
+

Example of Usage

+
+

Given below is an example usage of how sort behaves at each step.

+
+
+

Step 1. The user launches the application and views an unsorted list of transactions.

+
+
+
+sort dg 1 +
+
Figure 8. Initial State of PalPay
+
+
+

Step 2. The user now executes sort date/d to sort the transactions in the order of descending date.

+
+
+
+sort dg 2 +
+
Figure 9. User Inputs sort date/d
+
+
+

Step 3. Upon executing the command, LogicManager uses MainParser#parse() to parse the input from the user.

+
+
+

Step 4. MainParser determines which command is being used and creates SortCommandParser to further parse the input +from the user.

+
+
+

Step 5. SortCommandParser parses the argument and checks if it is valid. If it is +invalid, SortCommandParser throws an exception and terminates. Else, it returns a SortCommand.

+
+
+

Step 6. LogicManager uses SortCommand#execute() to sort the transactions in the order of descending date.

+
+
+

Step 7. SortCommand uses ModelManager#getBankAccount() to get the current bank account and uses +BankAccount#getTransactionHistory() to get the list of transactions of the user.

+
+
+

Step 8. SortCommand uses SortCommand#sortTransactionHistory() to sort the transactions.

+
+
+

Step 9. SortCommand uses Model#set() to store the sorted transactions and Model#commitUserState() to +save the latest state of the application.

+
+
+

Step 10. SortCommand returns a CommandResult to the LogicManager and the result will be displayed to the user +at the end.

+
+
+
+sort dg 3 +
+
Figure 10. After Sorting of Transactions
+
+
+
+

Design Considerations

+
+
Aspect: Sorting of the Bank Account
+
+
    +
  • +

    Alternative 1 (Current Choice): Creating a comparator for each area to be sorted.

    +
    +
      +
    • +

      Pros: Easy to implement.

      +
    • +
    • +

      Cons: Users can only sort by comparators that have been implemented. +Developers have to create a new comparator class to sort a new area.

      +
    • +
    +
    +
  • +
  • +

    Alternative 2: Users can define the area to be sorted.

    +
    +
      +
    • +

      Pros: Extremely flexible for the users as they are not limited to the number of areas to be sorted.

      +
    • +
    • +

      Cons: Difficult to implement.

      +
    • +
    +
    +
  • +
+
+
+
+
+
+

Undo / Redo Command Feature: undo/redo

+
+

Current Implementation

+
+

The undo/redo mechanism is facilitated by VersionedUserState. +It extends UserState with an undo/redo history, stored internally as an userStateList and currentStatePointer. +Additionally, it implements the following operations:

+
+
+
    +
  • +

    VersionedUserState#commit() — Saves the current user state in its history.

    +
  • +
  • +

    VersionedUserState#undo() — Restores the previous user state from its history.

    +
  • +
  • +

    VersionedUserState#redo() — Restores a previously undone user state from its history.

    +
  • +
+
+
+

These operations are exposed in the Model interface as Model#commitUserState(), Model#undoUserState() +and Model#redoUserState() respectively.

+
+
+

Given below is an example usage scenario and how the undo/redo mechanism behaves at each step.

+
+
+

Step 1. The user launches the application for the first time. +The VersionedUserState will be initialized with the initial user state, and the currentStatePointer +pointing to that single user state.

+
+
+
+UndoRedoState0 +
+
Figure 11. Initial State
+
+
+

Step 2. The user executes delete t5 command to delete the 5th transaction in the transaction list. +The delete command calls Model#commitUserState(), causing the modified state of the user state after the +delete t5 command executes to be saved in the userStateList, and the currentStatePointer is shifted +to the newly inserted user state.

+
+
+
+UndoRedoState1 +
+
Figure 12. After delete t1 Command
+
+
+

Step 3. The user executes in $/10 n/Allowance d/07112019 to log a new transaction. +The in command also calls Model#commitUserState(), causing another modified user state to be saved +into the userStateList.

+
+
+
+UndoRedoState2 +
+
Figure 13. After in $/10 n/Allowance d/07112019 Command
+
+
+ + + + + +
+
Note
+
+If a command fails its execution, it will not call Model#commitUserState(), so the user state will +not be saved into the userStateList. +
+
+
+

Step 4. The user now decides that logging the transaction was a mistake, and decides to undo that action by +executing the undo command. The undo command will call Model#undoUserState(), which will shift the +currentStatePointer once to the left, pointing it to the previous user state, and restores the user state +to that state.

+
+
+
+UndoRedoState3 +
+
Figure 14. After undo Command
+
+
+ + + + + +
+
Note
+
+If the currentStatePointer is at index 0, pointing to the initial user state, then there are no previous +user states to restore. The undo command uses Model#canUndoUserState() to check if this is the case. +If so, it will return an error to the user rather than attempting to perform the undo. +
+
+
+

Step 5. The user then decides to execute the command list. +Commands that do not modify the user state, such as list, will usually not call Model#commitUserState(), +Model#undoUserState() or Model#redoUserState(). Thus, the userStateList remains unchanged.

+
+
+
+UndoRedoState4 +
+
Figure 15. After list Command
+
+
+

Step 6. The user executes clear, which calls Model#commitUserState(). +Since the currentStatePointer is not pointing at the end of the userStateList, all user states after +the currentStatePointer will be purged. We designed it this way because it no longer makes sense to redo the +in $/10 n/Allowance d/07112019 command. This is the behavior that most modern desktop applications follow.

+
+
+
+UndoRedoState5 +
+
Figure 16. After clear Command
+
+
+

The following sequence diagram shows how the undo operation works:

+
+
+
+UndoSequenceDiagram +
+
Figure 17. Undo Sequence Diagram
+
+
+ + + + + +
+
Note
+
+The lifeline for UndoCommand should end at the destroy marker (X) but due to a limitation of PlantUML, +the lifeline reaches the end of diagram. +
+
+
+

The redo command does the opposite — it calls Model#redoUserState(), which shifts the currentStatePointer +once to the right, pointing to the previously undone state, and restores the user state to that state.

+
+
+ + + + + +
+
Note
+
+If the currentStatePointer is at index userStateList.size() - 1, pointing to the latest user state, then +there are no undone user states to restore. The redo command uses Model#canRedoUserState() to +check if this is the case. If so, it will return an error to the user rather than attempting to perform the redo. +
+
+
+
Aspect: How Undo and Redo Executes
+
+
    +
  • +

    Alternative 1 (current choice): Saves the entire user state.

    +
    +
      +
    • +

      Pros: Easy to implement.

      +
    • +
    • +

      Cons: May have performance issues in terms of memory usage.

      +
    • +
    +
    +
  • +
  • +

    Alternative 2: Individual command knows how to undo/redo by itself.

    +
    +
      +
    • +

      Pros: Will use less memory (e.g. for delete t1, just save the transaction being deleted).

      +
    • +
    • +

      Cons: We must ensure that the implementation of each individual command are correct.

      +
    • +
    +
    +
  • +
+
+
+
+
Aspect: Which Data Structure to Support the Undo/Redo Commands
+
+
    +
  • +

    Alternative 1 (current choice): Use a list and a pointer to store the history of user states.

    +
    +
      +
    • +

      Pros: Easy for new Computer Science student undergraduates to understand, +who are likely to be the new incoming developers of our project.

      +
    • +
    • +

      Cons: Need to manage the list and pointer carefully as the pointer has to point to the correct position in +the list at all times. +For example, when a new command is executed, we must remember to update both userStateList and currentStatePointer.

      +
    • +
    +
    +
  • +
  • +

    Alternative 2: Use two stacks. One stack stores the commands to undo and the other stores the commands to redo.

    +
    +
      +
    • +

      Pros: Do not need to manage a pointer for the stacks.

      +
    • +
    • +

      Cons: Need to manage both stacks carefully. For instance, when a command is popped from the undo stack, it needs to +be pushed into the redo stack.

      +
    • +
    +
    +
  • +
+
+
+
+
+
+
+
+
+ + + diff --git a/docs/team/joloong.pdf b/docs/team/joloong.pdf new file mode 100644 index 00000000000..a2d24897fb2 Binary files /dev/null and b/docs/team/joloong.pdf differ diff --git a/docs/team/wallacelim97.adoc b/docs/team/wallacelim97.adoc new file mode 100644 index 00000000000..e0a4ae0e761 --- /dev/null +++ b/docs/team/wallacelim97.adoc @@ -0,0 +1,121 @@ += Wallace Lim - Project Portfolio +:site-section: AboutUs +:imagesDir: ../images +:stylesDir: ../stylesheets +:experimental: +ifdef::env-github[] +:tip-caption: :bulb: +:note-caption: :information_source: +:warning-caption: :warning: +endif::[] + +== Overview + +The purpose of this portfolio is to document my contributions to _PalPay_, +a software engineering project under the module +_CS2103T - Software Engineering_. PalPay is a personal finance management application developed by a team of +5 students taking the module, including myself. +It is mostly written in Java and has roughly 15,000 Lines of Code (LoC). +Being a Command Line Interface (CLI) application, it is controlled mainly through +the Command Line in the app, while displaying output through a Graphical User Interface (GUI) +written in JavaFX. + +My main role within the team was to implement the *Projection* feature, which utilizes +a machine learning algorithm to predict the user's account balance and budget statuses at a specified point of time +in the future. I was also in charge of implementing the *Display* feature, which +further enhances the *Projection* feature by providing users with a graphical +representation of their balance and budget states. + +== Summary of contributions + +* *Code contributed*: My contributions to _PalPay_ can be viewed here - https://ay1920s1-cs2103t-w12-3.github.io/publish-RepoSense/#search=wallacelim97&sort=groupTitle&sortWithin=title&timeframe=commit&mergegroup=false&groupSelect=groupByRepos&breakdown=false&tabOpen=true&tabType=authorship&tabAuthor=wallacelim97&tabRepo=AY1920S1-CS2103T-W12-3%2Fmain%5Bmaster%5D[RepoSense] + +* *Major enhancement*: Implemented the `Projection` feature, along with various functions associated with it. + +** What it does: +*** Uses the https://en.wikipedia.org/wiki/Gradient_descent[Gradient Descent] algorithm to project the user's account balance +in the future +*** Allows users to predict whether they will meet their budget goals based on past income/outflow trends + +** Justification: While most finance tracking applications have relatively robust income/outflow tracking functions, +few offer the ability to project future financial states - something which is sorely needed +for effective financial planning + +** Highlights: By utilizing the Gradient Descent algorithm, the `Projection` feature is guaranteed to find the best-fit projection +line graph based on past transactions, with an extremely minute error tolerance (= 1E-11). +The feature also automatically adjusts all relevant projections whenever transactions or budgets +are added, deleted or updated, offering considerable convenience to the user, who thus does not need to update +them manually. + +* *Minor enhancement*: Developed the `display` feature, which offers an elegant, graphical representation +of the user's projections. + +* *Other contributions*: + +** Project management: +*** Authored and assigned multiple issues. (Issues: +https://github.com/AY1920S1-CS2103T-W12-3/main/issues/82[#82], +https://github.com/AY1920S1-CS2103T-W12-3/main/issues/84[#84], +https://github.com/AY1920S1-CS2103T-W12-3/main/issues/17[#17], +https://github.com/AY1920S1-CS2103T-W12-3/main/issues/19[#19], +https://github.com/AY1920S1-CS2103T-W12-3/main/issues/20[#20] +) +*** Reviewed and merged pull requests. +(Pull requests: https://github.com/AY1920S1-CS2103T-W12-3/main/pull/60[#60], +https://github.com/AY1920S1-CS2103T-W12-3/main/pull/23[#23]) +*** Performed optimizations and fixed numerous bugs. (Examples: +https://github.com/AY1920S1-CS2103T-W12-3/main/issues/125[#125], +https://github.com/AY1920S1-CS2103T-W12-3/main/issues/67[#67] +) + +** Enhancements to existing features: +*** Refactor `AddressBook` into `BankAccount` and `AddCommand` into `InCommand`, +such that _PalPay_ had its first entry point. (Pull requests: https://github.com/AY1920S1-CS2103T-W12-3/main/pull/27[#27]) +*** Refactor various JSON-adapted files and enabled PalPay's `Storage` functionality. +(Pull request: +https://github.com/AY1920S1-CS2103T-W12-3/main/pull/27[#27]) +*** Extended Java's in-build Date class to support parsing and comprehensive checking, +which currently supports all commands in _PalPay_ +(Pull request: +https://github.com/AY1920S1-CS2103T-W12-3/main/pull/86[#86]) + +** Documentation: +*** Wrote comprehensive documentation for the following commands in both the User Guide and the Developer Guide: +**** `project` +**** `display` +*** Created UML diagrams to help in the explanation of the `project` and `display` commands in the Developer Guide. + +** Community: +*** Reported bugs and suggestions for other teams in the module. (Examples: +https://github.com/AY1920S1-CS2103T-W13-4/main/issues/147[W13-4 #147], +https://github.com/AY1920S1-CS2103T-W13-4/main/issues/148[W13-4 #148], +https://github.com/AY1920S1-CS2103T-W13-4/main/issues/149[W13-4 #149], +) + +== Contributions to the User Guide + +|=== +|_Given below are sections I contributed to the User Guide. +They showcase my ability to write comprehensive and concise documentation for +non-technical users._ +|=== + +include::../UserGuide.adoc[tag=project] + +include::../UserGuide.adoc[tag=display1] +include::../UserGuide.adoc[tag=display2] + +== Contributions to the Developer Guide + +|=== +|_Given below are sections I contributed to the Developer Guide. +They showcase my ability design and implement complex features through code, as well as my technical competencies +in Java. +|=== + +include::../DeveloperGuide.adoc[tag=project1] +include::../DeveloperGuide.adoc[tag=project2] + +include::../DeveloperGuide.adoc[tag=display1] +include::../DeveloperGuide.adoc[tag=display2] +''' diff --git a/docs/team/wallacelim97.html b/docs/team/wallacelim97.html new file mode 100644 index 00000000000..1df210ca416 --- /dev/null +++ b/docs/team/wallacelim97.html @@ -0,0 +1,1143 @@ + + + + + + + +Wallace Lim - Project Portfolio + + + + + +
+
+

Overview

+
+
+

The purpose of this portfolio is to document my contributions to PalPay, +a software engineering project under the module +CS2103T - Software Engineering. PalPay is a personal finance management application. +It is mostly written in Java and has roughly 15,000 Lines of Code (LoC). +Being a Command Line Interface (CLI) application, it is controlled mainly through +the Command Line in the app, while displaying output through a Graphical User Interface (GUI) +written in JavaFX.

+
+
+

My main role within the team was to implement the Projection feature, which utilizes +a machine learning algorithm to predict the user’s account balance and budget statuses at a specified point of time +in the future. I was also in charge of implementing the Display feature, which +further enhances the Projection feature by providing users with a graphical +representation of their balance and budget states.

+
+
+
+
+

Summary of contributions

+
+
+
    +
  • +

    Code contributed: My contributions to PalPay can be viewed here - RepoSense

    +
  • +
  • +

    Major enhancement: Implemented the Projection feature, along with various functions associated with it.

    +
    +
      +
    • +

      What it does:

      +
      +
        +
      • +

        Uses Gradient Descent to project the user’s account balance +in the future

        +
      • +
      • +

        Allows users to predict whether they will meet their budget goals based on past income/outflow trends

        +
      • +
      +
      +
    • +
    • +

      Justification: While most finance tracking applications have relatively robust income/outflow tracking functions, +few offer the ability to project future financial states - something which is sorely needed +for effective financial planning

      +
    • +
    • +

      Highlights: By utilizing the Gradient Descent algorithm, the Projection feature is guaranteed to find the best-fit projection +line graph based on past transactions, with an extremely minute error tolerance (= 1E-11). +The feature also automatically adjusts all relevant projections whenever transactions or budgets +are added, deleted or updated, offering considerable convenience to the user, who thus does not need to update +them manually.

      +
    • +
    +
    +
  • +
  • +

    Minor enhancement: Developed the display feature, which offers an elegant, graphical representation +of the user’s projections.

    +
  • +
  • +

    Other contributions:

    +
    +
      +
    • +

      Project management:

      +
      +
        +
      • +

        Authored and assigned multiple issues. (Issues: +#82, +#84, +#17, +#19, +#20 +)

        +
      • +
      • +

        Reviewed and merged pull requests. +(Pull requests: #60, +#23)

        +
      • +
      • +

        Performed optimizations and fixed numerous bugs. (Examples: +#125, +#67 +)

        +
      • +
      +
      +
    • +
    • +

      Enhancements to existing features:

      +
      +
        +
      • +

        Refactor AddressBook into BankAccount and AddCommand into InCommand, +such that PalPay had its first entry point. (Pull requests: #27)

        +
      • +
      • +

        Refactor various JSON-adapted files and enabled PalPay’s Storage functionality. +(Pull request: +#27)

        +
      • +
      • +

        Extended Java’s in-build Date class to support parsing and comprehensive checking, +which currently supports all commands in PalPay +(Pull request: +#86)

        +
      • +
      +
      +
    • +
    • +

      Documentation:

      +
      +
        +
      • +

        Wrote comprehensive documentation for the following commands in both the User Guide and the Developer Guide:

        +
        +
          +
        • +

          project

          +
        • +
        • +

          display

          +
        • +
        +
        +
      • +
      • +

        Created UML diagrams to help in the explanation of the project and display commands in the Developer Guide.

        +
      • +
      +
      +
    • +
    • +

      Community:

      +
      + +
      +
    • +
    +
    +
  • +
+
+
+
+
+

Contributions to the User Guide

+
+ +++ + + + + + +

Given below are sections I contributed to the User Guide. +They showcase my ability to write comprehensive and concise documentation for +non-technical users.

+
+

Projecting Future Balance and Budgets : project

+
+

Cast a projection on your future balance amount and budget statuses based on your transaction history.

+
+
+

Format: project d/DATE [c/CATEGORY]

+
+
+ + + + + +
+
Note
+
+If a CATEGORY is not specified, it will be set as GENERAL by default. GENERAL projections project +upon ALL transactions, regardless of their categories. +
+
+
+

Example Usage

+
+
    +
  1. +

    project d/22072020

    +
    +
    +
    Projected balance: $955.80
    +
    +
    +
  2. +
  3. +

    project d/01012020 c/Food

    +
    +
    +
    Projected balance: $188.04
    +You are on track to meeting your budget of $600 by 08122019, with a surplus of $484.32!
    +
    +
    +
  4. +
+
+
+
+

Usage Constraints

+
+
Command Format
+
+
    +
  • +

    CATEGORY must be preceded by its tag c/. +A violation of any of the above will produce the following error message:

    +
  • +
+
+
+
+
+

Invalid command format!
+project: Project future balance based on past income/outflow.
+Parameters: d/DATE [c/CATEGORY]
+Example: project d/12122103 c/Food

+
+
+
+
+
+
Date Values
+
+
    +
  • +

    DATE input must be set in the future. +A violation of this constraint will produce the following +error message:

    +
  • +
+
+
+
+
+

Invalid command usage!
+Date must be set in the future.

+
+
+
+
+
    +
  • +

    DATE cannot be more than 720 days from the day of projection.
    +A violation of this constraint will produce the following error message:

    +
  • +
+
+
+
+
+

Projections should be a maximum of 2 years (730 days) from now.

+
+
+
+
+
+
Minimum Number of Transactions
+
+
    +
  • +

    There must be a minimum of 5 transactions in total, or in the specified CATEGORY +for a projection to be successfully cast. +Should the requirement above be unmet, the following error message will be produced:

    +
  • +
+
+
+
+
+

There are no transactions in [CATEGORY]. It is impossible to cast a projection.

+
+
+ + + + + +
+
Note
+
+[GENERAL] will be displayed in place of [CATEGORY] if a CATEGORY is not specified. This is due to +the auto-casting of uncategorised projections to the GENERAL category as explained here. +
+
+
+
+
+
    +
  • +

    Should the number of transactions in a projection fall below 5, it +will be automatically deleted, as shown below:

    +
    +
      +
    1. +

      Suppose there are 5 transactions, and a GENERAL projection, which projects upon them.

      +
      +
      +project1 +
      +
      Figure 1. Five transactions under the projection tab
      +
      +
      +
      +project2 +
      +
      Figure 2. A projection which is cast based on the 5 transactions above
      +
      +
    2. +
    3. +

      If a transaction being deleted causes the number of transactions being projected upon to fall below 5, +the corresponding projection will automatically be deleted.

      +
      +
      +project3 +
      +
      Figure 3. The fifth transaction has been deleted.
      +
      +
      +
      +project4 +
      +
      Figure 4. The project earlier seen in Figure 19 has been automatically deleted.
      +
      +
    4. +
    +
    +
  • +
+
+
+
+
Valid Budget Start Dates and Deadlines
+
+

A projection will only project upon budgets with deadlines set before or equal to the projection DATE. An example +is depicted below:

+
+
+
    +
  1. +

    Suppose there is currently a general Budget with a deadline set for 28th November 2019

    +
    +
    +project5 +
    +
    Figure 5. Two Budgets with dates 20112019 and 28112019 in the "GENERAL" category
    +
    +
  2. +
  3. +

    If a general Projection is cast to 20th November 2019, it will contain +the Budget with deadline 20112019 but not 28112019, +since the projection’s DATE is earlier than 28112019.

    +
    +
    +project6 +
    +
    Figure 6. The Projection only contains the Budget with deadline 20112019
    +
    +
  4. +
+
+
+
+
Backward Projections
+
+

While it is possible in PalPay, projecting your balance amount backwards in time is not guaranteed to +produce sensible results. It is generally not advisable to do so.

+
+
+
+
+
+

Display a Projection Graph: display

+
+

Display a graphical representation of a Projection in a new window.

+
+
+

Format: display PROJECTION_ID

+
+
+

Example Usage

+
+
    +
  1. +

    Type display PROJECTION_ID into the command box and press Enter. For instance:

    +
    +
    +
    +

    display p1

    +
    +
    +
    +
  2. +
  3. +

    A new window containing a graphical representation of the specified projection will pop up.

    +
    +
    +display2 +
    +
    +
    +

    If there are any budgets associated with the projection, a corresponding graphical +representation of the budget will be additionally displayed.

    +
    +
    +
    +display3 +
    +
    +
  4. +
+
+
+
+

Interpreting the Projection graph

+
+
    +
  • +

    The X-Axis
    +The X-Axis denotes your balance in dollars ($).

    +
  • +
  • +

    The Y-Axis
    +The Y-Axis denotes the number of days from now, with today being Y = 0.

    +
  • +
  • +

    Red Points
    +The red points on the graph each represent your account balance (denoted by the X-value) +at a particular point of time (denoted by the Y-value).

    +
  • +
  • +

    Blue Line Graph
    +The blue line graph represents the projection line, with each point along it representing +a prediction of your account balance (denoted by the X-value) +at a certain point of time (denoted by the Y-value).

    +
  • +
  • +

    All Other Coloured Line Graphs
    +All other coloured line graphs represent various budgets which fall within the CATEGORY and DATE range +of the PROJECTION. Each of these line graphs have three parts:

    +
  • +
+
+
+
+
+
+project8 +
+
Figure 7. A budget line graph with its parts labelled by a green, blue and yellow box each
+
+
+
    +
  1. +

    The line in the green box denotes the budget amount in dollars ($).

    +
  2. +
  3. +

    The line in the blue box denotes the budget’s duration lifetime in days.

    +
  4. +
  5. +

    The line in the yellow box denotes the budget’s projected deficit or surplus.

    +
  6. +
+
+
+
+
+
+

Usage Constraints

+
+
Valid Projection Index
+
+
    +
  • +

    A Projection with PROJECTION_ID must exist. +Attempting to display a non-existent PROJECTION will result in the following error message:

    +
  • +
+
+
+
+
+

The projection index provided is invalid.

+
+
+
+
+
+
Static Graph Rendering
+
+
    +
  • +

    Projection graphs do not update automatically when a new Transaction or Budget is +added or removed. Instead, they are statically rendered upon the display command.

    +
    + + + + + +
    +
    Note
    +
    +Due to the static nature of projection graphs, commands should NOT be executed while a projection +graph is open, lest the behaviour of PalPay become unpredictable.
    +Consequently, a display command should ALWAYS be followed by closing the projection graph window, before +any other actions are performed within PalPay. +
    +
    +
  • +
+
+
+
+
+
+
+
+

Contributions to the Developer Guide

+
+ +++ + + + + + +

_Given below are sections I contributed to the Developer Guide. +They showcase my ability design and implement complex features through code, as well as my technical competencies +in Java.

+
+

Project Feature: project

+
+

This feature allows users to project their balance amount and budget statuses based on past income and outflows as manifest in their +TransactionHistory by using the command project DATE [CATEGORY].

+
+
+

Current Implementation

+
+

The project command is facilitated by the Logic and Model components of the application, PalPay.

+
+
+

The sequence diagram below demonstrates how the project DATE [CATEGORY] command is handled by the application. +If a CATEGORY is not specified by the user, it will be set as GENERAL by default.

+
+
+
+ProjectCommand Sequence Diagram +
+
Figure 8. Sequence Diagram of the Project Command
+
+
+
Projection by Date
+
+

When projecting by date alone, all transactions in the user's transaction list will be taken into account, +regardless of their categories. On the other hand, only budgets without categories (thus belonging to the +GENERAL category by default) will be projected upon.

+
+
+
+
Projection by Date and Category
+
+

When projecting by date and category, all transactions tagged by the specified category will be taken into account. +Similarly, all budgets tagged with the specified category will be projected upon.

+
+
+
+
Budget Projections
+
+

Projections on budgets are made by first projecting the user's balance amount at the point when the budget was set. +Then, it compares the user's projected balance amount at the point of the budget’s deadline, with the budget’s amount. +A surplus is indicated when the former is greater than the latter, and a deficit is indicated when the former is smaller +than the latter. +===== Activity Diagram

+
+
+

The activity diagram below depicts how a projection is made.

+
+
+
+ProjectActivityDiagram +
+
Figure 9. Activity Diagram of the Project Command
+
+
+
+
Graphical Representation
+
+

A graphical representation of the user's projections may be rendered using the display command.

+
+
+
+
+

Future Enhancements

+
+
Polynomial Regression
+
+

For simplicity of logic and design, the current implementation performs linear regression (via gradient descent), +projecting user balance and budget states using a best-fit straight line. Ultimately, income and spending trends +may not be best represented by a straight line, but rather by a polynomial equation. In future updates, the projection +feature will choose a value, n, and perform a n-th degree polynomial regression, such that the user’s balance +and budget states can be more accurately projected.

+
+
+ + + + + +
+
Note
+
+Currently, the GradientDescent class implements feature scaling and mean normalisation. Although this +is not entirely necessary for the current implementation (which uses linear regression), it is meant +for optimizing polynomial regression in future updates. +
+
+
+
+
Normal Equation
+
+

Currently, the gradient descent algorithm is used to plot the projection graph, which is used for predicting the +user's balance and budget states at specified point in time. For smaller data sets, analytically computing the +normal equation to find the best-fit line graph may have result in a faster runtime. In future updates, the +normal equation method will be used in place of the gradient descent algorithm, for projections with less than +a set number (e.g. 500) of transactions.

+
+
+
+
+

Design Considerations

+ +
+
+
+

Display Feature: display

+
+

This feature provides a graphical view of an existing projection to the user.

+
+
+

Current Implementation

+
+

The following activity diagram depicts how the display command is executed.

+
+
+
+DisplayActivityDiagram +
+
Figure 10. Activity Diagram of the Display Command
+
+
+

For a more concrete illustration of how the display command is handled by PalPay, +a sequence diagram is provided below.

+
+
+
+DisplaySequenceDiagram +
+
Figure 11. Sequence Diagram of the Display Command
+
+
+
+
+
+
+
+ + + diff --git a/docs/team/wallacelim97.pdf b/docs/team/wallacelim97.pdf new file mode 100644 index 00000000000..011af21c5b6 Binary files /dev/null and b/docs/team/wallacelim97.pdf differ diff --git a/docs/team/yewon0303.adoc b/docs/team/yewon0303.adoc new file mode 100644 index 00000000000..cb399ab6f2c --- /dev/null +++ b/docs/team/yewon0303.adoc @@ -0,0 +1,113 @@ += Park Ye Won - Project Portfolio +:site-section: AboutUs +:sectnums: +:imagesDir: ../images +:stylesDir: ../stylesheets +:tip: :bulb: + +== Introduction +This project portfolio documents my contribution to the software project PalPay. + +=== About the team +PalPay is a project collectively done by five Sophomore Computer Science Undergraduate students +in National University of Singapore. As part of a requirement for our module - CS2103T Software Engineering, +we morphed an existing product called Address Book (Level 3) given constraints +that the user must interact with it using Command Line Interface (CLI). + +=== About the project +PalPay is a desktop application that is target to students who have limited time to keep track of their incomes +and expenditure and wish to have a simple and quick means to take charge of their finances. +Also recognising the problem faced by many students that they cannot keep track of lending and borrowing of money with friends, +PalPay offers a ledger function which keeps track of the movement of money between friends on a daily basis. + +This is what PalPay looks like: + +.PalPay's Graphical User Interface +image::dg_gui_example.png[] + + +With my role as a developer for this project, I implemented the budget function. +Understanding that many students have a poor management of their expenses, PalPay budget function allows them to set a budget +so that they can be more conscious of their expenditure. As they make expenses in that particular category, +the budget will indicate the amount of money left from the budget and serve as a constant reminder for them to make smart financial choices. + + +== Summary of contributions +This section shows a summary of my coding, documentation and other helpful contributions to the team in this project. + +*Enhancement added*: I added the ability to set a budget in the bank account +* What it does: The `set` command allows the user to set a budget until a deadline in a given category. +As the user makes `OutTransaction` s of the given category, he can see the percentage of remaining budget, as well as the number of days remaining. + +* Justification: As the user wishes to manage his expenses and restrict the overspending of money, +setting the budget is useful in allowing the user to track the outflow of his money. +Moreover, as the deadline he set approaches or upon exceeding the set budget, +the budget card displays red font which alerts the user that he needs to manage his finance better. +More details will be discussed below in the <> and <>. + +* Highlights: This enhancement is based on `Budget` class which is a build-up of the current +`Transaction` class. While `Transaction` class allows the user to key in inflows and outflows of money, +`Budget` allows the user to have an indication of the outflows in a given category. +As the two classes behaves as though `Budget` is a child class of `Transaction`, +an in-depth analysis of design alternatives was necessary to ensure that Liskov Substitution Principal +was not violated. More details will be elaborated in section Design Considerations of <> excerpt below. + + + +*Code contributed*: Please click these links to see a sample of my code: +https://ay1920s1-cs2103t-w12-3.github.io/publish-RepoSense/#search=&sort=groupTitle&sortWithin=title&timeframe=commit&mergegroup=false&groupSelect=groupByRepos&breakdown=true&tabOpen=true&tabType=authorship&tabAuthor=yewon0303&tabRepo=AY1920S1-CS2103T-W12-3%2Fmain%5Bmaster%5D[RepoSense] + + + +*Other contributions* : + +* Project management: +** Managed several issue trackers on GitHub: +(Issues: https://github.com/AY1920S1-CS2103T-W12-3/main/issues/92[#92], +https://github.com/AY1920S1-CS2103T-W12-3/main/issues/119[#119], +https://github.com/AY1920S1-CS2103T-W12-3/main/issues/199[#199]) + +* Enhancements to existing features: +** Comprehensive Unit and Integration Tests +(Pull requests: https://github.com/AY1920S1-CS2103T-W12-3/main/pull/204[#204]) + +** Updated the GUI colour scheme for budget tab so that necessary messages can be brought across the user such as exceeding the set budget +(Pull requests: https://github.com/AY1920S1-CS2103T-W12-3/main/pull/212[#212] +https://github.com/AY1920S1-CS2103T-W12-3/main/pull/223[#223]) + +* Documentation: +** Made updates to the User Guide and Developer Guide to make them more informative for the following sections: +(Pull requests: https://github.com/AY1920S1-CS2103T-W12-3/main/pull/107[#107] +https://github.com/AY1920S1-CS2103T-W12-3/main/pull/127[#127] +https://github.com/AY1920S1-CS2103T-W12-3/main/pull/227[#227]) + +* Community: +** Reported bugs and offered suggestions for other teams in the class +(Issues: https://github.com/AY1920S1-CS2103T-F11-1/main/issues/253[#253], +https://github.com/AY1920S1-CS2103T-F11-1/main/issues/255[#255], +https://github.com/AY1920S1-CS2103T-F11-1/main/issues/256[#256], +https://github.com/AY1920S1-CS2103T-F11-1/main/issues/260[#260]) + + +[[User-guide]] + +== Contributions to the User Guide +Original AddressBook User Guide was updated with instructions for the enhancements we added. +The following is an excerpt from our PalPay User Guide, showing additions that I have made for the `set` command feature. + + + +include::../UserGuide.adoc[tag=set] + + + +[[Developer-guide]] +== Contributions to the Developer Guide +The following excerpt shows my contribution to PalPay Developer Guide for the section `set` command. +The section also highlights the relationship of `Budget` class with the overall system. + + + +include::../DeveloperGuide.adoc[tag=set] + + diff --git a/docs/team/yewon0303.html b/docs/team/yewon0303.html new file mode 100644 index 00000000000..ed06eb6e7df --- /dev/null +++ b/docs/team/yewon0303.html @@ -0,0 +1,871 @@ + + + + + + + +Park Ye Won - Project Portfolio + + + + + +
+
+

1. Introduction

+
+
+

This project portfolio documents my contribution to the software project PalPay.

+
+
+

1.1. About the team

+
+

PalPay is a project collectively done by five Sophomore Computer Science Undergraduate students +in National University of Singapore. As part of a requirement for our module - CS2103T Software Engineering, +we morphed an existing product called Address Book (Level 3) given constraints +that the user must interact with it using Command Line Interface (CLI).

+
+
+
+

1.2. About the project

+
+

PalPay is a desktop application that is target to students who have limited time to keep track of their incomes +and expenditure and wish to have a simple and quick means to take charge of their finances. +Also recognising the problem faced by many students that they cannot keep track of lending and borrowing of money with friends, +PalPay offers a ledger function which keeps track of the movement of money between friends on a daily basis.

+
+
+

This is what PalPay looks like:

+
+
+
+dg gui example +
+
Figure 1. PalPay’s Graphical User Interface
+
+
+

With my role as a developer for this project, I implemented the budget function. +Understanding that many students have a poor management of their expenses, PalPay budget function allows them to set a budget +so that they can be more conscious of their expenditure. As they make expenses in that particular category, +the budget will indicate the amount of money left from the budget and serve as a constant reminder for them to make smart financial choices.

+
+
+
+
+
+

2. Summary of contributions

+
+
+

This section shows a summary of my coding, documentation and other helpful contributions to the team in this project.

+
+
+

Enhancement added: I added the ability to set a budget in the bank account +* What it does: The set command allows the user to set a budget until a deadline in a given category. +As the user makes OutTransaction s of the given category, he can see the percentage of remaining budget, as well as the number of days remaining.

+
+
+
    +
  • +

    Justification: As the user wishes to manage his expenses and restrict the overspending of money, +setting the budget is useful in allowing the user to track the outflow of his money. +Moreover, as the deadline he set approaches or upon exceeding the set budget, +the budget card displays red font which alerts the user that he needs to manage his finance better. +More details will be discussed below in the user guide and developer guide.

    +
  • +
  • +

    Highlights: This enhancement is based on Budget class which is a build-up of the current +Transaction class. While Transaction class allows the user to key in inflows and outflows of money, +Budget allows the user to have an indication of the outflows in a given category. +As the two classes behaves as though Budget is a child class of Transaction, +an in-depth analysis of design alternatives was necessary to ensure that Liskov Substitution Principal +was not violated. More details will be elaborated in section Design Considerations of developer guide excerpt below.

    +
  • +
+
+
+

Code contributed: Please click these links to see a sample of my code: +RepoSense

+
+
+

Other contributions :

+
+
+
    +
  • +

    Project management:

    +
    +
      +
    • +

      Managed several issue trackers on GitHub: +(Issues: #92, +#119, +#199)

      +
    • +
    +
    +
  • +
  • +

    Enhancements to existing features:

    +
    +
      +
    • +

      Comprehensive Unit and Integration Tests +(Pull requests: #204)

      +
    • +
    • +

      Updated the GUI colour scheme for budget tab so that necessary messages can be brought across the user such as exceeding the set budget +(Pull requests: #212 +#223)

      +
    • +
    +
    +
  • +
  • +

    Documentation:

    +
    +
      +
    • +

      Made updates to the User Guide and Developer Guide to make them more informative for the following sections: +(Pull requests: #107 +#127 +#227)

      +
    • +
    +
    +
  • +
  • +

    Community:

    +
    +
      +
    • +

      Reported bugs and offered suggestions for other teams in the class +(Issues: #253, +#255, +#256, +#260)

      +
    • +
    +
    +
  • +
+
+
+
+
+

3. Contributions to the User Guide

+
+
+

Original AddressBook User Guide was updated with instructions for the enhancements we added. +The following is an excerpt from our PalPay User Guide, showing additions that I have made for the set command feature.

+
+
+

<Start of Excerpt>

+
+
+

3.1. Setting a Budget : set

+
+

You can set a budget for a particular category until a certain date, given it is not already present in the budget list. +A duplicate budget is a budget with the same AMOUNT and DATE and CATEGORY.
+If you attempt to do so, you will receive an error message: This budget already exists.

+
+
+

3.1.1. Command Syntax

+
+

Format: set $/AMOUNT d/DATE [c/CATEGORY]…​

+
+
+
+
+

Parameters follow the same restrictions as highlighted in parameter constraints.

+
+
+
    +
  • +

    AMOUNT input accepts the budget amount to be set.

    +
  • +
  • +

    DATE input accepts the deadline to be set. It cannot be a date in the past.

    +
  • +
  • +

    CATEGORY accepts the CATEGORY for the budget. +A budget can be created without CATEGORY inputs in which case, the budget will automatically be assigned `GENERAL' category.

    +
  • +
+
+
+
+
+
+

3.1.2. Important Details

+
+

Let’s say you want to restrict your spending for a certain category until a certain deadline. +PalPay allows you to set a budget and serve as a reminder to show how much of the budget set you have left +until the deadline (inclusive). You will be more self-conscious of your spending and minimise your spending by setting a budget.

+
+
+

To set a new budget:
+1. Type set and enter the relevant details (amount, deadline, category) in the format given above.
+2. The result box will display the message New budget successfully set.
+3. If the budget already exists in the budget list, the result box will display the message This budget already exists.
+4. Now you can see the newly set budget in the budget list.

+
+
+

As you log an expenditure of a particular CATEGORY, your budgets with the same CATEGORY will be adjusted +to display the remaining amount of budget. Other budgets in the list belonging to different CATEGORY will not be adjusted.

+
+
+

For example, you went out with your friends and bought a cup of Gong Cha. +Before you log your spending, your budget list looks like this:

+
+
+
+approachingBudget +
+
Figure 2. Budget List before Executing OutTransaction
+
+
+

You then type in the command out $/5 c/BBT c/friends n/gong cha d/11112019.

+
+
+
+newOutTransaction +
+
Figure 3. New OutTransaction Command
+
+
+

Your budget list now shows the updated budgets. Observe how Budget 3 is not affected because it does not belong to the relevant category.

+
+
+
+budgetAffected +
+
Figure 4. Updated Budget List
+
+
+

Budget will not take into consideration past OutTransaction when calculating the remaining budget. Remember, you are setting a budget +from TODAY till the stated DATE (inclusive)!

+
+
+

If you overspend beyond a set budget, the overspent budget will be displayed in red. +Shown below as budget index 3 is an example of an overspent budget:

+
+
+
+overspentBudget +
+
Figure 5. Overspent Budget
+
+
+

As the day you have set for the budget approaches, the countdown placeholder as well as the percentage remaining placeholder +will turn to red when the number of remaining days reaches 3 and below. +Shown below as budget index 4 is an example of a budget approaching its deadline:

+
+
+
+approachingBudget +
+
Figure 6. Budget approaching deadline
+
+
+

Examples:

+
+
+
    +
  • +

    set $/100 d/010120120 c/BBT

    +
  • +
  • +

    set $/300 d/29022020 c/shopping

    +
  • +
+
+
+

<End of Excerpt>

+
+
+
+
+
+
+

4. Contributions to the Developer Guide

+
+
+

The following excerpt shows my contribution to PalPay Developer Guide for the section set command. +The section also highlights the relationship of Budget class with the overall system.

+
+
+

<Start of Excerpt>

+
+
+

4.1. Set Budget Feature: set

+
+

The Budget class allows the user to set a budget for a given time period for a category, if specified. +The user is allowed to set multiple budgets, but duplicate budgets (budgets with the same identity in terms of amount, date and category) are not allowed. +Upon setting the budget, making OutTransaction will deduct the amount from relevant budgets in the list. +The detailed implementation of the process of updating the budget is explained further below in Current Implementation.

+
+
+

4.1.1. Current Implementation

+
+

The set command is an extension of parent Command class, facilitated by the Logic and Model components of the application, PalPay
+Given an amount and date, a new Budget is set for the user.
+Upon setting a new budget, a BudgetCard is created and displayed in a list in the application window till the date set by the user.

+
+
+

A Budget stores an initial amount, amount (the current amount), deadline, categories. +There is a need for a Budget to store both initial amount and amount as it allows for percentage of budget remaining to be calculated.
+Shown below is the class diagram of Budget class:

+
+
+
+BudgetClassDiagram +
+
Figure 7. Class Diagram of Budget class
+
+
+

Displaying the percentage remaining improves the user experience greatly as our target user is a +visual person who wants to see how much budget he has left in each category so as to cut down on spending as necessary +as specified in the User Story. Hence, taking a quick glance at the Budget card allows the user to +determine how much of budget he has left, as well as be alarmed by the red font color to spend less if he has overspent beyond the budget set.

+
+
+

A snippet of the code which calculates the percentage of budget left is shown below:

+
+
+
+
public String displayPercentage() {
+    double percentage = this.amount.divideAmount(this.initialAmount) * 100;
+    if (percentage < 0.00) {
+        percentage = 0.0; // should not display a negative percentage
+    } else if (percentage > 100.00) {
+        percentage = 100.0; // should not display a percentage greater than 100%
+    }
+    return String.format("%.2f%% remaining", percentage);
+}
+
+
+
+

Moreover, as our user is a visual person, PalPay makes use of color to display different messages. +For instance, budget is displayed in red to alert the user that he has overspent beyond the set budget.

+
+
+

Shown below is an example of an overspent budget:

+
+
+
+overspentBudget +
+
Figure 8. Example of an Overspent Budget
+
+
+

When setting a new Budget, existence of a duplicate budget is checked through a sequence of checks. +The activity diagram below shows the activity diagram of setting a new budget:

+
+
+
+SetBudgetSimpleActivityDiagram +
+
Figure 9. Activity Diagram of Setting a New Budget Successfully
+
+
+

As shown, a new budget cannot have the same initalAmount, deadline and categories as any other existing budget in +budget list. Allowing existence of duplicate budgets will crowd the interface of Budget tab, +which prevents the user from getting a quick overview of his budget status. Hence, a duplicate check is essential +in providing a pleasing user experience.

+
+
+
+

4.1.2. Example of Usage

+
+

Given below is an example usage of how set behaves at each step.

+
+
+

Step 1. The user executes set $/100 d/31122019 c/shopping to set a new budget of $100 until 31st December 2019 under the category shopping.

+
+
+
+set dg 1 +
+
Figure 10. User Inputs set $/100 d/31122019 c/shopping
+
+
+

Step 2. Upon executing the command, LogicManager uses MainParser#parse to parse the input from the user.

+
+
+

Step 3. MainParser determines which command is being executed and creates SetCommandParser to further parse the input.

+
+
+

Step 4. SetCommandParser parses the argument and checks if it is valid. If it is invalid, an exception is thrown. +Else, it returns a SetCommand.

+
+
+

Step 5. LogicManager uses SetCommand#execute() to add a new budget.
+SetCommand uses ModelManager#has(Budget) to check if it is a duplicate of an existing budget +in the UniqueBudgetList as shown above in the above diagram.

+
+
+

Step 6. SetCommand uses Model#commitUserState() to save the latest state of the application. It then +returns a CommandResult to the LogicManager and the result will be displayed to the user at the end.

+
+
+
+set dg 2 +
+
Figure 11. New Budget Successfully Created
+
+
+
+

4.1.3. Design Considerations

+
+

Currently, Budget does not extend from Transaction although the two behave in a similar way. +There is an aggregation between Budget and Transaction as the two can exist independent of each other, +although an effect on one may also cause an impact on the other. +The current design was chosen over the former design of inheritance as there is a stark difference in the two +in a way that Budget does not affect the balance of the user’s bank account directly while Transaction does. +Hence, by Liskov Substitution Principle, inheritance is not a suitable design.

+
+
+

<End of Excerpt>

+
+
+
+
+
+
+ + + diff --git a/docs/team/yewon0303.pdf b/docs/team/yewon0303.pdf new file mode 100644 index 00000000000..262fa72ce0c Binary files /dev/null and b/docs/team/yewon0303.pdf differ diff --git a/src/main/java/seedu/address/MainApp.java b/src/main/java/seedu/address/MainApp.java index 8069ad6d47f..8ed1eae4cb9 100644 --- a/src/main/java/seedu/address/MainApp.java +++ b/src/main/java/seedu/address/MainApp.java @@ -37,7 +37,7 @@ */ public class MainApp extends Application { - public static final Version VERSION = new Version(1, 3, 1, true); + public static final Version VERSION = new Version(1, 4, 0, true); private static final Logger logger = LogsCenter.getLogger(MainApp.class); diff --git a/src/main/java/seedu/address/logic/commands/DisplayCommand.java b/src/main/java/seedu/address/logic/commands/DisplayCommand.java index 9cdf7b80722..2cca99434a4 100644 --- a/src/main/java/seedu/address/logic/commands/DisplayCommand.java +++ b/src/main/java/seedu/address/logic/commands/DisplayCommand.java @@ -12,7 +12,6 @@ /** * Displays a {@code Projection} identified using it's displayed index from the bank account. - * TODO: extend display to other data types */ public class DisplayCommand extends Command { diff --git a/src/main/java/seedu/address/logic/commands/ProjectCommand.java b/src/main/java/seedu/address/logic/commands/ProjectCommand.java index b96e88ec885..e35394e16ae 100644 --- a/src/main/java/seedu/address/logic/commands/ProjectCommand.java +++ b/src/main/java/seedu/address/logic/commands/ProjectCommand.java @@ -34,7 +34,7 @@ public class ProjectCommand extends Command { + "Parameters: " + PREFIX_DATE + "DATE [" + PREFIX_CATEGORY + "CATEGORY]\n" + "Example: " + COMMAND_WORD + " " - + PREFIX_DATE + "12122103 " + + PREFIX_DATE + "12122019 " + PREFIX_CATEGORY + "Food"; public static final int REQUIRED_MINIMUM_TRANSACTIONS = 5; diff --git a/src/main/java/seedu/address/logic/commands/SetCommand.java b/src/main/java/seedu/address/logic/commands/SetCommand.java index 366938f3a6e..3f9dc451ebd 100644 --- a/src/main/java/seedu/address/logic/commands/SetCommand.java +++ b/src/main/java/seedu/address/logic/commands/SetCommand.java @@ -24,7 +24,7 @@ public class SetCommand extends Command { + "[" + PREFIX_CATEGORY + "CATEGORY]...\n" + "Example: " + COMMAND_WORD + " " + PREFIX_AMOUNT + "100 " - + PREFIX_DATE + "010120120 " + + PREFIX_DATE + "01012020 " + PREFIX_CATEGORY + "food "; public static final String MESSAGE_SUCCESS = "New budget successfully set: %1$s"; diff --git a/src/main/java/seedu/address/logic/commands/SplitCommand.java b/src/main/java/seedu/address/logic/commands/SplitCommand.java index b0a3f4a0c9c..73049759215 100644 --- a/src/main/java/seedu/address/logic/commands/SplitCommand.java +++ b/src/main/java/seedu/address/logic/commands/SplitCommand.java @@ -35,7 +35,7 @@ public class SplitCommand extends Command { + PREFIX_SHARE + "2 " + PREFIX_SHARE + "3\n" + "If number of shares is one more than number of names listed, \n" - + "first share is taken to be user's share of the expenditure\n"; + + "first share is taken to be user's share of the expenditure"; public static final String SHARES_FORMAT = "If number of shares is equal to number of names given," + "user is assumed to be excluded from the expenditure.\n" + "Else, first share is taken to be the user's share."; diff --git a/src/main/java/seedu/address/logic/commands/UpdateCommand.java b/src/main/java/seedu/address/logic/commands/UpdateCommand.java index dd25f1934d4..81fa4f0cb84 100644 --- a/src/main/java/seedu/address/logic/commands/UpdateCommand.java +++ b/src/main/java/seedu/address/logic/commands/UpdateCommand.java @@ -71,6 +71,7 @@ public CommandResult execute(Model model) throws CommandException { requireNonNull(model); if (this.type.equals(Model.TRANSACTION_TYPE)) { + //update transaction type ObservableList lastShownList = model.getFilteredTransactionList(); if (targetIndex.getZeroBased() >= lastShownList.size()) { @@ -88,6 +89,7 @@ public CommandResult execute(Model model) throws CommandException { return new CommandResult(String.format(MESSAGE_UPDATE_ENTRY_SUCCESS, updatedTransaction), false, false, Tab.TRANSACTION); } else if (this.type.equals(Model.BUDGET_TYPE)) { + //update budget type ObservableList lastShownList = model.getFilteredBudgetList(); if (targetIndex.getZeroBased() >= lastShownList.size()) { @@ -97,9 +99,11 @@ public CommandResult execute(Model model) throws CommandException { Budget budgetToReplace = lastShownList.get(targetIndex.getZeroBased()); Budget updatedBudget = createUpdatedOperation(budgetToReplace, updateTransactionDescriptor); + if (model.has(updatedBudget)) { + throw new CommandException("Updated budget already exists!"); + } model.set(budgetToReplace, updatedBudget); - model.updateProjectionsAfterDelete(budgetToReplace); - model.updateProjectionsAfterAdd(updatedBudget); + model.updateProjectionsAfterUpdate(budgetToReplace, updatedBudget); model.commitUserState(); return new CommandResult(String.format(MESSAGE_UPDATE_ENTRY_SUCCESS, updatedBudget), false, false, Tab.BUDGET); @@ -140,12 +144,13 @@ private static Budget createUpdatedOperation(Budget budgetToEdit, UpdateTransactionDescriptor updateTransactionDescriptor) { assert budgetToEdit != null; - Amount updatedAmount = updateTransactionDescriptor.getAmount().orElse(budgetToEdit.getBudget()); + Amount updatedInitialAmount = updateTransactionDescriptor.getAmount().orElse(budgetToEdit.getInitialBudget()); + //Amount updatedAmount = budgetToEdit.getBudget(); Date updatedDate = updateTransactionDescriptor.getDate().orElse(budgetToEdit.getDeadline()); Set updatedCategories = updateTransactionDescriptor .getCategories().orElse(budgetToEdit.getCategories()); - return new Budget(updatedAmount, updatedDate, updatedCategories); + return new Budget(updatedInitialAmount, updatedInitialAmount, updatedDate, updatedCategories); } /** diff --git a/src/main/java/seedu/address/logic/parser/MainParser.java b/src/main/java/seedu/address/logic/parser/MainParser.java index a56e4133a68..e53e3497b13 100644 --- a/src/main/java/seedu/address/logic/parser/MainParser.java +++ b/src/main/java/seedu/address/logic/parser/MainParser.java @@ -78,6 +78,32 @@ public Command parseCommand(String userInput) throws ParseException { case ViewCommand.COMMAND_WORD: return new ViewCommandParser().parse(arguments); + case UpdateCommand.COMMAND_WORD: + return new UpdateCommandParser().parse(arguments); + + case DeleteCommand.COMMAND_WORD: + return new DeleteCommandParser().parse(arguments); + + case ReceiveCommand.COMMAND_WORD: + return new ReceiveCommandParser().parse(arguments); + + case DisplayCommand.COMMAND_WORD: + return new DisplayCommandParser().parse(arguments); + + default: + return singleCommandWordParser(commandWord, arguments); + } + } + + /** + * Parses single word commands. + */ + public Command singleCommandWordParser(String commandWord, String arguments) throws ParseException { + if (!arguments.equals("")) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, "One word only.")); + } + + switch(commandWord) { case ClearCommand.COMMAND_WORD: return new ClearCommand(); @@ -87,12 +113,6 @@ public Command parseCommand(String userInput) throws ParseException { case HelpCommand.COMMAND_WORD: return new HelpCommand(); - case UpdateCommand.COMMAND_WORD: - return new UpdateCommandParser().parse(arguments); - - case DeleteCommand.COMMAND_WORD: - return new DeleteCommandParser().parse(arguments); - case UndoCommand.COMMAND_WORD: return new UndoCommand(); @@ -102,12 +122,6 @@ public Command parseCommand(String userInput) throws ParseException { case ExitCommand.COMMAND_WORD: return new ExitCommand(); - case ReceiveCommand.COMMAND_WORD: - return new ReceiveCommandParser().parse(arguments); - - case DisplayCommand.COMMAND_WORD: - return new DisplayCommandParser().parse(arguments); - default: throw new ParseException(MESSAGE_UNKNOWN_COMMAND); } diff --git a/src/main/java/seedu/address/model/Model.java b/src/main/java/seedu/address/model/Model.java index e7e375a6ad2..9cae7730c05 100644 --- a/src/main/java/seedu/address/model/Model.java +++ b/src/main/java/seedu/address/model/Model.java @@ -237,6 +237,8 @@ public interface Model { void updateProjectionsAfterUpdate(BankAccountOperation toUpdate, BankAccountOperation updated); + void updateProjectionsAfterUpdate(Budget toUpdate, Budget updated); + /** * Returns an unmodifiable view of the filtered budget list */ diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/seedu/address/model/ModelManager.java index 9fcab9555d7..a305a6bf449 100644 --- a/src/main/java/seedu/address/model/ModelManager.java +++ b/src/main/java/seedu/address/model/ModelManager.java @@ -391,6 +391,58 @@ public void updateProjectionsAfterUpdate(BankAccountOperation toUpdate, BankAcco }); } + @Override + public void updateProjectionsAfterUpdate(Budget toUpdate, Budget updated) { + List copy = new ArrayList<>(this.getFilteredProjectionsList()); + copy.forEach(x -> { + if (x.isGeneral() && toUpdate.isGeneral()) { + this.delete(x); + UniqueBudgetList newBudgets = new UniqueBudgetList(); + newBudgets.setBudgets(x.getBudgets()); + if (newBudgets.contains(toUpdate)) { + newBudgets.setBudget(toUpdate, updated); + } else { + newBudgets.add(updated); + } + this.add(new Projection(x.getTransactionHistory(), x.getDate(), + newBudgets.asUnmodifiableObservableList())); + } else { + boolean sameCategoryAsToUpdate = toUpdate.getCategories().stream().anyMatch(c -> { + if (x.getCategory() != null) { + return c.equals(x.getCategory()); + } + return false; + }); + boolean sameCategoryAsUpdated = updated.getCategories().stream().anyMatch(c -> { + if (x.getCategory() != null) { + return c.equals(x.getCategory()); + } + return false; + }); + if (sameCategoryAsToUpdate) { + this.delete(x); + UniqueBudgetList newBudgets = new UniqueBudgetList(); + newBudgets.setBudgets(x.getBudgets()); + if (newBudgets.contains(toUpdate)) { + newBudgets.remove(toUpdate); + } + this.add(new Projection(x.getTransactionHistory(), + x.getDate(), newBudgets.asUnmodifiableObservableList())); + } + if (sameCategoryAsUpdated) { + this.delete(x); + UniqueBudgetList newBudgets = new UniqueBudgetList(); + newBudgets.setBudgets(x.getBudgets()); + if (newBudgets.contains(updated)) { + newBudgets.add(updated); + } + this.add(new Projection(x.getTransactionHistory(), + x.getDate(), newBudgets.asUnmodifiableObservableList())); + } + } + }); + } + @Override public void updateProjectionsAfterDelete(BankAccountOperation deleted) { List copy = new ArrayList<>(this.getFilteredProjectionsList()); @@ -399,7 +451,9 @@ public void updateProjectionsAfterDelete(BankAccountOperation deleted) { this.delete(x); UniqueTransactionList newTransactions = new UniqueTransactionList(); newTransactions.setTransactions(x.getTransactionHistory()); - newTransactions.remove(deleted); + if (newTransactions.contains(deleted)) { + newTransactions.remove(deleted); + } if (newTransactions.asUnmodifiableObservableList().size() >= ProjectCommand.REQUIRED_MINIMUM_TRANSACTIONS) { this.add(new Projection(newTransactions.asUnmodifiableObservableList(), @@ -416,7 +470,9 @@ public void updateProjectionsAfterDelete(BankAccountOperation deleted) { this.delete(x); UniqueTransactionList newTransactions = new UniqueTransactionList(); newTransactions.setTransactions(x.getTransactionHistory()); - newTransactions.remove(deleted); + if (newTransactions.contains(deleted)) { + newTransactions.remove(deleted); + } if (newTransactions.asUnmodifiableObservableList().size() >= ProjectCommand.REQUIRED_MINIMUM_TRANSACTIONS) { this.add(new Projection(newTransactions.asUnmodifiableObservableList(), @@ -435,7 +491,9 @@ public void updateProjectionsAfterDelete(Budget deleted) { this.delete(x); UniqueBudgetList newBudgets = new UniqueBudgetList(); newBudgets.setBudgets(x.getBudgets()); - newBudgets.remove(deleted); + if (newBudgets.contains(deleted)) { + newBudgets.remove(deleted); + } this.add(new Projection(this.getFilteredTransactionList(), x.getDate(), newBudgets.asUnmodifiableObservableList())); } else { @@ -449,7 +507,9 @@ public void updateProjectionsAfterDelete(Budget deleted) { this.delete(x); UniqueBudgetList newBudgets = new UniqueBudgetList(); newBudgets.setBudgets(x.getBudgets()); - newBudgets.remove(deleted); + if (newBudgets.contains(deleted)) { + newBudgets.remove(deleted); + } this.add(new Projection(x.getTransactionHistory(), x.getDate(), newBudgets.asUnmodifiableObservableList(), x.getCategory())); } diff --git a/src/main/java/seedu/address/model/projection/Projection.java b/src/main/java/seedu/address/model/projection/Projection.java index 53215b6aadd..4344f03b7c7 100644 --- a/src/main/java/seedu/address/model/projection/Projection.java +++ b/src/main/java/seedu/address/model/projection/Projection.java @@ -4,6 +4,7 @@ import java.util.List; import java.util.stream.IntStream; +import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.scene.Scene; import javafx.scene.image.Image; @@ -15,7 +16,6 @@ import seedu.address.model.transaction.Amount; import seedu.address.model.transaction.BankAccountOperation; import seedu.address.model.transaction.Budget; -import seedu.address.model.transaction.UniqueBudgetList; import seedu.address.model.util.Date; /** @@ -25,7 +25,7 @@ public class Projection { private final ObservableList transactionHistory; private final Date date; - private ObservableList budgets = new UniqueBudgetList().asUnmodifiableObservableList(); + private ObservableList budgets = FXCollections.observableArrayList(); private List budgetProjections = new ArrayList<>(); private List budgetStartValues = new ArrayList<>(); private List budgetThresholds = new ArrayList<>(); @@ -35,18 +35,18 @@ public class Projection { public Projection(ObservableList transactionHistory, Date date, ObservableList budgets) { - this.transactionHistory = transactionHistory.sorted(new DateComparator()); this.date = date; - this.budgets = budgets; + this.transactionHistory = transactionHistory.sorted(new DateComparator()); + this.budgets = budgets.filtered(x -> Date.daysBetween(this.date, x.getDeadline()) <= 0); this.category = Category.GENERAL; this.project(); } public Projection(ObservableList transactionHistory, Date date, ObservableList budgets, Category category) { - this.transactionHistory = transactionHistory.sorted(new DateComparator()); this.date = date; - this.budgets = budgets.sorted(); + this.transactionHistory = transactionHistory.sorted(new DateComparator()); + this.budgets = budgets.filtered(x -> Date.daysBetween(this.date, x.getDeadline()) <= 0).sorted(); this.category = category; this.project(); } @@ -64,7 +64,7 @@ public Projection(ObservableList transactionHistory, this.transactionHistory = transactionHistory.sorted(new DateComparator()); this.projection = amount; this.date = date; - this.budgets = budgets.sorted(); + this.budgets = budgets.filtered(x -> Date.daysBetween(this.date, x.getDeadline()) <= 0).sorted(); this.budgetProjections = new ArrayList<>(); this.category = category; this.project(); @@ -148,6 +148,14 @@ Amount getBudgetThreshold(int idx) { return this.budgetThresholds.get(idx); } + Date getBudgetDeadline(int idx) { + return this.budgets.get(idx).getDeadline(); + } + + Date getBudgetStart(int idx) { + return this.budgets.get(idx).getStart(); + } + public String getAllBudgetForecastText() { StringBuilder text = new StringBuilder(); IntStream.range(0, budgetProjections.size()).forEach(x -> { diff --git a/src/main/java/seedu/address/model/projection/ProjectionGraph.java b/src/main/java/seedu/address/model/projection/ProjectionGraph.java index e4804740141..8d2e663ca05 100644 --- a/src/main/java/seedu/address/model/projection/ProjectionGraph.java +++ b/src/main/java/seedu/address/model/projection/ProjectionGraph.java @@ -167,7 +167,17 @@ private NumberAxis defineXAxis() { xAxis.setLabel("Days From Now"); xAxis.setAutoRanging(false); this.xMin = Math.min(gradientDescent.getVariable(), gradientDescent.getMinData()); + if (!this.budgets.isEmpty()) { + this.xMin = Math.min(xMin, IntStream.range(0, this.budgets.size()) + .mapToDouble(idx -> Date.daysBetween(Date.now(), this.projection.getBudgetStart(idx))).min() + .orElseThrow(AssertionError::new)); + } this.xMax = Math.max(gradientDescent.getVariable(), gradientDescent.getMaxData()); + if (!this.budgets.isEmpty()) { + this.xMax = Math.max(xMax, IntStream.range(0, this.budgets.size()) + .mapToDouble(idx -> Date.daysBetween(Date.now(), this.projection.getBudgetDeadline(idx))).max() + .orElseThrow(AssertionError::new)); + } this.xRange = xMax - xMin; this.xUnit = Math.round(xRange / 10); xAxis.setTickUnit(xUnit); @@ -187,7 +197,7 @@ private NumberAxis defineYAxis() { this.yMin = Math.min(gradientDescent.getResult(), gradientDescent.getMinOutput()); if (!this.budgets.isEmpty()) { this.yMin = Math.min(yMin, IntStream.range(0, this.budgets.size()) - .mapToDouble(idx -> this.projection.getBudgetThreshold(idx) + .mapToDouble(idx -> this.projection.getBudgetStartValue(idx) .getActualValue()).min() .orElseThrow()); } diff --git a/src/main/java/seedu/address/model/transaction/Budget.java b/src/main/java/seedu/address/model/transaction/Budget.java index 6f2200dcf43..f67cff6b9de 100644 --- a/src/main/java/seedu/address/model/transaction/Budget.java +++ b/src/main/java/seedu/address/model/transaction/Budget.java @@ -222,6 +222,8 @@ public String displayPercentage() { double percentage = this.amount.divideAmount(this.initialAmount) * 100; if (percentage < 0.00) { percentage = 0.0; // should not display a negative percentage + } else if (percentage > 100.00) { + percentage = 100.0; // should not display a percentage greater than 100% } return String.format("%.2f%% remaining", percentage); } @@ -243,7 +245,7 @@ public boolean equals(Object obj) { @Override public String toString() { - return String.format("$%s by %s", this.amount.toString(), this.deadline.toString()); + return String.format("$%s by %s", this.initialAmount.toString(), this.deadline.toString()); } public String toLabelText() { diff --git a/src/main/java/seedu/address/model/transaction/InTransaction.java b/src/main/java/seedu/address/model/transaction/InTransaction.java index a4fc4024f22..af57b2942db 100644 --- a/src/main/java/seedu/address/model/transaction/InTransaction.java +++ b/src/main/java/seedu/address/model/transaction/InTransaction.java @@ -31,7 +31,6 @@ public boolean equals(Object obj) { InTransaction inObj = (InTransaction) obj; return super.amount.equals(inObj.amount) && super.date.equals(inObj.date) - // && super.peopleInvolved.equals(inObj.peopleInvolved) // TODO: CONFIRM? && super.description.equals(inObj.description) && super.categories.equals(inObj.categories); } else { diff --git a/src/main/java/seedu/address/model/util/SamplePlotDataUtil.java b/src/main/java/seedu/address/model/util/SamplePlotDataUtil.java index a601bcfe32a..5704597275d 100644 --- a/src/main/java/seedu/address/model/util/SamplePlotDataUtil.java +++ b/src/main/java/seedu/address/model/util/SamplePlotDataUtil.java @@ -6,7 +6,6 @@ /** * A sample plotting utility for 2 variable graphs - * TODO: integrate with MainWindow for graphical view mode */ public class SamplePlotDataUtil { private static double[] x = {2, 4, 6, 8}; diff --git a/src/main/java/seedu/address/storage/JsonAdaptedBankOperations.java b/src/main/java/seedu/address/storage/JsonAdaptedBankOperations.java index 4308f87236b..11f88f58ae6 100644 --- a/src/main/java/seedu/address/storage/JsonAdaptedBankOperations.java +++ b/src/main/java/seedu/address/storage/JsonAdaptedBankOperations.java @@ -33,7 +33,6 @@ class JsonAdaptedBankOperations { /** * Constructs a {@code JsonAdaptedBankOperations} with the given transaction details. - * TODO: LEft off here -> update Projection (getTxHist + noProjectVersion) */ @JsonCreator public JsonAdaptedBankOperations(@JsonProperty("description") String description, diff --git a/src/main/java/seedu/address/ui/MainTabPanel.java b/src/main/java/seedu/address/ui/MainTabPanel.java index ab81e288a77..3d2385365f3 100644 --- a/src/main/java/seedu/address/ui/MainTabPanel.java +++ b/src/main/java/seedu/address/ui/MainTabPanel.java @@ -50,7 +50,6 @@ public MainTabPanel(TransactionListPanel transactionListPanel, BudgetListPanel b projectionGraphPlaceholder.getChildren().add(projectionListPanel.getRoot()); } - // TODO: remove protected void switchToTransactionTab() { this.mainTabPanel.getSelectionModel().select(0); } diff --git a/src/main/resources/view/HelpWindow.fxml b/src/main/resources/view/HelpWindow.fxml index 6c15ee6ec37..7a6ce843d68 100644 --- a/src/main/resources/view/HelpWindow.fxml +++ b/src/main/resources/view/HelpWindow.fxml @@ -8,8 +8,6 @@ - - diff --git a/src/test/java/seedu/address/commons/util/JsonUtilTest.java b/src/test/java/seedu/address/commons/util/JsonUtilTest.java index d4907539dee..3aec626c4e7 100644 --- a/src/test/java/seedu/address/commons/util/JsonUtilTest.java +++ b/src/test/java/seedu/address/commons/util/JsonUtilTest.java @@ -39,7 +39,4 @@ public void deserializeObjectFromJsonFile_noExceptionThrown() throws IOException assertEquals(serializableTestClass.getMapOfIntegerToString(), SerializableTestClass.getHashMapTestValues()); } - //TODO: @Test jsonUtil_readJsonStringToObjectInstance_correctObject() - - //TODO: @Test jsonUtil_writeThenReadObjectToJson_correctObject() } diff --git a/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java b/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java deleted file mode 100644 index 09bb1e0f673..00000000000 --- a/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package seedu.address.logic.commands; - -import static seedu.address.testutil.TypicalTransactions.getTypicalUserState; - -import org.junit.jupiter.api.BeforeEach; - -import seedu.address.model.Model; -import seedu.address.model.ModelManager; -import seedu.address.model.UserPrefs; - -/** - * Contains integration tests (interaction with the Model) for {@code AddCommand}. - */ -public class AddCommandIntegrationTest { - - private Model model; - - @BeforeEach - public void setUp() { - model = new ModelManager(getTypicalUserState(), new UserPrefs()); - } - - // TODO: Refactor into InCommandIntegrationTest - /* - @Test - public void execute_newPerson_success() { - Transaction validTransaction = new BankOperationBuilder().build(); - - Model expectedModel = new ModelManager(model.getBankAccount(), new UserPrefs()); - expectedModel.add(validTransaction); - - assertCommandSuccess(new AddCommand(validTransaction), model, - String.format(AddCommand.MESSAGE_SUCCESS, validTransaction), expectedModel); - } - - - @Test - public void execute_duplicatePerson_throwsCommandException() { - Transaction transactionInList = model.getBankAccount().getTransactionHistory().get(0); - assertCommandFailure(new AddCommand(transactionInList), model, AddCommand.MESSAGE_DUPLICATE_PERSON); - } - */ - -} diff --git a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java b/src/test/java/seedu/address/logic/commands/CommandTestUtil.java index c26f7fca956..e2a2566df53 100644 --- a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java +++ b/src/test/java/seedu/address/logic/commands/CommandTestUtil.java @@ -56,19 +56,7 @@ public class CommandTestUtil { public static final String INVALID_DESCRIPTION_DESC = " " + PREFIX_NAME + "Milk@"; public static final String INVALID_CATEGORY_DESC = " " + PREFIX_CATEGORY + "Work*"; - // TODO: FIX - // - // public static final UpdateCommand.UpdateTransactionDescriptor DESC_AMY; - // public static final UpdateCommand.UpdateTransactionDescriptor DESC_BOB; - // - // static { - // DESC_AMY = new UpdateTransactionDescriptorBuilder().withName(VALID_NAME_AMY) - // .withPhone(VALID_PHONE_AMY).withEmail(VALID_EMAIL_AMY).withAddress(VALID_ADDRESS_AMY) - // .withCategories(VALID_TAG_FRIEND).build(); - // DESC_BOB = new UpdateTransactionDescriptorBuilder().withName(VALID_NAME_BOB) - // .withPhone(VALID_PHONE_BOB).withEmail(VALID_EMAIL_BOB).withAddress(VALID_ADDRESS_BOB) - // .withCategories(VALID_TAG_HUSBAND, VALID_TAG_FRIEND).build(); - // } + /** * Executes the given {@code command}, confirms that
diff --git a/src/test/java/seedu/address/logic/commands/FilterCommandTest.java b/src/test/java/seedu/address/logic/commands/FilterCommandTest.java index f70cdc6cafc..cc82f23c480 100644 --- a/src/test/java/seedu/address/logic/commands/FilterCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/FilterCommandTest.java @@ -64,7 +64,6 @@ public void equals() { assertFalse(filterFirstCommand.equals(filterSecondCommand)); } - // TODO: more testcases @Test public void execute_zeroKeywords_noTransactionFound() { String expectedMessage = String.format(MESSAGE_TRANSACTIONS_LISTED_OVERVIEW, 0); diff --git a/src/test/java/seedu/address/logic/commands/UpdateCommandTest.java b/src/test/java/seedu/address/logic/commands/UpdateCommandTest.java index 1284efc8d2d..3609d758ace 100644 --- a/src/test/java/seedu/address/logic/commands/UpdateCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/UpdateCommandTest.java @@ -63,114 +63,5 @@ public void execute_someFieldsSpecifiedUnfilteredList_success() { // assertCommandSuccess(updateCommand, model, expectedMessage, expectedModel); } - /* - @Test - public void execute_noFieldSpecifiedUnfilteredList_success() { - EditCommand editCommand = new EditCommand(INDEX_FIRST_TRANSACTION, new EditPersonDescriptor()); - Transaction editedTransaction = model.getFilteredTransactionList().get(INDEX_FIRST_TRANSACTION.getZeroBased()); - - String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_PERSON_SUCCESS, editedTransaction); - - Model expectedModel = new ModelManager(new BankAccount(model.getBankAccount()), new UserPrefs()); - - assertCommandSuccess(editCommand, model, expectedMessage, expectedModel); - } - - @Test - public void execute_filteredList_success() { - showPersonAtIndex(model, INDEX_FIRST_TRANSACTION); - - Transaction transactionInFilteredList = model - .getFilteredTransactionList() - .get(INDEX_FIRST_TRANSACTION.getZeroBased()); - // TODO: FIX - Transaction editedTransaction = new BankOperationBuilder(transactionInFilteredList).withAmount("1").build(); - EditCommand editCommand = new EditCommand(INDEX_FIRST_TRANSACTION, - new EditPersonDescriptorBuilder().withName(VALID_NAME_BOB).build()); - - String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_PERSON_SUCCESS, editedTransaction); - - Model expectedModel = new ModelManager(new BankAccount(model.getBankAccount()), new UserPrefs()); - expectedModel.set(model.getFilteredTransactionList().get(0), editedTransaction); - - assertCommandSuccess(editCommand, model, expectedMessage, expectedModel); - } - - @Test - public void execute_duplicateTransactionUnfilteredList_failure() { - Transaction firstTransaction = model.getFilteredTransactionList().get(INDEX_FIRST_TRANSACTION.getZeroBased()); - EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder(firstTransaction).build(); - EditCommand editCommand = new EditCommand(INDEX_SECOND_TRANSACTION, descriptor); - - assertCommandFailure(editCommand, model, EditCommand.MESSAGE_DUPLICATE_PERSON); - } - - @Test - public void execute_duplicateTransactionFilteredList_failure() { - showPersonAtIndex(model, INDEX_FIRST_TRANSACTION); - - // edit person in filtered list into a duplicate in address book - Transaction transactionInList = model - .getBankAccount().getTransactionHistory().get(INDEX_SECOND_TRANSACTION.getZeroBased()); - EditCommand editCommand = new EditCommand(INDEX_FIRST_TRANSACTION, - new EditPersonDescriptorBuilder(transactionInList).build()); - - assertCommandFailure(editCommand, model, EditCommand.MESSAGE_DUPLICATE_PERSON); - } - - @Test - public void execute_invalidTransactionIndexUnfilteredList_failure() { - Index outOfBoundIndex = Index.fromOneBased(model.getFilteredTransactionList().size() + 1); - EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withName(VALID_NAME_BOB).build(); - EditCommand editCommand = new EditCommand(outOfBoundIndex, descriptor); - - assertCommandFailure(editCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); - } - */ - - /** - * Edit filtered list where index is larger than size of filtered list, - * but smaller than size of address book - */ - /* - @Test - public void execute_invalidTransactionIndexFilteredList_failure() { - showPersonAtIndex(model, INDEX_FIRST_TRANSACTION); - Index outOfBoundIndex = INDEX_SECOND_TRANSACTION; - // ensures that outOfBoundIndex is still in bounds of address book list - assertTrue(outOfBoundIndex.getZeroBased() < model.getBankAccount().getTransactionHistory().size()); - - EditCommand editCommand = new EditCommand(outOfBoundIndex, - new EditPersonDescriptorBuilder().withName(VALID_NAME_BOB).build()); - - assertCommandFailure(editCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); - } - - @Test - public void equals() { - final EditCommand standardCommand = new EditCommand(INDEX_FIRST_TRANSACTION, DESC_AMY); - - // same values -> returns true - EditPersonDescriptor copyDescriptor = new EditPersonDescriptor(DESC_AMY); - EditCommand commandWithSameValues = new EditCommand(INDEX_FIRST_TRANSACTION, copyDescriptor); - assertTrue(standardCommand.equals(commandWithSameValues)); - - // same object -> returns true - assertTrue(standardCommand.equals(standardCommand)); - - // null -> returns false - assertFalse(standardCommand.equals(null)); - - // different types -> returns false - assertFalse(standardCommand.equals(new ClearCommand())); - - // different index -> returns false - assertFalse(standardCommand.equals(new EditCommand(INDEX_SECOND_TRANSACTION, DESC_AMY))); - - // different descriptor -> returns false - assertFalse(standardCommand.equals(new EditCommand(INDEX_FIRST_TRANSACTION, DESC_BOB))); - } - */ - } diff --git a/src/test/java/seedu/address/logic/parser/MainParserTest.java b/src/test/java/seedu/address/logic/parser/MainParserTest.java index eaeb143b018..eda25f72d66 100644 --- a/src/test/java/seedu/address/logic/parser/MainParserTest.java +++ b/src/test/java/seedu/address/logic/parser/MainParserTest.java @@ -39,7 +39,6 @@ import seedu.address.model.category.Category; import seedu.address.model.transaction.TransactionPredicate; -// TODO: ADD ALL THE COMMANDS public class MainParserTest { private final MainParser parser = new MainParser(); @@ -117,13 +116,13 @@ public void parseCommand_sort() throws Exception { @Test public void parseCommand_undo() throws Exception { assertTrue(parser.parseCommand(UndoCommand.COMMAND_WORD) instanceof UndoCommand); - assertTrue(parser.parseCommand(UndoCommand.COMMAND_WORD + " tmr") instanceof UndoCommand); + assertThrows(ParseException.class, () -> parser.parseCommand(UndoCommand.COMMAND_WORD + " tmr")); } @Test public void parseCommand_redo() throws Exception { assertTrue(parser.parseCommand(RedoCommand.COMMAND_WORD) instanceof RedoCommand); - assertTrue(parser.parseCommand(RedoCommand.COMMAND_WORD + " later") instanceof RedoCommand); + assertThrows(ParseException.class, () -> parser.parseCommand(RedoCommand.COMMAND_WORD + " later")); } @Test @@ -136,7 +135,7 @@ public void parseCommand_view() throws Exception { @Test public void parseCommand_clear() throws Exception { assertTrue(parser.parseCommand(ClearCommand.COMMAND_WORD) instanceof ClearCommand); - assertTrue(parser.parseCommand(ClearCommand.COMMAND_WORD + " 3") instanceof ClearCommand); + assertThrows(ParseException.class, () -> parser.parseCommand(ClearCommand.COMMAND_WORD + " 3")); } @Test @@ -161,19 +160,19 @@ public void parseCommand_delete() throws Exception { @Test public void parseCommand_exit() throws Exception { assertTrue(parser.parseCommand(ExitCommand.COMMAND_WORD) instanceof ExitCommand); - assertTrue(parser.parseCommand(ExitCommand.COMMAND_WORD + " 3") instanceof ExitCommand); + assertThrows(ParseException.class, () -> parser.parseCommand(ExitCommand.COMMAND_WORD + " 3")); } @Test public void parseCommand_help() throws Exception { assertTrue(parser.parseCommand(HelpCommand.COMMAND_WORD) instanceof HelpCommand); - assertTrue(parser.parseCommand(HelpCommand.COMMAND_WORD + " 3") instanceof HelpCommand); + assertThrows(ParseException.class, () -> parser.parseCommand(HelpCommand.COMMAND_WORD + " 3")); } @Test public void parseCommand_list() throws Exception { assertTrue(parser.parseCommand(ListCommand.COMMAND_WORD) instanceof ListCommand); - assertTrue(parser.parseCommand(ListCommand.COMMAND_WORD + " 3") instanceof ListCommand); + assertThrows(ParseException.class, () -> parser.parseCommand(ListCommand.COMMAND_WORD + " 3")); } @Test diff --git a/src/test/java/seedu/address/model/BankAccountTest.java b/src/test/java/seedu/address/model/BankAccountTest.java index 79490f77106..e87649b8607 100644 --- a/src/test/java/seedu/address/model/BankAccountTest.java +++ b/src/test/java/seedu/address/model/BankAccountTest.java @@ -46,12 +46,6 @@ public void resetData_withValidReadOnlyBankAccount_replacesData() { assertEquals(newData, bankAccount); } - // TODO: implement test for budget during copying - // @Test - // public void resetData_withDuplicateBudget_throwsDuplicateBudgetException() { - // - // } - @Test public void has_null_throwsNullPointerException() { assertThrows(NullPointerException.class, () -> bankAccount.has((BankAccountOperation) null)); diff --git a/src/test/java/seedu/address/model/stubs/ModelStub.java b/src/test/java/seedu/address/model/stubs/ModelStub.java index 880e9d86d9e..d4aa564c3bd 100644 --- a/src/test/java/seedu/address/model/stubs/ModelStub.java +++ b/src/test/java/seedu/address/model/stubs/ModelStub.java @@ -210,6 +210,11 @@ public void updateProjectionsAfterDelete(Budget budget) { public void updateProjectionsAfterUpdate(BankAccountOperation toUpdate, BankAccountOperation updated) { } + @Override + public void updateProjectionsAfterUpdate(Budget toUpdate, Budget updated) { + + } + @Override public void updateProjectionsAfterAdd(BankAccountOperation added) { } diff --git a/src/test/java/seedu/address/model/transaction/BudgetTest.java b/src/test/java/seedu/address/model/transaction/BudgetTest.java index 8b92c6c2d08..febc58a9929 100644 --- a/src/test/java/seedu/address/model/transaction/BudgetTest.java +++ b/src/test/java/seedu/address/model/transaction/BudgetTest.java @@ -25,6 +25,7 @@ public class BudgetTest { private static final Budget BUDGET_ONE = new Budget(); private static final Budget BUDGET_TWO = new Budget(HUNDRED, new Date(VALID_DATE)); private static final Budget BUDGET_THREE = new Budget(HUNDRED, new Date(VALID_DATE), CATEGORIES); + private static final Budget BUDGET_FOUR = new Budget(HUNDRED, HUNDRED, new Date(VALID_DATE), CATEGORIES); @Test @@ -35,6 +36,13 @@ public void budgetConstructor_overBoundary_throwsException() { new Date(VALID_DATE), CATEGORIES)); } + @Test + public void budgetConstructor_success() { + assertEquals(new Budget(HUNDRED, new Date(VALID_DATE)), BUDGET_TWO); + assertEquals(new Budget(HUNDRED, new Date(VALID_DATE), CATEGORIES), BUDGET_THREE); + assertEquals(new Budget(HUNDRED, HUNDRED, new Date(VALID_DATE), CATEGORIES), BUDGET_FOUR); + } + @Test public void getBudget_success() { assertEquals(HUNDRED, new Budget(HUNDRED, new Date(VALID_DATE)).getBudget()); diff --git a/src/test/java/seedu/address/testutil/BudgetBuilder.java b/src/test/java/seedu/address/testutil/BudgetBuilder.java index 0f3fa09b25f..9639a14409e 100644 --- a/src/test/java/seedu/address/testutil/BudgetBuilder.java +++ b/src/test/java/seedu/address/testutil/BudgetBuilder.java @@ -61,7 +61,6 @@ public BudgetBuilder withDate(String date) { return this; } - // TODO: Change constructor public Budget build() { return new Budget(amount, date, categories); } diff --git a/src/test/java/seedu/address/testutil/TypicalTransactions.java b/src/test/java/seedu/address/testutil/TypicalTransactions.java index 15fa24c9202..d198d7d49c3 100644 --- a/src/test/java/seedu/address/testutil/TypicalTransactions.java +++ b/src/test/java/seedu/address/testutil/TypicalTransactions.java @@ -6,8 +6,6 @@ import seedu.address.model.UserState; import seedu.address.model.transaction.BankAccountOperation; -import seedu.address.model.transaction.Budget; -import seedu.address.model.transaction.LedgerOperation; /** * A utility class containing a list of {@code Transaction} objects to be used in tests. @@ -134,14 +132,4 @@ public static List getOneToTenTypicalTransactions(int size return new ArrayList<>(); } } - - //TODO: implement: - public static List getTypicalLedgerOperations() { - return null; - } - - //TODO: implement: - public static List getTypicalBudget() { - return null; - } }