diff --git a/README.md b/README.md
index 13f5c77403f..7202f0a5a43 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,18 @@
-[](https://github.com/se-edu/addressbook-level3/actions)
+[](https://github.com/AY2021S2-CS2103-T16-3/tp/actions)
+## User Interface

-* This is **a sample project for Software Engineering (SE) students**.
- Example usages:
- * as a starting point of a course project (as opposed to writing everything from scratch)
- * as a case study
-* The project simulates an ongoing software project for a desktop application (called _AddressBook_) used for managing contact details.
- * It is **written in OOP fashion**. It provides a **reasonably well-written** code base **bigger** (around 6 KLoC) than what students usually write in beginner-level SE modules, without being overwhelmingly big.
- * It comes with a **reasonable level of user and developer documentation**.
-* It is named `AddressBook Level 3` (`AB3` for short) because it was initially created as a part of a series of `AddressBook` projects (`Level 1`, `Level 2`, `Level 3` ...).
-* For the detailed documentation of this project, see the **[Address Book Product Website](https://se-education.org/addressbook-level3)**.
-* This project is a **part of the se-education.org** initiative. If you would like to contribute code to this project, see [se-education.org](https://se-education.org#https://se-education.org/#contributing) for more info.
+## About ResidenceTracker
+ResidenceTracker is a command line based desktop application that assists landlords in managing their residences that they are listing out on the Airbnb platform for rent.
+
+* It gives user convenience by providing a centralised overview of all the user's residences and the respective bookingList/cleaning statuses of each residence.
+
+* It uses a **quick CLI** way to note down bookings and track status of different residence, such as
+ clean or needs cleaning/booked or available, so the landlord can process bookings more efficiently and inform the cleaning agent as necessary before the next lease arrives.
+
+* It is **written in OOP fashion**.
+
+* This project is based on the AddressBook-Level3 project created by the [SE-EDU initiative](https://se-education.org).
+
+* For more details on ResidenceTracker, please refer to our [User Guide](docs/UserGuide.md).
diff --git a/build.gradle b/build.gradle
index be2d2905dde..e161c7f7481 100644
--- a/build.gradle
+++ b/build.gradle
@@ -66,7 +66,14 @@ dependencies {
}
shadowJar {
- archiveName = 'addressbook.jar'
+ manifest {
+ attributes "Main-Class": 'seedu.address.Main'
+ archiveName("residencetracker.jar")
+ }
}
defaultTasks 'clean', 'test'
+
+run {
+ enableAssertions = true
+}
diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml
index 4c001417aea..6b34e465551 100644
--- a/config/checkstyle/checkstyle.xml
+++ b/config/checkstyle/checkstyle.xml
@@ -1,7 +1,7 @@
+ "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
+ "https://checkstyle.org/dtds/configuration_1_3.dtd">
-
-
-
-
+
+
+
+
@@ -216,7 +213,7 @@
some other variants which we don't publicized to promote consistency).
-->
+ value="fall through|Fall through|fallthru|Fallthru|falls through|Falls through|fallthrough|Fallthrough|No break|NO break|no break|continue on"/>
@@ -359,14 +356,12 @@
-->
diff --git a/docs/AboutUs.md b/docs/AboutUs.md
index 1c9514e966a..d7c05bdb3bc 100644
--- a/docs/AboutUs.md
+++ b/docs/AboutUs.md
@@ -9,51 +9,49 @@ You can reach us at the email `seer[at]comp.nus.edu.sg`
## Project team
-### John Doe
+### Lim Li Gang
-
+
-[[homepage](http://www.comp.nus.edu.sg/~damithch)]
-[[github](https://github.com/johndoe)]
-[[portfolio](team/johndoe.md)]
+[[github](https://github.com/whatthelump)]
-* Role: Project Advisor
+* Role: Code Quality and Documentation
+* Responsibilities: _TBC_
-### Jane Doe
+### Aw Zhen Yi
-
+
-[[github](http://github.com/johndoe)]
-[[portfolio](team/johndoe.md)]
+[[github](http://github.com/awzhenyi)]
-* Role: Team Lead
-* Responsibilities: UI
+* Role: Developer
+* Responsibilities: _TBC_
-### Johnny Doe
+### Teng Shu Wei Jared
-
+
-[[github](http://github.com/johndoe)] [[portfolio](team/johndoe.md)]
+[[github](http://github.com/jaredtengsw)]
* Role: Developer
-* Responsibilities: Data
+* Responsibilities: _TBC_
-### Jean Doe
+### V R Soorya
-
+
-[[github](http://github.com/johndoe)]
-[[portfolio](team/johndoe.md)]
+[[github](http://github.com/vrsoorya)]
+[[portfolio](team/vrsoorya.md)]
* Role: Developer
-* Responsibilities: Dev Ops + Threading
+* Responsibilities: Dev Ops
-### James Doe
+### Wang Tao
-
+
-[[github](http://github.com/johndoe)]
-[[portfolio](team/johndoe.md)]
+[[github](http://github.com/wangtao0717)]
+[[portfolio](team/wangtao0717.md)]
* Role: Developer
-* Responsibilities: UI
+* Responsibilities: _TBC_
diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md
index 4829fe43011..eb549b99d81 100644
--- a/docs/DeveloperGuide.md
+++ b/docs/DeveloperGuide.md
@@ -23,11 +23,11 @@ The ***Architecture Diagram*** given above explains the high-level design of the
-:bulb: **Tip:** The `.puml` files used to create diagrams in this document can be found in the [diagrams](https://github.com/se-edu/addressbook-level3/tree/master/docs/diagrams/) folder. Refer to the [_PlantUML Tutorial_ at se-edu/guides](https://se-education.org/guides/tutorials/plantUml.html) to learn how to create and edit diagrams.
+:bulb: **Tip:** The `.puml` files used to create diagrams in this document can be found in the [diagrams](https://github.com/ay2021s2-cs2103-t16-3/tp/tree/master/docs/diagrams/) folder. Refer to the [_PlantUML Tutorial_ at se-edu/guides](https://se-education.org/guides/tutorials/plantUml.html) to learn how to create and edit diagrams.
-**`Main`** has two classes called [`Main`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/Main.java) and [`MainApp`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/MainApp.java). It is responsible for,
+**`Main`** has two classes called [`Main`](https://github.com/ay2021s2-cs2103-t16-3/tp/tree/master/src/main/java/seedu/address/Main.java) and [`MainApp`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/MainApp.java). 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 methods where necessary.
@@ -62,7 +62,7 @@ The sections below give more details of each component.

**API** :
-[`Ui.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/ui/Ui.java)
+[`Ui.java`](https://github.com/ay2021s2-cs2103-t16-3/tp/tree/master/src/main/java/seedu/address/ui/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.
@@ -78,11 +78,11 @@ The `UI` component,

**API** :
-[`Logic.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/logic/Logic.java)
+[`Logic.java`](https://github.com/ay2021s2-cs2103-t16-3/tp/tree/master/src/main/java/seedu/address/logic/Logic.java)
-1. `Logic` uses the `AddressBookParser` class to parse the user command.
+1. `Logic` uses the `ResidenceTrackerParser` class to parse the user command.
1. This results in a `Command` object which is executed by the `LogicManager`.
-1. The command execution can affect the `Model` (e.g. adding a person).
+1. The command execution can affect the `Model` (e.g. adding a residence).
1. The result of the command execution is encapsulated as a `CommandResult` object which is passed back to the `Ui`.
1. In addition, the `CommandResult` object can also instruct the `Ui` to perform certain actions, such as displaying help to the user.
@@ -97,17 +97,16 @@ Given below is the Sequence Diagram for interactions within the `Logic` componen

-**API** : [`Model.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/model/Model.java)
-
+**API** : [`Model.java`](https://github.com/ay2021s2-cs2103-t16-3/tp/tree/master/src/main/java/seedu/address/model/Model.java)
The `Model`,
* stores a `UserPref` object that represents the user’s preferences.
-* stores the address book data.
-* exposes an unmodifiable `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.
+* stores the residence tracker data.
+* exposes an unmodifiable `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.
* does not depend on any of the other three components.
-
:information_source: **Note:** An alternative (arguably, a more OOP) model is given below. It has a `Tag` list in the `AddressBook`, which `Person` references. This allows `AddressBook` to only require one `Tag` object per unique `Tag`, instead of each `Person` needing their own `Tag` object.
+
:information_source: **Note:** An alternative (arguably, a more OOP) model is given below. It has a `Tag` list in the `ResidenceTracker`, which `Residence` references. This allows `ResidenceTracker` to only require one `Tag` object per unique `Tag`, instead of each `Residence` needing their own `Tag` object.

@@ -117,15 +116,15 @@ The `Model`,

-**API** : [`Storage.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/storage/Storage.java)
+**API** : [`Storage.java`](https://github.com/ay2021s2-cs2103-t16-3/tp/tree/master/src/main/java/seedu/address/storage/Storage.java)
The `Storage` component,
* can save `UserPref` objects in json format and read it back.
-* can save the address book data in json format and read it back.
+* can save the residence tracker data in json format and read it back.
### Common classes
-Classes used by multiple components are in the `seedu.addressbook.commons` package.
+Classes used by multiple components are in the `seedu.address.commons` package.
--------------------------------------------------------------------------------------------------------------------
@@ -133,89 +132,65 @@ Classes used by multiple components are in the `seedu.addressbook.commons` packa
This section describes some noteworthy details on how certain features are implemented.
-### \[Proposed\] Undo/redo feature
-
-#### Proposed Implementation
-
-The proposed undo/redo mechanism is facilitated by `VersionedAddressBook`. It extends `AddressBook` with an undo/redo history, stored internally as an `addressBookStateList` and `currentStatePointer`. Additionally, it implements the following operations:
+### Remind feature
-* `VersionedAddressBook#commit()` — Saves the current address book state in its history.
-* `VersionedAddressBook#undo()` — Restores the previous address book state from its history.
-* `VersionedAddressBook#redo()` — Restores a previously undone address book state from its history.
+#### Implementation
-These operations are exposed in the `Model` interface as `Model#commitAddressBook()`, `Model#undoAddressBook()` and `Model#redoAddressBook()` respectively.
+The proposed mechanism is facilitated by the `logic` component described above. It filters the displayed `Residence` list to show those with bookings starting in the next 7 days. It makes use of the following new method in `Residence`.
-Given below is an example usage scenario and how the undo/redo mechanism behaves at each step.
+* `Residence#hasUpcomingBooking()` — Returns true if the `Residence` has a booking starting in the next 7 days.
-Step 1. The user launches the application for the first time. The `VersionedAddressBook` will be initialized with the initial address book state, and the `currentStatePointer` pointing to that single address book state.
+These operations make use of the `Model` interface's `Model#updateFilteredResidenceList(Predicate predicate)` method and `Model` has a new public static `Predicate` named `PREDICATE_UPCOMING_BOOKED_RESIDENCES`.
-
+Given below is an example usage scenario and how the reminder filtering mechanism behaves at each step.
-Step 2. The user executes `delete 5` command to delete the 5th person in the address book. The `delete` command calls `Model#commitAddressBook()`, causing the modified state of the address book after the `delete 5` command executes to be saved in the `addressBookStateList`, and the `currentStatePointer` is shifted to the newly inserted address book state.
+Step 1. The user launches the application for the first time. The `ResidenceTracker` will be initialized with the initial residence tracker state.
-
+Step 2. The user executes `addb 2 n/New Tenant p/098 ...` command to add a booking that starts within the next 7 days to the 2nd residence in the residence tracker. The `addb` command calls `Residence#addBooking(Booking booking)`, which replaces the 2nd residence with the new `Residence` after the command execution.
-Step 3. The user executes `add n/David …` to add a new person. The `add` command also calls `Model#commitAddressBook()`, causing another modified address book state to be saved into the `addressBookStateList`.
+Step 3. The user executes `remind` to list all residences with upcoming bookings. The `remind` command also calls `Model#updateFilteredResidenceList(Predicate predicate)`, causing a filtered list of `Residence`s to be displayed which includes the updated residence from the previous step.
-
-
-
:information_source: **Note:** If a command fails its execution, it will not call `Model#commitAddressBook()`, so the address book state will not be saved into the `addressBookStateList`.
-
-
-
-Step 4. The user now decides that adding the person was a mistake, and decides to undo that action by executing the `undo` command. The `undo` command will call `Model#undoAddressBook()`, which will shift the `currentStatePointer` once to the left, pointing it to the previous address book state, and restores the address book to that state.
-
-
-
-
:information_source: **Note:** If the `currentStatePointer` is at index 0, pointing to the initial AddressBook state, then there are no previous AddressBook states to restore. The `undo` command uses `Model#canUndoAddressBook()` 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 4. Any successful execution of commands `add`, `addb`, `edit`, `editb`, `delete`, `deleteb` or `list` will return to the previous display of the full residence list.
-The following sequence diagram shows how the undo operation works:
-
-
-
-
:information_source: **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#redoAddressBook()`, which shifts the `currentStatePointer` once to the right, pointing to the previously undone state, and restores the address book to that state.
+#### Design consideration:
-
:information_source: **Note:** If the `currentStatePointer` is at index `addressBookStateList.size() - 1`, pointing to the latest address book state, then there are no undone AddressBook states to restore. The `redo` command uses `Model#canRedoAddressBook()` 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 & redo executes
-
+* **Alternative 1 (current choice):** Checks if residences have bookings starting in the next 7 days.
+ * Pros: Easy to implement.
+ * Cons: User is forced to actively use the command to be reminded.
-Step 5. The user then decides to execute the command `list`. Commands that do not modify the address book, such as `list`, will usually not call `Model#commitAddressBook()`, `Model#undoAddressBook()` or `Model#redoAddressBook()`. Thus, the `addressBookStateList` remains unchanged.
+* **Alternative 2:** Residences are automatically displayed with residences having upcoming bookings on top.
+ * Pros: Users will be able to see the residences that need the most urgent attention on top of their list without interacting with the app.
+ * Cons: The users will not be able to tell how many in the list will need to be cleaned immediately for the next 7 days.
+ Using colour codes to differentiate the residences from the rest will make it visually more unpleasant for the users as it already uses colour coding for bookings.
-
+### Status feature
-Step 6. The user executes `clear`, which calls `Model#commitAddressBook()`. Since the `currentStatePointer` is not pointing at the end of the `addressBookStateList`, all address book states after the `currentStatePointer` will be purged. Reason: It no longer makes sense to redo the `add n/David …` command. This is the behavior that most modern desktop applications follow.
+#### Implementation
-
+The proposed mechanism is facilitated by the `logic` component described above. It updates clean status of multiple `Residences` at one time. It makes use of the following new method.
-The following activity diagram summarizes what happens when a user executes a new command:
+* `StausCommand#createUpdatedResidence()` — Create updated residence with the required clean status and the same other data.
+* `StausCommandParser#paser()` — Manage the status command input, return a status command with required clean status and target residence index list.
-
+These operations make use of the `Model` interface's `Model#updateFilteredResidenceList(Predicate predicate)` method to update the order of residence list,
+and `Model#setResidence()` to update the residence in the residence list.
-#### Design consideration:
+Given below is an example usage scenario and how the `status` filtering mechanism behaves at each step.
-##### Aspect: How undo & redo executes
+Step 1. The user launches the application for the first time. The `ResidenceTracker` will be initialized with the initial residence tracker state.
-* **Alternative 1 (current choice):** Saves the entire address book.
- * Pros: Easy to implement.
- * Cons: May have performance issues in terms of memory usage.
+Step 2. The user executes two or more input`add n/NAME a/ADDRESS c/y ...` command to add multiple residence with the same clean status "CLEAN". The `add` command calls `addResidence()` which checks and adds new residence to the end of unique residence list where "UNCLEAN" residences is in front of "CLEAN" residences.
-* **Alternative 2:** Individual command knows how to undo/redo by
- itself.
- * Pros: Will use less memory (e.g. for `delete`, just save the person being deleted).
- * Cons: We must ensure that the implementation of each individual command are correct.
+Step 3. The user executes `status unclean 4 5` to update the forth and fifth residences' clean status to "UNCLEAN". The `status` command also calls `Model#updateFilteredResidenceList(Predicate predicate)`, causing an ordered list of `Residence`s to be displayed.
-_{more aspects and alternatives to be added}_
+The following sequence diagram shows how the status operation works:
-### \[Proposed\] Data archiving
+
-_{Explain here how the data archiving feature will be implemented}_
+The following activity diagram summarizes what happens when a user executes a `status` command:
+
--------------------------------------------------------------------------------------------------------------------
@@ -236,63 +211,219 @@ _{Explain here how the data archiving feature will be implemented}_
**Target user profile**:
-* has a need to manage a significant number of contacts
-* prefer desktop apps over other types
-* can type fast
-* prefers typing to mouse interactions
-* is reasonably comfortable using CLI apps
+* busy user that has to manage a considerable number of residences
+* is constantly renting out residences; high turnover rate
+* prefers working on laptop over mobile
+* is able to type quickly
+* prefers using a keyboard to using a mouse
+* is familiar with CLI apps
-**Value proposition**: manage contacts faster than a typical mouse/GUI driven app
+**Value proposition**: easily keep track of residences and inform cleaning agency whenever necessary
### User stories
Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unlikely to have) - `*`
-| Priority | As a … | I want to … | So that I can… |
-| -------- | ------------------------------------------ | ------------------------------ | ---------------------------------------------------------------------- |
-| `* * *` | new user | see usage instructions | refer to instructions when I forget how to use the App |
-| `* * *` | user | add a new person | |
-| `* * *` | user | delete a person | remove entries that I no longer need |
-| `* * *` | user | find a person by name | locate details of persons without having to go through the entire list |
-| `* *` | user | hide private contact details | minimize chance of someone else seeing them by accident |
-| `*` | user with many persons in the address book | sort persons by name | locate a person easily |
+| Priority | As a … | I want to … | So that I can… |
+| -------- | ------------------------------------------ | ----------------------------------- | ---------------------------------------------------------------------- |
+| `* * *` | new user | See a list of all commands | refer to instructions when I forget how to use the App |
+| `* * *` | user | add a new residence | manage all the residences I wish to keep track of |
+| `* * *` | user | delete a residence | remove residences that I no longer need to track |
+| `* * *` | user | find a residence by name | review details of specific residences without having to go through the entire list |
+| `* *` | new user | clear all sample residences | begin using Residence Tracker with my own data quickly
+| `* *` | user | edit a residence | change the information of a residence when necessary |
+|`* *` | user | exit the application | use my computer for other stuff
+|`* *` | user | go through a tutorial guide | quickly learn the usage of the application
+|`* *` | user | add a new booking of a residence | keep track of all booking information of my residences
+|`* *` | user | edit a new booking of a residence | change the information of booking when necessary
+|`* *` | user | delete a new booking of a residence | remove booking details that I no longer need to track
+|`* *` | busy user | be reminded me of upcoming bookings | quickly view the residences that need to be urgently cleaned
+| `*` | busy user renting out many residences | update status of multiple residence at once | save time and get to my other works |
+
*{More to be added}*
### Use cases
-(For all use cases below, the **System** is the `AddressBook` and the **Actor** is the `user`, unless specified otherwise)
+(For all use cases below, the **System** is the `ResidenceTracker` and the **Actor** is the `user`, unless specified otherwise)
-**Use case: Delete a person**
+**Use case (UC01): Add a residence**
+**MSS**
+1. User adds in the details of a residence.
+2. User validates the details of the residence to be added.
+3. System confirms the addition and residence is added to the list of existing residence.
+4. System saves the updated data.
+ Use case ends.
-**MSS**
+**Extensions**
-1. User requests to list persons
-2. AddressBook shows a list of persons
-3. User requests to delete a specific person in the list
-4. AddressBook deletes the person
+* 2a. System detects error in submission if user did not provide all relevant fields correctly.
+ * 2a1. ResidenceTracker shows an error message.
+ use case restarts from 1.
+
- Use case ends.
+**Use case (UC02): Delete a residence**
+**MSS**
+1. User deletes a residence.
+2. System validates the residence to be deleted.
+3. System deletes the respective entry of the residence.
+4. System saves the updated data.
+ Use case ends.
**Extensions**
-* 2a. The list is empty.
+* 2a. System detects an error in the user input.
+ * 2a1. System requests for the expected format to delete a residence.
+ * 2a2. User inputs the corrected details to delete a residence.
+
+ Use case resumes at step 2.
+
+
+
+**Use case(UC03): Find a residence**
+**MSS**
+1. User searches residences with keywords.
+2. System returns the residence(s) which include the keyword in their name.
+ Use case ends.
+
+**Extensions**
+* 1a. System found no matching residences.
+ * 1a1. A corresponding message is shown and the residence list displayed is empty.
+ Use case ends.
+
+
+
+**Use case(UC04): View list of all residences**
+**MSS**
+1. User lists all residences.
+2. System displays all residences in the list.
+ Use case ends.
+
+
+
+**Use case(UC05): Edit information of a residence**
+**MSS**
+1. User edits a residence.
+2. System validates the edits to the given residence.
+3. System updates the residence accordingly.
+4. System saves the updated data.
+ Use case ends.
+
+**Extensions**
+* 2a. System detects an error in the user input.
+ * 2a1. System requests for the expected input format to edit a residence.
+ * 2a2. User inputs the corrected details to edit a residence.
+ Use case resumes at step 2.
+
+
+
+**Use case (UC06): Show all available commands**
+**MSS**
+1. User requests the help page.
+2. System displays the help page.
+ Use case ends.
+
+
+
+**Use case (UC07): Exit the application**
+**MSS**
+1. User exits the application.
+2. System shuts down.
+ Use case ends.
+
+
+
+**Use case(UC08): Update clean status of multiple residences at once**
+**MSS**
+1. User updates multiple residences' clean status at once.
+2. System confirms the validity of clean status and residences provided.
+3. System updates the required residences' clean status.
+4. System saves the updated data.
+ Use case ends.
+
+**Extensions**
+* 2a. System detects an error in the user input.
+
+ * 2a1. System requests for the expected format to update multiple residences' clean status.
+ * 2a2. User inputs the corrected details to update multiple residences' clean status.
+ Use case resumes at step 2.
+
+
+
+**Use case(UC09): Adds a new booking of the specified residence**
+**MSS**
+1. User adds a new booking to a residence.
+2. System confirms the validity of the residence and the new booking details.
+3. System adds the new booking to the residence's booking list.
+4. System saves the updated data.
+ Use case ends.
+
+**Extensions**
+* 2a. System detects an error in the user input.
+
+ * 2a1. System requests for the expected format to add a booking to a residence.
+ * 2a2. User inputs the corrected details to add a booking to a residence.
+ Use case resumes at step 2.
+
+
+
+**Use case(UC10): edit a booking of the specified residence**
+**MSS**
+1. User edits a residence's booking.
+2. System confirms the validity of the residence and the edited booking details.
+3. System updates the given booking in the residence's booking list.
+4. System saves the updated data.
+ Use case ends.
+
+**Extensions**
+* 2a. System detects an error in the user input
+
+ * 2a1. System requests for the expected format of editing a residence's booking.
+ * 2a2. User inputs the corrected details to edit a residence's booking.
+ Use case resumes at step 2.
+
+
+
+**Use case (UC11): Delete a booking of a residence**
- Use case ends.
+**MSS**
+1. User deletes a booking from a residence.
+2. System validates the booking to be deleted.
+3. System deletes the respective entry of the booking from the given residence.
+4. System saves the updated data.
+ Use case ends.
-* 3a. The given index is invalid.
+**Extensions**
- * 3a1. AddressBook shows an error message.
+* 2a. System detects an error in the user input.
- Use case resumes at step 2.
+ * 2a1. System requests for the correct format to delete a booking from a residence.
+ * 2a2. User inputs the corrected details to delete a booking from a residence.
+ Use case resumes at step 2.
-*{More to be added}*
+
+
+**Use case (UC12): Reminder of Residences with Upcoming Bookings**
+**MSS**
+1. User requests a reminder of residences with upcoming bookings.
+2. System shows a list of all residences with bookings starting in the next 7 days.
+ Use case ends.
+
+
+
+**Use case (UC13): CLear all residence at once**
+**MSS**
+1. User chooses to clear all residences.
+2. System deletes all residence data from the storage file.
+ Use case ends.
+
+
### Non-Functional Requirements
1. Should work on any _mainstream OS_ as long as it has Java `11` or above installed.
-2. Should be able to hold up to 1000 persons without a noticeable sluggishness in performance for typical usage.
+2. Should be able to hold up to 100 residences without a noticeable sluggishness in performance for typical usage.
3. A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse.
*{More to be added}*
@@ -300,8 +431,10 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli
### Glossary
* **Mainstream OS**: Windows, Linux, Unix, OS-X
-* **Private contact detail**: A contact detail that is not meant to be shared with others
-
+* **Residence Status**:
+ * **Clean**: The residence has been cleaned
+ * **Unclean**: The residence needs to be cleaned
+
--------------------------------------------------------------------------------------------------------------------
## **Appendix: Instructions for manual testing**
@@ -328,29 +461,34 @@ testers are expected to do more *exploratory* testing.
1. Re-launch the app by double-clicking the jar file.
Expected: The most recent window size and location is retained.
-1. _{ more test cases … }_
-
-### Deleting a person
+### Deleting a residence
-1. Deleting a person while all persons are being shown
+1. Deleting a residence while all residence are being shown
- 1. Prerequisites: List all persons using the `list` command. Multiple persons in the list.
+ 1. Prerequisites: List all residences using the `list` command. Multiple residences in the list.
1. 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.
+ Expected: First residence is deleted from the list. Details of the deleted residence shown in the status message.
1. Test case: `delete 0`
- Expected: No person is deleted. Error details shown in the status message. Status bar remains the same.
+ Expected: No residence is deleted. Error details shown in the status message. Status bar remains the same.
1. Other incorrect delete commands to try: `delete`, `delete x`, `...` (where x is larger than the list size)
Expected: Similar to previous.
-1. _{ more test cases … }_
-
### Saving data
-1. Dealing with missing/corrupted data files
+1. Dealing with corrupted data files
+
+ 1. Prerequisites: There are some stored residences in the residence tracker. The app is closed.
+
+ 1. Test case: corrupted `residencetracker.json`
+ Steps: First edit the `residencetracker.json` such that it becomes an invalid format by removing a single `}` at the end of the file. Open the residence tracker.
+ Expected: The residence tracker will start but the residence list will be empty (i.e all previous data is lost). Add a few residences and try other commands. They should work as expected.
- 1. _{explain how to simulate a missing/corrupted file, and the expected behavior}_
+ 1. Test case: missing `residencetracker.json`
+ Steps: Exit the residence tracker. First delete the `residencetracker.json` from the `/data` directory. Open the residence tracker.
+ Expected: The residence tracker will start with only the sample data.
+
1. _{ more test cases … }_
diff --git a/docs/SettingUp.md b/docs/SettingUp.md
index 77667c6d581..04c6360553a 100644
--- a/docs/SettingUp.md
+++ b/docs/SettingUp.md
@@ -45,11 +45,4 @@ If you plan to use Intellij IDEA (highly recommended):
1. **Learn the design**
- When you are ready to start coding, we recommend that you get some sense of the overall design by reading about [AddressBook’s architecture](DeveloperGuide.md#architecture).
-
-1. **Do the tutorials**
- These tutorials will help you get acquainted with the codebase.
-
- * [Tracing code](tutorials/TracingCode.md)
- * [Removing fields](tutorials/RemovingFields.md)
- * [Adding a new command](tutorials/AddRemark.md)
+ When you are ready to start coding, we recommend that you get some sense of the overall design by reading about [ResidenceTracker’s architecture](DeveloperGuide.md#architecture).
diff --git a/docs/UserGuide.md b/docs/UserGuide.md
index 3716f3ca8a4..424974f3295 100644
--- a/docs/UserGuide.md
+++ b/docs/UserGuide.md
@@ -3,7 +3,11 @@ layout: page
title: User Guide
---
-AddressBook Level 3 (AB3) is a **desktop app for managing contacts, optimized for use via a Command Line Interface** (CLI) while still having the benefits of a Graphical User Interface (GUI). If you can type fast, AB3 can get your contact management tasks done faster than traditional GUI apps.
+
+ResidenceTracker (RT) is a **desktop app for managing residences, optimized for use via a Command Line Interface** (CLI) while still having the benefits of a Graphical User Interface (GUI). If you can type fast, RT can get your residence management tasks done faster than traditional GUI apps.
+
+In addition to being able to managing several residences at once with just a few key strokes of the keyboard,
+ResidenceTracker helps users to also keep track of any bookings a residence has, overseeing multiple residences with ease.
* Table of Contents
{:toc}
@@ -14,9 +18,9 @@ AddressBook Level 3 (AB3) is a **desktop app for managing contacts, optimized fo
1. Ensure you have Java `11` or above installed in your Computer.
-1. Download the latest `addressbook.jar` from [here](https://github.com/se-edu/addressbook-level3/releases).
+1. Download the latest `residencetracker.jar` from [here](https://github.com/AY2021S2-CS2103-T16-3/tp/releases).
-1. Copy the file to the folder you want to use as the _home folder_ for your AddressBook.
+1. Copy the file to the folder you want to use as the _home folder_ for your ResidenceTracker.
1. Double-click the file to start the app. The GUI similar to the below should appear in a few seconds. Note how the app contains some sample data.

@@ -24,14 +28,11 @@ AddressBook Level 3 (AB3) is a **desktop app for managing contacts, optimized fo
1. Type the command in the command box and press Enter to execute it. e.g. typing **`help`** and pressing Enter will open the help window.
Some example commands you can try:
- * **`list`** : Lists all contacts.
-
- * **`add`**`n/John Doe p/98765432 e/johnd@example.com a/John street, block 123, #01-01` : Adds a contact named `John Doe` to the Address Book.
-
- * **`delete`**`3` : Deletes the 3rd contact shown in the current list.
-
- * **`clear`** : Deletes all contacts.
-
+ * **`list`** : Lists all residences in the app.
+ * **`add`**`n/Clementi HDB a/459A Clementi Ave 3, #04-257, S121459 c/n` : Adds a residence named `Clementi HDB` to the ResidenceTracker.
+ * **`edit`**`1 c/y` : edit the first residence clean status as Clean.
+ * **`delete`**`3` : Deletes the 3rd residence shown in the current list.
+ * **`clear`** : Deletes all residences.
* **`exit`** : Exits the app.
1. Refer to the [Features](#features) below for details of each command.
@@ -45,19 +46,19 @@ AddressBook Level 3 (AB3) is a **desktop app for managing contacts, optimized fo
**:information_source: Notes about the command format:**
* Words in `UPPER_CASE` are the parameters to be supplied by the user.
- e.g. in `add n/NAME`, `NAME` is a parameter which can be used as `add n/John Doe`.
+ e.g. in `add n/NAME`, `NAME` is a parameter which can be used as `add n/Amber Heights`.
* Items in square brackets are optional.
- e.g `n/NAME [t/TAG]` can be used as `n/John Doe t/friend` or as `n/John Doe`.
+ e.g `n/NAME [t/TAG]` can be used as `n/Amber Heights t/friend` or as `n/Amber Heights`.
* Items with `…` after them can be used multiple times including zero times.
e.g. `[t/TAG]…` can be used as ` ` (i.e. 0 times), `t/friend`, `t/friend t/family` etc.
* Parameters can be in any order.
- e.g. if the command specifies `n/NAME p/PHONE_NUMBER`, `p/PHONE_NUMBER n/NAME` is also acceptable.
+ e.g. if the command specifies `n/NAME a/ADDRESS`, `a/ADDRESS n/NAME` is also acceptable.
* If a parameter is expected only once in the command but you specified it multiple times, only the last occurrence of the parameter will be taken.
- e.g. if you specify `p/12341234 p/56785678`, only `p/56785678` will be taken.
+ e.g. if you specify `a/Jurong West St 60 a/Jurong West St 70`, only `a/Jurong West St 70` will be taken.
* Extraneous parameters for commands that do not take in parameters (such as `help`, `list`, `exit` and `clear`) will be ignored.
e.g. if the command specifies `help 123`, it will be interpreted as `help`.
@@ -66,88 +67,175 @@ AddressBook Level 3 (AB3) is a **desktop app for managing contacts, optimized fo
### Viewing help : `help`
-Shows a message explaning how to access the help page.
+Shows a message with the current list of commands along with examples.
+It also provides a button to copy the URL link to access the help page.

Format: `help`
-### Adding a person: `add`
+### Adding a residence: `add`
-Adds a person to the address book.
+Adds a new residence to the list of residences, default for clean status is ‘clean’. Valid clean status inputs are `y`,`n`, `clean` and `unclean`
-Format: `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]…`
+* Names can include `@` inside. e.g `pinnacle@duxton`
+* Names can include numbers. e.g `Block71`
+* Names must include at least one alphanumeric character.
+* Valid clean statuses is case-insensitive, e.g `c/Y` is the same as `c/y`, `c/clean` is the same as `c/ClEaN`.
+* Address can contain any alphanumeric character and symbols. `@!df34!@//` is considered a valid address.
+* Tags should only contain alphanumeric characters, symbols and spaces are not valid.
-
:bulb: **Tip:**
-A person can have any number of tags (including 0)
-
+Format: ` add n/RESIDENCE_NAME a/ADDRESS [c/VALID_CLEAN_STATUS] [t/TAG]... `
Examples:
-* `add n/John Doe p/98765432 e/johnd@example.com a/John street, block 123, #01-01`
-* `add n/Betsy Crowe t/friend e/betsycrowe@example.com a/Newgate Prison p/1234567 t/criminal`
+* `add n/Melville Park a/22 Simei Street 1, #10-02, S529948`
+* `add n/Clementi HDB a/459A Clementi Ave 3, #04-257, S121459 c/n`
-### Listing all persons : `list`
+### Listing all residences: `list`
-Shows a list of all persons in the address book.
+Shows a list of all residences in the app.
Format: `list`
-### Editing a person : `edit`
+* The displayed list of residences will be sorted by their clean status.
+* Unclean residences come before clean residences.
-Edits an existing person in the address book.
+### Listing residences with bookings starting in the next 7 days: `remind`
-Format: `edit INDEX [n/NAME] [p/PHONE] [e/EMAIL] [a/ADDRESS] [t/TAG]…`
+Shows a list of all residences with bookings starting in the next 7 days.
-* Edits the person at the specified `INDEX`. The index refers to the index number shown in the displayed person list. The index **must be a positive integer** 1, 2, 3, …
-* At least one of the optional fields must be provided.
-* Existing values will be updated to the input values.
-* When editing tags, the existing tags of the person will be removed i.e adding of tags is not cumulative.
-* You can remove all the person’s tags by typing `t/` without
- specifying any tags after it.
+Format: `remind`
+
+* Next 7 days: If today is 1st April, residences with bookings starting on 2nd April to 8th April (inclusive) will be listed.
+* The displayed list of residences is always sorted.
+* Unclean residences come before clean residences.
+
+### Editing a residence: `edit`
+
+Edits the given fields of an existing residence (excludes bookings, see `editb` instead to edit bookings).
+
+Format: `edit RESIDENCE_INDEX [n/RESIDENCE_NAME] [a/ADDRESS] [c/VALID_CLEAN_STATUS] [t/TAG]`
+
+* Edits the residence at the specified `RESIDENCE_INDEX`.
+* The `RESIDENCE_INDEX` refers to the index number shown in the displayed residence list(i.e. **NOT** zero-indexed, items start at index 1).
+* The `RESIDENCE_INDEX` **must be a positive integer** 1, 2, 3, …
+* At least one field must be provided.
+* If this command is used to edit tags, all tags for this residence need to be specified.
+* Address can contain any alphanumeric character and symbols. `@!df34!@//` is considered a valid address.
+* Valid clean statuses is case-insensitive, e.g `c/Y` is the same as `c/y`, `c/clean` is the same as `c/ClEaN`.
+* Tags should only contain alphanumeric characters, symbols and spaces are not valid.
+* Editing of tags overwrites all existing tags.
Examples:
-* `edit 1 p/91234567 e/johndoe@example.com` Edits the phone number and email address of the 1st person to be `91234567` and `johndoe@example.com` respectively.
-* `edit 2 n/Betsy Crower t/` Edits the name of the 2nd person to be `Betsy Crower` and clears all existing tags.
+* `edit 1 c/y` Edits the clean status of the 1st residence on the list to `Clean`.
+* `edit 2 n/Nashville` Edits the name of the 2nd residence on the list from to `Nashville`.
+* `edit 1 t/tag1 t/tag2` Edits the 1st residence on the list to have tags `tag1` and `tag2`.
-### Locating persons by name: `find`
+### Locating residences by name: `find`
-Finds persons whose names contain any of the given keywords.
+Finds residences whose names contain any of the given keywords.
-Format: `find KEYWORD [MORE_KEYWORDS]`
+Format: `find KEYWORD [MORE_KEYWORDS]...`
-* The search is case-insensitive. e.g `hans` will match `Hans`
-* The order of the keywords does not matter. e.g. `Hans Bo` will match `Bo Hans`
+* The search is case-insensitive. e.g `duxton` will match `Duxton`
+* The order of the keywords does not matter. e.g. `Gardens Bay` will match `Bay Gardens`
* Only the name is searched.
-* Only full words will be matched e.g. `Han` will not match `Hans`
-* Persons matching at least one keyword will be returned (i.e. `OR` search).
- e.g. `Hans Bo` will return `Hans Gruber`, `Bo Yang`
+* Only full words will be matched e.g. `Dux` will not match `Duxton`
+* Apartments matching at least one keyword will be returned (i.e. `OR` search).
+ e.g. `Gardens Bay` will return `Botanic Gardens`, `Bay Area`
Examples:
-* `find John` returns `john` and `John Doe`
-* `find alex david` returns `Alex Yeoh`, `David Li`
- 
+* `find heights` returns `Hillview Heights` and `Aspen Heights`
+* `find east coast` returns `East View`, `West Coast`
-### Deleting a person : `delete`
+### Deleting a residence: `delete`
-Deletes the specified person from the address book.
+Deletes the specified residence from the list of residences shown.
-Format: `delete INDEX`
+Format: `delete RESIDENCE_INDEX`
-* Deletes the person at the specified `INDEX`.
-* The index refers to the index number shown in the displayed person list.
-* The index **must be a positive integer** 1, 2, 3, …
+* Deletes the residence at the specified `RESIDENCE_INDEX`.
+* The `RESIDENCE_INDEX` refers to the index number shown in the displayed residences list (i.e. **NOT** zero-indexed, items start at index 1).
+* The `RESIDENCE_INDEX` must be a **positive integer** 1, 2, 3, …
Examples:
-* `list` followed by `delete 2` deletes the 2nd person in the address book.
-* `find Betsy` followed by `delete 1` deletes the 1st person in the results of the `find` command.
+* `list` followed by `delete 3` deletes the 3rd residence in the list of residences shown.
+
+### Update multiple Clean status: `status`
+
+Update Clean status of multiple residences at once.
+
+Format: `status clean RESIDENCE_INDEX1 RESIDENCE_INDEX2..` or `status unclean RESIDENCE_INDEX1 RESIDENCE_INDEX2..`
+
+* Updates the clean status of the residences' with the specified `RESIDENCE_INDEX`.
+* The `RESIDENCE_INDEX` refers to the index number shown in the displayed residences list (i.e. **NOT** zero-indexed, items start at index 1).
+* The `RESIDENCE_INDEX` must be a **positive integer** 1, 2, 3, …
+* More than 1 residence indexes can be specified.
+* After updating, the residence list will sort automatically to show Unclean residences before the clean residences.
+
+Examples:
+* `status clean 1 3` update the 1st and 3rd residences clean status to `Clean`.
+* `status unclean 2 5` update the 2nd and 5th residences clean status to `Unclean`.
+
### Clearing all entries : `clear`
-Clears all entries from the address book.
+Clears all entries from the residence tracker.
Format: `clear`
+### Adding a booking: `addb`
+
+Adds a new booking to the specified residence.
+
+Format: `addb RESIDENCE_INDEX n/NAME_OF_TENANT p/PHONE_OF_TENANT s/START_DATE e/END_DATE`
+
+* Adds a booking to the residence at the specified `RESIDENCE_INDEX`.
+* The `RESIDENCE_INDEX` refers to the index number shown in the displayed residences list (i.e. **NOT** zero-indexed).
+* The `RESIDENCE_INDEX` must be a **positive integer** 1, 2, 3, …
+* The phone must only include numbers and must be at least 3 characters long. e.g `p/999` `p/12345678`
+* The dates must follow the format DD-MM-YYYY. e.g `s/01-02-2021`
+* It is invalid to edit the `START_DATE` to be later than the `END_DATE`. Likewise, it is invalid to update the `END_DATE`
+ to be earlier than the `START_DATE`.
+* It is invalid to edit `START_DATE` or `END_DATE` such that it overlaps with dates of other bookings.
+* Existing values will be updated to the input values.
+
+Examples:
+* `addb 1 n/John p/91234567 s/01-01-2021 e/02-01-2021`
+* `addb 2 n/Jane Tan p/65812567 s/31-12-2021 e/05-01-2022`
+
+### Deleting a booking from a residence: `deleteb`
+
+Deletes the specified booking from the specified residence.
+
+Format: `deleteb r/RESIDENCE_INDEX b/BOOKING_INDEX`
+
+* Deletes the booking at the specified `BOOKING_INDEX` from the residence at the specified `RESIDENCE_INDEX`
+* `RESIDENCE_INDEX` and `BOOKING_INDEX` refers to the index number as shown in ResidenceTracker (i.e. **NOT** zero-indexed, items start at index 1).
+* `RESIDENCE_INDEX` and `BOOKING_INDEX` must be **positive integer** 1, 2, 3, …
+
+Examples:
+* `list` followed by `deleteb r/3 b/2` deletes the 2nd booking from the 3rd residence.
+
+### Editing a booking: `editb`
+
+Edits the specified booking from the specified residence.
+
+Format: `editb r/RESIDENCE_INDEX b/BOOKING_INDEX [n/TENANT_NAME] [p/PHONE] [s/START_DATE] [e/END_DATE]`
+
+* `RESIDENCE_INDEX` and `BOOKING_INDEX` refers to the index number as shown in ResidenceTracker (i.e. **NOT** zero-indexed, items start at index 1).
+* `RESIDENCE_INDEX` and `BOOKING_INDEX` must be **positive integer** 1, 2, 3, …
+* At least one of the optional fields must be provided.
+* It is invalid to edit the `START_DATE` to be later than the `END_DATE`. Likewise, it is invalid to update the `END_DATE`
+to be earlier than the `START_DATE`.
+* It is invalid to edit `START_DATE` or `END_DATE` such that it overlaps with dates of other bookings.
+* Existing values will be updated to the input values.
+
+Examples:
+* `editb r/1 b/2 p/90069009 s/03-28-2021` Edits the phone number and start date of 2nd booking of the 1st residence to be
+`90069009` and `03-28-2021` respectively.
+
### Exiting the program : `exit`
Exits the program.
@@ -156,14 +244,14 @@ Format: `exit`
### Saving the data
-AddressBook data are saved in the hard disk automatically after any command that changes the data. There is no need to save manually.
+ResidenceTracker data are saved in the hard disk automatically after any command that changes the data. There is no need to save manually.
### Editing the data file
-AddressBook data are saved as a JSON file `[JAR file location]/data/addressbook.json`. Advanced users are welcome to update data directly by editing that data file.
+ResidenceTracker data are saved as a JSON file `[JAR file location]/data/residencetracker.json`. Advanced users are welcome to update data directly by editing that data file.
:exclamation: **Caution:**
-If your changes to the data file makes its format invalid, AddressBook will discard all data and start with an empty data file at the next run.
+If your changes to the data file makes its format invalid, ResidenceTracker will discard all data and start with an empty data file at the next run.
### Archiving data files `[coming in v2.0]`
@@ -175,7 +263,7 @@ _Details coming soon ..._
## 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 AddressBook home folder.
+**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 ResidenceTracker home folder.
--------------------------------------------------------------------------------------------------------------------
@@ -183,10 +271,16 @@ _Details coming soon ..._
Action | Format, Examples
--------|------------------
-**Add** | `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]…` e.g., `add n/James Ho p/22224444 e/jamesho@example.com a/123, Clementi Rd, 1234665 t/friend t/colleague`
-**Clear** | `clear`
-**Delete** | `delete INDEX` e.g., `delete 3`
-**Edit** | `edit INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [a/ADDRESS] [t/TAG]…` e.g.,`edit 2 n/James Lee e/jameslee@example.com`
-**Find** | `find KEYWORD [MORE_KEYWORDS]` e.g., `find James Jake`
-**List** | `list`
+**Add Residence** | `add n/NAME_OF_RESIDENCE a/ADDRESS [clean/[y or n]] [t/TAG] …` e.g., `add n/Clementi HDB a/459A Clementi Ave 3, #04-257, S121459 clean/n`
+**Add Booking to Residence** | `addb RESIDENCE_INDEX n/NAME_OF_BOOKER p/PHONE_OF_BOOKER s/START_TIME e/END_TIME` e.g., `add 2 n/John a/91234567 s/01-01-2021 e/02-01-2021`
+**Delete Residence** | `delete INDEX` e.g., `delete 3`
+**Delete Booking of Residence** | `deleteb r/RESIDENCE_INDEX b/BOOKING_INDEX` e.g., `delete r/3 b/2`
+**Edit Residence** | `edit INDEX [n/RESIDENCE_NAME] [a/ADDRESS] [c/VALID_CLEAN_STATUS] [t/TAG]` e.g.,`edit 2 c/n`
+**Edit Booking of Residence** | `editb r/RESIDENCE_INDEX b/BOOKING_INDEX [n/TENANT_NAME] [p/PHONE] [s/START_DATE] [e/END_DATE]` e.g., `editb r/1 b/2 p/90069009 s/03-28-2021`
+**Update Multiple Clean Status** | `status clean INDEX1 INDEX2..` or `status unclean INDEX1 INDEX2..` e.g., `status clean 1 3`
+**Find Residence** | `find KEYWORD [MORE_KEYWORDS]` e.g., `find Heights`
+**Remind Residences with Upcoming Bookings** | `remind`
+**List All Residences** | `list`
**Help** | `help`
+**Exit** | `exit`
+**Clear** | `clear`
diff --git a/docs/_config.yml b/docs/_config.yml
index 6bd245d8f4e..29fc3f25fd4 100644
--- a/docs/_config.yml
+++ b/docs/_config.yml
@@ -1,4 +1,4 @@
-title: "AB-3"
+title: "ResidenceTracker"
theme: minima
header_pages:
@@ -8,7 +8,7 @@ header_pages:
markdown: kramdown
-repository: "se-edu/addressbook-level3"
+repository: "AY2021S2-CS2103T-T16-3/tp"
github_icon: "images/github-icon.png"
plugins:
diff --git a/docs/diagrams/ArchitectureSequenceDiagram.puml b/docs/diagrams/ArchitectureSequenceDiagram.puml
index ef81d18c337..726500d0697 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 1")
activate logic LOGIC_COLOR
-logic -[LOGIC_COLOR]> model : deletePerson(p)
+logic -[LOGIC_COLOR]> model : deleteResidence(Residence)
activate model MODEL_COLOR
model -[MODEL_COLOR]-> logic
deactivate model
-logic -[LOGIC_COLOR]> storage : saveAddressBook(addressBook)
+logic -[LOGIC_COLOR]> storage : saveResidenceTracker(ResidenceTracker)
activate storage STORAGE_COLOR
storage -[STORAGE_COLOR]> storage : Save to file
diff --git a/docs/diagrams/BetterModelClassDiagram.puml b/docs/diagrams/BetterModelClassDiagram.puml
index 29076104af3..d519440b290 100644
--- a/docs/diagrams/BetterModelClassDiagram.puml
+++ b/docs/diagrams/BetterModelClassDiagram.puml
@@ -4,18 +4,24 @@ skinparam arrowThickness 1.1
skinparam arrowColor MODEL_COLOR
skinparam classBackgroundColor MODEL_COLOR
-AddressBook *-right-> "1" UniquePersonList
-AddressBook *-right-> "1" UniqueTagList
-UniqueTagList -[hidden]down- UniquePersonList
-UniqueTagList -[hidden]down- UniquePersonList
+ResidenceTracker *-right-> "1" UniqueResidenceList
+ResidenceTracker *-right-> "1" UniqueTagList
+UniqueTagList -[hidden]down- UniqueResidenceList
+UniqueTagList -[hidden]down- UniqueResidenceList
UniqueTagList *-right-> "*" Tag
-UniquePersonList o-right-> Person
+UniqueResidenceList o-right-> Residence
-Person -up-> "*" Tag
+Residence -up-> "*" Tag
+
+Residence *-->"1" ResidenceName
+Residence *--> "1"ResidenceAddress
+Residence *--> "1" CleanStatusTag
+Residence *--> "1"BookingList
+
+BookingList *-->"*" Booking
+Booking *--> TenantName
+Booking *--> Phone
+Booking *--> BookingTime
-Person *--> Name
-Person *--> Phone
-Person *--> Email
-Person *--> Address
@enduml
diff --git a/docs/diagrams/CommitActivityDiagram.puml b/docs/diagrams/CommitActivityDiagram.puml
index 6a6b23a006f..59fae658c36 100644
--- a/docs/diagrams/CommitActivityDiagram.puml
+++ b/docs/diagrams/CommitActivityDiagram.puml
@@ -5,10 +5,10 @@ start
'Since the beta syntax does not support placing the condition outside the
'diamond we place it as the true branch instead.
-if () then ([command commits AddressBook])
+if () then ([command commits ResidenceTracker])
:Purge redundant states;
- :Save AddressBook to
- addressBookStateList;
+ :Save ResidenceTracker to
+ residenceTrackerStateList;
else ([else])
endif
stop
diff --git a/docs/diagrams/DeleteSequenceDiagram.puml b/docs/diagrams/DeleteSequenceDiagram.puml
index 1dc2311b245..b8f6073b7aa 100644
--- a/docs/diagrams/DeleteSequenceDiagram.puml
+++ b/docs/diagrams/DeleteSequenceDiagram.puml
@@ -3,7 +3,7 @@
box Logic LOGIC_COLOR_T1
participant ":LogicManager" as LogicManager LOGIC_COLOR
-participant ":AddressBookParser" as AddressBookParser LOGIC_COLOR
+participant ":ResidenceTrackerParser" as ResidenceTrackerParser LOGIC_COLOR
participant ":DeleteCommandParser" as DeleteCommandParser LOGIC_COLOR
participant "d:DeleteCommand" as DeleteCommand LOGIC_COLOR
participant ":CommandResult" as CommandResult LOGIC_COLOR
@@ -16,17 +16,17 @@ end box
[-> LogicManager : execute("delete 1")
activate LogicManager
-LogicManager -> AddressBookParser : parseCommand("delete 1")
-activate AddressBookParser
+LogicManager -> ResidenceTrackerParser : parseCommand("delete 1")
+activate ResidenceTrackerParser
create DeleteCommandParser
-AddressBookParser -> DeleteCommandParser
+ResidenceTrackerParser -> DeleteCommandParser
activate DeleteCommandParser
-DeleteCommandParser --> AddressBookParser
+DeleteCommandParser --> ResidenceTrackerParser
deactivate DeleteCommandParser
-AddressBookParser -> DeleteCommandParser : parse("1")
+ResidenceTrackerParser -> DeleteCommandParser : parse("1")
activate DeleteCommandParser
create DeleteCommand
@@ -36,19 +36,19 @@ activate DeleteCommand
DeleteCommand --> DeleteCommandParser : d
deactivate DeleteCommand
-DeleteCommandParser --> AddressBookParser : d
+DeleteCommandParser -->ResidenceTrackerParser : d
deactivate DeleteCommandParser
'Hidden arrow to position the destroy marker below the end of the activation bar.
-DeleteCommandParser -[hidden]-> AddressBookParser
+DeleteCommandParser -[hidden]-> ResidenceTrackerParser
destroy DeleteCommandParser
-AddressBookParser --> LogicManager : d
-deactivate AddressBookParser
+ResidenceTrackerParser --> LogicManager : d
+deactivate ResidenceTrackerParser
LogicManager -> DeleteCommand : execute()
activate DeleteCommand
-DeleteCommand -> Model : deletePerson(1)
+DeleteCommand -> Model : deleteResidence(Residence)
activate Model
Model --> DeleteCommand
diff --git a/docs/diagrams/LogicClassDiagram.puml b/docs/diagrams/LogicClassDiagram.puml
index 50d8aff17a1..755308ea384 100644
--- a/docs/diagrams/LogicClassDiagram.puml
+++ b/docs/diagrams/LogicClassDiagram.puml
@@ -8,7 +8,7 @@ package Logic {
package Parser {
Interface Parser <>
-Class AddressBookParser
+Class ResidenceTrackerParser
Class XYZCommandParser
Class CliSyntax
Class ParserUtil
@@ -39,8 +39,8 @@ Class HiddenOutside #FFFFFF
HiddenOutside ..> Logic
LogicManager .up.|> Logic
-LogicManager -->"1" AddressBookParser
-AddressBookParser .left.> XYZCommandParser: creates >
+LogicManager -->"1" ResidenceTrackerParser
+ResidenceTrackerParser .left.> XYZCommandParser: creates >
XYZCommandParser ..> XYZCommand : creates >
XYZCommandParser .left.|> Parser
diff --git a/docs/diagrams/ModelClassDiagram.puml b/docs/diagrams/ModelClassDiagram.puml
index 3eae5326a82..19a24c3a4a8 100644
--- a/docs/diagrams/ModelClassDiagram.puml
+++ b/docs/diagrams/ModelClassDiagram.puml
@@ -5,23 +5,23 @@ skinparam arrowColor MODEL_COLOR
skinparam classBackgroundColor MODEL_COLOR
Package Model <>{
-Interface ReadOnlyAddressBook <>
+Interface ReadOnlyResidenceTracker <>
Interface Model <>
Interface ObservableList <>
-Class AddressBook
-Class ReadOnlyAddressBook
+Class ResidenceTracker
+Class ReadOnlyResidenceTracker
Class Model
Class ModelManager
Class UserPrefs
Class ReadOnlyUserPrefs
-Package Person {
-Class Person
-Class Address
-Class Email
-Class Name
-Class Phone
-Class UniquePersonList
+Package Residence {
+Class Residence
+Class ResidenceAddress
+Class ResidenceName
+Class CleanStatusTag
+Class BookingList
+Class UniqueResidenceList
}
Package Tag {
@@ -32,25 +32,25 @@ Class Tag
Class HiddenOutside #FFFFFF
HiddenOutside ..> Model
-AddressBook .up.|> ReadOnlyAddressBook
+ResidenceTracker .up.|> ReadOnlyResidenceTracker
ModelManager .up.|> Model
Model .right.> ObservableList
-ModelManager o--> "1" AddressBook
+ModelManager o--> "1" ResidenceTracker
ModelManager o-left-> "1" UserPrefs
UserPrefs .up.|> ReadOnlyUserPrefs
-AddressBook *--> "1" UniquePersonList
-UniquePersonList o--> "*" Person
-Person *--> Name
-Person *--> Phone
-Person *--> Email
-Person *--> Address
-Person *--> "*" Tag
+ResidenceTracker *--> "1" UniqueResidenceList
+UniqueResidenceList o--> "*" Residence
+Residence *--> ResidenceName
+Residence *--> ResidenceAddress
+Residence *--> CleanStatusTag
+Residence *--> BookingList
+Residence *--> "*" Tag
-Name -[hidden]right-> Phone
-Phone -[hidden]right-> Address
-Address -[hidden]right-> Email
+ResidenceName -[hidden]right-> ResidenceAddress
+ResidenceAddress -[hidden]right-> CleanStatusTag
+CleanStatusTag -[hidden]right-> BookingList
-ModelManager ----->" ~* filtered list" Person
+ModelManager ----->" ~* filtered list" Residence
@enduml
diff --git a/docs/diagrams/StorageClassDiagram.puml b/docs/diagrams/StorageClassDiagram.puml
index a200d532529..912433fa007 100644
--- a/docs/diagrams/StorageClassDiagram.puml
+++ b/docs/diagrams/StorageClassDiagram.puml
@@ -6,22 +6,23 @@ skinparam classBackgroundColor STORAGE_COLOR
Interface Storage <>
Interface UserPrefsStorage <>
-Interface AddressBookStorage <>
+Interface ResidenceTrackerStorage <>
Class StorageManager
Class JsonUserPrefsStorage
-Class JsonAddressBookStorage
+Class JsonResidenceTrackerStorage
StorageManager .left.|> Storage
StorageManager o-right-> UserPrefsStorage
-StorageManager o--> AddressBookStorage
+StorageManager o--> ResidenceTrackerStorage
Storage -|> UserPrefsStorage
-Storage -|> AddressBookStorage
+Storage -|> ResidenceTrackerStorage
JsonUserPrefsStorage .left.|> UserPrefsStorage
-JsonAddressBookStorage .left.|> AddressBookStorage
-JsonAddressBookStorage .down.> JsonSerializableAddressBook
-JsonSerializableAddressBook .right.> JsonAdaptedPerson
-JsonAdaptedPerson .right.> JsonAdaptedTag
+JsonResidenceTrackerStorage .left.|> ResidenceTrackerStorage
+JsonResidenceTrackerStorage .down.> JsonSerializableResidenceTracker
+JsonSerializableResidenceTracker .right.> JsonAdaptedResidence
+JsonAdaptedResidence .right.> JsonAdaptedTag
+JsonAdaptedResidence .up.> JsonAdaptedBooking
@enduml
diff --git a/docs/diagrams/UiClassDiagram.puml b/docs/diagrams/UiClassDiagram.puml
index 92746f9fcf7..b6d81b8eaeb 100644
--- a/docs/diagrams/UiClassDiagram.puml
+++ b/docs/diagrams/UiClassDiagram.puml
@@ -11,8 +11,8 @@ Class UiManager
Class MainWindow
Class HelpWindow
Class ResultDisplay
-Class PersonListPanel
-Class PersonCard
+Class ResidenceListPanel
+Class ResidenceCard
Class StatusBarFooter
Class CommandBox
}
@@ -33,25 +33,25 @@ UiManager -down-> MainWindow
MainWindow --> HelpWindow
MainWindow *-down-> CommandBox
MainWindow *-down-> ResultDisplay
-MainWindow *-down-> PersonListPanel
+MainWindow *-down-> ResidenceListPanel
MainWindow *-down-> StatusBarFooter
-PersonListPanel -down-> PersonCard
+ResidenceListPanel -down-> ResidenceCard
MainWindow -left-|> UiPart
ResultDisplay --|> UiPart
CommandBox --|> UiPart
-PersonListPanel --|> UiPart
-PersonCard --|> UiPart
+ResidenceListPanel --|> UiPart
+ResidenceCard --|> UiPart
StatusBarFooter --|> UiPart
HelpWindow -down-|> UiPart
-PersonCard ..> Model
+ResidenceCard ..> Model
UiManager -right-> Logic
MainWindow -left-> Logic
-PersonListPanel -[hidden]left- HelpWindow
+ResidenceListPanel -[hidden]left- HelpWindow
HelpWindow -[hidden]left- CommandBox
CommandBox -[hidden]left- ResultDisplay
ResultDisplay -[hidden]left- StatusBarFooter
diff --git a/docs/diagrams/UndoSequenceDiagram.puml b/docs/diagrams/UndoSequenceDiagram.puml
index 410aab4e412..4183d72f4f9 100644
--- a/docs/diagrams/UndoSequenceDiagram.puml
+++ b/docs/diagrams/UndoSequenceDiagram.puml
@@ -3,42 +3,42 @@
box Logic LOGIC_COLOR_T1
participant ":LogicManager" as LogicManager LOGIC_COLOR
-participant ":AddressBookParser" as AddressBookParser LOGIC_COLOR
+participant ":VersionedResidenceTracker" as VersionedResidenceTracker LOGIC_COLOR
participant "u:UndoCommand" as UndoCommand LOGIC_COLOR
end box
box Model MODEL_COLOR_T1
participant ":Model" as Model MODEL_COLOR
-participant ":VersionedAddressBook" as VersionedAddressBook MODEL_COLOR
+participant ":VersionedResidenceTracker" as VersionedResidenceTracker MODEL_COLOR
end box
[-> LogicManager : execute(undo)
activate LogicManager
-LogicManager -> AddressBookParser : parseCommand(undo)
-activate AddressBookParser
+LogicManager -> ResidenceTrackerParser : parseCommand(undo)
+activate ResidenceTrackerParser
create UndoCommand
-AddressBookParser -> UndoCommand
+ResidenceTrackerParser -> UndoCommand
activate UndoCommand
-UndoCommand --> AddressBookParser
+UndoCommand --> ResidenceTrackerParser
deactivate UndoCommand
-AddressBookParser --> LogicManager : u
-deactivate AddressBookParser
+ResidenceTrackerParser --> LogicManager : u
+deactivate ResidenceTrackerParser
LogicManager -> UndoCommand : execute()
activate UndoCommand
-UndoCommand -> Model : undoAddressBook()
+UndoCommand -> Model : undoResidenceTracker()
activate Model
-Model -> VersionedAddressBook : undo()
-activate VersionedAddressBook
+Model -> VersionedResidenceTracker : undo()
+activate VersionedResidenceTracker
-VersionedAddressBook -> VersionedAddressBook :resetData(ReadOnlyAddressBook)
-VersionedAddressBook --> Model :
-deactivate VersionedAddressBook
+VersionedResidenceTracker -> VersionedResidenceTracker :resetData(ReadOnlyResidenceTracker)
+VersionedResidenceTracker --> Model :
+deactivate VersionedResidenceTracker
Model --> UndoCommand
deactivate Model
diff --git a/docs/diagrams/plantuml/AbeforeC.png b/docs/diagrams/plantuml/AbeforeC.png
new file mode 100644
index 00000000000..5d60025e528
Binary files /dev/null and b/docs/diagrams/plantuml/AbeforeC.png differ
diff --git a/docs/diagrams/plantuml/AllDown.png b/docs/diagrams/plantuml/AllDown.png
new file mode 100644
index 00000000000..bb5caa4737c
Binary files /dev/null and b/docs/diagrams/plantuml/AllDown.png differ
diff --git a/docs/diagrams/plantuml/ArrowLength.png b/docs/diagrams/plantuml/ArrowLength.png
new file mode 100644
index 00000000000..a6f8b4e5f08
Binary files /dev/null and b/docs/diagrams/plantuml/ArrowLength.png differ
diff --git a/docs/diagrams/plantuml/CbeforeA.png b/docs/diagrams/plantuml/CbeforeA.png
new file mode 100644
index 00000000000..6fed2f8a1c3
Binary files /dev/null and b/docs/diagrams/plantuml/CbeforeA.png differ
diff --git a/docs/diagrams/plantuml/HiddenArrows.png b/docs/diagrams/plantuml/HiddenArrows.png
new file mode 100644
index 00000000000..8eb1605927e
Binary files /dev/null and b/docs/diagrams/plantuml/HiddenArrows.png differ
diff --git a/docs/diagrams/plantuml/PackagesAndConsistency.png b/docs/diagrams/plantuml/PackagesAndConsistency.png
new file mode 100644
index 00000000000..f70464b7a7c
Binary files /dev/null and b/docs/diagrams/plantuml/PackagesAndConsistency.png differ
diff --git a/docs/diagrams/plantuml/UpAndDown.png b/docs/diagrams/plantuml/UpAndDown.png
new file mode 100644
index 00000000000..9ceb4d0ee08
Binary files /dev/null and b/docs/diagrams/plantuml/UpAndDown.png differ
diff --git a/docs/diagrams/tracing/LogicSequenceDiagram.png b/docs/diagrams/tracing/LogicSequenceDiagram.png
new file mode 100644
index 00000000000..46f81cc164c
Binary files /dev/null and b/docs/diagrams/tracing/LogicSequenceDiagram.png differ
diff --git a/docs/diagrams/tracing/LogicSequenceDiagram.puml b/docs/diagrams/tracing/LogicSequenceDiagram.puml
index fdcbe1c0ccc..05d97f0cd3b 100644
--- a/docs/diagrams/tracing/LogicSequenceDiagram.puml
+++ b/docs/diagrams/tracing/LogicSequenceDiagram.puml
@@ -2,7 +2,7 @@
!include ../style.puml
Participant ":LogicManager" as logic LOGIC_COLOR
-Participant ":AddressBookParser" as abp LOGIC_COLOR
+Participant ":ResidenceTrackerParser" as abp LOGIC_COLOR
Participant ":EditCommandParser" as ecp LOGIC_COLOR
Participant "command:EditCommand" as ec LOGIC_COLOR
@@ -13,7 +13,7 @@ create ecp
abp -> ecp
abp -> ecp ++: parse(arguments)
create ec
-ecp -> ec ++: index, editPersonDescriptor
+ecp -> ec ++: index, editResidenceDescriptor
ec --> ecp --
ecp --> abp --: command
abp --> logic --: command
diff --git a/docs/images/ArchitectureSequenceDiagram.png b/docs/images/ArchitectureSequenceDiagram.png
index 2f1346869d0..3a07a2be6b3 100644
Binary files a/docs/images/ArchitectureSequenceDiagram.png and b/docs/images/ArchitectureSequenceDiagram.png differ
diff --git a/docs/images/BetterModelClassDiagram.png b/docs/images/BetterModelClassDiagram.png
index bc7ed18ae29..7ff44d5b37d 100644
Binary files a/docs/images/BetterModelClassDiagram.png and b/docs/images/BetterModelClassDiagram.png differ
diff --git a/docs/images/CommitActivityDiagram.png b/docs/images/CommitActivityDiagram.png
index c08c13f5c8b..0743e788b54 100644
Binary files a/docs/images/CommitActivityDiagram.png and b/docs/images/CommitActivityDiagram.png differ
diff --git a/docs/images/DeleteSequenceDiagram.png b/docs/images/DeleteSequenceDiagram.png
index fa327b39618..9afa458ba95 100644
Binary files a/docs/images/DeleteSequenceDiagram.png and b/docs/images/DeleteSequenceDiagram.png differ
diff --git a/docs/images/LogicClassDiagram.png b/docs/images/LogicClassDiagram.png
index e434feaf5b8..8a84011a511 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 ffd17662d41..4bd1dca8c1d 100644
Binary files a/docs/images/ModelClassDiagram.png and b/docs/images/ModelClassDiagram.png differ
diff --git a/docs/images/StatusActivityDiagram.png b/docs/images/StatusActivityDiagram.png
new file mode 100644
index 00000000000..fb03dc27d6b
Binary files /dev/null and b/docs/images/StatusActivityDiagram.png differ
diff --git a/docs/images/StatusSequenceDiagram.png b/docs/images/StatusSequenceDiagram.png
new file mode 100644
index 00000000000..dc1cd2219ce
Binary files /dev/null and b/docs/images/StatusSequenceDiagram.png differ
diff --git a/docs/images/StorageClassDiagram.png b/docs/images/StorageClassDiagram.png
index c7297c26887..6487d7fe365 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 5bd77847aa2..45437b8908c 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 7b4b3dbea45..dd7773a25a7 100644
Binary files a/docs/images/UiClassDiagram.png and b/docs/images/UiClassDiagram.png differ
diff --git a/docs/images/awzhenyi.png b/docs/images/awzhenyi.png
new file mode 100644
index 00000000000..fb84c016459
Binary files /dev/null and b/docs/images/awzhenyi.png differ
diff --git a/docs/images/helpMessage.png b/docs/images/helpMessage.png
index b1f70470137..a7a5a089e9f 100644
Binary files a/docs/images/helpMessage.png and b/docs/images/helpMessage.png differ
diff --git a/docs/images/jaredtengsw.png b/docs/images/jaredtengsw.png
new file mode 100644
index 00000000000..ca1038feab2
Binary files /dev/null and b/docs/images/jaredtengsw.png differ
diff --git a/docs/images/vrsoorya.png b/docs/images/vrsoorya.png
new file mode 100644
index 00000000000..70fd636f58c
Binary files /dev/null and b/docs/images/vrsoorya.png differ
diff --git a/docs/images/wangtao0717.png b/docs/images/wangtao0717.png
new file mode 100644
index 00000000000..9accccb1216
Binary files /dev/null and b/docs/images/wangtao0717.png differ
diff --git a/docs/images/whatthelump.png b/docs/images/whatthelump.png
new file mode 100644
index 00000000000..7a1c0beb9ea
Binary files /dev/null and b/docs/images/whatthelump.png differ
diff --git a/docs/index.md b/docs/index.md
index 7601dbaad0d..892590d507c 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -4,7 +4,7 @@ title: AddressBook Level-3
---
[](https://github.com/se-edu/addressbook-level3/actions)
-[](https://codecov.io/gh/se-edu/addressbook-level3)
+[](https://codecov.io/gh/AY2021S2-CS2103-T16-3/tp)

diff --git a/docs/team/awzhenyi.md b/docs/team/awzhenyi.md
new file mode 100644
index 00000000000..dcbf6652e2d
--- /dev/null
+++ b/docs/team/awzhenyi.md
@@ -0,0 +1,39 @@
+---
+layout: page
+title: Zhen Yi's Project Portfolio Page
+---
+
+## Project: Residence Tracker
+
+ResidenceTracker (RT) is a **desktop app for managing residences, optimized for use via a Command Line Interface** (CLI) while still having the benefits of a Graphical User Interface (GUI). If you can type fast, RT can get your residence management tasks done faster than traditional GUI apps.
+
+Given below are my contributions to the project.
+
+* **New Feature**: Edit Booking.
+ * What it does: allows user to edit the details of an existing booking.
+ * Justification: This feature improves the product since bookings are always subjected to changes such as postponements, additional day of booking, late estimated arrivals, etc. By
+ allowing the user to edit the details the of the bookings, it helps to smoothen the process of updating information.
+
+* **New Feature**: Delete Booking
+ * What it does: allows user to delete an existing booking.
+ * Justification: This feature improves the product by allowing the user to delete bookings that are expired, or cancelled so that the bookings column will not be cluttered with nonessential information.
+
+* **Code contributed**: [RepoSense link](https://nus-cs2103-ay2021s2.github.io/tp-dashboard/?search=awzhenyi&sort=groupTitle&sortWithin=title&timeframe=commit&mergegroup=&groupSelect=groupByRepos&breakdown=true&checkedFileTypes=docs~functional-code~test-code~other&since=2021-02-19&tabOpen=true&tabType=authorship&tabAuthor=awzhenyi&tabRepo=AY2021S2-CS2103-T16-3%2Ftp%5Bmaster%5D&authorshipIsMergeGroup=false&authorshipFileTypes=docs~functional-code~test-code&authorshipIsBinaryFileTypeChecked=false)
+
+* **Project management**:
+ * Opening of Github Issues and assignment.
+ * Practice of forking workflow.
+
+* **Enhancements to existing features**:
+ * TBD
+
+* **Documentation**:
+ * User Guide:
+ * Added documentation for the features `editb` [\#163](https://github.com/AY2021S2-CS2103-T16-3/tp/pull/163)
+ * Added documentation for the features `deteteb` [\#120](https://github.com/AY2021S2-CS2103-T16-3/tp/pull/120/)
+ * Developer Guide:
+ * Added implementation details of the `editb` feature.
+
+* **Community**:
+ * PRs reviewed (with non-trivial review comments): [\#161](https://github.com/AY2021S2-CS2103-T16-3/tp/pull/161)
+ * Reported bugs and suggestions for other teams in the class as part of practical dry run. (https://github.com/awzhenyi/ped/issues)
diff --git a/docs/team/vrsoorya.md b/docs/team/vrsoorya.md
new file mode 100644
index 00000000000..7333f0ed0e7
--- /dev/null
+++ b/docs/team/vrsoorya.md
@@ -0,0 +1,47 @@
+---
+layout: page
+title: John Doe's Project Portfolio Page
+NOTE: to be edited by Soorya accordingly as development progresses
+---
+
+## Project: AddressBook Level 3
+
+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.
+
+Given below are my contributions to the project.
+
+* **New Feature**: 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}*
+
+* **New Feature**: Added a history command that allows the user to navigate to previous commands using up/down keys.
+
+* **Code contributed**: [RepoSense link]()
+
+* **Project management**:
+ * Managed releases `v1.3` - `v1.5rc` (3 releases) on GitHub
+
+* **Enhancements to existing features**:
+ * Updated the GUI color scheme (Pull requests [\#33](), [\#34]())
+ * Wrote additional tests for existing features to increase coverage from 88% to 92% (Pull requests [\#36](), [\#38]())
+
+* **Documentation**:
+ * User Guide:
+ * Added documentation for the features `delete` and `find` [\#72]()
+ * Did cosmetic tweaks to existing documentation of features `clear`, `exit`: [\#74]()
+ * Developer Guide:
+ * Added implementation details of the `delete` feature.
+
+* **Community**:
+ * PRs reviewed (with non-trivial review comments): [\#12](), [\#32](), [\#19](), [\#42]()
+ * Contributed to forum discussions (examples: [1](), [2](), [3](), [4]())
+ * Reported bugs and suggestions for other teams in the class (examples: [1](), [2](), [3]())
+ * Some parts of the history feature I added was adopted by several other class mates ([1](), [2]())
+
+* **Tools**:
+ * Integrated a third party library (Natty) to the project ([\#42]())
+ * Integrated a new Github plugin (CircleCI) to the team repo
+
+* _{you can add/remove categories in the list above}_
diff --git a/docs/team/wangtao0717.md b/docs/team/wangtao0717.md
new file mode 100644
index 00000000000..0a9ce1dedd0
--- /dev/null
+++ b/docs/team/wangtao0717.md
@@ -0,0 +1,48 @@
+---
+layout: page
+title: Wang Tao's Project Portfolio Page
+NOTE: to be edited by Wang Tao accordingly as development progresses
+---
+
+## Project: Residence Tracker
+
+ResidenceTracker (RT) is a **desktop app for managing contacts, optimized for use via a Command Line Interface** (CLI) while still having the benefits of a Graphical User Interface (GUI). If you can type fast, RT can get your residence management tasks done faster than traditional GUI apps.
+
+Given below are my contributions to the project.
+
+* **New Feature**: a new feature of residence -- cleanStatusTag
+ * What it is: A remarkable sign to show the clean status of residence which help users clearly know whether the residence is clean or not, and arrange for home cleaning company to provide service in time.
+ * Justification: This feature improves the product significantly because as airbnb managers, they could manage the residences more conveniently with the help of this feature and avoid complaints caused by poor cleanup.
+ * Highlights: cleanStatusTag as a residence feature is applied to all aspects of the project. "add"and "edit" command can initialize and change it.
+
+* **New Feature**: new command "status"
+ * What it is: a convenient command to update clean status of multiple residences.
+ * Justification: This feature improves the product significantly because clean status is a special tag which is changed often, and after users call someone to clean residences, it usually needs to update more than one clean status. as busy managers, they definitely don’t want to waste time updating them one by one. So this command can save users' time.
+ * Highlights: cleanStatusTag as a residence feature is applied to all aspects of the project. "add"and "edit" command can initialize and change it.
+
+* **Code contributed**: [RepoSense link](https://nus-cs2103-ay2021s2.github.io/tp-dashboard/?search=&sort=groupTitle&sortWithin=title&timeframe=commit&mergegroup=&groupSelect=groupByRepos&breakdown=true&checkedFileTypes=docs~functional-code~test-code~other&since=&tabOpen=true&tabType=authorship&tabAuthor=wangtao0717&tabRepo=AY2021S2-CS2103-T16-3%2Ftp%5Bmaster%5D&authorshipIsMergeGroup=false&authorshipFileTypes=docs~functional-code~test-code&authorshipIsBinaryFileTypeChecked=false)
+
+* **Project management**:
+ * Pull and set up the GitHub team org/repo
+ * Maintaining the issue tracker
+
+* **Enhancements to existing features**:
+ * Updated the GUI background image and color (Pull requests [\#70](https://github.com/AY2021S2-CS2103-T16-3/tp/pull/70), [\#75](https://github.com/AY2021S2-CS2103-T16-3/tp/pull/75))
+ * Wrote tests for new features to increase coverage (Pull requests [\#80](https://github.com/AY2021S2-CS2103-T16-3/tp/pull/80), [\#109](https://github.com/AY2021S2-CS2103-T16-3/tp/pull/109))
+ * fix some failing tests (Pull requests [\#226](https://github.com/AY2021S2-CS2103-T16-3/tp/pull/226))
+
+* **Documentation**:
+ * User Guide:
+ * Added documentation for the features `add` [\#20](https://github.com/AY2021S2-CS2103-T16-3/tp/pull/20)
+ * Added documentation for the features `status` [\#171](https://github.com/AY2021S2-CS2103-T16-3/tp/pull/171)
+ * Did cosmetic tweaks to existing documentation: [\#224](https://github.com/AY2021S2-CS2103-T16-3/tp/pull/224)
+ * Developer Guide:
+ * Added use case.[\#35](https://github.com/AY2021S2-CS2103-T16-3/tp/pull/35)
+ * Added implementation details of the `status` feature [\#226](https://github.com/AY2021S2-CS2103-T16-3/tp/pull/226)
+ * Added `StatusSequenceDiagram` UML
+
+* **Community**:
+ * PRs reviewed (with non-trivial review comments): [\#229](https://github.com/AY2021S2-CS2103-T16-3/tp/pull/229)
+
+
+
diff --git a/docs/tutorials/AddRemark.md b/docs/tutorials/AddRemark.md
deleted file mode 100644
index 64c9b1f91de..00000000000
--- a/docs/tutorials/AddRemark.md
+++ /dev/null
@@ -1,394 +0,0 @@
----
-layout: page
-title: "Tutorial: Adding a command"
----
-
-Let's walk you through the implementation of a new command — `remark`.
-
-This command allows users of the AddressBook application to add optional remarks to people in their address book and edit it if required. The command should have the following format:
-
-`remark INDEX r/REMARK` (e.g., `remark 2 r/Likes baseball`)
-
-We’ll assume that you have already set up the development environment as outlined in the Developer’s Guide.
-
-
-## Create a new `remark` command
-
-Looking in the `logic.command` package, you will notice that each existing command have their own class. All the commands inherit from the abstract class `Command` which means that they must override `execute()`. Each `Command` returns an instance of `CommandResult` upon success and `CommandResult#feedbackToUser` is printed to the `ResultDisplay`.
-
-Let’s start by creating a new `RemarkCommand` class in the `src/main/java/seedu/address/logic/command` directory.
-
-For now, let’s keep `RemarkCommand` as simple as possible and print some output. We accomplish that by returning a `CommandResult` with an accompanying message.
-
-**`RemarkCommand.java`:**
-
-``` java
-package seedu.address.logic.commands;
-
-import seedu.address.model.Model;
-
-/**
- * Changes the remark of an existing person in the address book.
- */
-public class RemarkCommand extends Command {
-
- public static final String COMMAND_WORD = "remark";
-
- @Override
- public CommandResult execute(Model model) {
- return new CommandResult("Hello from remark");
- }
-}
-```
-
-### Hook `RemarkCommand` into the application
-
-Now that we have our `RemarkCommand` ready to be executed, we need to update `AddressBookParser#parseCommand()` to recognize the `remark` keyword. Add the new command to the `switch` block by creating a new `case` that returns a new instance of `RemarkCommand`.
-
-You can refer to the changes in this [diff](https://github.com/se-edu/addressbook-level3/commit/35eb7286f18a029d39cb7a29df8f172a001e4fd8#diff-34ace715a8a8d2e5a66e71289f017b47).
-
-### Run the application
-
-Run `Main#main` and try out your new `RemarkCommand`. If everything went well, you should see something like this:
-
-
-
-## Change `RemarkCommand` to throw an exception
-
-While we have successfully printed a message to `ResultDisplay`, the command does not do what it is supposed to do. Let’s change the command to throw a `CommandException` to accurately reflect that our command is still a work in progress.
-
-
-
-Following the convention in other commands, we add relevant messages as constants and use them.
-
-**`RemarkCommand.java`:**
-
-``` java
- public static final String MESSAGE_USAGE = COMMAND_WORD + ": Edits the remark of the person identified "
- + "by the index number used in the last person listing. "
- + "Existing remark will be overwritten by the input.\n"
- + "Parameters: INDEX (must be a positive integer) "
- + "r/ [REMARK]\n"
- + "Example: " + COMMAND_WORD + " 1 "
- + "r/ Likes to swim.";
-
- public static final String MESSAGE_NOT_IMPLEMENTED_YET = "Remark command not implemented yet";
-
- @Override
- public CommandResult execute(Model model) throws CommandException {
- throw new CommandException(MESSAGE_NOT_IMPLEMENTED_YET);
- }
-```
-
-## Enhancing `RemarkCommand`
-
-Let’s change `RemarkCommand` to parse input from the user.
-
-### Make the command accept parameters
-
-We start by modifying the constructor of `RemarkCommand` to accept an `Index` and a `String`. While we are at it, let’s change the error message to echo the values. While this is not a replacement for tests, it is an obvious way to tell if our code is functioning as intended.
-
-``` java
-import static seedu.address.commons.util.CollectionUtil.requireAllNonNull;
-//...
-public class RemarkCommand extends Command {
- //...
- public static final String MESSAGE_ARGUMENTS = "Index: %1$d, Remark: %2$s";
-
- private final Index index;
- private final String remark;
-
- /**
- * @param index of the person in the filtered person list to edit the remark
- * @param remark of the person to be updated to
- */
- public RemarkCommand(Index index, String remark) {
- requireAllNonNull(index, remark);
-
- this.index = index;
- this.remark = remark;
- }
- @Override
- public CommandResult execute(Model model) throws CommandException {
- throw new CommandException(String.format(MESSAGE_ARGUMENTS, index.getOneBased(), remark));
- }
-
- @Override
- public boolean equals(Object other) {
- // short circuit if same object
- if (other == this) {
- return true;
- }
-
- // instanceof handles nulls
- if (!(other instanceof RemarkCommand)) {
- return false;
- }
-
- // state check
- RemarkCommand e = (RemarkCommand) other;
- return index.equals(e.index)
- && remark.equals(e.remark);
- }
-}
-```
-
-Your code should look something like [this](https://github.com/se-edu/addressbook-level3/commit/35eb7286f18a029d39cb7a29df8f172a001e4fd8#diff-34ace715a8a8d2e5a66e71289f017b47) after you are done.
-
-### Parse user input
-
-Now let’s move on to writing a parser that will extract the index and remark from the input provided by the user.
-
-Create a `RemarkCommandParser` class in the `seedu.address.logic.parser` package. The class must extend the `Parser` interface.
-
-
-
-Thankfully, `ArgumentTokenizer#tokenize()` makes it trivial to parse user input. Let’s take a look at the JavaDoc provided for the function to understand what it does.
-
-**`ArgumentTokenizer.java`:**
-
-``` java
-/**
- * Tokenizes an arguments string and returns an {@code ArgumentMultimap}
- * object that maps prefixes to their respective argument values. Only the
- * given prefixes will be recognized in the arguments string.
- *
- * @param argsString Arguments string of the form:
- * {@code preamble value value ...}
- * @param prefixes Prefixes to tokenize the arguments string with
- * @return ArgumentMultimap object that maps prefixes to their
- * arguments
- */
-```
-
-We can tell `ArgumentTokenizer#tokenize()` to look out for our new prefix `r/` and it will return us an instance of `ArgumentMultimap`. Now let’s find out what we need to do in order to obtain the Index and String that we need. Let’s look through `ArgumentMultimap` :
-
-**`ArgumentMultimap.java`:**
-
-``` java
-/**
- * Returns the last value of {@code prefix}.
- */
-public Optional getValue(Prefix prefix) {
- List values = getAllValues(prefix);
- return values.isEmpty() ? Optional.empty() :
- Optional.of(values.get(values.size() - 1));
-}
-```
-
-This appears to be what we need to get a String of the remark. But what about the Index? Let's take a quick peek at existing `Command` that uses an index to see how it is done.
-
-**`DeleteCommandParser.java`:**
-
-``` java
-Index index = ParserUtil.parseIndex(args);
-return new DeleteCommand(index);
-```
-
-There appears to be another utility class that obtains an `Index` from the input provided by the user.
-
-Now that we have the know-how to extract the data that we need from the user’s input, we can parse the user command and create a new instance of `RemarkCommand`, as given below.
-
-**`RemarkCommandParser.java`:**
-
-``` java
-public RemarkCommand parse(String args) throws ParseException {
- requireNonNull(args);
- ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args,
- PREFIX_REMARK);
-
- Index index;
- try {
- index = ParserUtil.parseIndex(argMultimap.getPreamble());
- } catch (IllegalValueException ive) {
- throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT,
- RemarkCommand.MESSAGE_USAGE), ive);
- }
-
- String remark = argMultimap.getValue(PREFIX_REMARK).orElse("");
-
- return new RemarkCommand(index, remark);
-}
-```
-
-
-
-:information_source: Don’t forget to update `AddressBookParser` to use our new `RemarkCommandParser`!
-
-
-
-If you are stuck, check out the sample
-[here](https://github.com/se-edu/addressbook-level3/commit/dc6d5139d08f6403da0ec624ea32bd79a2ae0cbf#diff-fc19ecee89c3732a62fbc8c840250508).
-
-## Add `Remark` to the model
-
-Now that we have all the information that we need, let’s lay the groundwork for propagating the remarks added into the in-memory storage of person data. We achieve that by working with the `Person` model. Each field in a Person is implemented as a separate class (e.g. a `Name` object represents the person’s name). That means we should add a `Remark` class so that we can use a `Remark` object to represent a remark given to a person.
-
-### Add a new `Remark` class
-
-Create a new `Remark` in `seedu.address.model.person`. Since a `Remark` is a field that is similar to `Address`, we can reuse a significant bit of code.
-
-A copy-paste and search-replace later, you should have something like [this](https://github.com/se-edu/addressbook-level3/commit/4516e099699baa9e2d51801bd26f016d812dedcc#diff-af2f075d24dfcd333876f0fbce321f25). Note how `Remark` has no constrains and thus does not require input
-validation.
-
-### Make use of `Remark`
-
-Let’s change `RemarkCommand` and `RemarkCommandParser` to use the new `Remark` class instead of plain `String`. These should be relatively simple changes.
-
-## Add a placeholder element for remark to the UI
-
-Without getting too deep into `fxml`, let’s go on a 5 minute adventure to get some placeholder text to show up for each person.
-
-Simply add the following to [`seedu.address.ui.PersonCard`](https://github.com/se-edu/addressbook-level3/commit/850b78879582f38accb05dd20c245963c65ea599#diff-0c6b6abcfac8c205e075294f25e851fe).
-
-**`PersonCard.java`:**
-
-``` java
-@FXML
-private Label remark;
-```
-
-
-`@FXML` is an annotation that marks a private or protected field and makes it accessible to FXML. It might sound like Greek to you right now, don’t worry — we will get back to it later.
-
-Then insert the following into [`main/resources/view/PersonListCard.fxml`](https://github.com/se-edu/addressbook-level3/commit/850b78879582f38accb05dd20c245963c65ea599#diff-12580431f55d7880578aa4c16f249e71).
-
-**`PersonListCard.fxml`:**
-
-``` xml
-
-```
-
-That’s it! Fire up the application again and you should see something like this:
-
-
-
-## Modify `Person` to support a `Remark` field
-
-Since `PersonCard` displays data from a `Person`, we need to update `Person` to get our `Remark` displayed!
-
-### Modify `Person`
-
-We change the constructor of `Person` to take a `Remark`. We will also need to define new fields and accessors accordingly to store our new addition.
-
-### Update other usages of `Person`
-
-Unfortunately, a change to `Person` will cause other commands to break, you will have to modify these commands to use the updated `Person`!
-
-
-
-:bulb: Use the `Find Usages` feature in IntelliJ IDEA on the `Person` class to find these commands.
-
-
-
-Refer to [this commit](https://github.com/se-edu/addressbook-level3/commit/ce998c37e65b92d35c91d28c7822cd139c2c0a5c) and check that you have got everything in order!
-
-
-## Updating Storage
-
-AddressBook stores data by serializing `JsonAdaptedPerson` into `json` with the help of an external library — Jackson. Let’s update `JsonAdaptedPerson` to work with our new `Person`!
-
-While the changes to code may be minimal, the test data will have to be updated as well.
-
-
-
-:exclamation: You must delete AddressBook’s storage file located at `/data/addressbook.json` before running it! Not doing so will cause AddressBook to default to an empty address book!
-
-
-
-Check out [this commit](https://github.com/se-edu/addressbook-level3/commit/556cbd0e03ff224d7a68afba171ad2eb0ce56bbf)
-to see what the changes entail.
-
-## Finalizing the UI
-
-Now that we have finalized the `Person` class and its dependencies, we can now bind the `Remark` field to the UI.
-
-Just add [this one line of code!](https://github.com/se-edu/addressbook-level3/commit/5b98fee11b6b3f5749b6b943c4f3bd3aa049b692)
-
-**`PersonCard.java`:**
-
-``` java
-public PersonCard(Person person, int displayedIndex) {
- //...
- remark.setText(person.getRemark().value);
-}
-```
-
-
-
-## Putting everything together
-
-After the previous step, we notice a peculiar regression — we went from displaying something to nothing at all. However, this is expected behavior as we are yet to update the `RemarkCommand` to make use of the code we've been adding in the last few steps.
-
-### Update `RemarkCommand` and `RemarkCommandParser`
-
-In this last step, we modify `RemarkCommand#execute()` to change the `Remark` of a `Person`. Since all fields in a `Person` are immutable, we create a new instance of a `Person` with the values that we want and
-save it with `Model#setPerson()`.
-
-**`RemarkCommand.java`:**
-
-``` java
-//...
- public static final String MESSAGE_ADD_REMARK_SUCCESS = "Added remark to Person: %1$s";
- public static final String MESSAGE_DELETE_REMARK_SUCCESS = "Removed remark from Person: %1$s";
-//...
- @Override
- public CommandResult execute(Model model) throws CommandException {
- List lastShownList = model.getFilteredPersonList();
-
- if (index.getZeroBased() >= lastShownList.size()) {
- throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
- }
-
- Person personToEdit = lastShownList.get(index.getZeroBased());
- Person editedPerson = new Person(personToEdit.getName(), personToEdit.getPhone(), personToEdit.getEmail(),
- personToEdit.getAddress(), remark, personToEdit.getTags());
-
- model.setPerson(personToEdit, editedPerson);
- model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
-
- return new CommandResult(generateSuccessMessage(editedPerson));
- }
-
- /**
- * Generates a command execution success message based on whether the remark is added to or removed from
- * {@code personToEdit}.
- */
- private String generateSuccessMessage(Person personToEdit) {
- String message = !remark.value.isEmpty() ? MESSAGE_ADD_REMARK_SUCCESS : MESSAGE_DELETE_REMARK_SUCCESS;
- return String.format(message, personToEdit);
- }
-```
-
-
-
-## Writing tests
-
-Tests are crucial to ensuring that bugs don’t slip into the codebase unnoticed. This is especially true for large code bases where a change might lead to unintended behavior.
-
-Let’s verify the correctness of our code by writing some tests!
-
-### Automatically generating tests
-
-The goal is to write effective and efficient tests to ensure that `RemarkCommand#execute()` behaves as expected.
-
-The convention for test names is `methodName_testScenario_expectedResult`. An example would be
-`execute_filteredList_success`.
-
-Let’s create a test for `RemarkCommand#execute()` to test that adding a remark works. On `IntelliJ IDEA` you can bring up the context menu and choose to `Go To` \> `Test` or use the appropriate keyboard shortcut.
-
-
-
-Then, create a test for the `execute` method.
-
-
-
-Following convention, let’s change the name of the generated method to `execute_addRemarkUnfilteredList_success`.
-
-Let’s use the utility functions provided in `CommandTestUtil`. The functions ensure that commands produce the expected `CommandResult` and output the correct message. In this case, `CommandTestUtil#assertCommandSuccess` is the best fit as we are testing that a `RemarkCommand` will successfully add a `Remark`.
-
-You should end up with a test that looks something like [this](https://github.com/se-edu/addressbook-level3/commit/fac8f3fd855d55831ca0cc73313b5943d49d4d6e#diff-d749de38392f7ea504da7824641ba8d9).
-
-## Conclusion
-
-This concludes the tutorial for adding a new `Command` to AddressBook.
diff --git a/docs/tutorials/RemovingFields.md b/docs/tutorials/RemovingFields.md
deleted file mode 100644
index aa8e0baaad9..00000000000
--- a/docs/tutorials/RemovingFields.md
+++ /dev/null
@@ -1,103 +0,0 @@
----
-layout: page
-title: "Tutorial: Removing Fields"
----
-
-> Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.
->
-> — Antoine de Saint-Exupery
-
-When working on AddressBook, you will most likely find that some features and fields that are no longer necessary. In scenarios like this, you can consider refactoring the existing `Person` model to suit your use case.
-
-In this tutorial, we’ll do exactly just that and remove the `address` field from `Person`.
-
-* Table of Contents
-{:toc}
-
-## Safely deleting `Address`
-
-Fortunately, IntelliJ IDEA provides a robust refactoring tool that can identify *most* usages. Let’s try to use it as much as we can.
-
-### Assisted refactoring
-
-The `address` field in `Person` is actually an instance of the `seedu.address.model.person.Address` class. Since removing the `Address` class will break the application, we start by identifying `Address`'s usages. This allows us to see code that depends on `Address` to function properly and edit them on a case-by-case basis. Right-click the `Address` class and select `Refactor` \> `Safe Delete` through the menu.
-
-
-
-Choose to `View Usages` and you should be presented with a list of `Safe Delete Conflicts`. These conflicts describe locations in which the `Address` class is used.
-
-
-
-Remove usages of `Address` by performing `Safe Delete`s on each entry. You will need to exercise discretion when removing usages of `Address`. Functions like `ParserUtil#parseAddress()` can be safely removed but its usages must be removed as well. Other usages like in `EditPersonDescriptor` may require more careful inspection.
-
-Let’s try removing references to `Address` in `EditPersonDescriptor`.
-
-1. Safe delete the field `address` in `EditPersonDescriptor`.
-
-1. Select `Yes` when prompted to remove getters and setters.
-
-1. Select `View Usages` again.
- 
-
-1. Remove the usages of `address` and select `Do refactor` when you are done.
-
-
-
- :bulb: **Tip:** Removing usages may result in errors. Exercise discretion and fix them. For example, removing the `address` field from the `Person` class will require you to modify its constructor.
-
-
-1. Repeat the steps for the remaining usages of `Address`
-
-After you are done, verify that the application still works by compiling and running it again.
-
-### Manual refactoring
-
-Unfortunately, there are usages of `Address` that IntelliJ IDEA cannot identify. You can find them by searching for instances of the word `address` in your code (`Edit` \> `Find` \> `Find in path`).
-
-Places of interest to look out for would be resources used by the application. `main/resources` contains images and `fxml` files used by the application and `test/resources` contains test data. For example, there is a `$address` in each `PersonCard` that has not been removed nor identified.
-
-
-
-A quick look at the `PersonCard` class and its `fxml` file quickly reveals why it slipped past the automated refactoring.
-
-**`PersonCard.java`**
-
-``` java
-...
-@FXML
-private Label address;
-...
-```
-
-**`PersonCard.fxml`**
-
-``` xml
-...
-
-
-
-...
-```
-
-After removing the `Label`, we can proceed to formally test our code. If everything went well, you should have most of your tests pass. Fix any remaining errors until the tests all pass.
-
-## Tidying up
-
-At this point, your application is working as intended and all your tests are passing. What’s left to do is to clean up references to `Address` in test data and documentation.
-
-In `src/test/data/`, data meant for testing purposes are stored. While keeping the `address` field in the json files does not cause the tests to fail, it is not good practice to let cruft from old features accumulate.
-
-**`invalidPersonAddressBook.json`:**
-
-```json
-{
- "persons": [ {
- "name": "Person with invalid name field: Ha!ns Mu@ster",
- "phone": "9482424",
- "email": "hans@example.com",
- "address": "4th street"
- } ]
-}
-```
-
-You can go through each individual `json` file and manually remove the `address` field.
diff --git a/docs/tutorials/TracingCode.md b/docs/tutorials/TracingCode.md
deleted file mode 100644
index bd34ed498cd..00000000000
--- a/docs/tutorials/TracingCode.md
+++ /dev/null
@@ -1,250 +0,0 @@
----
-layout: page
-title: "Tutorial: Tracing code"
----
-
-> Indeed, the ratio of time spent reading versus writing is well over 10 to 1. We are constantly reading old code as part of the effort to write new code. …\[Therefore,\] making it easy to read makes it easier to write.
->
-> — Robert C. Martin Clean Code: A Handbook of Agile Software Craftsmanship
-
-When trying to understand an unfamiliar code base, one common strategy used is to trace some representative execution path through the code base. One easy way to trace an execution path is to use a debugger to step through the code. In this tutorial, you will be using the IntelliJ IDEA’s debugger to trace the execution path of a specific user command.
-
-* Table of Contents
-{:toc}
-
-## Before we start
-
-Before we jump into the code, it is useful to get an idea of the overall structure and the high-level behavior of the application. This is provided in the 'Architecture' section of the developer guide. In particular, the architecture diagram (reproduced below), tells us that the App consists of several components.
-
-
-
-It also has a sequence diagram (reproduced below) that tells us how a command propagates through the App.
-
-
-
-Note how the diagram shows only how the execution flows *between* the main components. That is, it does not show details of the execution path *inside* each component. By hiding those details, the diagram succeeds in informing the reader about the overall execution path of a command without overwhelming the reader with too much details. In this tutorial, you aim to find those omitted details so that you get a more in-depth understanding of the code base.
-
-Before we proceed, ensure that you have done the following:
-1. Read the [*Architecture* section of the DG](../DeveloperGuide.md#architecture)
-1. Set up the project in Intellij IDEA
-1. Learn basic debugging features of Intellij IDEA
-
-## Setting a break point
-
-As you know, the first step of debugging is to put in a breakpoint where you want the debugger to pause the execution. For example, if you are trying to understand how the App starts up, you would put a breakpoint in the first statement of the `main` method. In our case, we would want to begin the tracing at the very point where the App start processing user input (i.e., somewhere in the UI component), and then trace through how the execution proceeds through the UI component. However, the execution path through a GUI is often somewhat obscure due to various *event-driven mechanisms* used by GUI frameworks, which happens to be the case here too. Therefore, let us put the breakpoint where the UI transfers control to the Logic component. According to the sequence diagram, the UI component yields control to the Logic component through a method named `execute`. Searching through the code base for `execute()` yields a promising candidate in `seedu.address.ui.CommandBox.CommandExecutor`.
-
-
-
-A quick look at the class confirms that this is indeed close to what we’re looking for. However, it is just an `Interface`. Let’s delve further and find the implementation of the interface by using the `Find Usages` feature in IntelliJ IDEA.
-
-
-
-Bingo\! `MainWindow#executeCommand()` seems to be exactly what we’re looking for\!
-
-Now let’s set the breakpoint. First, double-click the item to reach the corresponding code. Once there, click on the left gutter to set a breakpoint, as shown below.
- 
-
-## Tracing the execution path
-
-Recall from the User Guide that the `edit` command has the format: `edit INDEX [n/NAME] [p/PHONE] [e/EMAIL] [a/ADDRESS] [t/TAG]…` For this tutorial we will be issuing the command `edit 1 n/Alice Yeoh`.
-
-
-
-:bulb: **Tip:** Over the course of the debugging session, you will encounter every major component in the application. Try to jot down what happens inside the component and where the execution transfers to another component.
-
-
-1. To start the debugging session, simply `Run` \> `Debug Main`
-
-1. Enter `edit 1 n/Alice Yeoh` into the command box and press `Enter`.
-
-1. The Debugger tool window should show up and look something like this:
- 
-
-1. Use the `Show execution point` feature to jump to the line of code that we stopped at:
- 
-
-1. `CommandResult commandResult = logic.execute(commandText);` is the line that you end up at.
-
-1. We are interested in the `logic.execute(commandText)` portion of that line so let’s `Step in` into that method call:
- 
-
-1. We end up in `LogicManager#execute()`. Let’s take a look at the body of the method and annotate what we can deduce.
-
- **LogicManager\#execute().**
-
- ``` java
- @Override
- public CommandResult execute(String commandText)
- throws CommandException, ParseException {
-
- //Logging, safe to ignore
- logger.info("----------------[USER COMMAND][" + commandText + "]");
-
- CommandResult commandResult;
- //Parse user input from String to a Command
- Command command = addressBookParser.parseCommand(commandText);
- //Executes the Command and stores the result
- commandResult = command.execute(model);
-
- try {
- //We can deduce that the previous line of code modifies model in some way
- // since it's being stored here.
- storage.saveAddressBook(model.getAddressBook());
- } catch (IOException ioe) {
- throw new CommandException(FILE_OPS_ERROR_MESSAGE + ioe, ioe);
- }
-
- return commandResult;
- }
- ```
-
-1. `LogicManager#execute()` appears to delegate most of the heavy lifting to other components. Let’s take a closer look at each one.
-
-1. `Step over` the logging code since it is of no interest to us now. 
-
-1. `Step into` the line where user input in parsed from a String to a Command.
-
- **`AddressBookParser\#parseCommand()`**
-
- ``` java
- public Command parseCommand(String userInput) throws ParseException {
- ...
- final String commandWord = matcher.group("commandWord");
- final String arguments = matcher.group("arguments");
- ...
- ```
-
-1. `Step over` until you reach the `switch` statement. The `Variables` window now shows the value of both `commandWord` and `arguments`:
- 
-
-1. We see that the value of `commandWord` is now `edit` but `arguments` is still not processed in any meaningful way.
-
-1. Stepping into the `switch`, we obviously stop at **`AddressBookParser\#parseCommand()`.**
-
- ``` java
- ...
- case EditCommand.COMMAND_WORD:
- return new EditCommandParser().parse(arguments);
- ...
- ```
-
-1. Let’s see what `EditCommandParser#parse()` does by stepping into it.
-
-1. Stepping through the method shows that it calls `ArgumentTokenizer#tokenize()` and `ParserUtil#parseIndex()` to obtain the arguments and index required.
-
-
:bulb: **Tip:** Sometimes you might end up stepping into functions that are not of interest. Simply `step out` of them\!
-
-
-1. The rest of the method seems to exhaustively check for the existence of each possible parameter of the `edit` command and store any possible changes in an `EditPersonDescriptor`. Recall that we can verify the contents of `editPersonDesciptor` through the `Variable` tool window.
- 
-
-1. Let’s continue stepping through until we return to `LogicManager#execute()`.
-
- The sequence diagram below shows the details of the execution path through the Logic component. Does the execution path you traced in the code so far matches with the diagram?
- 
-
-1. Now let’s see what happens when we call `command#execute()`\!
-
- **`EditCommand\#execute()`:**
-
- ``` java
- @Override
- public CommandResult execute(Model model) throws CommandException {
- ...
- Person personToEdit = lastShownList.get(index.getZeroBased());
- Person editedPerson = createEditedPerson(personToEdit, editPersonDescriptor);
- if (!personToEdit.isSamePerson(editedPerson) && model.hasPerson(editedPerson)) {
- throw new CommandException(MESSAGE_DUPLICATE_PERSON);
- }
- model.setPerson(personToEdit, editedPerson);
- model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
- return new CommandResult(String.format(MESSAGE_EDIT_PERSON_SUCCESS, editedPerson));
- }
- ```
-
-1. As suspected, `command#execute()` does indeed make changes to `model`.
-
-1. We can a closer look at how storage works by repeatedly stepping into the code until we arrive at
- `JsonAddressBook#saveAddressBook()`.
-
-1. Again, it appears that the heavy lifting is delegated. Let’s take a look at `JsonSerializableAddressBook`'s constructor.
-
- **`JsonSerializableAddressBook\#JsonSerializableAddressBook()`:**
-
- ``` java
- /**
- * Converts a given {@code ReadOnlyAddressBook} into this class for Jackson use.
- *
- * @param source future changes to this will not affect the created
- * {@code JsonSerializableAddressBook}.
- */
- public JsonSerializableAddressBook(ReadOnlyAddressBook source) {
- persons.addAll(
- source.getPersonList()
- .stream()
- .map(JsonAdaptedPerson::new)
- .collect(Collectors.toList()));
- }
- ```
-
-1. It appears that a `JsonAdaptedPerson` is created for each `Person` and then added to the `JsonSerializableAddressBook`.
-
-1. We can continue to step through until we return to `MainWindow#executeCommand()`.
-
-1. Stepping into `resultDisplay.setFeedbackToUser(commandResult.getFeedbackToUser());`, we end up in:
-
- **`ResultDisplay\#setFeedbackToUser()`**
-
- ``` java
- public void setFeedbackToUser(String feedbackToUser) {
- requireNonNull(feedbackToUser);
- resultDisplay.setText(feedbackToUser);
- }
- ```
-
-1. Finally, we step through until we reach the end of
- `MainWindow#executeCommand()`.
-
-## Conclusion
-
-In this tutorial, we traced a valid edit command from raw user input to
-the result being displayed to the user. From this tutorial, you learned
-more about the inner workings of AddressBook and how the various
-components mesh together to form one cohesive product.
-
-Here are some quick questions you can try to answer based on your
-execution path tracing. In some cases, you can do further tracing for
-the given commands to find exactly what happens.
-
-1. In this tutorial, we traced the "happy path" (i.e., no errors). What
- do you think will happen if we traced the following commands
- instead? What exceptions do you think will be thrown(if any), where
- will the exceptions be thrown and where will they be handled?
-
- 1. `redit 1 n/Alice Yu`
-
- 2. `edit 0 n/Alice Yu`
-
- 3. `edit 1 n/Alex Yeoh`
-
- 4. `edit 1`
-
- 5. `edit 1 n/アリス ユー`
-
- 6. `edit 1 t/one t/two t/three t/one`
-
-2. What components will you have to modify to perform the following
- enhancements to the application?
-
- 1. Make command words case-insensitive
-
- 2. Allow `delete` to remove more than one index at a time
-
- 3. Save the address book in the CSV format instead
-
- 4. Add a new command
-
- 5. Add a new field to `Person`
-
- 6. Add a new entity to the address book
diff --git a/src/main/java/seedu/address/MainApp.java b/src/main/java/seedu/address/MainApp.java
index e5cfb161b73..9330fd7b1d2 100644
--- a/src/main/java/seedu/address/MainApp.java
+++ b/src/main/java/seedu/address/MainApp.java
@@ -15,16 +15,16 @@
import seedu.address.commons.util.StringUtil;
import seedu.address.logic.Logic;
import seedu.address.logic.LogicManager;
-import seedu.address.model.AddressBook;
import seedu.address.model.Model;
import seedu.address.model.ModelManager;
-import seedu.address.model.ReadOnlyAddressBook;
+import seedu.address.model.ReadOnlyResidenceTracker;
import seedu.address.model.ReadOnlyUserPrefs;
+import seedu.address.model.ResidenceTracker;
import seedu.address.model.UserPrefs;
import seedu.address.model.util.SampleDataUtil;
-import seedu.address.storage.AddressBookStorage;
-import seedu.address.storage.JsonAddressBookStorage;
+import seedu.address.storage.JsonResidenceTrackerStorage;
import seedu.address.storage.JsonUserPrefsStorage;
+import seedu.address.storage.ResidenceTrackerStorage;
import seedu.address.storage.Storage;
import seedu.address.storage.StorageManager;
import seedu.address.storage.UserPrefsStorage;
@@ -36,7 +36,7 @@
*/
public class MainApp extends Application {
- public static final Version VERSION = new Version(0, 6, 0, true);
+ public static final Version VERSION = new Version(1, 3, 5, true);
private static final Logger logger = LogsCenter.getLogger(MainApp.class);
@@ -48,7 +48,7 @@ public class MainApp extends Application {
@Override
public void init() throws Exception {
- logger.info("=============================[ Initializing AddressBook ]===========================");
+ logger.info("=============================[ Initializing ResidenceTracker ]===========================");
super.init();
AppParameters appParameters = AppParameters.parse(getParameters());
@@ -56,8 +56,9 @@ public void init() throws Exception {
UserPrefsStorage userPrefsStorage = new JsonUserPrefsStorage(config.getUserPrefsFilePath());
UserPrefs userPrefs = initPrefs(userPrefsStorage);
- AddressBookStorage addressBookStorage = new JsonAddressBookStorage(userPrefs.getAddressBookFilePath());
- storage = new StorageManager(addressBookStorage, userPrefsStorage);
+ ResidenceTrackerStorage residenceTrackerStorage =
+ new JsonResidenceTrackerStorage(userPrefs.getResidenceTrackerFilePath());
+ storage = new StorageManager(residenceTrackerStorage, userPrefsStorage);
initLogging(config);
@@ -69,25 +70,26 @@ public void init() throws Exception {
}
/**
- * Returns a {@code ModelManager} with the data from {@code storage}'s address book and {@code userPrefs}.
- * The data from the sample address book will be used instead if {@code storage}'s address book is not found,
- * or an empty address book will be used instead if errors occur when reading {@code storage}'s address book.
+ * Returns a {@code ModelManager} with the data from {@code storage}'s residence tracker and {@code userPrefs}.
+ * The data from the sample residence tracker will be used instead if {@code storage}'s residence tracker is not
+ * found, or an empty residence tracker will be used instead if errors occur when reading {@code storage}'s
+ * residence tracker.
*/
private Model initModelManager(Storage storage, ReadOnlyUserPrefs userPrefs) {
- Optional addressBookOptional;
- ReadOnlyAddressBook initialData;
+ Optional residenceTrackerOptional;
+ ReadOnlyResidenceTracker initialData;
try {
- addressBookOptional = storage.readAddressBook();
- if (!addressBookOptional.isPresent()) {
- logger.info("Data file not found. Will be starting with a sample AddressBook");
+ residenceTrackerOptional = storage.readResidenceTracker();
+ if (!residenceTrackerOptional.isPresent()) {
+ logger.info("Data file not found. Will be starting with a sample ResidenceTracker");
}
- initialData = addressBookOptional.orElseGet(SampleDataUtil::getSampleAddressBook);
+ initialData = residenceTrackerOptional.orElseGet(SampleDataUtil::getSampleResidenceTracker);
} catch (DataConversionException e) {
- logger.warning("Data file not in the correct format. Will be starting with an empty AddressBook");
- initialData = new AddressBook();
+ logger.warning("Data file not in the correct format. Will be starting with an empty ResidenceTracker");
+ initialData = new ResidenceTracker();
} catch (IOException e) {
- logger.warning("Problem while reading from the file. Will be starting with an empty AddressBook");
- initialData = new AddressBook();
+ logger.warning("Problem while reading from the file. Will be starting with an empty ResidenceTracker");
+ initialData = new ResidenceTracker();
}
return new ModelManager(initialData, userPrefs);
@@ -151,7 +153,7 @@ protected UserPrefs initPrefs(UserPrefsStorage storage) {
+ "Using default user prefs");
initializedPrefs = new UserPrefs();
} catch (IOException e) {
- logger.warning("Problem while reading from the file. Will be starting with an empty AddressBook");
+ logger.warning("Problem while reading from the file. Will be starting with an empty ResidenceTracker");
initializedPrefs = new UserPrefs();
}
@@ -167,13 +169,13 @@ protected UserPrefs initPrefs(UserPrefsStorage storage) {
@Override
public void start(Stage primaryStage) {
- logger.info("Starting AddressBook " + MainApp.VERSION);
+ logger.info("Starting ResidenceTracker " + MainApp.VERSION);
ui.start(primaryStage);
}
@Override
public void stop() {
- logger.info("============================ [ Stopping Address Book ] =============================");
+ logger.info("============================ [ Stopping ResidenceTracker ] =============================");
try {
storage.saveUserPrefs(model.getUserPrefs());
} catch (IOException e) {
diff --git a/src/main/java/seedu/address/commons/core/LogsCenter.java b/src/main/java/seedu/address/commons/core/LogsCenter.java
index 431e7185e76..63d155cb922 100644
--- a/src/main/java/seedu/address/commons/core/LogsCenter.java
+++ b/src/main/java/seedu/address/commons/core/LogsCenter.java
@@ -18,7 +18,7 @@
public class LogsCenter {
private static final int MAX_FILE_COUNT = 5;
private static final int MAX_FILE_SIZE_IN_BYTES = (int) (Math.pow(2, 20) * 5); // 5MB
- private static final String LOG_FILE = "addressbook.log";
+ private static final String LOG_FILE = "ResidenceTracker.log";
private static Level currentLogLevel = Level.INFO;
private static final Logger logger = LogsCenter.getLogger(LogsCenter.class);
private static FileHandler fileHandler;
diff --git a/src/main/java/seedu/address/commons/core/Messages.java b/src/main/java/seedu/address/commons/core/Messages.java
index 1deb3a1e469..bba8ffd370b 100644
--- a/src/main/java/seedu/address/commons/core/Messages.java
+++ b/src/main/java/seedu/address/commons/core/Messages.java
@@ -7,7 +7,10 @@ public class Messages {
public static final String MESSAGE_UNKNOWN_COMMAND = "Unknown command";
public static final String MESSAGE_INVALID_COMMAND_FORMAT = "Invalid command format! \n%1$s";
- public static final String MESSAGE_INVALID_PERSON_DISPLAYED_INDEX = "The person index provided is invalid";
- public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d persons listed!";
+ public static final String MESSAGE_INVALID_RESIDENCE_DISPLAYED_INDEX = "The residence index provided is invalid";
+ public static final String MESSAGE_INVALID_BOOKING_DISPLAYED_INDEX = "The booking index provided is invalid";
+ public static final String MESSAGE_RESIDENCE_LISTED_OVERVIEW = "%1$d residences listed!";
+ public static final String MESSAGE_RESIDENCES_WITH_UPCOMING_BOOKINGS =
+ "%1$d residences have bookings starting in the next 7 days";
}
diff --git a/src/main/java/seedu/address/commons/core/index/Index.java b/src/main/java/seedu/address/commons/core/index/Index.java
index 19536439c09..e1c97d85ed6 100644
--- a/src/main/java/seedu/address/commons/core/index/Index.java
+++ b/src/main/java/seedu/address/commons/core/index/Index.java
@@ -51,4 +51,9 @@ public boolean equals(Object other) {
|| (other instanceof Index // instanceof handles nulls
&& zeroBasedIndex == ((Index) other).zeroBasedIndex); // state check
}
+
+ @Override
+ public String toString() {
+ return String.valueOf(zeroBasedIndex); // state check
+ }
}
diff --git a/src/main/java/seedu/address/logic/Logic.java b/src/main/java/seedu/address/logic/Logic.java
index 92cd8fa605a..7e6835de5fe 100644
--- a/src/main/java/seedu/address/logic/Logic.java
+++ b/src/main/java/seedu/address/logic/Logic.java
@@ -7,36 +7,40 @@
import seedu.address.logic.commands.CommandResult;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.logic.parser.exceptions.ParseException;
-import seedu.address.model.ReadOnlyAddressBook;
-import seedu.address.model.person.Person;
+import seedu.address.model.ReadOnlyResidenceTracker;
+import seedu.address.model.residence.Residence;
/**
* API of the Logic component
*/
public interface Logic {
+
/**
* Executes the command and returns the result.
+ *
* @param commandText The command as entered by the user.
* @return the result of the command execution.
* @throws CommandException If an error occurs during command execution.
- * @throws ParseException If an error occurs during parsing.
+ * @throws ParseException If an error occurs during parsing.
*/
CommandResult execute(String commandText) throws CommandException, ParseException;
/**
- * Returns the AddressBook.
+ * Returns the ResidenceTracker.
*
- * @see seedu.address.model.Model#getAddressBook()
+ * @see seedu.address.model.Model#getResidenceTracker()
*/
- ReadOnlyAddressBook getAddressBook();
+ ReadOnlyResidenceTracker getResidenceTracker();
- /** Returns an unmodifiable view of the filtered list of persons */
- ObservableList getFilteredPersonList();
+ /**
+ * Returns an unmodifiable view of the filtered list of persons
+ */
+ ObservableList getFilteredResidenceList();
/**
- * Returns the user prefs' address book file path.
+ * Returns the user prefs' residence tracker file path.
*/
- Path getAddressBookFilePath();
+ Path getResidenceTrackerFilePath();
/**
* Returns the user prefs' GUI settings.
diff --git a/src/main/java/seedu/address/logic/LogicManager.java b/src/main/java/seedu/address/logic/LogicManager.java
index 9d9c6d15bdc..41faae61f3e 100644
--- a/src/main/java/seedu/address/logic/LogicManager.java
+++ b/src/main/java/seedu/address/logic/LogicManager.java
@@ -10,11 +10,11 @@
import seedu.address.logic.commands.Command;
import seedu.address.logic.commands.CommandResult;
import seedu.address.logic.commands.exceptions.CommandException;
-import seedu.address.logic.parser.AddressBookParser;
+import seedu.address.logic.parser.ResidenceTrackerParser;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.Model;
-import seedu.address.model.ReadOnlyAddressBook;
-import seedu.address.model.person.Person;
+import seedu.address.model.ReadOnlyResidenceTracker;
+import seedu.address.model.residence.Residence;
import seedu.address.storage.Storage;
/**
@@ -26,7 +26,7 @@ public class LogicManager implements Logic {
private final Model model;
private final Storage storage;
- private final AddressBookParser addressBookParser;
+ private final ResidenceTrackerParser residenceTrackerParser;
/**
* Constructs a {@code LogicManager} with the given {@code Model} and {@code Storage}.
@@ -34,7 +34,7 @@ public class LogicManager implements Logic {
public LogicManager(Model model, Storage storage) {
this.model = model;
this.storage = storage;
- addressBookParser = new AddressBookParser();
+ residenceTrackerParser = new ResidenceTrackerParser();
}
@Override
@@ -42,11 +42,11 @@ public CommandResult execute(String commandText) throws CommandException, ParseE
logger.info("----------------[USER COMMAND][" + commandText + "]");
CommandResult commandResult;
- Command command = addressBookParser.parseCommand(commandText);
+ Command command = residenceTrackerParser.parseCommand(commandText);
commandResult = command.execute(model);
try {
- storage.saveAddressBook(model.getAddressBook());
+ storage.saveResidenceTracker(model.getResidenceTracker());
} catch (IOException ioe) {
throw new CommandException(FILE_OPS_ERROR_MESSAGE + ioe, ioe);
}
@@ -55,18 +55,18 @@ public CommandResult execute(String commandText) throws CommandException, ParseE
}
@Override
- public ReadOnlyAddressBook getAddressBook() {
- return model.getAddressBook();
+ public ReadOnlyResidenceTracker getResidenceTracker() {
+ return model.getResidenceTracker();
}
@Override
- public ObservableList getFilteredPersonList() {
- return model.getFilteredPersonList();
+ public ObservableList getFilteredResidenceList() {
+ return model.getFilteredResidenceList();
}
@Override
- public Path getAddressBookFilePath() {
- return model.getAddressBookFilePath();
+ public Path getResidenceTrackerFilePath() {
+ return model.getResidenceTrackerFilePath();
}
@Override
diff --git a/src/main/java/seedu/address/logic/commands/AddBookingCommand.java b/src/main/java/seedu/address/logic/commands/AddBookingCommand.java
new file mode 100644
index 00000000000..cbddc6c6170
--- /dev/null
+++ b/src/main/java/seedu/address/logic/commands/AddBookingCommand.java
@@ -0,0 +1,86 @@
+package seedu.address.logic.commands;
+
+import static java.util.Objects.requireNonNull;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_BOOKING_END_DATE;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_BOOKING_START_DATE;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE;
+import static seedu.address.model.Model.PREDICATE_SHOW_ALL_RESIDENCES;
+
+import java.util.List;
+
+import seedu.address.commons.core.Messages;
+import seedu.address.commons.core.index.Index;
+import seedu.address.logic.commands.exceptions.CommandException;
+import seedu.address.model.Model;
+import seedu.address.model.booking.Booking;
+import seedu.address.model.residence.Residence;
+
+
+/**
+ * Adds a {@code Booking} to a {@code Residence} tracker.
+ */
+//@@author Soorya
+public class AddBookingCommand extends Command {
+
+ public static final String COMMAND_WORD = "addb";
+
+ public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a booking to a specific residence.\n"
+ + "Parameters: RESIDENCE_INDEX (must be a positive integer)"
+ + PREFIX_NAME + "NAME "
+ + PREFIX_PHONE + "PHONE "
+ + PREFIX_BOOKING_START_DATE + "START_DATE "
+ + PREFIX_BOOKING_END_DATE + "END_DATE \n"
+ + "Example: " + COMMAND_WORD + " 1 "
+ + PREFIX_NAME + "Sandy "
+ + PREFIX_PHONE + "87654321 "
+ + PREFIX_BOOKING_START_DATE + "09-08-2021 "
+ + PREFIX_BOOKING_END_DATE + "11-08-2021 ";
+ public static final String MESSAGE_SUCCESS = "New booking added to Residence %1$s : %2$s";
+ public static final String MESSAGE_INVALID_BOOKING = "The specified date overlaps "
+ + "with another booking for this residence";
+
+ private final Index targetIndex;
+ private final Booking toAdd;
+
+ /**
+ * Creates an AddBookingCommand to add the specified {@code Residence}
+ */
+ public AddBookingCommand(Index targetIndex, Booking booking) {
+ requireNonNull(booking);
+ this.targetIndex = targetIndex;
+ this.toAdd = booking;
+ }
+
+ @Override
+ public CommandResult execute(Model model) throws CommandException {
+ requireNonNull(model);
+ List lastShownList = model.getFilteredResidenceList();
+
+ if (targetIndex.getZeroBased() >= lastShownList.size()) {
+ throw new CommandException(Messages.MESSAGE_INVALID_RESIDENCE_DISPLAYED_INDEX);
+ }
+
+ Residence residenceToAddBooking = lastShownList.get(targetIndex.getZeroBased());
+ if (residenceToAddBooking.hasBooking(toAdd)) {
+ throw new CommandException(MESSAGE_INVALID_BOOKING);
+ }
+
+ model.setResidence(residenceToAddBooking, residenceToAddBooking.addBooking(toAdd));
+ model.updateFilteredResidenceList(PREDICATE_SHOW_ALL_RESIDENCES);
+ return new CommandResult(String.format(MESSAGE_SUCCESS,
+ residenceToAddBooking.getResidenceName().toString(), toAdd));
+ }
+
+ public static String getCommandWord() {
+ return COMMAND_WORD;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ return other == this // short circuit if same object
+ || (other instanceof AddBookingCommand // instanceof handles nulls
+ && toAdd.equals(((AddBookingCommand) other).toAdd));
+ }
+
+}
diff --git a/src/main/java/seedu/address/logic/commands/AddCommand.java b/src/main/java/seedu/address/logic/commands/AddCommand.java
index 71656d7c5c8..a5799db5ad2 100644
--- a/src/main/java/seedu/address/logic/commands/AddCommand.java
+++ b/src/main/java/seedu/address/logic/commands/AddCommand.java
@@ -1,67 +1,76 @@
package seedu.address.logic.commands;
import static java.util.Objects.requireNonNull;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_CLEAN_STATUS_TAG;
import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_RESIDENCE_ADDRESS;
import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG;
+import java.util.Objects;
+
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.model.Model;
-import seedu.address.model.person.Person;
+import seedu.address.model.residence.Residence;
/**
- * Adds a person to the address book.
+ * Adds a residence to the residence tracker.
*/
public class AddCommand extends Command {
public static final String COMMAND_WORD = "add";
- public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a person to the address book. "
+ public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a residence to the residence tracker.\n"
+ "Parameters: "
+ PREFIX_NAME + "NAME "
- + PREFIX_PHONE + "PHONE "
- + PREFIX_EMAIL + "EMAIL "
- + PREFIX_ADDRESS + "ADDRESS "
+ + PREFIX_RESIDENCE_ADDRESS + "ADDRESS "
+ + "[" + PREFIX_CLEAN_STATUS_TAG + "VALID_CLEAN_STATUS] "
+ "[" + PREFIX_TAG + "TAG]...\n"
+ "Example: " + COMMAND_WORD + " "
- + PREFIX_NAME + "John Doe "
- + PREFIX_PHONE + "98765432 "
- + PREFIX_EMAIL + "johnd@example.com "
- + PREFIX_ADDRESS + "311, Clementi Ave 2, #02-25 "
- + PREFIX_TAG + "friends "
- + PREFIX_TAG + "owesMoney";
+ + PREFIX_NAME + "Seaside Villa "
+ + PREFIX_RESIDENCE_ADDRESS + "311, Pasir Ris Ave 2, #02-25 "
+ + PREFIX_CLEAN_STATUS_TAG + "n "
+ + PREFIX_TAG + "friends ";
- public static final String MESSAGE_SUCCESS = "New person added: %1$s";
- public static final String MESSAGE_DUPLICATE_PERSON = "This person already exists in the address book";
+ public static final String MESSAGE_SUCCESS = "New residence added: %1$s";
+ public static final String MESSAGE_DUPLICATE_RESIDENCE = "This residence already exists in the residence tracker";
- private final Person toAdd;
+ private final Residence toAdd;
/**
- * Creates an AddCommand to add the specified {@code Person}
+ * Creates an AddCommand to add the specified {@code Residence}
*/
- public AddCommand(Person person) {
- requireNonNull(person);
- toAdd = person;
+ public AddCommand(Residence residence) {
+ requireNonNull(residence);
+ toAdd = residence;
}
@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
- if (model.hasPerson(toAdd)) {
- throw new CommandException(MESSAGE_DUPLICATE_PERSON);
+ if (model.hasResidence(toAdd)) {
+ throw new CommandException(MESSAGE_DUPLICATE_RESIDENCE);
}
- model.addPerson(toAdd);
+ model.addResidence(toAdd);
return new CommandResult(String.format(MESSAGE_SUCCESS, toAdd));
}
+ public static String getCommandWord() {
+ return COMMAND_WORD;
+ }
+
+ @Override
+ public int hashCode() {
+ // use this method for custom fields hashing instead of implementing your own
+ return Objects.hash(toAdd);
+ }
+
@Override
public boolean equals(Object other) {
return other == this // short circuit if same object
|| (other instanceof AddCommand // instanceof handles nulls
&& toAdd.equals(((AddCommand) other).toAdd));
}
+
}
diff --git a/src/main/java/seedu/address/logic/commands/ClearCommand.java b/src/main/java/seedu/address/logic/commands/ClearCommand.java
index 9c86b1fa6e4..cd0996058c2 100644
--- a/src/main/java/seedu/address/logic/commands/ClearCommand.java
+++ b/src/main/java/seedu/address/logic/commands/ClearCommand.java
@@ -2,22 +2,26 @@
import static java.util.Objects.requireNonNull;
-import seedu.address.model.AddressBook;
import seedu.address.model.Model;
+import seedu.address.model.ResidenceTracker;
/**
- * Clears the address book.
+ * Clears the residence tracker.
*/
public class ClearCommand extends Command {
public static final String COMMAND_WORD = "clear";
- public static final String MESSAGE_SUCCESS = "Address book has been cleared!";
+ public static final String MESSAGE_SUCCESS = "Residence Tracker has been cleared!";
@Override
public CommandResult execute(Model model) {
requireNonNull(model);
- model.setAddressBook(new AddressBook());
+ model.setResidenceTracker(new ResidenceTracker());
return new CommandResult(MESSAGE_SUCCESS);
}
+
+ public static String getCommandWord() {
+ return COMMAND_WORD;
+ }
}
diff --git a/src/main/java/seedu/address/logic/commands/Command.java b/src/main/java/seedu/address/logic/commands/Command.java
index 64f18992160..4fbfb0a6458 100644
--- a/src/main/java/seedu/address/logic/commands/Command.java
+++ b/src/main/java/seedu/address/logic/commands/Command.java
@@ -16,5 +16,4 @@ public abstract class Command {
* @throws CommandException If an error occurs during command execution.
*/
public abstract CommandResult execute(Model model) throws CommandException;
-
}
diff --git a/src/main/java/seedu/address/logic/commands/DeleteBookingCommand.java b/src/main/java/seedu/address/logic/commands/DeleteBookingCommand.java
new file mode 100644
index 00000000000..14f30f3273b
--- /dev/null
+++ b/src/main/java/seedu/address/logic/commands/DeleteBookingCommand.java
@@ -0,0 +1,80 @@
+package seedu.address.logic.commands;
+
+import static java.util.Objects.requireNonNull;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_BOOKING;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_RESIDENCE;
+import static seedu.address.model.Model.PREDICATE_SHOW_ALL_RESIDENCES;
+
+import java.util.List;
+
+import seedu.address.commons.core.Messages;
+import seedu.address.commons.core.index.Index;
+import seedu.address.logic.commands.exceptions.CommandException;
+import seedu.address.model.Model;
+import seedu.address.model.booking.Booking;
+import seedu.address.model.residence.BookingList;
+import seedu.address.model.residence.Residence;
+
+
+/**
+ * Deletes a booking of residence identified using a booking index and residence index as displayed in ResidenceTracker.
+ */
+public class DeleteBookingCommand extends Command {
+
+ public static final String COMMAND_WORD = "deleteb";
+
+ public static final String MESSAGE_USAGE = COMMAND_WORD
+ + ": Deletes the booking identified by the booking index of the "
+ + "residence identified by residence index used in the displayed residence list.\n"
+ + "Parameters: " + PREFIX_RESIDENCE + "RESIDENCE_INDEX (must be a positive integer) "
+ + PREFIX_BOOKING + "BOOKING_INDEX (must be a positive integer)\n"
+ + "Example: " + COMMAND_WORD + " " + PREFIX_RESIDENCE + "1 " + PREFIX_BOOKING + "1";
+
+ public static final String MESSAGE_DELETE_BOOKING_SUCCESS = "Deleted Residence %1$d's Booking: %2$s";
+
+ private final Index residenceIndex;
+ private final Index bookingIndex;
+
+ /**
+ * Constructs a {@code DeleteBookingCommand} with {@code residenceIndex} and {@code bookingIndex}
+ */
+ public DeleteBookingCommand(Index residenceIndex, Index bookingIndex) {
+ this.residenceIndex = residenceIndex;
+ this.bookingIndex = bookingIndex;
+ }
+
+ @Override
+ public CommandResult execute(Model model) throws CommandException {
+ requireNonNull(model);
+ List lastShownList = model.getFilteredResidenceList();
+ if (residenceIndex.getZeroBased() >= lastShownList.size()) {
+ throw new CommandException(Messages.MESSAGE_INVALID_RESIDENCE_DISPLAYED_INDEX);
+ }
+ Residence targetResidence = lastShownList.get(residenceIndex.getZeroBased());
+ BookingList bookingList = targetResidence.getBookingList();
+
+ if (bookingIndex.getZeroBased() >= bookingList.getBookingListSize()) {
+ throw new CommandException(Messages.MESSAGE_INVALID_BOOKING_DISPLAYED_INDEX);
+ }
+ Booking bookingToDelete = bookingList.getBooking(bookingIndex.getZeroBased());
+ Residence residenceToDeleteBooking = lastShownList.get(residenceIndex.getZeroBased());
+ residenceToDeleteBooking.getBookingList().remove(bookingToDelete);
+ model.setResidence(targetResidence, residenceToDeleteBooking);
+ model.updateFilteredResidenceList(PREDICATE_SHOW_ALL_RESIDENCES);
+ return new CommandResult(String.format(MESSAGE_DELETE_BOOKING_SUCCESS,
+ residenceIndex.getOneBased(), bookingToDelete));
+ }
+
+ public static String getCommandWord() {
+ return COMMAND_WORD;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ return other == this // short circuit if same object
+ || (other instanceof DeleteBookingCommand // instanceof handles nulls
+ && residenceIndex.equals(((DeleteBookingCommand) other).residenceIndex)
+ && bookingIndex.equals(((DeleteBookingCommand) other).bookingIndex)); // state check
+ }
+}
+
diff --git a/src/main/java/seedu/address/logic/commands/DeleteCommand.java b/src/main/java/seedu/address/logic/commands/DeleteCommand.java
index 02fd256acba..6e92f6f446d 100644
--- a/src/main/java/seedu/address/logic/commands/DeleteCommand.java
+++ b/src/main/java/seedu/address/logic/commands/DeleteCommand.java
@@ -8,21 +8,21 @@
import seedu.address.commons.core.index.Index;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.model.Model;
-import seedu.address.model.person.Person;
+import seedu.address.model.residence.Residence;
/**
- * Deletes a person identified using it's displayed index from the address book.
+ * Deletes a residence identified using it's displayed index from the residence tracker.
*/
public class DeleteCommand extends Command {
public static final String COMMAND_WORD = "delete";
public static final String MESSAGE_USAGE = COMMAND_WORD
- + ": Deletes the person identified by the index number used in the displayed person list.\n"
- + "Parameters: INDEX (must be a positive integer)\n"
+ + ": Deletes the residence identified by the index number used in the displayed residence list.\n"
+ + "Parameters: RESIDENCE_INDEX (must be a positive integer)\n"
+ "Example: " + COMMAND_WORD + " 1";
- public static final String MESSAGE_DELETE_PERSON_SUCCESS = "Deleted Person: %1$s";
+ public static final String MESSAGE_DELETE_RESIDENCE_SUCCESS = "Deleted Residence: %1$s";
private final Index targetIndex;
@@ -33,15 +33,19 @@ public DeleteCommand(Index targetIndex) {
@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
- List lastShownList = model.getFilteredPersonList();
+ List lastShownList = model.getFilteredResidenceList();
if (targetIndex.getZeroBased() >= lastShownList.size()) {
- throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
+ throw new CommandException(Messages.MESSAGE_INVALID_RESIDENCE_DISPLAYED_INDEX);
}
- Person personToDelete = lastShownList.get(targetIndex.getZeroBased());
- model.deletePerson(personToDelete);
- return new CommandResult(String.format(MESSAGE_DELETE_PERSON_SUCCESS, personToDelete));
+ Residence residenceToDelete = lastShownList.get(targetIndex.getZeroBased());
+ model.deleteResidence(residenceToDelete);
+ return new CommandResult(String.format(MESSAGE_DELETE_RESIDENCE_SUCCESS, residenceToDelete));
+ }
+
+ public static String getCommandWord() {
+ return COMMAND_WORD;
}
@Override
diff --git a/src/main/java/seedu/address/logic/commands/EditBookingCommand.java b/src/main/java/seedu/address/logic/commands/EditBookingCommand.java
new file mode 100644
index 00000000000..44302bde942
--- /dev/null
+++ b/src/main/java/seedu/address/logic/commands/EditBookingCommand.java
@@ -0,0 +1,227 @@
+package seedu.address.logic.commands;
+
+import static java.util.Objects.requireNonNull;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_BOOKING;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_BOOKING_END_DATE;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_BOOKING_START_DATE;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_RESIDENCE;
+import static seedu.address.model.Model.PREDICATE_SHOW_ALL_RESIDENCES;
+
+import java.time.LocalDate;
+import java.util.List;
+import java.util.Optional;
+
+import seedu.address.commons.core.Messages;
+import seedu.address.commons.core.index.Index;
+import seedu.address.commons.util.CollectionUtil;
+import seedu.address.logic.commands.exceptions.CommandException;
+import seedu.address.model.Model;
+import seedu.address.model.booking.Booking;
+import seedu.address.model.booking.Phone;
+import seedu.address.model.booking.TenantName;
+import seedu.address.model.residence.BookingList;
+import seedu.address.model.residence.Residence;
+
+/**
+ * Edits the details of an existing booking in the specified residence.
+ */
+public class EditBookingCommand extends Command {
+
+ public static final String COMMAND_WORD = "editb";
+
+ public static final String MESSAGE_USAGE = COMMAND_WORD + ": Edits the details of the booking identified by "
+ + "booking index of the residence identified based on the residence index provided. "
+ + "Existing values will be overwritten by the input values.\n"
+ + "Parameters: "
+ + PREFIX_RESIDENCE + "RESIDENCE_INDEX "
+ + PREFIX_BOOKING + "BOOKING_INDEX "
+ + "[" + PREFIX_NAME + "TENANT_NAME] "
+ + "[" + PREFIX_PHONE + "PHONE] "
+ + "[" + PREFIX_BOOKING_START_DATE + "START_DATE] "
+ + "[" + PREFIX_BOOKING_END_DATE + "END_DATE]\n"
+ + "Example: " + COMMAND_WORD + " " + PREFIX_RESIDENCE + "1 "
+ + PREFIX_BOOKING + "1 "
+ + PREFIX_BOOKING_START_DATE + "01-01-2020";
+
+ public static final String MESSAGE_EDIT_BOOKING_SUCCESS = "Edited Booking: %1$s";
+ public static final String MESSAGE_NOT_EDITED = "At least one field to edit must be provided.";
+ public static final String MESSAGE_OVERLAP_BOOKING = "The edited booking overlaps with other existing bookings.";
+ public static final String MESSAGE_NOT_VALID_START_DATE = "Invalid start date, should not be later than end date.";
+
+ private final Index residenceIndex;
+ private final Index bookingIndex;
+ private final EditBookingDescriptor editBookingDescriptor;
+
+ /**
+ * @param residenceIndex index of the residence in the filtered residence list to edit
+ * @param bookingIndex index of the booking in the booking list of the residence to edit
+ * @param editBookingDescriptor details to edit the booking with
+ */
+ public EditBookingCommand(Index residenceIndex, Index bookingIndex, EditBookingDescriptor editBookingDescriptor) {
+ requireNonNull(residenceIndex);
+ requireNonNull(bookingIndex);
+
+ this.residenceIndex = residenceIndex;
+ this.bookingIndex = bookingIndex;
+ this.editBookingDescriptor = new EditBookingDescriptor(editBookingDescriptor);
+ }
+
+ @Override
+ public CommandResult execute(Model model) throws CommandException {
+ requireNonNull(model);
+ List lastShownList = model.getFilteredResidenceList();
+
+ if (residenceIndex.getZeroBased() >= lastShownList.size()) {
+ throw new CommandException(Messages.MESSAGE_INVALID_RESIDENCE_DISPLAYED_INDEX);
+ }
+ Residence targetResidence = lastShownList.get(residenceIndex.getZeroBased());
+ Residence residenceToEdit = lastShownList.get(residenceIndex.getZeroBased());
+ BookingList bookingListToEdit = residenceToEdit.getBookingList();
+ if (bookingIndex.getZeroBased() >= bookingListToEdit.getBookingListSize()) {
+ throw new CommandException(Messages.MESSAGE_INVALID_BOOKING_DISPLAYED_INDEX);
+ }
+ Booking bookingToEdit = bookingListToEdit.getBooking(bookingIndex.getZeroBased());
+ Booking editedBooking = createEditedBooking(bookingToEdit, editBookingDescriptor);
+
+ if (!editedBooking.isValidBookingTime(editedBooking.getStart(), editedBooking.getEnd())) {
+ throw new CommandException(MESSAGE_NOT_VALID_START_DATE);
+ }
+
+ if (residenceToEdit.getBookingList().containsExclude(bookingToEdit, editedBooking)) {
+ throw new CommandException(MESSAGE_OVERLAP_BOOKING);
+ }
+ bookingListToEdit.setBooking(bookingToEdit, editedBooking);
+ model.setResidence(targetResidence, residenceToEdit);
+ model.updateFilteredResidenceList(PREDICATE_SHOW_ALL_RESIDENCES);
+ return new CommandResult(String.format(MESSAGE_EDIT_BOOKING_SUCCESS, editedBooking));
+ }
+
+ /**
+ * Creates and returns a {@code Booking} with the details of {@code bookingToEdit}
+ * edited with {@code editBookingDescriptor}.
+ */
+ private static Booking createEditedBooking(Booking bookingToEdit,
+ EditBookingDescriptor editBookingDescriptor) {
+ assert bookingToEdit != null;
+
+ TenantName updatedTenantName = editBookingDescriptor.getName()
+ .orElse(bookingToEdit.getTenantName());
+ Phone updatedPhone = editBookingDescriptor.getPhone()
+ .orElse(bookingToEdit.getPhone());
+ LocalDate updatedStartTime = editBookingDescriptor.getStartDate()
+ .orElse(bookingToEdit.getStart());
+ LocalDate updatedEndTime = editBookingDescriptor.getEndDate()
+ .orElse(bookingToEdit.getEnd());
+
+ return new Booking(updatedTenantName, updatedPhone, updatedStartTime, updatedEndTime);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ // short circuit if same object
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof EditBookingCommand)) {
+ return false;
+ }
+
+ // state check
+ EditBookingCommand e = (EditBookingCommand) other;
+ return residenceIndex.equals(e.residenceIndex)
+ && bookingIndex.equals(e.bookingIndex)
+ && editBookingDescriptor.equals(e.editBookingDescriptor);
+ }
+
+ public static String getCommandWord() {
+ return COMMAND_WORD;
+ }
+
+ /**
+ * Stores the details to edit the booking with. Each non-empty field value will replace the
+ * corresponding field value of the booking.
+ */
+ public static class EditBookingDescriptor {
+ private TenantName tenantName;
+ private Phone phone;
+ private LocalDate startDate;
+ private LocalDate endDate;
+
+ public EditBookingDescriptor() {
+ }
+
+ /**
+ * Copy constructor.
+ * A defensive copy of {@code tags} is used internally.
+ */
+ public EditBookingDescriptor(EditBookingDescriptor toCopy) {
+ setName(toCopy.tenantName);
+ setPhone(toCopy.phone);
+ setStartDate(toCopy.startDate);
+ setEndDate(toCopy.endDate);
+ }
+ /**
+ * Returns true if at least one field is edited.
+ */
+ public boolean isAnyFieldEdited() {
+ return CollectionUtil.isAnyNonNull(tenantName, phone, startDate, endDate);
+ }
+
+ public void setName(TenantName tenantName) {
+ this.tenantName = tenantName;
+ }
+
+ public Optional getName() {
+ return Optional.ofNullable(tenantName);
+ }
+
+ public void setPhone(Phone phone) {
+ this.phone = phone;
+ }
+
+ public Optional getPhone() {
+ return Optional.ofNullable(phone);
+ }
+
+ public void setStartDate(LocalDate startDate) {
+ this.startDate = startDate;
+ }
+
+ public Optional getStartDate() {
+ return Optional.ofNullable(startDate);
+ }
+
+ public void setEndDate(LocalDate endDate) {
+ this.endDate = endDate;
+ }
+
+ public Optional getEndDate() {
+ return Optional.ofNullable(endDate);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ // short circuit if same object
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof EditBookingDescriptor)) {
+ return false;
+ }
+
+ // state check
+ EditBookingDescriptor e = (EditBookingDescriptor) other;
+
+ return getName().equals(e.getName())
+ && getPhone().equals(e.getPhone())
+ && getStartDate().equals(e.getStartDate())
+ && getEndDate().equals(e.getEndDate());
+ }
+ }
+}
diff --git a/src/main/java/seedu/address/logic/commands/EditCommand.java b/src/main/java/seedu/address/logic/commands/EditCommand.java
index 7e36114902f..c71023a0c33 100644
--- a/src/main/java/seedu/address/logic/commands/EditCommand.java
+++ b/src/main/java/seedu/address/logic/commands/EditCommand.java
@@ -1,12 +1,11 @@
package seedu.address.logic.commands;
import static java.util.Objects.requireNonNull;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_CLEAN_STATUS_TAG;
import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_RESIDENCE_ADDRESS;
import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG;
-import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PERSONS;
+import static seedu.address.model.Model.PREDICATE_SHOW_ALL_RESIDENCES;
import java.util.Collections;
import java.util.HashSet;
@@ -19,87 +18,95 @@
import seedu.address.commons.util.CollectionUtil;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.model.Model;
-import seedu.address.model.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Person;
-import seedu.address.model.person.Phone;
+import seedu.address.model.residence.BookingList;
+import seedu.address.model.residence.Residence;
+import seedu.address.model.residence.ResidenceAddress;
+import seedu.address.model.residence.ResidenceName;
+import seedu.address.model.tag.CleanStatusTag;
import seedu.address.model.tag.Tag;
/**
- * Edits the details of an existing person in the address book.
+ * Edits the details of an existing residence in the residence tracker.
*/
public class EditCommand extends Command {
public static final String COMMAND_WORD = "edit";
- public static final String MESSAGE_USAGE = COMMAND_WORD + ": Edits the details of the person identified "
- + "by the index number used in the displayed person list. "
+ public static final String MESSAGE_USAGE = COMMAND_WORD + ": Edits the details of the residence identified "
+ + "by the index number used in the displayed residence list. "
+ "Existing values will be overwritten by the input values.\n"
- + "Parameters: INDEX (must be a positive integer) "
- + "[" + PREFIX_NAME + "NAME] "
- + "[" + PREFIX_PHONE + "PHONE] "
- + "[" + PREFIX_EMAIL + "EMAIL] "
- + "[" + PREFIX_ADDRESS + "ADDRESS] "
+ + "Parameters: RESIDENCE_INDEX (must be a positive integer) "
+ + "[" + PREFIX_NAME + "RESIDENCE_NAME]"
+ + "[" + PREFIX_RESIDENCE_ADDRESS + "ADDRESS]"
+ + "[" + PREFIX_CLEAN_STATUS_TAG + "y or n] "
+ "[" + PREFIX_TAG + "TAG]...\n"
+ "Example: " + COMMAND_WORD + " 1 "
- + PREFIX_PHONE + "91234567 "
- + PREFIX_EMAIL + "johndoe@example.com";
+ + PREFIX_CLEAN_STATUS_TAG + "y";
- public static final String MESSAGE_EDIT_PERSON_SUCCESS = "Edited Person: %1$s";
+ public static final String MESSAGE_EDIT_RESIDENCE_SUCCESS = "Edited Residence: %1$s";
public static final String MESSAGE_NOT_EDITED = "At least one field to edit must be provided.";
- public static final String MESSAGE_DUPLICATE_PERSON = "This person already exists in the address book.";
+ public static final String MESSAGE_DUPLICATE_RESIDENCE = "This residence already exists in the residence tracker.";
private final Index index;
- private final EditPersonDescriptor editPersonDescriptor;
+ private final EditResidenceDescriptor editResidenceDescriptor;
/**
- * @param index of the person in the filtered person list to edit
- * @param editPersonDescriptor details to edit the person with
+ * @param index of the residence in the filtered residence list to edit
+ * @param editResidenceDescriptor details to edit the residence with
*/
- public EditCommand(Index index, EditPersonDescriptor editPersonDescriptor) {
+ public EditCommand(Index index, EditResidenceDescriptor editResidenceDescriptor) {
requireNonNull(index);
- requireNonNull(editPersonDescriptor);
+ requireNonNull(editResidenceDescriptor);
this.index = index;
- this.editPersonDescriptor = new EditPersonDescriptor(editPersonDescriptor);
+ this.editResidenceDescriptor = new EditResidenceDescriptor(editResidenceDescriptor);
}
@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
- List lastShownList = model.getFilteredPersonList();
+ List lastShownList = model.getFilteredResidenceList();
if (index.getZeroBased() >= lastShownList.size()) {
- throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
+ throw new CommandException(Messages.MESSAGE_INVALID_RESIDENCE_DISPLAYED_INDEX);
}
- Person personToEdit = lastShownList.get(index.getZeroBased());
- Person editedPerson = createEditedPerson(personToEdit, editPersonDescriptor);
+ Residence residenceToEdit = lastShownList.get(index.getZeroBased());
+ editResidenceDescriptor.setBookingDetails(residenceToEdit.getBookingList());
+ Residence editedResidence = createEditedResidence(residenceToEdit, editResidenceDescriptor);
- if (!personToEdit.isSamePerson(editedPerson) && model.hasPerson(editedPerson)) {
- throw new CommandException(MESSAGE_DUPLICATE_PERSON);
+ if (!residenceToEdit.isSameResidence(editedResidence) && model.hasResidence(editedResidence)) {
+ throw new CommandException(MESSAGE_DUPLICATE_RESIDENCE);
}
- model.setPerson(personToEdit, editedPerson);
- model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
- return new CommandResult(String.format(MESSAGE_EDIT_PERSON_SUCCESS, editedPerson));
+ model.setResidence(residenceToEdit, editedResidence);
+ model.updateFilteredResidenceList(PREDICATE_SHOW_ALL_RESIDENCES);
+ return new CommandResult(String.format(MESSAGE_EDIT_RESIDENCE_SUCCESS, editedResidence));
+ }
+
+ public static String getCommandWord() {
+ return COMMAND_WORD;
}
/**
- * Creates and returns a {@code Person} with the details of {@code personToEdit}
- * edited with {@code editPersonDescriptor}.
+ * Creates and returns a {@code Residence} with the details of {@code residenceToEdit}
+ * edited with {@code editResidenceDescriptor}.
*/
- private static Person createEditedPerson(Person personToEdit, EditPersonDescriptor editPersonDescriptor) {
- assert personToEdit != null;
-
- Name updatedName = editPersonDescriptor.getName().orElse(personToEdit.getName());
- Phone updatedPhone = editPersonDescriptor.getPhone().orElse(personToEdit.getPhone());
- Email updatedEmail = editPersonDescriptor.getEmail().orElse(personToEdit.getEmail());
- Address updatedAddress = editPersonDescriptor.getAddress().orElse(personToEdit.getAddress());
- Set updatedTags = editPersonDescriptor.getTags().orElse(personToEdit.getTags());
-
- return new Person(updatedName, updatedPhone, updatedEmail, updatedAddress, updatedTags);
+ private static Residence createEditedResidence(Residence residenceToEdit,
+ EditResidenceDescriptor editResidenceDescriptor) {
+ assert residenceToEdit != null;
+
+ ResidenceName updatedName = editResidenceDescriptor.getResidenceName()
+ .orElse(residenceToEdit.getResidenceName());
+ ResidenceAddress updatedAddress = editResidenceDescriptor.getResidenceAddress()
+ .orElse(residenceToEdit.getResidenceAddress());
+ BookingList updatedBookingList = editResidenceDescriptor.getBookingDetails()
+ .orElse(residenceToEdit.getBookingList());
+ CleanStatusTag updatedCleanStatus = editResidenceDescriptor.getCleanStatusTag().orElse(
+ residenceToEdit.getCleanStatusTag());
+ Set updatedTags = editResidenceDescriptor.getTags().orElse(residenceToEdit.getTags());
+
+ return new Residence(updatedName, updatedAddress, updatedBookingList, updatedCleanStatus, updatedTags);
}
@Override
@@ -117,31 +124,31 @@ public boolean equals(Object other) {
// state check
EditCommand e = (EditCommand) other;
return index.equals(e.index)
- && editPersonDescriptor.equals(e.editPersonDescriptor);
+ && editResidenceDescriptor.equals(e.editResidenceDescriptor);
}
/**
* Stores the details to edit the person with. Each non-empty field value will replace the
* corresponding field value of the person.
*/
- public static class EditPersonDescriptor {
- private Name name;
- private Phone phone;
- private Email email;
- private Address address;
+ public static class EditResidenceDescriptor {
+ private ResidenceName residenceName;
+ private ResidenceAddress residenceAddress;
+ private BookingList bookingList;
+ private CleanStatusTag cleanStatusTag;
private Set tags;
- public EditPersonDescriptor() {}
+ public EditResidenceDescriptor() {
+ }
/**
* Copy constructor.
* A defensive copy of {@code tags} is used internally.
*/
- public EditPersonDescriptor(EditPersonDescriptor toCopy) {
- setName(toCopy.name);
- setPhone(toCopy.phone);
- setEmail(toCopy.email);
- setAddress(toCopy.address);
+ public EditResidenceDescriptor(EditResidenceDescriptor toCopy) {
+ setResidenceName(toCopy.residenceName);
+ setResidenceAddress(toCopy.residenceAddress);
+ setCleanStatusTag(toCopy.cleanStatusTag);
setTags(toCopy.tags);
}
@@ -149,39 +156,42 @@ public EditPersonDescriptor(EditPersonDescriptor toCopy) {
* Returns true if at least one field is edited.
*/
public boolean isAnyFieldEdited() {
- return CollectionUtil.isAnyNonNull(name, phone, email, address, tags);
+ return CollectionUtil.isAnyNonNull(residenceName, residenceAddress, bookingList, cleanStatusTag, tags);
}
- public void setName(Name name) {
- this.name = name;
+ public void setResidenceName(ResidenceName name) {
+ this.residenceName = name;
}
- public Optional getName() {
- return Optional.ofNullable(name);
+ public Optional getResidenceName() {
+ return Optional.ofNullable(residenceName);
}
- public void setPhone(Phone phone) {
- this.phone = phone;
+ public void setResidenceAddress(ResidenceAddress address) {
+ this.residenceAddress = address;
}
- public Optional getPhone() {
- return Optional.ofNullable(phone);
+ public Optional getResidenceAddress() {
+ return Optional.ofNullable(residenceAddress);
}
- public void setEmail(Email email) {
- this.email = email;
+ public void setBookingDetails(BookingList bookingList) {
+ this.bookingList = bookingList;
}
- public Optional getEmail() {
- return Optional.ofNullable(email);
+ public Optional getBookingDetails() {
+ return Optional.ofNullable(bookingList);
}
- public void setAddress(Address address) {
- this.address = address;
+ /**
+ * Sets {@code cleanStatusTag} to this object's {@code cleanStatusTag}.
+ */
+ public void setCleanStatusTag(CleanStatusTag cleanStatusTag) {
+ this.cleanStatusTag = cleanStatusTag;
}
- public Optional getAddress() {
- return Optional.ofNullable(address);
+ public Optional getCleanStatusTag() {
+ return Optional.ofNullable(cleanStatusTag);
}
/**
@@ -209,17 +219,17 @@ public boolean equals(Object other) {
}
// instanceof handles nulls
- if (!(other instanceof EditPersonDescriptor)) {
+ if (!(other instanceof EditResidenceDescriptor)) {
return false;
}
// state check
- EditPersonDescriptor e = (EditPersonDescriptor) other;
+ EditResidenceDescriptor e = (EditResidenceDescriptor) other;
- return getName().equals(e.getName())
- && getPhone().equals(e.getPhone())
- && getEmail().equals(e.getEmail())
- && getAddress().equals(e.getAddress())
+ return getResidenceName().equals(e.getResidenceName())
+ && getResidenceAddress().equals(e.getResidenceAddress())
+ && getBookingDetails().equals(e.getBookingDetails())
+ && getCleanStatusTag().equals(e.getCleanStatusTag())
&& getTags().equals(e.getTags());
}
}
diff --git a/src/main/java/seedu/address/logic/commands/ExitCommand.java b/src/main/java/seedu/address/logic/commands/ExitCommand.java
index 3dd85a8ba90..a6126e89598 100644
--- a/src/main/java/seedu/address/logic/commands/ExitCommand.java
+++ b/src/main/java/seedu/address/logic/commands/ExitCommand.java
@@ -9,11 +9,14 @@ public class ExitCommand extends Command {
public static final String COMMAND_WORD = "exit";
- public static final String MESSAGE_EXIT_ACKNOWLEDGEMENT = "Exiting Address Book as requested ...";
+ public static final String MESSAGE_EXIT_ACKNOWLEDGEMENT = "Exiting Residence Tracker as requested ...";
@Override
public CommandResult execute(Model model) {
return new CommandResult(MESSAGE_EXIT_ACKNOWLEDGEMENT, false, true);
}
+ public static String getCommandWord() {
+ return COMMAND_WORD;
+ }
}
diff --git a/src/main/java/seedu/address/logic/commands/FindCommand.java b/src/main/java/seedu/address/logic/commands/FindCommand.java
index d6b19b0a0de..199395d9fa3 100644
--- a/src/main/java/seedu/address/logic/commands/FindCommand.java
+++ b/src/main/java/seedu/address/logic/commands/FindCommand.java
@@ -4,20 +4,20 @@
import seedu.address.commons.core.Messages;
import seedu.address.model.Model;
-import seedu.address.model.person.NameContainsKeywordsPredicate;
+import seedu.address.model.residence.NameContainsKeywordsPredicate;
/**
- * Finds and lists all persons in address book whose name contains any of the argument keywords.
+ * Finds and lists all residences in residence tracker whose name contains any of the argument keywords.
* Keyword matching is case insensitive.
*/
public class FindCommand extends Command {
public static final String COMMAND_WORD = "find";
- public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all persons whose names contain any of "
+ public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all residences whose names contain any of "
+ "the specified keywords (case-insensitive) and displays them as a list with index numbers.\n"
+ "Parameters: KEYWORD [MORE_KEYWORDS]...\n"
- + "Example: " + COMMAND_WORD + " alice bob charlie";
+ + "Example: " + COMMAND_WORD + " amber beverly casuarina";
private final NameContainsKeywordsPredicate predicate;
@@ -28,9 +28,13 @@ public FindCommand(NameContainsKeywordsPredicate predicate) {
@Override
public CommandResult execute(Model model) {
requireNonNull(model);
- model.updateFilteredPersonList(predicate);
+ model.updateFilteredResidenceList(predicate);
return new CommandResult(
- String.format(Messages.MESSAGE_PERSONS_LISTED_OVERVIEW, model.getFilteredPersonList().size()));
+ String.format(Messages.MESSAGE_RESIDENCE_LISTED_OVERVIEW, model.getFilteredResidenceList().size()));
+ }
+
+ public static String getCommandWord() {
+ return COMMAND_WORD;
}
@Override
diff --git a/src/main/java/seedu/address/logic/commands/HelpCommand.java b/src/main/java/seedu/address/logic/commands/HelpCommand.java
index bf824f91bd0..e9fe8cdbfb2 100644
--- a/src/main/java/seedu/address/logic/commands/HelpCommand.java
+++ b/src/main/java/seedu/address/logic/commands/HelpCommand.java
@@ -3,7 +3,7 @@
import seedu.address.model.Model;
/**
- * Format full help instructions for every command for display.
+ * Formats full help instructions for every command for display.
*/
public class HelpCommand extends Command {
@@ -12,10 +12,10 @@ public class HelpCommand extends Command {
public static final String MESSAGE_USAGE = COMMAND_WORD + ": Shows program usage instructions.\n"
+ "Example: " + COMMAND_WORD;
- public static final String SHOWING_HELP_MESSAGE = "Opened help window.";
+ public static final String HELP_MESSAGE_DISPLAY = "Opened help window.";
@Override
public CommandResult execute(Model model) {
- return new CommandResult(SHOWING_HELP_MESSAGE, true, false);
+ return new CommandResult(HELP_MESSAGE_DISPLAY, true, false);
}
}
diff --git a/src/main/java/seedu/address/logic/commands/ListCommand.java b/src/main/java/seedu/address/logic/commands/ListCommand.java
index 84be6ad2596..c245c0a8db9 100644
--- a/src/main/java/seedu/address/logic/commands/ListCommand.java
+++ b/src/main/java/seedu/address/logic/commands/ListCommand.java
@@ -1,24 +1,27 @@
package seedu.address.logic.commands;
import static java.util.Objects.requireNonNull;
-import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PERSONS;
+import static seedu.address.model.Model.PREDICATE_SHOW_ALL_RESIDENCES;
import seedu.address.model.Model;
/**
- * Lists all persons in the address book to the user.
+ * Lists all residences in the residence tracker to the user.
*/
public class ListCommand extends Command {
public static final String COMMAND_WORD = "list";
- public static final String MESSAGE_SUCCESS = "Listed all persons";
+ public static final String MESSAGE_SUCCESS = "Listed all residences.";
+ public static String getCommandWord() {
+ return COMMAND_WORD;
+ }
@Override
public CommandResult execute(Model model) {
requireNonNull(model);
- model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
+ model.updateFilteredResidenceList(PREDICATE_SHOW_ALL_RESIDENCES);
return new CommandResult(MESSAGE_SUCCESS);
}
}
diff --git a/src/main/java/seedu/address/logic/commands/RemindCommand.java b/src/main/java/seedu/address/logic/commands/RemindCommand.java
new file mode 100644
index 00000000000..a64545e4368
--- /dev/null
+++ b/src/main/java/seedu/address/logic/commands/RemindCommand.java
@@ -0,0 +1,28 @@
+package seedu.address.logic.commands;
+
+import static java.util.Objects.requireNonNull;
+import static seedu.address.model.Model.PREDICATE_UPCOMING_BOOKED_RESIDENCES;
+
+import seedu.address.commons.core.Messages;
+import seedu.address.model.Model;
+
+/**
+ * Lists all residences in the residence tracker with bookings starting in the next 7 days.
+ */
+public class RemindCommand extends Command {
+
+ public static final String COMMAND_WORD = "remind";
+
+ public static String getCommandWord() {
+ return COMMAND_WORD;
+ }
+
+ @Override
+ public CommandResult execute(Model model) {
+ requireNonNull(model);
+ model.updateFilteredResidenceList(PREDICATE_UPCOMING_BOOKED_RESIDENCES);
+ return new CommandResult(
+ String.format(Messages.MESSAGE_RESIDENCES_WITH_UPCOMING_BOOKINGS,
+ model.getFilteredResidenceList().size()));
+ }
+}
diff --git a/src/main/java/seedu/address/logic/commands/StatusCommand.java b/src/main/java/seedu/address/logic/commands/StatusCommand.java
new file mode 100644
index 00000000000..183c6d6af3b
--- /dev/null
+++ b/src/main/java/seedu/address/logic/commands/StatusCommand.java
@@ -0,0 +1,121 @@
+package seedu.address.logic.commands;
+
+import static java.util.Objects.requireNonNull;
+import static seedu.address.model.Model.PREDICATE_SHOW_ALL_RESIDENCES;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import seedu.address.commons.core.Messages;
+import seedu.address.commons.core.index.Index;
+import seedu.address.logic.commands.exceptions.CommandException;
+import seedu.address.model.Model;
+import seedu.address.model.residence.BookingList;
+import seedu.address.model.residence.Residence;
+import seedu.address.model.residence.ResidenceAddress;
+import seedu.address.model.residence.ResidenceName;
+import seedu.address.model.tag.CleanStatusTag;
+import seedu.address.model.tag.Tag;
+
+/**
+ * Edits the details of an existing residence in the residence tracker.
+ */
+public class StatusCommand extends Command {
+
+ public static final String COMMAND_WORD = "status";
+
+ public static final String MESSAGE_USAGE = COMMAND_WORD + ": Updates multiple residences clean status "
+ + "by the index number used in the displayed residence list. \n"
+ + "Parameters: status (clean or unclean) "
+ + "INDEX1 INDEX2... (must be positive integers) "
+ + "Example: " + COMMAND_WORD
+ + " clean 1 2 4 ";
+
+ public static final String MESSAGE_STATUS_RESIDENCE_SUCCESS = "Residences with updated status: %1$s";
+ public static final String MESSAGE_ERROR_STATUS = "Must input a correct clean status (clean/unclean)";
+ public static final String MESSAGE_NO_RESIDENCE = "At least one residence index to update status must be provided.";
+
+ private final ArrayList indexArray;
+ private final String status;
+
+ /**
+ * @param indexArray of the residences in the filtered residence list to update clean status
+ */
+ public StatusCommand(ArrayList indexArray , String status) {
+ requireNonNull(indexArray);
+ requireNonNull(status);
+ this.indexArray = indexArray;
+ this.status = status;
+ }
+
+ @Override
+ public CommandResult execute(Model model) throws CommandException {
+ requireNonNull(model);
+ List lastShownList = model.getFilteredResidenceList();
+ String updatedResidenceArrayString = "";
+ //check index list first
+ for (Index index : indexArray) {
+ if (index.getZeroBased() >= lastShownList.size()) {
+ throw new CommandException(Messages.MESSAGE_INVALID_RESIDENCE_DISPLAYED_INDEX);
+ }
+ }
+
+ for (Index index : indexArray) {
+ Residence residenceToUpdateStatus = lastShownList.get(index.getZeroBased());
+ Residence updatedResidence = createUpdatedResidence(residenceToUpdateStatus, status);
+ model.setResidence(residenceToUpdateStatus, updatedResidence);
+ updatedResidenceArrayString += updatedResidence.toString() + "\n";
+ }
+
+ model.updateFilteredResidenceList(PREDICATE_SHOW_ALL_RESIDENCES);
+ return new CommandResult(String.format(MESSAGE_STATUS_RESIDENCE_SUCCESS, updatedResidenceArrayString));
+ }
+
+ /**
+ * Creates and returns a {@code Residence} with the details of {@code residenceToEdit}
+ * edited with {@code editResidenceDescriptor}.
+ */
+ private static Residence createUpdatedResidence(Residence residenceToUpdateStatus,
+ String status) throws CommandException {
+ assert residenceToUpdateStatus != null;
+
+ ResidenceName updatedName = residenceToUpdateStatus.getResidenceName();
+ ResidenceAddress updatedAddress = residenceToUpdateStatus.getResidenceAddress();
+ BookingList updatedBooking = residenceToUpdateStatus.getBookingList();
+
+ CleanStatusTag updatedCleanStatus;
+ if (status.equals("clean")) {
+ updatedCleanStatus = new CleanStatusTag("y");
+ } else if (status.equals("unclean")) {
+ updatedCleanStatus = new CleanStatusTag("n");
+ } else {
+ throw new CommandException(MESSAGE_ERROR_STATUS);
+ }
+ Set updatedTags = residenceToUpdateStatus.getTags();
+
+ return new Residence(updatedName, updatedAddress, updatedBooking, updatedCleanStatus, updatedTags);
+ }
+
+ public static String getCommandWord() {
+ return COMMAND_WORD;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ // short circuit if same object
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof StatusCommand)) {
+ return false;
+ }
+
+ // state check
+ StatusCommand e = (StatusCommand) other;
+ return indexArray.equals(e.indexArray)
+ && status.equals(e.status);
+ }
+}
diff --git a/src/main/java/seedu/address/logic/parser/AddBookingCommandParser.java b/src/main/java/seedu/address/logic/parser/AddBookingCommandParser.java
new file mode 100644
index 00000000000..6434f7b1803
--- /dev/null
+++ b/src/main/java/seedu/address/logic/parser/AddBookingCommandParser.java
@@ -0,0 +1,65 @@
+package seedu.address.logic.parser;
+
+import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_BOOKING_END_DATE;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_BOOKING_START_DATE;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE;
+
+import java.util.stream.Stream;
+
+import seedu.address.commons.core.index.Index;
+import seedu.address.logic.commands.AddBookingCommand;
+import seedu.address.logic.parser.exceptions.ParseException;
+import seedu.address.model.booking.Booking;
+import seedu.address.model.booking.Phone;
+import seedu.address.model.booking.TenantName;
+
+/**
+ * Parses input arguments and creates a new AddBookingCommand object
+ */
+public class AddBookingCommandParser implements Parser {
+
+ /**
+ * Parses the given {@code String} of arguments in the context of the AddBookingCommand
+ * and returns an AddBookingCommand object for execution.
+ *
+ * @throws ParseException if the user input does not conform the expected format
+ */
+ public AddBookingCommand parse(String args) throws ParseException {
+ ArgumentMultimap argMultimap =
+ ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_PHONE,
+ PREFIX_BOOKING_START_DATE, PREFIX_BOOKING_END_DATE);
+ Index index;
+
+ try {
+ index = ParserUtil.parseIndex(argMultimap.getPreamble());
+ } catch (ParseException pe) {
+ throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT,
+ AddBookingCommand.MESSAGE_USAGE), pe);
+ }
+
+ if (!arePrefixesPresent(argMultimap, PREFIX_NAME, PREFIX_PHONE,
+ PREFIX_BOOKING_START_DATE, PREFIX_BOOKING_END_DATE)
+ || argMultimap.getPreamble().isEmpty()) {
+ throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddBookingCommand.MESSAGE_USAGE));
+ }
+
+ TenantName tenantName = ParserUtil.parseTenantName(argMultimap.getValue(PREFIX_NAME).get());
+ Phone phone = ParserUtil.parsePhone(argMultimap.getValue(PREFIX_PHONE).get());
+ Booking booking = ParserUtil.parseBooking(tenantName, phone,
+ argMultimap.getValue(PREFIX_BOOKING_START_DATE).get(),
+ argMultimap.getValue(PREFIX_BOOKING_END_DATE).get());
+
+ return new AddBookingCommand(index, booking);
+ }
+
+ /**
+ * Returns true if none of the prefixes contains empty {@code Optional} values in the given
+ * {@code ArgumentMultimap}.
+ */
+ private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) {
+ return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent());
+ }
+
+}
diff --git a/src/main/java/seedu/address/logic/parser/AddCommandParser.java b/src/main/java/seedu/address/logic/parser/AddCommandParser.java
index 3b8bfa035e8..4d49c364468 100644
--- a/src/main/java/seedu/address/logic/parser/AddCommandParser.java
+++ b/src/main/java/seedu/address/logic/parser/AddCommandParser.java
@@ -1,10 +1,9 @@
package seedu.address.logic.parser;
import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_CLEAN_STATUS_TAG;
import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_RESIDENCE_ADDRESS;
import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG;
import java.util.Set;
@@ -12,11 +11,11 @@
import seedu.address.logic.commands.AddCommand;
import seedu.address.logic.parser.exceptions.ParseException;
-import seedu.address.model.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Person;
-import seedu.address.model.person.Phone;
+import seedu.address.model.residence.BookingList;
+import seedu.address.model.residence.Residence;
+import seedu.address.model.residence.ResidenceAddress;
+import seedu.address.model.residence.ResidenceName;
+import seedu.address.model.tag.CleanStatusTag;
import seedu.address.model.tag.Tag;
/**
@@ -27,26 +26,36 @@ public class AddCommandParser implements Parser {
/**
* Parses the given {@code String} of arguments in the context of the AddCommand
* and returns an AddCommand object for execution.
+ *
* @throws ParseException if the user input does not conform the expected format
*/
public AddCommand parse(String args) throws ParseException {
ArgumentMultimap argMultimap =
- ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS, PREFIX_TAG);
+ ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_RESIDENCE_ADDRESS,
+ PREFIX_CLEAN_STATUS_TAG, PREFIX_TAG);
- if (!arePrefixesPresent(argMultimap, PREFIX_NAME, PREFIX_ADDRESS, PREFIX_PHONE, PREFIX_EMAIL)
+ if (!arePrefixesPresent(argMultimap, PREFIX_NAME, PREFIX_RESIDENCE_ADDRESS)
|| !argMultimap.getPreamble().isEmpty()) {
throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE));
}
- Name name = ParserUtil.parseName(argMultimap.getValue(PREFIX_NAME).get());
- Phone phone = ParserUtil.parsePhone(argMultimap.getValue(PREFIX_PHONE).get());
- Email email = ParserUtil.parseEmail(argMultimap.getValue(PREFIX_EMAIL).get());
- Address address = ParserUtil.parseAddress(argMultimap.getValue(PREFIX_ADDRESS).get());
+ ResidenceName name = ParserUtil.parseResidenceName(argMultimap.getValue(PREFIX_NAME).get());
+ ResidenceAddress address = ParserUtil.parseAddress(argMultimap.getValue(PREFIX_RESIDENCE_ADDRESS).get());
+
+ BookingList bookingList = new BookingList();
+
+ CleanStatusTag cleanStatusTag;
+ if (argMultimap.getAllValues(PREFIX_CLEAN_STATUS_TAG).size() > 0) {
+ cleanStatusTag = ParserUtil.parseCleanStatusTag(
+ argMultimap.getValue(PREFIX_CLEAN_STATUS_TAG).get());
+ } else {
+ cleanStatusTag = new CleanStatusTag();
+ }
Set tagList = ParserUtil.parseTags(argMultimap.getAllValues(PREFIX_TAG));
- Person person = new Person(name, phone, email, address, tagList);
+ Residence residence = new Residence(name, address, bookingList, cleanStatusTag, tagList);
- return new AddCommand(person);
+ return new AddCommand(residence);
}
/**
diff --git a/src/main/java/seedu/address/logic/parser/CliSyntax.java b/src/main/java/seedu/address/logic/parser/CliSyntax.java
index 75b1a9bf119..abe261112de 100644
--- a/src/main/java/seedu/address/logic/parser/CliSyntax.java
+++ b/src/main/java/seedu/address/logic/parser/CliSyntax.java
@@ -8,8 +8,11 @@ public class CliSyntax {
/* Prefix definitions */
public static final Prefix PREFIX_NAME = new Prefix("n/");
public static final Prefix PREFIX_PHONE = new Prefix("p/");
- public static final Prefix PREFIX_EMAIL = new Prefix("e/");
- public static final Prefix PREFIX_ADDRESS = new Prefix("a/");
+ public static final Prefix PREFIX_BOOKING = new Prefix("b/");
+ public static final Prefix PREFIX_RESIDENCE_ADDRESS = new Prefix("a/");
+ public static final Prefix PREFIX_CLEAN_STATUS_TAG = new Prefix("c/");
public static final Prefix PREFIX_TAG = new Prefix("t/");
-
+ public static final Prefix PREFIX_BOOKING_START_DATE = new Prefix("s/");
+ public static final Prefix PREFIX_BOOKING_END_DATE = new Prefix("e/");
+ public static final Prefix PREFIX_RESIDENCE = new Prefix("r/");
}
diff --git a/src/main/java/seedu/address/logic/parser/DeleteBookingCommandParser.java b/src/main/java/seedu/address/logic/parser/DeleteBookingCommandParser.java
new file mode 100644
index 00000000000..a8fe17b4c1b
--- /dev/null
+++ b/src/main/java/seedu/address/logic/parser/DeleteBookingCommandParser.java
@@ -0,0 +1,48 @@
+package seedu.address.logic.parser;
+
+import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_BOOKING;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_RESIDENCE;
+
+import java.util.stream.Stream;
+
+import seedu.address.commons.core.index.Index;
+import seedu.address.logic.commands.DeleteBookingCommand;
+import seedu.address.logic.parser.exceptions.ParseException;
+
+public class DeleteBookingCommandParser implements Parser {
+
+ /**
+ * Parses the given {@code String} of arguments in the context of the DeleteBookingCommand
+ * and returns a DeleteBookingCommand object for execution.
+ * @throws ParseException if the user input does not conform the expected format
+ */
+ public DeleteBookingCommand parse(String args) throws ParseException {
+
+ ArgumentMultimap argMultimap =
+ ArgumentTokenizer.tokenize(args, PREFIX_RESIDENCE, PREFIX_BOOKING);
+
+ if (!arePrefixesPresent(argMultimap, PREFIX_RESIDENCE, PREFIX_BOOKING)
+ || !argMultimap.getPreamble().isEmpty()) {
+ throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteBookingCommand.MESSAGE_USAGE));
+ }
+
+ if (argMultimap.getValue(PREFIX_RESIDENCE).get().isEmpty()
+ || argMultimap.getValue(PREFIX_BOOKING).get().isEmpty()) {
+ throw new ParseException(
+ String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteBookingCommand.MESSAGE_USAGE));
+ }
+
+ Index residenceIndex = ParserUtil.parseIndex(argMultimap.getValue(PREFIX_RESIDENCE).get());
+ Index bookingIndex = ParserUtil.parseIndex(argMultimap.getValue(PREFIX_BOOKING).get());
+ return new DeleteBookingCommand(residenceIndex, bookingIndex);
+ }
+
+ /**
+ * Returns true if none of the prefixes contains empty {@code Optional} values in the given
+ * {@code ArgumentMultimap}.
+ */
+ private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) {
+ return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent());
+ }
+}
diff --git a/src/main/java/seedu/address/logic/parser/DeleteCommandParser.java b/src/main/java/seedu/address/logic/parser/DeleteCommandParser.java
index 522b93081cc..e1ddcdadc78 100644
--- a/src/main/java/seedu/address/logic/parser/DeleteCommandParser.java
+++ b/src/main/java/seedu/address/logic/parser/DeleteCommandParser.java
@@ -17,13 +17,11 @@ public class DeleteCommandParser implements Parser {
* @throws ParseException if the user input does not conform the expected format
*/
public DeleteCommand parse(String args) throws ParseException {
- try {
- Index index = ParserUtil.parseIndex(args);
- return new DeleteCommand(index);
- } catch (ParseException pe) {
- throw new ParseException(
- String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE), pe);
+ if (args.isEmpty()) {
+ throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE));
}
+ Index index = ParserUtil.parseIndex(args);
+ return new DeleteCommand(index);
}
}
diff --git a/src/main/java/seedu/address/logic/parser/EditBookingCommandParser.java b/src/main/java/seedu/address/logic/parser/EditBookingCommandParser.java
new file mode 100644
index 00000000000..22af42baada
--- /dev/null
+++ b/src/main/java/seedu/address/logic/parser/EditBookingCommandParser.java
@@ -0,0 +1,80 @@
+package seedu.address.logic.parser;
+
+import static java.util.Objects.requireNonNull;
+import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_BOOKING;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_BOOKING_END_DATE;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_BOOKING_START_DATE;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_RESIDENCE;
+
+import java.util.stream.Stream;
+
+import seedu.address.commons.core.index.Index;
+import seedu.address.logic.commands.EditBookingCommand;
+import seedu.address.logic.commands.EditBookingCommand.EditBookingDescriptor;
+import seedu.address.logic.parser.exceptions.ParseException;
+
+public class EditBookingCommandParser implements Parser {
+
+ /**
+ * Parses the given {@code String} of arguments in the context of the EditBookingCommand
+ * and returns an EditBookingCommand object for execution.
+ *
+ * @throws ParseException if the user input does not conform the expected format
+ */
+ public EditBookingCommand parse(String args) throws ParseException {
+ requireNonNull(args);
+ ArgumentMultimap argMultimap =
+ ArgumentTokenizer.tokenize(args, PREFIX_RESIDENCE, PREFIX_BOOKING,
+ PREFIX_NAME, PREFIX_PHONE, PREFIX_BOOKING_START_DATE, PREFIX_BOOKING_END_DATE);
+
+ if (!arePrefixesPresent(argMultimap, PREFIX_RESIDENCE, PREFIX_BOOKING)
+ || !argMultimap.getPreamble().isEmpty()) {
+ throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, EditBookingCommand.MESSAGE_USAGE));
+ }
+
+ if (argMultimap.getValue(PREFIX_RESIDENCE).get().isEmpty()
+ || argMultimap.getValue(PREFIX_BOOKING).get().isEmpty()) {
+ throw new ParseException(
+ String.format(MESSAGE_INVALID_COMMAND_FORMAT, EditBookingCommand.MESSAGE_USAGE));
+ }
+
+ Index residenceIndex = ParserUtil.parseIndex(argMultimap.getValue(PREFIX_RESIDENCE).get());
+ Index bookingIndex = ParserUtil.parseIndex(argMultimap.getValue(PREFIX_BOOKING).get());
+
+ EditBookingDescriptor editBookingDescriptor = new EditBookingDescriptor();
+ if (argMultimap.getValue(PREFIX_NAME).isPresent()) {
+ editBookingDescriptor.setName(
+ ParserUtil.parseTenantName(argMultimap.getValue(PREFIX_NAME).get()));
+ }
+ if (argMultimap.getValue(PREFIX_PHONE).isPresent()) {
+ editBookingDescriptor.setPhone(
+ ParserUtil.parsePhone(argMultimap.getValue(PREFIX_PHONE).get()));
+ }
+ if (argMultimap.getValue(PREFIX_BOOKING_START_DATE).isPresent()) {
+ editBookingDescriptor.setStartDate(
+ ParserUtil.parseDate(argMultimap.getValue(PREFIX_BOOKING_START_DATE).get())
+ );
+ }
+ if (argMultimap.getValue(PREFIX_BOOKING_END_DATE).isPresent()) {
+ editBookingDescriptor.setEndDate(
+ ParserUtil.parseDate(argMultimap.getValue(PREFIX_BOOKING_END_DATE).get())
+ );
+ }
+ if (!editBookingDescriptor.isAnyFieldEdited()) {
+ throw new ParseException(EditBookingCommand.MESSAGE_NOT_EDITED);
+ }
+
+ return new EditBookingCommand(residenceIndex, bookingIndex, editBookingDescriptor);
+ }
+
+ /**
+ * Returns true if none of the prefixes contains empty {@code Optional} values in the given
+ * {@code ArgumentMultimap}.
+ */
+ private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) {
+ return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent());
+ }
+}
diff --git a/src/main/java/seedu/address/logic/parser/EditCommandParser.java b/src/main/java/seedu/address/logic/parser/EditCommandParser.java
index 845644b7dea..095ce0520b5 100644
--- a/src/main/java/seedu/address/logic/parser/EditCommandParser.java
+++ b/src/main/java/seedu/address/logic/parser/EditCommandParser.java
@@ -2,10 +2,9 @@
import static java.util.Objects.requireNonNull;
import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_CLEAN_STATUS_TAG;
import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_RESIDENCE_ADDRESS;
import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG;
import java.util.Collection;
@@ -15,7 +14,7 @@
import seedu.address.commons.core.index.Index;
import seedu.address.logic.commands.EditCommand;
-import seedu.address.logic.commands.EditCommand.EditPersonDescriptor;
+import seedu.address.logic.commands.EditCommand.EditResidenceDescriptor;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.tag.Tag;
@@ -27,41 +26,49 @@ public class EditCommandParser implements Parser {
/**
* Parses the given {@code String} of arguments in the context of the EditCommand
* and returns an EditCommand object for execution.
+ *
* @throws ParseException if the user input does not conform the expected format
*/
public EditCommand parse(String args) throws ParseException {
requireNonNull(args);
ArgumentMultimap argMultimap =
- ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS, PREFIX_TAG);
+ ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_RESIDENCE_ADDRESS,
+ PREFIX_CLEAN_STATUS_TAG, PREFIX_TAG);
Index index;
-
- try {
- index = ParserUtil.parseIndex(argMultimap.getPreamble());
- } catch (ParseException pe) {
- throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, EditCommand.MESSAGE_USAGE), pe);
+ if (argMultimap.getPreamble().isEmpty()) {
+ throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, EditCommand.MESSAGE_USAGE));
}
- EditPersonDescriptor editPersonDescriptor = new EditPersonDescriptor();
+ index = ParserUtil.parseIndex(argMultimap.getPreamble());
+
+ EditResidenceDescriptor editResidenceDescriptor = new EditResidenceDescriptor();
if (argMultimap.getValue(PREFIX_NAME).isPresent()) {
- editPersonDescriptor.setName(ParserUtil.parseName(argMultimap.getValue(PREFIX_NAME).get()));
+ editResidenceDescriptor.setResidenceName(
+ ParserUtil.parseResidenceName(argMultimap.getValue(PREFIX_NAME).get()));
}
- if (argMultimap.getValue(PREFIX_PHONE).isPresent()) {
- editPersonDescriptor.setPhone(ParserUtil.parsePhone(argMultimap.getValue(PREFIX_PHONE).get()));
+ if (argMultimap.getValue(PREFIX_RESIDENCE_ADDRESS).isPresent()) {
+ editResidenceDescriptor.setResidenceAddress(
+ ParserUtil.parseAddress(argMultimap.getValue(PREFIX_RESIDENCE_ADDRESS).get()));
}
- if (argMultimap.getValue(PREFIX_EMAIL).isPresent()) {
- editPersonDescriptor.setEmail(ParserUtil.parseEmail(argMultimap.getValue(PREFIX_EMAIL).get()));
+
+ if (argMultimap.getValue(PREFIX_CLEAN_STATUS_TAG).isPresent()) {
+ editResidenceDescriptor.setCleanStatusTag(
+ ParserUtil.parseCleanStatusTag(argMultimap.getValue(PREFIX_CLEAN_STATUS_TAG).get()));
}
- if (argMultimap.getValue(PREFIX_ADDRESS).isPresent()) {
- editPersonDescriptor.setAddress(ParserUtil.parseAddress(argMultimap.getValue(PREFIX_ADDRESS).get()));
+
+ parseTagsForEdit(argMultimap.getAllValues(PREFIX_TAG)).ifPresent(editResidenceDescriptor::setTags);
+
+ if (argMultimap.getValue(PREFIX_CLEAN_STATUS_TAG).isPresent()) {
+ editResidenceDescriptor.setCleanStatusTag(
+ ParserUtil.parseCleanStatusTag(argMultimap.getValue(PREFIX_CLEAN_STATUS_TAG).get()));
}
- parseTagsForEdit(argMultimap.getAllValues(PREFIX_TAG)).ifPresent(editPersonDescriptor::setTags);
- if (!editPersonDescriptor.isAnyFieldEdited()) {
+ if (!editResidenceDescriptor.isAnyFieldEdited()) {
throw new ParseException(EditCommand.MESSAGE_NOT_EDITED);
}
- return new EditCommand(index, editPersonDescriptor);
+ return new EditCommand(index, editResidenceDescriptor);
}
/**
diff --git a/src/main/java/seedu/address/logic/parser/FindCommandParser.java b/src/main/java/seedu/address/logic/parser/FindCommandParser.java
index 4fb71f23103..1991002561f 100644
--- a/src/main/java/seedu/address/logic/parser/FindCommandParser.java
+++ b/src/main/java/seedu/address/logic/parser/FindCommandParser.java
@@ -6,7 +6,7 @@
import seedu.address.logic.commands.FindCommand;
import seedu.address.logic.parser.exceptions.ParseException;
-import seedu.address.model.person.NameContainsKeywordsPredicate;
+import seedu.address.model.residence.NameContainsKeywordsPredicate;
/**
* Parses input arguments and creates a new FindCommand object
diff --git a/src/main/java/seedu/address/logic/parser/Parser.java b/src/main/java/seedu/address/logic/parser/Parser.java
index d6551ad8e3f..ce644a9c6fd 100644
--- a/src/main/java/seedu/address/logic/parser/Parser.java
+++ b/src/main/java/seedu/address/logic/parser/Parser.java
@@ -10,6 +10,7 @@ public interface Parser {
/**
* Parses {@code userInput} into a command and returns it.
+ *
* @throws ParseException if {@code userInput} does not conform the expected format
*/
T parse(String userInput) throws ParseException;
diff --git a/src/main/java/seedu/address/logic/parser/ParserUtil.java b/src/main/java/seedu/address/logic/parser/ParserUtil.java
index b117acb9c55..7a3ee47b9b2 100644
--- a/src/main/java/seedu/address/logic/parser/ParserUtil.java
+++ b/src/main/java/seedu/address/logic/parser/ParserUtil.java
@@ -2,6 +2,8 @@
import static java.util.Objects.requireNonNull;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
@@ -9,10 +11,12 @@
import seedu.address.commons.core.index.Index;
import seedu.address.commons.util.StringUtil;
import seedu.address.logic.parser.exceptions.ParseException;
-import seedu.address.model.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Phone;
+import seedu.address.model.booking.Booking;
+import seedu.address.model.booking.Phone;
+import seedu.address.model.booking.TenantName;
+import seedu.address.model.residence.ResidenceAddress;
+import seedu.address.model.residence.ResidenceName;
+import seedu.address.model.tag.CleanStatusTag;
import seedu.address.model.tag.Tag;
/**
@@ -21,10 +25,12 @@
public class ParserUtil {
public static final String MESSAGE_INVALID_INDEX = "Index is not a non-zero unsigned integer.";
+ public static final String MESSAGE_INVALID_DATE_FORMAT = "The date is not in the expected format: DD-MM-YYYY";
/**
* Parses {@code oneBasedIndex} into an {@code Index} and returns it. Leading and trailing whitespaces will be
* trimmed.
+ *
* @throws ParseException if the specified index is invalid (not non-zero unsigned integer).
*/
public static Index parseIndex(String oneBasedIndex) throws ParseException {
@@ -36,18 +42,33 @@ public static Index parseIndex(String oneBasedIndex) throws ParseException {
}
/**
- * Parses a {@code String name} into a {@code Name}.
+ * Parses a {@code String name} into a {@code ResidenceName}.
* Leading and trailing whitespaces will be trimmed.
*
* @throws ParseException if the given {@code name} is invalid.
*/
- public static Name parseName(String name) throws ParseException {
+ public static ResidenceName parseResidenceName(String name) throws ParseException {
requireNonNull(name);
String trimmedName = name.trim();
- if (!Name.isValidName(trimmedName)) {
- throw new ParseException(Name.MESSAGE_CONSTRAINTS);
+ if (!ResidenceName.isValidResidenceName(trimmedName)) {
+ throw new ParseException(ResidenceName.MESSAGE_CONSTRAINTS);
}
- return new Name(trimmedName);
+ return new ResidenceName(trimmedName);
+ }
+
+ /**
+ * Parses a {@code String name} into a {@code TenantName}.
+ * Leading and trailing whitespaces will be trimmed.
+ *
+ * @throws ParseException if the given {@code name} is invalid.
+ */
+ public static TenantName parseTenantName(String name) throws ParseException {
+ requireNonNull(name);
+ String trimmedName = name.trim();
+ if (!ResidenceName.isValidResidenceName(trimmedName)) {
+ throw new ParseException(TenantName.MESSAGE_CONSTRAINTS);
+ }
+ return new TenantName(trimmedName);
}
/**
@@ -66,33 +87,68 @@ public static Phone parsePhone(String phone) throws ParseException {
}
/**
- * Parses a {@code String address} into an {@code Address}.
+ * Parses a {@code String address} into an {@code ResidenceAddress}.
* Leading and trailing whitespaces will be trimmed.
*
* @throws ParseException if the given {@code address} is invalid.
*/
- public static Address parseAddress(String address) throws ParseException {
+ public static ResidenceAddress parseAddress(String address) throws ParseException {
requireNonNull(address);
String trimmedAddress = address.trim();
- if (!Address.isValidAddress(trimmedAddress)) {
- throw new ParseException(Address.MESSAGE_CONSTRAINTS);
+ if (!ResidenceAddress.isValidResidenceAddress(trimmedAddress)) {
+ throw new ParseException(ResidenceAddress.MESSAGE_CONSTRAINTS);
+ }
+ return new ResidenceAddress(trimmedAddress);
+ }
+
+ /**
+ * Parses a {@code String bookingDetails} into an {@code Booking}.
+ * Leading and trailing whitespaces will be trimmed.
+ *
+ * @throws ParseException if the given {@code booking} is invalid.
+ */
+ public static Booking parseBooking(TenantName tenantName, Phone phone,
+ String start, String end) throws ParseException {
+ requireNonNull(start);
+ requireNonNull(end);
+ try {
+
+ LocalDate startTime = LocalDate.parse(start.trim(), DateTimeFormatter.ofPattern("dd-MM-uuuu"));
+ LocalDate endTime = LocalDate.parse(end.trim(), DateTimeFormatter.ofPattern("dd-MM-uuuu"));
+ if (!Booking.isValidBookingTime(startTime, endTime)) {
+ throw new ParseException(Booking.MESSAGE_CONSTRAINTS);
+ }
+ return new Booking(tenantName, phone, startTime, endTime);
+ } catch (Exception e) {
+ throw new ParseException(MESSAGE_INVALID_DATE_FORMAT);
+ }
+ }
+
+ /**
+ *
+ */
+ public static LocalDate parseDate(String date) throws ParseException {
+ requireNonNull(date);
+ try {
+ return LocalDate.parse(date.trim(), DateTimeFormatter.ofPattern("dd-MM-uuuu"));
+ } catch (Exception e) {
+ throw new ParseException(MESSAGE_INVALID_DATE_FORMAT);
}
- return new Address(trimmedAddress);
}
/**
- * Parses a {@code String email} into an {@code Email}.
+ * Parses a {@code String clean status(y or n)} into a {@code CleanStatusTag}.
* Leading and trailing whitespaces will be trimmed.
*
- * @throws ParseException if the given {@code email} is invalid.
+ * @throws ParseException if the given {@code cleanStatus} is invalid.
*/
- public static Email parseEmail(String email) throws ParseException {
- requireNonNull(email);
- String trimmedEmail = email.trim();
- if (!Email.isValidEmail(trimmedEmail)) {
- throw new ParseException(Email.MESSAGE_CONSTRAINTS);
+ public static CleanStatusTag parseCleanStatusTag(String cleanStatus) throws ParseException {
+ requireNonNull(cleanStatus);
+ String trimmedTag = cleanStatus.trim();
+ if (!CleanStatusTag.isValidCleanStatusTag(trimmedTag)) {
+ throw new ParseException(CleanStatusTag.MESSAGE_CONSTRAINTS);
}
- return new Email(trimmedEmail);
+ return new CleanStatusTag(trimmedTag);
}
/**
diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/ResidenceTrackerParser.java
similarity index 75%
rename from src/main/java/seedu/address/logic/parser/AddressBookParser.java
rename to src/main/java/seedu/address/logic/parser/ResidenceTrackerParser.java
index 1e466792b46..0f8c99b9118 100644
--- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java
+++ b/src/main/java/seedu/address/logic/parser/ResidenceTrackerParser.java
@@ -6,21 +6,26 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import seedu.address.logic.commands.AddBookingCommand;
import seedu.address.logic.commands.AddCommand;
import seedu.address.logic.commands.ClearCommand;
import seedu.address.logic.commands.Command;
+import seedu.address.logic.commands.DeleteBookingCommand;
import seedu.address.logic.commands.DeleteCommand;
+import seedu.address.logic.commands.EditBookingCommand;
import seedu.address.logic.commands.EditCommand;
import seedu.address.logic.commands.ExitCommand;
import seedu.address.logic.commands.FindCommand;
import seedu.address.logic.commands.HelpCommand;
import seedu.address.logic.commands.ListCommand;
+import seedu.address.logic.commands.RemindCommand;
+import seedu.address.logic.commands.StatusCommand;
import seedu.address.logic.parser.exceptions.ParseException;
/**
* Parses user input.
*/
-public class AddressBookParser {
+public class ResidenceTrackerParser {
/**
* Used for initial separation of command word and args.
@@ -47,12 +52,21 @@ public Command parseCommand(String userInput) throws ParseException {
case AddCommand.COMMAND_WORD:
return new AddCommandParser().parse(arguments);
+ case AddBookingCommand.COMMAND_WORD:
+ return new AddBookingCommandParser().parse(arguments);
+
case EditCommand.COMMAND_WORD:
return new EditCommandParser().parse(arguments);
+ case EditBookingCommand.COMMAND_WORD:
+ return new EditBookingCommandParser().parse(arguments);
+
case DeleteCommand.COMMAND_WORD:
return new DeleteCommandParser().parse(arguments);
+ case DeleteBookingCommand.COMMAND_WORD:
+ return new DeleteBookingCommandParser().parse(arguments);
+
case ClearCommand.COMMAND_WORD:
return new ClearCommand();
@@ -62,12 +76,18 @@ public Command parseCommand(String userInput) throws ParseException {
case ListCommand.COMMAND_WORD:
return new ListCommand();
+ case RemindCommand.COMMAND_WORD:
+ return new RemindCommand();
+
case ExitCommand.COMMAND_WORD:
return new ExitCommand();
case HelpCommand.COMMAND_WORD:
return new HelpCommand();
+ case StatusCommand.COMMAND_WORD:
+ return new StatusCommandParser().parse(arguments);
+
default:
throw new ParseException(MESSAGE_UNKNOWN_COMMAND);
}
diff --git a/src/main/java/seedu/address/logic/parser/StatusCommandParser.java b/src/main/java/seedu/address/logic/parser/StatusCommandParser.java
new file mode 100644
index 00000000000..fb71db3f762
--- /dev/null
+++ b/src/main/java/seedu/address/logic/parser/StatusCommandParser.java
@@ -0,0 +1,47 @@
+package seedu.address.logic.parser;
+
+import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
+import static seedu.address.logic.commands.StatusCommand.MESSAGE_NO_RESIDENCE;
+
+import java.util.ArrayList;
+
+import seedu.address.commons.core.index.Index;
+import seedu.address.logic.commands.StatusCommand;
+import seedu.address.logic.parser.exceptions.ParseException;
+
+/**
+ * Parses input arguments and creates a new StatusCommand object
+ */
+public class StatusCommandParser implements Parser {
+
+ /**
+ * Parses the given {@code String} of arguments in the context of the StatusCommand
+ * and returns an StatusCommand object for execution.
+ *
+ * @throws ParseException if the user input does not conform the expected format
+ */
+ public StatusCommand parse(String args) throws ParseException {
+ String trimmedArgs = args.trim();
+ if (trimmedArgs.isEmpty()) {
+ throw new ParseException(
+ String.format(MESSAGE_NO_RESIDENCE, StatusCommand.MESSAGE_USAGE));
+ }
+
+ String[] keyword = trimmedArgs.split("\\s+");
+ if (keyword.length < 2) {
+ throw new ParseException(
+ String.format(MESSAGE_INVALID_COMMAND_FORMAT, StatusCommand.MESSAGE_USAGE));
+ }
+ String status = keyword[0];
+ if (!(status.equals("clean") || status.equals("unclean"))) {
+ throw new ParseException(StatusCommand.MESSAGE_ERROR_STATUS);
+ }
+ ArrayList indexArray = new ArrayList<>();
+ for (int i = 1; i < keyword.length; i++) {
+ indexArray.add(ParserUtil.parseIndex(keyword[i]));
+ }
+
+ return new StatusCommand(indexArray, status);
+ }
+
+}
diff --git a/src/main/java/seedu/address/model/AddressBook.java b/src/main/java/seedu/address/model/AddressBook.java
deleted file mode 100644
index 1a943a0781a..00000000000
--- a/src/main/java/seedu/address/model/AddressBook.java
+++ /dev/null
@@ -1,120 +0,0 @@
-package seedu.address.model;
-
-import static java.util.Objects.requireNonNull;
-
-import java.util.List;
-
-import javafx.collections.ObservableList;
-import seedu.address.model.person.Person;
-import seedu.address.model.person.UniquePersonList;
-
-/**
- * Wraps all data at the address-book level
- * Duplicates are not allowed (by .isSamePerson comparison)
- */
-public class AddressBook implements ReadOnlyAddressBook {
-
- private final UniquePersonList persons;
-
- /*
- * The 'unusual' code block below is a non-static initialization block, sometimes used to avoid duplication
- * between constructors. See https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html
- *
- * Note that non-static init blocks are not recommended to use. There are other ways to avoid duplication
- * among constructors.
- */
- {
- persons = new UniquePersonList();
- }
-
- public AddressBook() {}
-
- /**
- * Creates an AddressBook using the Persons in the {@code toBeCopied}
- */
- public AddressBook(ReadOnlyAddressBook toBeCopied) {
- this();
- resetData(toBeCopied);
- }
-
- //// list overwrite operations
-
- /**
- * Replaces the contents of the person list with {@code persons}.
- * {@code persons} must not contain duplicate persons.
- */
- public void setPersons(List persons) {
- this.persons.setPersons(persons);
- }
-
- /**
- * Resets the existing data of this {@code AddressBook} with {@code newData}.
- */
- public void resetData(ReadOnlyAddressBook newData) {
- requireNonNull(newData);
-
- setPersons(newData.getPersonList());
- }
-
- //// person-level operations
-
- /**
- * Returns true if a person with the same identity as {@code person} exists in the address book.
- */
- public boolean hasPerson(Person person) {
- requireNonNull(person);
- return persons.contains(person);
- }
-
- /**
- * Adds a person to the address book.
- * The person must not already exist in the address book.
- */
- public void addPerson(Person p) {
- persons.add(p);
- }
-
- /**
- * Replaces the given person {@code target} in the list with {@code editedPerson}.
- * {@code target} must exist in the address book.
- * The person identity of {@code editedPerson} must not be the same as another existing person in the address book.
- */
- public void setPerson(Person target, Person editedPerson) {
- requireNonNull(editedPerson);
-
- persons.setPerson(target, editedPerson);
- }
-
- /**
- * Removes {@code key} from this {@code AddressBook}.
- * {@code key} must exist in the address book.
- */
- public void removePerson(Person key) {
- persons.remove(key);
- }
-
- //// util methods
-
- @Override
- public String toString() {
- return persons.asUnmodifiableObservableList().size() + " persons";
- // TODO: refine later
- }
-
- @Override
- public ObservableList getPersonList() {
- return persons.asUnmodifiableObservableList();
- }
-
- @Override
- public boolean equals(Object other) {
- return other == this // short circuit if same object
- || (other instanceof AddressBook // instanceof handles nulls
- && persons.equals(((AddressBook) other).persons));
- }
-
- @Override
- public int hashCode() {
- return persons.hashCode();
- }
-}
diff --git a/src/main/java/seedu/address/model/Model.java b/src/main/java/seedu/address/model/Model.java
index d54df471c1f..6abace90874 100644
--- a/src/main/java/seedu/address/model/Model.java
+++ b/src/main/java/seedu/address/model/Model.java
@@ -5,14 +5,15 @@
import javafx.collections.ObservableList;
import seedu.address.commons.core.GuiSettings;
-import seedu.address.model.person.Person;
+import seedu.address.model.residence.Residence;
/**
* The API of the Model component.
*/
public interface Model {
- /** {@code Predicate} that always evaluate to true */
- Predicate PREDICATE_SHOW_ALL_PERSONS = unused -> true;
+ /** {@code Predicate} that always evaluates to true */
+ Predicate PREDICATE_SHOW_ALL_RESIDENCES = unused -> true;
+ Predicate PREDICATE_UPCOMING_BOOKED_RESIDENCES = residence -> residence.hasUpcomingBooking();
/**
* Replaces user prefs data with the data in {@code userPrefs}.
@@ -35,53 +36,55 @@ public interface Model {
void setGuiSettings(GuiSettings guiSettings);
/**
- * Returns the user prefs' address book file path.
+ * Returns the user prefs' residence tracker file path.
*/
- Path getAddressBookFilePath();
+ Path getResidenceTrackerFilePath();
/**
- * Sets the user prefs' address book file path.
+ * Sets the user prefs' residence tracker file path.
*/
- void setAddressBookFilePath(Path addressBookFilePath);
+ void setResidenceTrackerFilePath(Path residenceTrackerFilePath);
/**
- * Replaces address book data with the data in {@code addressBook}.
+ * Replaces residence tracker data with the data in {@code residenceTracker}.
*/
- void setAddressBook(ReadOnlyAddressBook addressBook);
+ void setResidenceTracker(ReadOnlyResidenceTracker residenceTracker);
- /** Returns the AddressBook */
- ReadOnlyAddressBook getAddressBook();
+ /** Returns the ResidenceTracker */
+ ReadOnlyResidenceTracker getResidenceTracker();
/**
- * Returns true if a person with the same identity as {@code person} exists in the address book.
+ * Returns true if a residence with the same identity as {@code residence} exists in the residence tracker.
*/
- boolean hasPerson(Person person);
+ boolean hasResidence(Residence residence);
/**
- * Deletes the given person.
- * The person must exist in the address book.
+ * Deletes the given residence.
+ * The residence must exist in the residence tracker.
*/
- void deletePerson(Person target);
+ void deleteResidence(Residence target);
/**
- * Adds the given person.
- * {@code person} must not already exist in the address book.
+ * Adds the given residence.
+ * {@code residence} must not already exist in the residence tracker.
*/
- void addPerson(Person person);
+ void addResidence(Residence residence);
/**
- * Replaces the given person {@code target} with {@code editedPerson}.
- * {@code target} must exist in the address book.
- * The person identity of {@code editedPerson} must not be the same as another existing person in the address book.
+ * Replaces the given residence {@code target} with {@code editedResidence}.
+ * {@code target} must exist in the residence tracker.
+ * The residence identity of {@code editedResidence} must not be the same as another existing residence in the
+ * residence tracker.
*/
- void setPerson(Person target, Person editedPerson);
+ void setResidence(Residence target, Residence editedResidence);
- /** Returns an unmodifiable view of the filtered person list */
- ObservableList getFilteredPersonList();
+ /** Returns an unmodifiable view of the filtered residence list */
+ ObservableList getFilteredResidenceList();
/**
- * Updates the filter of the filtered person list to filter by the given {@code predicate}.
+ * Updates the filter of the filtered residence list to filter by the given {@code predicate}.
+ * The result of this method always sorts the Residences as described in the Residence's {@code compareTo} method.
* @throws NullPointerException if {@code predicate} is null.
*/
- void updateFilteredPersonList(Predicate predicate);
+ void updateFilteredResidenceList(Predicate predicate);
}
diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/seedu/address/model/ModelManager.java
index 0650c954f5c..1c08434b81b 100644
--- a/src/main/java/seedu/address/model/ModelManager.java
+++ b/src/main/java/seedu/address/model/ModelManager.java
@@ -11,34 +11,35 @@
import javafx.collections.transformation.FilteredList;
import seedu.address.commons.core.GuiSettings;
import seedu.address.commons.core.LogsCenter;
-import seedu.address.model.person.Person;
+import seedu.address.model.residence.Residence;
/**
- * Represents the in-memory model of the address book data.
+ * Represents the in-memory model of the residence tracker data.
*/
public class ModelManager implements Model {
private static final Logger logger = LogsCenter.getLogger(ModelManager.class);
- private final AddressBook addressBook;
+ private final ResidenceTracker residenceTracker;
private final UserPrefs userPrefs;
- private final FilteredList filteredPersons;
+ private final FilteredList filteredResidences;
/**
- * Initializes a ModelManager with the given addressBook and userPrefs.
+ * Initializes a ModelManager with the given {@code residenceTracker} and {@code userPrefs}.
*/
- public ModelManager(ReadOnlyAddressBook addressBook, ReadOnlyUserPrefs userPrefs) {
+ public ModelManager(ReadOnlyResidenceTracker residenceTracker, ReadOnlyUserPrefs userPrefs) {
super();
- requireAllNonNull(addressBook, userPrefs);
+ requireAllNonNull(residenceTracker, userPrefs);
- logger.fine("Initializing with address book: " + addressBook + " and user prefs " + userPrefs);
+ logger.fine("Initializing with residence tracker: " + residenceTracker + " and user prefs " + userPrefs);
- this.addressBook = new AddressBook(addressBook);
+ this.residenceTracker = new ResidenceTracker(residenceTracker);
this.userPrefs = new UserPrefs(userPrefs);
- filteredPersons = new FilteredList<>(this.addressBook.getPersonList());
+ filteredResidences = new FilteredList<>(this.residenceTracker.getResidenceList());
+
}
public ModelManager() {
- this(new AddressBook(), new UserPrefs());
+ this(new ResidenceTracker(), new UserPrefs());
}
//=========== UserPrefs ==================================================================================
@@ -66,67 +67,70 @@ public void setGuiSettings(GuiSettings guiSettings) {
}
@Override
- public Path getAddressBookFilePath() {
- return userPrefs.getAddressBookFilePath();
+ public Path getResidenceTrackerFilePath() {
+ return userPrefs.getResidenceTrackerFilePath();
}
@Override
- public void setAddressBookFilePath(Path addressBookFilePath) {
- requireNonNull(addressBookFilePath);
- userPrefs.setAddressBookFilePath(addressBookFilePath);
+ public void setResidenceTrackerFilePath(Path residenceTrackerFilePath) {
+ requireNonNull(residenceTrackerFilePath);
+ userPrefs.setResidenceTrackerFilePath(residenceTrackerFilePath);
}
- //=========== AddressBook ================================================================================
+ //=========== ResidenceTracker ===========================================================================
@Override
- public void setAddressBook(ReadOnlyAddressBook addressBook) {
- this.addressBook.resetData(addressBook);
+ public void setResidenceTracker(ReadOnlyResidenceTracker residenceTracker) {
+ this.residenceTracker.resetData(residenceTracker);
+ this.residenceTracker.sortResidenceList();
}
@Override
- public ReadOnlyAddressBook getAddressBook() {
- return addressBook;
+ public ReadOnlyResidenceTracker getResidenceTracker() {
+ return residenceTracker;
}
@Override
- public boolean hasPerson(Person person) {
- requireNonNull(person);
- return addressBook.hasPerson(person);
+ public boolean hasResidence(Residence residence) {
+ requireNonNull(residence);
+ return residenceTracker.hasResidence(residence);
}
@Override
- public void deletePerson(Person target) {
- addressBook.removePerson(target);
+ public void deleteResidence(Residence target) {
+ residenceTracker.removeResidence(target);
}
@Override
- public void addPerson(Person person) {
- addressBook.addPerson(person);
- updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
+ public void addResidence(Residence residence) {
+ residenceTracker.addResidence(residence);
+ updateFilteredResidenceList(PREDICATE_SHOW_ALL_RESIDENCES);
}
@Override
- public void setPerson(Person target, Person editedPerson) {
- requireAllNonNull(target, editedPerson);
-
- addressBook.setPerson(target, editedPerson);
+ public void setResidence(Residence target, Residence editedResidence) {
+ requireAllNonNull(target, editedResidence);
+ residenceTracker.setResidence(target, editedResidence);
}
- //=========== Filtered Person List Accessors =============================================================
+ //=========== Filtered Residence and Residence List Accessors ===============================================
/**
- * Returns an unmodifiable view of the list of {@code Person} backed by the internal list of
- * {@code versionedAddressBook}
+ * Returns an unmodifiable view of the list of {@code Residence}s backed by the internal list of
+ * {@code versionedResidenceTracker}
*/
@Override
- public ObservableList getFilteredPersonList() {
- return filteredPersons;
+ public ObservableList getFilteredResidenceList() {
+ return filteredResidences;
}
+
@Override
- public void updateFilteredPersonList(Predicate predicate) {
+ public void updateFilteredResidenceList(Predicate predicate) {
requireNonNull(predicate);
- filteredPersons.setPredicate(predicate);
+ filteredResidences.setPredicate(predicate);
+ logger.fine("Sorting filtered residence list");
+ residenceTracker.sortResidenceList();
}
@Override
@@ -143,9 +147,9 @@ public boolean equals(Object obj) {
// state check
ModelManager other = (ModelManager) obj;
- return addressBook.equals(other.addressBook)
+ return residenceTracker.equals(other.residenceTracker)
&& userPrefs.equals(other.userPrefs)
- && filteredPersons.equals(other.filteredPersons);
+ && filteredResidences.equals(other.filteredResidences);
}
}
diff --git a/src/main/java/seedu/address/model/ReadOnlyAddressBook.java b/src/main/java/seedu/address/model/ReadOnlyAddressBook.java
deleted file mode 100644
index 6ddc2cd9a29..00000000000
--- a/src/main/java/seedu/address/model/ReadOnlyAddressBook.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package seedu.address.model;
-
-import javafx.collections.ObservableList;
-import seedu.address.model.person.Person;
-
-/**
- * Unmodifiable view of an address book
- */
-public interface ReadOnlyAddressBook {
-
- /**
- * Returns an unmodifiable view of the persons list.
- * This list will not contain any duplicate persons.
- */
- ObservableList getPersonList();
-
-}
diff --git a/src/main/java/seedu/address/model/ReadOnlyResidenceTracker.java b/src/main/java/seedu/address/model/ReadOnlyResidenceTracker.java
new file mode 100644
index 00000000000..c7b03e38955
--- /dev/null
+++ b/src/main/java/seedu/address/model/ReadOnlyResidenceTracker.java
@@ -0,0 +1,17 @@
+package seedu.address.model;
+
+import javafx.collections.ObservableList;
+import seedu.address.model.residence.Residence;
+
+/**
+ * Unmodifiable view of a residence tracker.
+ */
+public interface ReadOnlyResidenceTracker {
+
+ /**
+ * Returns an unmodifiable view of the residence list.
+ * This list will not contain any duplicate residences.
+ */
+ ObservableList getResidenceList();
+
+}
diff --git a/src/main/java/seedu/address/model/ReadOnlyUserPrefs.java b/src/main/java/seedu/address/model/ReadOnlyUserPrefs.java
index befd58a4c73..e043b8cb30c 100644
--- a/src/main/java/seedu/address/model/ReadOnlyUserPrefs.java
+++ b/src/main/java/seedu/address/model/ReadOnlyUserPrefs.java
@@ -11,6 +11,6 @@ public interface ReadOnlyUserPrefs {
GuiSettings getGuiSettings();
- Path getAddressBookFilePath();
+ Path getResidenceTrackerFilePath();
}
diff --git a/src/main/java/seedu/address/model/ResidenceTracker.java b/src/main/java/seedu/address/model/ResidenceTracker.java
new file mode 100644
index 00000000000..6ae3c282133
--- /dev/null
+++ b/src/main/java/seedu/address/model/ResidenceTracker.java
@@ -0,0 +1,129 @@
+package seedu.address.model;
+
+import static java.util.Objects.requireNonNull;
+
+import java.util.List;
+
+import javafx.collections.ObservableList;
+import seedu.address.model.residence.Residence;
+import seedu.address.model.residence.UniqueResidenceList;
+
+/**
+ * Wraps all data at the residence-tracker level
+ * Duplicates are not allowed (by .isSameResidence comparison)
+ */
+public class ResidenceTracker implements ReadOnlyResidenceTracker {
+
+ private final UniqueResidenceList residences;
+
+ /*
+ * The 'unusual' code block below is a non-static initialization block, sometimes used to avoid duplication
+ * between constructors. See https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html
+ *
+ * Note that non-static init blocks are not recommended to use. There are other ways to avoid duplication
+ * among constructors.
+ */
+ {
+ residences = new UniqueResidenceList();
+ }
+
+ public ResidenceTracker() {}
+
+ /**
+ * Creates a ResidenceTracker using the Residences in the {@code toBeCopied}
+ */
+
+ public ResidenceTracker(ReadOnlyResidenceTracker toBeCopied) {
+ this();
+ resetData(toBeCopied);
+ }
+
+ //// list overwrite operations
+
+ /**
+ * Replaces the contents of the residence list with {@code residences}.
+ * {@code residences} must not contain duplicate residences.
+ */
+ public void setResidences(List residences) {
+ this.residences.setResidences(residences);
+ }
+
+ /**
+ * Resets the existing data of this {@code ResidenceTracker} with {@code newData}.
+ */
+ public void resetData(ReadOnlyResidenceTracker newData) {
+ requireNonNull(newData);
+
+ setResidences(newData.getResidenceList());
+ }
+
+ //// residence-level operations
+
+ /**
+ * Returns true if a residence with the same identity as {@code residence} exists in the residence tracker.
+ */
+ public boolean hasResidence(Residence residence) {
+ requireNonNull(residence);
+ return residences.contains(residence);
+ }
+
+ /**
+ * Adds the given residence to the residence tracker.
+ * The residence must not already exist in the residence tracker.
+ */
+ public void addResidence(Residence r) {
+ residences.add(r);
+ }
+
+ /**
+ * Replaces the given residence {@code target} in the list with {@code editedResidence}.
+ * {@code target} must exist in the residence tracker.
+ * The residence identity of {@code editedResidence} must not be the same as another existing residence
+ * in the residence tracker.
+ */
+ public void setResidence(Residence target, Residence editedResidence) {
+ requireNonNull(editedResidence);
+
+ residences.setResidence(target, editedResidence);
+ }
+
+ /**
+ * Removes the Residence {@code key} from this {@code ResidenceTracker}.
+ * {@code key} must exist in the residence tracker.
+ */
+ public void removeResidence(Residence key) {
+ residences.remove(key);
+ }
+
+ /**
+ * Sorts the Residences in this {@code ResidenceTracker}
+ * as described in the Residence's {@code compareTo} method.
+ */
+ public void sortResidenceList() {
+ residences.sortUnmodifiableObservableList();
+ }
+
+ //// util methods
+
+ @Override
+ public String toString() {
+ return residences.asUnmodifiableObservableList().size() + " residences";
+ }
+
+ @Override
+ public ObservableList getResidenceList() {
+ return residences.asUnmodifiableObservableList();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ return other == this // short circuit if same object
+ || (other instanceof ResidenceTracker // instanceof handles nulls
+ && residences.equals(((ResidenceTracker) other).residences));
+ }
+
+ @Override
+ public int hashCode() {
+ return residences.hashCode();
+ }
+}
diff --git a/src/main/java/seedu/address/model/UserPrefs.java b/src/main/java/seedu/address/model/UserPrefs.java
index 25a5fd6eab9..784e49afb03 100644
--- a/src/main/java/seedu/address/model/UserPrefs.java
+++ b/src/main/java/seedu/address/model/UserPrefs.java
@@ -14,7 +14,7 @@
public class UserPrefs implements ReadOnlyUserPrefs {
private GuiSettings guiSettings = new GuiSettings();
- private Path addressBookFilePath = Paths.get("data" , "addressbook.json");
+ private Path residenceTrackerFilePath = Paths.get("data" , "residencetracker.json");
/**
* Creates a {@code UserPrefs} with default values.
@@ -35,7 +35,7 @@ public UserPrefs(ReadOnlyUserPrefs userPrefs) {
public void resetData(ReadOnlyUserPrefs newUserPrefs) {
requireNonNull(newUserPrefs);
setGuiSettings(newUserPrefs.getGuiSettings());
- setAddressBookFilePath(newUserPrefs.getAddressBookFilePath());
+ setResidenceTrackerFilePath(newUserPrefs.getResidenceTrackerFilePath());
}
public GuiSettings getGuiSettings() {
@@ -47,13 +47,13 @@ public void setGuiSettings(GuiSettings guiSettings) {
this.guiSettings = guiSettings;
}
- public Path getAddressBookFilePath() {
- return addressBookFilePath;
+ public Path getResidenceTrackerFilePath() {
+ return residenceTrackerFilePath;
}
- public void setAddressBookFilePath(Path addressBookFilePath) {
- requireNonNull(addressBookFilePath);
- this.addressBookFilePath = addressBookFilePath;
+ public void setResidenceTrackerFilePath(Path residenceTrackerFilePath) {
+ requireNonNull(residenceTrackerFilePath);
+ this.residenceTrackerFilePath = residenceTrackerFilePath;
}
@Override
@@ -68,19 +68,19 @@ public boolean equals(Object other) {
UserPrefs o = (UserPrefs) other;
return guiSettings.equals(o.guiSettings)
- && addressBookFilePath.equals(o.addressBookFilePath);
+ && residenceTrackerFilePath.equals(o.residenceTrackerFilePath);
}
@Override
public int hashCode() {
- return Objects.hash(guiSettings, addressBookFilePath);
+ return Objects.hash(guiSettings, residenceTrackerFilePath);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Gui Settings : " + guiSettings);
- sb.append("\nLocal data file location : " + addressBookFilePath);
+ sb.append("\nLocal data file location : " + residenceTrackerFilePath);
return sb.toString();
}
diff --git a/src/main/java/seedu/address/model/booking/Booking.java b/src/main/java/seedu/address/model/booking/Booking.java
new file mode 100644
index 00000000000..6b93c6190fc
--- /dev/null
+++ b/src/main/java/seedu/address/model/booking/Booking.java
@@ -0,0 +1,121 @@
+package seedu.address.model.booking;
+
+import static seedu.address.commons.util.CollectionUtil.requireAllNonNull;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.Objects;
+
+/**
+ * Represents a Booking in residence tracker.
+ * Guarantees: details are present and not null, field values are validated, immutable.
+ */
+public class Booking implements Comparable {
+
+ public static final String MESSAGE_CONSTRAINTS = "Bookings should be of the format n/PERSON_NAME p/PERSON_PHONE "
+ + "s/BOOKING_START_DATE e/BOOKING_END_DATE and adhere to the following constraints:\n"
+ + "1. Names should only contain alphanumeric characters and spaces, and they should not be blank. "
+ + "2. Phone numbers should only contain numbers, and they should be at least 3 digits long. "
+ + "The start and end dates must adhere to the following:\n"
+ + " - be of the format DD-MM-YYYY\n"
+ + " - end date must be after start date";
+
+ private final TenantName tenantName;
+ private final Phone phone;
+ private final BookingTime bookingTime;
+ private final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd-MM-uuuu");
+
+ /**
+ * Every field must be present and not null.
+ */
+ public Booking(TenantName tenantName, Phone phone, LocalDate start, LocalDate end) {
+ requireAllNonNull(tenantName, phone, start, end);
+ this.tenantName = tenantName;
+ this.phone = phone;
+ this.bookingTime = new BookingTime(start, end);
+ }
+
+ public TenantName getTenantName() {
+ return tenantName;
+ }
+
+ public Phone getPhone() {
+ return phone;
+ }
+
+ public BookingTime getBookingTime() {
+ return bookingTime;
+ }
+
+ public LocalDate getStart() {
+ return bookingTime.getStart();
+ }
+
+ public LocalDate getEnd() {
+ return bookingTime.getEnd();
+ }
+
+ /**
+ * Returns if a given booking is a valid booking.
+ */
+ public static boolean isValidBookingTime(LocalDate start, LocalDate end) {
+ return BookingTime.isValidBookingTime(start, end);
+ }
+
+ /**
+ * Returns true if both bookings have the same name, phone, start and end dates.
+ * This defines a stronger notion of equality between two bookings.
+ */
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ if (!(other instanceof Booking)) {
+ return false;
+ }
+
+ Booking otherBooking = (Booking) other;
+ return otherBooking.getTenantName().equals(getTenantName())
+ && otherBooking.getPhone().equals(getPhone())
+ && otherBooking.getBookingTime().equals(getBookingTime());
+ }
+
+ @Override
+ public int hashCode() {
+ // use this method for custom fields hashing instead of implementing your own
+ return Objects.hash(tenantName, phone, bookingTime);
+ }
+
+ /**
+ * Comparator of bookings to reflect chronological order.
+ * Bookings on earlier dates come before booking on later dates.
+ */
+ @Override
+ public int compareTo(Booking otherBooking) {
+ return this.bookingTime.compareTo(otherBooking.getBookingTime());
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(getTenantName())
+ .append("; Phone: ")
+ .append(getPhone())
+ .append("; Start: ")
+ .append(getStart().format(dateTimeFormatter))
+ .append("; End: ")
+ .append(getEnd().format(dateTimeFormatter));
+
+ return builder.toString();
+ }
+
+ /**
+ * Returns true if booking time of this Booking overlaps with another Booking's booking time.
+ */
+ public boolean doesOverlap(Booking otherBooking) {
+ return this.getBookingTime().doesOverlap(otherBooking.getBookingTime());
+ }
+
+}
diff --git a/src/main/java/seedu/address/model/booking/BookingTime.java b/src/main/java/seedu/address/model/booking/BookingTime.java
new file mode 100644
index 00000000000..c37be945431
--- /dev/null
+++ b/src/main/java/seedu/address/model/booking/BookingTime.java
@@ -0,0 +1,83 @@
+package seedu.address.model.booking;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.Objects;
+
+/**
+ * Represents a BookingTime of a Booking in residence tracker.
+ * Guarantees: details are present and not null, field values are validated, immutable.
+ */
+public class BookingTime {
+ private final LocalDate start;
+ private final LocalDate end;
+ private final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd-MM-uuuu");
+
+ /**
+ * initialize a booking Time
+ */
+ public BookingTime(LocalDate start, LocalDate end) {
+ this.start = start;
+ this.end = end;
+ }
+
+ public LocalDate getStart() {
+ return start;
+ }
+
+ public LocalDate getEnd() {
+ return end;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ if (!(other instanceof BookingTime)) {
+ return false;
+ }
+
+ BookingTime otherBookingTime = (BookingTime) other;
+ return otherBookingTime.getStart().equals(getStart())
+ && otherBookingTime.getEnd().equals(getEnd());
+ }
+
+ public static boolean isValidBookingTime(LocalDate start, LocalDate end) {
+ return !end.isBefore(start);
+ }
+
+ /**
+ * Comparator of {@code BookingTime}s by chronological order.
+ */
+ public int compareTo(BookingTime otherBookingTime) {
+ if (this.getStart().isBefore(otherBookingTime.getStart())) {
+ return -1;
+ } else if (this.getStart().isAfter(otherBookingTime.getStart())) {
+ return 1;
+ }
+ return 0;
+ }
+
+ @Override
+ public int hashCode() {
+ // use this method for custom fields hashing instead of implementing your own
+ return Objects.hash(start, end);
+ }
+
+ /**
+ * Returns true if bookingTime overlaps with another bookingTime.
+ * This happens if the start and end dates are not
+ * before the start date of the other booking time
+ * or after the end date of the other booking time.
+ */
+ public boolean doesOverlap(BookingTime otherBookingTime) {
+ boolean isBeforeOtherBooking = this.getEnd().isBefore(otherBookingTime.getStart());
+ boolean isAfterOtherBooking = this.getStart().isAfter(otherBookingTime.getEnd());
+
+ return !(isBeforeOtherBooking || isAfterOtherBooking);
+ }
+
+}
+
diff --git a/src/main/java/seedu/address/model/person/NameContainsKeywordsPredicate.java b/src/main/java/seedu/address/model/booking/NameContainsKeywordsPredicate.java
similarity index 75%
rename from src/main/java/seedu/address/model/person/NameContainsKeywordsPredicate.java
rename to src/main/java/seedu/address/model/booking/NameContainsKeywordsPredicate.java
index c9b5868427c..0d36457d7ba 100644
--- a/src/main/java/seedu/address/model/person/NameContainsKeywordsPredicate.java
+++ b/src/main/java/seedu/address/model/booking/NameContainsKeywordsPredicate.java
@@ -1,4 +1,4 @@
-package seedu.address.model.person;
+package seedu.address.model.booking;
import java.util.List;
import java.util.function.Predicate;
@@ -6,9 +6,10 @@
import seedu.address.commons.util.StringUtil;
/**
- * Tests that a {@code Person}'s {@code Name} matches any of the keywords given.
+ * Tests that a Booking's {@code TenantName} matches any of the keywords given.
+ * Search is not case sensitive.
*/
-public class NameContainsKeywordsPredicate implements Predicate {
+public class NameContainsKeywordsPredicate implements Predicate {
private final List keywords;
public NameContainsKeywordsPredicate(List keywords) {
@@ -16,9 +17,9 @@ public NameContainsKeywordsPredicate(List keywords) {
}
@Override
- public boolean test(Person person) {
+ public boolean test(Booking person) {
return keywords.stream()
- .anyMatch(keyword -> StringUtil.containsWordIgnoreCase(person.getName().fullName, keyword));
+ .anyMatch(keyword -> StringUtil.containsWordIgnoreCase(person.getTenantName().toString(), keyword));
}
@Override
diff --git a/src/main/java/seedu/address/model/person/Phone.java b/src/main/java/seedu/address/model/booking/Phone.java
similarity index 92%
rename from src/main/java/seedu/address/model/person/Phone.java
rename to src/main/java/seedu/address/model/booking/Phone.java
index 872c76b382f..6d0c3db4810 100644
--- a/src/main/java/seedu/address/model/person/Phone.java
+++ b/src/main/java/seedu/address/model/booking/Phone.java
@@ -1,10 +1,10 @@
-package seedu.address.model.person;
+package seedu.address.model.booking;
import static java.util.Objects.requireNonNull;
import static seedu.address.commons.util.AppUtil.checkArgument;
/**
- * Represents a Person's phone number in the address book.
+ * Represents a Booking's phone number in the residence tracker.
* Guarantees: immutable; is valid as declared in {@link #isValidPhone(String)}
*/
public class Phone {
diff --git a/src/main/java/seedu/address/model/person/Name.java b/src/main/java/seedu/address/model/booking/TenantName.java
similarity index 61%
rename from src/main/java/seedu/address/model/person/Name.java
rename to src/main/java/seedu/address/model/booking/TenantName.java
index 79244d71cf7..12391f8fe4d 100644
--- a/src/main/java/seedu/address/model/person/Name.java
+++ b/src/main/java/seedu/address/model/booking/TenantName.java
@@ -1,31 +1,31 @@
-package seedu.address.model.person;
+package seedu.address.model.booking;
import static java.util.Objects.requireNonNull;
import static seedu.address.commons.util.AppUtil.checkArgument;
+import seedu.address.model.name.CommonName;
+
/**
- * Represents a Person's name in the address book.
+ * Represents the TenantName of a tenant who made a booking.
* Guarantees: immutable; is valid as declared in {@link #isValidName(String)}
*/
-public class Name {
+public class TenantName extends CommonName {
public static final String MESSAGE_CONSTRAINTS =
"Names should only contain alphanumeric characters and spaces, and it should not be blank";
/*
- * The first character of the address must not be a whitespace,
+ * The first character of the Residence's name must not be a whitespace,
* otherwise " " (a blank string) becomes a valid input.
*/
public static final String VALIDATION_REGEX = "[\\p{Alnum}][\\p{Alnum} ]*";
- public final String fullName;
-
/**
- * Constructs a {@code Name}.
+ * Constructs a {@code TenantName}.
*
- * @param name A valid name.
+ * @param name A valid tenant name.
*/
- public Name(String name) {
+ public TenantName(String name) {
requireNonNull(name);
checkArgument(isValidName(name), MESSAGE_CONSTRAINTS);
fullName = name;
@@ -38,22 +38,13 @@ public static boolean isValidName(String test) {
return test.matches(VALIDATION_REGEX);
}
-
- @Override
- public String toString() {
- return fullName;
- }
-
@Override
public boolean equals(Object other) {
return other == this // short circuit if same object
- || (other instanceof Name // instanceof handles nulls
- && fullName.equals(((Name) other).fullName)); // state check
+ || (other instanceof TenantName // instanceof handles nulls
+ && fullName.equals(((TenantName) other).fullName)); // state check
}
- @Override
- public int hashCode() {
- return fullName.hashCode();
- }
+
}
diff --git a/src/main/java/seedu/address/model/booking/exceptions/BookingNotFoundException.java b/src/main/java/seedu/address/model/booking/exceptions/BookingNotFoundException.java
new file mode 100644
index 00000000000..e617d616fbd
--- /dev/null
+++ b/src/main/java/seedu/address/model/booking/exceptions/BookingNotFoundException.java
@@ -0,0 +1,6 @@
+package seedu.address.model.booking.exceptions;
+
+/**
+ * Signals that the operation is unable to find the specified booking.
+ */
+public class BookingNotFoundException extends RuntimeException {}
diff --git a/src/main/java/seedu/address/model/booking/exceptions/DuplicateBookingException.java b/src/main/java/seedu/address/model/booking/exceptions/DuplicateBookingException.java
new file mode 100644
index 00000000000..7e52818714b
--- /dev/null
+++ b/src/main/java/seedu/address/model/booking/exceptions/DuplicateBookingException.java
@@ -0,0 +1,11 @@
+package seedu.address.model.booking.exceptions;
+
+/**
+ * Signals that the operation will result in duplicate Bookings (Bookings are considered duplicates if they have the
+ * same identity).
+ */
+public class DuplicateBookingException extends RuntimeException {
+ public DuplicateBookingException() {
+ super("Operation would result in duplicate bookings");
+ }
+}
diff --git a/src/main/java/seedu/address/model/booking/exceptions/OverlappingBookingException.java b/src/main/java/seedu/address/model/booking/exceptions/OverlappingBookingException.java
new file mode 100644
index 00000000000..5658a6140e9
--- /dev/null
+++ b/src/main/java/seedu/address/model/booking/exceptions/OverlappingBookingException.java
@@ -0,0 +1,11 @@
+package seedu.address.model.booking.exceptions;
+
+/**
+ * Signals that the operation will result in overlapping Bookings for a Residence
+ * (Bookings are considered overlapping if they have overlapping booking times).
+ */
+public class OverlappingBookingException extends RuntimeException {
+ public OverlappingBookingException() {
+ super("Operation would result in overlapping bookings");
+ }
+}
diff --git a/src/main/java/seedu/address/model/name/CommonName.java b/src/main/java/seedu/address/model/name/CommonName.java
new file mode 100644
index 00000000000..e6b586bd4ad
--- /dev/null
+++ b/src/main/java/seedu/address/model/name/CommonName.java
@@ -0,0 +1,28 @@
+package seedu.address.model.name;
+
+public class CommonName {
+ protected String fullName;
+
+ /**
+ * Returns {@code String} representation of this {@code CommonName}.
+ */
+ @Override
+ public String toString() {
+ return fullName;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ return other == this // short circuit if same object
+ || (other instanceof CommonName // instanceof handles nulls
+ && fullName.equals(((CommonName) other).fullName)); // state check
+ }
+
+ /**
+ * Returns hashCode of this {@code CommonName}.
+ */
+ @Override
+ public int hashCode() {
+ return fullName.hashCode();
+ }
+}
diff --git a/src/main/java/seedu/address/model/person/Email.java b/src/main/java/seedu/address/model/person/Email.java
deleted file mode 100644
index a5bbe0b6a5f..00000000000
--- a/src/main/java/seedu/address/model/person/Email.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package seedu.address.model.person;
-
-import static java.util.Objects.requireNonNull;
-import static seedu.address.commons.util.AppUtil.checkArgument;
-
-/**
- * Represents a Person's email in the address book.
- * Guarantees: immutable; is valid as declared in {@link #isValidEmail(String)}
- */
-public class Email {
-
- private static final String SPECIAL_CHARACTERS = "!#$%&'*+/=?`{|}~^.-";
- public static final String MESSAGE_CONSTRAINTS = "Emails should be of the format local-part@domain "
- + "and adhere to the following constraints:\n"
- + "1. The local-part should only contain alphanumeric characters and these special characters, excluding "
- + "the parentheses, (" + SPECIAL_CHARACTERS + ") .\n"
- + "2. This is followed by a '@' and then a domain name. "
- + "The domain name must:\n"
- + " - be at least 2 characters long\n"
- + " - start and end with alphanumeric characters\n"
- + " - consist of alphanumeric characters, a period or a hyphen for the characters in between, if any.";
- // alphanumeric and special characters
- private static final String LOCAL_PART_REGEX = "^[\\w" + SPECIAL_CHARACTERS + "]+";
- private static final String DOMAIN_FIRST_CHARACTER_REGEX = "[^\\W_]"; // alphanumeric characters except underscore
- private static final String DOMAIN_MIDDLE_REGEX = "[a-zA-Z0-9.-]*"; // alphanumeric, period and hyphen
- private static final String DOMAIN_LAST_CHARACTER_REGEX = "[^\\W_]$";
- public static final String VALIDATION_REGEX = LOCAL_PART_REGEX + "@"
- + DOMAIN_FIRST_CHARACTER_REGEX + DOMAIN_MIDDLE_REGEX + DOMAIN_LAST_CHARACTER_REGEX;
-
- public final String value;
-
- /**
- * Constructs an {@code Email}.
- *
- * @param email A valid email address.
- */
- public Email(String email) {
- requireNonNull(email);
- checkArgument(isValidEmail(email), MESSAGE_CONSTRAINTS);
- value = email;
- }
-
- /**
- * Returns if a given string is a valid email.
- */
- public static boolean isValidEmail(String test) {
- return test.matches(VALIDATION_REGEX);
- }
-
- @Override
- public String toString() {
- return value;
- }
-
- @Override
- public boolean equals(Object other) {
- return other == this // short circuit if same object
- || (other instanceof Email // instanceof handles nulls
- && value.equals(((Email) other).value)); // state check
- }
-
- @Override
- public int hashCode() {
- return value.hashCode();
- }
-
-}
diff --git a/src/main/java/seedu/address/model/person/Person.java b/src/main/java/seedu/address/model/person/Person.java
deleted file mode 100644
index 8ff1d83fe89..00000000000
--- a/src/main/java/seedu/address/model/person/Person.java
+++ /dev/null
@@ -1,123 +0,0 @@
-package seedu.address.model.person;
-
-import static seedu.address.commons.util.CollectionUtil.requireAllNonNull;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Objects;
-import java.util.Set;
-
-import seedu.address.model.tag.Tag;
-
-/**
- * Represents a Person in the address book.
- * Guarantees: details are present and not null, field values are validated, immutable.
- */
-public class Person {
-
- // Identity fields
- private final Name name;
- private final Phone phone;
- private final Email email;
-
- // Data fields
- private final Address address;
- private final Set tags = new HashSet<>();
-
- /**
- * Every field must be present and not null.
- */
- public Person(Name name, Phone phone, Email email, Address address, Set tags) {
- requireAllNonNull(name, phone, email, address, tags);
- this.name = name;
- this.phone = phone;
- this.email = email;
- this.address = address;
- this.tags.addAll(tags);
- }
-
- public Name getName() {
- return name;
- }
-
- public Phone getPhone() {
- return phone;
- }
-
- public Email getEmail() {
- return email;
- }
-
- public Address getAddress() {
- return address;
- }
-
- /**
- * Returns an immutable tag set, which throws {@code UnsupportedOperationException}
- * if modification is attempted.
- */
- public Set getTags() {
- return Collections.unmodifiableSet(tags);
- }
-
- /**
- * Returns true if both persons have the same name.
- * This defines a weaker notion of equality between two persons.
- */
- public boolean isSamePerson(Person otherPerson) {
- if (otherPerson == this) {
- return true;
- }
-
- return otherPerson != null
- && otherPerson.getName().equals(getName());
- }
-
- /**
- * Returns true if both persons have the same identity and data fields.
- * This defines a stronger notion of equality between two persons.
- */
- @Override
- public boolean equals(Object other) {
- if (other == this) {
- return true;
- }
-
- if (!(other instanceof Person)) {
- return false;
- }
-
- Person otherPerson = (Person) other;
- return otherPerson.getName().equals(getName())
- && otherPerson.getPhone().equals(getPhone())
- && otherPerson.getEmail().equals(getEmail())
- && otherPerson.getAddress().equals(getAddress())
- && otherPerson.getTags().equals(getTags());
- }
-
- @Override
- public int hashCode() {
- // use this method for custom fields hashing instead of implementing your own
- return Objects.hash(name, phone, email, address, tags);
- }
-
- @Override
- public String toString() {
- final StringBuilder builder = new StringBuilder();
- builder.append(getName())
- .append("; Phone: ")
- .append(getPhone())
- .append("; Email: ")
- .append(getEmail())
- .append("; Address: ")
- .append(getAddress());
-
- Set tags = getTags();
- if (!tags.isEmpty()) {
- builder.append("; Tags: ");
- tags.forEach(builder::append);
- }
- return builder.toString();
- }
-
-}
diff --git a/src/main/java/seedu/address/model/person/UniquePersonList.java b/src/main/java/seedu/address/model/person/UniquePersonList.java
deleted file mode 100644
index 0fee4fe57e6..00000000000
--- a/src/main/java/seedu/address/model/person/UniquePersonList.java
+++ /dev/null
@@ -1,137 +0,0 @@
-package seedu.address.model.person;
-
-import static java.util.Objects.requireNonNull;
-import static seedu.address.commons.util.CollectionUtil.requireAllNonNull;
-
-import java.util.Iterator;
-import java.util.List;
-
-import javafx.collections.FXCollections;
-import javafx.collections.ObservableList;
-import seedu.address.model.person.exceptions.DuplicatePersonException;
-import seedu.address.model.person.exceptions.PersonNotFoundException;
-
-/**
- * A list of persons that enforces uniqueness between its elements and does not allow nulls.
- * A person is considered unique by comparing using {@code Person#isSamePerson(Person)}. As such, adding and updating of
- * persons uses Person#isSamePerson(Person) for equality so as to ensure that the person being added or updated is
- * unique in terms of identity in the UniquePersonList. However, the removal of a person uses Person#equals(Object) so
- * as to ensure that the person with exactly the same fields will be removed.
- *
- * Supports a minimal set of list operations.
- *
- * @see Person#isSamePerson(Person)
- */
-public class UniquePersonList implements Iterable {
-
- private final ObservableList internalList = FXCollections.observableArrayList();
- private final ObservableList internalUnmodifiableList =
- FXCollections.unmodifiableObservableList(internalList);
-
- /**
- * Returns true if the list contains an equivalent person as the given argument.
- */
- public boolean contains(Person toCheck) {
- requireNonNull(toCheck);
- return internalList.stream().anyMatch(toCheck::isSamePerson);
- }
-
- /**
- * Adds a person to the list.
- * The person must not already exist in the list.
- */
- public void add(Person toAdd) {
- requireNonNull(toAdd);
- if (contains(toAdd)) {
- throw new DuplicatePersonException();
- }
- internalList.add(toAdd);
- }
-
- /**
- * Replaces the person {@code target} in the list with {@code editedPerson}.
- * {@code target} must exist in the list.
- * The person identity of {@code editedPerson} must not be the same as another existing person in the list.
- */
- public void setPerson(Person target, Person editedPerson) {
- requireAllNonNull(target, editedPerson);
-
- int index = internalList.indexOf(target);
- if (index == -1) {
- throw new PersonNotFoundException();
- }
-
- if (!target.isSamePerson(editedPerson) && contains(editedPerson)) {
- throw new DuplicatePersonException();
- }
-
- internalList.set(index, editedPerson);
- }
-
- /**
- * Removes the equivalent person from the list.
- * The person must exist in the list.
- */
- public void remove(Person toRemove) {
- requireNonNull(toRemove);
- if (!internalList.remove(toRemove)) {
- throw new PersonNotFoundException();
- }
- }
-
- public void setPersons(UniquePersonList replacement) {
- requireNonNull(replacement);
- internalList.setAll(replacement.internalList);
- }
-
- /**
- * Replaces the contents of this list with {@code persons}.
- * {@code persons} must not contain duplicate persons.
- */
- public void setPersons(List persons) {
- requireAllNonNull(persons);
- if (!personsAreUnique(persons)) {
- throw new DuplicatePersonException();
- }
-
- internalList.setAll(persons);
- }
-
- /**
- * Returns the backing list as an unmodifiable {@code ObservableList}.
- */
- public ObservableList asUnmodifiableObservableList() {
- return internalUnmodifiableList;
- }
-
- @Override
- public Iterator iterator() {
- return internalList.iterator();
- }
-
- @Override
- public boolean equals(Object other) {
- return other == this // short circuit if same object
- || (other instanceof UniquePersonList // instanceof handles nulls
- && internalList.equals(((UniquePersonList) other).internalList));
- }
-
- @Override
- public int hashCode() {
- return internalList.hashCode();
- }
-
- /**
- * Returns true if {@code persons} contains only unique persons.
- */
- private boolean personsAreUnique(List persons) {
- for (int i = 0; i < persons.size() - 1; i++) {
- for (int j = i + 1; j < persons.size(); j++) {
- if (persons.get(i).isSamePerson(persons.get(j))) {
- return false;
- }
- }
- }
- return true;
- }
-}
diff --git a/src/main/java/seedu/address/model/person/exceptions/DuplicatePersonException.java b/src/main/java/seedu/address/model/person/exceptions/DuplicatePersonException.java
deleted file mode 100644
index d7290f59442..00000000000
--- a/src/main/java/seedu/address/model/person/exceptions/DuplicatePersonException.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package seedu.address.model.person.exceptions;
-
-/**
- * Signals that the operation will result in duplicate Persons (Persons are considered duplicates if they have the same
- * identity).
- */
-public class DuplicatePersonException extends RuntimeException {
- public DuplicatePersonException() {
- super("Operation would result in duplicate persons");
- }
-}
diff --git a/src/main/java/seedu/address/model/person/exceptions/PersonNotFoundException.java b/src/main/java/seedu/address/model/person/exceptions/PersonNotFoundException.java
deleted file mode 100644
index fa764426ca7..00000000000
--- a/src/main/java/seedu/address/model/person/exceptions/PersonNotFoundException.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package seedu.address.model.person.exceptions;
-
-/**
- * Signals that the operation is unable to find the specified person.
- */
-public class PersonNotFoundException extends RuntimeException {}
diff --git a/src/main/java/seedu/address/model/residence/BookingList.java b/src/main/java/seedu/address/model/residence/BookingList.java
new file mode 100644
index 00000000000..53912f15151
--- /dev/null
+++ b/src/main/java/seedu/address/model/residence/BookingList.java
@@ -0,0 +1,214 @@
+package seedu.address.model.residence;
+
+import static java.util.Objects.requireNonNull;
+import static seedu.address.commons.util.CollectionUtil.requireAllNonNull;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.logging.Logger;
+
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import seedu.address.commons.core.LogsCenter;
+import seedu.address.model.booking.Booking;
+import seedu.address.model.booking.exceptions.BookingNotFoundException;
+import seedu.address.model.booking.exceptions.OverlappingBookingException;
+
+/**
+ * A list of bookings that enforces no overlapping between its elements and does not allow nulls.
+ * A booking is considered non-overlapping by comparing using {@code Booking#doesOverlap(Booking)}. As such, adding and
+ * updating of bookings uses Booking#doesOverlap(Booking) so as to ensure that the booking being added or
+ * updated does not overlap in timing with another booking in the UniqueBookingList. However, the removal of a booking
+ * uses Booking#equals(Object) so as to ensure that the booking with exactly the same fields will be removed.
+ * Supports a minimal set of list operations.
+ *
+ * @see Booking#doesOverlap(Booking)
+ *
+ * Note: All operations that modify the contents of the {@code interalList} will return the sorted list
+ * as described in {@code Booking}'s {@code compareTo} method.
+ *
+ * @see Booking#compareTo(Booking)
+ */
+public class BookingList implements Iterable {
+ //@@author Soorya
+ private static final Logger logger = LogsCenter.getLogger(BookingList.class);
+
+ //@@author Li Gang
+ private final ObservableList internalList = FXCollections.observableArrayList();
+ private final ObservableList internalUnmodifiableList =
+ FXCollections.unmodifiableObservableList(internalList);
+
+ //@@author Soorya
+ public BookingList() {}
+
+ public BookingList(List residenceBookingList) {
+ setBookings(residenceBookingList);
+ }
+
+ public BookingList(BookingList residenceBookingList) {
+ resetBookings(residenceBookingList);
+ }
+
+ //@@author Li Gang
+ /**
+ * Returns true if the list contains a booking which overlaps with the given argument.
+ */
+ public boolean contains(Booking toCheck) {
+ requireNonNull(toCheck);
+ return internalList.stream().anyMatch(toCheck::doesOverlap);
+ }
+
+ /**
+ * Checks if edited Booking overlaps with any other bookings in the current booking list.
+ */
+ public boolean containsExclude(Booking toExclude, Booking toCheck) {
+ requireNonNull(toCheck);
+ ObservableList copyOfInternalList = FXCollections.observableArrayList();
+ Iterator iterator = internalList.iterator();
+ while (iterator.hasNext()) {
+ copyOfInternalList.add(iterator.next());
+ }
+ copyOfInternalList.remove(toExclude);
+ return copyOfInternalList.stream().anyMatch(toCheck::doesOverlap);
+ }
+
+ /**
+ * Adds a booking to the list.
+ * The booking must not overlap with another booking which already exists in the list.
+ * Returns a sorted booking list.
+ */
+ public void add(Booking toAdd) {
+ requireNonNull(toAdd);
+ if (contains(toAdd)) {
+ throw new OverlappingBookingException();
+ }
+ internalList.add(toAdd);
+ logger.fine("Sorting the booking list.");
+ sortBookingList();
+ }
+
+ /**
+ * Replaces the booking {@code target} in the list with {@code editedBooking}.
+ * {@code target} must exist in the list.
+ * The booking identity of {@code editedBooking} must not overlap with another existing booking in the list.
+ * Returns a sorted booking list.
+ */
+ public void setBooking(Booking target, Booking editedBooking) {
+ requireAllNonNull(target, editedBooking);
+
+ int index = internalList.indexOf(target);
+ if (index == -1) {
+ throw new BookingNotFoundException();
+ }
+
+ internalList.set(index, editedBooking);
+ logger.fine("Sorting the booking list.");
+ sortBookingList();
+ }
+
+ /**
+ * Returns the size of booking list
+ */
+ public int getBookingListSize() {
+ return internalList.size();
+ }
+
+ public Booking getBooking(int zeroBasedIndex) {
+ return internalList.get(zeroBasedIndex);
+ }
+
+ /**
+ * Removes the equivalent booking from the list.
+ * The booking must exist in the list.
+ */
+ public void remove(Booking toRemove) {
+ requireNonNull(toRemove);
+ if (!internalList.remove(toRemove)) {
+ throw new BookingNotFoundException();
+ }
+ }
+
+ /**
+ * Replaces all the {@code bookings} with those from the other {@code BookingList}.
+ * Returns a sorted booking list.
+ */
+ public void resetBookings(BookingList replacement) {
+ requireNonNull(replacement);
+ internalList.setAll(replacement.internalList);
+ logger.fine("Sorting the booking list.");
+ sortBookingList();
+ }
+
+ /**
+ * Replaces the contents of this list with {@code bookings}.
+ * {@code bookings} must not contain overlapping bookings.
+ * Returns a sorted booking list.
+ */
+ public void setBookings(List bookings) {
+ requireAllNonNull(bookings);
+ if (!bookingsAreUnique(bookings)) {
+ throw new OverlappingBookingException();
+ }
+ internalList.setAll(bookings);
+ logger.fine("Sorting the booking list.");
+ sortBookingList();
+ }
+
+ /**
+ * Returns the backing list as an unmodifiable {@code ObservableList}
+ * sorted as described in Booking's {@code compareTo} method.
+ */
+ //@@author Soorya
+ public ObservableList getValue() {
+ return internalUnmodifiableList;
+ }
+
+ //@@author Li Gang
+ @Override
+ public Iterator iterator() {
+ return internalList.iterator();
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ if (getValue().isEmpty()) {
+ builder.append("No bookings.");
+ } else {
+ builder.append("Bookings:\n");
+ getValue().stream().forEach(obj -> builder.append(obj + "\n"));
+ }
+ return builder.toString();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ return other == this // short circuit if same object
+ || (other instanceof BookingList // instanceof handles nulls
+ && internalList.equals(((BookingList) other).internalList));
+ }
+
+ @Override
+ public int hashCode() {
+ return internalList.hashCode();
+ }
+
+ /**
+ * Returns true if {@code bookings} contains only non-overlapping bookings.
+ */
+ private boolean bookingsAreUnique(List bookings) {
+ for (int i = 0; i < bookings.size() - 1; i++) {
+ for (int j = i + 1; j < bookings.size(); j++) {
+ if (bookings.get(i).doesOverlap(bookings.get(j))) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ //@@author Wang Tao
+ public void sortBookingList() {
+ FXCollections.sort(internalList);
+ }
+
+}
diff --git a/src/main/java/seedu/address/model/residence/NameContainsKeywordsPredicate.java b/src/main/java/seedu/address/model/residence/NameContainsKeywordsPredicate.java
new file mode 100644
index 00000000000..aeaf74f4cbd
--- /dev/null
+++ b/src/main/java/seedu/address/model/residence/NameContainsKeywordsPredicate.java
@@ -0,0 +1,32 @@
+package seedu.address.model.residence;
+
+import java.util.List;
+import java.util.function.Predicate;
+
+import seedu.address.commons.util.StringUtil;
+
+/**
+ * Tests that a {@code Residence}'s {@code ResidenceName} matches any of the keywords given.
+ */
+public class NameContainsKeywordsPredicate implements Predicate {
+ private final List keywords;
+
+ public NameContainsKeywordsPredicate(List keywords) {
+ this.keywords = keywords;
+ }
+
+ @Override
+ public boolean test(Residence residence) {
+ return keywords.stream()
+ .anyMatch(keyword -> StringUtil.containsWordIgnoreCase(
+ residence.getResidenceName().toString(), keyword));
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ return other == this // short circuit if same object
+ || (other instanceof NameContainsKeywordsPredicate // instanceof handles nulls
+ && keywords.equals(((NameContainsKeywordsPredicate) other).keywords)); // state check
+ }
+
+}
diff --git a/src/main/java/seedu/address/model/residence/Residence.java b/src/main/java/seedu/address/model/residence/Residence.java
new file mode 100644
index 00000000000..0a07bfcba83
--- /dev/null
+++ b/src/main/java/seedu/address/model/residence/Residence.java
@@ -0,0 +1,178 @@
+package seedu.address.model.residence;
+
+import static seedu.address.commons.util.CollectionUtil.requireAllNonNull;
+
+import java.time.LocalDate;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+
+import seedu.address.model.booking.Booking;
+import seedu.address.model.tag.CleanStatusTag;
+import seedu.address.model.tag.Tag;
+
+/**
+ * Represents a Residence in ResidenceTracker.
+ * Guarantees: details are present and not null, field values are validated, immutable except {@code CleanStatusTag}.
+ */
+public class Residence implements Comparable {
+
+ // Identity fields
+ private final ResidenceName residenceName;
+
+ // Data fields
+ private final ResidenceAddress residenceAddress;
+ private final BookingList bookingList;
+ private final Set tags = new HashSet<>();
+ private CleanStatusTag cleanStatusTag;
+
+ /**
+ * Every field must be present and not null except {@code BookingList}.
+ */
+ public Residence(ResidenceName residenceName, ResidenceAddress residenceAddress,
+ CleanStatusTag cleanStatusTag, Set tags) {
+ this.bookingList = new BookingList();
+ requireAllNonNull(residenceName, residenceAddress, cleanStatusTag, tags);
+ this.residenceName = residenceName;
+ this.residenceAddress = residenceAddress;
+ this.cleanStatusTag = cleanStatusTag;
+ this.tags.addAll(tags);
+ }
+
+ /**
+ * When BookingList is provided.
+ */
+ public Residence(ResidenceName residenceName, ResidenceAddress residenceAddress, BookingList bookingList,
+ CleanStatusTag cleanStatusTag, Set tags) {
+ this.bookingList = bookingList;
+ requireAllNonNull(residenceName, residenceAddress, cleanStatusTag, tags);
+ this.residenceName = residenceName;
+ this.residenceAddress = residenceAddress;
+ this.cleanStatusTag = cleanStatusTag;
+ this.tags.addAll(tags);
+ }
+
+ public ResidenceName getResidenceName() {
+ return residenceName;
+ }
+
+ public ResidenceAddress getResidenceAddress() {
+ return residenceAddress;
+ }
+
+ public BookingList getBookingList() {
+ return bookingList;
+ }
+
+ public CleanStatusTag getCleanStatusTag() {
+ return cleanStatusTag;
+ }
+
+ /**
+ * Returns an immutable tag set, which throws {@code UnsupportedOperationException}
+ * if modification is attempted.
+ */
+ public Set getTags() {
+ return Collections.unmodifiableSet(tags);
+ }
+
+ /**
+ * Returns an immutable tag set, which throws {@code UnsupportedOperationException}
+ * if modification is attempted.
+ */
+ public boolean hasBooking(Booking booking) {
+ return bookingList.contains(booking);
+ }
+
+ /**
+ * Returns a modified {@code Residence} with new {@code booking} added to it's BookingList.
+ */
+ public Residence addBooking(Booking booking) {
+ assert !this.hasBooking(booking);
+ bookingList.add(booking);
+ return this;
+ }
+
+ /**
+ * Returns true if both residences have the same residenceName.
+ * This defines a weaker notion of equality between two residences.
+ */
+ public boolean isSameResidence(Residence otherResidence) {
+ if (otherResidence == this) {
+ return true;
+ }
+
+ return otherResidence != null
+ && otherResidence.getResidenceName().equals(getResidenceName());
+ }
+
+ /**
+ * Returns true if this residence has any bookings that start in the next 7 days.
+ */
+ public boolean hasUpcomingBooking() {
+ return this.bookingList.getValue().stream()
+ .filter(b -> b.getStart().isAfter(LocalDate.now())
+ && b.getStart().isBefore(LocalDate.now().plusDays(8)))
+ .mapToInt(b -> 1).sum() > 0;
+ }
+
+ /**
+ * Returns true if both residence have the same identity and data fields.
+ * This defines a stronger notion of equality between two residence.
+ */
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ if (!(other instanceof Residence)) {
+ return false;
+ }
+
+ Residence otherResidence = (Residence) other;
+ return otherResidence.getResidenceName().equals(getResidenceName())
+ && otherResidence.getResidenceAddress().equals(getResidenceAddress())
+ && otherResidence.getBookingList().equals(getBookingList())
+ && otherResidence.getCleanStatusTag().equals(getCleanStatusTag())
+ && otherResidence.getTags().equals(getTags());
+ }
+
+ @Override
+ public int hashCode() {
+ // use this method for custom fields hashing instead of implementing your own
+ return Objects.hash(residenceName, residenceAddress, bookingList, cleanStatusTag, tags);
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(getResidenceName())
+ .append("; Residence Address: ")
+ .append(getResidenceAddress())
+ .append("; Clean Status: ")
+ .append(getCleanStatusTag());
+
+ Set tags = getTags();
+ if (!tags.isEmpty()) {
+ builder.append("; Tags: ");
+ tags.forEach(builder::append);
+ }
+ return builder.toString();
+ }
+
+ //@@author Zhen Yi
+ @Override
+ public int compareTo(Residence o) {
+ if (this.getCleanStatusTag().getValue().equals("Unclean")
+ && (o.getCleanStatusTag().getValue().equals("Clean"))) {
+ return -1;
+ } else if (this.getCleanStatusTag().getValue().equals("Clean")
+ && (o.getCleanStatusTag().getValue().equals("Unclean"))) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+}
diff --git a/src/main/java/seedu/address/model/person/Address.java b/src/main/java/seedu/address/model/residence/ResidenceAddress.java
similarity index 53%
rename from src/main/java/seedu/address/model/person/Address.java
rename to src/main/java/seedu/address/model/residence/ResidenceAddress.java
index 60472ca22a0..e41ec3a1d50 100644
--- a/src/main/java/seedu/address/model/person/Address.java
+++ b/src/main/java/seedu/address/model/residence/ResidenceAddress.java
@@ -1,18 +1,18 @@
-package seedu.address.model.person;
+package seedu.address.model.residence;
import static java.util.Objects.requireNonNull;
import static seedu.address.commons.util.AppUtil.checkArgument;
/**
- * Represents a Person's address in the address book.
- * Guarantees: immutable; is valid as declared in {@link #isValidAddress(String)}
+ * Represents a Residence's address in ResidenceTracker.
+ * Guarantees: immutable; is valid as declared in {@link #isValidResidenceAddress(String)}
*/
-public class Address {
+public class ResidenceAddress {
public static final String MESSAGE_CONSTRAINTS = "Addresses can take any values, and it should not be blank";
/*
- * The first character of the address must not be a whitespace,
+ * The first character of the Residence's address must not be a whitespace,
* otherwise " " (a blank string) becomes a valid input.
*/
public static final String VALIDATION_REGEX = "[^\\s].*";
@@ -20,23 +20,30 @@ public class Address {
public final String value;
/**
- * Constructs an {@code Address}.
+ * Constructs an {@code ResidenceAddress}.
*
* @param address A valid address.
*/
- public Address(String address) {
+ public ResidenceAddress(String address) {
requireNonNull(address);
- checkArgument(isValidAddress(address), MESSAGE_CONSTRAINTS);
+ checkArgument(isValidResidenceAddress(address), MESSAGE_CONSTRAINTS);
value = address;
}
/**
- * Returns true if a given string is a valid email.
+ * Returns true if a given string is a valid address.
*/
- public static boolean isValidAddress(String test) {
+ public static boolean isValidResidenceAddress(String test) {
return test.matches(VALIDATION_REGEX);
}
+ /**
+ * Returns value of this {@code ResidenceAddress}.
+ */
+ public String getValue() {
+ return value;
+ }
+
@Override
public String toString() {
return value;
@@ -45,8 +52,8 @@ public String toString() {
@Override
public boolean equals(Object other) {
return other == this // short circuit if same object
- || (other instanceof Address // instanceof handles nulls
- && value.equals(((Address) other).value)); // state check
+ || (other instanceof ResidenceAddress // instanceof handles nulls
+ && value.equals(((ResidenceAddress) other).value)); // state check
}
@Override
diff --git a/src/main/java/seedu/address/model/residence/ResidenceName.java b/src/main/java/seedu/address/model/residence/ResidenceName.java
new file mode 100644
index 00000000000..bf6e0695837
--- /dev/null
+++ b/src/main/java/seedu/address/model/residence/ResidenceName.java
@@ -0,0 +1,55 @@
+package seedu.address.model.residence;
+
+import static java.util.Objects.requireNonNull;
+import static seedu.address.commons.util.AppUtil.checkArgument;
+
+import seedu.address.model.name.CommonName;
+
+/**
+ * Represents a Residence's name in ResidenceTracker.
+ * Guarantees: immutable; is valid as declared in {@link #isValidResidenceName(String)}
+ */
+public class ResidenceName extends CommonName {
+
+ public static final String MESSAGE_CONSTRAINTS =
+ "Residence Names should only contain 1 or more alphanumeric characters, 0 or more spaces, and "
+ + "\n0 or more '@'. Residence Names should not be blank.";
+
+ /*
+ * The first character of the Residence's name must not be a whitespace,
+ * otherwise " " (a blank string) becomes a valid input.
+ */
+ public static final String VALIDATION_REGEX = "[\\p{Alnum}][@\\p{Alnum} ]*";
+
+ /**
+ * Constructs a {@code ResidenceName}.
+ *
+ * @param name A valid residence name.
+ */
+ public ResidenceName(String name) {
+ requireNonNull(name);
+ checkArgument(isValidResidenceName(name), MESSAGE_CONSTRAINTS);
+ fullName = name;
+ }
+
+ /**
+ * Returns true if a given string is a valid residence name.
+ */
+ public static boolean isValidResidenceName(String test) {
+ return test.matches(VALIDATION_REGEX);
+ }
+
+ /**
+ * Returns value of this {@code ResidenceName}.
+ */
+ public String getValue() {
+ return fullName;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ return other == this // short circuit if same object
+ || (other instanceof ResidenceName // instanceof handles nulls
+ && fullName.equals(((ResidenceName) other).fullName)); // state check
+ }
+}
diff --git a/src/main/java/seedu/address/model/residence/UniqueResidenceList.java b/src/main/java/seedu/address/model/residence/UniqueResidenceList.java
new file mode 100644
index 00000000000..1ae1d8232e0
--- /dev/null
+++ b/src/main/java/seedu/address/model/residence/UniqueResidenceList.java
@@ -0,0 +1,153 @@
+package seedu.address.model.residence;
+
+import static java.util.Objects.requireNonNull;
+import static seedu.address.commons.util.CollectionUtil.requireAllNonNull;
+
+import java.util.Iterator;
+import java.util.List;
+
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import seedu.address.model.residence.exceptions.DuplicateResidenceException;
+import seedu.address.model.residence.exceptions.ResidenceNotFoundException;
+
+
+/**
+ * A list of residences that enforces uniqueness between its elements and does not allow nulls.
+ * A residence is considered unique by comparing using {@code Residence#isSameResidence(Residence)}.
+ * As such, adding and updating of residences uses Residence#isSameResidence(Residence) for equality so as to
+ * ensure that the residence being added or updated is unique in terms of identity in the UniqueResidenceList.
+ * However, the removal of a Residence uses Residence#equals(Object) so as to ensure that the Residence
+ * with exactly the same fields will be removed.
+ *
+ * Supports a minimal set of list operations.
+ *
+ * @see Residence#isSameResidence(Residence)
+ */
+public class UniqueResidenceList implements Iterable {
+
+ private final ObservableList internalList = FXCollections.observableArrayList();
+ private final ObservableList internalUnmodifiableList =
+ FXCollections.unmodifiableObservableList(internalList);
+
+ /**
+ * Returns true if the list contains an equivalent residence as the given argument.
+ */
+ public boolean contains(Residence toCheck) {
+ requireNonNull(toCheck);
+ return internalList.stream().anyMatch(toCheck::isSameResidence);
+ }
+
+ /**
+ * Adds the given residence to the list.
+ * The residence must not already exist in the list.
+ */
+ public void add(Residence toAdd) {
+ requireNonNull(toAdd);
+ if (contains(toAdd)) {
+ throw new DuplicateResidenceException();
+ }
+ internalList.add(toAdd);
+ }
+ /**
+ * Replaces the residence {@code target} in the list with {@code editedResidence}.
+ * {@code target} must exist in the list.
+ * The residence identity of {@code editedResidence} must not be the same as another existing residence in the list.
+ */
+ public void setResidence(Residence target, Residence editedResidence) {
+ requireAllNonNull(target, editedResidence);
+
+ int index = internalList.indexOf(target);
+ if (index == -1) {
+ throw new ResidenceNotFoundException();
+ }
+
+ if (!target.isSameResidence(editedResidence) && contains(editedResidence)) {
+ throw new DuplicateResidenceException();
+ }
+
+ internalList.set(index, editedResidence);
+ }
+
+ /**
+ * Removes the equivalent residence from the list.
+ * The residence must exist in the list.
+ */
+ public void remove(Residence toRemove) {
+ requireNonNull(toRemove);
+ if (!internalList.remove(toRemove)) {
+ throw new ResidenceNotFoundException();
+ }
+ }
+
+ /**
+ * Replaces the contents of this list with {@code replacement}.
+ * {@code replacement} must not be null.
+ */
+ public void setResidences(UniqueResidenceList replacement) {
+ requireNonNull(replacement);
+ internalList.setAll(replacement.internalList);
+
+ }
+
+ /**
+ * Replaces the contents of this list with {@code residences}.
+ * {@code residences} must not contain duplicate residences.
+ */
+ public void setResidences(List residences) {
+ requireAllNonNull(residences);
+ if (!residencesAreUnique(residences)) {
+ throw new DuplicateResidenceException();
+ }
+ internalList.setAll(residences);
+ }
+
+ /**
+ * Returns the backing list as an unmodifiable {@code ObservableList}.
+ */
+ public ObservableList asUnmodifiableObservableList() {
+ return internalUnmodifiableList;
+ }
+
+ /**
+ * Sorts the backing list as described in Residence's {@code compareTo} method.
+ */
+ public void sortUnmodifiableObservableList() {
+ FXCollections.sort(internalList);
+ }
+
+ @Override
+ public Iterator iterator() {
+ return internalList.iterator();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ return other == this // short circuit if same object
+ || (other instanceof UniqueResidenceList // instanceof handles nulls
+ && internalList.equals(((UniqueResidenceList) other).internalList));
+ }
+
+ @Override
+ public int hashCode() {
+ return internalList.hashCode();
+ }
+
+ /**
+ * Returns true if {@code residences} contains only unique residences.
+ */
+ private boolean residencesAreUnique(List residences) {
+ for (int i = 0; i < residences.size() - 1; i++) {
+ for (int j = i + 1; j < residences.size(); j++) {
+ if (residences.get(i).isSameResidence(residences.get(j))) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ public void sortResidenceList() {
+ FXCollections.sort(internalList);
+ }
+}
diff --git a/src/main/java/seedu/address/model/residence/exceptions/DuplicateResidenceException.java b/src/main/java/seedu/address/model/residence/exceptions/DuplicateResidenceException.java
new file mode 100644
index 00000000000..d98a5cafcfe
--- /dev/null
+++ b/src/main/java/seedu/address/model/residence/exceptions/DuplicateResidenceException.java
@@ -0,0 +1,12 @@
+package seedu.address.model.residence.exceptions;
+
+/**
+ * Signals that the operation will result in duplicate Residences (Residences are considered duplicates
+ * if they have the same identity).
+ */
+
+public class DuplicateResidenceException extends RuntimeException {
+ public DuplicateResidenceException() {
+ super("Operation would result in duplicate residences");
+ }
+}
diff --git a/src/main/java/seedu/address/model/residence/exceptions/ResidenceNotFoundException.java b/src/main/java/seedu/address/model/residence/exceptions/ResidenceNotFoundException.java
new file mode 100644
index 00000000000..9fe2ccc6a33
--- /dev/null
+++ b/src/main/java/seedu/address/model/residence/exceptions/ResidenceNotFoundException.java
@@ -0,0 +1,5 @@
+package seedu.address.model.residence.exceptions;
+
+public class ResidenceNotFoundException extends RuntimeException {
+
+}
diff --git a/src/main/java/seedu/address/model/tag/CleanStatusTag.java b/src/main/java/seedu/address/model/tag/CleanStatusTag.java
new file mode 100644
index 00000000000..1d61b7adfa6
--- /dev/null
+++ b/src/main/java/seedu/address/model/tag/CleanStatusTag.java
@@ -0,0 +1,77 @@
+package seedu.address.model.tag;
+
+import static java.util.Objects.requireNonNull;
+import static seedu.address.commons.util.AppUtil.checkArgument;
+
+/**
+ * Represents a CleanStatusTag in the residence tracker.
+ * Guarantees: name is valid as declared in {@link #isValidCleanStatusTag(String)}
+ */
+public class CleanStatusTag {
+ //@@author Soorya
+ public static final String CLEAN = "Clean";
+ public static final String UNCLEAN = "Unclean";
+ public static final String MESSAGE_CONSTRAINTS = "Please use 'c/y', 'c/n', 'c/clean' or 'c/unclean'";
+
+ private String cleanStatus;
+
+ /**
+ * Constructs a default {@code CleanStatusTag} with status value "Clean".
+ */
+ public CleanStatusTag() {
+ this.cleanStatus = CLEAN;
+ }
+
+ //@@author Wang Tao
+ /**
+ * Constructs a {@code CleanStatusTag}.
+ *
+ * @param cleanStatus A valid clean status.
+ */
+ public CleanStatusTag(String cleanStatus) {
+ requireNonNull(cleanStatus);
+ checkArgument(isValidCleanStatusTag(cleanStatus), MESSAGE_CONSTRAINTS);
+ if (cleanStatus.equalsIgnoreCase("y") || cleanStatus.equalsIgnoreCase("clean")) {
+ this.cleanStatus = CLEAN;
+ } else if (cleanStatus.equalsIgnoreCase("n") || cleanStatus.equalsIgnoreCase("unclean")) {
+ this.cleanStatus = UNCLEAN;
+ }
+ }
+
+ /**
+ * Returns true if a given string is a valid tag name.
+ */
+ public static boolean isValidCleanStatusTag(String test) {
+ return test.equalsIgnoreCase("y") || test.equalsIgnoreCase("n")
+ || test.equalsIgnoreCase("clean") || test.equalsIgnoreCase("unclean");
+ }
+
+ //@@author Soorya
+ /**
+ * Returns value of this {@code CleanStatusTag}.
+ */
+ public String getValue() {
+ return cleanStatus;
+ }
+
+ //@@author Wang Tao
+ @Override
+ public boolean equals(Object other) {
+ return other == this // short circuit if same object
+ || (other instanceof CleanStatusTag // instanceof handles nulls
+ && cleanStatus.equals(((CleanStatusTag) other).cleanStatus)); // state check
+ }
+
+ @Override
+ public int hashCode() {
+ return cleanStatus.hashCode();
+ }
+
+ /**
+ * Formats this CleanStatusTag as text for viewing.
+ */
+ @Override
+ public String toString() {
+ return '[' + cleanStatus + ']';
+ }
+}
diff --git a/src/main/java/seedu/address/model/tag/Tag.java b/src/main/java/seedu/address/model/tag/Tag.java
index b0ea7e7dad7..e4b3040ce51 100644
--- a/src/main/java/seedu/address/model/tag/Tag.java
+++ b/src/main/java/seedu/address/model/tag/Tag.java
@@ -4,12 +4,12 @@
import static seedu.address.commons.util.AppUtil.checkArgument;
/**
- * Represents a Tag in the address book.
+ * Represents a Tag in the residence tracker.
* Guarantees: immutable; name is valid as declared in {@link #isValidTagName(String)}
*/
public class Tag {
- public static final String MESSAGE_CONSTRAINTS = "Tags names should be alphanumeric";
+ public static final String MESSAGE_CONSTRAINTS = "Tag names should be alphanumeric and should not contain spaces";
public static final String VALIDATION_REGEX = "\\p{Alnum}+";
public final String tagName;
@@ -45,8 +45,9 @@ public int hashCode() {
}
/**
- * Format state as text for viewing.
+ * Formats this Tag as text for viewing.
*/
+ @Override
public String toString() {
return '[' + tagName + ']';
}
diff --git a/src/main/java/seedu/address/model/util/SampleDataUtil.java b/src/main/java/seedu/address/model/util/SampleDataUtil.java
index 1806da4facf..4d3a2da3bf1 100644
--- a/src/main/java/seedu/address/model/util/SampleDataUtil.java
+++ b/src/main/java/seedu/address/model/util/SampleDataUtil.java
@@ -1,51 +1,68 @@
package seedu.address.model.util;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;
-import seedu.address.model.AddressBook;
-import seedu.address.model.ReadOnlyAddressBook;
-import seedu.address.model.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Person;
-import seedu.address.model.person.Phone;
+import seedu.address.model.ReadOnlyResidenceTracker;
+import seedu.address.model.ResidenceTracker;
+import seedu.address.model.booking.Booking;
+import seedu.address.model.booking.Phone;
+import seedu.address.model.booking.TenantName;
+import seedu.address.model.residence.BookingList;
+import seedu.address.model.residence.Residence;
+import seedu.address.model.residence.ResidenceAddress;
+import seedu.address.model.residence.ResidenceName;
+import seedu.address.model.tag.CleanStatusTag;
import seedu.address.model.tag.Tag;
/**
- * Contains utility methods for populating {@code AddressBook} with sample data.
+ * Contains utility methods for populating {@code ResidenceTracker} with sample data.
*/
public class SampleDataUtil {
- public static Person[] getSamplePersons() {
- return new Person[] {
- new Person(new Name("Alex Yeoh"), new Phone("87438807"), new Email("alexyeoh@example.com"),
- new Address("Blk 30 Geylang Street 29, #06-40"),
- getTagSet("friends")),
- new Person(new Name("Bernice Yu"), new Phone("99272758"), new Email("berniceyu@example.com"),
- new Address("Blk 30 Lorong 3 Serangoon Gardens, #07-18"),
- getTagSet("colleagues", "friends")),
- new Person(new Name("Charlotte Oliveiro"), new Phone("93210283"), new Email("charlotte@example.com"),
- new Address("Blk 11 Ang Mo Kio Street 74, #11-04"),
- getTagSet("neighbours")),
- new Person(new Name("David Li"), new Phone("91031282"), new Email("lidavid@example.com"),
- new Address("Blk 436 Serangoon Gardens Street 26, #16-43"),
- getTagSet("family")),
- new Person(new Name("Irfan Ibrahim"), new Phone("92492021"), new Email("irfan@example.com"),
- new Address("Blk 47 Tampines Street 20, #17-35"),
- getTagSet("classmates")),
- new Person(new Name("Roy Balakrishnan"), new Phone("92624417"), new Email("royb@example.com"),
- new Address("Blk 45 Aljunied Street 85, #11-31"),
- getTagSet("colleagues"))
+ public static Residence[] getSampleResidence() {
+ BookingList bookingListA = new BookingList();
+ BookingList bookingListB = new BookingList();
+
+ DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("dd-MM-uuuu");
+ LocalDate startA = LocalDate.parse("27-03-2021", dateFormat);
+ LocalDate endA = LocalDate.parse("02-04-2021", dateFormat);
+ LocalDate startB = LocalDate.parse("10-04-2021", dateFormat);
+ LocalDate endB = LocalDate.parse("21-04-2021", dateFormat);
+ LocalDate startC = LocalDate.parse("05-05-2021", dateFormat);
+ LocalDate endC = LocalDate.parse("31-05-2021", dateFormat);
+
+
+ Booking bookingA = new Booking(new TenantName("Alice Carol"), new Phone("90098118"), startA, endA);
+ Booking bookingB = new Booking(new TenantName("David Michael"), new Phone("82316788"), startB, endB);
+ Booking bookingC = new Booking(new TenantName("Cara Delevingne"), new Phone("96221200"), startC, endC);
+
+ bookingListA.add(bookingA);
+ bookingListA.add(bookingB);
+ bookingListB.add(bookingC);
+
+ return new Residence[]{
+ new Residence(new ResidenceName("Condo"), new ResidenceAddress("Blk 45 Tampines Street 29, #08-01"),
+ new BookingList(bookingListB), new CleanStatusTag("n"), getTagSet("Reserved")),
+ new Residence(new ResidenceName("Melville Park"), new ResidenceAddress("22 Simei Street 1, #10-02"),
+ new BookingList(), new CleanStatusTag("n"), getTagSet("Available")),
+ new Residence(new ResidenceName("HDB"), new ResidenceAddress("Blk 30 Geylang Street 29, #06-40"),
+ new BookingList(bookingListA), new CleanStatusTag("y"), getTagSet("Booked"))
+
};
}
- public static ReadOnlyAddressBook getSampleAddressBook() {
- AddressBook sampleAb = new AddressBook();
- for (Person samplePerson : getSamplePersons()) {
- sampleAb.addPerson(samplePerson);
+ /**
+ * Returns an unmodifiable view of the residence tracker with the sample data.
+ */
+ public static ReadOnlyResidenceTracker getSampleResidenceTracker() {
+ ResidenceTracker sampleRt = new ResidenceTracker();
+ for (Residence sampleResidence : getSampleResidence()) {
+ sampleRt.addResidence(sampleResidence);
}
- return sampleAb;
+ return sampleRt;
}
/**
diff --git a/src/main/java/seedu/address/storage/AddressBookStorage.java b/src/main/java/seedu/address/storage/AddressBookStorage.java
deleted file mode 100644
index 4599182b3f9..00000000000
--- a/src/main/java/seedu/address/storage/AddressBookStorage.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package seedu.address.storage;
-
-import java.io.IOException;
-import java.nio.file.Path;
-import java.util.Optional;
-
-import seedu.address.commons.exceptions.DataConversionException;
-import seedu.address.model.ReadOnlyAddressBook;
-
-/**
- * Represents a storage for {@link seedu.address.model.AddressBook}.
- */
-public interface AddressBookStorage {
-
- /**
- * Returns the file path of the data file.
- */
- Path getAddressBookFilePath();
-
- /**
- * Returns AddressBook data as a {@link ReadOnlyAddressBook}.
- * Returns {@code Optional.empty()} if storage file is not found.
- * @throws DataConversionException if the data in storage is not in the expected format.
- * @throws IOException if there was any problem when reading from the storage.
- */
- Optional readAddressBook() throws DataConversionException, IOException;
-
- /**
- * @see #getAddressBookFilePath()
- */
- Optional readAddressBook(Path filePath) throws DataConversionException, IOException;
-
- /**
- * Saves the given {@link ReadOnlyAddressBook} to the storage.
- * @param addressBook cannot be null.
- * @throws IOException if there was any problem writing to the file.
- */
- void saveAddressBook(ReadOnlyAddressBook addressBook) throws IOException;
-
- /**
- * @see #saveAddressBook(ReadOnlyAddressBook)
- */
- void saveAddressBook(ReadOnlyAddressBook addressBook, Path filePath) throws IOException;
-
-}
diff --git a/src/main/java/seedu/address/storage/JsonAdaptedBooking.java b/src/main/java/seedu/address/storage/JsonAdaptedBooking.java
new file mode 100644
index 00000000000..3f489345aa8
--- /dev/null
+++ b/src/main/java/seedu/address/storage/JsonAdaptedBooking.java
@@ -0,0 +1,80 @@
+package seedu.address.storage;
+
+import java.time.LocalDate;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import seedu.address.commons.exceptions.IllegalValueException;
+import seedu.address.model.booking.Booking;
+import seedu.address.model.booking.Phone;
+import seedu.address.model.booking.TenantName;
+
+/**
+ * Jackson-friendly version of {@link Booking}.
+ */
+class JsonAdaptedBooking {
+
+ public static final String MISSING_FIELD_MESSAGE_FORMAT = "Booking's %s field is missing!";
+
+ private final String tenantName;
+ private final String phone;
+ private final LocalDate start;
+ private final LocalDate end;
+
+ /**
+ * Constructs a {@code JsonAdaptedBooking} with the given booking details.
+ */
+ @JsonCreator
+ public JsonAdaptedBooking(@JsonProperty("name") String tenantName, @JsonProperty("phone") String phone,
+ @JsonProperty("start") LocalDate start, @JsonProperty("end") LocalDate end) {
+ this.tenantName = tenantName;
+ this.phone = phone;
+ this.start = start;
+ this.end = end;
+ }
+
+ /**
+ * Converts a given {@code Booking} into this class for Jackson use.
+ */
+ public JsonAdaptedBooking(Booking source) {
+ tenantName = source.getTenantName().toString();
+ phone = source.getPhone().toString();
+ start = source.getStart();
+ end = source.getEnd();
+ }
+
+ /**
+ * Converts this Jackson-friendly adapted booking object into the model's {@code Booking} object.
+ *
+ * @throws IllegalValueException if there were any data constraints violated in the adapted booking.
+ */
+ public Booking toModelType() throws IllegalValueException {
+
+ if (tenantName == null) {
+ throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT,
+ TenantName.class.getSimpleName()));
+ }
+ if (!TenantName.isValidName(tenantName)) {
+ throw new IllegalValueException(TenantName.MESSAGE_CONSTRAINTS);
+ }
+ final TenantName modelTenantName = new TenantName(tenantName);
+
+ if (phone == null) {
+ throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Phone.class.getSimpleName()));
+ }
+ if (!Phone.isValidPhone(phone)) {
+ throw new IllegalValueException(Phone.MESSAGE_CONSTRAINTS);
+ }
+ final Phone modelPhone = new Phone(phone);
+
+ if (start == null || end == null) {
+ throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Booking.class.getSimpleName()));
+ }
+ if (start.isAfter(end)) {
+ throw new IllegalValueException(Booking.MESSAGE_CONSTRAINTS);
+ }
+ return new Booking(modelTenantName, modelPhone, start, end);
+ }
+
+}
diff --git a/src/main/java/seedu/address/storage/JsonAdaptedPerson.java b/src/main/java/seedu/address/storage/JsonAdaptedPerson.java
deleted file mode 100644
index a6321cec2ea..00000000000
--- a/src/main/java/seedu/address/storage/JsonAdaptedPerson.java
+++ /dev/null
@@ -1,109 +0,0 @@
-package seedu.address.storage;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import seedu.address.commons.exceptions.IllegalValueException;
-import seedu.address.model.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Person;
-import seedu.address.model.person.Phone;
-import seedu.address.model.tag.Tag;
-
-/**
- * Jackson-friendly version of {@link Person}.
- */
-class JsonAdaptedPerson {
-
- public static final String MISSING_FIELD_MESSAGE_FORMAT = "Person's %s field is missing!";
-
- private final String name;
- private final String phone;
- private final String email;
- private final String address;
- private final List tagged = new ArrayList<>();
-
- /**
- * Constructs a {@code JsonAdaptedPerson} with the given person details.
- */
- @JsonCreator
- public JsonAdaptedPerson(@JsonProperty("name") String name, @JsonProperty("phone") String phone,
- @JsonProperty("email") String email, @JsonProperty("address") String address,
- @JsonProperty("tagged") List tagged) {
- this.name = name;
- this.phone = phone;
- this.email = email;
- this.address = address;
- if (tagged != null) {
- this.tagged.addAll(tagged);
- }
- }
-
- /**
- * Converts a given {@code Person} into this class for Jackson use.
- */
- public JsonAdaptedPerson(Person source) {
- name = source.getName().fullName;
- phone = source.getPhone().value;
- email = source.getEmail().value;
- address = source.getAddress().value;
- tagged.addAll(source.getTags().stream()
- .map(JsonAdaptedTag::new)
- .collect(Collectors.toList()));
- }
-
- /**
- * Converts this Jackson-friendly adapted person object into the model's {@code Person} object.
- *
- * @throws IllegalValueException if there were any data constraints violated in the adapted person.
- */
- public Person toModelType() throws IllegalValueException {
- final List personTags = new ArrayList<>();
- for (JsonAdaptedTag tag : tagged) {
- personTags.add(tag.toModelType());
- }
-
- if (name == null) {
- throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Name.class.getSimpleName()));
- }
- if (!Name.isValidName(name)) {
- throw new IllegalValueException(Name.MESSAGE_CONSTRAINTS);
- }
- final Name modelName = new Name(name);
-
- if (phone == null) {
- throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Phone.class.getSimpleName()));
- }
- if (!Phone.isValidPhone(phone)) {
- throw new IllegalValueException(Phone.MESSAGE_CONSTRAINTS);
- }
- final Phone modelPhone = new Phone(phone);
-
- if (email == null) {
- throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Email.class.getSimpleName()));
- }
- if (!Email.isValidEmail(email)) {
- throw new IllegalValueException(Email.MESSAGE_CONSTRAINTS);
- }
- final Email modelEmail = new Email(email);
-
- if (address == null) {
- throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Address.class.getSimpleName()));
- }
- if (!Address.isValidAddress(address)) {
- throw new IllegalValueException(Address.MESSAGE_CONSTRAINTS);
- }
- final Address modelAddress = new Address(address);
-
- final Set modelTags = new HashSet<>(personTags);
- return new Person(modelName, modelPhone, modelEmail, modelAddress, modelTags);
- }
-
-}
diff --git a/src/main/java/seedu/address/storage/JsonAdaptedResidence.java b/src/main/java/seedu/address/storage/JsonAdaptedResidence.java
new file mode 100644
index 00000000000..ea1354c3c02
--- /dev/null
+++ b/src/main/java/seedu/address/storage/JsonAdaptedResidence.java
@@ -0,0 +1,111 @@
+package seedu.address.storage;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import seedu.address.commons.exceptions.IllegalValueException;
+import seedu.address.model.booking.Booking;
+import seedu.address.model.residence.BookingList;
+import seedu.address.model.residence.Residence;
+import seedu.address.model.residence.ResidenceAddress;
+import seedu.address.model.residence.ResidenceName;
+import seedu.address.model.tag.CleanStatusTag;
+import seedu.address.model.tag.Tag;
+
+/**
+ * Jackson-friendly version of {@link Residence}.
+ */
+public class JsonAdaptedResidence {
+
+ public static final String MISSING_FIELD_MESSAGE_FORMAT = "Residence's %s field is missing!";
+
+ private final String residenceName;
+ private final String residenceAddress;
+ private final List bookingList = new ArrayList<>();
+ private final String cleanStatusTag;
+ private final List tags = new ArrayList<>();
+
+ /**
+ * Constructs a {@code JsonAdaptedResidence} with the given residence details.
+ */
+ @JsonCreator
+ public JsonAdaptedResidence(@JsonProperty("name") String residenceName,
+ @JsonProperty("address") String residenceAddress,
+ @JsonProperty("booking") List bookings,
+ @JsonProperty("cleanStatusTag") String cleanStatusTag,
+ @JsonProperty("tag") List tags) {
+ this.residenceName = residenceName;
+ this.residenceAddress = residenceAddress;
+ this.cleanStatusTag = cleanStatusTag;
+ if (bookings != null) {
+ this.bookingList.addAll(bookings);
+ }
+ if (tags != null) {
+ this.tags.addAll(tags);
+ }
+ }
+
+ /**
+ * Converts a given {@code Residence} into this class for Jackson use.
+ */
+ public JsonAdaptedResidence(Residence source) {
+ residenceName = source.getResidenceName().getValue();
+ residenceAddress = source.getResidenceAddress().getValue();
+ cleanStatusTag = source.getCleanStatusTag().getValue();
+ bookingList.addAll(source.getBookingList().getValue().stream()
+ .map(JsonAdaptedBooking::new)
+ .collect(Collectors.toList()));
+ tags.addAll(source.getTags().stream()
+ .map(JsonAdaptedTag::new)
+ .collect(Collectors.toList()));
+ }
+
+ /**
+ * Converts this Jackson-friendly adapted residence object into the model's {@code Residence} object.
+ *
+ * @throws IllegalValueException if there were any data constraints violated in the adapted person.
+ */
+ public Residence toModelType() throws IllegalValueException {
+ final List residenceTags = new ArrayList<>();
+ for (JsonAdaptedTag tag : tags) {
+ residenceTags.add(tag.toModelType());
+ }
+
+ final List residenceBookingList = new ArrayList<>();
+ for (JsonAdaptedBooking booking : bookingList) {
+ residenceBookingList.add(booking.toModelType());
+ }
+
+ if (residenceName == null) {
+ throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT,
+ ResidenceName.class.getSimpleName()));
+ }
+ if (!ResidenceName.isValidResidenceName(residenceName)) {
+ throw new IllegalValueException(ResidenceName.MESSAGE_CONSTRAINTS);
+ }
+ final ResidenceName modelResidenceName = new ResidenceName(residenceName);
+
+ if (residenceAddress == null) {
+ throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT,
+ ResidenceAddress.class.getSimpleName()));
+ }
+ if (!ResidenceAddress.isValidResidenceAddress(residenceAddress)) {
+ throw new IllegalValueException(ResidenceAddress.MESSAGE_CONSTRAINTS);
+ }
+ final ResidenceAddress modelAddress = new ResidenceAddress(residenceAddress);
+
+ //might need to do valid and null check for booking details but skip first
+ final BookingList modelBookingList = new BookingList(residenceBookingList);
+
+ final CleanStatusTag modelCleanStatusTag = new CleanStatusTag(cleanStatusTag);
+
+ final Set modelTags = new HashSet<>(residenceTags);
+ return new Residence(modelResidenceName, modelAddress, modelBookingList, modelCleanStatusTag, modelTags);
+ }
+}
diff --git a/src/main/java/seedu/address/storage/JsonAddressBookStorage.java b/src/main/java/seedu/address/storage/JsonAddressBookStorage.java
deleted file mode 100644
index dfab9daaa0d..00000000000
--- a/src/main/java/seedu/address/storage/JsonAddressBookStorage.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package seedu.address.storage;
-
-import static java.util.Objects.requireNonNull;
-
-import java.io.IOException;
-import java.nio.file.Path;
-import java.util.Optional;
-import java.util.logging.Logger;
-
-import seedu.address.commons.core.LogsCenter;
-import seedu.address.commons.exceptions.DataConversionException;
-import seedu.address.commons.exceptions.IllegalValueException;
-import seedu.address.commons.util.FileUtil;
-import seedu.address.commons.util.JsonUtil;
-import seedu.address.model.ReadOnlyAddressBook;
-
-/**
- * A class to access AddressBook data stored as a json file on the hard disk.
- */
-public class JsonAddressBookStorage implements AddressBookStorage {
-
- private static final Logger logger = LogsCenter.getLogger(JsonAddressBookStorage.class);
-
- private Path filePath;
-
- public JsonAddressBookStorage(Path filePath) {
- this.filePath = filePath;
- }
-
- public Path getAddressBookFilePath() {
- return filePath;
- }
-
- @Override
- public Optional readAddressBook() throws DataConversionException {
- return readAddressBook(filePath);
- }
-
- /**
- * Similar to {@link #readAddressBook()}.
- *
- * @param filePath location of the data. Cannot be null.
- * @throws DataConversionException if the file is not in the correct format.
- */
- public Optional readAddressBook(Path filePath) throws DataConversionException {
- requireNonNull(filePath);
-
- Optional jsonAddressBook = JsonUtil.readJsonFile(
- filePath, JsonSerializableAddressBook.class);
- if (!jsonAddressBook.isPresent()) {
- return Optional.empty();
- }
-
- try {
- return Optional.of(jsonAddressBook.get().toModelType());
- } catch (IllegalValueException ive) {
- logger.info("Illegal values found in " + filePath + ": " + ive.getMessage());
- throw new DataConversionException(ive);
- }
- }
-
- @Override
- public void saveAddressBook(ReadOnlyAddressBook addressBook) throws IOException {
- saveAddressBook(addressBook, filePath);
- }
-
- /**
- * Similar to {@link #saveAddressBook(ReadOnlyAddressBook)}.
- *
- * @param filePath location of the data. Cannot be null.
- */
- public void saveAddressBook(ReadOnlyAddressBook addressBook, Path filePath) throws IOException {
- requireNonNull(addressBook);
- requireNonNull(filePath);
-
- FileUtil.createIfMissing(filePath);
- JsonUtil.saveJsonFile(new JsonSerializableAddressBook(addressBook), filePath);
- }
-
-}
diff --git a/src/main/java/seedu/address/storage/JsonResidenceTrackerStorage.java b/src/main/java/seedu/address/storage/JsonResidenceTrackerStorage.java
new file mode 100644
index 00000000000..49fa638a643
--- /dev/null
+++ b/src/main/java/seedu/address/storage/JsonResidenceTrackerStorage.java
@@ -0,0 +1,80 @@
+package seedu.address.storage;
+
+import static java.util.Objects.requireNonNull;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Optional;
+import java.util.logging.Logger;
+
+import seedu.address.commons.core.LogsCenter;
+import seedu.address.commons.exceptions.DataConversionException;
+import seedu.address.commons.exceptions.IllegalValueException;
+import seedu.address.commons.util.FileUtil;
+import seedu.address.commons.util.JsonUtil;
+import seedu.address.model.ReadOnlyResidenceTracker;
+
+/**
+ * A class to access ResidenceTracker data stored as a json file on the hard disk.
+ */
+public class JsonResidenceTrackerStorage implements ResidenceTrackerStorage {
+
+ private static final Logger logger = LogsCenter.getLogger(JsonResidenceTrackerStorage.class);
+
+ private Path filePath;
+
+ public JsonResidenceTrackerStorage(Path filePath) {
+ this.filePath = filePath;
+ }
+
+ public Path getResidenceTrackerFilePath() {
+ return filePath;
+ }
+
+ @Override
+ public Optional readResidenceTracker() throws DataConversionException {
+ return readResidenceTracker(filePath);
+ }
+
+ /**
+ * Similar to {@link #readResidenceTracker()}.
+ *
+ * @param filePath location of the data. Cannot be null.
+ * @throws DataConversionException if the file is not in the correct format.
+ */
+ public Optional readResidenceTracker(Path filePath) throws DataConversionException {
+ requireNonNull(filePath);
+
+ Optional jsonResidenceTracker = JsonUtil.readJsonFile(
+ filePath, JsonSerializableResidenceTracker.class);
+ if (!jsonResidenceTracker.isPresent()) {
+ return Optional.empty();
+ }
+
+ try {
+ return Optional.of(jsonResidenceTracker.get().toModelType());
+ } catch (IllegalValueException ive) {
+ logger.info("Illegal values found in " + filePath + ": " + ive.getMessage());
+ throw new DataConversionException(ive);
+ }
+ }
+
+ @Override
+ public void saveResidenceTracker(ReadOnlyResidenceTracker residenceTracker) throws IOException {
+ saveResidenceTracker(residenceTracker, filePath);
+ }
+
+ /**
+ * Similar to {@link #saveResidenceTracker(ReadOnlyResidenceTracker)}.
+ *
+ * @param filePath location of the data. Cannot be null.
+ */
+ public void saveResidenceTracker(ReadOnlyResidenceTracker residenceTracker, Path filePath) throws IOException {
+ requireNonNull(residenceTracker);
+ requireNonNull(filePath);
+
+ FileUtil.createIfMissing(filePath);
+ JsonUtil.saveJsonFile(new JsonSerializableResidenceTracker(residenceTracker), filePath);
+ }
+
+}
diff --git a/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java b/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java
deleted file mode 100644
index 5efd834091d..00000000000
--- a/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package seedu.address.storage;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonRootName;
-
-import seedu.address.commons.exceptions.IllegalValueException;
-import seedu.address.model.AddressBook;
-import seedu.address.model.ReadOnlyAddressBook;
-import seedu.address.model.person.Person;
-
-/**
- * An Immutable AddressBook that is serializable to JSON format.
- */
-@JsonRootName(value = "addressbook")
-class JsonSerializableAddressBook {
-
- public static final String MESSAGE_DUPLICATE_PERSON = "Persons list contains duplicate person(s).";
-
- private final List persons = new ArrayList<>();
-
- /**
- * Constructs a {@code JsonSerializableAddressBook} with the given persons.
- */
- @JsonCreator
- public JsonSerializableAddressBook(@JsonProperty("persons") List persons) {
- this.persons.addAll(persons);
- }
-
- /**
- * Converts a given {@code ReadOnlyAddressBook} into this class for Jackson use.
- *
- * @param source future changes to this will not affect the created {@code JsonSerializableAddressBook}.
- */
- public JsonSerializableAddressBook(ReadOnlyAddressBook source) {
- persons.addAll(source.getPersonList().stream().map(JsonAdaptedPerson::new).collect(Collectors.toList()));
- }
-
- /**
- * Converts this address book into the model's {@code AddressBook} object.
- *
- * @throws IllegalValueException if there were any data constraints violated.
- */
- public AddressBook toModelType() throws IllegalValueException {
- AddressBook addressBook = new AddressBook();
- for (JsonAdaptedPerson jsonAdaptedPerson : persons) {
- Person person = jsonAdaptedPerson.toModelType();
- if (addressBook.hasPerson(person)) {
- throw new IllegalValueException(MESSAGE_DUPLICATE_PERSON);
- }
- addressBook.addPerson(person);
- }
- return addressBook;
- }
-
-}
diff --git a/src/main/java/seedu/address/storage/JsonSerializableResidenceTracker.java b/src/main/java/seedu/address/storage/JsonSerializableResidenceTracker.java
new file mode 100644
index 00000000000..be9adcecd9d
--- /dev/null
+++ b/src/main/java/seedu/address/storage/JsonSerializableResidenceTracker.java
@@ -0,0 +1,61 @@
+package seedu.address.storage;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonRootName;
+
+import seedu.address.commons.exceptions.IllegalValueException;
+import seedu.address.model.ReadOnlyResidenceTracker;
+import seedu.address.model.ResidenceTracker;
+import seedu.address.model.residence.Residence;
+
+/**
+ * An Immutable ResidenceTracker that is serializable to JSON format.
+ */
+@JsonRootName(value = "residencetracker")
+class JsonSerializableResidenceTracker {
+
+ public static final String MESSAGE_DUPLICATE_RESIDENCE = "Residences list contains duplicate residences(s).";
+
+ private final List residences = new ArrayList<>();
+
+ /**
+ * Constructs a {@code JsonSerializableResidenceTracker} with the given residences.
+ */
+ @JsonCreator
+ public JsonSerializableResidenceTracker(@JsonProperty("residences") List residences) {
+ this.residences.addAll(residences);
+ }
+
+ /**
+ * Converts a given {@code ReadOnlyResidenceTracker} into this class for Jackson use.
+ *
+ * @param source future changes to this will not affect the created {@code JsonSerializableResidenceTracker}.
+ */
+ public JsonSerializableResidenceTracker(ReadOnlyResidenceTracker source) {
+ residences.addAll(source.getResidenceList()
+ .stream().map(JsonAdaptedResidence::new).collect(Collectors.toList()));
+ }
+
+ /**
+ * Converts residences into the model's {@code ResidenceTracker} object.
+ *
+ * @throws IllegalValueException if there were any data constraints violated.
+ */
+ public ResidenceTracker toModelType() throws IllegalValueException {
+ ResidenceTracker residenceTracker = new ResidenceTracker();
+ for (JsonAdaptedResidence jsonAdaptedResidence : residences) {
+ Residence residence = jsonAdaptedResidence.toModelType();
+ if (residenceTracker.hasResidence(residence)) {
+ throw new IllegalValueException(MESSAGE_DUPLICATE_RESIDENCE);
+ }
+ residenceTracker.addResidence(residence);
+ }
+ return residenceTracker;
+ }
+
+}
diff --git a/src/main/java/seedu/address/storage/ResidenceTrackerStorage.java b/src/main/java/seedu/address/storage/ResidenceTrackerStorage.java
new file mode 100644
index 00000000000..10f0d9cc8db
--- /dev/null
+++ b/src/main/java/seedu/address/storage/ResidenceTrackerStorage.java
@@ -0,0 +1,45 @@
+package seedu.address.storage;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Optional;
+
+import seedu.address.commons.exceptions.DataConversionException;
+import seedu.address.model.ReadOnlyResidenceTracker;
+
+/**
+ * Represents a storage for {@link seedu.address.model.ResidenceTracker}.
+ */
+public interface ResidenceTrackerStorage {
+
+ /**
+ * Returns the file path of the data file.
+ */
+ Path getResidenceTrackerFilePath();
+
+ /**
+ * Returns ResidenceTracker data as a {@link ReadOnlyResidenceTracker}.
+ * Returns {@code Optional.empty()} if storage file is not found.
+ * @throws DataConversionException if the data in storage is not in the expected format.
+ * @throws IOException if there was any problem when reading from the storage.
+ */
+ Optional readResidenceTracker() throws DataConversionException, IOException;
+
+ /**
+ * @see #getResidenceTrackerFilePath()
+ */
+ Optional readResidenceTracker(Path filePath) throws DataConversionException, IOException;
+
+ /**
+ * Saves the given {@link ReadOnlyResidenceTracker} to the storage.
+ * @param residenceTracker cannot be null.
+ * @throws IOException if there was any problem writing to the file.
+ */
+ void saveResidenceTracker(ReadOnlyResidenceTracker residenceTracker) throws IOException;
+
+ /**
+ * @see #saveResidenceTracker(ReadOnlyResidenceTracker)
+ */
+ void saveResidenceTracker(ReadOnlyResidenceTracker residenceTracker, Path filePath) throws IOException;
+
+}
diff --git a/src/main/java/seedu/address/storage/Storage.java b/src/main/java/seedu/address/storage/Storage.java
index beda8bd9f11..9d590093ba8 100644
--- a/src/main/java/seedu/address/storage/Storage.java
+++ b/src/main/java/seedu/address/storage/Storage.java
@@ -5,14 +5,14 @@
import java.util.Optional;
import seedu.address.commons.exceptions.DataConversionException;
-import seedu.address.model.ReadOnlyAddressBook;
+import seedu.address.model.ReadOnlyResidenceTracker;
import seedu.address.model.ReadOnlyUserPrefs;
import seedu.address.model.UserPrefs;
/**
* API of the Storage component
*/
-public interface Storage extends AddressBookStorage, UserPrefsStorage {
+public interface Storage extends ResidenceTrackerStorage, UserPrefsStorage {
@Override
Optional readUserPrefs() throws DataConversionException, IOException;
@@ -21,12 +21,12 @@ public interface Storage extends AddressBookStorage, UserPrefsStorage {
void saveUserPrefs(ReadOnlyUserPrefs userPrefs) throws IOException;
@Override
- Path getAddressBookFilePath();
+ Path getResidenceTrackerFilePath();
@Override
- Optional readAddressBook() throws DataConversionException, IOException;
+ Optional readResidenceTracker() throws DataConversionException, IOException;
@Override
- void saveAddressBook(ReadOnlyAddressBook addressBook) throws IOException;
+ void saveResidenceTracker(ReadOnlyResidenceTracker residenceTracker) throws IOException;
}
diff --git a/src/main/java/seedu/address/storage/StorageManager.java b/src/main/java/seedu/address/storage/StorageManager.java
index 79868290974..00559110d87 100644
--- a/src/main/java/seedu/address/storage/StorageManager.java
+++ b/src/main/java/seedu/address/storage/StorageManager.java
@@ -7,25 +7,25 @@
import seedu.address.commons.core.LogsCenter;
import seedu.address.commons.exceptions.DataConversionException;
-import seedu.address.model.ReadOnlyAddressBook;
+import seedu.address.model.ReadOnlyResidenceTracker;
import seedu.address.model.ReadOnlyUserPrefs;
import seedu.address.model.UserPrefs;
/**
- * Manages storage of AddressBook data in local storage.
+ * Manages storage of ResidenceTracker data in local storage.
*/
public class StorageManager implements Storage {
private static final Logger logger = LogsCenter.getLogger(StorageManager.class);
- private AddressBookStorage addressBookStorage;
+ private ResidenceTrackerStorage residenceTrackerStorage;
private UserPrefsStorage userPrefsStorage;
/**
- * Creates a {@code StorageManager} with the given {@code AddressBookStorage} and {@code UserPrefStorage}.
+ * Creates a {@code StorageManager} with the given {@code ResidenceTrackerStorage} and {@code UserPrefStorage}.
*/
- public StorageManager(AddressBookStorage addressBookStorage, UserPrefsStorage userPrefsStorage) {
+ public StorageManager(ResidenceTrackerStorage residenceTrackerStorage, UserPrefsStorage userPrefsStorage) {
super();
- this.addressBookStorage = addressBookStorage;
+ this.residenceTrackerStorage = residenceTrackerStorage;
this.userPrefsStorage = userPrefsStorage;
}
@@ -47,33 +47,34 @@ public void saveUserPrefs(ReadOnlyUserPrefs userPrefs) throws IOException {
}
- // ================ AddressBook methods ==============================
+ // ================ ResidenceTracker methods ==============================
@Override
- public Path getAddressBookFilePath() {
- return addressBookStorage.getAddressBookFilePath();
+ public Path getResidenceTrackerFilePath() {
+ return residenceTrackerStorage.getResidenceTrackerFilePath();
}
@Override
- public Optional readAddressBook() throws DataConversionException, IOException {
- return readAddressBook(addressBookStorage.getAddressBookFilePath());
+ public Optional readResidenceTracker() throws DataConversionException, IOException {
+ return readResidenceTracker(residenceTrackerStorage.getResidenceTrackerFilePath());
}
@Override
- public Optional readAddressBook(Path filePath) throws DataConversionException, IOException {
+ public Optional readResidenceTracker(Path filePath)
+ throws DataConversionException, IOException {
logger.fine("Attempting to read data from file: " + filePath);
- return addressBookStorage.readAddressBook(filePath);
+ return residenceTrackerStorage.readResidenceTracker(filePath);
}
@Override
- public void saveAddressBook(ReadOnlyAddressBook addressBook) throws IOException {
- saveAddressBook(addressBook, addressBookStorage.getAddressBookFilePath());
+ public void saveResidenceTracker(ReadOnlyResidenceTracker residenceTracker) throws IOException {
+ saveResidenceTracker(residenceTracker, residenceTrackerStorage.getResidenceTrackerFilePath());
}
@Override
- public void saveAddressBook(ReadOnlyAddressBook addressBook, Path filePath) throws IOException {
+ public void saveResidenceTracker(ReadOnlyResidenceTracker residenceTracker, Path filePath) throws IOException {
logger.fine("Attempting to write to data file: " + filePath);
- addressBookStorage.saveAddressBook(addressBook, filePath);
+ residenceTrackerStorage.saveResidenceTracker(residenceTracker, filePath);
}
}
diff --git a/src/main/java/seedu/address/ui/HelpWindow.java b/src/main/java/seedu/address/ui/HelpWindow.java
index 9a665915949..d43d80415b6 100644
--- a/src/main/java/seedu/address/ui/HelpWindow.java
+++ b/src/main/java/seedu/address/ui/HelpWindow.java
@@ -9,14 +9,142 @@
import javafx.scene.input.ClipboardContent;
import javafx.stage.Stage;
import seedu.address.commons.core.LogsCenter;
+import seedu.address.logic.commands.AddBookingCommand;
+import seedu.address.logic.commands.AddCommand;
+import seedu.address.logic.commands.ClearCommand;
+import seedu.address.logic.commands.DeleteBookingCommand;
+import seedu.address.logic.commands.DeleteCommand;
+import seedu.address.logic.commands.EditBookingCommand;
+import seedu.address.logic.commands.EditCommand;
+import seedu.address.logic.commands.ExitCommand;
+import seedu.address.logic.commands.FindCommand;
+import seedu.address.logic.commands.ListCommand;
+import seedu.address.logic.commands.RemindCommand;
+import seedu.address.logic.commands.StatusCommand;
+import seedu.address.logic.parser.CliSyntax;
/**
* Controller for a help page
*/
public class HelpWindow extends UiPart {
+ public static final String USERGUIDE_URL = "https://ay2021s2-cs2103-t16-3.github.io/tp/UserGuide.html";
- public static final String USERGUIDE_URL = "https://se-education.org/addressbook-level3/UserGuide.html";
- public static final String HELP_MESSAGE = "Refer to the user guide: " + USERGUIDE_URL;
+ public static final String ADD_PROMPT = AddCommand.getCommandWord()
+ + " - Adds a residence into ResidenceTracker. If a parameter is specified "
+ + "multiple times, only the last occurrence will be taken."
+ + "\nEnter \"" + AddCommand.getCommandWord()
+ + " " + CliSyntax.PREFIX_NAME + "NAME_OF_RESIDENCE "
+ + CliSyntax.PREFIX_RESIDENCE_ADDRESS + "ADDRESS "
+ + "[" + CliSyntax.PREFIX_CLEAN_STATUS_TAG + "VALID_CLEAN_STATUS]"
+ + " [" + CliSyntax.PREFIX_TAG + "TAG]...\""
+ + "\nExample: " + AddCommand.getCommandWord() + " "
+ + CliSyntax.PREFIX_NAME + "Clementi HDB "
+ + CliSyntax.PREFIX_RESIDENCE_ADDRESS
+ + "459A Clementi Ave 3, #04-257, S121459 "
+ + CliSyntax.PREFIX_CLEAN_STATUS_TAG + "n "
+ + CliSyntax.PREFIX_TAG + "Reserved\n\n";
+
+ public static final String ADDB_PROMPT = AddBookingCommand.getCommandWord()
+ + " - Adds a booking to a residence. If a parameter is specified "
+ + "multiple times, only the last occurrence will be taken."
+ + "\nEnter \""
+ + AddBookingCommand.getCommandWord() + " RESIDENCE_INDEX "
+ + CliSyntax.PREFIX_NAME + "NAME_OF_BOOKER "
+ + CliSyntax.PREFIX_PHONE + "PHONE_OF_BOOKER "
+ + CliSyntax.PREFIX_BOOKING_START_DATE + "START_TIME "
+ + CliSyntax.PREFIX_BOOKING_END_DATE + "END_TIME\""
+ + "\nExample: " + AddBookingCommand.getCommandWord()
+ + " 1 " + CliSyntax.PREFIX_NAME + "John "
+ + CliSyntax.PREFIX_PHONE + "91234567 "
+ + CliSyntax.PREFIX_BOOKING_START_DATE + "01-01-2021 "
+ + CliSyntax.PREFIX_BOOKING_END_DATE + "02-01-2021\n\n";
+
+ public static final String CLEAR_PROMPT = ClearCommand.getCommandWord()
+ + " - Clears all entries from the residence tracker."
+ + "\nEnter \"" + ClearCommand.getCommandWord() + "\"\n\n";
+
+ public static final String DELETE_PROMPT = DeleteCommand.getCommandWord()
+ + " - Deletes the specified residence from the list of residences "
+ + "based on index."
+ + "\nEnter \"" + DeleteCommand.getCommandWord() + "INDEX\""
+ + "\nExample: " + DeleteCommand.getCommandWord() + " 3\n\n";
+
+ public static final String DELETEB_PROMPT = DeleteBookingCommand.getCommandWord()
+ + " - Deletes the specified booking from the specified residence "
+ + "based on index."
+ + "\nEnter \"" + DeleteBookingCommand.getCommandWord()
+ + " " + CliSyntax.PREFIX_RESIDENCE + "RESIDENCE_INDEX "
+ + CliSyntax.PREFIX_BOOKING + "BOOKING_INDEX\""
+ + "\nExample: " + DeleteBookingCommand.getCommandWord()
+ + " " + CliSyntax.PREFIX_RESIDENCE + "3 "
+ + CliSyntax.PREFIX_BOOKING + "2\n\n";
+
+ public static final String EDIT_PROMPT = EditCommand.getCommandWord()
+ + " - Edits fields of an existing residence (other than bookings)."
+ + "\nEnter \"" + EditCommand.getCommandWord() + " INDEX "
+ + CliSyntax.PREFIX_CLEAN_STATUS_TAG + "n\""
+ + "\nExample: " + EditCommand.getCommandWord() + " 2 "
+ + CliSyntax.PREFIX_CLEAN_STATUS_TAG + "n\n\n";
+
+ public static final String EDITB_PROMPT = EditBookingCommand.getCommandWord()
+ + " - Edits the details of the booking identified by "
+ + "booking index of the residence identified "
+ + "based on the residence's index provided. "
+ + "\nExisting values will be overwritten by the input values."
+ + "\nEnter \"" + EditBookingCommand.getCommandWord()
+ + " " + CliSyntax.PREFIX_RESIDENCE + " RESIDENCE_INDEX "
+ + CliSyntax.PREFIX_BOOKING + " BOOKING_INDEX "
+ + "[" + CliSyntax.PREFIX_NAME + "NAME] "
+ + "[" + CliSyntax.PREFIX_PHONE + "PHONE] "
+ + "[" + CliSyntax.PREFIX_BOOKING_START_DATE + "START_DATE] "
+ + "[" + CliSyntax.PREFIX_BOOKING_END_DATE + "END_DATE]\""
+ + "\nExample: " + EditBookingCommand.getCommandWord()
+ + " " + CliSyntax.PREFIX_RESIDENCE + "1 "
+ + CliSyntax.PREFIX_BOOKING + "1 "
+ + CliSyntax.PREFIX_BOOKING_START_DATE + "01-01-2020\n\n";
+
+
+
+ public static final String STATUS_PROMPT = StatusCommand.getCommandWord()
+ + " - Updates multiple residences' clean status "
+ + "by the index number used in the displayed residence list."
+ + "\nEnter \"" + StatusCommand.getCommandWord()
+ + "clean INDEX1 INDEX2 ...\""
+ + "\n Example: " + StatusCommand.getCommandWord() + " clean 1 2 4\n\n";
+
+
+ public static final String FIND_PROMPT = FindCommand.getCommandWord()
+ + " - Finds residences whose name contains the given keyword."
+ + "\nEnter \"" + FindCommand.getCommandWord() + " KEYWORDS\""
+ + "\nExample: " + FindCommand.getCommandWord() + " Heights Condo\n\n";
+
+ public static final String LIST_PROMPT = ListCommand.getCommandWord()
+ + " - Shows a list of all residences in ResidenceTracker."
+ + "\nEnter \"" + ListCommand.getCommandWord() + "\"\n\n";
+
+ public static final String REMIND_PROMPT = RemindCommand.getCommandWord()
+ + " - Shows a list of residences with bookings starting in the next 7 days."
+ + "\nEnter \"" + RemindCommand.getCommandWord() + "\"\n\n";
+
+ public static final String EXIT_PROMPT = ExitCommand.getCommandWord() + " - Exits the program."
+ + "\nEnter \"" + ExitCommand.getCommandWord() + "\"\n\n";
+
+
+ public static final String HELP_MESSAGE = "List of commands:\n"
+ + ADD_PROMPT
+ + ADDB_PROMPT
+ + CLEAR_PROMPT
+ + DELETE_PROMPT
+ + DELETEB_PROMPT
+ + EDIT_PROMPT
+ + EDITB_PROMPT
+ + STATUS_PROMPT
+ + FIND_PROMPT
+ + LIST_PROMPT
+ + REMIND_PROMPT
+ + EXIT_PROMPT;
+
+ public static final String URL_MESSAGE = "For more info, refer to user guide: " + USERGUIDE_URL;
private static final Logger logger = LogsCenter.getLogger(HelpWindow.class);
private static final String FXML = "HelpWindow.fxml";
@@ -27,6 +155,9 @@ public class HelpWindow extends UiPart {
@FXML
private Label helpMessage;
+ @FXML
+ private Label urlMessage;
+
/**
* Creates a new HelpWindow.
*
@@ -35,6 +166,7 @@ public class HelpWindow extends UiPart {
public HelpWindow(Stage root) {
super(FXML, root);
helpMessage.setText(HELP_MESSAGE);
+ urlMessage.setText(URL_MESSAGE);
}
/**
diff --git a/src/main/java/seedu/address/ui/MainWindow.java b/src/main/java/seedu/address/ui/MainWindow.java
index 9106c3aa6e5..87d10217ca9 100644
--- a/src/main/java/seedu/address/ui/MainWindow.java
+++ b/src/main/java/seedu/address/ui/MainWindow.java
@@ -31,7 +31,7 @@ public class MainWindow extends UiPart {
private Logic logic;
// Independent Ui parts residing in this Ui container
- private PersonListPanel personListPanel;
+ private ResidenceListPanel residenceListPanel;
private ResultDisplay resultDisplay;
private HelpWindow helpWindow;
@@ -42,7 +42,7 @@ public class MainWindow extends UiPart {
private MenuItem helpMenuItem;
@FXML
- private StackPane personListPanelPlaceholder;
+ private StackPane residenceListPanelPlaceholder;
@FXML
private StackPane resultDisplayPlaceholder;
@@ -110,13 +110,13 @@ private void setAccelerator(MenuItem menuItem, KeyCombination keyCombination) {
* Fills up all the placeholders of this window.
*/
void fillInnerParts() {
- personListPanel = new PersonListPanel(logic.getFilteredPersonList());
- personListPanelPlaceholder.getChildren().add(personListPanel.getRoot());
+ residenceListPanel = new ResidenceListPanel(logic.getFilteredResidenceList());
+ residenceListPanelPlaceholder.getChildren().add(residenceListPanel.getRoot());
resultDisplay = new ResultDisplay();
resultDisplayPlaceholder.getChildren().add(resultDisplay.getRoot());
- StatusBarFooter statusBarFooter = new StatusBarFooter(logic.getAddressBookFilePath());
+ StatusBarFooter statusBarFooter = new StatusBarFooter(logic.getResidenceTrackerFilePath());
statusbarPlaceholder.getChildren().add(statusBarFooter.getRoot());
CommandBox commandBox = new CommandBox(this::executeCommand);
@@ -163,8 +163,8 @@ private void handleExit() {
primaryStage.hide();
}
- public PersonListPanel getPersonListPanel() {
- return personListPanel;
+ public ResidenceListPanel getResidenceListPanel() {
+ return residenceListPanel;
}
/**
diff --git a/src/main/java/seedu/address/ui/PersonCard.java b/src/main/java/seedu/address/ui/PersonCard.java
deleted file mode 100644
index 7fc927bc5d9..00000000000
--- a/src/main/java/seedu/address/ui/PersonCard.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package seedu.address.ui;
-
-import java.util.Comparator;
-
-import javafx.fxml.FXML;
-import javafx.scene.control.Label;
-import javafx.scene.layout.FlowPane;
-import javafx.scene.layout.HBox;
-import javafx.scene.layout.Region;
-import seedu.address.model.person.Person;
-
-/**
- * An UI component that displays information of a {@code Person}.
- */
-public class PersonCard extends UiPart {
-
- private static final String FXML = "PersonListCard.fxml";
-
- /**
- * Note: Certain keywords such as "location" and "resources" are reserved keywords in JavaFX.
- * As a consequence, UI elements' variable names cannot be set to such keywords
- * or an exception will be thrown by JavaFX during runtime.
- *
- * @see The issue on AddressBook level 4
- */
-
- public final Person person;
-
- @FXML
- private HBox cardPane;
- @FXML
- private Label name;
- @FXML
- private Label id;
- @FXML
- private Label phone;
- @FXML
- private Label address;
- @FXML
- private Label email;
- @FXML
- private FlowPane tags;
-
- /**
- * Creates a {@code PersonCode} with the given {@code Person} and index to display.
- */
- public PersonCard(Person person, int displayedIndex) {
- super(FXML);
- this.person = person;
- id.setText(displayedIndex + ". ");
- name.setText(person.getName().fullName);
- phone.setText(person.getPhone().value);
- address.setText(person.getAddress().value);
- email.setText(person.getEmail().value);
- person.getTags().stream()
- .sorted(Comparator.comparing(tag -> tag.tagName))
- .forEach(tag -> tags.getChildren().add(new Label(tag.tagName)));
- }
-
- @Override
- public boolean equals(Object other) {
- // short circuit if same object
- if (other == this) {
- return true;
- }
-
- // instanceof handles nulls
- if (!(other instanceof PersonCard)) {
- return false;
- }
-
- // state check
- PersonCard card = (PersonCard) other;
- return id.getText().equals(card.id.getText())
- && person.equals(card.person);
- }
-}
diff --git a/src/main/java/seedu/address/ui/PersonListPanel.java b/src/main/java/seedu/address/ui/PersonListPanel.java
deleted file mode 100644
index f4c501a897b..00000000000
--- a/src/main/java/seedu/address/ui/PersonListPanel.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package seedu.address.ui;
-
-import java.util.logging.Logger;
-
-import javafx.collections.ObservableList;
-import javafx.fxml.FXML;
-import javafx.scene.control.ListCell;
-import javafx.scene.control.ListView;
-import javafx.scene.layout.Region;
-import seedu.address.commons.core.LogsCenter;
-import seedu.address.model.person.Person;
-
-/**
- * Panel containing the list of persons.
- */
-public class PersonListPanel extends UiPart {
- private static final String FXML = "PersonListPanel.fxml";
- private final Logger logger = LogsCenter.getLogger(PersonListPanel.class);
-
- @FXML
- private ListView personListView;
-
- /**
- * Creates a {@code PersonListPanel} with the given {@code ObservableList}.
- */
- public PersonListPanel(ObservableList personList) {
- super(FXML);
- personListView.setItems(personList);
- personListView.setCellFactory(listView -> new PersonListViewCell());
- }
-
- /**
- * Custom {@code ListCell} that displays the graphics of a {@code Person} using a {@code PersonCard}.
- */
- class PersonListViewCell extends ListCell {
- @Override
- protected void updateItem(Person person, boolean empty) {
- super.updateItem(person, empty);
-
- if (empty || person == null) {
- setGraphic(null);
- setText(null);
- } else {
- setGraphic(new PersonCard(person, getIndex() + 1).getRoot());
- }
- }
- }
-
-}
diff --git a/src/main/java/seedu/address/ui/ResidenceCard.java b/src/main/java/seedu/address/ui/ResidenceCard.java
new file mode 100644
index 00000000000..c3f6cf9e07f
--- /dev/null
+++ b/src/main/java/seedu/address/ui/ResidenceCard.java
@@ -0,0 +1,123 @@
+package seedu.address.ui;
+
+import java.time.LocalDate;
+import java.util.Comparator;
+
+import javafx.collections.ObservableList;
+import javafx.fxml.FXML;
+import javafx.geometry.Insets;
+import javafx.scene.control.Label;
+import javafx.scene.control.ScrollPane;
+import javafx.scene.layout.AnchorPane;
+import javafx.scene.layout.Background;
+import javafx.scene.layout.BackgroundFill;
+import javafx.scene.layout.CornerRadii;
+import javafx.scene.layout.FlowPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Region;
+import javafx.scene.layout.VBox;
+import javafx.scene.paint.Color;
+import seedu.address.model.booking.Booking;
+import seedu.address.model.residence.Residence;
+
+public class ResidenceCard extends UiPart {
+
+ private static final String FXML = "ResidenceListCard.fxml";
+
+ public final Residence residence;
+
+ private LocalDate today = LocalDate.now();
+
+ @FXML
+ private HBox cardPane;
+ @FXML
+ private Label name;
+ @FXML
+ private Label id;
+ @FXML
+ private Label address;
+ @FXML
+ private Label bookingListTitle;
+ @FXML
+ private FlowPane bookingTitlePane;
+ @FXML
+ private FlowPane bookingListPane;
+ @FXML
+ private FlowPane cleanStatusTags;
+ @FXML
+ private FlowPane tags;
+ @FXML
+ private ScrollPane bookingListScrollPane;
+ @FXML
+ private VBox bookingListVBox;
+ @FXML
+ private AnchorPane anchorPane;
+ @FXML
+ private ScrollPane tagsScrollPane;
+
+ /**
+ * Creates a {@code ResidenceCode} with the given {@code residence} and index to display.
+ */
+ public ResidenceCard(Residence residence, int displayedIndex) {
+ super(FXML);
+ this.residence = residence;
+ id.setText(displayedIndex + ". ");
+ name.setText(residence.getResidenceName().getValue());
+ address.setText(residence.getResidenceAddress().getValue());
+ bookingListTitle.setText("BOOKINGS");
+ cleanStatusTags.getChildren().add(new Label(residence.getCleanStatusTag().getValue()));
+
+ residence.getTags().stream()
+ .sorted(Comparator.comparing(tag -> tag.tagName))
+ .forEach(tag -> tags.getChildren().add(new Label(tag.tagName)));
+
+ ObservableList bookingList = residence.getBookingList().getValue();
+
+ for (Booking booking : bookingList) {
+ Label label = new Label(" "
+ + String.valueOf(bookingList.indexOf(booking) + 1)
+ + ". "
+ + booking.toString());
+
+ if (booking.getEnd().compareTo(today) > 0 && booking.getStart().compareTo(today) > 0) {
+ //green for upcoming bookings
+ label.setBackground(new Background(new BackgroundFill(Color.web("#adddce"),
+ new CornerRadii(0.0),
+ new Insets(0.0))));
+ } else if (booking.getEnd().compareTo(today) > 0 && booking.getStart().compareTo(today) <= 0) {
+ //orange for occurring bookings
+ label.setBackground(new Background(new BackgroundFill(Color.web("#fbd7be"),
+ new CornerRadii(0.0),
+ new Insets(0.0))));
+ } else {
+ //red for past/expired bookings
+ label.setBackground(new Background(new BackgroundFill(Color.web("#f6bbc2"),
+ new CornerRadii(0.0),
+ new Insets(0.0))));
+ }
+ HBox holder = new HBox();
+ holder.getChildren().add(label);
+ bookingListVBox.getChildren().add(holder);
+ }
+ }
+
+
+
+ @Override
+ public boolean equals(Object other) {
+ // short circuit if same object
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof ResidenceCard)) {
+ return false;
+ }
+
+ // state check
+ ResidenceCard card = (ResidenceCard) other;
+ return id.getText().equals(card.id.getText())
+ && residence.equals(card.residence);
+ }
+}
diff --git a/src/main/java/seedu/address/ui/ResidenceListPanel.java b/src/main/java/seedu/address/ui/ResidenceListPanel.java
new file mode 100644
index 00000000000..3e18529111b
--- /dev/null
+++ b/src/main/java/seedu/address/ui/ResidenceListPanel.java
@@ -0,0 +1,46 @@
+package seedu.address.ui;
+
+import java.util.logging.Logger;
+
+import javafx.collections.ObservableList;
+import javafx.fxml.FXML;
+import javafx.scene.control.ListCell;
+import javafx.scene.control.ListView;
+import javafx.scene.layout.Region;
+import seedu.address.commons.core.LogsCenter;
+import seedu.address.model.residence.Residence;
+
+public class ResidenceListPanel extends UiPart {
+ private static final String FXML = "ResidenceListPanel.fxml";
+ private final Logger logger = LogsCenter.getLogger(ResidenceListPanel.class);
+
+ @FXML
+ private ListView residenceListView;
+
+ /**
+ * Creates a {@code PersonListPanel} with the given {@code ObservableList}.
+ */
+ public ResidenceListPanel(ObservableList residenceList) {
+ super(FXML);
+ residenceListView.setItems(residenceList);
+ residenceListView.setCellFactory(listView -> new ResidenceListPanel.ResidenceListViewCell());
+ }
+
+ /**
+ * Custom {@code ListCell} that displays the graphics of a {@code Person} using a {@code PersonCard}.
+ */
+ class ResidenceListViewCell extends ListCell {
+ @Override
+ protected void updateItem(Residence residence, boolean empty) {
+ super.updateItem(residence, empty);
+
+ if (empty || residence == null) {
+ setGraphic(null);
+ setText(null);
+ } else {
+ setGraphic(new ResidenceCard(residence, getIndex() + 1).getRoot());
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/seedu/address/ui/UiManager.java b/src/main/java/seedu/address/ui/UiManager.java
index 882027e4537..895434c4c81 100644
--- a/src/main/java/seedu/address/ui/UiManager.java
+++ b/src/main/java/seedu/address/ui/UiManager.java
@@ -20,7 +20,7 @@ public class UiManager implements Ui {
public static final String ALERT_DIALOG_PANE_FIELD_ID = "alertDialogPane";
private static final Logger logger = LogsCenter.getLogger(UiManager.class);
- private static final String ICON_APPLICATION = "/images/address_book_32.png";
+ private static final String ICON_APPLICATION = "/images/residence_tracker.png";
private Logic logic;
private MainWindow mainWindow;
diff --git a/src/main/resources/images/background.png b/src/main/resources/images/background.png
new file mode 100644
index 00000000000..c8dcaa0bd54
Binary files /dev/null and b/src/main/resources/images/background.png differ
diff --git a/src/main/resources/images/residence_tracker.png b/src/main/resources/images/residence_tracker.png
new file mode 100644
index 00000000000..364c31d5e59
Binary files /dev/null and b/src/main/resources/images/residence_tracker.png differ
diff --git a/src/main/resources/images/resultBar.png b/src/main/resources/images/resultBar.png
new file mode 100644
index 00000000000..4b4345b8685
Binary files /dev/null and b/src/main/resources/images/resultBar.png differ
diff --git a/src/main/resources/view/DarkTheme.css b/src/main/resources/view/DarkTheme.css
index 36e6b001cd8..a842880324f 100644
--- a/src/main/resources/view/DarkTheme.css
+++ b/src/main/resources/view/DarkTheme.css
@@ -1,6 +1,7 @@
.background {
- -fx-background-color: derive(#1d1d1d, 20%);
- background-color: #383838; /* Used in the default.html file */
+ -fx-background-color: derive(#FFFAFA, 20%);
+ background-color: #FFFAFA; /* Used in the default.html file */
+
}
.label {
@@ -41,7 +42,7 @@
.table-view {
-fx-base: #1d1d1d;
- -fx-control-inner-background: #1d1d1d;
+ -fx-control-inner-background: #FAEBD7;
-fx-background-color: #1d1d1d;
-fx-table-cell-border-color: transparent;
-fx-table-header-border-color: transparent;
@@ -90,7 +91,8 @@
.list-view {
-fx-background-insets: 0;
-fx-padding: 0;
- -fx-background-color: derive(#1d1d1d, 20%);
+ -fx-background-color: derive(#C2DAF2, 20%);
+
}
.list-cell {
@@ -101,10 +103,18 @@
.list-cell:filled:even {
-fx-background-color: #3c3e3f;
+ -fx-background-image:url(/images/background.png);
+ -fx-background-repeat:no-repeat ;
+ -fx-background-size:100% 100%;
+ -fx-background-attachment: fixed;
}
.list-cell:filled:odd {
-fx-background-color: #515658;
+ -fx-background-image:url(/images/background.png);
+ -fx-background-repeat:no-repeat ;
+ -fx-background-size:100% 100%;
+ -fx-background-attachment: fixed;
}
.list-cell:filled:selected {
@@ -113,11 +123,12 @@
.list-cell:filled:selected #cardPane {
-fx-border-color: #3e7b91;
- -fx-border-width: 1;
+ -fx-border-width: 4;
+ -fx-border-style: dashed;
}
.list-cell .label {
- -fx-text-fill: white;
+ -fx-text-fill: black;
}
.cell_big_label {
@@ -128,29 +139,37 @@
.cell_small_label {
-fx-font-family: "Segoe UI";
- -fx-font-size: 13px;
+ -fx-font-size: 14px;
-fx-text-fill: #010504;
}
.stack-pane {
-fx-background-color: derive(#1d1d1d, 20%);
+ -fx-background-image:url(/images/background.png);
+ -fx-background-repeat:no-repeat ;
+ -fx-background-size:100% 100%;
+ -fx-background-attachment: fixed;
}
.pane-with-border {
- -fx-background-color: derive(#1d1d1d, 20%);
- -fx-border-color: derive(#1d1d1d, 10%);
- -fx-border-top-width: 1px;
+ -fx-background-color: transparent;
+ -fx-border-color: transparent;
+ -fx-background-image:url(/images/background.png);
+ -fx-background-repeat:no-repeat ;
+ -fx-background-size:100% 100%;
+ -fx-background-attachment: fixed;
+ -fx-border-top-width: 2px;
}
.status-bar {
- -fx-background-color: derive(#1d1d1d, 30%);
+ -fx-background-color: #53868B;
}
.result-display {
-fx-background-color: transparent;
-fx-font-family: "Segoe UI Light";
-fx-font-size: 13pt;
- -fx-text-fill: white;
+ -fx-text-fill: black;;
}
.result-display .label {
@@ -193,7 +212,7 @@
}
.menu-bar {
- -fx-background-color: derive(#1d1d1d, 20%);
+ -fx-background-color: #528B8B;
}
.menu-bar .label {
@@ -282,11 +301,11 @@
}
.scroll-bar {
- -fx-background-color: derive(#1d1d1d, 20%);
+ -fx-background-color: derive(#BFCDE7, 30%);
}
.scroll-bar .thumb {
- -fx-background-color: derive(#1d1d1d, 50%);
+ -fx-background-color: derive(#F4E8F6, 50%);
-fx-background-insets: 3;
}
@@ -309,7 +328,7 @@
#cardPane {
-fx-background-color: transparent;
- -fx-border-width: 0;
+ -fx-border-width: 2;
}
#commandTypeLabel {
@@ -318,14 +337,14 @@
}
#commandTextField {
- -fx-background-color: transparent #383838 transparent #383838;
+ -fx-background-color: #F0F8FF;
-fx-background-insets: 0;
-fx-border-color: #383838 #383838 #ffffff #383838;
-fx-border-insets: 0;
-fx-border-width: 1;
-fx-font-family: "Segoe UI Light";
-fx-font-size: 13pt;
- -fx-text-fill: white;
+ -fx-text-fill: #452e52;
}
#filterField, #personListPanel, #personWebpage {
@@ -333,10 +352,31 @@
}
#resultDisplay .content {
- -fx-background-color: transparent, #383838, transparent, #383838;
+ -fx-background-color: transparent;
+ -fx-background-image:url(/images/resultBar.png);
+ -fx-background-repeat:no-repeat ;
+ -fx-background-size:100% 100%;
+ -fx-background-attachment: fixed;
+ -fx-border-color: #383838 #383838 #ffffff #383838;
+ -fx-border-insets: 0;
+ -fx-border-width: 1;
-fx-background-radius: 0;
}
+#cleanStatusTags {
+ -fx-hgap: 7;
+ -fx-vgap: 3;
+}
+
+#cleanStatusTags .label {
+ -fx-text-fill: white;
+ -fx-background-color: #65357e;
+ -fx-padding: 1 3 1 5;
+ -fx-border-radius: 2;
+ -fx-background-radius: 2;
+ -fx-font-size: 13;
+}
+
#tags {
-fx-hgap: 7;
-fx-vgap: 3;
@@ -348,5 +388,42 @@
-fx-padding: 1 3 1 3;
-fx-border-radius: 2;
-fx-background-radius: 2;
- -fx-font-size: 11;
+ -fx-font-size: 13;
+}
+
+#bookingListPane .label {
+ -fx-border-radius: 3;
+ -fx-font-size: 13;
+}
+
+#bookingTitlePane .label {
+ -fx-text-fill: white;
+ -fx-background-color: #3e7b91;
+}
+
+#bookingListScrollPane {
+ -fx-border-color: #7772b6;
+ -fx-border-radius: 2px;
+}
+
+#bookingListScrollPane .viewport {
+ -fx-background-image: url(/images/background.png);
+ -fx-background-repeat: no-repeat ;
+ -fx-background-size: 100% 100%;
+ -fx-background-attachment: fixed;
+}
+
+#bookingListScrollPane .scroll-bar:vertical .thumb {
+ -fx-background-color: #fffef2;
+}
+#bookingListScrollPane .scroll-bar:horizontal .thumb {
+ -fx-background-color: #fffef2;
+}
+
+#tagsScrollPane .viewport {
+ -fx-background-color: transparent;
+}
+
+#tagsScrollPane {
+ -fx-background-color: transparent;
}
diff --git a/src/main/resources/view/Extensions.css b/src/main/resources/view/Extensions.css
index bfe82a85964..d36e77fc15c 100644
--- a/src/main/resources/view/Extensions.css
+++ b/src/main/resources/view/Extensions.css
@@ -5,7 +5,7 @@
.list-cell:empty {
/* Empty cells will not have alternating colours */
- -fx-background: #383838;
+ -fx-background: #C2DAF2;
}
.tag-selector {
diff --git a/src/main/resources/view/HelpWindow.fxml b/src/main/resources/view/HelpWindow.fxml
index fa0fb54d9f4..12dd8022b31 100644
--- a/src/main/resources/view/HelpWindow.fxml
+++ b/src/main/resources/view/HelpWindow.fxml
@@ -4,36 +4,37 @@
+
+
-
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
diff --git a/src/main/resources/view/MainWindow.fxml b/src/main/resources/view/MainWindow.fxml
index a431648f6c0..9ef543d06c4 100644
--- a/src/main/resources/view/MainWindow.fxml
+++ b/src/main/resources/view/MainWindow.fxml
@@ -6,55 +6,53 @@
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
+
+
+
+
diff --git a/src/main/resources/view/ResidenceListCard.fxml b/src/main/resources/view/ResidenceListCard.fxml
new file mode 100644
index 00000000000..422e9593f8b
--- /dev/null
+++ b/src/main/resources/view/ResidenceListCard.fxml
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/view/ResidenceListPanel.fxml b/src/main/resources/view/ResidenceListPanel.fxml
new file mode 100644
index 00000000000..22cf3596555
--- /dev/null
+++ b/src/main/resources/view/ResidenceListPanel.fxml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/src/test/data/JsonAddressBookStorageTest/invalidAndValidPersonAddressBook.json b/src/test/data/JsonAddressBookStorageTest/invalidAndValidPersonAddressBook.json
deleted file mode 100644
index 6a4d2b7181c..00000000000
--- a/src/test/data/JsonAddressBookStorageTest/invalidAndValidPersonAddressBook.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "persons": [ {
- "name": "Valid Person",
- "phone": "9482424",
- "email": "hans@example.com",
- "address": "4th street"
- }, {
- "name": "Person With Invalid Phone Field",
- "phone": "948asdf2424",
- "email": "hans@example.com",
- "address": "4th street"
- } ]
-}
diff --git a/src/test/data/JsonAddressBookStorageTest/invalidPersonAddressBook.json b/src/test/data/JsonAddressBookStorageTest/invalidPersonAddressBook.json
deleted file mode 100644
index ccd21f7d1a9..00000000000
--- a/src/test/data/JsonAddressBookStorageTest/invalidPersonAddressBook.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "persons": [ {
- "name": "Person with invalid name field: Ha!ns Mu@ster",
- "phone": "9482424",
- "email": "hans@example.com",
- "address": "4th street"
- } ]
-}
diff --git a/src/test/data/JsonResidenceTrackerStorageTest/invalidAndValidResidenceResidenceTracker.json b/src/test/data/JsonResidenceTrackerStorageTest/invalidAndValidResidenceResidenceTracker.json
new file mode 100644
index 00000000000..0be894c13ab
--- /dev/null
+++ b/src/test/data/JsonResidenceTrackerStorageTest/invalidAndValidResidenceResidenceTracker.json
@@ -0,0 +1,25 @@
+{
+ "residences" : [ {
+ "bookingList" : [ {
+ "name" : "933230",
+ "phone" : "092382",
+ "start" : "2008-08-08",
+ "end" : "2008-09-09"
+ } ],
+ "cleanStatusTag" : "Unclean",
+ "tags" : [ "Booked" ],
+ "residenceName" : "HDB",
+ "residenceAddress" : "Blk 30 Geylang Street 29, #06-40"
+ }, {
+ "bookingList" : [ {
+ "name" : "933230",
+ "phone" : "0923^@82",
+ "start" : "2008-08-08",
+ "end" : "2008-09-09"
+ } ],
+ "cleanStatusTag" : "Clean",
+ "tags" : [ "Reserved" ],
+ "residenceName" : "Condo",
+ "residenceAddress" : "Blk 45 Tampines Street 29, #08-01"
+ }]
+}
diff --git a/src/test/data/JsonResidenceTrackerStorageTest/invalidResidenceResidenceTracker.json b/src/test/data/JsonResidenceTrackerStorageTest/invalidResidenceResidenceTracker.json
new file mode 100644
index 00000000000..7ab49ed9e05
--- /dev/null
+++ b/src/test/data/JsonResidenceTrackerStorageTest/invalidResidenceResidenceTracker.json
@@ -0,0 +1,9 @@
+{
+ "residences" : [ {
+ "bookingList" : [ ],
+ "cleanStatusTag" : "Unclean",
+ "tags" : [ "Boo ked" ],
+ "residenceName" : "HDB",
+ "residenceAddress" : "Blk 30 Geylang Street 29, #06-40"
+ } ]
+}
diff --git a/src/test/data/JsonAddressBookStorageTest/notJsonFormatAddressBook.json b/src/test/data/JsonResidenceTrackerStorageTest/notJsonFormatResidenceTracker.json
similarity index 100%
rename from src/test/data/JsonAddressBookStorageTest/notJsonFormatAddressBook.json
rename to src/test/data/JsonResidenceTrackerStorageTest/notJsonFormatResidenceTracker.json
diff --git a/src/test/data/JsonSerializableAddressBookTest/duplicatePersonAddressBook.json b/src/test/data/JsonSerializableAddressBookTest/duplicatePersonAddressBook.json
deleted file mode 100644
index 48831cc7674..00000000000
--- a/src/test/data/JsonSerializableAddressBookTest/duplicatePersonAddressBook.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "persons": [ {
- "name": "Alice Pauline",
- "phone": "94351253",
- "email": "alice@example.com",
- "address": "123, Jurong West Ave 6, #08-111",
- "tagged": [ "friends" ]
- }, {
- "name": "Alice Pauline",
- "phone": "94351253",
- "email": "pauline@example.com",
- "address": "4th street"
- } ]
-}
diff --git a/src/test/data/JsonSerializableAddressBookTest/invalidPersonAddressBook.json b/src/test/data/JsonSerializableAddressBookTest/invalidPersonAddressBook.json
deleted file mode 100644
index ad3f135ae42..00000000000
--- a/src/test/data/JsonSerializableAddressBookTest/invalidPersonAddressBook.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "persons": [ {
- "name": "Hans Muster",
- "phone": "9482424",
- "email": "invalid@email!3e",
- "address": "4th street"
- } ]
-}
diff --git a/src/test/data/JsonSerializableAddressBookTest/typicalPersonsAddressBook.json b/src/test/data/JsonSerializableAddressBookTest/typicalPersonsAddressBook.json
deleted file mode 100644
index f10eddee12e..00000000000
--- a/src/test/data/JsonSerializableAddressBookTest/typicalPersonsAddressBook.json
+++ /dev/null
@@ -1,46 +0,0 @@
-{
- "_comment": "AddressBook save file which contains the same Person values as in TypicalPersons#getTypicalAddressBook()",
- "persons" : [ {
- "name" : "Alice Pauline",
- "phone" : "94351253",
- "email" : "alice@example.com",
- "address" : "123, Jurong West Ave 6, #08-111",
- "tagged" : [ "friends" ]
- }, {
- "name" : "Benson Meier",
- "phone" : "98765432",
- "email" : "johnd@example.com",
- "address" : "311, Clementi Ave 2, #02-25",
- "tagged" : [ "owesMoney", "friends" ]
- }, {
- "name" : "Carl Kurz",
- "phone" : "95352563",
- "email" : "heinz@example.com",
- "address" : "wall street",
- "tagged" : [ ]
- }, {
- "name" : "Daniel Meier",
- "phone" : "87652533",
- "email" : "cornelia@example.com",
- "address" : "10th street",
- "tagged" : [ "friends" ]
- }, {
- "name" : "Elle Meyer",
- "phone" : "9482224",
- "email" : "werner@example.com",
- "address" : "michegan ave",
- "tagged" : [ ]
- }, {
- "name" : "Fiona Kunz",
- "phone" : "9482427",
- "email" : "lydia@example.com",
- "address" : "little tokyo",
- "tagged" : [ ]
- }, {
- "name" : "George Best",
- "phone" : "9482442",
- "email" : "anna@example.com",
- "address" : "4th street",
- "tagged" : [ ]
- } ]
-}
diff --git a/src/test/data/JsonSerializableResidenceTrackerTest/duplicateResidenceResidenceTracker.json b/src/test/data/JsonSerializableResidenceTrackerTest/duplicateResidenceResidenceTracker.json
new file mode 100644
index 00000000000..760606c5be1
--- /dev/null
+++ b/src/test/data/JsonSerializableResidenceTrackerTest/duplicateResidenceResidenceTracker.json
@@ -0,0 +1,25 @@
+{
+ "residences" : [ {
+ "bookingList" : [ {
+ "name" : "933230",
+ "phone" : "092382",
+ "start" : "2008-08-08",
+ "end" : "2008-09-09"
+ } ],
+ "cleanStatusTag" : "Unclean",
+ "tags" : [ "Reserved" ],
+ "residenceName" : "HDB",
+ "residenceAddress" : "Blk 30 Geylang Street 29, #06-40"
+ }, {
+ "bookingList" : [ {
+ "name" : "933230",
+ "phone" : "092382",
+ "start" : "2008-08-08",
+ "end" : "2008-09-09"
+ } ],
+ "cleanStatusTag" : "Clean",
+ "tags" : [ "Booked" ],
+ "residenceName" : "HDB",
+ "residenceAddress" : "Blk 31 Geylang Street 29, #06-40"
+ }]
+}
diff --git a/src/test/data/JsonSerializableResidenceTrackerTest/invalidResidenceResidenceTracker.json b/src/test/data/JsonSerializableResidenceTrackerTest/invalidResidenceResidenceTracker.json
new file mode 100644
index 00000000000..c0549b93aca
--- /dev/null
+++ b/src/test/data/JsonSerializableResidenceTrackerTest/invalidResidenceResidenceTracker.json
@@ -0,0 +1,14 @@
+{
+ "residences" : [ {
+ "bookingList" : [ {
+ "name" : "933230",
+ "phone" : "092382",
+ "start" : "2008-08-08",
+ "end" : "2008-07-07"
+ } ],
+ "cleanStatusTag" : "Unclean",
+ "tags" : [ "Booked" ],
+ "residenceName" : "HDB",
+ "residenceAddress" : "Blk 30 Geylang Street 29, #06-40"
+ } ]
+}
diff --git a/src/test/data/JsonSerializableResidenceTrackerTest/typicalResidencesResidenceTracker.json b/src/test/data/JsonSerializableResidenceTrackerTest/typicalResidencesResidenceTracker.json
new file mode 100644
index 00000000000..c102ae0250d
--- /dev/null
+++ b/src/test/data/JsonSerializableResidenceTrackerTest/typicalResidencesResidenceTracker.json
@@ -0,0 +1,76 @@
+{
+ "_comment": "Residence Tracker save file which contains the same Residence values as in TypicalResidence#getTypicalResidenceTracker()",
+ "residences" : [ {
+ "cleanStatusTag" : "Clean",
+ "residenceName" : "Amber Heights",
+ "residenceAddress" : "123, Jurong West Ave 6, #08-111",
+ "bookingList" : [{
+ "name" : "933230",
+ "phone" : "092382",
+ "start" : "2008-08-08",
+ "end" : "2008-09-09"
+ }],
+ "tags" : [ "valuable" ]
+ }, {
+ "cleanStatusTag" : "Unclean",
+ "residenceName" : "Beverly Hills",
+ "residenceAddress" : "311, Clementi Ave 2, #02-25",
+ "bookingList" : [ ],
+ "tags" : [ "repair", "popular" ]
+ }, {
+ "cleanStatusTag" : "Clean",
+ "residenceName" : "Casuarina Apartment",
+ "residenceAddress" : "wall street",
+ "bookingList" : [ {
+ "name" : "933230",
+ "phone" : "092382",
+ "start" : "2008-08-08",
+ "end" : "2008-09-09"
+ }, {
+ "name" : "nsd",
+ "phone" : "098",
+ "start" : "2009-09-09",
+ "end" : "2009-09-09"
+ }, {
+ "name" : "cs",
+ "phone" : "098",
+ "start" : "2010-10-10",
+ "end" : "2011-09-09"
+ } ],
+ "tags" : [ ]
+ }, {
+ "cleanStatusTag" : "Clean",
+ "residenceName" : "Dover Condominium",
+ "residenceAddress" : "10th street",
+ "bookingList" : [ {
+ "name" : "nsd",
+ "phone" : "098",
+ "start" : "2009-09-09",
+ "end" : "2009-09-09"
+ }, {
+ "name" : "cs",
+ "phone" : "098",
+ "start" : "2010-10-10",
+ "end" : "2011-09-09"
+ } ],
+ "tags" : [ "forFriends" ]
+ }, {
+ "cleanStatusTag" : "Clean",
+ "residenceName" : "Emerald Hills",
+ "residenceAddress" : "michegan ave",
+ "bookingList" : [ ],
+ "tags" : [ ]
+ }, {
+ "cleanStatusTag" : "Unclean",
+ "residenceName" : "Floravale",
+ "residenceAddress" : "little tokyo",
+ "bookingList" : [ ],
+ "tags" : [ ]
+ }, {
+ "cleanStatusTag" : "Clean",
+ "residenceName" : "Gem Residences",
+ "residenceAddress" : "4th street",
+ "bookingList" : [ ],
+ "tags" : [ ]
+ } ]
+}
diff --git a/src/test/data/JsonUserPrefsStorageTest/ExtraValuesUserPref.json b/src/test/data/JsonUserPrefsStorageTest/ExtraValuesUserPref.json
index 1037548a9cd..76f88f036bb 100644
--- a/src/test/data/JsonUserPrefsStorageTest/ExtraValuesUserPref.json
+++ b/src/test/data/JsonUserPrefsStorageTest/ExtraValuesUserPref.json
@@ -9,5 +9,5 @@
"z" : 99
}
},
- "addressBookFilePath" : "addressbook.json"
+ "addressBookFilePath" : "residencetracker.json"
}
diff --git a/src/test/data/JsonUserPrefsStorageTest/TypicalUserPref.json b/src/test/data/JsonUserPrefsStorageTest/TypicalUserPref.json
index b819bed900a..39121838ef5 100644
--- a/src/test/data/JsonUserPrefsStorageTest/TypicalUserPref.json
+++ b/src/test/data/JsonUserPrefsStorageTest/TypicalUserPref.json
@@ -7,5 +7,5 @@
"y" : 100
}
},
- "addressBookFilePath" : "addressbook.json"
+ "addressBookFilePath" : "residencetracker.json"
}
diff --git a/src/test/java/seedu/address/logic/LogicManagerTest.java b/src/test/java/seedu/address/logic/LogicManagerTest.java
index ad923ac249a..921f29cf3a8 100644
--- a/src/test/java/seedu/address/logic/LogicManagerTest.java
+++ b/src/test/java/seedu/address/logic/LogicManagerTest.java
@@ -1,14 +1,15 @@
package seedu.address.logic;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static seedu.address.commons.core.Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX;
+import static seedu.address.commons.core.Messages.MESSAGE_INVALID_RESIDENCE_DISPLAYED_INDEX;
import static seedu.address.commons.core.Messages.MESSAGE_UNKNOWN_COMMAND;
-import static seedu.address.logic.commands.CommandTestUtil.ADDRESS_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.EMAIL_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.NAME_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.PHONE_DESC_AMY;
+import static seedu.address.logic.commands.CommandTestUtil.ADDRESS_DESC_RESIDENCE1;
+import static seedu.address.logic.commands.CommandTestUtil.NAME_DESC_RESIDENCE1;
+import static seedu.address.logic.commands.CommandTestUtil.TAG_DESC_RESERVED;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_RESERVED;
+import static seedu.address.model.Model.PREDICATE_SHOW_ALL_RESIDENCES;
import static seedu.address.testutil.Assert.assertThrows;
-import static seedu.address.testutil.TypicalPersons.AMY;
+import static seedu.address.testutil.TypicalResidences.RESIDENCE1;
import java.io.IOException;
import java.nio.file.Path;
@@ -24,13 +25,13 @@
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.Model;
import seedu.address.model.ModelManager;
-import seedu.address.model.ReadOnlyAddressBook;
+import seedu.address.model.ReadOnlyResidenceTracker;
import seedu.address.model.UserPrefs;
-import seedu.address.model.person.Person;
-import seedu.address.storage.JsonAddressBookStorage;
+import seedu.address.model.residence.Residence;
+import seedu.address.storage.JsonResidenceTrackerStorage;
import seedu.address.storage.JsonUserPrefsStorage;
import seedu.address.storage.StorageManager;
-import seedu.address.testutil.PersonBuilder;
+import seedu.address.testutil.ResidenceBuilder;
public class LogicManagerTest {
private static final IOException DUMMY_IO_EXCEPTION = new IOException("dummy exception");
@@ -43,10 +44,10 @@ public class LogicManagerTest {
@BeforeEach
public void setUp() {
- JsonAddressBookStorage addressBookStorage =
- new JsonAddressBookStorage(temporaryFolder.resolve("addressBook.json"));
+ JsonResidenceTrackerStorage residenceTrackerStorage =
+ new JsonResidenceTrackerStorage(temporaryFolder.resolve("residenceTracker.json"));
JsonUserPrefsStorage userPrefsStorage = new JsonUserPrefsStorage(temporaryFolder.resolve("userPrefs.json"));
- StorageManager storage = new StorageManager(addressBookStorage, userPrefsStorage);
+ StorageManager storage = new StorageManager(residenceTrackerStorage, userPrefsStorage);
logic = new LogicManager(model, storage);
}
@@ -59,7 +60,7 @@ public void execute_invalidCommandFormat_throwsParseException() {
@Test
public void execute_commandExecutionError_throwsCommandException() {
String deleteCommand = "delete 9";
- assertCommandException(deleteCommand, MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
+ assertCommandException(deleteCommand, MESSAGE_INVALID_RESIDENCE_DISPLAYED_INDEX);
}
@Test
@@ -70,27 +71,28 @@ public void execute_validCommand_success() throws Exception {
@Test
public void execute_storageThrowsIoException_throwsCommandException() {
- // Setup LogicManager with JsonAddressBookIoExceptionThrowingStub
- JsonAddressBookStorage addressBookStorage =
- new JsonAddressBookIoExceptionThrowingStub(temporaryFolder.resolve("ioExceptionAddressBook.json"));
+ // Setup LogicManager with JsonResidenceTrackerIoExceptionThrowingStub
+ JsonResidenceTrackerStorage residenceTrackerStorage =
+ new JsonResidenceTrackerIoExceptionThrowingStub(temporaryFolder.resolve("ioExceptionAddressBook.json"));
JsonUserPrefsStorage userPrefsStorage =
new JsonUserPrefsStorage(temporaryFolder.resolve("ioExceptionUserPrefs.json"));
- StorageManager storage = new StorageManager(addressBookStorage, userPrefsStorage);
+ StorageManager storage = new StorageManager(residenceTrackerStorage, userPrefsStorage);
logic = new LogicManager(model, storage);
// Execute add command
- String addCommand = AddCommand.COMMAND_WORD + NAME_DESC_AMY + PHONE_DESC_AMY + EMAIL_DESC_AMY
- + ADDRESS_DESC_AMY;
- Person expectedPerson = new PersonBuilder(AMY).withTags().build();
+ String addCommand = AddCommand.COMMAND_WORD + NAME_DESC_RESIDENCE1 + ADDRESS_DESC_RESIDENCE1
+ + TAG_DESC_RESERVED;
+ Residence expectedResidence = new ResidenceBuilder(RESIDENCE1).withTags(VALID_TAG_RESERVED).build();
ModelManager expectedModel = new ModelManager();
- expectedModel.addPerson(expectedPerson);
+ expectedModel.addResidence(expectedResidence);
+ expectedModel.updateFilteredResidenceList(PREDICATE_SHOW_ALL_RESIDENCES);
String expectedMessage = LogicManager.FILE_OPS_ERROR_MESSAGE + DUMMY_IO_EXCEPTION;
assertCommandFailure(addCommand, CommandException.class, expectedMessage, expectedModel);
}
@Test
- public void getFilteredPersonList_modifyList_throwsUnsupportedOperationException() {
- assertThrows(UnsupportedOperationException.class, () -> logic.getFilteredPersonList().remove(0));
+ public void getFilteredResidenceList_modifyList_throwsUnsupportedOperationException() {
+ assertThrows(UnsupportedOperationException.class, () -> logic.getFilteredResidenceList().remove(0));
}
/**
@@ -129,7 +131,7 @@ private void assertCommandException(String inputCommand, String expectedMessage)
*/
private void assertCommandFailure(String inputCommand, Class extends Throwable> expectedException,
String expectedMessage) {
- Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs());
+ Model expectedModel = new ModelManager(model.getResidenceTracker(), new UserPrefs());
assertCommandFailure(inputCommand, expectedException, expectedMessage, expectedModel);
}
@@ -141,7 +143,7 @@ private void assertCommandFailure(String inputCommand, Class extends Throwable
* @see #assertCommandSuccess(String, String, Model)
*/
private void assertCommandFailure(String inputCommand, Class extends Throwable> expectedException,
- String expectedMessage, Model expectedModel) {
+ String expectedMessage, Model expectedModel) {
assertThrows(expectedException, expectedMessage, () -> logic.execute(inputCommand));
assertEquals(expectedModel, model);
}
@@ -149,13 +151,13 @@ private void assertCommandFailure(String inputCommand, Class extends Throwable
/**
* A stub class to throw an {@code IOException} when the save method is called.
*/
- private static class JsonAddressBookIoExceptionThrowingStub extends JsonAddressBookStorage {
- private JsonAddressBookIoExceptionThrowingStub(Path filePath) {
+ private static class JsonResidenceTrackerIoExceptionThrowingStub extends JsonResidenceTrackerStorage {
+ private JsonResidenceTrackerIoExceptionThrowingStub(Path filePath) {
super(filePath);
}
@Override
- public void saveAddressBook(ReadOnlyAddressBook addressBook, Path filePath) throws IOException {
+ public void saveResidenceTracker(ReadOnlyResidenceTracker residenceTracker, Path filePath) throws IOException {
throw DUMMY_IO_EXCEPTION;
}
}
diff --git a/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java b/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java
index cb8714bb055..0b6f1e046d5 100644
--- a/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java
+++ b/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java
@@ -2,7 +2,8 @@
import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure;
import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
+import static seedu.address.model.Model.PREDICATE_SHOW_ALL_RESIDENCES;
+import static seedu.address.testutil.TypicalResidences.getTypicalResidenceTracker;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -10,8 +11,8 @@
import seedu.address.model.Model;
import seedu.address.model.ModelManager;
import seedu.address.model.UserPrefs;
-import seedu.address.model.person.Person;
-import seedu.address.testutil.PersonBuilder;
+import seedu.address.model.residence.Residence;
+import seedu.address.testutil.ResidenceBuilder;
/**
* Contains integration tests (interaction with the Model) for {@code AddCommand}.
@@ -22,24 +23,25 @@ public class AddCommandIntegrationTest {
@BeforeEach
public void setUp() {
- model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
+ model = new ModelManager(getTypicalResidenceTracker(), new UserPrefs());
}
@Test
- public void execute_newPerson_success() {
- Person validPerson = new PersonBuilder().build();
+ public void execute_newResidence_success() {
+ Residence validResidence = new ResidenceBuilder().build();
- Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs());
- expectedModel.addPerson(validPerson);
+ Model expectedModel = new ModelManager(model.getResidenceTracker(), new UserPrefs());
+ expectedModel.addResidence(validResidence);
+ expectedModel.updateFilteredResidenceList(PREDICATE_SHOW_ALL_RESIDENCES);
- assertCommandSuccess(new AddCommand(validPerson), model,
- String.format(AddCommand.MESSAGE_SUCCESS, validPerson), expectedModel);
+ assertCommandSuccess(new AddCommand(validResidence), model,
+ String.format(AddCommand.MESSAGE_SUCCESS, validResidence), expectedModel);
}
@Test
- public void execute_duplicatePerson_throwsCommandException() {
- Person personInList = model.getAddressBook().getPersonList().get(0);
- assertCommandFailure(new AddCommand(personInList), model, AddCommand.MESSAGE_DUPLICATE_PERSON);
+ public void execute_duplicateResidence_throwsCommandException() {
+ Residence residenceInList = model.getResidenceTracker().getResidenceList().get(0);
+ assertCommandFailure(new AddCommand(residenceInList), model, AddCommand.MESSAGE_DUPLICATE_RESIDENCE);
}
}
diff --git a/src/test/java/seedu/address/logic/commands/AddCommandTest.java b/src/test/java/seedu/address/logic/commands/AddCommandTest.java
index 5865713d5dd..74c1392fb6f 100644
--- a/src/test/java/seedu/address/logic/commands/AddCommandTest.java
+++ b/src/test/java/seedu/address/logic/commands/AddCommandTest.java
@@ -16,62 +16,63 @@
import javafx.collections.ObservableList;
import seedu.address.commons.core.GuiSettings;
import seedu.address.logic.commands.exceptions.CommandException;
-import seedu.address.model.AddressBook;
import seedu.address.model.Model;
-import seedu.address.model.ReadOnlyAddressBook;
+import seedu.address.model.ReadOnlyResidenceTracker;
import seedu.address.model.ReadOnlyUserPrefs;
-import seedu.address.model.person.Person;
-import seedu.address.testutil.PersonBuilder;
+import seedu.address.model.ResidenceTracker;
+import seedu.address.model.residence.Residence;
+import seedu.address.testutil.ResidenceBuilder;
public class AddCommandTest {
@Test
- public void constructor_nullPerson_throwsNullPointerException() {
+ public void constructor_nullResidence_throwsNullPointerException() {
assertThrows(NullPointerException.class, () -> new AddCommand(null));
}
@Test
- public void execute_personAcceptedByModel_addSuccessful() throws Exception {
- ModelStubAcceptingPersonAdded modelStub = new ModelStubAcceptingPersonAdded();
- Person validPerson = new PersonBuilder().build();
+ public void execute_residenceAcceptedByModel_addSuccessful() throws Exception {
+ ModelStubAcceptingResidenceAdded modelStub = new ModelStubAcceptingResidenceAdded();
+ Residence validResidence = new ResidenceBuilder().build();
- CommandResult commandResult = new AddCommand(validPerson).execute(modelStub);
+ CommandResult commandResult = new AddCommand(validResidence).execute(modelStub);
- assertEquals(String.format(AddCommand.MESSAGE_SUCCESS, validPerson), commandResult.getFeedbackToUser());
- assertEquals(Arrays.asList(validPerson), modelStub.personsAdded);
+ assertEquals(String.format(AddCommand.MESSAGE_SUCCESS, validResidence), commandResult.getFeedbackToUser());
+ assertEquals(Arrays.asList(validResidence), modelStub.residencesAdded);
}
@Test
- public void execute_duplicatePerson_throwsCommandException() {
- Person validPerson = new PersonBuilder().build();
- AddCommand addCommand = new AddCommand(validPerson);
- ModelStub modelStub = new ModelStubWithPerson(validPerson);
+ public void execute_duplicateResidence_throwsCommandException() {
+ Residence validResidence = new ResidenceBuilder().build();
+ AddCommand addCommand = new AddCommand(validResidence);
+ ModelStub modelStub = new ModelStubWithResidence(validResidence);
- assertThrows(CommandException.class, AddCommand.MESSAGE_DUPLICATE_PERSON, () -> addCommand.execute(modelStub));
+ assertThrows(CommandException.class,
+ AddCommand.MESSAGE_DUPLICATE_RESIDENCE, () -> addCommand.execute(modelStub));
}
@Test
public void equals() {
- Person alice = new PersonBuilder().withName("Alice").build();
- Person bob = new PersonBuilder().withName("Bob").build();
- AddCommand addAliceCommand = new AddCommand(alice);
- AddCommand addBobCommand = new AddCommand(bob);
+ Residence residence1 = new ResidenceBuilder().withName("Amber Heights").build();
+ Residence residence2 = new ResidenceBuilder().withName("Beauty World").build();
+ AddCommand addFirstCommand = new AddCommand(residence1);
+ AddCommand addSecondCommand = new AddCommand(residence2);
// same object -> returns true
- assertTrue(addAliceCommand.equals(addAliceCommand));
+ assertTrue(addFirstCommand.equals(addFirstCommand));
// same values -> returns true
- AddCommand addAliceCommandCopy = new AddCommand(alice);
- assertTrue(addAliceCommand.equals(addAliceCommandCopy));
+ AddCommand addAliceCommandCopy = new AddCommand(residence1);
+ assertTrue(addFirstCommand.equals(addAliceCommandCopy));
// different types -> returns false
- assertFalse(addAliceCommand.equals(1));
+ assertFalse(addFirstCommand.equals(1));
// null -> returns false
- assertFalse(addAliceCommand.equals(null));
+ assertFalse(addFirstCommand.equals(null));
// different person -> returns false
- assertFalse(addAliceCommand.equals(addBobCommand));
+ assertFalse(addFirstCommand.equals(addSecondCommand));
}
/**
@@ -99,95 +100,95 @@ public void setGuiSettings(GuiSettings guiSettings) {
}
@Override
- public Path getAddressBookFilePath() {
+ public Path getResidenceTrackerFilePath() {
throw new AssertionError("This method should not be called.");
}
@Override
- public void setAddressBookFilePath(Path addressBookFilePath) {
+ public void setResidenceTrackerFilePath(Path residenceTrackerFilePath) {
throw new AssertionError("This method should not be called.");
}
@Override
- public void addPerson(Person person) {
+ public void addResidence(Residence residence) {
throw new AssertionError("This method should not be called.");
}
@Override
- public void setAddressBook(ReadOnlyAddressBook newData) {
+ public void setResidenceTracker(ReadOnlyResidenceTracker newData) {
throw new AssertionError("This method should not be called.");
}
@Override
- public ReadOnlyAddressBook getAddressBook() {
+ public ReadOnlyResidenceTracker getResidenceTracker() {
throw new AssertionError("This method should not be called.");
}
@Override
- public boolean hasPerson(Person person) {
+ public boolean hasResidence(Residence residence) {
throw new AssertionError("This method should not be called.");
}
@Override
- public void deletePerson(Person target) {
+ public void deleteResidence(Residence target) {
throw new AssertionError("This method should not be called.");
}
@Override
- public void setPerson(Person target, Person editedPerson) {
+ public void setResidence(Residence target, Residence editedResidence) {
throw new AssertionError("This method should not be called.");
}
@Override
- public ObservableList getFilteredPersonList() {
+ public ObservableList getFilteredResidenceList() {
throw new AssertionError("This method should not be called.");
}
@Override
- public void updateFilteredPersonList(Predicate predicate) {
+ public void updateFilteredResidenceList(Predicate predicate) {
throw new AssertionError("This method should not be called.");
}
}
/**
- * A Model stub that contains a single person.
+ * A Model stub that contains a single residence.
*/
- private class ModelStubWithPerson extends ModelStub {
- private final Person person;
+ private class ModelStubWithResidence extends ModelStub {
+ private final Residence residence;
- ModelStubWithPerson(Person person) {
- requireNonNull(person);
- this.person = person;
+ ModelStubWithResidence(Residence residence) {
+ requireNonNull(residence);
+ this.residence = residence;
}
@Override
- public boolean hasPerson(Person person) {
- requireNonNull(person);
- return this.person.isSamePerson(person);
+ public boolean hasResidence(Residence residence) {
+ requireNonNull(residence);
+ return this.residence.isSameResidence(residence);
}
}
/**
- * A Model stub that always accept the person being added.
+ * A Model stub that always accept the residence being added.
*/
- private class ModelStubAcceptingPersonAdded extends ModelStub {
- final ArrayList personsAdded = new ArrayList<>();
+ private class ModelStubAcceptingResidenceAdded extends ModelStub {
+ final ArrayList residencesAdded = new ArrayList<>();
@Override
- public boolean hasPerson(Person person) {
- requireNonNull(person);
- return personsAdded.stream().anyMatch(person::isSamePerson);
+ public boolean hasResidence(Residence residence) {
+ requireNonNull(residence);
+ return residencesAdded.stream().anyMatch(residence::isSameResidence);
}
@Override
- public void addPerson(Person person) {
- requireNonNull(person);
- personsAdded.add(person);
+ public void addResidence(Residence residence) {
+ requireNonNull(residence);
+ residencesAdded.add(residence);
}
@Override
- public ReadOnlyAddressBook getAddressBook() {
- return new AddressBook();
+ public ReadOnlyResidenceTracker getResidenceTracker() {
+ return new ResidenceTracker();
}
}
diff --git a/src/test/java/seedu/address/logic/commands/ClearCommandTest.java b/src/test/java/seedu/address/logic/commands/ClearCommandTest.java
index 80d9110c03a..186dce3d651 100644
--- a/src/test/java/seedu/address/logic/commands/ClearCommandTest.java
+++ b/src/test/java/seedu/address/logic/commands/ClearCommandTest.java
@@ -1,19 +1,19 @@
package seedu.address.logic.commands;
import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
+import static seedu.address.testutil.TypicalResidences.getTypicalResidenceTracker;
import org.junit.jupiter.api.Test;
-import seedu.address.model.AddressBook;
import seedu.address.model.Model;
import seedu.address.model.ModelManager;
+import seedu.address.model.ResidenceTracker;
import seedu.address.model.UserPrefs;
public class ClearCommandTest {
@Test
- public void execute_emptyAddressBook_success() {
+ public void execute_emptyResidenceTracker_success() {
Model model = new ModelManager();
Model expectedModel = new ModelManager();
@@ -21,10 +21,10 @@ public void execute_emptyAddressBook_success() {
}
@Test
- public void execute_nonEmptyAddressBook_success() {
- Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
- Model expectedModel = new ModelManager(getTypicalAddressBook(), new UserPrefs());
- expectedModel.setAddressBook(new AddressBook());
+ public void execute_nonEmptyResidenceTracker_success() {
+ Model model = new ModelManager(getTypicalResidenceTracker(), new UserPrefs());
+ Model expectedModel = new ModelManager(getTypicalResidenceTracker(), new UserPrefs());
+ expectedModel.setResidenceTracker(new ResidenceTracker());
assertCommandSuccess(new ClearCommand(), model, ClearCommand.MESSAGE_SUCCESS, expectedModel);
}
diff --git a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java b/src/test/java/seedu/address/logic/commands/CommandTestUtil.java
index 643a1d08069..7be734b5410 100644
--- a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java
+++ b/src/test/java/seedu/address/logic/commands/CommandTestUtil.java
@@ -2,71 +2,112 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_CLEAN_STATUS_TAG;
import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_RESIDENCE_ADDRESS;
import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG;
import static seedu.address.testutil.Assert.assertThrows;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import seedu.address.commons.core.index.Index;
import seedu.address.logic.commands.exceptions.CommandException;
-import seedu.address.model.AddressBook;
import seedu.address.model.Model;
-import seedu.address.model.person.NameContainsKeywordsPredicate;
-import seedu.address.model.person.Person;
-import seedu.address.testutil.EditPersonDescriptorBuilder;
+import seedu.address.model.ResidenceTracker;
+import seedu.address.model.residence.NameContainsKeywordsPredicate;
+import seedu.address.model.residence.Residence;
+import seedu.address.testutil.EditBookingDescriptorBuilder;
+import seedu.address.testutil.EditResidenceDescriptorBuilder;
/**
* Contains helper methods for testing commands.
*/
public class CommandTestUtil {
-
- public static final String VALID_NAME_AMY = "Amy Bee";
- public static final String VALID_NAME_BOB = "Bob Choo";
- public static final String VALID_PHONE_AMY = "11111111";
- public static final String VALID_PHONE_BOB = "22222222";
- public static final String VALID_EMAIL_AMY = "amy@example.com";
- public static final String VALID_EMAIL_BOB = "bob@example.com";
- public static final String VALID_ADDRESS_AMY = "Block 312, Amy Street 1";
- public static final String VALID_ADDRESS_BOB = "Block 123, Bobby Street 3";
- public static final String VALID_TAG_HUSBAND = "husband";
- public static final String VALID_TAG_FRIEND = "friend";
-
- public static final String NAME_DESC_AMY = " " + PREFIX_NAME + VALID_NAME_AMY;
- public static final String NAME_DESC_BOB = " " + PREFIX_NAME + VALID_NAME_BOB;
- public static final String PHONE_DESC_AMY = " " + PREFIX_PHONE + VALID_PHONE_AMY;
- public static final String PHONE_DESC_BOB = " " + PREFIX_PHONE + VALID_PHONE_BOB;
- public static final String EMAIL_DESC_AMY = " " + PREFIX_EMAIL + VALID_EMAIL_AMY;
- public static final String EMAIL_DESC_BOB = " " + PREFIX_EMAIL + VALID_EMAIL_BOB;
- public static final String ADDRESS_DESC_AMY = " " + PREFIX_ADDRESS + VALID_ADDRESS_AMY;
- public static final String ADDRESS_DESC_BOB = " " + PREFIX_ADDRESS + VALID_ADDRESS_BOB;
- public static final String TAG_DESC_FRIEND = " " + PREFIX_TAG + VALID_TAG_FRIEND;
- public static final String TAG_DESC_HUSBAND = " " + PREFIX_TAG + VALID_TAG_HUSBAND;
-
- public static final String INVALID_NAME_DESC = " " + PREFIX_NAME + "James&"; // '&' not allowed in names
- public static final String INVALID_PHONE_DESC = " " + PREFIX_PHONE + "911a"; // 'a' not allowed in phones
- public static final String INVALID_EMAIL_DESC = " " + PREFIX_EMAIL + "bob!yahoo"; // missing '@' symbol
- public static final String INVALID_ADDRESS_DESC = " " + PREFIX_ADDRESS; // empty string not allowed for addresses
- public static final String INVALID_TAG_DESC = " " + PREFIX_TAG + "hubby*"; // '*' not allowed in tags
+ public static final String VALID_NAME_RESIDENCE1 = "Amber Park";
+ public static final String VALID_NAME_RESIDENCE2 = "Duxton";
+ public static final String VALID_ADDRESS_RESIDENCE1 = "14 Amber Gardens, 439960";
+ public static final String VALID_ADDRESS_RESIDENCE2 = "Block 50, Cantonment Rd";
+
+ public static final String VALID_CLEAN_TAG = "y";
+ public static final String VALID_UNCLEAN_TAG = "n";
+ public static final String VALID_BOOKED_TAG = "y";
+ public static final String VALID_UNBOOKED_TAG = "n";
+ public static final String VALID_TAG_RESERVED = "reserved";
+ public static final String VALID_TAG_REPAIR = "plumbing";
+
+ public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("dd-MM-yyyy");
+
+ public static final String VALID_PHONE_BOOKING1 = "11111111";
+ public static final String VALID_PHONE_BOOKING2 = "22222222";
+ public static final String VALID_NAME_BOOKING1 = "Amy";
+ public static final String VALID_NAME_BOOKING2 = "John";
+ public static final String VALID_BOOKING_START1 = "03-03-2021";
+ public static final String VALID_BOOKING_START2 = "30-03-2021";
+ public static final String VALID_BOOKING_END1 = "05-05-2021";
+ public static final String VALID_BOOKING_END2 = "30-05-2021";
+
+ public static final LocalDate INVALID_BOOKING_END = LocalDate.parse("01-01-1990", DATE_TIME_FORMATTER);
+ public static final LocalDate OVERLAP_BOOKING_DATE = LocalDate.parse("03-03-2020", DATE_TIME_FORMATTER);
+ public static final LocalDate VALID_LOCALDATE_START1 = LocalDate.parse(VALID_BOOKING_START1, DATE_TIME_FORMATTER);
+ public static final LocalDate VALID_LOCALDATE_END1 = LocalDate.parse(VALID_BOOKING_END1, DATE_TIME_FORMATTER);
+
+ public static final String NAME_DESC_RESIDENCE1 = " " + PREFIX_NAME + VALID_NAME_RESIDENCE1;
+ public static final String NAME_DESC_RESIDENCE2 = " " + PREFIX_NAME + VALID_NAME_RESIDENCE2;
+ public static final String ADDRESS_DESC_RESIDENCE1 = " " + PREFIX_RESIDENCE_ADDRESS + VALID_ADDRESS_RESIDENCE1;
+ public static final String ADDRESS_DESC_RESIDENCE2 = " " + PREFIX_RESIDENCE_ADDRESS + VALID_ADDRESS_RESIDENCE2;
+ public static final String TAG_DESC_BOOKED = " " + PREFIX_TAG + VALID_BOOKED_TAG;
+ public static final String TAG_DESC_UNBOOKED = " " + PREFIX_TAG + VALID_UNBOOKED_TAG;
+ public static final String TAG_DESC_RESERVED = " " + PREFIX_TAG + VALID_TAG_RESERVED;
+ public static final String TAG_DESC_REPAIR = " " + PREFIX_TAG + VALID_TAG_REPAIR;
+ public static final String CLEAN_STATUS_DESC = " " + PREFIX_CLEAN_STATUS_TAG + VALID_CLEAN_TAG;
+ public static final String UNCLEAN_STATUS_DESC = " " + PREFIX_CLEAN_STATUS_TAG + VALID_UNCLEAN_TAG;
+ public static final String PHONE_DESC_BOOKING1 = " " + PREFIX_PHONE + VALID_PHONE_BOOKING1;
+ public static final String PHONE_DESC_BOOKING2 = " " + PREFIX_PHONE + VALID_PHONE_BOOKING2;
+ public static final String TENANT_NAME_DESC_AMY = " " + PREFIX_NAME + VALID_NAME_BOOKING1;
+
+ // '&' not allowed in names
+ public static final String INVALID_NAME_DESC = " " + PREFIX_NAME + "James&";
+ // 'a' not allowed in phones
+ public static final String INVALID_PHONE_DESC = " " + PREFIX_PHONE + "911a";
+ // empty string not allowed for addresses
+ public static final String INVALID_ADDRESS_DESC = " " + PREFIX_RESIDENCE_ADDRESS;
+ // must be 'y' or 'clean'
+ public static final String INVALID_CLEAN_TAG_DESC = " " + PREFIX_CLEAN_STATUS_TAG + "yup";
+ // must be 'n' or 'unclean'
+ public static final String INVALID_UNCLEAN_TAG_DESC = " " + PREFIX_CLEAN_STATUS_TAG + "CLEAN IT!!";
+ // '*' not allowed in tags
+ public static final String INVALID_TAG_DESC = " " + PREFIX_TAG + "renovate*";
public static final String PREAMBLE_WHITESPACE = "\t \r \n";
public static final String PREAMBLE_NON_EMPTY = "NonEmptyPreamble";
- public static final EditCommand.EditPersonDescriptor DESC_AMY;
- public static final EditCommand.EditPersonDescriptor DESC_BOB;
+ public static final EditCommand.EditResidenceDescriptor DESC_RESIDENCE1;
+ public static final EditCommand.EditResidenceDescriptor DESC_RESIDENCE2;
+ public static final EditBookingCommand.EditBookingDescriptor DESC_BOOKING1;
+ public static final EditBookingCommand.EditBookingDescriptor DESC_BOOKING2;
static {
- DESC_AMY = new EditPersonDescriptorBuilder().withName(VALID_NAME_AMY)
- .withPhone(VALID_PHONE_AMY).withEmail(VALID_EMAIL_AMY).withAddress(VALID_ADDRESS_AMY)
- .withTags(VALID_TAG_FRIEND).build();
- DESC_BOB = new EditPersonDescriptorBuilder().withName(VALID_NAME_BOB)
- .withPhone(VALID_PHONE_BOB).withEmail(VALID_EMAIL_BOB).withAddress(VALID_ADDRESS_BOB)
- .withTags(VALID_TAG_HUSBAND, VALID_TAG_FRIEND).build();
+ DESC_RESIDENCE1 = new EditResidenceDescriptorBuilder().withName(VALID_NAME_RESIDENCE1)
+ .withAddress(VALID_ADDRESS_RESIDENCE1)
+ .withCleanStatusTag(VALID_CLEAN_TAG).withTags(VALID_TAG_RESERVED).build();
+ DESC_RESIDENCE2 = new EditResidenceDescriptorBuilder().withName(VALID_NAME_RESIDENCE1)
+ .withAddress(VALID_ADDRESS_RESIDENCE2)
+ .withCleanStatusTag(VALID_CLEAN_TAG).withTags(VALID_TAG_RESERVED, VALID_TAG_REPAIR).build();
+ DESC_BOOKING1 = new EditBookingDescriptorBuilder().withName(VALID_NAME_BOOKING1)
+ .withPhone(VALID_PHONE_BOOKING1)
+ .withStartDate(LocalDate.parse(VALID_BOOKING_START1, DATE_TIME_FORMATTER))
+ .withEndDate(LocalDate.parse(VALID_BOOKING_END1, DATE_TIME_FORMATTER))
+ .build();
+ DESC_BOOKING2 = new EditBookingDescriptorBuilder().withName(VALID_NAME_BOOKING2)
+ .withPhone(VALID_PHONE_BOOKING1)
+ .withStartDate(LocalDate.parse(VALID_BOOKING_START2, DATE_TIME_FORMATTER))
+ .withEndDate(LocalDate.parse(VALID_BOOKING_END2, DATE_TIME_FORMATTER))
+ .build();
}
/**
@@ -99,30 +140,30 @@ public static void assertCommandSuccess(Command command, Model actualModel, Stri
* Executes the given {@code command}, confirms that
* - a {@code CommandException} is thrown
* - the CommandException message matches {@code expectedMessage}
- * - the address book, filtered person list and selected person in {@code actualModel} remain unchanged
+ * - the residence tracker, filtered residence list and selected residence in {@code actualModel} remain unchanged
*/
public static void assertCommandFailure(Command command, Model actualModel, String expectedMessage) {
// we are unable to defensively copy the model for comparison later, so we can
// only do so by copying its components.
- AddressBook expectedAddressBook = new AddressBook(actualModel.getAddressBook());
- List expectedFilteredList = new ArrayList<>(actualModel.getFilteredPersonList());
+ ResidenceTracker expectedAddressBook = new ResidenceTracker(actualModel.getResidenceTracker());
+ List expectedFilteredList = new ArrayList<>(actualModel.getFilteredResidenceList());
assertThrows(CommandException.class, expectedMessage, () -> command.execute(actualModel));
- assertEquals(expectedAddressBook, actualModel.getAddressBook());
- assertEquals(expectedFilteredList, actualModel.getFilteredPersonList());
+ assertEquals(expectedAddressBook, actualModel.getResidenceTracker());
+ assertEquals(expectedFilteredList, actualModel.getFilteredResidenceList());
}
/**
- * Updates {@code model}'s filtered list to show only the person at the given {@code targetIndex} in the
- * {@code model}'s address book.
+ * Updates {@code model}'s filtered list to show only the residence at the given {@code targetIndex} in the
+ * {@code model}'s Residence Tracker.
*/
- public static void showPersonAtIndex(Model model, Index targetIndex) {
- assertTrue(targetIndex.getZeroBased() < model.getFilteredPersonList().size());
+ public static void showResidenceAtIndex(Model model, Index targetIndex) {
+ assertTrue(targetIndex.getZeroBased() < model.getFilteredResidenceList().size());
- Person person = model.getFilteredPersonList().get(targetIndex.getZeroBased());
- final String[] splitName = person.getName().fullName.split("\\s+");
- model.updateFilteredPersonList(new NameContainsKeywordsPredicate(Arrays.asList(splitName[0])));
+ Residence residence = model.getFilteredResidenceList().get(targetIndex.getZeroBased());
+ final String[] splitName = residence.getResidenceName().toString().split("\\s+");
+ model.updateFilteredResidenceList(new NameContainsKeywordsPredicate(Arrays.asList(splitName[0])));
- assertEquals(1, model.getFilteredPersonList().size());
+ assertEquals(1, model.getFilteredResidenceList().size());
}
}
diff --git a/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java b/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java
index 45a8c910ba1..673e3149bee 100644
--- a/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java
+++ b/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java
@@ -4,10 +4,10 @@
import static org.junit.jupiter.api.Assertions.assertTrue;
import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure;
import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
-import static seedu.address.logic.commands.CommandTestUtil.showPersonAtIndex;
-import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON;
-import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_PERSON;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
+import static seedu.address.logic.commands.CommandTestUtil.showResidenceAtIndex;
+import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_RESIDENCE;
+import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_RESIDENCE;
+import static seedu.address.testutil.TypicalResidences.getTypicalResidenceTracker;
import org.junit.jupiter.api.Test;
@@ -16,7 +16,7 @@
import seedu.address.model.Model;
import seedu.address.model.ModelManager;
import seedu.address.model.UserPrefs;
-import seedu.address.model.person.Person;
+import seedu.address.model.residence.Residence;
/**
* Contains integration tests (interaction with the Model) and unit tests for
@@ -24,68 +24,68 @@
*/
public class DeleteCommandTest {
- private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
+ private Model model = new ModelManager(getTypicalResidenceTracker(), new UserPrefs());
@Test
public void execute_validIndexUnfilteredList_success() {
- Person personToDelete = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased());
- DeleteCommand deleteCommand = new DeleteCommand(INDEX_FIRST_PERSON);
+ Residence residenceToDelete = model.getFilteredResidenceList().get(INDEX_FIRST_RESIDENCE.getZeroBased());
+ DeleteCommand deleteCommand = new DeleteCommand(INDEX_FIRST_RESIDENCE);
- String expectedMessage = String.format(DeleteCommand.MESSAGE_DELETE_PERSON_SUCCESS, personToDelete);
+ String expectedMessage = String.format(DeleteCommand.MESSAGE_DELETE_RESIDENCE_SUCCESS, residenceToDelete);
- ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs());
- expectedModel.deletePerson(personToDelete);
+ ModelManager expectedModel = new ModelManager(model.getResidenceTracker(), new UserPrefs());
+ expectedModel.deleteResidence(residenceToDelete);
assertCommandSuccess(deleteCommand, model, expectedMessage, expectedModel);
}
@Test
public void execute_invalidIndexUnfilteredList_throwsCommandException() {
- Index outOfBoundIndex = Index.fromOneBased(model.getFilteredPersonList().size() + 1);
+ Index outOfBoundIndex = Index.fromOneBased(model.getFilteredResidenceList().size() + 1);
DeleteCommand deleteCommand = new DeleteCommand(outOfBoundIndex);
- assertCommandFailure(deleteCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
+ assertCommandFailure(deleteCommand, model, Messages.MESSAGE_INVALID_RESIDENCE_DISPLAYED_INDEX);
}
@Test
public void execute_validIndexFilteredList_success() {
- showPersonAtIndex(model, INDEX_FIRST_PERSON);
+ showResidenceAtIndex(model, INDEX_FIRST_RESIDENCE);
- Person personToDelete = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased());
- DeleteCommand deleteCommand = new DeleteCommand(INDEX_FIRST_PERSON);
+ Residence residenceToDelete = model.getFilteredResidenceList().get(INDEX_FIRST_RESIDENCE.getZeroBased());
+ DeleteCommand deleteCommand = new DeleteCommand(INDEX_FIRST_RESIDENCE);
- String expectedMessage = String.format(DeleteCommand.MESSAGE_DELETE_PERSON_SUCCESS, personToDelete);
+ String expectedMessage = String.format(DeleteCommand.MESSAGE_DELETE_RESIDENCE_SUCCESS, residenceToDelete);
- Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs());
- expectedModel.deletePerson(personToDelete);
- showNoPerson(expectedModel);
+ Model expectedModel = new ModelManager(model.getResidenceTracker(), new UserPrefs());
+ expectedModel.deleteResidence(residenceToDelete);
+ showNoResidence(expectedModel);
assertCommandSuccess(deleteCommand, model, expectedMessage, expectedModel);
}
@Test
public void execute_invalidIndexFilteredList_throwsCommandException() {
- showPersonAtIndex(model, INDEX_FIRST_PERSON);
+ showResidenceAtIndex(model, INDEX_FIRST_RESIDENCE);
- Index outOfBoundIndex = INDEX_SECOND_PERSON;
+ Index outOfBoundIndex = INDEX_SECOND_RESIDENCE;
// ensures that outOfBoundIndex is still in bounds of address book list
- assertTrue(outOfBoundIndex.getZeroBased() < model.getAddressBook().getPersonList().size());
+ assertTrue(outOfBoundIndex.getZeroBased() < model.getResidenceTracker().getResidenceList().size());
DeleteCommand deleteCommand = new DeleteCommand(outOfBoundIndex);
- assertCommandFailure(deleteCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
+ assertCommandFailure(deleteCommand, model, Messages.MESSAGE_INVALID_RESIDENCE_DISPLAYED_INDEX);
}
@Test
public void equals() {
- DeleteCommand deleteFirstCommand = new DeleteCommand(INDEX_FIRST_PERSON);
- DeleteCommand deleteSecondCommand = new DeleteCommand(INDEX_SECOND_PERSON);
+ DeleteCommand deleteFirstCommand = new DeleteCommand(INDEX_FIRST_RESIDENCE);
+ DeleteCommand deleteSecondCommand = new DeleteCommand(INDEX_SECOND_RESIDENCE);
// same object -> returns true
assertTrue(deleteFirstCommand.equals(deleteFirstCommand));
// same values -> returns true
- DeleteCommand deleteFirstCommandCopy = new DeleteCommand(INDEX_FIRST_PERSON);
+ DeleteCommand deleteFirstCommandCopy = new DeleteCommand(INDEX_FIRST_RESIDENCE);
assertTrue(deleteFirstCommand.equals(deleteFirstCommandCopy));
// different types -> returns false
@@ -101,9 +101,9 @@ public void equals() {
/**
* Updates {@code model}'s filtered list to show no one.
*/
- private void showNoPerson(Model model) {
- model.updateFilteredPersonList(p -> false);
+ private void showNoResidence(Model model) {
+ model.updateFilteredResidenceList(p -> false);
- assertTrue(model.getFilteredPersonList().isEmpty());
+ assertTrue(model.getFilteredResidenceList().isEmpty());
}
}
diff --git a/src/test/java/seedu/address/logic/commands/EditBookingCommandTest.java b/src/test/java/seedu/address/logic/commands/EditBookingCommandTest.java
new file mode 100644
index 00000000000..c2053295e02
--- /dev/null
+++ b/src/test/java/seedu/address/logic/commands/EditBookingCommandTest.java
@@ -0,0 +1,139 @@
+package seedu.address.logic.commands;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static seedu.address.logic.commands.CommandTestUtil.DESC_BOOKING1;
+import static seedu.address.logic.commands.CommandTestUtil.DESC_BOOKING2;
+import static seedu.address.logic.commands.CommandTestUtil.INVALID_BOOKING_END;
+import static seedu.address.logic.commands.CommandTestUtil.OVERLAP_BOOKING_DATE;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_BOOKING1;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_BOOKING2;
+import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure;
+import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
+import static seedu.address.logic.commands.CommandTestUtil.showResidenceAtIndex;
+import static seedu.address.model.Model.PREDICATE_SHOW_ALL_RESIDENCES;
+import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_BOOKING;
+import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_RESIDENCE;
+import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_BOOKING;
+import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_RESIDENCE;
+import static seedu.address.testutil.TypicalIndexes.INDEX_THIRD_RESIDENCE;
+import static seedu.address.testutil.TypicalResidences.getTypicalResidenceTracker;
+
+import org.junit.jupiter.api.Test;
+
+import seedu.address.commons.core.Messages;
+import seedu.address.commons.core.index.Index;
+import seedu.address.logic.commands.EditBookingCommand.EditBookingDescriptor;
+import seedu.address.model.Model;
+import seedu.address.model.ModelManager;
+import seedu.address.model.UserPrefs;
+import seedu.address.model.booking.Booking;
+import seedu.address.model.residence.BookingList;
+import seedu.address.model.residence.Residence;
+import seedu.address.testutil.BookingBuilder;
+import seedu.address.testutil.EditBookingDescriptorBuilder;
+
+public class EditBookingCommandTest {
+
+ private Model model = new ModelManager(getTypicalResidenceTracker(), new UserPrefs());
+
+ @Test
+ public void execute_validResidenceIndexInvalidBookingIndexFilteredList_failure() {
+ showResidenceAtIndex(model, INDEX_FIRST_RESIDENCE);
+ Index outOfBoundBookingIndex = INDEX_FIRST_BOOKING;
+ EditBookingCommand editBookingCommand = new EditBookingCommand(INDEX_FIRST_RESIDENCE, outOfBoundBookingIndex,
+ new EditBookingDescriptorBuilder().withName(VALID_NAME_BOOKING1).build());
+ assertCommandFailure(editBookingCommand, model, Messages.MESSAGE_INVALID_BOOKING_DISPLAYED_INDEX);
+ }
+
+ @Test
+ public void execute_invalidResidenceIndexValidBookingIndexFilteredList_failure() {
+ showResidenceAtIndex(model, INDEX_SECOND_RESIDENCE);
+ Index outOfBoundResidenceIndex = INDEX_THIRD_RESIDENCE;
+ assertTrue(outOfBoundResidenceIndex.getZeroBased() < model.getResidenceTracker().getResidenceList().size());
+ Index validBookingIndex = INDEX_FIRST_BOOKING;
+ assertTrue(outOfBoundResidenceIndex.getZeroBased() < model.getResidenceTracker().getResidenceList().size());
+ EditBookingCommand editBookingCommand = new EditBookingCommand(INDEX_THIRD_RESIDENCE, validBookingIndex,
+ new EditBookingDescriptorBuilder().withName(VALID_NAME_BOOKING1).build());
+ assertCommandFailure(editBookingCommand, model, Messages.MESSAGE_INVALID_RESIDENCE_DISPLAYED_INDEX);
+
+ }
+
+ @Test
+ public void execute_validResidenceAndBookingIndex_invalidEndDate() {
+ Index validResidenceIndex = INDEX_SECOND_RESIDENCE;
+ Index validBookingIndex = INDEX_FIRST_BOOKING;
+ Residence residenceToEdit = model.getFilteredResidenceList().get(validResidenceIndex.getZeroBased());
+ BookingList bookingListToEdit = residenceToEdit.getBookingList();
+ Booking bookingToEdit = bookingListToEdit.getBooking(validBookingIndex.getZeroBased());
+ Booking editedBooking = new BookingBuilder(bookingToEdit).withEnd(INVALID_BOOKING_END).build();
+ EditBookingCommand editBookingCommand = new EditBookingCommand(validResidenceIndex, validBookingIndex,
+ new EditBookingDescriptorBuilder().withEndDate(INVALID_BOOKING_END).build());
+ String expectedMessage = EditBookingCommand.MESSAGE_NOT_VALID_START_DATE;
+ assertCommandFailure(editBookingCommand, model, expectedMessage);
+ }
+
+ @Test
+ public void execute_validResidenceAndBookingIndex_overlapDate() {
+ Index validResidenceIndex = INDEX_SECOND_RESIDENCE;
+ Index validBookingIndex = INDEX_SECOND_BOOKING;
+ Residence residenceToEdit = model.getFilteredResidenceList().get(validResidenceIndex.getZeroBased());
+ BookingList bookingListToEdit = residenceToEdit.getBookingList();
+ Booking bookingToEdit = bookingListToEdit.getBooking(validBookingIndex.getZeroBased());
+ Booking editedBooking = new BookingBuilder(bookingToEdit).withStart(OVERLAP_BOOKING_DATE).build();
+ EditBookingCommand editBookingCommand = new EditBookingCommand(validResidenceIndex, validBookingIndex,
+ new EditBookingDescriptorBuilder().withStartDate(OVERLAP_BOOKING_DATE).build());
+ String expectedMessage = EditBookingCommand.MESSAGE_OVERLAP_BOOKING;
+ assertCommandFailure(editBookingCommand, model, expectedMessage);
+ }
+
+ @Test
+ public void execute_validEditBookingCommandSuccess() {
+ Index validResidenceIndex = INDEX_SECOND_RESIDENCE;
+ Index validBookingIndex = INDEX_FIRST_BOOKING;
+ Residence targetResidence = model.getFilteredResidenceList().get(validResidenceIndex.getZeroBased());
+ Residence residenceToEdit = model.getFilteredResidenceList().get(validResidenceIndex.getZeroBased());
+ BookingList bookingListToEdit = residenceToEdit.getBookingList();
+ Booking bookingToEdit = bookingListToEdit.getBooking(validBookingIndex.getZeroBased());
+ Booking editedBooking = new BookingBuilder(bookingToEdit).withName(VALID_NAME_BOOKING2).build();
+ EditBookingCommand editBookingCommand = new EditBookingCommand(validResidenceIndex, validBookingIndex,
+ new EditBookingDescriptorBuilder().withName(VALID_NAME_BOOKING2).build());
+ bookingListToEdit.setBooking(bookingToEdit, editedBooking);
+ String expectedMessage = String.format(EditBookingCommand.MESSAGE_EDIT_BOOKING_SUCCESS, editedBooking);
+ Model expectedModel = new ModelManager(getTypicalResidenceTracker(), new UserPrefs());
+ expectedModel.setResidence(targetResidence, residenceToEdit);
+ expectedModel.updateFilteredResidenceList(PREDICATE_SHOW_ALL_RESIDENCES);
+ assertCommandSuccess(editBookingCommand, model, expectedMessage, expectedModel);
+ }
+
+ @Test
+ public void equals() {
+ final EditBookingCommand standardCommand = new EditBookingCommand(
+ INDEX_SECOND_RESIDENCE, INDEX_FIRST_BOOKING, new EditBookingDescriptor(DESC_BOOKING1));
+
+ // same values -> returns true
+ EditBookingDescriptor copyDescriptor = new EditBookingDescriptor(DESC_BOOKING1);
+ EditBookingCommand commandWithSameValues = new EditBookingCommand(
+ INDEX_SECOND_RESIDENCE, INDEX_FIRST_BOOKING, 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 EditBookingCommand(
+ INDEX_FIRST_RESIDENCE, INDEX_FIRST_BOOKING, DESC_BOOKING1)));
+
+ // different descriptor -> returns false
+ assertFalse(standardCommand.equals(new EditBookingCommand(
+ INDEX_SECOND_RESIDENCE, INDEX_FIRST_BOOKING, DESC_BOOKING2)));
+ }
+
+
+}
diff --git a/src/test/java/seedu/address/logic/commands/EditCommandTest.java b/src/test/java/seedu/address/logic/commands/EditCommandTest.java
index 214c6c2507b..0de8a7eb13a 100644
--- a/src/test/java/seedu/address/logic/commands/EditCommandTest.java
+++ b/src/test/java/seedu/address/logic/commands/EditCommandTest.java
@@ -2,130 +2,137 @@
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.logic.commands.CommandTestUtil.DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.DESC_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND;
+import static seedu.address.logic.commands.CommandTestUtil.DESC_RESIDENCE1;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_RESIDENCE1;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_UNCLEAN_TAG;
import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure;
import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
-import static seedu.address.logic.commands.CommandTestUtil.showPersonAtIndex;
-import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON;
-import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_PERSON;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
+import static seedu.address.logic.commands.CommandTestUtil.showResidenceAtIndex;
+import static seedu.address.model.Model.PREDICATE_SHOW_ALL_RESIDENCES;
+import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_RESIDENCE;
+import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_RESIDENCE;
+import static seedu.address.testutil.TypicalResidences.getTypicalResidenceTracker;
import org.junit.jupiter.api.Test;
import seedu.address.commons.core.Messages;
import seedu.address.commons.core.index.Index;
-import seedu.address.logic.commands.EditCommand.EditPersonDescriptor;
-import seedu.address.model.AddressBook;
+import seedu.address.logic.commands.EditCommand.EditResidenceDescriptor;
import seedu.address.model.Model;
import seedu.address.model.ModelManager;
+import seedu.address.model.ResidenceTracker;
import seedu.address.model.UserPrefs;
-import seedu.address.model.person.Person;
-import seedu.address.testutil.EditPersonDescriptorBuilder;
-import seedu.address.testutil.PersonBuilder;
+import seedu.address.model.residence.Residence;
+import seedu.address.testutil.EditResidenceDescriptorBuilder;
+import seedu.address.testutil.ResidenceBuilder;
/**
* Contains integration tests (interaction with the Model) and unit tests for EditCommand.
*/
public class EditCommandTest {
- private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
+ private Model model = new ModelManager(getTypicalResidenceTracker(), new UserPrefs());
@Test
public void execute_allFieldsSpecifiedUnfilteredList_success() {
- Person editedPerson = new PersonBuilder().build();
- EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder(editedPerson).build();
- EditCommand editCommand = new EditCommand(INDEX_FIRST_PERSON, descriptor);
+ Residence editedResidence = new ResidenceBuilder().build();
+ EditResidenceDescriptor descriptor = new EditResidenceDescriptorBuilder(editedResidence).build();
+ EditCommand editCommand = new EditCommand(INDEX_FIRST_RESIDENCE, descriptor);
- String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_PERSON_SUCCESS, editedPerson);
-
- Model expectedModel = new ModelManager(new AddressBook(model.getAddressBook()), new UserPrefs());
- expectedModel.setPerson(model.getFilteredPersonList().get(0), editedPerson);
+ String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_RESIDENCE_SUCCESS, editedResidence);
+ Model expectedModel = new ModelManager(new ResidenceTracker(model.getResidenceTracker()), new UserPrefs());
+ expectedModel.setResidence(model.getFilteredResidenceList().get(0), editedResidence);
+ expectedModel.updateFilteredResidenceList(PREDICATE_SHOW_ALL_RESIDENCES);
assertCommandSuccess(editCommand, model, expectedMessage, expectedModel);
}
@Test
public void execute_someFieldsSpecifiedUnfilteredList_success() {
- Index indexLastPerson = Index.fromOneBased(model.getFilteredPersonList().size());
- Person lastPerson = model.getFilteredPersonList().get(indexLastPerson.getZeroBased());
+ Index indexLastResidence = Index.fromOneBased(model.getFilteredResidenceList().size());
+ Residence lastResidence = model.getFilteredResidenceList().get(indexLastResidence.getZeroBased());
+
+ ResidenceBuilder residenceInList = new ResidenceBuilder(lastResidence);
+ Residence editedResidence = residenceInList.withName(VALID_NAME_RESIDENCE1)
+ .withCleanStatusTag(VALID_UNCLEAN_TAG).build();
+
+ EditResidenceDescriptor descriptor = new EditResidenceDescriptorBuilder().withName(VALID_NAME_RESIDENCE1)
+ .withCleanStatusTag(VALID_UNCLEAN_TAG).build();
- PersonBuilder personInList = new PersonBuilder(lastPerson);
- Person editedPerson = personInList.withName(VALID_NAME_BOB).withPhone(VALID_PHONE_BOB)
- .withTags(VALID_TAG_HUSBAND).build();
- EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withName(VALID_NAME_BOB)
- .withPhone(VALID_PHONE_BOB).withTags(VALID_TAG_HUSBAND).build();
- EditCommand editCommand = new EditCommand(indexLastPerson, descriptor);
+ EditCommand editCommand = new EditCommand(indexLastResidence, descriptor);
- String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_PERSON_SUCCESS, editedPerson);
+ String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_RESIDENCE_SUCCESS, editedResidence);
- Model expectedModel = new ModelManager(new AddressBook(model.getAddressBook()), new UserPrefs());
- expectedModel.setPerson(lastPerson, editedPerson);
+ Model expectedModel = new ModelManager(new ResidenceTracker(model.getResidenceTracker()), new UserPrefs());
+ expectedModel.setResidence(lastResidence, editedResidence);
+ expectedModel.updateFilteredResidenceList(PREDICATE_SHOW_ALL_RESIDENCES);
assertCommandSuccess(editCommand, model, expectedMessage, expectedModel);
}
@Test
public void execute_noFieldSpecifiedUnfilteredList_success() {
- EditCommand editCommand = new EditCommand(INDEX_FIRST_PERSON, new EditPersonDescriptor());
- Person editedPerson = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased());
+ EditCommand editCommand = new EditCommand(INDEX_FIRST_RESIDENCE, new EditResidenceDescriptor());
+ Residence editedResidence = model.getFilteredResidenceList().get(INDEX_FIRST_RESIDENCE.getZeroBased());
- String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_PERSON_SUCCESS, editedPerson);
+ String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_RESIDENCE_SUCCESS, editedResidence);
- Model expectedModel = new ModelManager(new AddressBook(model.getAddressBook()), new UserPrefs());
+ Model expectedModel = new ModelManager(new ResidenceTracker(model.getResidenceTracker()), new UserPrefs());
+ expectedModel.updateFilteredResidenceList(PREDICATE_SHOW_ALL_RESIDENCES);
assertCommandSuccess(editCommand, model, expectedMessage, expectedModel);
}
@Test
public void execute_filteredList_success() {
- showPersonAtIndex(model, INDEX_FIRST_PERSON);
+ showResidenceAtIndex(model, INDEX_FIRST_RESIDENCE);
- Person personInFilteredList = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased());
- Person editedPerson = new PersonBuilder(personInFilteredList).withName(VALID_NAME_BOB).build();
- EditCommand editCommand = new EditCommand(INDEX_FIRST_PERSON,
- new EditPersonDescriptorBuilder().withName(VALID_NAME_BOB).build());
+ Residence residenceInFilteredList = model.getFilteredResidenceList().get(INDEX_FIRST_RESIDENCE.getZeroBased());
+ Residence editedResidence = new ResidenceBuilder(residenceInFilteredList)
+ .withName(VALID_NAME_RESIDENCE1).build();
+ EditCommand editCommand = new EditCommand(INDEX_FIRST_RESIDENCE,
+ new EditResidenceDescriptorBuilder().withName(VALID_NAME_RESIDENCE1).build());
- String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_PERSON_SUCCESS, editedPerson);
+ String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_RESIDENCE_SUCCESS, editedResidence);
- Model expectedModel = new ModelManager(new AddressBook(model.getAddressBook()), new UserPrefs());
- expectedModel.setPerson(model.getFilteredPersonList().get(0), editedPerson);
+ Model expectedModel = new ModelManager(new ResidenceTracker(model.getResidenceTracker()), new UserPrefs());
+ expectedModel.setResidence(model.getFilteredResidenceList().get(0), editedResidence);
+ expectedModel.updateFilteredResidenceList(PREDICATE_SHOW_ALL_RESIDENCES);
assertCommandSuccess(editCommand, model, expectedMessage, expectedModel);
}
@Test
- public void execute_duplicatePersonUnfilteredList_failure() {
- Person firstPerson = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased());
- EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder(firstPerson).build();
- EditCommand editCommand = new EditCommand(INDEX_SECOND_PERSON, descriptor);
+ public void execute_duplicateResidenceUnfilteredList_failure() {
+ Residence firstResidence = model.getFilteredResidenceList().get(INDEX_FIRST_RESIDENCE.getZeroBased());
+ EditResidenceDescriptor descriptor = new EditResidenceDescriptorBuilder(firstResidence).build();
+ EditCommand editCommand = new EditCommand(INDEX_SECOND_RESIDENCE, descriptor);
- assertCommandFailure(editCommand, model, EditCommand.MESSAGE_DUPLICATE_PERSON);
+ assertCommandFailure(editCommand, model, EditCommand.MESSAGE_DUPLICATE_RESIDENCE);
}
@Test
- public void execute_duplicatePersonFilteredList_failure() {
- showPersonAtIndex(model, INDEX_FIRST_PERSON);
+ public void execute_duplicateResidenceFilteredList_failure() {
+ showResidenceAtIndex(model, INDEX_FIRST_RESIDENCE);
// edit person in filtered list into a duplicate in address book
- Person personInList = model.getAddressBook().getPersonList().get(INDEX_SECOND_PERSON.getZeroBased());
- EditCommand editCommand = new EditCommand(INDEX_FIRST_PERSON,
- new EditPersonDescriptorBuilder(personInList).build());
+ Residence residenceInList = model.getResidenceTracker().getResidenceList()
+ .get(INDEX_SECOND_RESIDENCE.getZeroBased());
+ EditCommand editCommand = new EditCommand(INDEX_FIRST_RESIDENCE,
+ new EditResidenceDescriptorBuilder(residenceInList).build());
- assertCommandFailure(editCommand, model, EditCommand.MESSAGE_DUPLICATE_PERSON);
+ assertCommandFailure(editCommand, model, EditCommand.MESSAGE_DUPLICATE_RESIDENCE);
}
@Test
- public void execute_invalidPersonIndexUnfilteredList_failure() {
- Index outOfBoundIndex = Index.fromOneBased(model.getFilteredPersonList().size() + 1);
- EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withName(VALID_NAME_BOB).build();
+ public void execute_invalidResidenceIndexUnfilteredList_failure() {
+ Index outOfBoundIndex = Index.fromOneBased(model.getFilteredResidenceList().size() + 1);
+ EditResidenceDescriptor descriptor = new EditResidenceDescriptorBuilder()
+ .withName(VALID_NAME_RESIDENCE1).build();
EditCommand editCommand = new EditCommand(outOfBoundIndex, descriptor);
- assertCommandFailure(editCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
+ assertCommandFailure(editCommand, model, Messages.MESSAGE_INVALID_RESIDENCE_DISPLAYED_INDEX);
}
/**
@@ -133,25 +140,26 @@ public void execute_invalidPersonIndexUnfilteredList_failure() {
* but smaller than size of address book
*/
@Test
- public void execute_invalidPersonIndexFilteredList_failure() {
- showPersonAtIndex(model, INDEX_FIRST_PERSON);
- Index outOfBoundIndex = INDEX_SECOND_PERSON;
+ public void execute_invalidResidenceIndexFilteredList_failure() {
+ showResidenceAtIndex(model, INDEX_FIRST_RESIDENCE);
+ Index outOfBoundIndex = INDEX_SECOND_RESIDENCE;
// ensures that outOfBoundIndex is still in bounds of address book list
- assertTrue(outOfBoundIndex.getZeroBased() < model.getAddressBook().getPersonList().size());
+ assertTrue(outOfBoundIndex.getZeroBased() < model.getResidenceTracker().getResidenceList().size());
EditCommand editCommand = new EditCommand(outOfBoundIndex,
- new EditPersonDescriptorBuilder().withName(VALID_NAME_BOB).build());
+ new EditResidenceDescriptorBuilder().withName(VALID_NAME_RESIDENCE1).build());
- assertCommandFailure(editCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
+ assertCommandFailure(editCommand, model, Messages.MESSAGE_INVALID_RESIDENCE_DISPLAYED_INDEX);
}
@Test
public void equals() {
- final EditCommand standardCommand = new EditCommand(INDEX_FIRST_PERSON, DESC_AMY);
+ final EditCommand standardCommand =
+ new EditCommand(INDEX_FIRST_RESIDENCE, new EditResidenceDescriptor(DESC_RESIDENCE1));
// same values -> returns true
- EditPersonDescriptor copyDescriptor = new EditPersonDescriptor(DESC_AMY);
- EditCommand commandWithSameValues = new EditCommand(INDEX_FIRST_PERSON, copyDescriptor);
+ EditResidenceDescriptor copyDescriptor = new EditResidenceDescriptor(DESC_RESIDENCE1);
+ EditCommand commandWithSameValues = new EditCommand(INDEX_FIRST_RESIDENCE, copyDescriptor);
assertTrue(standardCommand.equals(commandWithSameValues));
// same object -> returns true
@@ -164,10 +172,10 @@ public void equals() {
assertFalse(standardCommand.equals(new ClearCommand()));
// different index -> returns false
- assertFalse(standardCommand.equals(new EditCommand(INDEX_SECOND_PERSON, DESC_AMY)));
+ assertFalse(standardCommand.equals(new EditCommand(INDEX_SECOND_RESIDENCE, DESC_RESIDENCE1)));
// different descriptor -> returns false
- assertFalse(standardCommand.equals(new EditCommand(INDEX_FIRST_PERSON, DESC_BOB)));
+ assertFalse(standardCommand.equals(new EditCommand(INDEX_SECOND_RESIDENCE, DESC_RESIDENCE1)));
}
}
diff --git a/src/test/java/seedu/address/logic/commands/EditPersonDescriptorTest.java b/src/test/java/seedu/address/logic/commands/EditPersonDescriptorTest.java
deleted file mode 100644
index e0288792e72..00000000000
--- a/src/test/java/seedu/address/logic/commands/EditPersonDescriptorTest.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package seedu.address.logic.commands;
-
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.logic.commands.CommandTestUtil.DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.DESC_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND;
-
-import org.junit.jupiter.api.Test;
-
-import seedu.address.logic.commands.EditCommand.EditPersonDescriptor;
-import seedu.address.testutil.EditPersonDescriptorBuilder;
-
-public class EditPersonDescriptorTest {
-
- @Test
- public void equals() {
- // same values -> returns true
- EditPersonDescriptor descriptorWithSameValues = new EditPersonDescriptor(DESC_AMY);
- assertTrue(DESC_AMY.equals(descriptorWithSameValues));
-
- // same object -> returns true
- assertTrue(DESC_AMY.equals(DESC_AMY));
-
- // null -> returns false
- assertFalse(DESC_AMY.equals(null));
-
- // different types -> returns false
- assertFalse(DESC_AMY.equals(5));
-
- // different values -> returns false
- assertFalse(DESC_AMY.equals(DESC_BOB));
-
- // different name -> returns false
- EditPersonDescriptor editedAmy = new EditPersonDescriptorBuilder(DESC_AMY).withName(VALID_NAME_BOB).build();
- assertFalse(DESC_AMY.equals(editedAmy));
-
- // different phone -> returns false
- editedAmy = new EditPersonDescriptorBuilder(DESC_AMY).withPhone(VALID_PHONE_BOB).build();
- assertFalse(DESC_AMY.equals(editedAmy));
-
- // different email -> returns false
- editedAmy = new EditPersonDescriptorBuilder(DESC_AMY).withEmail(VALID_EMAIL_BOB).build();
- assertFalse(DESC_AMY.equals(editedAmy));
-
- // different address -> returns false
- editedAmy = new EditPersonDescriptorBuilder(DESC_AMY).withAddress(VALID_ADDRESS_BOB).build();
- assertFalse(DESC_AMY.equals(editedAmy));
-
- // different tags -> returns false
- editedAmy = new EditPersonDescriptorBuilder(DESC_AMY).withTags(VALID_TAG_HUSBAND).build();
- assertFalse(DESC_AMY.equals(editedAmy));
- }
-}
diff --git a/src/test/java/seedu/address/logic/commands/FindCommandTest.java b/src/test/java/seedu/address/logic/commands/FindCommandTest.java
index 9b15db28bbb..e720a10ce29 100644
--- a/src/test/java/seedu/address/logic/commands/FindCommandTest.java
+++ b/src/test/java/seedu/address/logic/commands/FindCommandTest.java
@@ -3,12 +3,12 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.commons.core.Messages.MESSAGE_PERSONS_LISTED_OVERVIEW;
+import static seedu.address.commons.core.Messages.MESSAGE_RESIDENCE_LISTED_OVERVIEW;
import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
-import static seedu.address.testutil.TypicalPersons.CARL;
-import static seedu.address.testutil.TypicalPersons.ELLE;
-import static seedu.address.testutil.TypicalPersons.FIONA;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
+import static seedu.address.testutil.TypicalResidences.RESIDENCE_C;
+import static seedu.address.testutil.TypicalResidences.RESIDENCE_E;
+import static seedu.address.testutil.TypicalResidences.RESIDENCE_F;
+import static seedu.address.testutil.TypicalResidences.getTypicalResidenceTracker;
import java.util.Arrays;
import java.util.Collections;
@@ -18,14 +18,14 @@
import seedu.address.model.Model;
import seedu.address.model.ModelManager;
import seedu.address.model.UserPrefs;
-import seedu.address.model.person.NameContainsKeywordsPredicate;
+import seedu.address.model.residence.NameContainsKeywordsPredicate;
/**
* Contains integration tests (interaction with the Model) for {@code FindCommand}.
*/
public class FindCommandTest {
- private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
- private Model expectedModel = new ModelManager(getTypicalAddressBook(), new UserPrefs());
+ private Model model = new ModelManager(getTypicalResidenceTracker(), new UserPrefs());
+ private Model expectedModel = new ModelManager(getTypicalResidenceTracker(), new UserPrefs());
@Test
public void equals() {
@@ -55,23 +55,23 @@ public void equals() {
}
@Test
- public void execute_zeroKeywords_noPersonFound() {
- String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 0);
+ public void execute_zeroKeywords_noResidenceFound() {
+ String expectedMessage = String.format(MESSAGE_RESIDENCE_LISTED_OVERVIEW, 0);
NameContainsKeywordsPredicate predicate = preparePredicate(" ");
FindCommand command = new FindCommand(predicate);
- expectedModel.updateFilteredPersonList(predicate);
+ expectedModel.updateFilteredResidenceList(predicate);
assertCommandSuccess(command, model, expectedMessage, expectedModel);
- assertEquals(Collections.emptyList(), model.getFilteredPersonList());
+ assertEquals(Collections.emptyList(), model.getFilteredResidenceList());
}
@Test
- public void execute_multipleKeywords_multiplePersonsFound() {
- String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 3);
- NameContainsKeywordsPredicate predicate = preparePredicate("Kurz Elle Kunz");
+ public void execute_multipleKeywords_multipleResidencesFound() {
+ String expectedMessage = String.format(MESSAGE_RESIDENCE_LISTED_OVERVIEW, 3);
+ NameContainsKeywordsPredicate predicate = preparePredicate("Casuarina Emerald Floravale");
FindCommand command = new FindCommand(predicate);
- expectedModel.updateFilteredPersonList(predicate);
+ expectedModel.updateFilteredResidenceList(predicate);
assertCommandSuccess(command, model, expectedMessage, expectedModel);
- assertEquals(Arrays.asList(CARL, ELLE, FIONA), model.getFilteredPersonList());
+ assertEquals(Arrays.asList(RESIDENCE_F, RESIDENCE_C, RESIDENCE_E), model.getFilteredResidenceList());
}
/**
diff --git a/src/test/java/seedu/address/logic/commands/HelpCommandTest.java b/src/test/java/seedu/address/logic/commands/HelpCommandTest.java
index 4904fc4352e..10bbdc12ee0 100644
--- a/src/test/java/seedu/address/logic/commands/HelpCommandTest.java
+++ b/src/test/java/seedu/address/logic/commands/HelpCommandTest.java
@@ -1,7 +1,7 @@
package seedu.address.logic.commands;
import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
-import static seedu.address.logic.commands.HelpCommand.SHOWING_HELP_MESSAGE;
+import static seedu.address.logic.commands.HelpCommand.HELP_MESSAGE_DISPLAY;
import org.junit.jupiter.api.Test;
@@ -14,7 +14,7 @@ public class HelpCommandTest {
@Test
public void execute_help_success() {
- CommandResult expectedCommandResult = new CommandResult(SHOWING_HELP_MESSAGE, true, false);
+ CommandResult expectedCommandResult = new CommandResult(HELP_MESSAGE_DISPLAY, true, false);
assertCommandSuccess(new HelpCommand(), model, expectedCommandResult, expectedModel);
}
}
diff --git a/src/test/java/seedu/address/logic/commands/ListCommandTest.java b/src/test/java/seedu/address/logic/commands/ListCommandTest.java
index 435ff1f7275..391c3c7b19d 100644
--- a/src/test/java/seedu/address/logic/commands/ListCommandTest.java
+++ b/src/test/java/seedu/address/logic/commands/ListCommandTest.java
@@ -1,9 +1,10 @@
package seedu.address.logic.commands;
import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
-import static seedu.address.logic.commands.CommandTestUtil.showPersonAtIndex;
-import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
+import static seedu.address.logic.commands.CommandTestUtil.showResidenceAtIndex;
+import static seedu.address.model.Model.PREDICATE_SHOW_ALL_RESIDENCES;
+import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_RESIDENCE;
+import static seedu.address.testutil.TypicalResidences.getTypicalResidenceTracker;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -22,8 +23,9 @@ public class ListCommandTest {
@BeforeEach
public void setUp() {
- model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
- expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs());
+ model = new ModelManager(getTypicalResidenceTracker(), new UserPrefs());
+ expectedModel = new ModelManager(getTypicalResidenceTracker(), new UserPrefs());
+ expectedModel.updateFilteredResidenceList(PREDICATE_SHOW_ALL_RESIDENCES);
}
@Test
@@ -33,7 +35,7 @@ public void execute_listIsNotFiltered_showsSameList() {
@Test
public void execute_listIsFiltered_showsEverything() {
- showPersonAtIndex(model, INDEX_FIRST_PERSON);
+ showResidenceAtIndex(model, INDEX_FIRST_RESIDENCE);
assertCommandSuccess(new ListCommand(), model, ListCommand.MESSAGE_SUCCESS, expectedModel);
}
}
diff --git a/src/test/java/seedu/address/logic/commands/StatusCommandTest.java b/src/test/java/seedu/address/logic/commands/StatusCommandTest.java
new file mode 100644
index 00000000000..947cdfb4763
--- /dev/null
+++ b/src/test/java/seedu/address/logic/commands/StatusCommandTest.java
@@ -0,0 +1,73 @@
+package seedu.address.logic.commands;
+
+import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure;
+import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
+import static seedu.address.model.Model.PREDICATE_SHOW_ALL_RESIDENCES;
+import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_RESIDENCE;
+import static seedu.address.testutil.TypicalIndexes.INDEX_SIXTH_RESIDENCE;
+import static seedu.address.testutil.TypicalResidences.getTypicalResidenceTracker;
+
+import java.util.ArrayList;
+import java.util.Set;
+
+import org.junit.jupiter.api.Test;
+
+import seedu.address.commons.core.Messages;
+import seedu.address.commons.core.index.Index;
+import seedu.address.logic.commands.exceptions.CommandException;
+import seedu.address.model.Model;
+import seedu.address.model.ModelManager;
+import seedu.address.model.ResidenceTracker;
+import seedu.address.model.UserPrefs;
+import seedu.address.model.residence.BookingList;
+import seedu.address.model.residence.Residence;
+import seedu.address.model.residence.ResidenceAddress;
+import seedu.address.model.residence.ResidenceName;
+import seedu.address.model.tag.CleanStatusTag;
+import seedu.address.model.tag.Tag;
+
+public class StatusCommandTest {
+ private Model model = new ModelManager(getTypicalResidenceTracker(), new UserPrefs());
+ @Test
+ public void execute_updateMultipleResidenceStatus_cleanSuccess() throws CommandException {
+ ArrayList indexArray = new ArrayList<>();
+ indexArray.add(INDEX_SECOND_RESIDENCE);
+ indexArray.add(INDEX_SIXTH_RESIDENCE);
+ String cleanStatus = "clean";
+ StatusCommand statusCommand = new StatusCommand(indexArray, cleanStatus);
+ Model expectedModel = new ModelManager(new ResidenceTracker(model.getResidenceTracker()), new UserPrefs());
+ String expectedMessage = "";
+
+ for (Index index : indexArray) {
+ Residence residenceToUpdateStatus = model.getFilteredResidenceList().get(index.getZeroBased());
+ ResidenceName updatedName = residenceToUpdateStatus.getResidenceName();
+ ResidenceAddress updatedAddress = residenceToUpdateStatus.getResidenceAddress();
+ BookingList updatedBooking = residenceToUpdateStatus.getBookingList();
+ CleanStatusTag updatedCleanStatus;
+ if (cleanStatus.equals("clean")) {
+ updatedCleanStatus = new CleanStatusTag("y");
+ } else if (cleanStatus.equals("unclean")) {
+ updatedCleanStatus = new CleanStatusTag("n");
+ } else {
+ throw new CommandException(StatusCommand.MESSAGE_ERROR_STATUS);
+ }
+ Set updatedTags = residenceToUpdateStatus.getTags();
+ Residence updatedResidence = new Residence(updatedName, updatedAddress,
+ updatedBooking, updatedCleanStatus, updatedTags);
+ expectedModel.setResidence(residenceToUpdateStatus, updatedResidence);
+ expectedMessage += updatedResidence.toString() + "\n";
+ }
+ expectedModel.updateFilteredResidenceList(PREDICATE_SHOW_ALL_RESIDENCES);
+ expectedMessage = String.format(StatusCommand.MESSAGE_STATUS_RESIDENCE_SUCCESS, expectedMessage);
+ assertCommandSuccess(statusCommand, model, expectedMessage, expectedModel);
+ }
+
+ @Test
+ public void execute_invalidResidenceIndexUnfilteredList_failure() {
+ Index outOfBoundIndex = Index.fromOneBased(model.getFilteredResidenceList().size() + 1);
+ ArrayList indexArray = new ArrayList<>();
+ indexArray.add(outOfBoundIndex);
+ StatusCommand statusCommand = new StatusCommand(indexArray, "clean");
+ assertCommandFailure(statusCommand, model, Messages.MESSAGE_INVALID_RESIDENCE_DISPLAYED_INDEX);
+ }
+}
diff --git a/src/test/java/seedu/address/logic/parser/AddCommandParserTest.java b/src/test/java/seedu/address/logic/parser/AddCommandParserTest.java
index 5cf487d7ebb..86da5a6e1cb 100644
--- a/src/test/java/seedu/address/logic/parser/AddCommandParserTest.java
+++ b/src/test/java/seedu/address/logic/parser/AddCommandParserTest.java
@@ -1,85 +1,95 @@
package seedu.address.logic.parser;
import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
-import static seedu.address.logic.commands.CommandTestUtil.ADDRESS_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.ADDRESS_DESC_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.EMAIL_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.EMAIL_DESC_BOB;
+import static seedu.address.logic.commands.CommandTestUtil.ADDRESS_DESC_RESIDENCE1;
+import static seedu.address.logic.commands.CommandTestUtil.ADDRESS_DESC_RESIDENCE2;
+import static seedu.address.logic.commands.CommandTestUtil.CLEAN_STATUS_DESC;
import static seedu.address.logic.commands.CommandTestUtil.INVALID_ADDRESS_DESC;
-import static seedu.address.logic.commands.CommandTestUtil.INVALID_EMAIL_DESC;
+import static seedu.address.logic.commands.CommandTestUtil.INVALID_CLEAN_TAG_DESC;
import static seedu.address.logic.commands.CommandTestUtil.INVALID_NAME_DESC;
-import static seedu.address.logic.commands.CommandTestUtil.INVALID_PHONE_DESC;
import static seedu.address.logic.commands.CommandTestUtil.INVALID_TAG_DESC;
-import static seedu.address.logic.commands.CommandTestUtil.NAME_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.NAME_DESC_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.PHONE_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.PHONE_DESC_BOB;
+import static seedu.address.logic.commands.CommandTestUtil.NAME_DESC_RESIDENCE1;
+import static seedu.address.logic.commands.CommandTestUtil.NAME_DESC_RESIDENCE2;
import static seedu.address.logic.commands.CommandTestUtil.PREAMBLE_NON_EMPTY;
import static seedu.address.logic.commands.CommandTestUtil.PREAMBLE_WHITESPACE;
-import static seedu.address.logic.commands.CommandTestUtil.TAG_DESC_FRIEND;
-import static seedu.address.logic.commands.CommandTestUtil.TAG_DESC_HUSBAND;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_FRIEND;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND;
+import static seedu.address.logic.commands.CommandTestUtil.TAG_DESC_REPAIR;
+import static seedu.address.logic.commands.CommandTestUtil.TAG_DESC_RESERVED;
+import static seedu.address.logic.commands.CommandTestUtil.UNCLEAN_STATUS_DESC;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_RESIDENCE2;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_CLEAN_TAG;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_RESIDENCE2;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_REPAIR;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_RESERVED;
import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure;
import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess;
-import static seedu.address.testutil.TypicalPersons.AMY;
-import static seedu.address.testutil.TypicalPersons.BOB;
+import static seedu.address.testutil.TypicalResidences.RESIDENCE1;
+import static seedu.address.testutil.TypicalResidences.RESIDENCE2;
import org.junit.jupiter.api.Test;
import seedu.address.logic.commands.AddCommand;
-import seedu.address.model.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Person;
-import seedu.address.model.person.Phone;
+import seedu.address.model.residence.Residence;
+import seedu.address.model.residence.ResidenceAddress;
+import seedu.address.model.residence.ResidenceName;
+import seedu.address.model.tag.CleanStatusTag;
import seedu.address.model.tag.Tag;
-import seedu.address.testutil.PersonBuilder;
+import seedu.address.testutil.ResidenceBuilder;
public class AddCommandParserTest {
private AddCommandParser parser = new AddCommandParser();
@Test
public void parse_allFieldsPresent_success() {
- Person expectedPerson = new PersonBuilder(BOB).withTags(VALID_TAG_FRIEND).build();
-
+ Residence expectedResidence = new ResidenceBuilder(RESIDENCE2).withTags(VALID_TAG_RESERVED).build();
+ //normal input
+ assertParseSuccess(parser, NAME_DESC_RESIDENCE2 + ADDRESS_DESC_RESIDENCE2
+ + CLEAN_STATUS_DESC + TAG_DESC_RESERVED, new AddCommand(expectedResidence));
// whitespace only preamble
- assertParseSuccess(parser, PREAMBLE_WHITESPACE + NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB
- + ADDRESS_DESC_BOB + TAG_DESC_FRIEND, new AddCommand(expectedPerson));
+ assertParseSuccess(parser, PREAMBLE_WHITESPACE + NAME_DESC_RESIDENCE2 + ADDRESS_DESC_RESIDENCE2
+ + CLEAN_STATUS_DESC + TAG_DESC_RESERVED, new AddCommand(expectedResidence));
// multiple names - last name accepted
- assertParseSuccess(parser, NAME_DESC_AMY + NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB
- + ADDRESS_DESC_BOB + TAG_DESC_FRIEND, new AddCommand(expectedPerson));
-
- // multiple phones - last phone accepted
- assertParseSuccess(parser, NAME_DESC_BOB + PHONE_DESC_AMY + PHONE_DESC_BOB + EMAIL_DESC_BOB
- + ADDRESS_DESC_BOB + TAG_DESC_FRIEND, new AddCommand(expectedPerson));
-
- // multiple emails - last email accepted
- assertParseSuccess(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_AMY + EMAIL_DESC_BOB
- + ADDRESS_DESC_BOB + TAG_DESC_FRIEND, new AddCommand(expectedPerson));
+ assertParseSuccess(parser, NAME_DESC_RESIDENCE1 + NAME_DESC_RESIDENCE2 + ADDRESS_DESC_RESIDENCE2
+ + CLEAN_STATUS_DESC + TAG_DESC_RESERVED, new AddCommand(expectedResidence));
// multiple addresses - last address accepted
- assertParseSuccess(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_AMY
- + ADDRESS_DESC_BOB + TAG_DESC_FRIEND, new AddCommand(expectedPerson));
+ assertParseSuccess(parser, NAME_DESC_RESIDENCE2 + ADDRESS_DESC_RESIDENCE1 + ADDRESS_DESC_RESIDENCE2
+ + CLEAN_STATUS_DESC + TAG_DESC_RESERVED, new AddCommand(expectedResidence));
+
+ // multiple clean tags - last clean tag accepted
+ assertParseSuccess(parser, NAME_DESC_RESIDENCE2 + ADDRESS_DESC_RESIDENCE2
+ + UNCLEAN_STATUS_DESC + CLEAN_STATUS_DESC + TAG_DESC_RESERVED, new AddCommand(expectedResidence));
// multiple tags - all accepted
- Person expectedPersonMultipleTags = new PersonBuilder(BOB).withTags(VALID_TAG_FRIEND, VALID_TAG_HUSBAND)
- .build();
- assertParseSuccess(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB
- + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, new AddCommand(expectedPersonMultipleTags));
+ Residence expectedResidenceMultipleTags = new ResidenceBuilder(RESIDENCE2).withTags(VALID_TAG_REPAIR,
+ VALID_TAG_RESERVED).build();
+ assertParseSuccess(parser, NAME_DESC_RESIDENCE2 + ADDRESS_DESC_RESIDENCE2
+ + CLEAN_STATUS_DESC + TAG_DESC_RESERVED
+ + TAG_DESC_REPAIR, new AddCommand(expectedResidenceMultipleTags));
}
@Test
public void parse_optionalFieldsMissing_success() {
+ // zero clean status tags and tags
+ Residence expectedResidence1 = new ResidenceBuilder(RESIDENCE1).withCleanStatusTag("clean")
+ .withTags().build();
+
+ assertParseSuccess(parser, NAME_DESC_RESIDENCE1 + ADDRESS_DESC_RESIDENCE1,
+ new AddCommand(expectedResidence1));
+
+ // zero clean status tags
+ Residence expectedResidence2 = new ResidenceBuilder(RESIDENCE1).withCleanStatusTag("clean")
+ .withTags(VALID_TAG_RESERVED).build();
+
+ assertParseSuccess(parser, NAME_DESC_RESIDENCE1 + ADDRESS_DESC_RESIDENCE1
+ + TAG_DESC_RESERVED, new AddCommand(expectedResidence2));
+
// zero tags
- Person expectedPerson = new PersonBuilder(AMY).withTags().build();
- assertParseSuccess(parser, NAME_DESC_AMY + PHONE_DESC_AMY + EMAIL_DESC_AMY + ADDRESS_DESC_AMY,
- new AddCommand(expectedPerson));
+ Residence expectedResidence3 = new ResidenceBuilder(RESIDENCE1).withCleanStatusTag("clean")
+ .withTags().build();
+
+ assertParseSuccess(parser, NAME_DESC_RESIDENCE1 + ADDRESS_DESC_RESIDENCE1
+ + CLEAN_STATUS_DESC, new AddCommand(expectedResidence3));
}
@Test
@@ -87,55 +97,41 @@ public void parse_compulsoryFieldMissing_failure() {
String expectedMessage = String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE);
// missing name prefix
- assertParseFailure(parser, VALID_NAME_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB,
- expectedMessage);
-
- // missing phone prefix
- assertParseFailure(parser, NAME_DESC_BOB + VALID_PHONE_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB,
- expectedMessage);
-
- // missing email prefix
- assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + VALID_EMAIL_BOB + ADDRESS_DESC_BOB,
- expectedMessage);
+ assertParseFailure(parser, VALID_NAME_RESIDENCE2 + ADDRESS_DESC_RESIDENCE2, expectedMessage);
// missing address prefix
- assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + VALID_ADDRESS_BOB,
- expectedMessage);
+ assertParseFailure(parser, NAME_DESC_RESIDENCE2 + VALID_ADDRESS_RESIDENCE2, expectedMessage);
// all prefixes missing
- assertParseFailure(parser, VALID_NAME_BOB + VALID_PHONE_BOB + VALID_EMAIL_BOB + VALID_ADDRESS_BOB,
- expectedMessage);
+ assertParseFailure(parser, VALID_NAME_RESIDENCE2 + VALID_ADDRESS_RESIDENCE2
+ + VALID_CLEAN_TAG, expectedMessage);
}
@Test
public void parse_invalidValue_failure() {
// invalid name
- assertParseFailure(parser, INVALID_NAME_DESC + PHONE_DESC_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB
- + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, Name.MESSAGE_CONSTRAINTS);
-
- // invalid phone
- assertParseFailure(parser, NAME_DESC_BOB + INVALID_PHONE_DESC + EMAIL_DESC_BOB + ADDRESS_DESC_BOB
- + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, Phone.MESSAGE_CONSTRAINTS);
-
- // invalid email
- assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + INVALID_EMAIL_DESC + ADDRESS_DESC_BOB
- + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, Email.MESSAGE_CONSTRAINTS);
+ assertParseFailure(parser, INVALID_NAME_DESC + ADDRESS_DESC_RESIDENCE2
+ + CLEAN_STATUS_DESC, ResidenceName.MESSAGE_CONSTRAINTS);
// invalid address
- assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + INVALID_ADDRESS_DESC
- + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, Address.MESSAGE_CONSTRAINTS);
+ assertParseFailure(parser, NAME_DESC_RESIDENCE2 + INVALID_ADDRESS_DESC
+ + CLEAN_STATUS_DESC, ResidenceAddress.MESSAGE_CONSTRAINTS);
+
+ // invalid clean status tag
+ assertParseFailure(parser, NAME_DESC_RESIDENCE2 + ADDRESS_DESC_RESIDENCE2
+ + INVALID_CLEAN_TAG_DESC, CleanStatusTag.MESSAGE_CONSTRAINTS);
// invalid tag
- assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB
- + INVALID_TAG_DESC + VALID_TAG_FRIEND, Tag.MESSAGE_CONSTRAINTS);
+ assertParseFailure(parser, NAME_DESC_RESIDENCE2 + ADDRESS_DESC_RESIDENCE2
+ + CLEAN_STATUS_DESC + INVALID_TAG_DESC, Tag.MESSAGE_CONSTRAINTS);
// two invalid values, only first invalid value reported
- assertParseFailure(parser, INVALID_NAME_DESC + PHONE_DESC_BOB + EMAIL_DESC_BOB + INVALID_ADDRESS_DESC,
- Name.MESSAGE_CONSTRAINTS);
+ assertParseFailure(parser, INVALID_NAME_DESC + INVALID_ADDRESS_DESC
+ + CLEAN_STATUS_DESC, ResidenceName.MESSAGE_CONSTRAINTS);
// non-empty preamble
- assertParseFailure(parser, PREAMBLE_NON_EMPTY + NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB
- + ADDRESS_DESC_BOB + TAG_DESC_HUSBAND + TAG_DESC_FRIEND,
+ assertParseFailure(parser, PREAMBLE_NON_EMPTY + NAME_DESC_RESIDENCE2 + ADDRESS_DESC_RESIDENCE2
+ + CLEAN_STATUS_DESC + TAG_DESC_RESERVED + TAG_DESC_REPAIR,
String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE));
}
}
diff --git a/src/test/java/seedu/address/logic/parser/DeleteCommandParserTest.java b/src/test/java/seedu/address/logic/parser/DeleteCommandParserTest.java
index 27eaec84450..2db0a625300 100644
--- a/src/test/java/seedu/address/logic/parser/DeleteCommandParserTest.java
+++ b/src/test/java/seedu/address/logic/parser/DeleteCommandParserTest.java
@@ -1,9 +1,8 @@
package seedu.address.logic.parser;
-import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure;
import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess;
-import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON;
+import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_RESIDENCE;
import org.junit.jupiter.api.Test;
@@ -22,11 +21,11 @@ public class DeleteCommandParserTest {
@Test
public void parse_validArgs_returnsDeleteCommand() {
- assertParseSuccess(parser, "1", new DeleteCommand(INDEX_FIRST_PERSON));
+ assertParseSuccess(parser, "1", new DeleteCommand(INDEX_FIRST_RESIDENCE));
}
@Test
public void parse_invalidArgs_throwsParseException() {
- assertParseFailure(parser, "a", String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE));
+ assertParseFailure(parser, "a", ParserUtil.MESSAGE_INVALID_INDEX);
}
}
diff --git a/src/test/java/seedu/address/logic/parser/EditBookingCommandParserTest.java b/src/test/java/seedu/address/logic/parser/EditBookingCommandParserTest.java
new file mode 100644
index 00000000000..731e1e31524
--- /dev/null
+++ b/src/test/java/seedu/address/logic/parser/EditBookingCommandParserTest.java
@@ -0,0 +1,148 @@
+package seedu.address.logic.parser;
+
+import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
+import static seedu.address.logic.commands.CommandTestUtil.INVALID_NAME_DESC;
+import static seedu.address.logic.commands.CommandTestUtil.INVALID_PHONE_DESC;
+import static seedu.address.logic.commands.CommandTestUtil.PHONE_DESC_BOOKING1;
+import static seedu.address.logic.commands.CommandTestUtil.TENANT_NAME_DESC_AMY;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_BOOKING_END1;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_BOOKING_START1;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_LOCALDATE_END1;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_LOCALDATE_START1;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_BOOKING1;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_BOOKING1;
+import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure;
+import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess;
+import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_BOOKING;
+import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_RESIDENCE;
+
+import org.junit.jupiter.api.Test;
+
+import seedu.address.commons.core.index.Index;
+import seedu.address.logic.commands.EditBookingCommand;
+import seedu.address.logic.commands.EditBookingCommand.EditBookingDescriptor;
+import seedu.address.model.booking.Phone;
+import seedu.address.model.booking.TenantName;
+import seedu.address.testutil.EditBookingDescriptorBuilder;
+
+
+public class EditBookingCommandParserTest {
+
+ private static final String MESSAGE_INVALID_FORMAT =
+ String.format(MESSAGE_INVALID_COMMAND_FORMAT, EditBookingCommand.MESSAGE_USAGE);
+
+ private EditBookingCommandParser parser = new EditBookingCommandParser();
+
+ @SuppressWarnings("checkstyle:SingleSpaceSeparator")
+ @Test
+ public void parse_missingParts_failure() {
+ //no index specified
+ assertParseFailure(parser, "1", MESSAGE_INVALID_FORMAT);
+
+ //index 0 specified => should show non zero unsigned integer
+ assertParseFailure(parser, " r/0 b/0 ", ParserUtil.MESSAGE_INVALID_INDEX);
+
+ //no field specified
+ assertParseFailure(parser, " r/1 b/1 ", EditBookingCommand.MESSAGE_NOT_EDITED);
+
+ //no index and no field specified
+ assertParseFailure(parser, "", MESSAGE_INVALID_FORMAT);
+
+ }
+
+ @Test
+ public void parse_invalidPreamble_failure() {
+ // negative index
+ assertParseFailure(parser, " r/-5 b/1" + TENANT_NAME_DESC_AMY, ParserUtil.MESSAGE_INVALID_INDEX);
+
+ // zero index
+ assertParseFailure(parser, " r/0 b/0" + TENANT_NAME_DESC_AMY, ParserUtil.MESSAGE_INVALID_INDEX);
+
+ // string
+ assertParseFailure(parser, " r/one b/one" + TENANT_NAME_DESC_AMY, ParserUtil.MESSAGE_INVALID_INDEX);
+
+ // invalid arguments being parsed as preamble
+ assertParseFailure(parser, " r/1 b/1 some random string", ParserUtil.MESSAGE_INVALID_INDEX);
+
+ //invalid prefix being parsed as preamble
+ assertParseFailure(parser, " r/1 b/1 z/nameToChange", ParserUtil.MESSAGE_INVALID_INDEX);
+ }
+
+ @Test
+ public void parse_invalidValue_failure() {
+ // invalid name
+ assertParseFailure(parser, " r/1 b/1 " + INVALID_NAME_DESC, TenantName.MESSAGE_CONSTRAINTS);
+ // invalid address
+ assertParseFailure(parser, " r/1 b/1 " + INVALID_PHONE_DESC, Phone.MESSAGE_CONSTRAINTS);
+ // invalid dates
+ assertParseFailure(parser, " r/1 b/1 s/2000-2000", ParserUtil.MESSAGE_INVALID_DATE_FORMAT);
+ }
+
+ @Test
+ public void parse_allFieldsSuccess() {
+ Index bookingIndex = INDEX_SECOND_BOOKING;
+ Index residenceIndex = INDEX_SECOND_RESIDENCE;
+ String userInput = " r/" + residenceIndex.getOneBased() + " b/" + bookingIndex.getOneBased()
+ + TENANT_NAME_DESC_AMY + PHONE_DESC_BOOKING1
+ + " s/" + VALID_BOOKING_START1 + " e/" + VALID_BOOKING_END1;
+ EditBookingDescriptor descriptor = new EditBookingDescriptorBuilder()
+ .withName(VALID_NAME_BOOKING1)
+ .withPhone(VALID_PHONE_BOOKING1)
+ .withStartDate(VALID_LOCALDATE_START1)
+ .withEndDate(VALID_LOCALDATE_END1).build();
+ EditBookingCommand expectedCommand = new EditBookingCommand(residenceIndex, bookingIndex, descriptor);
+ assertParseSuccess(parser, userInput, expectedCommand);
+ }
+
+ @Test
+ public void parse_someFieldsSuccess() {
+ Index bookingIndex = INDEX_SECOND_BOOKING;
+ Index residenceIndex = INDEX_SECOND_RESIDENCE;
+ String userInput = " r/" + residenceIndex.getOneBased() + " b/" + bookingIndex.getOneBased()
+ + TENANT_NAME_DESC_AMY + PHONE_DESC_BOOKING1;
+ EditBookingDescriptor descriptor = new EditBookingDescriptorBuilder()
+ .withName(VALID_NAME_BOOKING1)
+ .withPhone(VALID_PHONE_BOOKING1).build();
+ EditBookingCommand expectedCommand = new EditBookingCommand(residenceIndex, bookingIndex, descriptor);
+ assertParseSuccess(parser, userInput, expectedCommand);
+
+ }
+
+ @Test
+ public void parse_oneFieldSuccess() {
+ //TenantName
+ Index bookingIndex = INDEX_SECOND_BOOKING;
+ Index residenceIndex = INDEX_SECOND_RESIDENCE;
+ String userInput = " r/" + residenceIndex.getOneBased() + " b/" + bookingIndex.getOneBased()
+ + TENANT_NAME_DESC_AMY;
+ EditBookingDescriptor descriptor = new EditBookingDescriptorBuilder()
+ .withName(VALID_NAME_BOOKING1).build();
+ EditBookingCommand expectedCommand = new EditBookingCommand(residenceIndex, bookingIndex, descriptor);
+ assertParseSuccess(parser, userInput, expectedCommand);
+
+ //Phone
+ userInput = " r/" + residenceIndex.getOneBased() + " b/" + bookingIndex.getOneBased()
+ + PHONE_DESC_BOOKING1;
+ descriptor = new EditBookingDescriptorBuilder()
+ .withPhone(VALID_PHONE_BOOKING1).build();
+ expectedCommand = new EditBookingCommand(residenceIndex, bookingIndex, descriptor);
+ assertParseSuccess(parser, userInput, expectedCommand);
+
+ //Start Date
+ userInput = " r/" + residenceIndex.getOneBased() + " b/" + bookingIndex.getOneBased()
+ + " s/" + VALID_BOOKING_START1;
+ descriptor = new EditBookingDescriptorBuilder()
+ .withStartDate(VALID_LOCALDATE_START1).build();
+ expectedCommand = new EditBookingCommand(residenceIndex, bookingIndex, descriptor);
+ assertParseSuccess(parser, userInput, expectedCommand);
+
+ //End Date
+ userInput = " r/" + residenceIndex.getOneBased() + " b/" + bookingIndex.getOneBased()
+ + " e/" + VALID_BOOKING_END1;
+ descriptor = new EditBookingDescriptorBuilder()
+ .withEndDate(VALID_LOCALDATE_END1).build();
+ expectedCommand = new EditBookingCommand(residenceIndex, bookingIndex, descriptor);
+ assertParseSuccess(parser, userInput, expectedCommand);
+ }
+
+}
diff --git a/src/test/java/seedu/address/logic/parser/EditCommandParserTest.java b/src/test/java/seedu/address/logic/parser/EditCommandParserTest.java
index 2ff31522486..67c6a7b4087 100644
--- a/src/test/java/seedu/address/logic/parser/EditCommandParserTest.java
+++ b/src/test/java/seedu/address/logic/parser/EditCommandParserTest.java
@@ -1,47 +1,35 @@
package seedu.address.logic.parser;
import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
-import static seedu.address.logic.commands.CommandTestUtil.ADDRESS_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.ADDRESS_DESC_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.EMAIL_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.EMAIL_DESC_BOB;
+import static seedu.address.logic.commands.CommandTestUtil.ADDRESS_DESC_RESIDENCE1;
+import static seedu.address.logic.commands.CommandTestUtil.CLEAN_STATUS_DESC;
import static seedu.address.logic.commands.CommandTestUtil.INVALID_ADDRESS_DESC;
-import static seedu.address.logic.commands.CommandTestUtil.INVALID_EMAIL_DESC;
import static seedu.address.logic.commands.CommandTestUtil.INVALID_NAME_DESC;
-import static seedu.address.logic.commands.CommandTestUtil.INVALID_PHONE_DESC;
import static seedu.address.logic.commands.CommandTestUtil.INVALID_TAG_DESC;
-import static seedu.address.logic.commands.CommandTestUtil.NAME_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.PHONE_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.PHONE_DESC_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.TAG_DESC_FRIEND;
-import static seedu.address.logic.commands.CommandTestUtil.TAG_DESC_HUSBAND;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_FRIEND;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND;
+import static seedu.address.logic.commands.CommandTestUtil.NAME_DESC_RESIDENCE1;
+import static seedu.address.logic.commands.CommandTestUtil.TAG_DESC_BOOKED;
+import static seedu.address.logic.commands.CommandTestUtil.TAG_DESC_REPAIR;
+import static seedu.address.logic.commands.CommandTestUtil.TAG_DESC_RESERVED;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_RESIDENCE1;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_CLEAN_TAG;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_RESIDENCE1;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_REPAIR;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_RESERVED;
import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG;
import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure;
import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess;
-import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON;
-import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_PERSON;
-import static seedu.address.testutil.TypicalIndexes.INDEX_THIRD_PERSON;
+import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_RESIDENCE;
+import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_RESIDENCE;
import org.junit.jupiter.api.Test;
import seedu.address.commons.core.index.Index;
import seedu.address.logic.commands.EditCommand;
-import seedu.address.logic.commands.EditCommand.EditPersonDescriptor;
-import seedu.address.model.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Phone;
+import seedu.address.logic.commands.EditCommand.EditResidenceDescriptor;
+import seedu.address.model.residence.ResidenceAddress;
+import seedu.address.model.residence.ResidenceName;
import seedu.address.model.tag.Tag;
-import seedu.address.testutil.EditPersonDescriptorBuilder;
+import seedu.address.testutil.EditResidenceDescriptorBuilder;
public class EditCommandParserTest {
@@ -55,7 +43,7 @@ public class EditCommandParserTest {
@Test
public void parse_missingParts_failure() {
// no index specified
- assertParseFailure(parser, VALID_NAME_AMY, MESSAGE_INVALID_FORMAT);
+ assertParseFailure(parser, ADDRESS_DESC_RESIDENCE1, MESSAGE_INVALID_FORMAT);
// no field specified
assertParseFailure(parser, "1", EditCommand.MESSAGE_NOT_EDITED);
@@ -67,53 +55,45 @@ public void parse_missingParts_failure() {
@Test
public void parse_invalidPreamble_failure() {
// negative index
- assertParseFailure(parser, "-5" + NAME_DESC_AMY, MESSAGE_INVALID_FORMAT);
+ assertParseFailure(parser, "-5" + NAME_DESC_RESIDENCE1, ParserUtil.MESSAGE_INVALID_INDEX);
// zero index
- assertParseFailure(parser, "0" + NAME_DESC_AMY, MESSAGE_INVALID_FORMAT);
+ assertParseFailure(parser, "0" + NAME_DESC_RESIDENCE1, ParserUtil.MESSAGE_INVALID_INDEX);
// invalid arguments being parsed as preamble
- assertParseFailure(parser, "1 some random string", MESSAGE_INVALID_FORMAT);
+ assertParseFailure(parser, "1 some random string", ParserUtil.MESSAGE_INVALID_INDEX);
// invalid prefix being parsed as preamble
- assertParseFailure(parser, "1 i/ string", MESSAGE_INVALID_FORMAT);
+ assertParseFailure(parser, "1 i/ string", ParserUtil.MESSAGE_INVALID_INDEX);
}
@Test
public void parse_invalidValue_failure() {
- assertParseFailure(parser, "1" + INVALID_NAME_DESC, Name.MESSAGE_CONSTRAINTS); // invalid name
- assertParseFailure(parser, "1" + INVALID_PHONE_DESC, Phone.MESSAGE_CONSTRAINTS); // invalid phone
- assertParseFailure(parser, "1" + INVALID_EMAIL_DESC, Email.MESSAGE_CONSTRAINTS); // invalid email
- assertParseFailure(parser, "1" + INVALID_ADDRESS_DESC, Address.MESSAGE_CONSTRAINTS); // invalid address
- assertParseFailure(parser, "1" + INVALID_TAG_DESC, Tag.MESSAGE_CONSTRAINTS); // invalid tag
-
- // invalid phone followed by valid email
- assertParseFailure(parser, "1" + INVALID_PHONE_DESC + EMAIL_DESC_AMY, Phone.MESSAGE_CONSTRAINTS);
-
- // valid phone followed by invalid phone. The test case for invalid phone followed by valid phone
- // is tested at {@code parse_invalidValueFollowedByValidValue_success()}
- assertParseFailure(parser, "1" + PHONE_DESC_BOB + INVALID_PHONE_DESC, Phone.MESSAGE_CONSTRAINTS);
-
- // while parsing {@code PREFIX_TAG} alone will reset the tags of the {@code Person} being edited,
+ // invalid name
+ assertParseFailure(parser, "1" + INVALID_NAME_DESC, ResidenceName.MESSAGE_CONSTRAINTS);
+ // invalid address
+ assertParseFailure(parser, "1" + INVALID_ADDRESS_DESC, ResidenceAddress.MESSAGE_CONSTRAINTS);
+ // invalid tag
+ assertParseFailure(parser, "1" + INVALID_TAG_DESC, Tag.MESSAGE_CONSTRAINTS);
+
+ // while parsing {@code PREFIX_TAG} alone will reset the tags of the {@code Residence} being edited,
// parsing it together with a valid tag results in error
- assertParseFailure(parser, "1" + TAG_DESC_FRIEND + TAG_DESC_HUSBAND + TAG_EMPTY, Tag.MESSAGE_CONSTRAINTS);
- assertParseFailure(parser, "1" + TAG_DESC_FRIEND + TAG_EMPTY + TAG_DESC_HUSBAND, Tag.MESSAGE_CONSTRAINTS);
- assertParseFailure(parser, "1" + TAG_EMPTY + TAG_DESC_FRIEND + TAG_DESC_HUSBAND, Tag.MESSAGE_CONSTRAINTS);
+ assertParseFailure(parser, "1" + TAG_DESC_RESERVED + TAG_DESC_BOOKED + TAG_EMPTY, Tag.MESSAGE_CONSTRAINTS);
+ assertParseFailure(parser, "1" + TAG_DESC_RESERVED + TAG_EMPTY + TAG_DESC_BOOKED, Tag.MESSAGE_CONSTRAINTS);
// multiple invalid values, but only the first invalid value is captured
- assertParseFailure(parser, "1" + INVALID_NAME_DESC + INVALID_EMAIL_DESC + VALID_ADDRESS_AMY + VALID_PHONE_AMY,
- Name.MESSAGE_CONSTRAINTS);
+ assertParseFailure(parser, "1" + INVALID_NAME_DESC + INVALID_ADDRESS_DESC + VALID_ADDRESS_RESIDENCE1,
+ ResidenceName.MESSAGE_CONSTRAINTS);
}
@Test
- public void parse_allFieldsSpecified_success() {
- Index targetIndex = INDEX_SECOND_PERSON;
- String userInput = targetIndex.getOneBased() + PHONE_DESC_BOB + TAG_DESC_HUSBAND
- + EMAIL_DESC_AMY + ADDRESS_DESC_AMY + NAME_DESC_AMY + TAG_DESC_FRIEND;
-
- EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withName(VALID_NAME_AMY)
- .withPhone(VALID_PHONE_BOB).withEmail(VALID_EMAIL_AMY).withAddress(VALID_ADDRESS_AMY)
- .withTags(VALID_TAG_HUSBAND, VALID_TAG_FRIEND).build();
+ public void parse_allFieldsSpecified_success() {
+ Index targetIndex = INDEX_SECOND_RESIDENCE;
+ String userInput = targetIndex.getOneBased() + NAME_DESC_RESIDENCE1 + ADDRESS_DESC_RESIDENCE1
+ + CLEAN_STATUS_DESC + TAG_DESC_RESERVED;
+ EditResidenceDescriptor descriptor = new EditResidenceDescriptorBuilder().withName(VALID_NAME_RESIDENCE1)
+ .withAddress(VALID_ADDRESS_RESIDENCE1).withCleanStatusTag(VALID_CLEAN_TAG)
+ .withTags(VALID_TAG_RESERVED).build();
EditCommand expectedCommand = new EditCommand(targetIndex, descriptor);
assertParseSuccess(parser, userInput, expectedCommand);
@@ -121,11 +101,10 @@ public void parse_allFieldsSpecified_success() {
@Test
public void parse_someFieldsSpecified_success() {
- Index targetIndex = INDEX_FIRST_PERSON;
- String userInput = targetIndex.getOneBased() + PHONE_DESC_BOB + EMAIL_DESC_AMY;
-
- EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withPhone(VALID_PHONE_BOB)
- .withEmail(VALID_EMAIL_AMY).build();
+ Index targetIndex = INDEX_FIRST_RESIDENCE;
+ String userInput = targetIndex.getOneBased() + NAME_DESC_RESIDENCE1 + ADDRESS_DESC_RESIDENCE1;
+ EditResidenceDescriptor descriptor = new EditResidenceDescriptorBuilder()
+ .withName(VALID_NAME_RESIDENCE1).withAddress(VALID_ADDRESS_RESIDENCE1).build();
EditCommand expectedCommand = new EditCommand(targetIndex, descriptor);
assertParseSuccess(parser, userInput, expectedCommand);
@@ -134,46 +113,43 @@ public void parse_someFieldsSpecified_success() {
@Test
public void parse_oneFieldSpecified_success() {
// name
- Index targetIndex = INDEX_THIRD_PERSON;
- String userInput = targetIndex.getOneBased() + NAME_DESC_AMY;
- EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withName(VALID_NAME_AMY).build();
+ Index targetIndex = INDEX_FIRST_RESIDENCE;
+ String userInput = targetIndex.getOneBased() + NAME_DESC_RESIDENCE1;
+ EditResidenceDescriptor descriptor = new EditResidenceDescriptorBuilder()
+ .withName(VALID_NAME_RESIDENCE1).build();
EditCommand expectedCommand = new EditCommand(targetIndex, descriptor);
assertParseSuccess(parser, userInput, expectedCommand);
- // phone
- userInput = targetIndex.getOneBased() + PHONE_DESC_AMY;
- descriptor = new EditPersonDescriptorBuilder().withPhone(VALID_PHONE_AMY).build();
- expectedCommand = new EditCommand(targetIndex, descriptor);
- assertParseSuccess(parser, userInput, expectedCommand);
-
- // email
- userInput = targetIndex.getOneBased() + EMAIL_DESC_AMY;
- descriptor = new EditPersonDescriptorBuilder().withEmail(VALID_EMAIL_AMY).build();
+ // address
+ userInput = targetIndex.getOneBased() + ADDRESS_DESC_RESIDENCE1;
+ descriptor = new EditResidenceDescriptorBuilder().withAddress(VALID_ADDRESS_RESIDENCE1).build();
expectedCommand = new EditCommand(targetIndex, descriptor);
assertParseSuccess(parser, userInput, expectedCommand);
- // address
- userInput = targetIndex.getOneBased() + ADDRESS_DESC_AMY;
- descriptor = new EditPersonDescriptorBuilder().withAddress(VALID_ADDRESS_AMY).build();
+ // Clean Status Tag
+ userInput = targetIndex.getOneBased() + CLEAN_STATUS_DESC;
+ descriptor = new EditResidenceDescriptorBuilder().withCleanStatusTag(VALID_CLEAN_TAG).build();
expectedCommand = new EditCommand(targetIndex, descriptor);
assertParseSuccess(parser, userInput, expectedCommand);
// tags
- userInput = targetIndex.getOneBased() + TAG_DESC_FRIEND;
- descriptor = new EditPersonDescriptorBuilder().withTags(VALID_TAG_FRIEND).build();
+ userInput = targetIndex.getOneBased() + TAG_DESC_RESERVED;
+ descriptor = new EditResidenceDescriptorBuilder().withTags(VALID_TAG_RESERVED).build();
expectedCommand = new EditCommand(targetIndex, descriptor);
assertParseSuccess(parser, userInput, expectedCommand);
}
@Test
public void parse_multipleRepeatedFields_acceptsLast() {
- Index targetIndex = INDEX_FIRST_PERSON;
- String userInput = targetIndex.getOneBased() + PHONE_DESC_AMY + ADDRESS_DESC_AMY + EMAIL_DESC_AMY
- + TAG_DESC_FRIEND + PHONE_DESC_AMY + ADDRESS_DESC_AMY + EMAIL_DESC_AMY + TAG_DESC_FRIEND
- + PHONE_DESC_BOB + ADDRESS_DESC_BOB + EMAIL_DESC_BOB + TAG_DESC_HUSBAND;
-
- EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withPhone(VALID_PHONE_BOB)
- .withEmail(VALID_EMAIL_BOB).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_FRIEND, VALID_TAG_HUSBAND)
+ Index targetIndex = INDEX_FIRST_RESIDENCE;
+ String userInput = targetIndex.getOneBased() + NAME_DESC_RESIDENCE1 + ADDRESS_DESC_RESIDENCE1
+ + CLEAN_STATUS_DESC + TAG_DESC_RESERVED + NAME_DESC_RESIDENCE1 + ADDRESS_DESC_RESIDENCE1
+ + CLEAN_STATUS_DESC + TAG_DESC_RESERVED + NAME_DESC_RESIDENCE1 + ADDRESS_DESC_RESIDENCE1
+ + CLEAN_STATUS_DESC + TAG_DESC_RESERVED + TAG_DESC_REPAIR;
+
+ EditResidenceDescriptor descriptor = new EditResidenceDescriptorBuilder().withName(VALID_NAME_RESIDENCE1)
+ .withAddress(VALID_ADDRESS_RESIDENCE1).withCleanStatusTag(VALID_CLEAN_TAG)
+ .withTags(VALID_TAG_RESERVED, VALID_TAG_REPAIR)
.build();
EditCommand expectedCommand = new EditCommand(targetIndex, descriptor);
@@ -183,27 +159,29 @@ public void parse_multipleRepeatedFields_acceptsLast() {
@Test
public void parse_invalidValueFollowedByValidValue_success() {
// no other valid values specified
- Index targetIndex = INDEX_FIRST_PERSON;
- String userInput = targetIndex.getOneBased() + INVALID_PHONE_DESC + PHONE_DESC_BOB;
- EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withPhone(VALID_PHONE_BOB).build();
+ Index targetIndex = INDEX_FIRST_RESIDENCE;
+ String userInput = targetIndex.getOneBased() + INVALID_ADDRESS_DESC + ADDRESS_DESC_RESIDENCE1;
+ EditResidenceDescriptor descriptor = new EditResidenceDescriptorBuilder()
+ .withAddress(VALID_ADDRESS_RESIDENCE1).build();
EditCommand expectedCommand = new EditCommand(targetIndex, descriptor);
assertParseSuccess(parser, userInput, expectedCommand);
// other valid values specified
- userInput = targetIndex.getOneBased() + EMAIL_DESC_BOB + INVALID_PHONE_DESC + ADDRESS_DESC_BOB
- + PHONE_DESC_BOB;
- descriptor = new EditPersonDescriptorBuilder().withPhone(VALID_PHONE_BOB).withEmail(VALID_EMAIL_BOB)
- .withAddress(VALID_ADDRESS_BOB).build();
+ userInput = targetIndex.getOneBased() + ADDRESS_DESC_RESIDENCE1 + CLEAN_STATUS_DESC + ADDRESS_DESC_RESIDENCE1
+ + TAG_DESC_RESERVED;
+ descriptor = new EditResidenceDescriptorBuilder().withAddress(VALID_ADDRESS_RESIDENCE1)
+ .withCleanStatusTag(VALID_CLEAN_TAG)
+ .withTags(VALID_TAG_RESERVED).build();
expectedCommand = new EditCommand(targetIndex, descriptor);
assertParseSuccess(parser, userInput, expectedCommand);
}
@Test
public void parse_resetTags_success() {
- Index targetIndex = INDEX_THIRD_PERSON;
+ Index targetIndex = INDEX_FIRST_RESIDENCE;
String userInput = targetIndex.getOneBased() + TAG_EMPTY;
- EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withTags().build();
+ EditResidenceDescriptor descriptor = new EditResidenceDescriptorBuilder().withTags().build();
EditCommand expectedCommand = new EditCommand(targetIndex, descriptor);
assertParseSuccess(parser, userInput, expectedCommand);
diff --git a/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java b/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java
index 70f4f0e79c4..488b7482906 100644
--- a/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java
+++ b/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java
@@ -9,7 +9,7 @@
import org.junit.jupiter.api.Test;
import seedu.address.logic.commands.FindCommand;
-import seedu.address.model.person.NameContainsKeywordsPredicate;
+import seedu.address.model.residence.NameContainsKeywordsPredicate;
public class FindCommandParserTest {
diff --git a/src/test/java/seedu/address/logic/parser/ParserUtilTest.java b/src/test/java/seedu/address/logic/parser/ParserUtilTest.java
index 4256788b1a7..a4f49216dbb 100644
--- a/src/test/java/seedu/address/logic/parser/ParserUtilTest.java
+++ b/src/test/java/seedu/address/logic/parser/ParserUtilTest.java
@@ -4,7 +4,7 @@
import static org.junit.jupiter.api.Assertions.assertTrue;
import static seedu.address.logic.parser.ParserUtil.MESSAGE_INVALID_INDEX;
import static seedu.address.testutil.Assert.assertThrows;
-import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON;
+import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_RESIDENCE;
import java.util.Arrays;
import java.util.Collections;
@@ -14,20 +14,19 @@
import org.junit.jupiter.api.Test;
import seedu.address.logic.parser.exceptions.ParseException;
-import seedu.address.model.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Phone;
+import seedu.address.model.booking.Phone;
+import seedu.address.model.residence.ResidenceAddress;
+import seedu.address.model.residence.ResidenceName;
import seedu.address.model.tag.Tag;
public class ParserUtilTest {
- private static final String INVALID_NAME = "R@chel";
+ private static final String INVALID_NAME = "R--chel";
private static final String INVALID_PHONE = "+651234";
private static final String INVALID_ADDRESS = " ";
private static final String INVALID_EMAIL = "example.com";
private static final String INVALID_TAG = "#friend";
- private static final String VALID_NAME = "Rachel Walker";
+ private static final String VALID_NAME = "Amber Heights";
private static final String VALID_PHONE = "123456";
private static final String VALID_ADDRESS = "123 Main Street #0505";
private static final String VALID_EMAIL = "rachel@example.com";
@@ -50,33 +49,33 @@ public void parseIndex_outOfRangeInput_throwsParseException() {
@Test
public void parseIndex_validInput_success() throws Exception {
// No whitespaces
- assertEquals(INDEX_FIRST_PERSON, ParserUtil.parseIndex("1"));
+ assertEquals(INDEX_FIRST_RESIDENCE, ParserUtil.parseIndex("1"));
// Leading and trailing whitespaces
- assertEquals(INDEX_FIRST_PERSON, ParserUtil.parseIndex(" 1 "));
+ assertEquals(INDEX_FIRST_RESIDENCE, ParserUtil.parseIndex(" 1 "));
}
@Test
public void parseName_null_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> ParserUtil.parseName((String) null));
+ assertThrows(NullPointerException.class, () -> ParserUtil.parseResidenceName((String) null));
}
@Test
public void parseName_invalidValue_throwsParseException() {
- assertThrows(ParseException.class, () -> ParserUtil.parseName(INVALID_NAME));
+ assertThrows(ParseException.class, () -> ParserUtil.parseResidenceName(INVALID_NAME));
}
@Test
public void parseName_validValueWithoutWhitespace_returnsName() throws Exception {
- Name expectedName = new Name(VALID_NAME);
- assertEquals(expectedName, ParserUtil.parseName(VALID_NAME));
+ ResidenceName expectedName = new ResidenceName(VALID_NAME);
+ assertEquals(expectedName, ParserUtil.parseResidenceName(VALID_NAME));
}
@Test
public void parseName_validValueWithWhitespace_returnsTrimmedName() throws Exception {
String nameWithWhitespace = WHITESPACE + VALID_NAME + WHITESPACE;
- Name expectedName = new Name(VALID_NAME);
- assertEquals(expectedName, ParserUtil.parseName(nameWithWhitespace));
+ ResidenceName expectedName = new ResidenceName(VALID_NAME);
+ assertEquals(expectedName, ParserUtil.parseResidenceName(nameWithWhitespace));
}
@Test
@@ -114,40 +113,17 @@ public void parseAddress_invalidValue_throwsParseException() {
@Test
public void parseAddress_validValueWithoutWhitespace_returnsAddress() throws Exception {
- Address expectedAddress = new Address(VALID_ADDRESS);
+ ResidenceAddress expectedAddress = new ResidenceAddress(VALID_ADDRESS);
assertEquals(expectedAddress, ParserUtil.parseAddress(VALID_ADDRESS));
}
@Test
public void parseAddress_validValueWithWhitespace_returnsTrimmedAddress() throws Exception {
String addressWithWhitespace = WHITESPACE + VALID_ADDRESS + WHITESPACE;
- Address expectedAddress = new Address(VALID_ADDRESS);
+ ResidenceAddress expectedAddress = new ResidenceAddress(VALID_ADDRESS);
assertEquals(expectedAddress, ParserUtil.parseAddress(addressWithWhitespace));
}
- @Test
- public void parseEmail_null_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> ParserUtil.parseEmail((String) null));
- }
-
- @Test
- public void parseEmail_invalidValue_throwsParseException() {
- assertThrows(ParseException.class, () -> ParserUtil.parseEmail(INVALID_EMAIL));
- }
-
- @Test
- public void parseEmail_validValueWithoutWhitespace_returnsEmail() throws Exception {
- Email expectedEmail = new Email(VALID_EMAIL);
- assertEquals(expectedEmail, ParserUtil.parseEmail(VALID_EMAIL));
- }
-
- @Test
- public void parseEmail_validValueWithWhitespace_returnsTrimmedEmail() throws Exception {
- String emailWithWhitespace = WHITESPACE + VALID_EMAIL + WHITESPACE;
- Email expectedEmail = new Email(VALID_EMAIL);
- assertEquals(expectedEmail, ParserUtil.parseEmail(emailWithWhitespace));
- }
-
@Test
public void parseTag_null_throwsNullPointerException() {
assertThrows(NullPointerException.class, () -> ParserUtil.parseTag(null));
diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/ResidenceTrackerParserTest.java
similarity index 72%
rename from src/test/java/seedu/address/logic/parser/AddressBookParserTest.java
rename to src/test/java/seedu/address/logic/parser/ResidenceTrackerParserTest.java
index d9659205b57..d1384584b79 100644
--- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java
+++ b/src/test/java/seedu/address/logic/parser/ResidenceTrackerParserTest.java
@@ -5,7 +5,7 @@
import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.address.commons.core.Messages.MESSAGE_UNKNOWN_COMMAND;
import static seedu.address.testutil.Assert.assertThrows;
-import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON;
+import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_RESIDENCE;
import java.util.Arrays;
import java.util.List;
@@ -17,27 +17,27 @@
import seedu.address.logic.commands.ClearCommand;
import seedu.address.logic.commands.DeleteCommand;
import seedu.address.logic.commands.EditCommand;
-import seedu.address.logic.commands.EditCommand.EditPersonDescriptor;
+import seedu.address.logic.commands.EditCommand.EditResidenceDescriptor;
import seedu.address.logic.commands.ExitCommand;
import seedu.address.logic.commands.FindCommand;
import seedu.address.logic.commands.HelpCommand;
import seedu.address.logic.commands.ListCommand;
import seedu.address.logic.parser.exceptions.ParseException;
-import seedu.address.model.person.NameContainsKeywordsPredicate;
-import seedu.address.model.person.Person;
-import seedu.address.testutil.EditPersonDescriptorBuilder;
-import seedu.address.testutil.PersonBuilder;
-import seedu.address.testutil.PersonUtil;
+import seedu.address.model.residence.NameContainsKeywordsPredicate;
+import seedu.address.model.residence.Residence;
+import seedu.address.testutil.EditResidenceDescriptorBuilder;
+import seedu.address.testutil.ResidenceBuilder;
+import seedu.address.testutil.ResidenceUtil;
-public class AddressBookParserTest {
+public class ResidenceTrackerParserTest {
- private final AddressBookParser parser = new AddressBookParser();
+ private final ResidenceTrackerParser parser = new ResidenceTrackerParser();
@Test
public void parseCommand_add() throws Exception {
- Person person = new PersonBuilder().build();
- AddCommand command = (AddCommand) parser.parseCommand(PersonUtil.getAddCommand(person));
- assertEquals(new AddCommand(person), command);
+ Residence residence = new ResidenceBuilder().build();
+ AddCommand command = (AddCommand) parser.parseCommand(ResidenceUtil.getAddCommand(residence));
+ assertEquals(new AddCommand(residence), command);
}
@Test
@@ -49,17 +49,18 @@ public void parseCommand_clear() throws Exception {
@Test
public void parseCommand_delete() throws Exception {
DeleteCommand command = (DeleteCommand) parser.parseCommand(
- DeleteCommand.COMMAND_WORD + " " + INDEX_FIRST_PERSON.getOneBased());
- assertEquals(new DeleteCommand(INDEX_FIRST_PERSON), command);
+ DeleteCommand.COMMAND_WORD + " " + INDEX_FIRST_RESIDENCE.getOneBased());
+ assertEquals(new DeleteCommand(INDEX_FIRST_RESIDENCE), command);
}
@Test
public void parseCommand_edit() throws Exception {
- Person person = new PersonBuilder().build();
- EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder(person).build();
+ Residence residence = new ResidenceBuilder().build();
+ EditResidenceDescriptor descriptor = new EditResidenceDescriptorBuilder(residence).build();
EditCommand command = (EditCommand) parser.parseCommand(EditCommand.COMMAND_WORD + " "
- + INDEX_FIRST_PERSON.getOneBased() + " " + PersonUtil.getEditPersonDescriptorDetails(descriptor));
- assertEquals(new EditCommand(INDEX_FIRST_PERSON, descriptor), command);
+ + INDEX_FIRST_RESIDENCE.getOneBased() + " "
+ + ResidenceUtil.getEditResidenceDescriptorDetails(descriptor));
+ assertEquals(new EditCommand(INDEX_FIRST_RESIDENCE, descriptor), command);
}
@Test
diff --git a/src/test/java/seedu/address/logic/parser/StatusCommandParserTest.java b/src/test/java/seedu/address/logic/parser/StatusCommandParserTest.java
new file mode 100644
index 00000000000..14e51736fa9
--- /dev/null
+++ b/src/test/java/seedu/address/logic/parser/StatusCommandParserTest.java
@@ -0,0 +1,68 @@
+package seedu.address.logic.parser;
+
+import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
+import static seedu.address.logic.commands.CommandTestUtil.INVALID_CLEAN_TAG_DESC;
+import static seedu.address.logic.commands.StatusCommand.MESSAGE_NO_RESIDENCE;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG;
+import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure;
+import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess;
+import static seedu.address.logic.parser.ParserUtil.MESSAGE_INVALID_INDEX;
+
+import java.util.ArrayList;
+
+import org.junit.jupiter.api.Test;
+
+import seedu.address.commons.core.index.Index;
+import seedu.address.logic.commands.StatusCommand;
+import seedu.address.logic.parser.exceptions.ParseException;
+
+public class StatusCommandParserTest {
+ private static final String TAG_EMPTY = " " + PREFIX_TAG;
+
+ private static final String MESSAGE_INVALID_FORMAT =
+ String.format(MESSAGE_INVALID_COMMAND_FORMAT, StatusCommand.MESSAGE_USAGE);
+
+ private StatusCommandParser parser = new StatusCommandParser();
+
+ @Test
+ public void parse_status_success() throws ParseException {
+ String statusClean = "clean";
+ String statusUnclean = "unclean";
+ ArrayList indexArray = new ArrayList<>();
+ indexArray.add(ParserUtil.parseIndex("1"));
+ indexArray.add(ParserUtil.parseIndex("2"));
+ StatusCommand expectedCommand = new StatusCommand(indexArray , statusClean);
+ assertParseSuccess(parser, statusClean + " 1 2", expectedCommand);
+ expectedCommand = new StatusCommand(indexArray , statusUnclean);
+ assertParseSuccess(parser, statusUnclean + " 1 2", expectedCommand);
+ }
+
+ @Test
+ public void parse_missingParts_failure() {
+ // no status and index array
+ assertParseFailure(parser, "", MESSAGE_NO_RESIDENCE);
+
+ // no index array
+ assertParseFailure(parser, "clean ", MESSAGE_INVALID_FORMAT);
+ assertParseFailure(parser, "unclean ", MESSAGE_INVALID_FORMAT);
+
+ // no status while only input one index
+ assertParseFailure(parser, "1", MESSAGE_INVALID_FORMAT);
+ }
+
+ @Test
+ public void parse_invalidCleanStatus_failure() {
+ // input invalid clean status and index array
+ assertParseFailure(parser, INVALID_CLEAN_TAG_DESC + " 1 2 ", StatusCommand.MESSAGE_ERROR_STATUS);
+
+ //input two or more index
+ assertParseFailure(parser, "1 2", StatusCommand.MESSAGE_ERROR_STATUS);
+ }
+
+ @Test
+ public void parse_invalidIndex_failure() {
+ assertParseFailure(parser, "clean" + " w 2", MESSAGE_INVALID_INDEX);
+ assertParseFailure(parser, "clean" + " 1 2 SS", MESSAGE_INVALID_INDEX);
+ }
+
+}
diff --git a/src/test/java/seedu/address/model/AddressBookTest.java b/src/test/java/seedu/address/model/AddressBookTest.java
deleted file mode 100644
index 87782528ecd..00000000000
--- a/src/test/java/seedu/address/model/AddressBookTest.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package seedu.address.model;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND;
-import static seedu.address.testutil.Assert.assertThrows;
-import static seedu.address.testutil.TypicalPersons.ALICE;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-import org.junit.jupiter.api.Test;
-
-import javafx.collections.FXCollections;
-import javafx.collections.ObservableList;
-import seedu.address.model.person.Person;
-import seedu.address.model.person.exceptions.DuplicatePersonException;
-import seedu.address.testutil.PersonBuilder;
-
-public class AddressBookTest {
-
- private final AddressBook addressBook = new AddressBook();
-
- @Test
- public void constructor() {
- assertEquals(Collections.emptyList(), addressBook.getPersonList());
- }
-
- @Test
- public void resetData_null_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> addressBook.resetData(null));
- }
-
- @Test
- public void resetData_withValidReadOnlyAddressBook_replacesData() {
- AddressBook newData = getTypicalAddressBook();
- addressBook.resetData(newData);
- assertEquals(newData, addressBook);
- }
-
- @Test
- public void resetData_withDuplicatePersons_throwsDuplicatePersonException() {
- // Two persons with the same identity fields
- Person editedAlice = new PersonBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND)
- .build();
- List newPersons = Arrays.asList(ALICE, editedAlice);
- AddressBookStub newData = new AddressBookStub(newPersons);
-
- assertThrows(DuplicatePersonException.class, () -> addressBook.resetData(newData));
- }
-
- @Test
- public void hasPerson_nullPerson_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> addressBook.hasPerson(null));
- }
-
- @Test
- public void hasPerson_personNotInAddressBook_returnsFalse() {
- assertFalse(addressBook.hasPerson(ALICE));
- }
-
- @Test
- public void hasPerson_personInAddressBook_returnsTrue() {
- addressBook.addPerson(ALICE);
- assertTrue(addressBook.hasPerson(ALICE));
- }
-
- @Test
- public void hasPerson_personWithSameIdentityFieldsInAddressBook_returnsTrue() {
- addressBook.addPerson(ALICE);
- Person editedAlice = new PersonBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND)
- .build();
- assertTrue(addressBook.hasPerson(editedAlice));
- }
-
- @Test
- public void getPersonList_modifyList_throwsUnsupportedOperationException() {
- assertThrows(UnsupportedOperationException.class, () -> addressBook.getPersonList().remove(0));
- }
-
- /**
- * A stub ReadOnlyAddressBook whose persons list can violate interface constraints.
- */
- private static class AddressBookStub implements ReadOnlyAddressBook {
- private final ObservableList persons = FXCollections.observableArrayList();
-
- AddressBookStub(Collection persons) {
- this.persons.setAll(persons);
- }
-
- @Override
- public ObservableList getPersonList() {
- return persons;
- }
- }
-
-}
diff --git a/src/test/java/seedu/address/model/ModelManagerTest.java b/src/test/java/seedu/address/model/ModelManagerTest.java
index 2cf1418d116..87421a7303b 100644
--- a/src/test/java/seedu/address/model/ModelManagerTest.java
+++ b/src/test/java/seedu/address/model/ModelManagerTest.java
@@ -3,10 +3,10 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PERSONS;
+import static seedu.address.model.Model.PREDICATE_SHOW_ALL_RESIDENCES;
import static seedu.address.testutil.Assert.assertThrows;
-import static seedu.address.testutil.TypicalPersons.ALICE;
-import static seedu.address.testutil.TypicalPersons.BENSON;
+import static seedu.address.testutil.TypicalResidences.RESIDENCE_A;
+import static seedu.address.testutil.TypicalResidences.RESIDENCE_B;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -15,8 +15,8 @@
import org.junit.jupiter.api.Test;
import seedu.address.commons.core.GuiSettings;
-import seedu.address.model.person.NameContainsKeywordsPredicate;
-import seedu.address.testutil.AddressBookBuilder;
+import seedu.address.model.residence.NameContainsKeywordsPredicate;
+import seedu.address.testutil.ResidenceTrackerBuilder;
public class ModelManagerTest {
@@ -26,7 +26,7 @@ public class ModelManagerTest {
public void constructor() {
assertEquals(new UserPrefs(), modelManager.getUserPrefs());
assertEquals(new GuiSettings(), modelManager.getGuiSettings());
- assertEquals(new AddressBook(), new AddressBook(modelManager.getAddressBook()));
+ assertEquals(new ResidenceTracker(), new ResidenceTracker(modelManager.getResidenceTracker()));
}
@Test
@@ -37,14 +37,14 @@ public void setUserPrefs_nullUserPrefs_throwsNullPointerException() {
@Test
public void setUserPrefs_validUserPrefs_copiesUserPrefs() {
UserPrefs userPrefs = new UserPrefs();
- userPrefs.setAddressBookFilePath(Paths.get("address/book/file/path"));
+ userPrefs.setResidenceTrackerFilePath(Paths.get("residence/tracker/file/path"));
userPrefs.setGuiSettings(new GuiSettings(1, 2, 3, 4));
modelManager.setUserPrefs(userPrefs);
assertEquals(userPrefs, modelManager.getUserPrefs());
// Modifying userPrefs should not modify modelManager's userPrefs
UserPrefs oldUserPrefs = new UserPrefs(userPrefs);
- userPrefs.setAddressBookFilePath(Paths.get("new/address/book/file/path"));
+ userPrefs.setResidenceTrackerFilePath(Paths.get("new/residence/tracker/file/path"));
assertEquals(oldUserPrefs, modelManager.getUserPrefs());
}
@@ -61,47 +61,48 @@ public void setGuiSettings_validGuiSettings_setsGuiSettings() {
}
@Test
- public void setAddressBookFilePath_nullPath_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> modelManager.setAddressBookFilePath(null));
+ public void setResidenceTrackerFilePath_nullPath_throwsNullPointerException() {
+ assertThrows(NullPointerException.class, () -> modelManager.setResidenceTrackerFilePath(null));
}
@Test
- public void setAddressBookFilePath_validPath_setsAddressBookFilePath() {
+ public void setResidenceTrackerFilePath_validPath_setsResidenceTrackerFilePath() {
Path path = Paths.get("address/book/file/path");
- modelManager.setAddressBookFilePath(path);
- assertEquals(path, modelManager.getAddressBookFilePath());
+ modelManager.setResidenceTrackerFilePath(path);
+ assertEquals(path, modelManager.getResidenceTrackerFilePath());
}
@Test
- public void hasPerson_nullPerson_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> modelManager.hasPerson(null));
+ public void hasResidence_nullResidence_throwsNullPointerException() {
+ assertThrows(NullPointerException.class, () -> modelManager.hasResidence(null));
}
@Test
- public void hasPerson_personNotInAddressBook_returnsFalse() {
- assertFalse(modelManager.hasPerson(ALICE));
+ public void hasResidence_personNotInResidenceTracker_returnsFalse() {
+ assertFalse(modelManager.hasResidence(RESIDENCE_A));
}
@Test
- public void hasPerson_personInAddressBook_returnsTrue() {
- modelManager.addPerson(ALICE);
- assertTrue(modelManager.hasPerson(ALICE));
+ public void hasResidence_residenceInResidenceTracker_returnsTrue() {
+ modelManager.addResidence(RESIDENCE_A);
+ assertTrue(modelManager.hasResidence(RESIDENCE_A));
}
@Test
public void getFilteredPersonList_modifyList_throwsUnsupportedOperationException() {
- assertThrows(UnsupportedOperationException.class, () -> modelManager.getFilteredPersonList().remove(0));
+ assertThrows(UnsupportedOperationException.class, () -> modelManager.getFilteredResidenceList().remove(0));
}
@Test
public void equals() {
- AddressBook addressBook = new AddressBookBuilder().withPerson(ALICE).withPerson(BENSON).build();
- AddressBook differentAddressBook = new AddressBook();
+ ResidenceTracker residenceTracker = new ResidenceTrackerBuilder().withResidence(RESIDENCE_A)
+ .withResidence(RESIDENCE_B).build();
+ ResidenceTracker differentAddressBook = new ResidenceTracker();
UserPrefs userPrefs = new UserPrefs();
// same values -> returns true
- modelManager = new ModelManager(addressBook, userPrefs);
- ModelManager modelManagerCopy = new ModelManager(addressBook, userPrefs);
+ modelManager = new ModelManager(residenceTracker, userPrefs);
+ ModelManager modelManagerCopy = new ModelManager(residenceTracker, userPrefs);
assertTrue(modelManager.equals(modelManagerCopy));
// same object -> returns true
@@ -117,16 +118,16 @@ public void equals() {
assertFalse(modelManager.equals(new ModelManager(differentAddressBook, userPrefs)));
// different filteredList -> returns false
- String[] keywords = ALICE.getName().fullName.split("\\s+");
- modelManager.updateFilteredPersonList(new NameContainsKeywordsPredicate(Arrays.asList(keywords)));
- assertFalse(modelManager.equals(new ModelManager(addressBook, userPrefs)));
+ String[] keywords = RESIDENCE_A.getResidenceName().toString().split("\\s+");
+ modelManager.updateFilteredResidenceList(new NameContainsKeywordsPredicate(Arrays.asList(keywords)));
+ assertFalse(modelManager.equals(new ModelManager(residenceTracker, userPrefs)));
// resets modelManager to initial state for upcoming tests
- modelManager.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
+ modelManager.updateFilteredResidenceList(PREDICATE_SHOW_ALL_RESIDENCES);
// different userPrefs -> returns false
UserPrefs differentUserPrefs = new UserPrefs();
- differentUserPrefs.setAddressBookFilePath(Paths.get("differentFilePath"));
- assertFalse(modelManager.equals(new ModelManager(addressBook, differentUserPrefs)));
+ differentUserPrefs.setResidenceTrackerFilePath(Paths.get("differentFilePath"));
+ assertFalse(modelManager.equals(new ModelManager(residenceTracker, differentUserPrefs)));
}
}
diff --git a/src/test/java/seedu/address/model/ResidenceTrackerTest.java b/src/test/java/seedu/address/model/ResidenceTrackerTest.java
new file mode 100644
index 00000000000..cf82155ffdd
--- /dev/null
+++ b/src/test/java/seedu/address/model/ResidenceTrackerTest.java
@@ -0,0 +1,102 @@
+package seedu.address.model;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_RESIDENCE2;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_REPAIR;
+import static seedu.address.testutil.Assert.assertThrows;
+import static seedu.address.testutil.TypicalResidences.RESIDENCE1;
+import static seedu.address.testutil.TypicalResidences.getTypicalResidenceTracker;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.jupiter.api.Test;
+
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import seedu.address.model.residence.Residence;
+import seedu.address.model.residence.exceptions.DuplicateResidenceException;
+import seedu.address.testutil.ResidenceBuilder;
+
+public class ResidenceTrackerTest {
+
+ private final ResidenceTracker residenceTracker = new ResidenceTracker();
+
+ @Test
+ public void constructor() {
+ assertEquals(Collections.emptyList(), residenceTracker.getResidenceList());
+ }
+
+ @Test
+ public void resetData_null_throwsNullPointerException() {
+ assertThrows(NullPointerException.class, () -> residenceTracker.resetData(null));
+ }
+
+ @Test
+ public void resetData_withValidReadOnlyAddressBook_replacesData() {
+ ResidenceTracker newData = getTypicalResidenceTracker();
+ residenceTracker.resetData(newData);
+ assertEquals(newData, residenceTracker);
+ }
+
+ @Test
+ public void resetData_withDuplicateResidences_throwsDuplicateResidenceException() {
+ // Two persons with the same identity fields
+ Residence editedR1 = new ResidenceBuilder(RESIDENCE1).withAddress(VALID_ADDRESS_RESIDENCE2)
+ .withTags(VALID_TAG_REPAIR).build();
+ List newResidences = Arrays.asList(RESIDENCE1, editedR1);
+ ResidenceTrackerStub newData = new ResidenceTrackerStub(newResidences);
+
+ assertThrows(DuplicateResidenceException.class, () -> residenceTracker.resetData(newData));
+ }
+
+ @Test
+ public void hasResidence_nullResidence_throwsNullPointerException() {
+ assertThrows(NullPointerException.class, () -> residenceTracker.hasResidence(null));
+ }
+
+ @Test
+ public void hasResidence_residenceNotInResidenceTracker_returnsFalse() {
+ assertFalse(residenceTracker.hasResidence(RESIDENCE1));
+ }
+
+ @Test
+ public void hasResidence_residenceInResidenceTracker_returnsTrue() {
+ residenceTracker.addResidence(RESIDENCE1);
+ assertTrue(residenceTracker.hasResidence(RESIDENCE1));
+ }
+
+ @Test
+ public void hasResidence_residenceWithSameIdentityFieldsInResidenceTracker_returnsTrue() {
+ residenceTracker.addResidence(RESIDENCE1);
+ Residence editedR1 = new ResidenceBuilder(RESIDENCE1).withAddress(VALID_ADDRESS_RESIDENCE2)
+ .withTags(VALID_TAG_REPAIR).build();
+ assertTrue(residenceTracker.hasResidence(editedR1));
+ }
+
+ @Test
+ public void getResidenceList_modifyList_throwsUnsupportedOperationException() {
+ assertThrows(UnsupportedOperationException.class, () -> residenceTracker.getResidenceList().remove(0));
+ }
+
+ /**
+ * A stub ReadOnlyResidenceTracker whose list of residence can violate interface constraints.
+ */
+ private static class ResidenceTrackerStub implements ReadOnlyResidenceTracker {
+ private final ObservableList residences = FXCollections.observableArrayList();
+
+ ResidenceTrackerStub(Collection residences) {
+ this.residences.setAll(residences);
+ }
+
+ @Override
+ public ObservableList getResidenceList() {
+ return residences;
+ }
+ }
+
+}
diff --git a/src/test/java/seedu/address/model/UserPrefsTest.java b/src/test/java/seedu/address/model/UserPrefsTest.java
index b1307a70d52..5c0136f99f2 100644
--- a/src/test/java/seedu/address/model/UserPrefsTest.java
+++ b/src/test/java/seedu/address/model/UserPrefsTest.java
@@ -15,7 +15,7 @@ public void setGuiSettings_nullGuiSettings_throwsNullPointerException() {
@Test
public void setAddressBookFilePath_nullPath_throwsNullPointerException() {
UserPrefs userPrefs = new UserPrefs();
- assertThrows(NullPointerException.class, () -> userPrefs.setAddressBookFilePath(null));
+ assertThrows(NullPointerException.class, () -> userPrefs.setResidenceTrackerFilePath(null));
}
}
diff --git a/src/test/java/seedu/address/model/booking/BookingTest.java b/src/test/java/seedu/address/model/booking/BookingTest.java
new file mode 100644
index 00000000000..706b225e43f
--- /dev/null
+++ b/src/test/java/seedu/address/model/booking/BookingTest.java
@@ -0,0 +1,57 @@
+package seedu.address.model.booking;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static seedu.address.testutil.Assert.assertThrows;
+
+import java.time.LocalDate;
+
+import org.junit.jupiter.api.Test;
+
+public class BookingTest {
+
+ private TenantName validName = new TenantName("John");
+ private Phone validPhone = new Phone("91234567");
+ private LocalDate validStart = LocalDate.of(2021, 3, 22);
+ private LocalDate validEnd = LocalDate.of(2021, 3, 25);
+
+ @Test
+ public void constructor_null_throwsNullPointerException() {
+ assertThrows(NullPointerException.class, () -> new Booking(null, null, null, null));
+ assertThrows(NullPointerException.class, () -> new Booking(validName, null, null, null));
+ assertThrows(NullPointerException.class, () -> new Booking(validName, validPhone, null, null));
+ assertThrows(NullPointerException.class, () -> new Booking(validName, validPhone, validStart, null));
+ assertThrows(NullPointerException.class, () -> new Booking(validName, validPhone, null, validEnd));
+ assertThrows(NullPointerException.class, () -> new Booking(validName, null, validStart, null));
+ assertThrows(NullPointerException.class, () -> new Booking(validName, null, validStart, validEnd));
+ assertThrows(NullPointerException.class, () -> new Booking(validName, null, null, validEnd));
+ assertThrows(NullPointerException.class, () -> new Booking(null, validPhone, null, null));
+ assertThrows(NullPointerException.class, () -> new Booking(null, validPhone, validStart, null));
+ assertThrows(NullPointerException.class, () -> new Booking(null, validPhone, validStart, validEnd));
+ assertThrows(NullPointerException.class, () -> new Booking(null, validPhone, null, validEnd));
+ assertThrows(NullPointerException.class, () -> new Booking(null, null, validStart, null));
+ assertThrows(NullPointerException.class, () -> new Booking(null, null, validStart, validEnd));
+ assertThrows(NullPointerException.class, () -> new Booking(null, null, null, validEnd));
+ }
+
+ @Test
+ public void constructor_invalidBooking_throwsIllegalArgumentException() {
+ assertThrows(IllegalArgumentException.class, () -> new Booking(new TenantName(""),
+ validPhone, validStart, validEnd));
+ assertThrows(
+ IllegalArgumentException.class, () -> new Booking(validName, new Phone("12"), validStart, validEnd));
+ }
+
+ @Test
+ public void isValidBooking() {
+
+ // null booking
+ assertThrows(NullPointerException.class, () -> Booking.isValidBookingTime(null, null));
+
+ // invalid dates - start date after end date
+ assertFalse(Booking.isValidBookingTime(validEnd, validStart));
+
+ // valid bookings
+ assertTrue(Booking.isValidBookingTime(validStart, validEnd));
+ }
+}
diff --git a/src/test/java/seedu/address/model/person/PhoneTest.java b/src/test/java/seedu/address/model/booking/PhoneTest.java
similarity index 97%
rename from src/test/java/seedu/address/model/person/PhoneTest.java
rename to src/test/java/seedu/address/model/booking/PhoneTest.java
index 8dd52766a5f..4752d522d52 100644
--- a/src/test/java/seedu/address/model/person/PhoneTest.java
+++ b/src/test/java/seedu/address/model/booking/PhoneTest.java
@@ -1,4 +1,4 @@
-package seedu.address.model.person;
+package seedu.address.model.booking;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
diff --git a/src/test/java/seedu/address/model/booking/TenantNameTest.java b/src/test/java/seedu/address/model/booking/TenantNameTest.java
new file mode 100644
index 00000000000..55b8cdba95d
--- /dev/null
+++ b/src/test/java/seedu/address/model/booking/TenantNameTest.java
@@ -0,0 +1,40 @@
+package seedu.address.model.booking;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static seedu.address.testutil.Assert.assertThrows;
+
+import org.junit.jupiter.api.Test;
+
+public class TenantNameTest {
+
+ @Test
+ public void constructor_null_throwsNullPointerException() {
+ assertThrows(NullPointerException.class, () -> new TenantName(null));
+ }
+
+ @Test
+ public void constructor_invalidName_throwsIllegalArgumentException() {
+ String invalidName = "";
+ assertThrows(IllegalArgumentException.class, () -> new TenantName(invalidName));
+ }
+
+ @Test
+ public void isValidName() {
+ // null name
+ assertThrows(NullPointerException.class, () -> TenantName.isValidName(null));
+
+ // invalid name
+ assertFalse(TenantName.isValidName("")); // empty string
+ assertFalse(TenantName.isValidName(" ")); // spaces only
+ assertFalse(TenantName.isValidName("^")); // only non-alphanumeric characters
+ assertFalse(TenantName.isValidName("peter*")); // contains non-alphanumeric characters
+
+ // valid name
+ assertTrue(TenantName.isValidName("peter jack")); // alphabets only
+ assertTrue(TenantName.isValidName("12345")); // numbers only
+ assertTrue(TenantName.isValidName("peter the 2nd")); // alphanumeric characters
+ assertTrue(TenantName.isValidName("Capital Tan")); // with capital letters
+ assertTrue(TenantName.isValidName("David Roger Jackson Ray Jr 2nd")); // long names
+ }
+}
diff --git a/src/test/java/seedu/address/model/person/AddressTest.java b/src/test/java/seedu/address/model/person/AddressTest.java
deleted file mode 100644
index dcd3be87b3a..00000000000
--- a/src/test/java/seedu/address/model/person/AddressTest.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package seedu.address.model.person;
-
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.testutil.Assert.assertThrows;
-
-import org.junit.jupiter.api.Test;
-
-public class AddressTest {
-
- @Test
- public void constructor_null_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> new Address(null));
- }
-
- @Test
- public void constructor_invalidAddress_throwsIllegalArgumentException() {
- String invalidAddress = "";
- assertThrows(IllegalArgumentException.class, () -> new Address(invalidAddress));
- }
-
- @Test
- public void isValidAddress() {
- // null address
- assertThrows(NullPointerException.class, () -> Address.isValidAddress(null));
-
- // invalid addresses
- assertFalse(Address.isValidAddress("")); // empty string
- assertFalse(Address.isValidAddress(" ")); // spaces only
-
- // valid addresses
- assertTrue(Address.isValidAddress("Blk 456, Den Road, #01-355"));
- assertTrue(Address.isValidAddress("-")); // one character
- assertTrue(Address.isValidAddress("Leng Inc; 1234 Market St; San Francisco CA 2349879; USA")); // long address
- }
-}
diff --git a/src/test/java/seedu/address/model/person/EmailTest.java b/src/test/java/seedu/address/model/person/EmailTest.java
deleted file mode 100644
index 7fa726ceb18..00000000000
--- a/src/test/java/seedu/address/model/person/EmailTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package seedu.address.model.person;
-
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.testutil.Assert.assertThrows;
-
-import org.junit.jupiter.api.Test;
-
-public class EmailTest {
-
- @Test
- public void constructor_null_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> new Email(null));
- }
-
- @Test
- public void constructor_invalidEmail_throwsIllegalArgumentException() {
- String invalidEmail = "";
- assertThrows(IllegalArgumentException.class, () -> new Email(invalidEmail));
- }
-
- @Test
- public void isValidEmail() {
- // null email
- assertThrows(NullPointerException.class, () -> Email.isValidEmail(null));
-
- // blank email
- assertFalse(Email.isValidEmail("")); // empty string
- assertFalse(Email.isValidEmail(" ")); // spaces only
-
- // missing parts
- assertFalse(Email.isValidEmail("@example.com")); // missing local part
- assertFalse(Email.isValidEmail("peterjackexample.com")); // missing '@' symbol
- assertFalse(Email.isValidEmail("peterjack@")); // missing domain name
-
- // invalid parts
- assertFalse(Email.isValidEmail("peterjack@-")); // invalid domain name
- assertFalse(Email.isValidEmail("peterjack@exam_ple.com")); // underscore in domain name
- assertFalse(Email.isValidEmail("peter jack@example.com")); // spaces in local part
- assertFalse(Email.isValidEmail("peterjack@exam ple.com")); // spaces in domain name
- assertFalse(Email.isValidEmail(" peterjack@example.com")); // leading space
- assertFalse(Email.isValidEmail("peterjack@example.com ")); // trailing space
- assertFalse(Email.isValidEmail("peterjack@@example.com")); // double '@' symbol
- assertFalse(Email.isValidEmail("peter@jack@example.com")); // '@' symbol in local part
- assertFalse(Email.isValidEmail("peterjack@example@com")); // '@' symbol in domain name
- assertFalse(Email.isValidEmail("peterjack@.example.com")); // domain name starts with a period
- assertFalse(Email.isValidEmail("peterjack@example.com.")); // domain name ends with a period
- assertFalse(Email.isValidEmail("peterjack@-example.com")); // domain name starts with a hyphen
- assertFalse(Email.isValidEmail("peterjack@example.com-")); // domain name ends with a hyphen
-
- // valid email
- assertTrue(Email.isValidEmail("PeterJack_1190@example.com"));
- assertTrue(Email.isValidEmail("a@bc")); // minimal
- assertTrue(Email.isValidEmail("test@localhost")); // alphabets only
- assertTrue(Email.isValidEmail("!#$%&'*+/=?`{|}~^.-@example.org")); // special characters local part
- assertTrue(Email.isValidEmail("123@145")); // numeric local part and domain name
- assertTrue(Email.isValidEmail("a1+be!@example1.com")); // mixture of alphanumeric and special characters
- assertTrue(Email.isValidEmail("peter_jack@very-very-very-long-example.com")); // long domain name
- assertTrue(Email.isValidEmail("if.you.dream.it_you.can.do.it@example.com")); // long local part
- }
-}
diff --git a/src/test/java/seedu/address/model/person/NameTest.java b/src/test/java/seedu/address/model/person/NameTest.java
deleted file mode 100644
index c9801392874..00000000000
--- a/src/test/java/seedu/address/model/person/NameTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package seedu.address.model.person;
-
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.testutil.Assert.assertThrows;
-
-import org.junit.jupiter.api.Test;
-
-public class NameTest {
-
- @Test
- public void constructor_null_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> new Name(null));
- }
-
- @Test
- public void constructor_invalidName_throwsIllegalArgumentException() {
- String invalidName = "";
- assertThrows(IllegalArgumentException.class, () -> new Name(invalidName));
- }
-
- @Test
- public void isValidName() {
- // null name
- assertThrows(NullPointerException.class, () -> Name.isValidName(null));
-
- // invalid name
- assertFalse(Name.isValidName("")); // empty string
- assertFalse(Name.isValidName(" ")); // spaces only
- assertFalse(Name.isValidName("^")); // only non-alphanumeric characters
- assertFalse(Name.isValidName("peter*")); // contains non-alphanumeric characters
-
- // valid name
- assertTrue(Name.isValidName("peter jack")); // alphabets only
- assertTrue(Name.isValidName("12345")); // numbers only
- assertTrue(Name.isValidName("peter the 2nd")); // alphanumeric characters
- assertTrue(Name.isValidName("Capital Tan")); // with capital letters
- assertTrue(Name.isValidName("David Roger Jackson Ray Jr 2nd")); // long names
- }
-}
diff --git a/src/test/java/seedu/address/model/person/PersonTest.java b/src/test/java/seedu/address/model/person/PersonTest.java
deleted file mode 100644
index b29c097cfd4..00000000000
--- a/src/test/java/seedu/address/model/person/PersonTest.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package seedu.address.model.person;
-
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND;
-import static seedu.address.testutil.Assert.assertThrows;
-import static seedu.address.testutil.TypicalPersons.ALICE;
-import static seedu.address.testutil.TypicalPersons.BOB;
-
-import org.junit.jupiter.api.Test;
-
-import seedu.address.testutil.PersonBuilder;
-
-public class PersonTest {
-
- @Test
- public void asObservableList_modifyList_throwsUnsupportedOperationException() {
- Person person = new PersonBuilder().build();
- assertThrows(UnsupportedOperationException.class, () -> person.getTags().remove(0));
- }
-
- @Test
- public void isSamePerson() {
- // same object -> returns true
- assertTrue(ALICE.isSamePerson(ALICE));
-
- // null -> returns false
- assertFalse(ALICE.isSamePerson(null));
-
- // same name, all other attributes different -> returns true
- Person editedAlice = new PersonBuilder(ALICE).withPhone(VALID_PHONE_BOB).withEmail(VALID_EMAIL_BOB)
- .withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND).build();
- assertTrue(ALICE.isSamePerson(editedAlice));
-
- // different name, all other attributes same -> returns false
- editedAlice = new PersonBuilder(ALICE).withName(VALID_NAME_BOB).build();
- assertFalse(ALICE.isSamePerson(editedAlice));
-
- // name differs in case, all other attributes same -> returns false
- Person editedBob = new PersonBuilder(BOB).withName(VALID_NAME_BOB.toLowerCase()).build();
- assertFalse(BOB.isSamePerson(editedBob));
-
- // name has trailing spaces, all other attributes same -> returns false
- String nameWithTrailingSpaces = VALID_NAME_BOB + " ";
- editedBob = new PersonBuilder(BOB).withName(nameWithTrailingSpaces).build();
- assertFalse(BOB.isSamePerson(editedBob));
- }
-
- @Test
- public void equals() {
- // same values -> returns true
- Person aliceCopy = new PersonBuilder(ALICE).build();
- assertTrue(ALICE.equals(aliceCopy));
-
- // same object -> returns true
- assertTrue(ALICE.equals(ALICE));
-
- // null -> returns false
- assertFalse(ALICE.equals(null));
-
- // different type -> returns false
- assertFalse(ALICE.equals(5));
-
- // different person -> returns false
- assertFalse(ALICE.equals(BOB));
-
- // different name -> returns false
- Person editedAlice = new PersonBuilder(ALICE).withName(VALID_NAME_BOB).build();
- assertFalse(ALICE.equals(editedAlice));
-
- // different phone -> returns false
- editedAlice = new PersonBuilder(ALICE).withPhone(VALID_PHONE_BOB).build();
- assertFalse(ALICE.equals(editedAlice));
-
- // different email -> returns false
- editedAlice = new PersonBuilder(ALICE).withEmail(VALID_EMAIL_BOB).build();
- assertFalse(ALICE.equals(editedAlice));
-
- // different address -> returns false
- editedAlice = new PersonBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).build();
- assertFalse(ALICE.equals(editedAlice));
-
- // different tags -> returns false
- editedAlice = new PersonBuilder(ALICE).withTags(VALID_TAG_HUSBAND).build();
- assertFalse(ALICE.equals(editedAlice));
- }
-}
diff --git a/src/test/java/seedu/address/model/person/UniquePersonListTest.java b/src/test/java/seedu/address/model/person/UniquePersonListTest.java
deleted file mode 100644
index 1cc5fe9e0fe..00000000000
--- a/src/test/java/seedu/address/model/person/UniquePersonListTest.java
+++ /dev/null
@@ -1,170 +0,0 @@
-package seedu.address.model.person;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND;
-import static seedu.address.testutil.Assert.assertThrows;
-import static seedu.address.testutil.TypicalPersons.ALICE;
-import static seedu.address.testutil.TypicalPersons.BOB;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import org.junit.jupiter.api.Test;
-
-import seedu.address.model.person.exceptions.DuplicatePersonException;
-import seedu.address.model.person.exceptions.PersonNotFoundException;
-import seedu.address.testutil.PersonBuilder;
-
-public class UniquePersonListTest {
-
- private final UniquePersonList uniquePersonList = new UniquePersonList();
-
- @Test
- public void contains_nullPerson_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> uniquePersonList.contains(null));
- }
-
- @Test
- public void contains_personNotInList_returnsFalse() {
- assertFalse(uniquePersonList.contains(ALICE));
- }
-
- @Test
- public void contains_personInList_returnsTrue() {
- uniquePersonList.add(ALICE);
- assertTrue(uniquePersonList.contains(ALICE));
- }
-
- @Test
- public void contains_personWithSameIdentityFieldsInList_returnsTrue() {
- uniquePersonList.add(ALICE);
- Person editedAlice = new PersonBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND)
- .build();
- assertTrue(uniquePersonList.contains(editedAlice));
- }
-
- @Test
- public void add_nullPerson_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> uniquePersonList.add(null));
- }
-
- @Test
- public void add_duplicatePerson_throwsDuplicatePersonException() {
- uniquePersonList.add(ALICE);
- assertThrows(DuplicatePersonException.class, () -> uniquePersonList.add(ALICE));
- }
-
- @Test
- public void setPerson_nullTargetPerson_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> uniquePersonList.setPerson(null, ALICE));
- }
-
- @Test
- public void setPerson_nullEditedPerson_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> uniquePersonList.setPerson(ALICE, null));
- }
-
- @Test
- public void setPerson_targetPersonNotInList_throwsPersonNotFoundException() {
- assertThrows(PersonNotFoundException.class, () -> uniquePersonList.setPerson(ALICE, ALICE));
- }
-
- @Test
- public void setPerson_editedPersonIsSamePerson_success() {
- uniquePersonList.add(ALICE);
- uniquePersonList.setPerson(ALICE, ALICE);
- UniquePersonList expectedUniquePersonList = new UniquePersonList();
- expectedUniquePersonList.add(ALICE);
- assertEquals(expectedUniquePersonList, uniquePersonList);
- }
-
- @Test
- public void setPerson_editedPersonHasSameIdentity_success() {
- uniquePersonList.add(ALICE);
- Person editedAlice = new PersonBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND)
- .build();
- uniquePersonList.setPerson(ALICE, editedAlice);
- UniquePersonList expectedUniquePersonList = new UniquePersonList();
- expectedUniquePersonList.add(editedAlice);
- assertEquals(expectedUniquePersonList, uniquePersonList);
- }
-
- @Test
- public void setPerson_editedPersonHasDifferentIdentity_success() {
- uniquePersonList.add(ALICE);
- uniquePersonList.setPerson(ALICE, BOB);
- UniquePersonList expectedUniquePersonList = new UniquePersonList();
- expectedUniquePersonList.add(BOB);
- assertEquals(expectedUniquePersonList, uniquePersonList);
- }
-
- @Test
- public void setPerson_editedPersonHasNonUniqueIdentity_throwsDuplicatePersonException() {
- uniquePersonList.add(ALICE);
- uniquePersonList.add(BOB);
- assertThrows(DuplicatePersonException.class, () -> uniquePersonList.setPerson(ALICE, BOB));
- }
-
- @Test
- public void remove_nullPerson_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> uniquePersonList.remove(null));
- }
-
- @Test
- public void remove_personDoesNotExist_throwsPersonNotFoundException() {
- assertThrows(PersonNotFoundException.class, () -> uniquePersonList.remove(ALICE));
- }
-
- @Test
- public void remove_existingPerson_removesPerson() {
- uniquePersonList.add(ALICE);
- uniquePersonList.remove(ALICE);
- UniquePersonList expectedUniquePersonList = new UniquePersonList();
- assertEquals(expectedUniquePersonList, uniquePersonList);
- }
-
- @Test
- public void setPersons_nullUniquePersonList_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> uniquePersonList.setPersons((UniquePersonList) null));
- }
-
- @Test
- public void setPersons_uniquePersonList_replacesOwnListWithProvidedUniquePersonList() {
- uniquePersonList.add(ALICE);
- UniquePersonList expectedUniquePersonList = new UniquePersonList();
- expectedUniquePersonList.add(BOB);
- uniquePersonList.setPersons(expectedUniquePersonList);
- assertEquals(expectedUniquePersonList, uniquePersonList);
- }
-
- @Test
- public void setPersons_nullList_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> uniquePersonList.setPersons((List) null));
- }
-
- @Test
- public void setPersons_list_replacesOwnListWithProvidedList() {
- uniquePersonList.add(ALICE);
- List personList = Collections.singletonList(BOB);
- uniquePersonList.setPersons(personList);
- UniquePersonList expectedUniquePersonList = new UniquePersonList();
- expectedUniquePersonList.add(BOB);
- assertEquals(expectedUniquePersonList, uniquePersonList);
- }
-
- @Test
- public void setPersons_listWithDuplicatePersons_throwsDuplicatePersonException() {
- List listWithDuplicatePersons = Arrays.asList(ALICE, ALICE);
- assertThrows(DuplicatePersonException.class, () -> uniquePersonList.setPersons(listWithDuplicatePersons));
- }
-
- @Test
- public void asUnmodifiableObservableList_modifyList_throwsUnsupportedOperationException() {
- assertThrows(UnsupportedOperationException.class, ()
- -> uniquePersonList.asUnmodifiableObservableList().remove(0));
- }
-}
diff --git a/src/test/java/seedu/address/model/residence/AddressTest.java b/src/test/java/seedu/address/model/residence/AddressTest.java
new file mode 100644
index 00000000000..cec46bf6bc4
--- /dev/null
+++ b/src/test/java/seedu/address/model/residence/AddressTest.java
@@ -0,0 +1,37 @@
+package seedu.address.model.residence;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static seedu.address.testutil.Assert.assertThrows;
+
+import org.junit.jupiter.api.Test;
+
+public class AddressTest {
+
+ @Test
+ public void constructor_null_throwsNullPointerException() {
+ assertThrows(NullPointerException.class, () -> new ResidenceAddress(null));
+ }
+
+ @Test
+ public void constructor_invalidAddress_throwsIllegalArgumentException() {
+ String invalidAddress = "";
+ assertThrows(IllegalArgumentException.class, () -> new ResidenceAddress(invalidAddress));
+ }
+
+ @Test
+ public void isValidAddress() {
+ // null address
+ assertThrows(NullPointerException.class, () -> ResidenceAddress.isValidResidenceAddress(null));
+
+ // invalid addresses
+ assertFalse(ResidenceAddress.isValidResidenceAddress("")); // empty string
+ assertFalse(ResidenceAddress.isValidResidenceAddress(" ")); // spaces only
+
+ // valid addresses
+ assertTrue(ResidenceAddress.isValidResidenceAddress("Blk 456, Den Road, #01-355"));
+ assertTrue(ResidenceAddress.isValidResidenceAddress("-")); // one character
+ assertTrue(ResidenceAddress.isValidResidenceAddress("Leng Inc; 1234 Market St; "
+ + "San Francisco CA 2349879; USA")); // long address
+ }
+}
diff --git a/src/test/java/seedu/address/model/person/NameContainsKeywordsPredicateTest.java b/src/test/java/seedu/address/model/residence/NameContainsKeywordsPredicateTest.java
similarity index 51%
rename from src/test/java/seedu/address/model/person/NameContainsKeywordsPredicateTest.java
rename to src/test/java/seedu/address/model/residence/NameContainsKeywordsPredicateTest.java
index f136664e017..80110b6cce7 100644
--- a/src/test/java/seedu/address/model/person/NameContainsKeywordsPredicateTest.java
+++ b/src/test/java/seedu/address/model/residence/NameContainsKeywordsPredicateTest.java
@@ -1,15 +1,16 @@
-package seedu.address.model.person;
+package seedu.address.model.residence;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import java.time.LocalDate;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.junit.jupiter.api.Test;
-import seedu.address.testutil.PersonBuilder;
+import seedu.address.testutil.ResidenceBuilder;
public class NameContainsKeywordsPredicateTest {
@@ -18,14 +19,17 @@ public void equals() {
List firstPredicateKeywordList = Collections.singletonList("first");
List secondPredicateKeywordList = Arrays.asList("first", "second");
- NameContainsKeywordsPredicate firstPredicate = new NameContainsKeywordsPredicate(firstPredicateKeywordList);
- NameContainsKeywordsPredicate secondPredicate = new NameContainsKeywordsPredicate(secondPredicateKeywordList);
+ NameContainsKeywordsPredicate firstPredicate =
+ new NameContainsKeywordsPredicate(firstPredicateKeywordList);
+ NameContainsKeywordsPredicate secondPredicate =
+ new NameContainsKeywordsPredicate(secondPredicateKeywordList);
// same object -> returns true
assertTrue(firstPredicate.equals(firstPredicate));
// same values -> returns true
- NameContainsKeywordsPredicate firstPredicateCopy = new NameContainsKeywordsPredicate(firstPredicateKeywordList);
+ NameContainsKeywordsPredicate firstPredicateCopy =
+ new NameContainsKeywordsPredicate(firstPredicateKeywordList);
assertTrue(firstPredicate.equals(firstPredicateCopy));
// different types -> returns false
@@ -41,35 +45,39 @@ public void equals() {
@Test
public void test_nameContainsKeywords_returnsTrue() {
// One keyword
- NameContainsKeywordsPredicate predicate = new NameContainsKeywordsPredicate(Collections.singletonList("Alice"));
- assertTrue(predicate.test(new PersonBuilder().withName("Alice Bob").build()));
+ NameContainsKeywordsPredicate predicate =
+ new NameContainsKeywordsPredicate(Collections.singletonList("Alice"));
+ assertTrue(predicate.test(new ResidenceBuilder().withName("Alice Bob").build()));
// Multiple keywords
predicate = new NameContainsKeywordsPredicate(Arrays.asList("Alice", "Bob"));
- assertTrue(predicate.test(new PersonBuilder().withName("Alice Bob").build()));
+ assertTrue(predicate.test(new ResidenceBuilder().withName("Alice Bob").build()));
// Only one matching keyword
predicate = new NameContainsKeywordsPredicate(Arrays.asList("Bob", "Carol"));
- assertTrue(predicate.test(new PersonBuilder().withName("Alice Carol").build()));
+ assertTrue(predicate.test(new ResidenceBuilder().withName("Alice Carol").build()));
// Mixed-case keywords
predicate = new NameContainsKeywordsPredicate(Arrays.asList("aLIce", "bOB"));
- assertTrue(predicate.test(new PersonBuilder().withName("Alice Bob").build()));
+ assertTrue(predicate.test(new ResidenceBuilder().withName("Alice Bob").build()));
}
@Test
public void test_nameDoesNotContainKeywords_returnsFalse() {
+ LocalDate start = LocalDate.of(2021, 3, 22);
+ LocalDate end = LocalDate.of(2021, 3, 25);
+
// Zero keywords
- NameContainsKeywordsPredicate predicate = new NameContainsKeywordsPredicate(Collections.emptyList());
- assertFalse(predicate.test(new PersonBuilder().withName("Alice").build()));
+ NameContainsKeywordsPredicate predicate =
+ new NameContainsKeywordsPredicate(Collections.emptyList());
+ assertFalse(predicate.test(new ResidenceBuilder().withName("Alice").build()));
// Non-matching keyword
predicate = new NameContainsKeywordsPredicate(Arrays.asList("Carol"));
- assertFalse(predicate.test(new PersonBuilder().withName("Alice Bob").build()));
+ assertFalse(predicate.test(new ResidenceBuilder().withName("Alice Bob").build()));
- // Keywords match phone, email and address, but does not match name
- predicate = new NameContainsKeywordsPredicate(Arrays.asList("12345", "alice@email.com", "Main", "Street"));
- assertFalse(predicate.test(new PersonBuilder().withName("Alice").withPhone("12345")
- .withEmail("alice@email.com").withAddress("Main Street").build()));
+ // Keywords match address, but does not match name
+ predicate = new NameContainsKeywordsPredicate(Arrays.asList("12345"));
+ assertFalse(predicate.test(new ResidenceBuilder().withName("Alice").withAddress("12345").build()));
}
}
diff --git a/src/test/java/seedu/address/model/residence/NameTest.java b/src/test/java/seedu/address/model/residence/NameTest.java
new file mode 100644
index 00000000000..d5fba2aedb2
--- /dev/null
+++ b/src/test/java/seedu/address/model/residence/NameTest.java
@@ -0,0 +1,40 @@
+package seedu.address.model.residence;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static seedu.address.testutil.Assert.assertThrows;
+
+import org.junit.jupiter.api.Test;
+
+public class NameTest {
+
+ @Test
+ public void constructor_null_throwsNullPointerException() {
+ assertThrows(NullPointerException.class, () -> new ResidenceName(null));
+ }
+
+ @Test
+ public void constructor_invalidName_throwsIllegalArgumentException() {
+ String invalidName = "";
+ assertThrows(IllegalArgumentException.class, () -> new ResidenceName(invalidName));
+ }
+
+ @Test
+ public void isValidName() {
+ // null name
+ assertThrows(NullPointerException.class, () -> ResidenceName.isValidResidenceName(null));
+
+ // invalid name
+ assertFalse(ResidenceName.isValidResidenceName("")); // empty string
+ assertFalse(ResidenceName.isValidResidenceName(" ")); // spaces only
+ assertFalse(ResidenceName.isValidResidenceName("^")); // only non-alphanumeric characters
+ assertFalse(ResidenceName.isValidResidenceName("peter*")); // contains non-alphanumeric characters
+
+ // valid name
+ assertTrue(ResidenceName.isValidResidenceName("Hudson Village")); // alphabets only
+ assertTrue(ResidenceName.isValidResidenceName("12345")); // numbers only
+ assertTrue(ResidenceName.isValidResidenceName("North Tower 2")); // alphanumeric characters
+ assertTrue(ResidenceName.isValidResidenceName("Capital Heights")); // with capital letters
+ assertTrue(ResidenceName.isValidResidenceName("Pinnacle Duxton Cantonment Rd HDB")); // long names
+ }
+}
diff --git a/src/test/java/seedu/address/model/residence/ResidenceTest.java b/src/test/java/seedu/address/model/residence/ResidenceTest.java
new file mode 100644
index 00000000000..7e00f9d7091
--- /dev/null
+++ b/src/test/java/seedu/address/model/residence/ResidenceTest.java
@@ -0,0 +1,91 @@
+package seedu.address.model.residence;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_RESIDENCE2;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_RESIDENCE2;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_REPAIR;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_UNCLEAN_TAG;
+import static seedu.address.testutil.Assert.assertThrows;
+import static seedu.address.testutil.TypicalResidences.RESIDENCE1;
+import static seedu.address.testutil.TypicalResidences.RESIDENCE2;
+
+import org.junit.jupiter.api.Test;
+
+import seedu.address.testutil.ResidenceBuilder;
+
+public class ResidenceTest {
+
+ @Test
+ public void asObservableList_modifyList_throwsUnsupportedOperationException() {
+ Residence residence = new ResidenceBuilder().build();
+ assertThrows(UnsupportedOperationException.class, () -> residence.getTags().remove(0));
+ }
+
+ @Test
+ public void isSameResidence() {
+ // same object -> returns true
+ assertTrue(RESIDENCE1.isSameResidence(RESIDENCE1));
+
+ // null -> returns false
+ assertFalse(RESIDENCE1.isSameResidence(null));
+
+ // same name, all other attributes different -> returns true
+ Residence editedR1 = new ResidenceBuilder(RESIDENCE1).withAddress(VALID_ADDRESS_RESIDENCE2)
+ .withCleanStatusTag("n").withTags(VALID_TAG_REPAIR).build();
+ //.withBookingDetails()
+ assertTrue(RESIDENCE1.isSameResidence(editedR1));
+
+ // different name, all other attributes same -> returns false
+ editedR1 = new ResidenceBuilder(RESIDENCE1).withName("new name").build();
+ assertFalse(RESIDENCE1.isSameResidence(editedR1));
+
+ // name differs in case, all other attributes same -> returns false
+ Residence editedR2 = new ResidenceBuilder(RESIDENCE2).withName(VALID_NAME_RESIDENCE2.toUpperCase()).build();
+ assertFalse(RESIDENCE2.isSameResidence(editedR2));
+
+ // name has trailing spaces, all other attributes same -> returns false
+ String nameWithTrailingSpaces = VALID_NAME_RESIDENCE2 + " ";
+ editedR2 = new ResidenceBuilder(RESIDENCE2).withName(nameWithTrailingSpaces).build();
+ assertFalse(RESIDENCE2.isSameResidence(editedR2));
+ }
+
+ @Test
+ public void equals() {
+ // same values -> returns true
+ Residence r1Copy = new ResidenceBuilder(RESIDENCE1).build();
+ assertTrue(RESIDENCE1.equals(r1Copy));
+
+ // same object -> returns true
+ assertTrue(RESIDENCE1.equals(r1Copy));
+
+ // null -> returns false
+ assertFalse(RESIDENCE1.equals(null));
+
+ // different type -> returns false
+ assertFalse(RESIDENCE1.equals(5));
+
+ // different residence -> returns false
+ assertFalse(RESIDENCE1.equals(RESIDENCE2));
+
+ // different name -> returns false
+ Residence editedR1 = new ResidenceBuilder(RESIDENCE1).withName(VALID_NAME_RESIDENCE2).build();
+ assertFalse(RESIDENCE1.equals(editedR1));
+
+ // different clean status tag -> returns false
+ editedR1 = new ResidenceBuilder(RESIDENCE1).withCleanStatusTag(VALID_UNCLEAN_TAG).build();
+ assertFalse(RESIDENCE1.equals(editedR1));
+
+ // different booking details -> returns false
+ //editedR1 = new ResidenceBuilder(RESIDENCE1).withBookingDetails(VALID_BOOKING_DETAILS).build();
+ //assertFalse(RESIDENCE1.equals(editedR1));
+
+ // different address -> returns false
+ editedR1 = new ResidenceBuilder(RESIDENCE1).withAddress(VALID_ADDRESS_RESIDENCE2).build();
+ assertFalse(RESIDENCE1.equals(editedR1));
+
+ // different tags -> returns false
+ editedR1 = new ResidenceBuilder(RESIDENCE1).withTags(VALID_TAG_REPAIR).build();
+ assertFalse(RESIDENCE1.equals(editedR1));
+ }
+}
diff --git a/src/test/java/seedu/address/model/residence/UniqueResidenceListTest.java b/src/test/java/seedu/address/model/residence/UniqueResidenceListTest.java
new file mode 100644
index 00000000000..c8b60d18622
--- /dev/null
+++ b/src/test/java/seedu/address/model/residence/UniqueResidenceListTest.java
@@ -0,0 +1,175 @@
+package seedu.address.model.residence;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_RESIDENCE1;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_RESERVED;
+import static seedu.address.testutil.Assert.assertThrows;
+import static seedu.address.testutil.TypicalResidences.RESIDENCE_A;
+import static seedu.address.testutil.TypicalResidences.RESIDENCE_B;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.jupiter.api.Test;
+
+import seedu.address.model.residence.exceptions.DuplicateResidenceException;
+import seedu.address.model.residence.exceptions.ResidenceNotFoundException;
+import seedu.address.testutil.ResidenceBuilder;
+
+public class UniqueResidenceListTest {
+
+ private final UniqueResidenceList uniqueResidenceList = new UniqueResidenceList();
+
+ @Test
+ public void contains_nullResidence_throwsNullPointerException() {
+ assertThrows(NullPointerException.class, () -> uniqueResidenceList.contains(null));
+ }
+
+ @Test
+ public void contains_residenceNotInList_returnsFalse() {
+ assertFalse(uniqueResidenceList.contains(RESIDENCE_A));
+ }
+
+ @Test
+ public void contains_residenceInList_returnsTrue() {
+ uniqueResidenceList.add(RESIDENCE_A);
+ assertTrue(uniqueResidenceList.contains(RESIDENCE_A));
+ }
+
+ @Test
+ public void contains_residenceWithSameIdentityFieldsInList_returnsTrue() {
+ uniqueResidenceList.add(RESIDENCE_A);
+ Residence editedAlice = new ResidenceBuilder(RESIDENCE_A).withAddress(VALID_ADDRESS_RESIDENCE1)
+ .withTags(VALID_TAG_RESERVED).build();
+ assertTrue(uniqueResidenceList.contains(editedAlice));
+ }
+
+ @Test
+ public void add_nullResidence_throwsNullPointerException() {
+ assertThrows(NullPointerException.class, () -> uniqueResidenceList.add(null));
+ }
+
+ @Test
+ public void add_duplicateResidence_throwsDuplicateResidenceException() {
+ uniqueResidenceList.add(RESIDENCE_A);
+ assertThrows(DuplicateResidenceException.class, () -> uniqueResidenceList.add(RESIDENCE_A));
+ }
+
+ @Test
+ public void setResidence_nullTargetResidence_throwsNullPointerException() {
+ assertThrows(NullPointerException.class, () -> uniqueResidenceList.setResidence(null, RESIDENCE_A));
+ }
+
+ @Test
+ public void setResidence_nullEditedResidence_throwsNullPointerException() {
+ assertThrows(NullPointerException.class, () -> uniqueResidenceList
+ .setResidence(RESIDENCE_A, null));
+ }
+
+ @Test
+ public void setResidence_targetResidenceNotInList_throwsResidenceNotFoundException() {
+ assertThrows(ResidenceNotFoundException.class, () -> uniqueResidenceList
+ .setResidence(RESIDENCE_A, RESIDENCE_A));
+ }
+
+ @Test
+ public void setResidence_editedResidenceIsSamePerson_success() {
+ uniqueResidenceList.add(RESIDENCE_A);
+ uniqueResidenceList.setResidence(RESIDENCE_A, RESIDENCE_A);
+ UniqueResidenceList expectedUniqueResidenceList = new UniqueResidenceList();
+ expectedUniqueResidenceList.add(RESIDENCE_A);
+ assertEquals(expectedUniqueResidenceList, uniqueResidenceList);
+ }
+
+ @Test
+ public void setResidence_editedResidenceHasSameIdentity_success() {
+ uniqueResidenceList.add(RESIDENCE_A);
+ Residence editedAlice = new ResidenceBuilder(RESIDENCE_A)
+ .withAddress(VALID_ADDRESS_RESIDENCE1).withTags(VALID_TAG_RESERVED)
+ .build();
+ uniqueResidenceList.setResidence(RESIDENCE_A, editedAlice);
+ UniqueResidenceList expectedUniqueResidenceList = new UniqueResidenceList();
+ expectedUniqueResidenceList.add(editedAlice);
+ assertEquals(expectedUniqueResidenceList, uniqueResidenceList);
+ }
+
+ @Test
+ public void setResidence_editedResidenceHasDifferentIdentity_success() {
+ uniqueResidenceList.add(RESIDENCE_A);
+ uniqueResidenceList.setResidence(RESIDENCE_A, RESIDENCE_B);
+ UniqueResidenceList expectedUniqueResidenceList = new UniqueResidenceList();
+ expectedUniqueResidenceList.add(RESIDENCE_B);
+ assertEquals(expectedUniqueResidenceList, uniqueResidenceList);
+ }
+
+ @Test
+ public void setResidence_editedResidenceHasNonUniqueIdentity_throwsDuplicatePersonException() {
+ uniqueResidenceList.add(RESIDENCE_A);
+ uniqueResidenceList.add(RESIDENCE_B);
+ assertThrows(DuplicateResidenceException.class, () ->
+ uniqueResidenceList.setResidence(RESIDENCE_A, RESIDENCE_B));
+ }
+
+ @Test
+ public void remove_nullResidence_throwsNullPointerException() {
+ assertThrows(NullPointerException.class, () -> uniqueResidenceList.remove(null));
+ }
+
+ @Test
+ public void remove_residenceDoesNotExist_throwsResidenceNotFoundException() {
+ assertThrows(ResidenceNotFoundException.class, () -> uniqueResidenceList.remove(RESIDENCE_A));
+ }
+
+ @Test
+ public void remove_existingResidence_removesPerson() {
+ uniqueResidenceList.add(RESIDENCE_A);
+ uniqueResidenceList.remove(RESIDENCE_A);
+ UniqueResidenceList expectedUniqueResidenceList = new UniqueResidenceList();
+ assertEquals(expectedUniqueResidenceList, uniqueResidenceList);
+ }
+
+ @Test
+ public void setResidence_nullUniqueResidenceList_throwsNullPointerException() {
+ assertThrows(NullPointerException.class, () -> uniqueResidenceList.setResidences((UniqueResidenceList) null));
+ }
+
+ @Test
+ public void setResidence_uniqueResidenceList_replacesOwnListWithProvidedUniqueResidenceList() {
+ uniqueResidenceList.add(RESIDENCE_A);
+ UniqueResidenceList expectedUniqueResidenceList = new UniqueResidenceList();
+ expectedUniqueResidenceList.add(RESIDENCE_B);
+ uniqueResidenceList.setResidences(expectedUniqueResidenceList);
+ assertEquals(expectedUniqueResidenceList, uniqueResidenceList);
+ }
+
+ @Test
+ public void setResidences_nullList_throwsNullPointerException() {
+ assertThrows(NullPointerException.class, () -> uniqueResidenceList.setResidences((List) null));
+ }
+
+ @Test
+ public void setResidences_list_replacesOwnListWithProvidedList() {
+ uniqueResidenceList.add(RESIDENCE_A);
+ List residenceList = Collections.singletonList(RESIDENCE_B);
+ uniqueResidenceList.setResidences(residenceList);
+ UniqueResidenceList expectedUniqueResidenceList = new UniqueResidenceList();
+ expectedUniqueResidenceList.add(RESIDENCE_B);
+ assertEquals(expectedUniqueResidenceList, uniqueResidenceList);
+ }
+
+ @Test
+ public void setResidences_listWithDuplicateResidences_throwsDuplicateResidenceException() {
+ List listWithDuplicateResidences = Arrays.asList(RESIDENCE_A, RESIDENCE_A);
+ assertThrows(DuplicateResidenceException.class, () -> uniqueResidenceList
+ .setResidences(listWithDuplicateResidences));
+ }
+
+ @Test
+ public void asUnmodifiableObservableList_modifyList_throwsUnsupportedOperationException() {
+ assertThrows(UnsupportedOperationException.class, () -> uniqueResidenceList
+ .asUnmodifiableObservableList().remove(0));
+ }
+}
diff --git a/src/test/java/seedu/address/model/tag/CleanStatusTagTest.java b/src/test/java/seedu/address/model/tag/CleanStatusTagTest.java
new file mode 100644
index 00000000000..f72bc884ff1
--- /dev/null
+++ b/src/test/java/seedu/address/model/tag/CleanStatusTagTest.java
@@ -0,0 +1,39 @@
+package seedu.address.model.tag;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static seedu.address.testutil.Assert.assertThrows;
+
+import org.junit.jupiter.api.Test;
+
+public class CleanStatusTagTest {
+
+ @Test
+ public void constructor_null_throwsNullPointerException() {
+ assertThrows(NullPointerException.class, () -> new CleanStatusTag(null));
+ }
+
+ @Test
+ public void constructor_invalidName_throwsIllegalArgumentException() {
+ String invalidName = "";
+ assertThrows(IllegalArgumentException.class, () -> new CleanStatusTag(invalidName));
+ }
+
+ @Test
+ public void isValidName() {
+ // null name
+ assertThrows(NullPointerException.class, () -> CleanStatusTag.isValidCleanStatusTag(null));
+
+ // invalid name
+ assertFalse(CleanStatusTag.isValidCleanStatusTag("")); // empty string
+ assertFalse(CleanStatusTag.isValidCleanStatusTag(" ")); // spaces only
+ assertFalse(CleanStatusTag.isValidCleanStatusTag("^")); // only non-alphanumeric characters
+ assertFalse(CleanStatusTag.isValidCleanStatusTag("peter*")); // contains non-alphanumeric characters
+
+ // valid name
+ assertTrue(CleanStatusTag.isValidCleanStatusTag("y")); // lowercase y
+ assertTrue(CleanStatusTag.isValidCleanStatusTag("Y")); // uppercase Y
+ assertTrue(CleanStatusTag.isValidCleanStatusTag("n")); // lowercase n
+ assertTrue(CleanStatusTag.isValidCleanStatusTag("N")); // uppercase N
+ }
+}
diff --git a/src/test/java/seedu/address/storage/JsonAdaptedPersonTest.java b/src/test/java/seedu/address/storage/JsonAdaptedPersonTest.java
index 83b11331cdb..bd40aff009d 100644
--- a/src/test/java/seedu/address/storage/JsonAdaptedPersonTest.java
+++ b/src/test/java/seedu/address/storage/JsonAdaptedPersonTest.java
@@ -1,110 +1,133 @@
-package seedu.address.storage;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static seedu.address.storage.JsonAdaptedPerson.MISSING_FIELD_MESSAGE_FORMAT;
-import static seedu.address.testutil.Assert.assertThrows;
-import static seedu.address.testutil.TypicalPersons.BENSON;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import org.junit.jupiter.api.Test;
-
-import seedu.address.commons.exceptions.IllegalValueException;
-import seedu.address.model.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Phone;
-
-public class JsonAdaptedPersonTest {
- private static final String INVALID_NAME = "R@chel";
- private static final String INVALID_PHONE = "+651234";
- private static final String INVALID_ADDRESS = " ";
- private static final String INVALID_EMAIL = "example.com";
- private static final String INVALID_TAG = "#friend";
-
- private static final String VALID_NAME = BENSON.getName().toString();
- private static final String VALID_PHONE = BENSON.getPhone().toString();
- private static final String VALID_EMAIL = BENSON.getEmail().toString();
- private static final String VALID_ADDRESS = BENSON.getAddress().toString();
- private static final List VALID_TAGS = BENSON.getTags().stream()
- .map(JsonAdaptedTag::new)
- .collect(Collectors.toList());
-
- @Test
- public void toModelType_validPersonDetails_returnsPerson() throws Exception {
- JsonAdaptedPerson person = new JsonAdaptedPerson(BENSON);
- assertEquals(BENSON, person.toModelType());
- }
-
- @Test
- public void toModelType_invalidName_throwsIllegalValueException() {
- JsonAdaptedPerson person =
- new JsonAdaptedPerson(INVALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS);
- String expectedMessage = Name.MESSAGE_CONSTRAINTS;
- assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
- }
-
- @Test
- public void toModelType_nullName_throwsIllegalValueException() {
- JsonAdaptedPerson person = new JsonAdaptedPerson(null, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS);
- String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Name.class.getSimpleName());
- assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
- }
-
- @Test
- public void toModelType_invalidPhone_throwsIllegalValueException() {
- JsonAdaptedPerson person =
- new JsonAdaptedPerson(VALID_NAME, INVALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS);
- String expectedMessage = Phone.MESSAGE_CONSTRAINTS;
- assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
- }
-
- @Test
- public void toModelType_nullPhone_throwsIllegalValueException() {
- JsonAdaptedPerson person = new JsonAdaptedPerson(VALID_NAME, null, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS);
- String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Phone.class.getSimpleName());
- assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
- }
-
- @Test
- public void toModelType_invalidEmail_throwsIllegalValueException() {
- JsonAdaptedPerson person =
- new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, INVALID_EMAIL, VALID_ADDRESS, VALID_TAGS);
- String expectedMessage = Email.MESSAGE_CONSTRAINTS;
- assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
- }
-
- @Test
- public void toModelType_nullEmail_throwsIllegalValueException() {
- JsonAdaptedPerson person = new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, null, VALID_ADDRESS, VALID_TAGS);
- String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Email.class.getSimpleName());
- assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
- }
-
- @Test
- public void toModelType_invalidAddress_throwsIllegalValueException() {
- JsonAdaptedPerson person =
- new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, INVALID_ADDRESS, VALID_TAGS);
- String expectedMessage = Address.MESSAGE_CONSTRAINTS;
- assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
- }
-
- @Test
- public void toModelType_nullAddress_throwsIllegalValueException() {
- JsonAdaptedPerson person = new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, null, VALID_TAGS);
- String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Address.class.getSimpleName());
- assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
- }
-
- @Test
- public void toModelType_invalidTags_throwsIllegalValueException() {
- List invalidTags = new ArrayList<>(VALID_TAGS);
- invalidTags.add(new JsonAdaptedTag(INVALID_TAG));
- JsonAdaptedPerson person =
- new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, invalidTags);
- assertThrows(IllegalValueException.class, person::toModelType);
- }
-
-}
+//package seedu.address.storage;
+//
+//import static org.junit.jupiter.api.Assertions.assertEquals;
+//import static seedu.address.storage.JsonAdaptedPerson.MISSING_FIELD_MESSAGE_FORMAT;
+//import static seedu.address.testutil.Assert.assertThrows;
+//import static seedu.address.testutil.TypicalPersons.BENSON;
+//
+//import java.util.ArrayList;
+//import java.util.List;
+//import java.util.stream.Collectors;
+//
+//import org.junit.jupiter.api.Test;
+//
+//import seedu.address.commons.exceptions.IllegalValueException;
+//import seedu.address.model.person.Address;
+//import seedu.address.model.person.Email;
+//import seedu.address.model.booking.TenantName;
+//import seedu.address.model.booking.Phone;
+//
+//public class JsonAdaptedPersonTest {
+// private static final String INVALID_NAME = "R@chel";
+// private static final String INVALID_PHONE = "+651234";
+// private static final String INVALID_ADDRESS = " ";
+// private static final String INVALID_EMAIL = "example.com";
+// private static final String INVALID_CLEAN_STATUS_TAG = "NO MEANING";
+// private static final String INVALID_TAG = "#friend";
+//
+// private static final String VALID_NAME = BENSON.getName().toString();
+// private static final String VALID_PHONE = BENSON.getPhone().toString();
+// private static final String VALID_EMAIL = BENSON.getEmail().toString();
+// private static final String VALID_ADDRESS = BENSON.getAddress().toString();
+// private static final List VALID_CLEAN_STATUS_TAG = BENSON.getCleanStatusTags().stream()
+// .map(JsonAdaptedCleanStatusTag::new)
+// .collect(Collectors.toList());
+// private static final List VALID_TAGS = BENSON.getTags().stream()
+// .map(JsonAdaptedTag::new)
+// .collect(Collectors.toList());
+//
+// @Test
+// public void toModelType_validPersonDetails_returnsPerson() throws Exception {
+// JsonAdaptedPerson person = new JsonAdaptedPerson(BENSON);
+// assertEquals(BENSON, person.toModelType());
+// }
+//
+// @Test
+// public void toModelType_invalidName_throwsIllegalValueException() {
+// JsonAdaptedPerson person =
+// new JsonAdaptedPerson(INVALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS,
+// VALID_CLEAN_STATUS_TAG, VALID_TAGS);
+// String expectedMessage = TenantName.MESSAGE_CONSTRAINTS;
+// assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
+// }
+//
+// @Test
+// public void toModelType_nullName_throwsIllegalValueException() {
+// JsonAdaptedPerson person = new JsonAdaptedPerson(null, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS,
+// VALID_CLEAN_STATUS_TAG, VALID_TAGS);
+// String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, TenantName.class.getSimpleName());
+// assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
+// }
+//
+// @Test
+// public void toModelType_invalidPhone_throwsIllegalValueException() {
+// JsonAdaptedPerson person =
+// new JsonAdaptedPerson(VALID_NAME, INVALID_PHONE, VALID_EMAIL, VALID_ADDRESS,
+// VALID_CLEAN_STATUS_TAG, VALID_TAGS);
+// String expectedMessage = Phone.MESSAGE_CONSTRAINTS;
+// assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
+// }
+//
+// @Test
+// public void toModelType_nullPhone_throwsIllegalValueException() {
+// JsonAdaptedPerson person = new JsonAdaptedPerson(VALID_NAME, null, VALID_EMAIL, VALID_ADDRESS,
+// VALID_CLEAN_STATUS_TAG, VALID_TAGS);
+// String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Phone.class.getSimpleName());
+// assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
+// }
+//
+// @Test
+// public void toModelType_invalidEmail_throwsIllegalValueException() {
+// JsonAdaptedPerson person =
+// new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, INVALID_EMAIL, VALID_ADDRESS,
+// VALID_CLEAN_STATUS_TAG, VALID_TAGS);
+// String expectedMessage = Email.MESSAGE_CONSTRAINTS;
+// assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
+// }
+//
+// @Test
+// public void toModelType_nullEmail_throwsIllegalValueException() {
+// JsonAdaptedPerson person = new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, null, VALID_ADDRESS,
+// VALID_CLEAN_STATUS_TAG, VALID_TAGS);
+// String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Email.class.getSimpleName());
+// assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
+// }
+//
+// @Test
+// public void toModelType_invalidAddress_throwsIllegalValueException() {
+// JsonAdaptedPerson person =
+// new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, INVALID_ADDRESS,
+// VALID_CLEAN_STATUS_TAG, VALID_TAGS);
+// String expectedMessage = Address.MESSAGE_CONSTRAINTS;
+// assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
+// }
+//
+// @Test
+// public void toModelType_nullAddress_throwsIllegalValueException() {
+// JsonAdaptedPerson person = new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, null,
+// VALID_CLEAN_STATUS_TAG, VALID_TAGS);
+// String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Address.class.getSimpleName());
+// assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
+// }
+//
+// @Test
+// public void toModelType_invalidCleanStatusTag_throwsIllegalValueException() {
+// List invalidCleanStatusTag = new ArrayList<>(VALID_CLEAN_STATUS_TAG);
+// invalidCleanStatusTag.add(new JsonAdaptedCleanStatusTag(INVALID_CLEAN_STATUS_TAG));
+// JsonAdaptedPerson person =
+// new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS,
+// invalidCleanStatusTag, VALID_TAGS);
+// assertThrows(IllegalValueException.class, person::toModelType);
+// }
+//
+// @Test
+// public void toModelType_invalidTags_throwsIllegalValueException() {
+// List invalidTags = new ArrayList<>(VALID_TAGS);
+// invalidTags.add(new JsonAdaptedTag(INVALID_TAG));
+// JsonAdaptedPerson person =
+// new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS,
+// VALID_CLEAN_STATUS_TAG, invalidTags);
+// assertThrows(IllegalValueException.class, person::toModelType);
+// }
+//
+//}
diff --git a/src/test/java/seedu/address/storage/JsonAdaptedResidenceTest.java b/src/test/java/seedu/address/storage/JsonAdaptedResidenceTest.java
new file mode 100644
index 00000000000..e59adad91f9
--- /dev/null
+++ b/src/test/java/seedu/address/storage/JsonAdaptedResidenceTest.java
@@ -0,0 +1,103 @@
+package seedu.address.storage;
+
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static seedu.address.storage.JsonAdaptedResidence.MISSING_FIELD_MESSAGE_FORMAT;
+import static seedu.address.testutil.Assert.assertThrows;
+import static seedu.address.testutil.TypicalResidences.RESIDENCE_A;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.junit.jupiter.api.Test;
+
+import seedu.address.commons.exceptions.IllegalValueException;
+import seedu.address.model.residence.ResidenceAddress;
+import seedu.address.model.residence.ResidenceName;
+import seedu.address.model.tag.CleanStatusTag;
+
+public class JsonAdaptedResidenceTest {
+ private static final String INVALID_NAME = "Rchel!";
+ private static final String INVALID_ADDRESS = " ";
+ private static final String INVALID_CLEAN_STATUS_TAG = "NO MEANING";
+ private static final String INVALID_TAG = "#friend";
+
+ private static final String VALID_NAME = RESIDENCE_A.getResidenceName().toString();
+ private static final String VALID_ADDRESS = RESIDENCE_A.getResidenceAddress().toString();
+ private static final String VALID_CLEAN_STATUS_TAG = RESIDENCE_A.getCleanStatusTag().toString();
+ private static final List VALID_BOOKINGS = new ArrayList<>();
+ private static final List VALID_TAGS = RESIDENCE_A.getTags().stream()
+ .map(JsonAdaptedTag::new)
+ .collect(Collectors.toList());
+
+ @Test
+ public void toModelType_validPersonDetails_returnsPerson() throws Exception {
+ JsonAdaptedResidence residence = new JsonAdaptedResidence(RESIDENCE_A);
+ assertEquals(RESIDENCE_A, residence.toModelType());
+ }
+
+ @Test
+ public void toModelType_invalidName_throwsIllegalValueException() {
+ JsonAdaptedResidence residence =
+ new JsonAdaptedResidence(INVALID_NAME, VALID_ADDRESS, VALID_BOOKINGS,
+ VALID_CLEAN_STATUS_TAG, VALID_TAGS);
+ String expectedMessage = ResidenceName.MESSAGE_CONSTRAINTS;
+ assertThrows(IllegalValueException.class, expectedMessage, residence::toModelType);
+ }
+
+ @Test
+ public void toModelType_nullName_throwsIllegalValueException() {
+ JsonAdaptedResidence residence = new JsonAdaptedResidence(null, VALID_ADDRESS, VALID_BOOKINGS,
+ VALID_CLEAN_STATUS_TAG, VALID_TAGS);
+ String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, ResidenceName.class.getSimpleName());
+ assertThrows(IllegalValueException.class, expectedMessage, residence::toModelType);
+ }
+
+ @Test
+ public void toModelType_invalidAddress_throwsIllegalValueException() {
+ JsonAdaptedResidence residence =
+ new JsonAdaptedResidence(VALID_NAME, INVALID_ADDRESS, VALID_BOOKINGS,
+ VALID_CLEAN_STATUS_TAG, VALID_TAGS);
+ String expectedMessage = ResidenceAddress.MESSAGE_CONSTRAINTS;
+ assertThrows(IllegalValueException.class, expectedMessage, residence::toModelType);
+ }
+
+ @Test
+ public void toModelType_nullAddress_throwsIllegalValueException() {
+ JsonAdaptedResidence residence = new JsonAdaptedResidence(VALID_NAME, null, VALID_BOOKINGS,
+ VALID_CLEAN_STATUS_TAG, VALID_TAGS);
+ String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, ResidenceAddress.class.getSimpleName());
+ assertThrows(IllegalValueException.class, expectedMessage, residence::toModelType);
+ }
+
+ @Test
+ public void toModelType_invalidCleanStatus_throwsIllegalValueException() {
+ JsonAdaptedResidence residence =
+ new JsonAdaptedResidence(VALID_NAME, VALID_ADDRESS, VALID_BOOKINGS,
+ INVALID_CLEAN_STATUS_TAG, VALID_TAGS);
+ String expectedMessage = CleanStatusTag.MESSAGE_CONSTRAINTS;
+ assertThrows(IllegalArgumentException.class, expectedMessage, residence::toModelType);
+ }
+
+ @Test
+ public void toModelType_nullCleanStatus_throwsIllegalValueException() {
+ JsonAdaptedResidence residence =
+ new JsonAdaptedResidence(VALID_NAME, VALID_ADDRESS, VALID_BOOKINGS,
+ null, VALID_TAGS);
+ String expectedMessage = null;
+ assertThrows(NullPointerException.class, expectedMessage, residence::toModelType);
+ }
+
+
+ @Test
+ public void toModelType_invalidTags_throwsIllegalValueException() {
+ List invalidTags = new ArrayList<>(VALID_TAGS);
+ invalidTags.add(new JsonAdaptedTag(INVALID_TAG));
+ JsonAdaptedResidence residence =
+ new JsonAdaptedResidence(VALID_NAME, VALID_ADDRESS, VALID_BOOKINGS,
+ VALID_CLEAN_STATUS_TAG, invalidTags);
+ assertThrows(IllegalValueException.class, residence::toModelType);
+ }
+
+}
diff --git a/src/test/java/seedu/address/storage/JsonAddressBookStorageTest.java b/src/test/java/seedu/address/storage/JsonAddressBookStorageTest.java
deleted file mode 100644
index ac3c3af9566..00000000000
--- a/src/test/java/seedu/address/storage/JsonAddressBookStorageTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package seedu.address.storage;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static seedu.address.testutil.Assert.assertThrows;
-import static seedu.address.testutil.TypicalPersons.ALICE;
-import static seedu.address.testutil.TypicalPersons.HOON;
-import static seedu.address.testutil.TypicalPersons.IDA;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
-
-import java.io.IOException;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.io.TempDir;
-
-import seedu.address.commons.exceptions.DataConversionException;
-import seedu.address.model.AddressBook;
-import seedu.address.model.ReadOnlyAddressBook;
-
-public class JsonAddressBookStorageTest {
- private static final Path TEST_DATA_FOLDER = Paths.get("src", "test", "data", "JsonAddressBookStorageTest");
-
- @TempDir
- public Path testFolder;
-
- @Test
- public void readAddressBook_nullFilePath_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> readAddressBook(null));
- }
-
- private java.util.Optional readAddressBook(String filePath) throws Exception {
- return new JsonAddressBookStorage(Paths.get(filePath)).readAddressBook(addToTestDataPathIfNotNull(filePath));
- }
-
- private Path addToTestDataPathIfNotNull(String prefsFileInTestDataFolder) {
- return prefsFileInTestDataFolder != null
- ? TEST_DATA_FOLDER.resolve(prefsFileInTestDataFolder)
- : null;
- }
-
- @Test
- public void read_missingFile_emptyResult() throws Exception {
- assertFalse(readAddressBook("NonExistentFile.json").isPresent());
- }
-
- @Test
- public void read_notJsonFormat_exceptionThrown() {
- assertThrows(DataConversionException.class, () -> readAddressBook("notJsonFormatAddressBook.json"));
- }
-
- @Test
- public void readAddressBook_invalidPersonAddressBook_throwDataConversionException() {
- assertThrows(DataConversionException.class, () -> readAddressBook("invalidPersonAddressBook.json"));
- }
-
- @Test
- public void readAddressBook_invalidAndValidPersonAddressBook_throwDataConversionException() {
- assertThrows(DataConversionException.class, () -> readAddressBook("invalidAndValidPersonAddressBook.json"));
- }
-
- @Test
- public void readAndSaveAddressBook_allInOrder_success() throws Exception {
- Path filePath = testFolder.resolve("TempAddressBook.json");
- AddressBook original = getTypicalAddressBook();
- JsonAddressBookStorage jsonAddressBookStorage = new JsonAddressBookStorage(filePath);
-
- // Save in new file and read back
- jsonAddressBookStorage.saveAddressBook(original, filePath);
- ReadOnlyAddressBook readBack = jsonAddressBookStorage.readAddressBook(filePath).get();
- assertEquals(original, new AddressBook(readBack));
-
- // Modify data, overwrite exiting file, and read back
- original.addPerson(HOON);
- original.removePerson(ALICE);
- jsonAddressBookStorage.saveAddressBook(original, filePath);
- readBack = jsonAddressBookStorage.readAddressBook(filePath).get();
- assertEquals(original, new AddressBook(readBack));
-
- // Save and read without specifying file path
- original.addPerson(IDA);
- jsonAddressBookStorage.saveAddressBook(original); // file path not specified
- readBack = jsonAddressBookStorage.readAddressBook().get(); // file path not specified
- assertEquals(original, new AddressBook(readBack));
-
- }
-
- @Test
- public void saveAddressBook_nullAddressBook_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> saveAddressBook(null, "SomeFile.json"));
- }
-
- /**
- * Saves {@code addressBook} at the specified {@code filePath}.
- */
- private void saveAddressBook(ReadOnlyAddressBook addressBook, String filePath) {
- try {
- new JsonAddressBookStorage(Paths.get(filePath))
- .saveAddressBook(addressBook, addToTestDataPathIfNotNull(filePath));
- } catch (IOException ioe) {
- throw new AssertionError("There should not be an error writing to the file.", ioe);
- }
- }
-
- @Test
- public void saveAddressBook_nullFilePath_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> saveAddressBook(new AddressBook(), null));
- }
-}
diff --git a/src/test/java/seedu/address/storage/JsonResidenceTrackerStorageTest.java b/src/test/java/seedu/address/storage/JsonResidenceTrackerStorageTest.java
new file mode 100644
index 00000000000..2842376fd1e
--- /dev/null
+++ b/src/test/java/seedu/address/storage/JsonResidenceTrackerStorageTest.java
@@ -0,0 +1,113 @@
+package seedu.address.storage;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static seedu.address.testutil.Assert.assertThrows;
+import static seedu.address.testutil.TypicalResidences.EXTRA_R1;
+import static seedu.address.testutil.TypicalResidences.EXTRA_R2;
+import static seedu.address.testutil.TypicalResidences.RESIDENCE_A;
+import static seedu.address.testutil.TypicalResidences.getTypicalResidenceTracker;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+import seedu.address.commons.exceptions.DataConversionException;
+import seedu.address.model.ReadOnlyResidenceTracker;
+import seedu.address.model.ResidenceTracker;
+
+public class JsonResidenceTrackerStorageTest {
+ private static final Path TEST_DATA_FOLDER = Paths.get("src", "test", "data", "JsonResidenceTrackerStorageTest");
+
+ @TempDir
+ public Path testFolder;
+
+ @Test
+ public void readResidenceTracker_nullFilePath_throwsNullPointerException() {
+ assertThrows(NullPointerException.class, () -> readResidenceTracker(null));
+ }
+
+ private java.util.Optional readResidenceTracker(String filePath) throws Exception {
+ return new JsonResidenceTrackerStorage(Paths.get(filePath))
+ .readResidenceTracker(addToTestDataPathIfNotNull(filePath));
+ }
+
+ private Path addToTestDataPathIfNotNull(String prefsFileInTestDataFolder) {
+ return prefsFileInTestDataFolder != null
+ ? TEST_DATA_FOLDER.resolve(prefsFileInTestDataFolder)
+ : null;
+ }
+
+ @Test
+ public void read_missingFile_emptyResult() throws Exception {
+ assertFalse(readResidenceTracker("NonExistentFile.json").isPresent());
+ }
+
+ @Test
+ public void read_notJsonFormat_exceptionThrown() {
+ assertThrows(DataConversionException.class, () -> readResidenceTracker("notJsonFormatResidenceTracker.json"));
+ }
+
+ @Test
+ public void readAddressBook_invalidPersonAddressBook_throwDataConversionException() {
+ assertThrows(
+ DataConversionException.class, () -> readResidenceTracker("invalidResidenceResidenceTracker.json"));
+ }
+
+ @Test
+ public void readAddressBook_invalidAndValidPersonAddressBook_throwDataConversionException() {
+ assertThrows(DataConversionException.class, () -> readResidenceTracker(
+ "invalidAndValidResidenceResidenceTracker.json"));
+ }
+
+ @Test
+ public void readAndSaveAddressBook_allInOrder_success() throws Exception {
+ Path filePath = testFolder.resolve("TempResidenceTracker.json");
+ ResidenceTracker original = getTypicalResidenceTracker();
+ JsonResidenceTrackerStorage jsonResidenceTrackerStorage = new JsonResidenceTrackerStorage(filePath);
+
+ // Save in new file and read back
+ jsonResidenceTrackerStorage.saveResidenceTracker(original, filePath);
+ ReadOnlyResidenceTracker readBack = jsonResidenceTrackerStorage.readResidenceTracker(filePath).get();
+ assertEquals(original, new ResidenceTracker(readBack));
+
+ // Modify data, overwrite exiting file, and read back
+ original.addResidence(EXTRA_R1);
+ original.removeResidence(RESIDENCE_A);
+ jsonResidenceTrackerStorage.saveResidenceTracker(original, filePath);
+ readBack = jsonResidenceTrackerStorage.readResidenceTracker(filePath).get();
+ assertEquals(original, new ResidenceTracker(readBack));
+
+ // Save and read without specifying file path
+ original.addResidence(EXTRA_R2);
+ jsonResidenceTrackerStorage.saveResidenceTracker(original); // file path not specified
+ readBack = jsonResidenceTrackerStorage.readResidenceTracker().get(); // file path not specified
+ assertEquals(original, new ResidenceTracker(readBack));
+
+ }
+
+ @Test
+ public void saveResidenceTracker_nullResidenceTracker_throwsNullPointerException() {
+ assertThrows(NullPointerException.class, () -> saveResidenceTracker(null, "SomeFile.json"));
+ }
+
+ /**
+ * Saves {@code addressBook} at the specified {@code filePath}.
+ */
+ private void saveResidenceTracker(ReadOnlyResidenceTracker residenceTracker, String filePath) {
+ try {
+ new JsonResidenceTrackerStorage(Paths.get(filePath))
+ .saveResidenceTracker(residenceTracker, addToTestDataPathIfNotNull(filePath));
+ } catch (IOException ioe) {
+ throw new AssertionError("There should not be an error writing to the file.", ioe);
+ }
+ }
+
+ @Test
+ public void saveResidenceTracker_nullFilePath_throwsNullPointerException() {
+ assertThrows(NullPointerException.class, () -> saveResidenceTracker(new ResidenceTracker(), null));
+ }
+}
diff --git a/src/test/java/seedu/address/storage/JsonSerializableAddressBookTest.java b/src/test/java/seedu/address/storage/JsonSerializableAddressBookTest.java
deleted file mode 100644
index 188c9058d20..00000000000
--- a/src/test/java/seedu/address/storage/JsonSerializableAddressBookTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package seedu.address.storage;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static seedu.address.testutil.Assert.assertThrows;
-
-import java.nio.file.Path;
-import java.nio.file.Paths;
-
-import org.junit.jupiter.api.Test;
-
-import seedu.address.commons.exceptions.IllegalValueException;
-import seedu.address.commons.util.JsonUtil;
-import seedu.address.model.AddressBook;
-import seedu.address.testutil.TypicalPersons;
-
-public class JsonSerializableAddressBookTest {
-
- private static final Path TEST_DATA_FOLDER = Paths.get("src", "test", "data", "JsonSerializableAddressBookTest");
- private static final Path TYPICAL_PERSONS_FILE = TEST_DATA_FOLDER.resolve("typicalPersonsAddressBook.json");
- private static final Path INVALID_PERSON_FILE = TEST_DATA_FOLDER.resolve("invalidPersonAddressBook.json");
- private static final Path DUPLICATE_PERSON_FILE = TEST_DATA_FOLDER.resolve("duplicatePersonAddressBook.json");
-
- @Test
- public void toModelType_typicalPersonsFile_success() throws Exception {
- JsonSerializableAddressBook dataFromFile = JsonUtil.readJsonFile(TYPICAL_PERSONS_FILE,
- JsonSerializableAddressBook.class).get();
- AddressBook addressBookFromFile = dataFromFile.toModelType();
- AddressBook typicalPersonsAddressBook = TypicalPersons.getTypicalAddressBook();
- assertEquals(addressBookFromFile, typicalPersonsAddressBook);
- }
-
- @Test
- public void toModelType_invalidPersonFile_throwsIllegalValueException() throws Exception {
- JsonSerializableAddressBook dataFromFile = JsonUtil.readJsonFile(INVALID_PERSON_FILE,
- JsonSerializableAddressBook.class).get();
- assertThrows(IllegalValueException.class, dataFromFile::toModelType);
- }
-
- @Test
- public void toModelType_duplicatePersons_throwsIllegalValueException() throws Exception {
- JsonSerializableAddressBook dataFromFile = JsonUtil.readJsonFile(DUPLICATE_PERSON_FILE,
- JsonSerializableAddressBook.class).get();
- assertThrows(IllegalValueException.class, JsonSerializableAddressBook.MESSAGE_DUPLICATE_PERSON,
- dataFromFile::toModelType);
- }
-
-}
diff --git a/src/test/java/seedu/address/storage/JsonSerializableResidenceTrackerTest.java b/src/test/java/seedu/address/storage/JsonSerializableResidenceTrackerTest.java
new file mode 100644
index 00000000000..49e2abbfd1a
--- /dev/null
+++ b/src/test/java/seedu/address/storage/JsonSerializableResidenceTrackerTest.java
@@ -0,0 +1,51 @@
+package seedu.address.storage;
+
+//import static org.junit.jupiter.api.Assertions.assertEquals;
+import static seedu.address.testutil.Assert.assertThrows;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import org.junit.jupiter.api.Test;
+
+import seedu.address.commons.exceptions.IllegalValueException;
+import seedu.address.commons.util.JsonUtil;
+//import seedu.address.model.ResidenceTracker;
+//import seedu.address.testutil.TypicalResidences;
+
+public class JsonSerializableResidenceTrackerTest {
+
+ private static final Path TEST_DATA_FOLDER =
+ Paths.get("src", "test", "data", "JsonSerializableResidenceTrackerTest");
+ private static final Path TYPICAL_RESIDENCE_FILE = TEST_DATA_FOLDER
+ .resolve("typicalResidencesResidenceTracker.json");
+ private static final Path INVALID_RESIDENCE_FILE = TEST_DATA_FOLDER
+ .resolve("invalidResidenceResidenceTracker.json");
+ private static final Path DUPLICATE_RESIDENCE_FILE = TEST_DATA_FOLDER
+ .resolve("duplicateResidenceResidenceTracker.json");
+
+ /*@Test
+ public void toModelType_typicalResidencesFile_success() throws Exception {
+ JsonSerializableResidenceTracker dataFromFile = JsonUtil.readJsonFile(TYPICAL_RESIDENCE_FILE,
+ JsonSerializableResidenceTracker.class).get();
+ ResidenceTracker residenceTrackerFromFile = dataFromFile.toModelType();
+ ResidenceTracker typicalResidenceTracker = TypicalResidences.getTypicalResidenceTracker();
+ assertEquals(residenceTrackerFromFile, typicalResidenceTracker);
+ }*/
+
+ @Test
+ public void toModelType_invalidResidenceFile_throwsIllegalValueException() throws Exception {
+ JsonSerializableResidenceTracker dataFromFile = JsonUtil.readJsonFile(INVALID_RESIDENCE_FILE,
+ JsonSerializableResidenceTracker.class).get();
+ assertThrows(IllegalValueException.class, dataFromFile::toModelType);
+ }
+
+ @Test
+ public void toModelType_duplicateResidences_throwsIllegalValueException() throws Exception {
+ JsonSerializableResidenceTracker dataFromFile = JsonUtil.readJsonFile(DUPLICATE_RESIDENCE_FILE,
+ JsonSerializableResidenceTracker.class).get();
+ assertThrows(IllegalValueException.class, JsonSerializableResidenceTracker.MESSAGE_DUPLICATE_RESIDENCE,
+ dataFromFile::toModelType);
+ }
+
+}
diff --git a/src/test/java/seedu/address/storage/JsonUserPrefsStorageTest.java b/src/test/java/seedu/address/storage/JsonUserPrefsStorageTest.java
index 16f33f4a6bb..6d008687622 100644
--- a/src/test/java/seedu/address/storage/JsonUserPrefsStorageTest.java
+++ b/src/test/java/seedu/address/storage/JsonUserPrefsStorageTest.java
@@ -73,7 +73,7 @@ public void readUserPrefs_extraValuesInFile_extraValuesIgnored() throws DataConv
private UserPrefs getTypicalUserPrefs() {
UserPrefs userPrefs = new UserPrefs();
userPrefs.setGuiSettings(new GuiSettings(1000, 500, 300, 100));
- userPrefs.setAddressBookFilePath(Paths.get("addressbook.json"));
+ userPrefs.setResidenceTrackerFilePath(Paths.get("data/residencetracker.json"));
return userPrefs;
}
diff --git a/src/test/java/seedu/address/storage/StorageManagerTest.java b/src/test/java/seedu/address/storage/StorageManagerTest.java
index 99a16548970..4139a35a9e2 100644
--- a/src/test/java/seedu/address/storage/StorageManagerTest.java
+++ b/src/test/java/seedu/address/storage/StorageManagerTest.java
@@ -2,7 +2,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
+import static seedu.address.testutil.TypicalResidences.getTypicalResidenceTracker;
import java.nio.file.Path;
@@ -11,8 +11,8 @@
import org.junit.jupiter.api.io.TempDir;
import seedu.address.commons.core.GuiSettings;
-import seedu.address.model.AddressBook;
-import seedu.address.model.ReadOnlyAddressBook;
+import seedu.address.model.ReadOnlyResidenceTracker;
+import seedu.address.model.ResidenceTracker;
import seedu.address.model.UserPrefs;
public class StorageManagerTest {
@@ -24,9 +24,10 @@ public class StorageManagerTest {
@BeforeEach
public void setUp() {
- JsonAddressBookStorage addressBookStorage = new JsonAddressBookStorage(getTempFilePath("ab"));
+ JsonResidenceTrackerStorage jsonResidenceTrackerStorage =
+ new JsonResidenceTrackerStorage(getTempFilePath("ab"));
JsonUserPrefsStorage userPrefsStorage = new JsonUserPrefsStorage(getTempFilePath("prefs"));
- storageManager = new StorageManager(addressBookStorage, userPrefsStorage);
+ storageManager = new StorageManager(jsonResidenceTrackerStorage, userPrefsStorage);
}
private Path getTempFilePath(String fileName) {
@@ -48,21 +49,21 @@ public void prefsReadSave() throws Exception {
}
@Test
- public void addressBookReadSave() throws Exception {
+ public void residenceTrackerReadSave() throws Exception {
/*
* Note: This is an integration test that verifies the StorageManager is properly wired to the
- * {@link JsonAddressBookStorage} class.
- * More extensive testing of UserPref saving/reading is done in {@link JsonAddressBookStorageTest} class.
+ * {@link JsonResidenceTrackerStorage} class.
+ * More extensive testing of UserPref saving/reading is done in {@link JsonResidenceTrackerStorageTest} class.
*/
- AddressBook original = getTypicalAddressBook();
- storageManager.saveAddressBook(original);
- ReadOnlyAddressBook retrieved = storageManager.readAddressBook().get();
- assertEquals(original, new AddressBook(retrieved));
+ ResidenceTracker original = getTypicalResidenceTracker();
+ storageManager.saveResidenceTracker(original);
+ ReadOnlyResidenceTracker retrieved = storageManager.readResidenceTracker().get();
+ assertEquals(original, new ResidenceTracker(retrieved));
}
@Test
- public void getAddressBookFilePath() {
- assertNotNull(storageManager.getAddressBookFilePath());
+ public void getResidenceTrackerFilePath() {
+ assertNotNull(storageManager.getResidenceTrackerFilePath());
}
}
diff --git a/src/test/java/seedu/address/testutil/AddressBookBuilder.java b/src/test/java/seedu/address/testutil/AddressBookBuilder.java
deleted file mode 100644
index d53799fd110..00000000000
--- a/src/test/java/seedu/address/testutil/AddressBookBuilder.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package seedu.address.testutil;
-
-import seedu.address.model.AddressBook;
-import seedu.address.model.person.Person;
-
-/**
- * A utility class to help with building Addressbook objects.
- * Example usage:
- * {@code AddressBook ab = new AddressBookBuilder().withPerson("John", "Doe").build();}
- */
-public class AddressBookBuilder {
-
- private AddressBook addressBook;
-
- public AddressBookBuilder() {
- addressBook = new AddressBook();
- }
-
- public AddressBookBuilder(AddressBook addressBook) {
- this.addressBook = addressBook;
- }
-
- /**
- * Adds a new {@code Person} to the {@code AddressBook} that we are building.
- */
- public AddressBookBuilder withPerson(Person person) {
- addressBook.addPerson(person);
- return this;
- }
-
- public AddressBook build() {
- return addressBook;
- }
-}
diff --git a/src/test/java/seedu/address/testutil/BookingBuilder.java b/src/test/java/seedu/address/testutil/BookingBuilder.java
new file mode 100644
index 00000000000..f08e6494255
--- /dev/null
+++ b/src/test/java/seedu/address/testutil/BookingBuilder.java
@@ -0,0 +1,80 @@
+package seedu.address.testutil;
+
+import java.time.LocalDate;
+
+import seedu.address.model.booking.Booking;
+import seedu.address.model.booking.Phone;
+import seedu.address.model.booking.TenantName;
+
+/**
+ * A utility class to help with building Booking objects.
+ */
+public class BookingBuilder {
+
+ public static final String DEFAULT_NAME = "Amy Bee";
+ public static final String DEFAULT_PHONE = "85355255";
+ public static final LocalDate DEFAULT_START = LocalDate.of(2021, 3, 22);
+ public static final LocalDate DEFAULT_END = LocalDate.of(2021, 3, 25);
+
+ private TenantName tenantName;
+ private Phone phone;
+ private LocalDate start;
+ private LocalDate end;
+
+ /**
+ * Creates a {@code BookingBuilder} with the default details.
+ */
+ public BookingBuilder() {
+ tenantName = new TenantName(DEFAULT_NAME);
+ phone = new Phone(DEFAULT_PHONE);
+ start = DEFAULT_START;
+ end = DEFAULT_END;
+ }
+
+ /**
+ * Initializes the BookingBuilder with the data of {@code bookingToCopy}.
+ */
+ public BookingBuilder(Booking bookingToCopy) {
+ tenantName = bookingToCopy.getTenantName();
+ phone = bookingToCopy.getPhone();
+ start = bookingToCopy.getStart();
+ end = bookingToCopy.getEnd();
+ }
+
+ /**
+ * Sets the {@code TenantName} of the {@code Booking} that we are building.
+ */
+ public BookingBuilder withName(String name) {
+ this.tenantName = new TenantName(name);
+ return this;
+ }
+
+ /**
+ * Sets the {@code Phone} of the {@code Booking} that we are building.
+ */
+ public BookingBuilder withPhone(String phone) {
+ this.phone = new Phone(phone);
+ return this;
+ }
+
+ /**
+ * Sets the {@code Start} of the {@code Booking} that we are building.
+ */
+ public BookingBuilder withStart(LocalDate start) {
+ this.start = start;
+ return this;
+ }
+
+ /**
+ * Sets the {@code End} of the {@code Booking} that we are building.
+ */
+ public BookingBuilder withEnd(LocalDate end) {
+ this.end = end;
+ return this;
+ }
+
+ public Booking build() {
+ return new Booking(tenantName, phone, start, end);
+ }
+
+}
diff --git a/src/test/java/seedu/address/testutil/BookingListBuilder.java b/src/test/java/seedu/address/testutil/BookingListBuilder.java
new file mode 100644
index 00000000000..96d059f2bb6
--- /dev/null
+++ b/src/test/java/seedu/address/testutil/BookingListBuilder.java
@@ -0,0 +1,80 @@
+//package seedu.address.testutil;
+//
+//import java.time.LocalDate;
+//
+//import seedu.address.model.booking.Booking;
+//import seedu.address.model.booking.TenantName;
+//import seedu.address.model.booking.Phone;
+//
+///**
+// * A utility class to help with building Booking objects.
+// */
+//public class BookingListBuilder {
+//
+// public static final String DEFAULT_NAME = "Amy Bee";
+// public static final String DEFAULT_PHONE = "85355255";
+// public static final LocalDate DEFAULT_START = LocalDate.of(2021, 3, 22);
+// public static final LocalDate DEFAULT_END = LocalDate.of(2021, 3, 25);
+//
+// private TenantName name;
+// private Phone phone;
+// private LocalDate start;
+// private LocalDate end;
+//
+// /**
+// * Creates a {@code BookingBuilder} with the default details.
+// */
+// public BookingListBuilder() {
+// name = new TenantName(DEFAULT_NAME);
+// phone = new Phone(DEFAULT_PHONE);
+// start = DEFAULT_START;
+// end = DEFAULT_END;
+// }
+//
+// /**
+// * Initializes the BookingBuilder with the data of {@code bookingToCopy}.
+// */
+// public BookingListBuilder(Booking bookingToCopy) {
+// name = bookingToCopy.getName();
+// phone = bookingToCopy.getPhone();
+// start = bookingToCopy.getStart();
+// end = bookingToCopy.getEnd();
+// }
+//
+// /**
+// * Sets the {@code TenantName} of the {@code Booking} that we are building.
+// */
+// public BookingListBuilder withName(String name) {
+// this.name = new TenantName(name);
+// return this;
+// }
+//
+// /**
+// * Sets the {@code Phone} of the {@code Booking} that we are building.
+// */
+// public BookingListBuilder withPhone(String phone) {
+// this.phone = new Phone(phone);
+// return this;
+// }
+//
+// /**
+// * Sets the {@code Start} of the {@code Booking} that we are building.
+// */
+// public BookingListBuilder withStart(LocalDate start) {
+// this.start = start;
+// return this;
+// }
+//
+// /**
+// * Sets the {@code End} of the {@code Booking} that we are building.
+// */
+// public BookingListBuilder withEnd(LocalDate end) {
+// this.end = end;
+// return this;
+// }
+//
+// public Booking build() {
+// return new Booking(name, phone, start, end);
+// }
+//
+//}
diff --git a/src/test/java/seedu/address/testutil/EditBookingDescriptorBuilder.java b/src/test/java/seedu/address/testutil/EditBookingDescriptorBuilder.java
new file mode 100644
index 00000000000..5eb217af146
--- /dev/null
+++ b/src/test/java/seedu/address/testutil/EditBookingDescriptorBuilder.java
@@ -0,0 +1,71 @@
+package seedu.address.testutil;
+
+import java.time.LocalDate;
+
+import seedu.address.logic.commands.EditBookingCommand.EditBookingDescriptor;
+import seedu.address.model.booking.Booking;
+import seedu.address.model.booking.Phone;
+import seedu.address.model.booking.TenantName;
+
+public class EditBookingDescriptorBuilder {
+
+ private EditBookingDescriptor descriptor;
+
+ public EditBookingDescriptorBuilder() {
+ descriptor = new EditBookingDescriptor();
+ }
+
+ public EditBookingDescriptorBuilder(EditBookingDescriptor descriptor) {
+ this.descriptor = new EditBookingDescriptor(descriptor);
+ }
+
+ /**
+ * Returns an {@code EditBookingDescriptor} with fields containing {@code booking}'s details
+ */
+ public EditBookingDescriptorBuilder(Booking booking) {
+ descriptor = new EditBookingDescriptor();
+ descriptor.setName(booking.getTenantName());
+ descriptor.setPhone(booking.getPhone());
+ descriptor.setStartDate(booking.getStart());
+ descriptor.setEndDate(booking.getEnd());
+ }
+
+ /**
+ * Sets the {@code TenantName} of the {@code EditBookingDescriptor} that we are building.
+ */
+ public EditBookingDescriptorBuilder withName(String name) {
+ descriptor.setName(new TenantName(name));
+ return this;
+ }
+
+ /**
+ * Sets the {@code Phone} of the {@code EditBookingDescriptor} that we are building.
+ */
+ public EditBookingDescriptorBuilder withPhone(String phone) {
+ descriptor.setPhone(new Phone(phone));
+ return this;
+ }
+
+ /**
+ * Sets the start date of the {@code EditBookingDescriptor} that we are building.
+ */
+ public EditBookingDescriptorBuilder withStartDate(LocalDate startDate) {
+ descriptor.setStartDate(startDate);
+ return this;
+ }
+
+ /**
+ * Sets the end date of the {@code EditBookingDescriptor} that we are building.
+ */
+ public EditBookingDescriptorBuilder withEndDate(LocalDate endDate) {
+ descriptor.setEndDate(endDate);
+ return this;
+ }
+
+
+ public EditBookingDescriptor build() {
+ return descriptor;
+ }
+
+
+}
diff --git a/src/test/java/seedu/address/testutil/EditPersonDescriptorBuilder.java b/src/test/java/seedu/address/testutil/EditPersonDescriptorBuilder.java
index 4584bd5044e..3c1795eac07 100644
--- a/src/test/java/seedu/address/testutil/EditPersonDescriptorBuilder.java
+++ b/src/test/java/seedu/address/testutil/EditPersonDescriptorBuilder.java
@@ -1,3 +1,4 @@
+/*
package seedu.address.testutil;
import java.util.Set;
@@ -7,14 +8,16 @@
import seedu.address.logic.commands.EditCommand.EditPersonDescriptor;
import seedu.address.model.person.Address;
import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
+import seedu.address.model.booking.TenantName;
import seedu.address.model.person.Person;
-import seedu.address.model.person.Phone;
+import seedu.address.model.booking.Phone;
import seedu.address.model.tag.Tag;
+*/
/**
* A utility class to help with building EditPersonDescriptor objects.
- */
+ *//*
+
public class EditPersonDescriptorBuilder {
private EditPersonDescriptor descriptor;
@@ -27,9 +30,11 @@ public EditPersonDescriptorBuilder(EditPersonDescriptor descriptor) {
this.descriptor = new EditPersonDescriptor(descriptor);
}
- /**
+ */
+/**
* Returns an {@code EditPersonDescriptor} with fields containing {@code person}'s details
- */
+ *//*
+
public EditPersonDescriptorBuilder(Person person) {
descriptor = new EditPersonDescriptor();
descriptor.setName(person.getName());
@@ -39,42 +44,52 @@ public EditPersonDescriptorBuilder(Person person) {
descriptor.setTags(person.getTags());
}
- /**
- * Sets the {@code Name} of the {@code EditPersonDescriptor} that we are building.
- */
+ */
+/**
+ * Sets the {@code TenantName} of the {@code EditPersonDescriptor} that we are building.
+ *//*
+
public EditPersonDescriptorBuilder withName(String name) {
- descriptor.setName(new Name(name));
+ descriptor.setName(new TenantName(name));
return this;
}
- /**
+ */
+/**
* Sets the {@code Phone} of the {@code EditPersonDescriptor} that we are building.
- */
+ *//*
+
public EditPersonDescriptorBuilder withPhone(String phone) {
descriptor.setPhone(new Phone(phone));
return this;
}
- /**
+ */
+/**
* Sets the {@code Email} of the {@code EditPersonDescriptor} that we are building.
- */
+ *//*
+
public EditPersonDescriptorBuilder withEmail(String email) {
descriptor.setEmail(new Email(email));
return this;
}
- /**
+ */
+/**
* Sets the {@code Address} of the {@code EditPersonDescriptor} that we are building.
- */
+ *//*
+
public EditPersonDescriptorBuilder withAddress(String address) {
descriptor.setAddress(new Address(address));
return this;
}
- /**
+ */
+/**
* Parses the {@code tags} into a {@code Set} and set it to the {@code EditPersonDescriptor}
* that we are building.
- */
+ *//*
+
public EditPersonDescriptorBuilder withTags(String... tags) {
Set tagSet = Stream.of(tags).map(Tag::new).collect(Collectors.toSet());
descriptor.setTags(tagSet);
@@ -85,3 +100,4 @@ public EditPersonDescriptor build() {
return descriptor;
}
}
+*/
diff --git a/src/test/java/seedu/address/testutil/EditResidenceDescriptorBuilder.java b/src/test/java/seedu/address/testutil/EditResidenceDescriptorBuilder.java
new file mode 100644
index 00000000000..f8f3307669b
--- /dev/null
+++ b/src/test/java/seedu/address/testutil/EditResidenceDescriptorBuilder.java
@@ -0,0 +1,88 @@
+package seedu.address.testutil;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import seedu.address.logic.commands.EditCommand.EditResidenceDescriptor;
+//import seedu.address.model.residence.BookingList;
+import seedu.address.model.residence.Residence;
+import seedu.address.model.residence.ResidenceAddress;
+import seedu.address.model.residence.ResidenceName;
+import seedu.address.model.tag.CleanStatusTag;
+import seedu.address.model.tag.Tag;
+
+/**
+ * A utility class to help with building EditResidenceDescriptor objects.
+ */
+public class EditResidenceDescriptorBuilder {
+
+ private EditResidenceDescriptor descriptor;
+
+ public EditResidenceDescriptorBuilder() {
+ descriptor = new EditResidenceDescriptor();
+ }
+
+ public EditResidenceDescriptorBuilder(EditResidenceDescriptor descriptor) {
+ this.descriptor = new EditResidenceDescriptor(descriptor);
+ }
+
+ /**
+ * Returns an {@code EditResidenceDescriptor} with fields containing {@code residence}'s details
+ */
+ public EditResidenceDescriptorBuilder(Residence residence) {
+ descriptor = new EditResidenceDescriptor();
+ descriptor.setResidenceName(residence.getResidenceName());
+ descriptor.setResidenceAddress(residence.getResidenceAddress());
+ descriptor.setBookingDetails(residence.getBookingList());
+ descriptor.setCleanStatusTag(residence.getCleanStatusTag());
+ descriptor.setTags(residence.getTags());
+ }
+
+ /**
+ * Sets the {@code ResidenceName} of the {@code EditResidenceDescriptor} that we are building.
+ */
+ public EditResidenceDescriptorBuilder withName(String name) {
+ descriptor.setResidenceName(new ResidenceName(name));
+ return this;
+ }
+
+ /**
+ * Sets the {@code ResidenceAddress} of the {@code EditResidenceDescriptor} that we are building.
+ */
+ public EditResidenceDescriptorBuilder withAddress(String address) {
+ descriptor.setResidenceAddress(new ResidenceAddress(address));
+ return this;
+ }
+
+ ///**
+ //* Sets the {@code Booking} of the {@code EditResidenceDescriptor} that we are building.
+ //*/
+ //public EditResidenceDescriptorBuilder withBookingDetails() {
+ // descriptor.setBookingDetails(new BookingList(bookingDetails));
+ // return this;
+ //}
+
+ /**
+ * Parses the {@code tags} into a {@code Set} and set it to the {@code EditPersonDescriptor}
+ * that we are building.
+ */
+ public EditResidenceDescriptorBuilder withCleanStatusTag(String cleanStatusTag) {
+ descriptor.setCleanStatusTag(new CleanStatusTag(cleanStatusTag));
+ return this;
+ }
+
+ /**
+ * Parses the {@code tags} into a {@code Set} and set it to the {@code EditResidenceDescriptor}
+ * that we are building.
+ */
+ public EditResidenceDescriptorBuilder withTags(String... tags) {
+ Set tagSet = Stream.of(tags).map(Tag::new).collect(Collectors.toSet());
+ descriptor.setTags(tagSet);
+ return this;
+ }
+
+ public EditResidenceDescriptor build() {
+ return descriptor;
+ }
+}
diff --git a/src/test/java/seedu/address/testutil/PersonBuilder.java b/src/test/java/seedu/address/testutil/PersonBuilder.java
deleted file mode 100644
index 6be381d39ba..00000000000
--- a/src/test/java/seedu/address/testutil/PersonBuilder.java
+++ /dev/null
@@ -1,96 +0,0 @@
-package seedu.address.testutil;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import seedu.address.model.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Person;
-import seedu.address.model.person.Phone;
-import seedu.address.model.tag.Tag;
-import seedu.address.model.util.SampleDataUtil;
-
-/**
- * A utility class to help with building Person objects.
- */
-public class PersonBuilder {
-
- public static final String DEFAULT_NAME = "Amy Bee";
- public static final String DEFAULT_PHONE = "85355255";
- public static final String DEFAULT_EMAIL = "amy@gmail.com";
- public static final String DEFAULT_ADDRESS = "123, Jurong West Ave 6, #08-111";
-
- private Name name;
- private Phone phone;
- private Email email;
- private Address address;
- private Set tags;
-
- /**
- * Creates a {@code PersonBuilder} with the default details.
- */
- public PersonBuilder() {
- name = new Name(DEFAULT_NAME);
- phone = new Phone(DEFAULT_PHONE);
- email = new Email(DEFAULT_EMAIL);
- address = new Address(DEFAULT_ADDRESS);
- tags = new HashSet<>();
- }
-
- /**
- * Initializes the PersonBuilder with the data of {@code personToCopy}.
- */
- public PersonBuilder(Person personToCopy) {
- name = personToCopy.getName();
- phone = personToCopy.getPhone();
- email = personToCopy.getEmail();
- address = personToCopy.getAddress();
- tags = new HashSet<>(personToCopy.getTags());
- }
-
- /**
- * Sets the {@code Name} of the {@code Person} that we are building.
- */
- public PersonBuilder withName(String name) {
- this.name = new Name(name);
- return this;
- }
-
- /**
- * Parses the {@code tags} into a {@code Set} and set it to the {@code Person} that we are building.
- */
- public PersonBuilder withTags(String ... tags) {
- this.tags = SampleDataUtil.getTagSet(tags);
- return this;
- }
-
- /**
- * Sets the {@code Address} of the {@code Person} that we are building.
- */
- public PersonBuilder withAddress(String address) {
- this.address = new Address(address);
- return this;
- }
-
- /**
- * Sets the {@code Phone} of the {@code Person} that we are building.
- */
- public PersonBuilder withPhone(String phone) {
- this.phone = new Phone(phone);
- return this;
- }
-
- /**
- * Sets the {@code Email} of the {@code Person} that we are building.
- */
- public PersonBuilder withEmail(String email) {
- this.email = new Email(email);
- return this;
- }
-
- public Person build() {
- return new Person(name, phone, email, address, tags);
- }
-
-}
diff --git a/src/test/java/seedu/address/testutil/PersonUtil.java b/src/test/java/seedu/address/testutil/PersonUtil.java
index 90849945183..c5feee6faeb 100644
--- a/src/test/java/seedu/address/testutil/PersonUtil.java
+++ b/src/test/java/seedu/address/testutil/PersonUtil.java
@@ -1,62 +1,62 @@
-package seedu.address.testutil;
-
-import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG;
-
-import java.util.Set;
-
-import seedu.address.logic.commands.AddCommand;
-import seedu.address.logic.commands.EditCommand.EditPersonDescriptor;
-import seedu.address.model.person.Person;
-import seedu.address.model.tag.Tag;
-
-/**
- * A utility class for Person.
- */
-public class PersonUtil {
-
- /**
- * Returns an add command string for adding the {@code person}.
- */
- public static String getAddCommand(Person person) {
- return AddCommand.COMMAND_WORD + " " + getPersonDetails(person);
- }
-
- /**
- * Returns the part of command string for the given {@code person}'s details.
- */
- public static String getPersonDetails(Person person) {
- StringBuilder sb = new StringBuilder();
- sb.append(PREFIX_NAME + person.getName().fullName + " ");
- sb.append(PREFIX_PHONE + person.getPhone().value + " ");
- sb.append(PREFIX_EMAIL + person.getEmail().value + " ");
- sb.append(PREFIX_ADDRESS + person.getAddress().value + " ");
- person.getTags().stream().forEach(
- s -> sb.append(PREFIX_TAG + s.tagName + " ")
- );
- return sb.toString();
- }
-
- /**
- * Returns the part of command string for the given {@code EditPersonDescriptor}'s details.
- */
- public static String getEditPersonDescriptorDetails(EditPersonDescriptor descriptor) {
- StringBuilder sb = new StringBuilder();
- descriptor.getName().ifPresent(name -> sb.append(PREFIX_NAME).append(name.fullName).append(" "));
- descriptor.getPhone().ifPresent(phone -> sb.append(PREFIX_PHONE).append(phone.value).append(" "));
- descriptor.getEmail().ifPresent(email -> sb.append(PREFIX_EMAIL).append(email.value).append(" "));
- descriptor.getAddress().ifPresent(address -> sb.append(PREFIX_ADDRESS).append(address.value).append(" "));
- if (descriptor.getTags().isPresent()) {
- Set tags = descriptor.getTags().get();
- if (tags.isEmpty()) {
- sb.append(PREFIX_TAG);
- } else {
- tags.forEach(s -> sb.append(PREFIX_TAG).append(s.tagName).append(" "));
- }
- }
- return sb.toString();
- }
-}
+//package seedu.address.testutil;
+//
+//import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS;
+//import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL;
+//import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
+//import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE;
+//import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG;
+//
+//import java.util.Set;
+//
+//import seedu.address.logic.commands.AddCommand;
+//import seedu.address.logic.commands.EditCommand.EditPersonDescriptor;
+//import seedu.address.model.person.Person;
+//import seedu.address.model.tag.Tag;
+//
+///**
+// * A utility class for Person.
+// */
+//public class PersonUtil {
+//
+// /**
+// * Returns an add command string for adding the {@code person}.
+// */
+// public static String getAddCommand(Person person) {
+// return AddCommand.COMMAND_WORD + " " + getPersonDetails(person);
+// }
+//
+// /**
+// * Returns the part of command string for the given {@code person}'s details.
+// */
+// public static String getPersonDetails(Person person) {
+// StringBuilder sb = new StringBuilder();
+// sb.append(PREFIX_NAME + person.getName().fullName + " ");
+// sb.append(PREFIX_PHONE + person.getPhone().value + " ");
+// sb.append(PREFIX_EMAIL + person.getEmail().value + " ");
+// sb.append(PREFIX_ADDRESS + person.getAddress().value + " ");
+// person.getTags().stream().forEach(
+// s -> sb.append(PREFIX_TAG + s.tagName + " ")
+// );
+// return sb.toString();
+// }
+//
+// /**
+// * Returns the part of command string for the given {@code EditPersonDescriptor}'s details.
+// */
+// public static String getEditPersonDescriptorDetails(EditPersonDescriptor descriptor) {
+// StringBuilder sb = new StringBuilder();
+// descriptor.getName().ifPresent(name -> sb.append(PREFIX_NAME).append(name.fullName).append(" "));
+// descriptor.getPhone().ifPresent(phone -> sb.append(PREFIX_PHONE).append(phone.value).append(" "));
+// descriptor.getEmail().ifPresent(email -> sb.append(PREFIX_EMAIL).append(email.value).append(" "));
+// descriptor.getAddress().ifPresent(address -> sb.append(PREFIX_ADDRESS).append(address.value).append(" "));
+// if (descriptor.getTags().isPresent()) {
+// Set tags = descriptor.getTags().get();
+// if (tags.isEmpty()) {
+// sb.append(PREFIX_TAG);
+// } else {
+// tags.forEach(s -> sb.append(PREFIX_TAG).append(s.tagName).append(" "));
+// }
+// }
+// return sb.toString();
+// }
+//}
diff --git a/src/test/java/seedu/address/testutil/ResidenceBuilder.java b/src/test/java/seedu/address/testutil/ResidenceBuilder.java
new file mode 100644
index 00000000000..d5d410fa308
--- /dev/null
+++ b/src/test/java/seedu/address/testutil/ResidenceBuilder.java
@@ -0,0 +1,105 @@
+package seedu.address.testutil;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import seedu.address.model.booking.Booking;
+import seedu.address.model.residence.BookingList;
+import seedu.address.model.residence.Residence;
+import seedu.address.model.residence.ResidenceAddress;
+import seedu.address.model.residence.ResidenceName;
+import seedu.address.model.tag.CleanStatusTag;
+import seedu.address.model.tag.Tag;
+import seedu.address.model.util.SampleDataUtil;
+
+/**
+ * A utility class to help with building Residence objects.
+ */
+public class ResidenceBuilder {
+ public static final String DEFAULT_RESIDENCE_NAME = "Olive Park";
+ public static final String DEFAULT_RESIDENCE_ADDRESS = "122 Olive Gardens, 652260";
+ public static final String DEFAULT_CLEAN_STATUS = "y";
+
+ private ResidenceName name;
+ private ResidenceAddress address;
+ private BookingList bookingList;
+ private CleanStatusTag cleanStatusTag;
+ private Set tags;
+
+ /**
+ * Creates a {@code ResidenceBuilder} with the default details.
+ */
+ public ResidenceBuilder() {
+ name = new ResidenceName(DEFAULT_RESIDENCE_NAME);
+ address = new ResidenceAddress(DEFAULT_RESIDENCE_ADDRESS);
+ cleanStatusTag = new CleanStatusTag(DEFAULT_CLEAN_STATUS);
+ bookingList = new BookingList();
+ tags = new HashSet<>();
+ }
+
+ /**
+ * Initializes the ResidenceBuilder with the data of {@code residenceToCopy}.
+ */
+ public ResidenceBuilder(Residence residenceToCopy) {
+ name = residenceToCopy.getResidenceName();
+ address = residenceToCopy.getResidenceAddress();
+ bookingList = residenceToCopy.getBookingList();
+ cleanStatusTag = residenceToCopy.getCleanStatusTag();
+ tags = new HashSet<>(residenceToCopy.getTags());
+ }
+
+ /**
+ * Sets the {@code ResidenceName} of the {@code Residence} that we are building.
+ */
+ public ResidenceBuilder withName(String name) {
+ this.name = new ResidenceName(name);
+ return this;
+ }
+
+ /**
+ * Sets the {@code ResidenceAddress} of the {@code Residence} that we are building.
+ */
+ public ResidenceBuilder withAddress(String address) {
+ this.address = new ResidenceAddress(address);
+ return this;
+ }
+
+ /**
+ * Sets the {@code BookingList} of the {@code Residence} that we are building.
+ */
+ public ResidenceBuilder withBookingList(List bookings) {
+ this.bookingList = new BookingList(bookings);
+ return this;
+ }
+
+ /**
+ * Sets the {@code BookingList} of the {@code Residence} that we are building with an empty BookingList.
+ */
+ public ResidenceBuilder withBookingList() {
+ this.bookingList = new BookingList();
+ return this;
+ }
+
+ /**
+ * Parses the {@code String cleanStatusTag} into a {@code CleanStatusTag} and set it to the {@code Residence}
+ * that we are building.
+ */
+ public ResidenceBuilder withCleanStatusTag(String cleanStatusTag) {
+ this.cleanStatusTag = new CleanStatusTag(cleanStatusTag);
+ return this;
+ }
+
+ /**
+ * Parses the {@code tags} into a {@code Set} and set it to the {@code Residence} that we are building.
+ */
+ public ResidenceBuilder withTags(String... tags) {
+ this.tags = SampleDataUtil.getTagSet(tags);
+ return this;
+ }
+
+ public Residence build() {
+ return new Residence(name, address, bookingList, cleanStatusTag, tags);
+ }
+
+}
diff --git a/src/test/java/seedu/address/testutil/ResidenceTrackerBuilder.java b/src/test/java/seedu/address/testutil/ResidenceTrackerBuilder.java
new file mode 100644
index 00000000000..0d636175ace
--- /dev/null
+++ b/src/test/java/seedu/address/testutil/ResidenceTrackerBuilder.java
@@ -0,0 +1,34 @@
+package seedu.address.testutil;
+
+import seedu.address.model.ResidenceTracker;
+import seedu.address.model.residence.Residence;
+
+/**
+ * A utility class to help with building ResidenceTracker objects.
+ * Example usage:
+ * {@code ResidenceTracker rt = new ResidenceTrackerBuilder().withResidence(new Residence(...)).build();}
+ */
+public class ResidenceTrackerBuilder {
+
+ private ResidenceTracker residenceTracker;
+
+ public ResidenceTrackerBuilder() {
+ residenceTracker = new ResidenceTracker();
+ }
+
+ public ResidenceTrackerBuilder(ResidenceTracker residenceTracker) {
+ this.residenceTracker = residenceTracker;
+ }
+
+ /**
+ * Adds a new {@code Residence} to the {@code ResidenceTracker} that we are building.
+ */
+ public ResidenceTrackerBuilder withResidence(Residence residence) {
+ residenceTracker.addResidence(residence);
+ return this;
+ }
+
+ public ResidenceTracker build() {
+ return residenceTracker;
+ }
+}
diff --git a/src/test/java/seedu/address/testutil/ResidenceUtil.java b/src/test/java/seedu/address/testutil/ResidenceUtil.java
new file mode 100644
index 00000000000..8b04180457b
--- /dev/null
+++ b/src/test/java/seedu/address/testutil/ResidenceUtil.java
@@ -0,0 +1,63 @@
+package seedu.address.testutil;
+
+import static seedu.address.logic.parser.CliSyntax.PREFIX_CLEAN_STATUS_TAG;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_RESIDENCE_ADDRESS;
+import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG;
+
+import java.util.Set;
+
+import seedu.address.logic.commands.AddCommand;
+import seedu.address.logic.commands.EditCommand.EditResidenceDescriptor;
+import seedu.address.model.residence.Residence;
+import seedu.address.model.tag.Tag;
+
+/**
+ * A utility class for Residence.
+ */
+public class ResidenceUtil {
+
+ /**
+ * Returns an add command string for adding the {@code residence}.
+ */
+ public static String getAddCommand(Residence residence) {
+ return AddCommand.COMMAND_WORD + " " + getResidenceDetails(residence);
+ }
+
+ /**
+ * Returns the part of command string for the given {@code residence}'s details.
+ */
+ public static String getResidenceDetails(Residence residence) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(PREFIX_NAME + residence.getResidenceName().getValue() + " ");
+ sb.append(PREFIX_RESIDENCE_ADDRESS + residence.getResidenceAddress().getValue() + " ");
+ sb.append(PREFIX_CLEAN_STATUS_TAG + residence.getCleanStatusTag().getValue() + " ");
+
+ residence.getTags().stream().forEach(
+ s -> sb.append(PREFIX_TAG + s.tagName + " ")
+ );
+ return sb.toString();
+ }
+
+ /**
+ * Returns the part of command string for the given {@code EditResidenceDescriptor}'s details.
+ */
+ public static String getEditResidenceDescriptorDetails(EditResidenceDescriptor descriptor) {
+ StringBuilder sb = new StringBuilder();
+ descriptor.getResidenceName().ifPresent(name -> sb.append(PREFIX_NAME)
+ .append(name.getValue()).append(" "));
+ descriptor.getResidenceAddress().ifPresent(address -> sb.append(PREFIX_RESIDENCE_ADDRESS)
+ .append(address.getValue()).append(" "));
+ descriptor.getCleanStatusTag().ifPresent(cleanStatusTag -> sb.append(PREFIX_CLEAN_STATUS_TAG)
+ .append(cleanStatusTag.getValue()).append(" "));
+ if (descriptor.getTags().isPresent()) {
+ Set tags = descriptor.getTags().get();
+ if (tags.isEmpty()) {
+ sb.append(PREFIX_TAG);
+ } else {
+ tags.forEach(s -> sb.append(PREFIX_TAG).append(s.tagName).append(" "));
+ }
+ }
+ return sb.toString();
+ }
+}
diff --git a/src/test/java/seedu/address/testutil/TestUtil.java b/src/test/java/seedu/address/testutil/TestUtil.java
index 896d103eb0b..b803ac3226b 100644
--- a/src/test/java/seedu/address/testutil/TestUtil.java
+++ b/src/test/java/seedu/address/testutil/TestUtil.java
@@ -7,7 +7,7 @@
import seedu.address.commons.core.index.Index;
import seedu.address.model.Model;
-import seedu.address.model.person.Person;
+import seedu.address.model.residence.Residence;
/**
* A utility class for test cases.
@@ -33,23 +33,23 @@ public static Path getFilePathInSandboxFolder(String fileName) {
}
/**
- * Returns the middle index of the person in the {@code model}'s person list.
+ * Returns the middle index of the residence in the {@code model}'s residence list.
*/
public static Index getMidIndex(Model model) {
- return Index.fromOneBased(model.getFilteredPersonList().size() / 2);
+ return Index.fromOneBased(model.getFilteredResidenceList().size() / 2);
}
/**
- * Returns the last index of the person in the {@code model}'s person list.
+ * Returns the last index of the residence in the {@code model}'s residence list.
*/
public static Index getLastIndex(Model model) {
- return Index.fromOneBased(model.getFilteredPersonList().size());
+ return Index.fromOneBased(model.getFilteredResidenceList().size());
}
/**
- * Returns the person in the {@code model}'s person list at {@code index}.
+ * Returns the residence in the {@code model}'s residence list at {@code index}.
*/
- public static Person getPerson(Model model, Index index) {
- return model.getFilteredPersonList().get(index.getZeroBased());
+ public static Residence getResidence(Model model, Index index) {
+ return model.getFilteredResidenceList().get(index.getZeroBased());
}
}
diff --git a/src/test/java/seedu/address/testutil/TypicalIndexes.java b/src/test/java/seedu/address/testutil/TypicalIndexes.java
index 1e613937657..a83f3c6eb9b 100644
--- a/src/test/java/seedu/address/testutil/TypicalIndexes.java
+++ b/src/test/java/seedu/address/testutil/TypicalIndexes.java
@@ -6,7 +6,16 @@
* A utility class containing a list of {@code Index} objects to be used in tests.
*/
public class TypicalIndexes {
- public static final Index INDEX_FIRST_PERSON = Index.fromOneBased(1);
- public static final Index INDEX_SECOND_PERSON = Index.fromOneBased(2);
- public static final Index INDEX_THIRD_PERSON = Index.fromOneBased(3);
+ public static final Index INDEX_FIRST_RESIDENCE = Index.fromOneBased(1);
+ public static final Index INDEX_SECOND_RESIDENCE = Index.fromOneBased(2);
+ public static final Index INDEX_THIRD_RESIDENCE = Index.fromOneBased(3);
+ public static final Index INDEX_FOURTH_RESIDENCE = Index.fromOneBased(4);
+ public static final Index INDEX_FIFTH_RESIDENCE = Index.fromOneBased(5);
+ public static final Index INDEX_SIXTH_RESIDENCE = Index.fromOneBased(6);
+ public static final Index INDEX_SEVENTH_RESIDENCE = Index.fromOneBased(7);
+
+ public static final Index INDEX_FIRST_BOOKING = Index.fromOneBased(1);
+ public static final Index INDEX_SECOND_BOOKING = Index.fromOneBased(2);
+
+
}
diff --git a/src/test/java/seedu/address/testutil/TypicalPersons.java b/src/test/java/seedu/address/testutil/TypicalPersons.java
index fec76fb7129..09d9fd10b5f 100644
--- a/src/test/java/seedu/address/testutil/TypicalPersons.java
+++ b/src/test/java/seedu/address/testutil/TypicalPersons.java
@@ -1,76 +1,77 @@
-package seedu.address.testutil;
-
-import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_FRIEND;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import seedu.address.model.AddressBook;
-import seedu.address.model.person.Person;
-
-/**
- * A utility class containing a list of {@code Person} objects to be used in tests.
- */
-public class TypicalPersons {
-
- public static final Person ALICE = new PersonBuilder().withName("Alice Pauline")
- .withAddress("123, Jurong West Ave 6, #08-111").withEmail("alice@example.com")
- .withPhone("94351253")
- .withTags("friends").build();
- public static final Person BENSON = new PersonBuilder().withName("Benson Meier")
- .withAddress("311, Clementi Ave 2, #02-25")
- .withEmail("johnd@example.com").withPhone("98765432")
- .withTags("owesMoney", "friends").build();
- public static final Person CARL = new PersonBuilder().withName("Carl Kurz").withPhone("95352563")
- .withEmail("heinz@example.com").withAddress("wall street").build();
- public static final Person DANIEL = new PersonBuilder().withName("Daniel Meier").withPhone("87652533")
- .withEmail("cornelia@example.com").withAddress("10th street").withTags("friends").build();
- public static final Person ELLE = new PersonBuilder().withName("Elle Meyer").withPhone("9482224")
- .withEmail("werner@example.com").withAddress("michegan ave").build();
- public static final Person FIONA = new PersonBuilder().withName("Fiona Kunz").withPhone("9482427")
- .withEmail("lydia@example.com").withAddress("little tokyo").build();
- public static final Person GEORGE = new PersonBuilder().withName("George Best").withPhone("9482442")
- .withEmail("anna@example.com").withAddress("4th street").build();
-
- // Manually added
- public static final Person HOON = new PersonBuilder().withName("Hoon Meier").withPhone("8482424")
- .withEmail("stefan@example.com").withAddress("little india").build();
- public static final Person IDA = new PersonBuilder().withName("Ida Mueller").withPhone("8482131")
- .withEmail("hans@example.com").withAddress("chicago ave").build();
-
- // Manually added - Person's details found in {@code CommandTestUtil}
- public static final Person AMY = new PersonBuilder().withName(VALID_NAME_AMY).withPhone(VALID_PHONE_AMY)
- .withEmail(VALID_EMAIL_AMY).withAddress(VALID_ADDRESS_AMY).withTags(VALID_TAG_FRIEND).build();
- public static final Person BOB = new PersonBuilder().withName(VALID_NAME_BOB).withPhone(VALID_PHONE_BOB)
- .withEmail(VALID_EMAIL_BOB).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND, VALID_TAG_FRIEND)
- .build();
-
- public static final String KEYWORD_MATCHING_MEIER = "Meier"; // A keyword that matches MEIER
-
- private TypicalPersons() {} // prevents instantiation
-
- /**
- * Returns an {@code AddressBook} with all the typical persons.
- */
- public static AddressBook getTypicalAddressBook() {
- AddressBook ab = new AddressBook();
- for (Person person : getTypicalPersons()) {
- ab.addPerson(person);
- }
- return ab;
- }
-
- public static List getTypicalPersons() {
- return new ArrayList<>(Arrays.asList(ALICE, BENSON, CARL, DANIEL, ELLE, FIONA, GEORGE));
- }
-}
+//package seedu.address.testutil;
+//
+//import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_AMY;
+//import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB;
+//import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_AMY;
+//import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_BOB;
+//import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_AMY;
+//import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_BOB;
+//import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_AMY;
+//import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB;
+//import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_FRIEND;
+//import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND;
+//
+//import java.util.ArrayList;
+//import java.util.Arrays;
+//import java.util.List;
+//
+//import seedu.address.model.ResidenceTracker;
+//import seedu.address.model.person.Person;
+//
+///**
+// * A utility class containing a list of {@code Person} objects to be used in tests.
+// */
+//public class TypicalPersons {
+//
+// public static final Person ALICE = new PersonBuilder().withName("Alice Pauline")
+// .withAddress("123, Jurong West Ave 6, #08-111").withEmail("alice@example.com")
+// .withPhone("94351253")
+// .withTags("friends").build();
+// public static final Person BENSON = new PersonBuilder().withName("Benson Meier")
+// .withAddress("311, Clementi Ave 2, #02-25")
+// .withEmail("johnd@example.com").withPhone("98765432")
+// .withTags("owesMoney", "friends").build();
+// public static final Person CARL = new PersonBuilder().withName("Carl Kurz").withPhone("95352563")
+// .withEmail("heinz@example.com").withAddress("wall street").build();
+// public static final Person DANIEL = new PersonBuilder().withName("Daniel Meier").withPhone("87652533")
+// .withEmail("cornelia@example.com").withAddress("10th street").withTags("friends").build();
+// public static final Person ELLE = new PersonBuilder().withName("Elle Meyer").withPhone("9482224")
+// .withEmail("werner@example.com").withAddress("michegan ave").build();
+// public static final Person FIONA = new PersonBuilder().withName("Fiona Kunz").withPhone("9482427")
+// .withEmail("lydia@example.com").withAddress("little tokyo").build();
+// public static final Person GEORGE = new PersonBuilder().withName("George Best").withPhone("9482442")
+// .withEmail("anna@example.com").withAddress("4th street").build();
+//
+// // Manually added
+// public static final Person HOON = new PersonBuilder().withName("Hoon Meier").withPhone("8482424")
+// .withEmail("stefan@example.com").withAddress("little india").build();
+// public static final Person IDA = new PersonBuilder().withName("Ida Mueller").withPhone("8482131")
+// .withEmail("hans@example.com").withAddress("chicago ave").build();
+//
+// // Manually added - Person's details found in {@code CommandTestUtil}
+// public static final Person AMY = new PersonBuilder().withName(VALID_NAME_AMY).withPhone(VALID_PHONE_AMY)
+// .withEmail(VALID_EMAIL_AMY).withAddress(VALID_ADDRESS_AMY).withTags(VALID_TAG_FRIEND).build();
+// public static final Person BOB = new PersonBuilder().withName(VALID_NAME_BOB).withPhone(VALID_PHONE_BOB)
+// .withEmail(VALID_EMAIL_BOB).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND, VALID_TAG_FRIEND)
+// .build();
+//
+// public static final String KEYWORD_MATCHING_MEIER = "Meier"; // A keyword that matches MEIER
+//
+// private TypicalPersons() {} // prevents instantiation
+//
+// /**
+// * Todo: person to keep in RT? currently no addPerson method
+// * Returns an {@code ResidenceTracker} with all the typical persons.
+// */
+// public static ResidenceTracker getTypicalAddressBook() {
+// ResidenceTracker ab = new ResidenceTracker();
+// for (Person person : getTypicalPersons()) {
+// // ab.addPerson(person);
+// }
+// return ab;
+// }
+//
+// public static List getTypicalPersons() {
+// return new ArrayList<>(Arrays.asList(ALICE, BENSON, CARL, DANIEL, ELLE, FIONA, GEORGE));
+// }
+//}
diff --git a/src/test/java/seedu/address/testutil/TypicalResidences.java b/src/test/java/seedu/address/testutil/TypicalResidences.java
new file mode 100644
index 00000000000..63cd6150a19
--- /dev/null
+++ b/src/test/java/seedu/address/testutil/TypicalResidences.java
@@ -0,0 +1,86 @@
+package seedu.address.testutil;
+
+import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_RESIDENCE1;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_RESIDENCE2;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_CLEAN_TAG;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_RESIDENCE1;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_RESIDENCE2;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_REPAIR;
+import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_RESERVED;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import seedu.address.model.ResidenceTracker;
+import seedu.address.model.booking.Booking;
+import seedu.address.model.booking.Phone;
+import seedu.address.model.booking.TenantName;
+import seedu.address.model.residence.Residence;
+
+/**
+ * A utility class containing a list of {@code Residence} objects to be used in tests.
+ */
+public class TypicalResidences {
+
+ public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("dd-MM-yyyy");
+
+ public static final Residence RESIDENCE_A = new ResidenceBuilder().withName("Amber Heights")
+ .withAddress("123, Jurong West Ave 6, #08-111").withBookingList().withTags("valuable").build();
+ public static final Residence RESIDENCE_B = new ResidenceBuilder().withName("Beverly Hills")
+ .withAddress("311, Clementi Ave 2, #02-25").withTags("repair", "popular")
+ .withBookingList(new ArrayList(Arrays.asList(
+ new Booking(new TenantName("Amy"), new Phone("91910606"),
+ LocalDate.parse("03-03-2020", DATE_TIME_FORMATTER),
+ LocalDate.parse("04-03-2020", DATE_TIME_FORMATTER)),
+ new Booking(new TenantName("Bob"), new Phone("90241134"),
+ LocalDate.parse("05-03-2020", DATE_TIME_FORMATTER),
+ LocalDate.parse("06-03-2020", DATE_TIME_FORMATTER))
+ ))).withCleanStatusTag("n").build();
+ public static final Residence RESIDENCE_C = new ResidenceBuilder().withName("Casuarina Apartment")
+ .withAddress("wall street").build();
+ public static final Residence RESIDENCE_D = new ResidenceBuilder().withName("Dover Condominium")
+ .withAddress("10th street").withTags("forFriends").build();
+ public static final Residence RESIDENCE_E = new ResidenceBuilder().withName("Emerald Hills")
+ .withAddress("michegan ave").build();
+ public static final Residence RESIDENCE_F = new ResidenceBuilder().withName("Floravale")
+ .withAddress("little tokyo").withCleanStatusTag("n").build();
+ public static final Residence RESIDENCE_G = new ResidenceBuilder().withName("Gem Residences")
+ .withAddress("4th street").build();
+
+ // Manually added
+ public static final Residence EXTRA_R1 = new ResidenceBuilder().withName("Hillview")
+ .withAddress("little india").build();
+ public static final Residence EXTRA_R2 = new ResidenceBuilder().withName("iSuites")
+ .withAddress("chicago ave").build();
+
+ // Manually added - Residence's details found in {@code CommandTestUtil}
+ public static final Residence RESIDENCE1 = new ResidenceBuilder().withName(VALID_NAME_RESIDENCE1)
+ .withAddress(VALID_ADDRESS_RESIDENCE1).withBookingList()
+ .withCleanStatusTag(VALID_CLEAN_TAG).withTags(VALID_TAG_RESERVED).build();
+ public static final Residence RESIDENCE2 = new ResidenceBuilder().withName(VALID_NAME_RESIDENCE2)
+ .withAddress(VALID_ADDRESS_RESIDENCE2).withBookingList()
+ .withCleanStatusTag(VALID_CLEAN_TAG).withTags(VALID_TAG_REPAIR, VALID_TAG_RESERVED).build();
+
+ public static final String KEYWORD_MATCHING_HILLS = "Hills"; // A keyword that matches MEIER
+
+ private TypicalResidences() {} // prevents instantiation
+
+ /**
+ * Returns an {@code ResidenceTracker} with all the typical residences.
+ */
+ public static ResidenceTracker getTypicalResidenceTracker() {
+ ResidenceTracker rt = new ResidenceTracker();
+ for (Residence residence : getTypicalResidences()) {
+ rt.addResidence(residence);
+ }
+ return rt;
+ }
+
+ public static List getTypicalResidences() {
+ return new ArrayList<>(Arrays.asList(RESIDENCE_A, RESIDENCE_B, RESIDENCE_C,
+ RESIDENCE_D, RESIDENCE_E, RESIDENCE_F, RESIDENCE_G));
+ }
+}