From 95652e76b3d707fbff49f24f2b2ffa15302516d1 Mon Sep 17 00:00:00 2001 From: Wu Di Date: Tue, 6 Mar 2018 02:09:37 +0800 Subject: [PATCH 01/66] updated url in DeveloperGuide.adoc and UserGuide.adoc It is to match our fork in Organisation CS2103JAN2018-F09-B1 --- docs/DeveloperGuide.adoc | 2 +- docs/UserGuide.adoc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/DeveloperGuide.adoc b/docs/DeveloperGuide.adoc index 1733af113b29..688b00653e80 100644 --- a/docs/DeveloperGuide.adoc +++ b/docs/DeveloperGuide.adoc @@ -10,7 +10,7 @@ ifdef::env-github[] :tip-caption: :bulb: :note-caption: :information_source: endif::[] -:repoURL: https://github.com/se-edu/addressbook-level4/tree/master +:repoURL: https://github.com/CS2103JAN2018-F09-B1/addressbook-level4/tree/master By: `Team SE-EDU`      Since: `Jun 2016`      Licence: `MIT` diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index 74248917e438..a28f372dc756 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -11,7 +11,7 @@ ifdef::env-github[] :tip-caption: :bulb: :note-caption: :information_source: endif::[] -:repoURL: https://github.com/se-edu/addressbook-level4 +:repoURL: https://github.com/CS2103JAN2018-F09-B1/addressbook-level4 By: `Team SE-EDU` Since: `Jun 2016` Licence: `MIT` From d110f90d4df8ad77d59959287fbfff17c076dafe Mon Sep 17 00:00:00 2001 From: alaru Date: Thu, 8 Mar 2018 13:24:40 +0800 Subject: [PATCH 02/66] Add backup method to AddressBookStorage Interface --- src/main/java/seedu/address/storage/AddressBookStorage.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/seedu/address/storage/AddressBookStorage.java b/src/main/java/seedu/address/storage/AddressBookStorage.java index cf5b527c063a..cba76a48324f 100644 --- a/src/main/java/seedu/address/storage/AddressBookStorage.java +++ b/src/main/java/seedu/address/storage/AddressBookStorage.java @@ -41,4 +41,10 @@ public interface AddressBookStorage { */ void saveAddressBook(ReadOnlyAddressBook addressBook, String filePath) throws IOException; + /** + * Saves the given (@link ReadOnlyAddressBook) to storage as a backup + * @param addressBook cannot be null + * @throws IOException if there is any issue writing to the temporary file + */ + void backupAddressBook(ReadOnlyAddressBook addressBook) throws IOException; } From 183640af9d93763ab3f70e895e36afcfd7a3cbcc Mon Sep 17 00:00:00 2001 From: alaru Date: Thu, 8 Mar 2018 13:25:36 +0800 Subject: [PATCH 03/66] Add backup methods to save the addressbook in a separate backup file --- src/main/java/seedu/address/storage/StorageManager.java | 4 ++++ .../java/seedu/address/storage/XmlAddressBookStorage.java | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/src/main/java/seedu/address/storage/StorageManager.java b/src/main/java/seedu/address/storage/StorageManager.java index 53967b391a5a..f7a29e8e2170 100644 --- a/src/main/java/seedu/address/storage/StorageManager.java +++ b/src/main/java/seedu/address/storage/StorageManager.java @@ -77,6 +77,10 @@ public void saveAddressBook(ReadOnlyAddressBook addressBook, String filePath) th addressBookStorage.saveAddressBook(addressBook, filePath); } + @Override + public void backupAddressBook(ReadOnlyAddressBook addressBook) throws IOException { + backupAddressBook(addressBook); + } @Override @Subscribe diff --git a/src/main/java/seedu/address/storage/XmlAddressBookStorage.java b/src/main/java/seedu/address/storage/XmlAddressBookStorage.java index c77ebe67435c..a45a8e3f9102 100644 --- a/src/main/java/seedu/address/storage/XmlAddressBookStorage.java +++ b/src/main/java/seedu/address/storage/XmlAddressBookStorage.java @@ -66,6 +66,11 @@ public void saveAddressBook(ReadOnlyAddressBook addressBook) throws IOException saveAddressBook(addressBook, filePath); } + @Override + public void backupAddressBook(ReadOnlyAddressBook addressBook) throws IOException { + saveAddressBook(addressBook, (filePath + ".bak")); + } + /** * Similar to {@link #saveAddressBook(ReadOnlyAddressBook)} * @param filePath location of the data. Cannot be null From 39c7ae35b56ddffed2e67437cf07a5dafabb79d0 Mon Sep 17 00:00:00 2001 From: Wu Di Date: Thu, 8 Mar 2018 18:44:12 +0800 Subject: [PATCH 04/66] update on the repo name from addressbook level 4 to main --- docs/DeveloperGuide.adoc | 2 +- docs/UserGuide.adoc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/DeveloperGuide.adoc b/docs/DeveloperGuide.adoc index 688b00653e80..071bc4056c1f 100644 --- a/docs/DeveloperGuide.adoc +++ b/docs/DeveloperGuide.adoc @@ -10,7 +10,7 @@ ifdef::env-github[] :tip-caption: :bulb: :note-caption: :information_source: endif::[] -:repoURL: https://github.com/CS2103JAN2018-F09-B1/addressbook-level4/tree/master +:repoURL: https://github.com/CS2103JAN2018-F09-B1/main/tree/master By: `Team SE-EDU`      Since: `Jun 2016`      Licence: `MIT` diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index a28f372dc756..6392aec49b3e 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -11,7 +11,7 @@ ifdef::env-github[] :tip-caption: :bulb: :note-caption: :information_source: endif::[] -:repoURL: https://github.com/CS2103JAN2018-F09-B1/addressbook-level4 +:repoURL: https://github.com/CS2103JAN2018-F09-B1/main By: `Team SE-EDU` Since: `Jun 2016` Licence: `MIT` From 3ee33e44ca0b21a80c6eab5c31bb14971d9b0df5 Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 8 Mar 2018 18:46:23 +0800 Subject: [PATCH 05/66] Change tag colours to blue (test not edited yet) Add more words and definitions to DGs glossary --- docs/DeveloperGuide.adoc | 37 +++++++++++++++++++ .../java/seedu/address/ui/PersonCard.java | 17 ++++++++- src/main/resources/view/DarkTheme.css | 7 +++- 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/docs/DeveloperGuide.adoc b/docs/DeveloperGuide.adoc index 1733af113b29..0c701aa77b76 100644 --- a/docs/DeveloperGuide.adoc +++ b/docs/DeveloperGuide.adoc @@ -864,6 +864,43 @@ Windows, Linux, Unix, OS-X [[private-contact-detail]] Private contact detail:: A contact detail that is not meant to be shared with others +[[ui]] User interface:: +The visible interface that the user will be seeing when using the application + +[[logic]] Logic:: +The set of commands that can be executed by the application + +[[model]] Model:: +The internal memory used when application is running + +[[storage]] Storage:: +The set of instructions to store specific states and data of the application when application is not running so that it +can be loaded back into the application when application is started again. + +[[feature]] Feature:: +A specific function of the program + +[[parser]] Parser:: +A converting function or class that takes in raw input and separates it into its usable components for other methods + +[[tasks]] Tasks:: +A command to be executed + +[[deadline]] Deadline:: +The date for which certain tasks are due to be done + +[[tags]] Tags:: +Keywords tied to categories og people + +[[to-do-list]]To-do list:: +A list of things to do + +[[import]] Import:: +Bring into the application from an external source + +User - +
Developer - + [appendix] == Product Survey diff --git a/src/main/java/seedu/address/ui/PersonCard.java b/src/main/java/seedu/address/ui/PersonCard.java index f6727ea83abd..2e337d92c971 100644 --- a/src/main/java/seedu/address/ui/PersonCard.java +++ b/src/main/java/seedu/address/ui/PersonCard.java @@ -13,6 +13,9 @@ public class PersonCard extends UiPart { private static final String FXML = "PersonListCard.fxml"; + //this is the colours that can be used to colour code labels + private static final String[] TAG_COLOUR_STYLES = + { "blue" }; /** * Note: Certain keywords such as "location" and "resources" are reserved keywords in JavaFX. @@ -47,9 +50,21 @@ public PersonCard(Person person, int displayedIndex) { phone.setText(person.getPhone().value); address.setText(person.getAddress().value); email.setText(person.getEmail().value); - person.getTags().forEach(tag -> tags.getChildren().add(new Label(tag.tagName))); + person.getTags().forEach(tag -> { Label tagLabel = new Label(tag.tagName); + tagLabel.getStyleClass().add(TAG_COLOUR_STYLES[0]); + tags.getChildren().add(tagLabel); }); } + /** to be implemented with more tag colours + * + */ + +// private String getTagColourStyleFor(String tagName) { +// +// +// return TAG_COLOUR_STYLES[Math.abs(tagName.hashCode()) % TAG_COLOUR_STYLES.length]; +// } + @Override public boolean equals(Object other) { // short circuit if same object diff --git a/src/main/resources/view/DarkTheme.css b/src/main/resources/view/DarkTheme.css index d06336391cca..36e3459e36fb 100644 --- a/src/main/resources/view/DarkTheme.css +++ b/src/main/resources/view/DarkTheme.css @@ -342,10 +342,13 @@ } #tags .label { - -fx-text-fill: white; - -fx-background-color: #3e7b91; -fx-padding: 1 3 1 3; -fx-border-radius: 2; -fx-background-radius: 2; -fx-font-size: 11; } + +#tags .blue { + -fx-text-fill: white; + -fx-background-color: blue; +} \ No newline at end of file From 81fe21ed10912873380e927ce05abad789718704 Mon Sep 17 00:00:00 2001 From: "DESKTOP-QB7JG7G\\akiya" Date: Thu, 8 Mar 2018 20:44:28 +0800 Subject: [PATCH 06/66] add listTags() function in model, update developer's guide (user profile, value proposition and user stories) --- docs/DeveloperGuide.adoc | 41 +++++++++++++++---- .../java/seedu/address/model/AddressBook.java | 17 ++++++++ 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/docs/DeveloperGuide.adoc b/docs/DeveloperGuide.adoc index 688b00653e80..0ceaef82684e 100644 --- a/docs/DeveloperGuide.adoc +++ b/docs/DeveloperGuide.adoc @@ -780,15 +780,16 @@ See this https://github.com/se-edu/addressbook-level4/pull/599[PR] for the step- [appendix] == Product Scope -*Target user profile*: +*Target user profile*: Tech-Savvy University Teachers/Tutors -* has a need to manage a significant number of contacts +* have the need to manage a significant number of contacts * prefer desktop apps over other types * can type fast -* prefers typing over mouse input -* is reasonably comfortable using CLI apps +* prefer typing over mouse input +* are reasonably comfortable using CLI apps -*Value proposition*: manage contacts faster than a typical mouse/GUI driven app +*Value proposition*: manage contacts faster than a typical mouse/GUI driven app, includes to-do + list features (with prioritization, etc.) and scheduling (with calendar and reminders) [appendix] == User Stories @@ -800,15 +801,41 @@ Priorities: High (must have) - `* * \*`, Medium (nice to have) - `* \*`, Low (un |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 | +|`* * *` |new user |get error messages/prompts |better adapt to commands to use them properly + +|`* * *` |user |add a new person |better manage all my contacts at one go |`* * *` |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 |find a person by matriculation number/email |identify people easily + +|`* * *` |user |sort contacts based on name/address/email/tags |work with specific groups of people + +|`* * *` |user |assign a to-do list to each person in address book |know what I need to do for them + +|`* * *` |user |add individual items to the to-do lists |update additional tasks + +|`* * *` |user |remove entire to-do lists or items in it |remove completed tasks + +|`* * *` |user |add events to the schedule |better manage work/students + +|`* * *` |user |add a deadline to tasks/items |know what needs to be done and by when + +|`* * *` |user |prioritize tasks/items |efficiently get tasks/items done on time + |`* *` |user |hide <> by default |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 +|`* *` |user |import students/people from a text file |it is easier to enter large numbers of people + +|`* *` |user |add profile pictures |know who the people I am working with are + +|`* *` |user |mass email students/people based on a tag |easily email/inform a class of students of announcements + +|`* *` |user |set reminders for certain events |have an email sent to me before the actual event so that I don't forget + +|`*` |user with many persons in the address book |combine groups/tags |better work with people who have similar interests/work |======================================================================= _{More to be added}_ diff --git a/src/main/java/seedu/address/model/AddressBook.java b/src/main/java/seedu/address/model/AddressBook.java index f8d0260de159..b0bc3a7639d1 100644 --- a/src/main/java/seedu/address/model/AddressBook.java +++ b/src/main/java/seedu/address/model/AddressBook.java @@ -4,6 +4,7 @@ import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Objects; @@ -59,6 +60,22 @@ public void setTags(Set tags) { this.tags.setTags(tags); } + /** + * Lists all the current tags that are used. + * @return a continuous String of tags in UniqueTagList separated by a nextline between each tag. + */ + public String listTags() { + String tagString = ""; + + Iterator it = tags.iterator(); + while(it.hasNext()){ + Tag nextTag = (Tag)it.next(); + tagString += (nextTag.toString() + "\n"); + } + + return tagString; + } + /** * Resets the existing data of this {@code AddressBook} with {@code newData}. */ From e80fd0865f0a2bb9ade796d97cc332d7550ca1aa Mon Sep 17 00:00:00 2001 From: Wu Di Date: Thu, 8 Mar 2018 20:45:51 +0800 Subject: [PATCH 07/66] update some NFRs on DG --- docs/DeveloperGuide.adoc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/DeveloperGuide.adoc b/docs/DeveloperGuide.adoc index 071bc4056c1f..bbdaa5d04ec3 100644 --- a/docs/DeveloperGuide.adoc +++ b/docs/DeveloperGuide.adoc @@ -852,6 +852,11 @@ _{More to be added}_ . Should work on any <> as long as it has Java `1.8.0_60` or higher installed. . Should be able to hold up to 1000 persons without a noticeable sluggishness in performance for typical usage. . 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. +. Should be intuitive or easily understood after reading the User Guide. +. Should not exceed the size of 100 MB. +. Should respond to any requests within 3 seconds. +. Should not modify and copy any user's personal data on the computer. +. A User's data should be password protected. _{More to be added}_ From ad37bebb8a67562462f6dbac313faad2efbbbcb4 Mon Sep 17 00:00:00 2001 From: Ellery Chia Date: Thu, 8 Mar 2018 21:21:19 +0800 Subject: [PATCH 08/66] Put overloaded methods together --- .../seedu/address/storage/XmlAddressBookStorage.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/seedu/address/storage/XmlAddressBookStorage.java b/src/main/java/seedu/address/storage/XmlAddressBookStorage.java index a45a8e3f9102..79ca2b80202d 100644 --- a/src/main/java/seedu/address/storage/XmlAddressBookStorage.java +++ b/src/main/java/seedu/address/storage/XmlAddressBookStorage.java @@ -66,11 +66,6 @@ public void saveAddressBook(ReadOnlyAddressBook addressBook) throws IOException saveAddressBook(addressBook, filePath); } - @Override - public void backupAddressBook(ReadOnlyAddressBook addressBook) throws IOException { - saveAddressBook(addressBook, (filePath + ".bak")); - } - /** * Similar to {@link #saveAddressBook(ReadOnlyAddressBook)} * @param filePath location of the data. Cannot be null @@ -84,4 +79,9 @@ public void saveAddressBook(ReadOnlyAddressBook addressBook, String filePath) th XmlFileStorage.saveDataToFile(file, new XmlSerializableAddressBook(addressBook)); } + @Override + public void backupAddressBook(ReadOnlyAddressBook addressBook) throws IOException { + saveAddressBook(addressBook, (filePath + ".bak")); + } + } From 2ad122f0ad7163f42d0d98c2e7393ff2b72085f6 Mon Sep 17 00:00:00 2001 From: Wu Di Date: Thu, 8 Mar 2018 21:38:53 +0800 Subject: [PATCH 09/66] update on the coverall badge --- README.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.adoc b/README.adoc index 03eff3a4d191..66132f39da6f 100644 --- a/README.adoc +++ b/README.adoc @@ -1,9 +1,9 @@ = Address Book (Level 4) ifdef::env-github,env-browser[:relfileprefix: docs/] -https://travis-ci.org/se-edu/addressbook-level4[image:https://travis-ci.org/se-edu/addressbook-level4.svg?branch=master[Build Status]] +https://travis-ci.org/CS2103JAN2018-F09-B1/main[image:https://travis-ci.org/CS2103JAN2018-F09-B1/main.svg?branch=master[Build Status]] https://ci.appveyor.com/project/damithc/addressbook-level4[image:https://ci.appveyor.com/api/projects/status/3boko2x2vr5cc3w2?svg=true[Build status]] -https://coveralls.io/github/se-edu/addressbook-level4?branch=master[image:https://coveralls.io/repos/github/se-edu/addressbook-level4/badge.svg?branch=master[Coverage Status]] +https://coveralls.io/github/CS2103JAN2018-F09-B1/main?branch=master[image:https://coveralls.io/repos/github/CS2103JAN2018-F09-B1/main/badge.svg?branch=master[Coverage Status]] https://www.codacy.com/app/damith/addressbook-level4?utm_source=github.com&utm_medium=referral&utm_content=se-edu/addressbook-level4&utm_campaign=Badge_Grade[image:https://api.codacy.com/project/badge/Grade/fc0b7775cf7f4fdeaf08776f3d8e364a[Codacy Badge]] https://gitter.im/se-edu/Lobby[image:https://badges.gitter.im/se-edu/Lobby.svg[Gitter chat]] From 3d12ff8cc7f0104ccf2522ec965f6835433f1304 Mon Sep 17 00:00:00 2001 From: alaru Date: Thu, 8 Mar 2018 21:55:00 +0800 Subject: [PATCH 10/66] Add some Use Cases to DeveloperGuide.adoc --- docs/DeveloperGuide.adoc | 88 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 83 insertions(+), 5 deletions(-) diff --git a/docs/DeveloperGuide.adoc b/docs/DeveloperGuide.adoc index 688b00653e80..b297e69fef07 100644 --- a/docs/DeveloperGuide.adoc +++ b/docs/DeveloperGuide.adoc @@ -819,14 +819,14 @@ _{More to be added}_ (For all use cases below, the *System* is the `AddressBook` and the *Actor* is the `user`, unless specified otherwise) [discrete] -=== Use case: Delete person +=== Use case: Delete student *MSS* -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 +1. User requests to list students +2. AddressBook shows a list of students +3. User requests to delete a specific student in the list +4. AddressBook deletes the student and all related entries (if any) + Use case ends. @@ -844,6 +844,84 @@ Use case ends. + Use case resumes at step 2. +[discrete] +=== Use case: Find a student by name + +*MSS* + +1. User requests to find a student by name +2. AddressBook shows a list of students that match the search query ++ +Use case ends. + +*Extensions* + +[none] +* 2a. The list is empty. ++ +Use case ends. + +[discrete] +=== Use case: Add event to schedule + +*MSS* + +1. User requests to add an event to a day +2. AddressBook shows the current schedule for the day +3. User requests to add the event to a timeslot for that day +4. AddressBook confirms the addition to the timeslot ++ +Use case ends. + +*Extensions* + +[none] +* 2a. The schedule for the day is full. ++ +[none] +** 2a1. AddressBook will display an error message. ++ +Use case ends. +* 3a. User tries to add it to a non-empty timeslot +[none] +** 3a1. AddressBook will display an error message. ++ +Use case resumes at step 2. + +[discrete] +=== Use case: Edit lesson for a student + +*MSS* + +1. User requests to edit lesson for a student. +2. AddressBook shows the current lessons for a student in a list. +3. User enters the index of lesson to edit. +4. AddressBook prompts the user to enter the new entry. +5. User inputs the new entry. +6. AddressBook confirms with user on the edit. +7. User confirms. +8. AddressBook replaces the old entry with the new entry. ++ +Use case ends. + +*Extensions* + +[none] +* 2a. There are no lessons for the student. ++ +Use case ends. +* 3a. User enters an invalid index +[none] +** 3a1. AddressBook will display an error message. ++ +Use case resumes at step 3. + +* 5a. User does not enter a valid lesson entry +[none] +** 5a1. AddressBook will display an error message. ++ +User case resumes at step 5. + _{More to be added}_ [appendix] From 5c24d03cf5e9d0ff47376abcbd7554780efeabb9 Mon Sep 17 00:00:00 2001 From: Wu Di Date: Fri, 9 Mar 2018 01:00:50 +0800 Subject: [PATCH 11/66] implement alias for commands -- add, clear, delete, edit, find, help, history, list, redo, undo and select --- docs/UserGuide.adoc | 12 +++ .../address/logic/commands/AddCommand.java | 2 + .../address/logic/commands/ClearCommand.java | 1 + .../address/logic/commands/DeleteCommand.java | 2 + .../address/logic/commands/EditCommand.java | 1 + .../address/logic/commands/FindCommand.java | 1 + .../address/logic/commands/HelpCommand.java | 1 + .../logic/commands/HistoryCommand.java | 1 + .../address/logic/commands/ListCommand.java | 1 + .../address/logic/commands/RedoCommand.java | 1 + .../address/logic/commands/SelectCommand.java | 1 + .../address/logic/commands/UndoCommand.java | 1 + .../logic/parser/AddressBookParser.java | 13 +++ .../logic/parser/AddressBookParserTest.java | 81 +++++++++++++++++++ 14 files changed, 119 insertions(+) diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index 6392aec49b3e..39f627797895 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -50,6 +50,7 @@ e.g. typing *`help`* and pressing kbd:[Enter] will open the help window. ==== *Command Format* +* There are some equivalent shortcut commands known as alias with fewer alphabetic letters or a sign e.g. to add a person to the addressbook, you can type 'add n/John Doe', 'a n/John Doe' or '+ n/John Doe' * 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`. * 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`. * Items with `…`​ after them can be used multiple times including zero times e.g. `[t/TAG]...` can be used as `{nbsp}` (i.e. 0 times), `t/friend`, `t/friend t/family` etc. @@ -58,11 +59,13 @@ e.g. typing *`help`* and pressing kbd:[Enter] will open the help window. === Viewing help : `help` +Alias: `?` + Format: `help` === Adding a person: `add` Adds a person to the address book + +Alias: `a` and `+` + Format: `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]...` [TIP] @@ -76,11 +79,13 @@ Examples: === Listing all persons : `list` Shows a list of all persons in the address book. + +Alias: `ls` + Format: `list` === Editing a person : `edit` Edits an existing person in the address book. + +Alias: `e` + Format: `edit INDEX [n/NAME] [p/PHONE] [e/EMAIL] [a/ADDRESS] [t/TAG]...` **** @@ -101,6 +106,7 @@ Edits the name of the 2nd person to be `Betsy Crower` and clears all existing ta === Locating persons by name: `find` Finds persons whose names contain any of the given keywords. + +Alias: `f` + Format: `find KEYWORD [MORE_KEYWORDS]` **** @@ -121,6 +127,7 @@ Returns any person having names `Betsy`, `Tim`, or `John` === Deleting a person : `delete` Deletes the specified person from the address book. + +Alias: `d` and `-` + Format: `delete INDEX` **** @@ -141,6 +148,7 @@ Deletes the 1st person in the results of the `find` command. === Selecting a person : `select` Selects the person identified by the index number used in the last person listing. + +Alias: `s` + Format: `select INDEX` **** @@ -161,6 +169,7 @@ Selects the 1st person in the results of the `find` command. === Listing entered commands : `history` Lists all the commands that you have entered in reverse chronological order. + +Alias: `h` + Format: `history` [NOTE] @@ -172,6 +181,7 @@ Pressing the kbd:[↑] and kbd:[↓] arrows will display the previous and === Undoing previous command : `undo` Restores the address book to the state before the previous _undoable_ command was executed. + +Alias: `u` + Format: `undo` [NOTE] @@ -198,6 +208,7 @@ The `undo` command fails as there are no undoable commands executed previously. === Redoing the previously undone command : `redo` Reverses the most recent `undo` command. + +Alias: `r` + Format: `redo` Examples: @@ -221,6 +232,7 @@ The `redo` command fails as there are no `undo` commands executed previously. === Clearing all entries : `clear` Clears all entries from the address book. + +Alias: `c` + Format: `clear` === Exiting the program : `exit` diff --git a/src/main/java/seedu/address/logic/commands/AddCommand.java b/src/main/java/seedu/address/logic/commands/AddCommand.java index c334710c0ea3..295f424e74c9 100644 --- a/src/main/java/seedu/address/logic/commands/AddCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddCommand.java @@ -17,6 +17,8 @@ public class AddCommand extends UndoableCommand { public static final String COMMAND_WORD = "add"; + public static final String COMMAND_ALIAS = "a"; + public static final String COMMAND_SIGN = "+"; public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a person to the address book. " + "Parameters: " diff --git a/src/main/java/seedu/address/logic/commands/ClearCommand.java b/src/main/java/seedu/address/logic/commands/ClearCommand.java index ceeb7ba913c6..6d04efaf3295 100644 --- a/src/main/java/seedu/address/logic/commands/ClearCommand.java +++ b/src/main/java/seedu/address/logic/commands/ClearCommand.java @@ -10,6 +10,7 @@ public class ClearCommand extends UndoableCommand { public static final String COMMAND_WORD = "clear"; + public static final String COMMAND_ALIAS = "c"; public static final String MESSAGE_SUCCESS = "Address book has been cleared!"; diff --git a/src/main/java/seedu/address/logic/commands/DeleteCommand.java b/src/main/java/seedu/address/logic/commands/DeleteCommand.java index b539d240001a..cb66589a0934 100644 --- a/src/main/java/seedu/address/logic/commands/DeleteCommand.java +++ b/src/main/java/seedu/address/logic/commands/DeleteCommand.java @@ -17,6 +17,8 @@ public class DeleteCommand extends UndoableCommand { public static final String COMMAND_WORD = "delete"; + public static final String COMMAND_ALIAS = "d"; + public static final String COMMAND_SIGN = "-"; public static final String MESSAGE_USAGE = COMMAND_WORD + ": Deletes the person identified by the index number used in the last person listing.\n" diff --git a/src/main/java/seedu/address/logic/commands/EditCommand.java b/src/main/java/seedu/address/logic/commands/EditCommand.java index e6c3a3e034bc..3021c951a5b1 100644 --- a/src/main/java/seedu/address/logic/commands/EditCommand.java +++ b/src/main/java/seedu/address/logic/commands/EditCommand.java @@ -34,6 +34,7 @@ public class EditCommand extends UndoableCommand { public static final String COMMAND_WORD = "edit"; + public static final String COMMAND_ALIAS = "e"; public static final String MESSAGE_USAGE = COMMAND_WORD + ": Edits the details of the person identified " + "by the index number used in the last person listing. " diff --git a/src/main/java/seedu/address/logic/commands/FindCommand.java b/src/main/java/seedu/address/logic/commands/FindCommand.java index b1e671f633d2..a73078ed6ea3 100644 --- a/src/main/java/seedu/address/logic/commands/FindCommand.java +++ b/src/main/java/seedu/address/logic/commands/FindCommand.java @@ -9,6 +9,7 @@ public class FindCommand extends Command { public static final String COMMAND_WORD = "find"; + public static final String COMMAND_ALIAS = "f"; public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all persons whose names contain any of " + "the specified keywords (case-sensitive) and displays them as a list with index numbers.\n" diff --git a/src/main/java/seedu/address/logic/commands/HelpCommand.java b/src/main/java/seedu/address/logic/commands/HelpCommand.java index 10febf6d9136..fa2f5603cd91 100644 --- a/src/main/java/seedu/address/logic/commands/HelpCommand.java +++ b/src/main/java/seedu/address/logic/commands/HelpCommand.java @@ -9,6 +9,7 @@ public class HelpCommand extends Command { public static final String COMMAND_WORD = "help"; + public static final String COMMAND_SIGN = "?"; public static final String MESSAGE_USAGE = COMMAND_WORD + ": Shows program usage instructions.\n" + "Example: " + COMMAND_WORD; diff --git a/src/main/java/seedu/address/logic/commands/HistoryCommand.java b/src/main/java/seedu/address/logic/commands/HistoryCommand.java index f87abee5511d..a3a8f11563d0 100644 --- a/src/main/java/seedu/address/logic/commands/HistoryCommand.java +++ b/src/main/java/seedu/address/logic/commands/HistoryCommand.java @@ -15,6 +15,7 @@ public class HistoryCommand extends Command { public static final String COMMAND_WORD = "history"; + public static final String COMMAND_ALIAS = "h"; public static final String MESSAGE_SUCCESS = "Entered commands (from most recent to earliest):\n%1$s"; public static final String MESSAGE_NO_HISTORY = "You have not yet entered any commands."; diff --git a/src/main/java/seedu/address/logic/commands/ListCommand.java b/src/main/java/seedu/address/logic/commands/ListCommand.java index 7b6463780824..440f944d3a07 100644 --- a/src/main/java/seedu/address/logic/commands/ListCommand.java +++ b/src/main/java/seedu/address/logic/commands/ListCommand.java @@ -8,6 +8,7 @@ public class ListCommand extends Command { public static final String COMMAND_WORD = "list"; + public static final String COMMAND_ALIAS = "ls"; public static final String MESSAGE_SUCCESS = "Listed all persons"; diff --git a/src/main/java/seedu/address/logic/commands/RedoCommand.java b/src/main/java/seedu/address/logic/commands/RedoCommand.java index 7b99d0f372fc..311c95c1a1f2 100644 --- a/src/main/java/seedu/address/logic/commands/RedoCommand.java +++ b/src/main/java/seedu/address/logic/commands/RedoCommand.java @@ -13,6 +13,7 @@ public class RedoCommand extends Command { public static final String COMMAND_WORD = "redo"; + public static final String COMMAND_ALIAS = "r"; public static final String MESSAGE_SUCCESS = "Redo success!"; public static final String MESSAGE_FAILURE = "No more commands to redo!"; diff --git a/src/main/java/seedu/address/logic/commands/SelectCommand.java b/src/main/java/seedu/address/logic/commands/SelectCommand.java index 9e3840a9dde6..0bc2e3e21485 100644 --- a/src/main/java/seedu/address/logic/commands/SelectCommand.java +++ b/src/main/java/seedu/address/logic/commands/SelectCommand.java @@ -15,6 +15,7 @@ public class SelectCommand extends Command { public static final String COMMAND_WORD = "select"; + public static final String COMMAND_ALIAS = "s"; public static final String MESSAGE_USAGE = COMMAND_WORD + ": Selects the person identified by the index number used in the last person listing.\n" diff --git a/src/main/java/seedu/address/logic/commands/UndoCommand.java b/src/main/java/seedu/address/logic/commands/UndoCommand.java index 1f3dcea8bbaa..7d62dcc53d38 100644 --- a/src/main/java/seedu/address/logic/commands/UndoCommand.java +++ b/src/main/java/seedu/address/logic/commands/UndoCommand.java @@ -13,6 +13,7 @@ public class UndoCommand extends Command { public static final String COMMAND_WORD = "undo"; + public static final String COMMAND_ALIAS = "u"; public static final String MESSAGE_SUCCESS = "Undo success!"; public static final String MESSAGE_FAILURE = "No more commands to undo!"; diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index b7d57f5db86a..abed25f26008 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -49,39 +49,52 @@ public Command parseCommand(String userInput) throws ParseException { switch (commandWord) { case AddCommand.COMMAND_WORD: + case AddCommand.COMMAND_ALIAS: + case AddCommand.COMMAND_SIGN: return new AddCommandParser().parse(arguments); case EditCommand.COMMAND_WORD: + case EditCommand.COMMAND_ALIAS: return new EditCommandParser().parse(arguments); case SelectCommand.COMMAND_WORD: + case SelectCommand.COMMAND_ALIAS: return new SelectCommandParser().parse(arguments); case DeleteCommand.COMMAND_WORD: + case DeleteCommand.COMMAND_ALIAS: + case DeleteCommand.COMMAND_SIGN: return new DeleteCommandParser().parse(arguments); case ClearCommand.COMMAND_WORD: + case ClearCommand.COMMAND_ALIAS: return new ClearCommand(); case FindCommand.COMMAND_WORD: + case FindCommand.COMMAND_ALIAS: return new FindCommandParser().parse(arguments); case ListCommand.COMMAND_WORD: + case ListCommand.COMMAND_ALIAS: return new ListCommand(); case HistoryCommand.COMMAND_WORD: + case HistoryCommand.COMMAND_ALIAS: return new HistoryCommand(); case ExitCommand.COMMAND_WORD: return new ExitCommand(); case HelpCommand.COMMAND_WORD: + case HelpCommand.COMMAND_SIGN: return new HelpCommand(); case UndoCommand.COMMAND_WORD: + case UndoCommand.COMMAND_ALIAS: return new UndoCommand(); case RedoCommand.COMMAND_WORD: + case RedoCommand.COMMAND_ALIAS: return new RedoCommand(); default: diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index 7466da232666..1d3888135e49 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -48,12 +48,34 @@ public void parseCommand_add() throws Exception { assertEquals(new AddCommand(person), command); } + @Test + public void parseCommand_add_alias() throws Exception { + Person person = new PersonBuilder().build(); + AddCommand command = (AddCommand) parser.parseCommand(AddCommand.COMMAND_ALIAS + " " + + PersonUtil.getPersonDetails(person)); + assertEquals(new AddCommand(person), command); + } + + @Test + public void parseCommand_add_sign() throws Exception { + Person person = new PersonBuilder().build(); + AddCommand command = (AddCommand) parser.parseCommand(AddCommand.COMMAND_SIGN + " " + + PersonUtil.getPersonDetails(person)); + assertEquals(new AddCommand(person), command); + } + @Test public void parseCommand_clear() throws Exception { assertTrue(parser.parseCommand(ClearCommand.COMMAND_WORD) instanceof ClearCommand); assertTrue(parser.parseCommand(ClearCommand.COMMAND_WORD + " 3") instanceof ClearCommand); } + @Test + public void parseCommand_clear_alias() throws Exception { + assertTrue(parser.parseCommand(ClearCommand.COMMAND_ALIAS) instanceof ClearCommand); + assertTrue(parser.parseCommand(ClearCommand.COMMAND_ALIAS + " 3") instanceof ClearCommand); + } + @Test public void parseCommand_delete() throws Exception { DeleteCommand command = (DeleteCommand) parser.parseCommand( @@ -61,6 +83,20 @@ public void parseCommand_delete() throws Exception { assertEquals(new DeleteCommand(INDEX_FIRST_PERSON), command); } + @Test + public void parseCommand_delete_alias() throws Exception { + DeleteCommand command = (DeleteCommand) parser.parseCommand( + DeleteCommand.COMMAND_ALIAS + " " + INDEX_FIRST_PERSON.getOneBased()); + assertEquals(new DeleteCommand(INDEX_FIRST_PERSON), command); + } + + @Test + public void parseCommand_delete_sign() throws Exception { + DeleteCommand command = (DeleteCommand) parser.parseCommand( + DeleteCommand.COMMAND_SIGN + " " + INDEX_FIRST_PERSON.getOneBased()); + assertEquals(new DeleteCommand(INDEX_FIRST_PERSON), command); + } + @Test public void parseCommand_edit() throws Exception { Person person = new PersonBuilder().build(); @@ -84,12 +120,26 @@ public void parseCommand_find() throws Exception { assertEquals(new FindCommand(new NameContainsKeywordsPredicate(keywords)), command); } + @Test + public void parseCommand_find_alias() throws Exception { + List keywords = Arrays.asList("foo", "bar", "baz"); + FindCommand command = (FindCommand) parser.parseCommand( + FindCommand.COMMAND_ALIAS + " " + keywords.stream().collect(Collectors.joining(" "))); + assertEquals(new FindCommand(new NameContainsKeywordsPredicate(keywords)), command); + } + @Test public void parseCommand_help() throws Exception { assertTrue(parser.parseCommand(HelpCommand.COMMAND_WORD) instanceof HelpCommand); assertTrue(parser.parseCommand(HelpCommand.COMMAND_WORD + " 3") instanceof HelpCommand); } + @Test + public void parseCommand_help_sign() throws Exception { + assertTrue(parser.parseCommand(HelpCommand.COMMAND_SIGN) instanceof HelpCommand); + assertTrue(parser.parseCommand(HelpCommand.COMMAND_SIGN + " 3") instanceof HelpCommand); + } + @Test public void parseCommand_history() throws Exception { assertTrue(parser.parseCommand(HistoryCommand.COMMAND_WORD) instanceof HistoryCommand); @@ -103,12 +153,24 @@ public void parseCommand_history() throws Exception { } } + @Test + public void parseCommand_history_alias() throws Exception { + assertTrue(parser.parseCommand(HistoryCommand.COMMAND_ALIAS) instanceof HistoryCommand); + assertTrue(parser.parseCommand(HistoryCommand.COMMAND_ALIAS + " 3") instanceof HistoryCommand); + } + @Test public void parseCommand_list() throws Exception { assertTrue(parser.parseCommand(ListCommand.COMMAND_WORD) instanceof ListCommand); assertTrue(parser.parseCommand(ListCommand.COMMAND_WORD + " 3") instanceof ListCommand); } + @Test + public void parseCommand_list_alias() throws Exception { + assertTrue(parser.parseCommand(ListCommand.COMMAND_ALIAS) instanceof ListCommand); + assertTrue(parser.parseCommand(ListCommand.COMMAND_ALIAS + " 3") instanceof ListCommand); + } + @Test public void parseCommand_select() throws Exception { SelectCommand command = (SelectCommand) parser.parseCommand( @@ -116,18 +178,37 @@ public void parseCommand_select() throws Exception { assertEquals(new SelectCommand(INDEX_FIRST_PERSON), command); } + @Test + public void parseCommand_select_alias() throws Exception { + SelectCommand command = (SelectCommand) parser.parseCommand( + SelectCommand.COMMAND_ALIAS + " " + INDEX_FIRST_PERSON.getOneBased()); + assertEquals(new SelectCommand(INDEX_FIRST_PERSON), command); + } + @Test public void parseCommand_redoCommandWord_returnsRedoCommand() throws Exception { assertTrue(parser.parseCommand(RedoCommand.COMMAND_WORD) instanceof RedoCommand); assertTrue(parser.parseCommand("redo 1") instanceof RedoCommand); } + @Test + public void parseCommand_redoCommandAlias_returnsRedoCommand() throws Exception { + assertTrue(parser.parseCommand(RedoCommand.COMMAND_ALIAS) instanceof RedoCommand); + assertTrue(parser.parseCommand(RedoCommand.COMMAND_ALIAS + " 1") instanceof RedoCommand); + } + @Test public void parseCommand_undoCommandWord_returnsUndoCommand() throws Exception { assertTrue(parser.parseCommand(UndoCommand.COMMAND_WORD) instanceof UndoCommand); assertTrue(parser.parseCommand("undo 3") instanceof UndoCommand); } + @Test + public void parseCommand_undoCommandAlias_returnsUndoCommand() throws Exception { + assertTrue(parser.parseCommand(UndoCommand.COMMAND_ALIAS) instanceof UndoCommand); + assertTrue(parser.parseCommand(UndoCommand.COMMAND_ALIAS + " 3") instanceof UndoCommand); + } + @Test public void parseCommand_unrecognisedInput_throwsParseException() throws Exception { thrown.expect(ParseException.class); From 11fb2683f66ae9cac1ca783974ce7b71df3170df Mon Sep 17 00:00:00 2001 From: "DESKTOP-QB7JG7G\\akiya" Date: Fri, 9 Mar 2018 09:29:43 +0800 Subject: [PATCH 12/66] add listTags() function in model, update developer's guide (user profile, value proposition and user stories) --- src/main/java/seedu/address/model/AddressBook.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/address/model/AddressBook.java b/src/main/java/seedu/address/model/AddressBook.java index b0bc3a7639d1..d2e7ea7f606a 100644 --- a/src/main/java/seedu/address/model/AddressBook.java +++ b/src/main/java/seedu/address/model/AddressBook.java @@ -68,8 +68,8 @@ public String listTags() { String tagString = ""; Iterator it = tags.iterator(); - while(it.hasNext()){ - Tag nextTag = (Tag)it.next(); + while (it.hasNext()) { + Tag nextTag = (Tag) it.next(); tagString += (nextTag.toString() + "\n"); } From 1908e945febfc89dac6016e21b852c2f568cc59f Mon Sep 17 00:00:00 2001 From: "DESKTOP-QB7JG7G\\akiya" Date: Fri, 9 Mar 2018 09:50:01 +0800 Subject: [PATCH 13/66] add listTags() function in model, update developer's guide (user profile, value proposition and user stories) --- src/main/java/seedu/address/model/AddressBook.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/address/model/AddressBook.java b/src/main/java/seedu/address/model/AddressBook.java index d2e7ea7f606a..be98faaf72ae 100644 --- a/src/main/java/seedu/address/model/AddressBook.java +++ b/src/main/java/seedu/address/model/AddressBook.java @@ -68,7 +68,7 @@ public String listTags() { String tagString = ""; Iterator it = tags.iterator(); - while (it.hasNext()) { + while (it.hasNext()) { Tag nextTag = (Tag) it.next(); tagString += (nextTag.toString() + "\n"); } From 0fc309208548d62972beeefa776214323ce444ab Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 9 Mar 2018 09:52:27 +0800 Subject: [PATCH 14/66] Add newline at EOF for DarkTheme.css --- src/main/resources/view/DarkTheme.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/view/DarkTheme.css b/src/main/resources/view/DarkTheme.css index 36e3459e36fb..9fcae65dccda 100644 --- a/src/main/resources/view/DarkTheme.css +++ b/src/main/resources/view/DarkTheme.css @@ -351,4 +351,4 @@ #tags .blue { -fx-text-fill: white; -fx-background-color: blue; -} \ No newline at end of file +} From de190ac0a747ed7487eb4377a07bdd7ed2c9b18f Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 9 Mar 2018 10:04:03 +0800 Subject: [PATCH 15/66] Adjusted indents --- src/main/java/seedu/address/ui/PersonCard.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/seedu/address/ui/PersonCard.java b/src/main/java/seedu/address/ui/PersonCard.java index 2e337d92c971..7795e693b1f9 100644 --- a/src/main/java/seedu/address/ui/PersonCard.java +++ b/src/main/java/seedu/address/ui/PersonCard.java @@ -50,20 +50,20 @@ public PersonCard(Person person, int displayedIndex) { phone.setText(person.getPhone().value); address.setText(person.getAddress().value); email.setText(person.getEmail().value); - person.getTags().forEach(tag -> { Label tagLabel = new Label(tag.tagName); - tagLabel.getStyleClass().add(TAG_COLOUR_STYLES[0]); - tags.getChildren().add(tagLabel); }); + person.getTags().forEach(tag -> { Label tagLabel = new Label(tag.tagName); + tagLabel.getStyleClass().add(TAG_COLOUR_STYLES[0]); + tags.getChildren().add(tagLabel); }); } /** to be implemented with more tag colours * */ -// private String getTagColourStyleFor(String tagName) { -// -// -// return TAG_COLOUR_STYLES[Math.abs(tagName.hashCode()) % TAG_COLOUR_STYLES.length]; -// } + // private String getTagColourStyleFor(String tagName) { + // + // + // return TAG_COLOUR_STYLES[Math.abs(tagName.hashCode()) % TAG_COLOUR_STYLES.length]; + // } @Override public boolean equals(Object other) { From 5096d46de3e02250b4d2817ba5c33516c1686a91 Mon Sep 17 00:00:00 2001 From: Wu Di Date: Fri, 9 Mar 2018 10:19:21 +0800 Subject: [PATCH 16/66] update team name and product name on UGDG --- docs/DeveloperGuide.adoc | 4 ++-- docs/UserGuide.adoc | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/DeveloperGuide.adoc b/docs/DeveloperGuide.adoc index bbdaa5d04ec3..aed0cadd6a0e 100644 --- a/docs/DeveloperGuide.adoc +++ b/docs/DeveloperGuide.adoc @@ -1,4 +1,4 @@ -= AddressBook Level 4 - Developer Guide += Your TA - Developer Guide :toc: :toc-title: :toc-placement: preamble @@ -12,7 +12,7 @@ ifdef::env-github[] endif::[] :repoURL: https://github.com/CS2103JAN2018-F09-B1/main/tree/master -By: `Team SE-EDU`      Since: `Jun 2016`      Licence: `MIT` +By: `F09-B1`      Since: `Jun 2016`      Licence: `MIT` == Setting up diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index 39f627797895..0b497b2880b2 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -1,4 +1,4 @@ -= AddressBook Level 4 - User Guide += Your TA - User Guide :toc: :toc-title: :toc-placement: preamble @@ -13,7 +13,7 @@ ifdef::env-github[] endif::[] :repoURL: https://github.com/CS2103JAN2018-F09-B1/main -By: `Team SE-EDU` Since: `Jun 2016` Licence: `MIT` +By: `F09-B1` Since: `Jun 2016` Licence: `MIT` == Introduction From 566890aa54b6eb57c6b85c84b3fedf2d99140a44 Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 9 Mar 2018 10:21:53 +0800 Subject: [PATCH 17/66] Adjusted indents --- src/main/java/seedu/address/ui/PersonCard.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/address/ui/PersonCard.java b/src/main/java/seedu/address/ui/PersonCard.java index 7795e693b1f9..f2456f30c9ff 100644 --- a/src/main/java/seedu/address/ui/PersonCard.java +++ b/src/main/java/seedu/address/ui/PersonCard.java @@ -15,7 +15,7 @@ public class PersonCard extends UiPart { private static final String FXML = "PersonListCard.fxml"; //this is the colours that can be used to colour code labels private static final String[] TAG_COLOUR_STYLES = - { "blue" }; + { "blue" }; /** * Note: Certain keywords such as "location" and "resources" are reserved keywords in JavaFX. @@ -50,7 +50,8 @@ public PersonCard(Person person, int displayedIndex) { phone.setText(person.getPhone().value); address.setText(person.getAddress().value); email.setText(person.getEmail().value); - person.getTags().forEach(tag -> { Label tagLabel = new Label(tag.tagName); + person.getTags().forEach(tag -> { + Label tagLabel = new Label(tag.tagName); tagLabel.getStyleClass().add(TAG_COLOUR_STYLES[0]); tags.getChildren().add(tagLabel); }); } From bf7d1c2a37ed66b6a029f39e83e793f2ac745fe3 Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 9 Mar 2018 10:27:09 +0800 Subject: [PATCH 18/66] Adjusted indents --- src/main/java/seedu/address/ui/PersonCard.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/address/ui/PersonCard.java b/src/main/java/seedu/address/ui/PersonCard.java index f2456f30c9ff..53576332ee95 100644 --- a/src/main/java/seedu/address/ui/PersonCard.java +++ b/src/main/java/seedu/address/ui/PersonCard.java @@ -52,8 +52,8 @@ public PersonCard(Person person, int displayedIndex) { email.setText(person.getEmail().value); person.getTags().forEach(tag -> { Label tagLabel = new Label(tag.tagName); - tagLabel.getStyleClass().add(TAG_COLOUR_STYLES[0]); - tags.getChildren().add(tagLabel); }); + tagLabel.getStyleClass().add(TAG_COLOUR_STYLES[0]); + tags.getChildren().add(tagLabel); }); } /** to be implemented with more tag colours From 6007bd4f2805f3b1c792132dbd424bc237ab872d Mon Sep 17 00:00:00 2001 From: "DESKTOP-QB7JG7G\\akiya" Date: Fri, 9 Mar 2018 10:48:17 +0800 Subject: [PATCH 19/66] add listTags() enhancement --- docs/DeveloperGuide.adoc | 41 +++++++--------------------------------- 1 file changed, 7 insertions(+), 34 deletions(-) diff --git a/docs/DeveloperGuide.adoc b/docs/DeveloperGuide.adoc index 0ceaef82684e..688b00653e80 100644 --- a/docs/DeveloperGuide.adoc +++ b/docs/DeveloperGuide.adoc @@ -780,16 +780,15 @@ See this https://github.com/se-edu/addressbook-level4/pull/599[PR] for the step- [appendix] == Product Scope -*Target user profile*: Tech-Savvy University Teachers/Tutors +*Target user profile*: -* have the need to manage a significant number of contacts +* has a need to manage a significant number of contacts * prefer desktop apps over other types * can type fast -* prefer typing over mouse input -* are reasonably comfortable using CLI apps +* prefers typing over mouse input +* is reasonably comfortable using CLI apps -*Value proposition*: manage contacts faster than a typical mouse/GUI driven app, includes to-do - list features (with prioritization, etc.) and scheduling (with calendar and reminders) +*Value proposition*: manage contacts faster than a typical mouse/GUI driven app [appendix] == User Stories @@ -801,41 +800,15 @@ Priorities: High (must have) - `* * \*`, Medium (nice to have) - `* \*`, Low (un |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 -|`* * *` |new user |get error messages/prompts |better adapt to commands to use them properly - -|`* * *` |user |add a new person |better manage all my contacts at one go +|`* * *` |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 |find a person by matriculation number/email |identify people easily - -|`* * *` |user |sort contacts based on name/address/email/tags |work with specific groups of people - -|`* * *` |user |assign a to-do list to each person in address book |know what I need to do for them - -|`* * *` |user |add individual items to the to-do lists |update additional tasks - -|`* * *` |user |remove entire to-do lists or items in it |remove completed tasks - -|`* * *` |user |add events to the schedule |better manage work/students - -|`* * *` |user |add a deadline to tasks/items |know what needs to be done and by when - -|`* * *` |user |prioritize tasks/items |efficiently get tasks/items done on time - |`* *` |user |hide <> by default |minimize chance of someone else seeing them by accident -|`* *` |user |import students/people from a text file |it is easier to enter large numbers of people - -|`* *` |user |add profile pictures |know who the people I am working with are - -|`* *` |user |mass email students/people based on a tag |easily email/inform a class of students of announcements - -|`* *` |user |set reminders for certain events |have an email sent to me before the actual event so that I don't forget - -|`*` |user with many persons in the address book |combine groups/tags |better work with people who have similar interests/work +|`*` |user with many persons in the address book |sort persons by name |locate a person easily |======================================================================= _{More to be added}_ From bb00f77ad27fb429b0c975bb3ad1e90c25a6f5f1 Mon Sep 17 00:00:00 2001 From: "DESKTOP-QB7JG7G\\akiya" Date: Fri, 9 Mar 2018 10:52:14 +0800 Subject: [PATCH 20/66] update developer's guide (user profile, value proposition and user stories) --- docs/DeveloperGuide.adoc | 41 +++++++++++++++---- .../java/seedu/address/model/AddressBook.java | 16 -------- 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/docs/DeveloperGuide.adoc b/docs/DeveloperGuide.adoc index 688b00653e80..0ceaef82684e 100644 --- a/docs/DeveloperGuide.adoc +++ b/docs/DeveloperGuide.adoc @@ -780,15 +780,16 @@ See this https://github.com/se-edu/addressbook-level4/pull/599[PR] for the step- [appendix] == Product Scope -*Target user profile*: +*Target user profile*: Tech-Savvy University Teachers/Tutors -* has a need to manage a significant number of contacts +* have the need to manage a significant number of contacts * prefer desktop apps over other types * can type fast -* prefers typing over mouse input -* is reasonably comfortable using CLI apps +* prefer typing over mouse input +* are reasonably comfortable using CLI apps -*Value proposition*: manage contacts faster than a typical mouse/GUI driven app +*Value proposition*: manage contacts faster than a typical mouse/GUI driven app, includes to-do + list features (with prioritization, etc.) and scheduling (with calendar and reminders) [appendix] == User Stories @@ -800,15 +801,41 @@ Priorities: High (must have) - `* * \*`, Medium (nice to have) - `* \*`, Low (un |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 | +|`* * *` |new user |get error messages/prompts |better adapt to commands to use them properly + +|`* * *` |user |add a new person |better manage all my contacts at one go |`* * *` |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 |find a person by matriculation number/email |identify people easily + +|`* * *` |user |sort contacts based on name/address/email/tags |work with specific groups of people + +|`* * *` |user |assign a to-do list to each person in address book |know what I need to do for them + +|`* * *` |user |add individual items to the to-do lists |update additional tasks + +|`* * *` |user |remove entire to-do lists or items in it |remove completed tasks + +|`* * *` |user |add events to the schedule |better manage work/students + +|`* * *` |user |add a deadline to tasks/items |know what needs to be done and by when + +|`* * *` |user |prioritize tasks/items |efficiently get tasks/items done on time + |`* *` |user |hide <> by default |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 +|`* *` |user |import students/people from a text file |it is easier to enter large numbers of people + +|`* *` |user |add profile pictures |know who the people I am working with are + +|`* *` |user |mass email students/people based on a tag |easily email/inform a class of students of announcements + +|`* *` |user |set reminders for certain events |have an email sent to me before the actual event so that I don't forget + +|`*` |user with many persons in the address book |combine groups/tags |better work with people who have similar interests/work |======================================================================= _{More to be added}_ diff --git a/src/main/java/seedu/address/model/AddressBook.java b/src/main/java/seedu/address/model/AddressBook.java index be98faaf72ae..1e8df5849ab4 100644 --- a/src/main/java/seedu/address/model/AddressBook.java +++ b/src/main/java/seedu/address/model/AddressBook.java @@ -60,22 +60,6 @@ public void setTags(Set tags) { this.tags.setTags(tags); } - /** - * Lists all the current tags that are used. - * @return a continuous String of tags in UniqueTagList separated by a nextline between each tag. - */ - public String listTags() { - String tagString = ""; - - Iterator it = tags.iterator(); - while (it.hasNext()) { - Tag nextTag = (Tag) it.next(); - tagString += (nextTag.toString() + "\n"); - } - - return tagString; - } - /** * Resets the existing data of this {@code AddressBook} with {@code newData}. */ From eae6ce4851aad712805021f7749ee6504d871556 Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 9 Mar 2018 10:54:53 +0800 Subject: [PATCH 21/66] Only DeveloperGuide --- src/main/java/seedu/address/ui/PersonCard.java | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/main/java/seedu/address/ui/PersonCard.java b/src/main/java/seedu/address/ui/PersonCard.java index 53576332ee95..12ef73d54617 100644 --- a/src/main/java/seedu/address/ui/PersonCard.java +++ b/src/main/java/seedu/address/ui/PersonCard.java @@ -50,22 +50,9 @@ public PersonCard(Person person, int displayedIndex) { phone.setText(person.getPhone().value); address.setText(person.getAddress().value); email.setText(person.getEmail().value); - person.getTags().forEach(tag -> { - Label tagLabel = new Label(tag.tagName); - tagLabel.getStyleClass().add(TAG_COLOUR_STYLES[0]); - tags.getChildren().add(tagLabel); }); + person.getTags().forEach(tag -> tags.getChildren().add(new Label(tag.tagName))); } - /** to be implemented with more tag colours - * - */ - - // private String getTagColourStyleFor(String tagName) { - // - // - // return TAG_COLOUR_STYLES[Math.abs(tagName.hashCode()) % TAG_COLOUR_STYLES.length]; - // } - @Override public boolean equals(Object other) { // short circuit if same object From d5254744ac57a73dc62bb89b414861911aff1d38 Mon Sep 17 00:00:00 2001 From: "DESKTOP-QB7JG7G\\akiya" Date: Fri, 9 Mar 2018 11:03:37 +0800 Subject: [PATCH 22/66] update developer's guide (user profile, value proposition and user stories) --- src/main/java/seedu/address/model/AddressBook.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/seedu/address/model/AddressBook.java b/src/main/java/seedu/address/model/AddressBook.java index 1e8df5849ab4..f8d0260de159 100644 --- a/src/main/java/seedu/address/model/AddressBook.java +++ b/src/main/java/seedu/address/model/AddressBook.java @@ -4,7 +4,6 @@ import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Objects; From bc2ea8ed505c90724d092ff71a61048489ea8960 Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 9 Mar 2018 12:18:39 +0800 Subject: [PATCH 23/66] Only DeveloperGuide --- src/main/resources/view/DarkTheme.css | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/resources/view/DarkTheme.css b/src/main/resources/view/DarkTheme.css index 9fcae65dccda..a0e6fa2e1a55 100644 --- a/src/main/resources/view/DarkTheme.css +++ b/src/main/resources/view/DarkTheme.css @@ -342,13 +342,10 @@ } #tags .label { + -fx-text-fill: white; + -fx-background-colour: #3e7b91; -fx-padding: 1 3 1 3; -fx-border-radius: 2; -fx-background-radius: 2; -fx-font-size: 11; } - -#tags .blue { - -fx-text-fill: white; - -fx-background-color: blue; -} From c47d77e936f7fa28adc38caa3925a1c22fe519d5 Mon Sep 17 00:00:00 2001 From: Alaru Date: Tue, 13 Mar 2018 23:36:13 +0800 Subject: [PATCH 24/66] Add dummy EmailCommand.java file --- .../address/logic/commands/EmailCommand.java | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 src/main/java/seedu/address/logic/commands/EmailCommand.java diff --git a/src/main/java/seedu/address/logic/commands/EmailCommand.java b/src/main/java/seedu/address/logic/commands/EmailCommand.java new file mode 100644 index 000000000000..ad1be8ed83b9 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/EmailCommand.java @@ -0,0 +1,69 @@ +package seedu.address.logic.commands; + +import static java.util.Objects.requireNonNull; + +import java.util.List; +import java.util.Objects; + +import seedu.address.commons.core.Messages; +import seedu.address.commons.core.index.Index; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.person.Person; +import seedu.address.model.person.exceptions.PersonNotFoundException; + +/** + * Deletes a person identified using it's last displayed index from the address book. + */ +public class EmailCommand extends UndoableCommand { + + public static final String COMMAND_WORD = "delete"; + public static final String COMMAND_ALIAS = "d"; + public static final String COMMAND_SIGN = "-"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + + ": Deletes the person identified by the index number used in the last person listing.\n" + + "Parameters: INDEX (must be a positive integer)\n" + + "Example: " + COMMAND_WORD + " 1"; + + public static final String MESSAGE_DELETE_PERSON_SUCCESS = "Deleted Person: %1$s"; + + private final Index targetIndex; + + private Person personToDelete; + + public EmailCommand(Index targetIndex) { + this.targetIndex = targetIndex; + } + + + @Override + public CommandResult executeUndoableCommand() { + requireNonNull(personToDelete); + try { + model.deletePerson(personToDelete); + } catch (PersonNotFoundException pnfe) { + throw new AssertionError("The target person cannot be missing"); + } + + return new CommandResult(String.format(MESSAGE_DELETE_PERSON_SUCCESS, personToDelete)); + } + + @Override + protected void preprocessUndoableCommand() throws CommandException { + List lastShownList = model.getFilteredPersonList(); + + if (targetIndex.getZeroBased() >= lastShownList.size()) { + throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + } + + personToDelete = lastShownList.get(targetIndex.getZeroBased()); + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof EmailCommand // instanceof handles nulls + && this.targetIndex.equals(((EmailCommand) other).targetIndex) // state check + && Objects.equals(this.personToDelete, ((EmailCommand) other).personToDelete)); + } +} From 5062aa5c734466582dab378b464e8729f94b2d80 Mon Sep 17 00:00:00 2001 From: Alaru Date: Tue, 13 Mar 2018 23:39:08 +0800 Subject: [PATCH 25/66] Add error message if default system mail app cannot be open --- src/main/java/seedu/address/commons/core/Messages.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/seedu/address/commons/core/Messages.java b/src/main/java/seedu/address/commons/core/Messages.java index 1deb3a1e4695..3c3a24e391b1 100644 --- a/src/main/java/seedu/address/commons/core/Messages.java +++ b/src/main/java/seedu/address/commons/core/Messages.java @@ -9,5 +9,6 @@ public class Messages { 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 MAIL_APP_ERROR = "Error opening the default mail app on this system"; } From ea941d1b364055de14c05b33e6c425306232fcc0 Mon Sep 17 00:00:00 2001 From: Alaru Date: Tue, 13 Mar 2018 23:40:51 +0800 Subject: [PATCH 26/66] Update EmailCommand to process the index and open the mail app with mailto: field filled --- .../address/logic/commands/EmailCommand.java | 53 +++++++++---------- 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/EmailCommand.java b/src/main/java/seedu/address/logic/commands/EmailCommand.java index ad1be8ed83b9..962b848cfd80 100644 --- a/src/main/java/seedu/address/logic/commands/EmailCommand.java +++ b/src/main/java/seedu/address/logic/commands/EmailCommand.java @@ -1,69 +1,64 @@ package seedu.address.logic.commands; -import static java.util.Objects.requireNonNull; - +import java.awt.Desktop; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; import java.util.List; -import java.util.Objects; import seedu.address.commons.core.Messages; import seedu.address.commons.core.index.Index; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.model.person.Person; -import seedu.address.model.person.exceptions.PersonNotFoundException; /** * Deletes a person identified using it's last displayed index from the address book. */ -public class EmailCommand extends UndoableCommand { +public class EmailCommand extends Command { - public static final String COMMAND_WORD = "delete"; - public static final String COMMAND_ALIAS = "d"; - public static final String COMMAND_SIGN = "-"; + public static final String COMMAND_WORD = "email"; + public static final String MAIL_SYNTAX = "mailto:"; public static final String MESSAGE_USAGE = COMMAND_WORD - + ": Deletes the person identified by the index number used in the last person listing.\n" + + ": Email the person identified by the index number used in the last person listing.\n" + "Parameters: 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_EMAIL_PERSON_SUCCESS = "Email Person: %1$s"; private final Index targetIndex; - private Person personToDelete; - public EmailCommand(Index targetIndex) { this.targetIndex = targetIndex; } - @Override - public CommandResult executeUndoableCommand() { - requireNonNull(personToDelete); - try { - model.deletePerson(personToDelete); - } catch (PersonNotFoundException pnfe) { - throw new AssertionError("The target person cannot be missing"); - } - - return new CommandResult(String.format(MESSAGE_DELETE_PERSON_SUCCESS, personToDelete)); - } - - @Override - protected void preprocessUndoableCommand() throws CommandException { + public CommandResult execute() throws CommandException { List lastShownList = model.getFilteredPersonList(); if (targetIndex.getZeroBased() >= lastShownList.size()) { throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); } + Person personToEmail = lastShownList.get(targetIndex.getZeroBased()); + + String emailAddress = personToEmail.getEmail().toString(); + String emailName = personToEmail.getName().toString(); + + try { + Desktop.getDesktop().mail(new URI(MAIL_SYNTAX + emailAddress)); + } catch (URISyntaxException Urierror) { + throw new CommandException(Messages.MAIL_APP_ERROR); + } catch (IOException e) { + throw new CommandException(Messages.MAIL_APP_ERROR); + } - personToDelete = lastShownList.get(targetIndex.getZeroBased()); + return new CommandResult(String.format(MESSAGE_EMAIL_PERSON_SUCCESS, emailName)); } @Override public boolean equals(Object other) { return other == this // short circuit if same object || (other instanceof EmailCommand // instanceof handles nulls - && this.targetIndex.equals(((EmailCommand) other).targetIndex) // state check - && Objects.equals(this.personToDelete, ((EmailCommand) other).personToDelete)); + && this.targetIndex.equals(((EmailCommand) other).targetIndex)); // state check } } From 813f3c2ad50f9d561589ac1386fa05d0093621a5 Mon Sep 17 00:00:00 2001 From: Alaru Date: Tue, 13 Mar 2018 23:41:40 +0800 Subject: [PATCH 27/66] Add EmailCommandParser --- .../logic/parser/EmailCommandParser.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/main/java/seedu/address/logic/parser/EmailCommandParser.java diff --git a/src/main/java/seedu/address/logic/parser/EmailCommandParser.java b/src/main/java/seedu/address/logic/parser/EmailCommandParser.java new file mode 100644 index 000000000000..892e88f94465 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/EmailCommandParser.java @@ -0,0 +1,30 @@ +package seedu.address.logic.parser; + +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; + +import seedu.address.commons.core.index.Index; +import seedu.address.commons.exceptions.IllegalValueException; +import seedu.address.logic.commands.EmailCommand; +import seedu.address.logic.parser.exceptions.ParseException; + +/** + * Parses input arguments and creates a new DeleteCommand object + */ +public class EmailCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the EmailCommand + * and returns an EmailCommand object for execution. + * @throws ParseException if the user input does not conform the expected format + */ + public EmailCommand parse(String args) throws ParseException { + try { + Index index = ParserUtil.parseIndex(args); + return new EmailCommand(index); + } catch (IllegalValueException ive) { + throw new ParseException( + String.format(MESSAGE_INVALID_COMMAND_FORMAT, EmailCommand.MESSAGE_USAGE)); + } + } + +} From a9c3c270be3295ff0ec2bfa76007be23d439dada Mon Sep 17 00:00:00 2001 From: Alaru Date: Tue, 13 Mar 2018 23:43:30 +0800 Subject: [PATCH 28/66] Update AddressBookParser to recognise Email command --- .../java/seedu/address/logic/parser/AddressBookParser.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index abed25f26008..5b57fb071c2d 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -11,6 +11,7 @@ import seedu.address.logic.commands.Command; import seedu.address.logic.commands.DeleteCommand; import seedu.address.logic.commands.EditCommand; +import seedu.address.logic.commands.EmailCommand; import seedu.address.logic.commands.ExitCommand; import seedu.address.logic.commands.FindCommand; import seedu.address.logic.commands.HelpCommand; @@ -66,6 +67,9 @@ public Command parseCommand(String userInput) throws ParseException { case DeleteCommand.COMMAND_SIGN: return new DeleteCommandParser().parse(arguments); + case EmailCommand.COMMAND_WORD: + return new EmailCommandParser().parse(arguments); + case ClearCommand.COMMAND_WORD: case ClearCommand.COMMAND_ALIAS: return new ClearCommand(); From 84e9fbefc9fd3f59996477a025a4fcd4c1247618 Mon Sep 17 00:00:00 2001 From: Alaru Date: Tue, 13 Mar 2018 23:53:06 +0800 Subject: [PATCH 29/66] Update userguide with email command --- docs/UserGuide.adoc | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index 0b497b2880b2..95679381fadf 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -103,6 +103,26 @@ Edits the phone number and email address of the 1st person to be `91234567` and * `edit 2 n/Betsy Crower t/` + Edits the name of the 2nd person to be `Betsy Crower` and clears all existing tags. +=== Emailing a person : `email` + +Email a person in the address book. This uses your default mail app to email. + +Format: `email INDEX` + +**** +* Emails the person at the specified `INDEX`. +* The index refers to the index number shown in the most recent listing. +* The index *must be a positive integer* 1, 2, 3, ... +**** + +Examples: + +* `list` + +`email 2` + +Emails the 2nd person in the address book. +* `find Betsy` + +`email 1` + +Emails the 1st person in the results of the `find` command. + === Locating persons by name: `find` Finds persons whose names contain any of the given keywords. + From 825dced11fdeb83fcff3eb4a89e97608475eb809 Mon Sep 17 00:00:00 2001 From: alaru Date: Wed, 14 Mar 2018 18:35:44 +0800 Subject: [PATCH 30/66] Update description of EmailCommand --- src/main/java/seedu/address/logic/commands/EmailCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/address/logic/commands/EmailCommand.java b/src/main/java/seedu/address/logic/commands/EmailCommand.java index 962b848cfd80..9e1554d7e334 100644 --- a/src/main/java/seedu/address/logic/commands/EmailCommand.java +++ b/src/main/java/seedu/address/logic/commands/EmailCommand.java @@ -12,7 +12,7 @@ import seedu.address.model.person.Person; /** - * Deletes a person identified using it's last displayed index from the address book. + * Emails a person identified using it's last displayed index from the address book. */ public class EmailCommand extends Command { From e5d6e1655ec20ca101258e3222e3dd870aeeff26 Mon Sep 17 00:00:00 2001 From: Pearlissa Date: Wed, 14 Mar 2018 22:01:18 +0800 Subject: [PATCH 31/66] Changed from help window listing possible commands and examples for use. To be updated when reworking help window in the future. --- docs/DeveloperGuide.adoc | 7 ++++++ docs/UserGuide.adoc | 2 +- .../address/logic/commands/HelpCommand.java | 24 ++++++++++++++++++- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/docs/DeveloperGuide.adoc b/docs/DeveloperGuide.adoc index 736c58bbf896..5746a804aa8c 100644 --- a/docs/DeveloperGuide.adoc +++ b/docs/DeveloperGuide.adoc @@ -230,6 +230,13 @@ Classes used by multiple components are in the `seedu.addressbook.commons` packa This section describes some noteworthy details on how certain features are implemented. +=== Help feature +==== Current Implementation + +The help command displays a list of all the possible commands the user can make, followed by an example on its use. + +[This section is to be expanded when the help command is reworked into the help window.] + // tag::undoredo[] === Undo/Redo feature ==== Current Implementation diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index 0b497b2880b2..a5434500f58a 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -34,7 +34,7 @@ This app will not work with earlier versions of Java 8. image::Ui.png[width="790"] + . Type the command in the command box and press kbd:[Enter] to execute it. + -e.g. typing *`help`* and pressing kbd:[Enter] will open the help window. +e.g. typing *`help`* and pressing kbd:[Enter] will list all possible commands and their formats. . Some example commands you can try: * *`list`* : lists all contacts diff --git a/src/main/java/seedu/address/logic/commands/HelpCommand.java b/src/main/java/seedu/address/logic/commands/HelpCommand.java index fa2f5603cd91..559bc9554d23 100644 --- a/src/main/java/seedu/address/logic/commands/HelpCommand.java +++ b/src/main/java/seedu/address/logic/commands/HelpCommand.java @@ -14,7 +14,29 @@ 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 SHOWING_HELP_MESSAGE = "1. add/a/+: Add person to addressbook.\n" + + "Example: add n/NAME m/MATRIC NUMBER p/PHONE e/EMAIL [t/TAG]...\n" + + "2. clear/c: Clear the addressbook.\n" + + "Example: clear\n" + + "3. delete/d/-: Delete a person from addressbook using their index.\n" + + "Example: delete INDEX\n" + + "4. edit/e: Edit the details of an existing person using their index.\n" + + "Example: edit INDEX [n/NAME] [m/MATRIC NUMBER] [p/PHONE] [e/EMAIL] [t/TAG]...\n" + + "5. exit: Exit the addressbook.\n" + + "Example: exit\n" + + "6. find/f: Find all persons with names containing any keyword(s) and lists them.\n" + + "Example: find KEYWORD [KEYWORD]...\n" + + "7. history/h: List all commands made by the user from the latest to earliest.\n" + + "Example: history\n" + + "8. list/ls: List all persons in the addressbook with index.\n" + + "Example: ls\n" + + "9. redo/r: Redo the previously undone command.\n" + + "Example: redo\n" + + "10. select/s: Select an existing person using their index.\n" + + "Example: select INDEX\n" + + "11. undo/u: Undo the previous UNDOABLE command.\n" + + "Example: undo\n"; + @Override public CommandResult execute() { From c02434048bc131b398932a2aae3cda4032ddad13 Mon Sep 17 00:00:00 2001 From: Alaru Date: Wed, 14 Mar 2018 18:35:44 +0800 Subject: [PATCH 32/66] Update description of EmailCommand --- src/main/java/seedu/address/logic/commands/EmailCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/address/logic/commands/EmailCommand.java b/src/main/java/seedu/address/logic/commands/EmailCommand.java index 962b848cfd80..9e1554d7e334 100644 --- a/src/main/java/seedu/address/logic/commands/EmailCommand.java +++ b/src/main/java/seedu/address/logic/commands/EmailCommand.java @@ -12,7 +12,7 @@ import seedu.address.model.person.Person; /** - * Deletes a person identified using it's last displayed index from the address book. + * Emails a person identified using it's last displayed index from the address book. */ public class EmailCommand extends Command { From 680c996f9efd36dfbece03a7c698aa8132cbfd02 Mon Sep 17 00:00:00 2001 From: Alaru Date: Wed, 14 Mar 2018 23:29:02 +0800 Subject: [PATCH 33/66] Revert "Update description of EmailCommand" This reverts commit c02434048bc131b398932a2aae3cda4032ddad13. --- src/main/java/seedu/address/logic/commands/EmailCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/address/logic/commands/EmailCommand.java b/src/main/java/seedu/address/logic/commands/EmailCommand.java index 9e1554d7e334..962b848cfd80 100644 --- a/src/main/java/seedu/address/logic/commands/EmailCommand.java +++ b/src/main/java/seedu/address/logic/commands/EmailCommand.java @@ -12,7 +12,7 @@ import seedu.address.model.person.Person; /** - * Emails a person identified using it's last displayed index from the address book. + * Deletes a person identified using it's last displayed index from the address book. */ public class EmailCommand extends Command { From c577bd05d84359c1b2505ac7c96b6fcc84558847 Mon Sep 17 00:00:00 2001 From: Alaru Date: Wed, 14 Mar 2018 23:30:06 +0800 Subject: [PATCH 34/66] Revert "Update userguide with email command" This reverts commit 84e9fbefc9fd3f59996477a025a4fcd4c1247618. --- docs/UserGuide.adoc | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index 95679381fadf..0b497b2880b2 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -103,26 +103,6 @@ Edits the phone number and email address of the 1st person to be `91234567` and * `edit 2 n/Betsy Crower t/` + Edits the name of the 2nd person to be `Betsy Crower` and clears all existing tags. -=== Emailing a person : `email` - -Email a person in the address book. This uses your default mail app to email. + -Format: `email INDEX` - -**** -* Emails the person at the specified `INDEX`. -* The index refers to the index number shown in the most recent listing. -* The index *must be a positive integer* 1, 2, 3, ... -**** - -Examples: - -* `list` + -`email 2` + -Emails the 2nd person in the address book. -* `find Betsy` + -`email 1` + -Emails the 1st person in the results of the `find` command. - === Locating persons by name: `find` Finds persons whose names contain any of the given keywords. + From 591282b20bbd7ad82c148e58198ae2b4eb3486d8 Mon Sep 17 00:00:00 2001 From: Alaru Date: Wed, 14 Mar 2018 23:35:18 +0800 Subject: [PATCH 35/66] Reupdate userguide with email command --- docs/UserGuide.adoc | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index 0b497b2880b2..95679381fadf 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -103,6 +103,26 @@ Edits the phone number and email address of the 1st person to be `91234567` and * `edit 2 n/Betsy Crower t/` + Edits the name of the 2nd person to be `Betsy Crower` and clears all existing tags. +=== Emailing a person : `email` + +Email a person in the address book. This uses your default mail app to email. + +Format: `email INDEX` + +**** +* Emails the person at the specified `INDEX`. +* The index refers to the index number shown in the most recent listing. +* The index *must be a positive integer* 1, 2, 3, ... +**** + +Examples: + +* `list` + +`email 2` + +Emails the 2nd person in the address book. +* `find Betsy` + +`email 1` + +Emails the 1st person in the results of the `find` command. + === Locating persons by name: `find` Finds persons whose names contain any of the given keywords. + From e6d9ebf1658250ab073b6e49b13019f2e63a5ff4 Mon Sep 17 00:00:00 2001 From: Alaru Date: Thu, 15 Mar 2018 01:52:08 +0800 Subject: [PATCH 36/66] Added one EmailCommandTest to check if expected output is correct --- .../logic/commands/EmailCommandTest.java | 207 ++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100644 src/test/java/seedu/address/logic/commands/EmailCommandTest.java diff --git a/src/test/java/seedu/address/logic/commands/EmailCommandTest.java b/src/test/java/seedu/address/logic/commands/EmailCommandTest.java new file mode 100644 index 000000000000..d84d4bc755f9 --- /dev/null +++ b/src/test/java/seedu/address/logic/commands/EmailCommandTest.java @@ -0,0 +1,207 @@ +package seedu.address.logic.commands; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; +import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure; +import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; +import static seedu.address.logic.commands.CommandTestUtil.prepareRedoCommand; +import static seedu.address.logic.commands.CommandTestUtil.prepareUndoCommand; +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 org.junit.Test; + +import seedu.address.commons.core.Messages; +import seedu.address.commons.core.index.Index; +import seedu.address.logic.CommandHistory; +import seedu.address.logic.UndoRedoStack; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.ModelManager; +import seedu.address.model.UserPrefs; +import seedu.address.model.person.Person; + +/** + * Contains integration tests (interaction with the Model, UndoCommand and RedoCommand) and unit tests for + * {@code EmailCommand}. + */ +public class EmailCommandTest { + + private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); + + @Test + public void execute_validIndexUnfilteredList_success() throws Exception { + Person personToEmail = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased()); + EmailCommand emailCommand = prepareCommand(INDEX_FIRST_PERSON); + + String expectedMessage = String.format(EmailCommand.MESSAGE_EMAIL_PERSON_SUCCESS, + personToEmail.getName().toString()); + assertEmailSuccess(expectedMessage, emailCommand); + } + /* + @Test + public void execute_invalidIndexUnfilteredList_throwsCommandException() throws Exception { + Index outOfBoundIndex = Index.fromOneBased(model.getFilteredPersonList().size() + 1); + EmailCommand emailCommand = prepareCommand(outOfBoundIndex); + + assertCommandFailure(deleteCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + } + / + @Test + public void execute_validIndexFilteredList_success() throws Exception { + showPersonAtIndex(model, INDEX_FIRST_PERSON); + + Person personToDelete = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased()); + DeleteCommand deleteCommand = prepareCommand(INDEX_FIRST_PERSON); + + String expectedMessage = String.format(DeleteCommand.MESSAGE_DELETE_PERSON_SUCCESS, personToDelete); + + Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); + expectedModel.deletePerson(personToDelete); + showNoPerson(expectedModel); + + assertCommandSuccess(deleteCommand, model, expectedMessage, expectedModel); + } + + @Test + public void execute_invalidIndexFilteredList_throwsCommandException() { + showPersonAtIndex(model, INDEX_FIRST_PERSON); + + Index outOfBoundIndex = INDEX_SECOND_PERSON; + // ensures that outOfBoundIndex is still in bounds of address book list + assertTrue(outOfBoundIndex.getZeroBased() < model.getAddressBook().getPersonList().size()); + + DeleteCommand deleteCommand = prepareCommand(outOfBoundIndex); + + assertCommandFailure(deleteCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + } + + @Test + public void executeUndoRedo_validIndexUnfilteredList_success() throws Exception { + UndoRedoStack undoRedoStack = new UndoRedoStack(); + UndoCommand undoCommand = prepareUndoCommand(model, undoRedoStack); + RedoCommand redoCommand = prepareRedoCommand(model, undoRedoStack); + Person personToDelete = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased()); + DeleteCommand deleteCommand = prepareCommand(INDEX_FIRST_PERSON); + Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); + + // delete -> first person deleted + deleteCommand.execute(); + undoRedoStack.push(deleteCommand); + + // undo -> reverts addressbook back to previous state and filtered person list to show all persons + assertCommandSuccess(undoCommand, model, UndoCommand.MESSAGE_SUCCESS, expectedModel); + + // redo -> same first person deleted again + expectedModel.deletePerson(personToDelete); + assertCommandSuccess(redoCommand, model, RedoCommand.MESSAGE_SUCCESS, expectedModel); + } + + @Test + public void executeUndoRedo_invalidIndexUnfilteredList_failure() { + UndoRedoStack undoRedoStack = new UndoRedoStack(); + UndoCommand undoCommand = prepareUndoCommand(model, undoRedoStack); + RedoCommand redoCommand = prepareRedoCommand(model, undoRedoStack); + Index outOfBoundIndex = Index.fromOneBased(model.getFilteredPersonList().size() + 1); + DeleteCommand deleteCommand = prepareCommand(outOfBoundIndex); + + // execution failed -> deleteCommand not pushed into undoRedoStack + assertCommandFailure(deleteCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + + // no commands in undoRedoStack -> undoCommand and redoCommand fail + assertCommandFailure(undoCommand, model, UndoCommand.MESSAGE_FAILURE); + assertCommandFailure(redoCommand, model, RedoCommand.MESSAGE_FAILURE); + } + + /** + * 1. Deletes a {@code Person} from a filtered list. + * 2. Undo the deletion. + * 3. The unfiltered list should be shown now. Verify that the index of the previously deleted person in the + * unfiltered list is different from the index at the filtered list. + * 4. Redo the deletion. This ensures {@code RedoCommand} deletes the person object regardless of indexing. + */ /* + @Test + public void executeUndoRedo_validIndexFilteredList_samePersonDeleted() throws Exception { + UndoRedoStack undoRedoStack = new UndoRedoStack(); + UndoCommand undoCommand = prepareUndoCommand(model, undoRedoStack); + RedoCommand redoCommand = prepareRedoCommand(model, undoRedoStack); + DeleteCommand deleteCommand = prepareCommand(INDEX_FIRST_PERSON); + Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); + + showPersonAtIndex(model, INDEX_SECOND_PERSON); + Person personToDelete = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased()); + // delete -> deletes second person in unfiltered person list / first person in filtered person list + deleteCommand.execute(); + undoRedoStack.push(deleteCommand); + + // undo -> reverts addressbook back to previous state and filtered person list to show all persons + assertCommandSuccess(undoCommand, model, UndoCommand.MESSAGE_SUCCESS, expectedModel); + + expectedModel.deletePerson(personToDelete); + assertNotEquals(personToDelete, model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased())); + // redo -> deletes same second person in unfiltered person list + assertCommandSuccess(redoCommand, model, RedoCommand.MESSAGE_SUCCESS, expectedModel); + } + + @Test + public void equals() throws Exception { + DeleteCommand deleteFirstCommand = prepareCommand(INDEX_FIRST_PERSON); + DeleteCommand deleteSecondCommand = prepareCommand(INDEX_SECOND_PERSON); + + // same object -> returns true + assertTrue(deleteFirstCommand.equals(deleteFirstCommand)); + + // same values -> returns true + DeleteCommand deleteFirstCommandCopy = prepareCommand(INDEX_FIRST_PERSON); + assertTrue(deleteFirstCommand.equals(deleteFirstCommandCopy)); + + // one command preprocessed when previously equal -> returns false + deleteFirstCommandCopy.preprocessUndoableCommand(); + assertFalse(deleteFirstCommand.equals(deleteFirstCommandCopy)); + + // different types -> returns false + assertFalse(deleteFirstCommand.equals(1)); + + // null -> returns false + assertFalse(deleteFirstCommand.equals(null)); + + // different person -> returns false + assertFalse(deleteFirstCommand.equals(deleteSecondCommand)); + } + */ + /** + * Returns a {@code EmailCommand} with the parameter {@code index}. + */ + private EmailCommand prepareCommand(Index index) { + EmailCommand emailCommand = new EmailCommand(index); + emailCommand.setData(model, new CommandHistory(), new UndoRedoStack()); + return emailCommand; + } + + /** + * Updates {@code model}'s filtered list to show no one. + */ + private void showNoPerson(Model model) { + model.updateFilteredPersonList(p -> false); + + assertTrue(model.getFilteredPersonList().isEmpty()); + } + + /** + * Executes the given {@code command}, confirms that
+ * - the result message matches {@code expectedMessage}
+ * - the {@code actualModel} matches {@code expectedModel} + */ + public static void assertEmailSuccess(String expectedResult, EmailCommand testCommand) { + try { + CommandResult result = testCommand.execute(); + assertEquals(expectedResult, result.feedbackToUser); + } catch (CommandException ce) { + throw new AssertionError("Execution of command should not fail.", ce); + } + } +} From bb7a16fd530edc72058fca1184c76ca52e5cd253 Mon Sep 17 00:00:00 2001 From: Alaru Date: Thu, 15 Mar 2018 02:00:04 +0800 Subject: [PATCH 37/66] Update EmailCommandTest --- .../logic/commands/EmailCommandTest.java | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/test/java/seedu/address/logic/commands/EmailCommandTest.java b/src/test/java/seedu/address/logic/commands/EmailCommandTest.java index d84d4bc755f9..7d7f5a9dd60e 100644 --- a/src/test/java/seedu/address/logic/commands/EmailCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/EmailCommandTest.java @@ -42,31 +42,27 @@ public void execute_validIndexUnfilteredList_success() throws Exception { personToEmail.getName().toString()); assertEmailSuccess(expectedMessage, emailCommand); } - /* + @Test public void execute_invalidIndexUnfilteredList_throwsCommandException() throws Exception { Index outOfBoundIndex = Index.fromOneBased(model.getFilteredPersonList().size() + 1); EmailCommand emailCommand = prepareCommand(outOfBoundIndex); - assertCommandFailure(deleteCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + assertCommandFailure(emailCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); } - / + @Test public void execute_validIndexFilteredList_success() throws Exception { showPersonAtIndex(model, INDEX_FIRST_PERSON); - Person personToDelete = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased()); - DeleteCommand deleteCommand = prepareCommand(INDEX_FIRST_PERSON); - - String expectedMessage = String.format(DeleteCommand.MESSAGE_DELETE_PERSON_SUCCESS, personToDelete); - - Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); - expectedModel.deletePerson(personToDelete); - showNoPerson(expectedModel); + Person personToEmail = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased()); + EmailCommand emailCommand = prepareCommand(INDEX_FIRST_PERSON); - assertCommandSuccess(deleteCommand, model, expectedMessage, expectedModel); + String expectedMessage = String.format(EmailCommand.MESSAGE_EMAIL_PERSON_SUCCESS, + personToEmail.getName().toString()); + assertEmailSuccess(expectedMessage, emailCommand); } - + /* @Test public void execute_invalidIndexFilteredList_throwsCommandException() { showPersonAtIndex(model, INDEX_FIRST_PERSON); @@ -196,7 +192,7 @@ private void showNoPerson(Model model) { * - the result message matches {@code expectedMessage}
* - the {@code actualModel} matches {@code expectedModel} */ - public static void assertEmailSuccess(String expectedResult, EmailCommand testCommand) { + private static void assertEmailSuccess(String expectedResult, EmailCommand testCommand) { try { CommandResult result = testCommand.execute(); assertEquals(expectedResult, result.feedbackToUser); From a24f46c9fd7bfa94b61a2952147cddd3784e33a1 Mon Sep 17 00:00:00 2001 From: Alaru Date: Thu, 15 Mar 2018 02:32:13 +0800 Subject: [PATCH 38/66] Remove redundant imports --- .../logic/commands/EmailCommandTest.java | 22 ++++--------------- 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/src/test/java/seedu/address/logic/commands/EmailCommandTest.java b/src/test/java/seedu/address/logic/commands/EmailCommandTest.java index 7d7f5a9dd60e..ec66b63915ca 100644 --- a/src/test/java/seedu/address/logic/commands/EmailCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/EmailCommandTest.java @@ -1,13 +1,8 @@ package seedu.address.logic.commands; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure; -import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; -import static seedu.address.logic.commands.CommandTestUtil.prepareRedoCommand; -import static seedu.address.logic.commands.CommandTestUtil.prepareUndoCommand; 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; @@ -62,7 +57,7 @@ public void execute_validIndexFilteredList_success() throws Exception { personToEmail.getName().toString()); assertEmailSuccess(expectedMessage, emailCommand); } - /* + @Test public void execute_invalidIndexFilteredList_throwsCommandException() { showPersonAtIndex(model, INDEX_FIRST_PERSON); @@ -71,11 +66,11 @@ public void execute_invalidIndexFilteredList_throwsCommandException() { // ensures that outOfBoundIndex is still in bounds of address book list assertTrue(outOfBoundIndex.getZeroBased() < model.getAddressBook().getPersonList().size()); - DeleteCommand deleteCommand = prepareCommand(outOfBoundIndex); + EmailCommand emailCommand = prepareCommand(outOfBoundIndex); - assertCommandFailure(deleteCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + assertCommandFailure(emailCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); } - + /* @Test public void executeUndoRedo_validIndexUnfilteredList_success() throws Exception { UndoRedoStack undoRedoStack = new UndoRedoStack(); @@ -178,15 +173,6 @@ private EmailCommand prepareCommand(Index index) { return emailCommand; } - /** - * Updates {@code model}'s filtered list to show no one. - */ - private void showNoPerson(Model model) { - model.updateFilteredPersonList(p -> false); - - assertTrue(model.getFilteredPersonList().isEmpty()); - } - /** * Executes the given {@code command}, confirms that
* - the result message matches {@code expectedMessage}
From 925b03e2102246f42e236e7a468034d54c8065b2 Mon Sep 17 00:00:00 2001 From: Alaru Date: Thu, 15 Mar 2018 03:06:03 +0800 Subject: [PATCH 39/66] Update test for systems that do not support Desktop --- src/main/java/seedu/address/commons/core/Messages.java | 1 + .../java/seedu/address/logic/commands/EmailCommand.java | 3 +++ .../java/seedu/address/logic/commands/EmailCommandTest.java | 6 +++++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/address/commons/core/Messages.java b/src/main/java/seedu/address/commons/core/Messages.java index 3c3a24e391b1..5aefa9b91221 100644 --- a/src/main/java/seedu/address/commons/core/Messages.java +++ b/src/main/java/seedu/address/commons/core/Messages.java @@ -10,5 +10,6 @@ public class Messages { 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 MAIL_APP_ERROR = "Error opening the default mail app on this system"; + public static final String UNSUPPORTED_DESKTOP = "The client does not support desktop operations on this system"; } diff --git a/src/main/java/seedu/address/logic/commands/EmailCommand.java b/src/main/java/seedu/address/logic/commands/EmailCommand.java index 9e1554d7e334..e472ff91324d 100644 --- a/src/main/java/seedu/address/logic/commands/EmailCommand.java +++ b/src/main/java/seedu/address/logic/commands/EmailCommand.java @@ -1,6 +1,7 @@ package seedu.address.logic.commands; import java.awt.Desktop; +import java.awt.HeadlessException; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; @@ -46,6 +47,8 @@ public CommandResult execute() throws CommandException { try { Desktop.getDesktop().mail(new URI(MAIL_SYNTAX + emailAddress)); + } catch (HeadlessException hlError) { + throw new CommandException(Messages.UNSUPPORTED_DESKTOP); } catch (URISyntaxException Urierror) { throw new CommandException(Messages.MAIL_APP_ERROR); } catch (IOException e) { diff --git a/src/test/java/seedu/address/logic/commands/EmailCommandTest.java b/src/test/java/seedu/address/logic/commands/EmailCommandTest.java index ec66b63915ca..0f2ce64067e7 100644 --- a/src/test/java/seedu/address/logic/commands/EmailCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/EmailCommandTest.java @@ -183,7 +183,11 @@ private static void assertEmailSuccess(String expectedResult, EmailCommand testC CommandResult result = testCommand.execute(); assertEquals(expectedResult, result.feedbackToUser); } catch (CommandException ce) { - throw new AssertionError("Execution of command should not fail.", ce); + if (ce.equals(new CommandException(Messages.UNSUPPORTED_DESKTOP))) { + assertEquals(ce, (new CommandException(Messages.UNSUPPORTED_DESKTOP))); + } else { + throw new AssertionError("Execution of command should not fail.", ce); + } } } } From 500e7c7159e337e0059705159efefda69d835241 Mon Sep 17 00:00:00 2001 From: Alaru Date: Thu, 15 Mar 2018 03:19:57 +0800 Subject: [PATCH 40/66] Update test for systems that do not support Desktop v2 --- .../seedu/address/logic/commands/EmailCommand.java | 3 ++- .../commands/exceptions/UnsupportDesktopException.java | 10 ++++++++++ .../seedu/address/logic/commands/EmailCommandTest.java | 9 ++++----- 3 files changed, 16 insertions(+), 6 deletions(-) create mode 100644 src/main/java/seedu/address/logic/commands/exceptions/UnsupportDesktopException.java diff --git a/src/main/java/seedu/address/logic/commands/EmailCommand.java b/src/main/java/seedu/address/logic/commands/EmailCommand.java index e472ff91324d..6247c8a17853 100644 --- a/src/main/java/seedu/address/logic/commands/EmailCommand.java +++ b/src/main/java/seedu/address/logic/commands/EmailCommand.java @@ -10,6 +10,7 @@ import seedu.address.commons.core.Messages; import seedu.address.commons.core.index.Index; import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.logic.commands.exceptions.UnsupportDesktopException; import seedu.address.model.person.Person; /** @@ -48,7 +49,7 @@ public CommandResult execute() throws CommandException { try { Desktop.getDesktop().mail(new URI(MAIL_SYNTAX + emailAddress)); } catch (HeadlessException hlError) { - throw new CommandException(Messages.UNSUPPORTED_DESKTOP); + throw new UnsupportDesktopException(Messages.UNSUPPORTED_DESKTOP); } catch (URISyntaxException Urierror) { throw new CommandException(Messages.MAIL_APP_ERROR); } catch (IOException e) { diff --git a/src/main/java/seedu/address/logic/commands/exceptions/UnsupportDesktopException.java b/src/main/java/seedu/address/logic/commands/exceptions/UnsupportDesktopException.java new file mode 100644 index 000000000000..c520473016fa --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/exceptions/UnsupportDesktopException.java @@ -0,0 +1,10 @@ +package seedu.address.logic.commands.exceptions; + +/** + * Represents an error which occurs during execution of a Desktop operation. + */ +public class UnsupportDesktopException extends CommandException { + public UnsupportDesktopException(String message) { + super(message); + } +} diff --git a/src/test/java/seedu/address/logic/commands/EmailCommandTest.java b/src/test/java/seedu/address/logic/commands/EmailCommandTest.java index 0f2ce64067e7..80abec8be1fd 100644 --- a/src/test/java/seedu/address/logic/commands/EmailCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/EmailCommandTest.java @@ -15,6 +15,7 @@ import seedu.address.logic.CommandHistory; import seedu.address.logic.UndoRedoStack; import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.logic.commands.exceptions.UnsupportDesktopException; import seedu.address.model.Model; import seedu.address.model.ModelManager; import seedu.address.model.UserPrefs; @@ -182,12 +183,10 @@ private static void assertEmailSuccess(String expectedResult, EmailCommand testC try { CommandResult result = testCommand.execute(); assertEquals(expectedResult, result.feedbackToUser); + } catch (UnsupportDesktopException de) { + assertEquals(de, new UnsupportDesktopException(Messages.UNSUPPORTED_DESKTOP)); } catch (CommandException ce) { - if (ce.equals(new CommandException(Messages.UNSUPPORTED_DESKTOP))) { - assertEquals(ce, (new CommandException(Messages.UNSUPPORTED_DESKTOP))); - } else { - throw new AssertionError("Execution of command should not fail.", ce); - } + throw new AssertionError("Execution of command should not fail.", ce); } } } From 220882e6890f112b725a760c59839de550033054 Mon Sep 17 00:00:00 2001 From: Alaru Date: Thu, 15 Mar 2018 03:27:08 +0800 Subject: [PATCH 41/66] Update test for systems that do not support Desktop v3 --- .../java/seedu/address/logic/commands/EmailCommandTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/seedu/address/logic/commands/EmailCommandTest.java b/src/test/java/seedu/address/logic/commands/EmailCommandTest.java index 80abec8be1fd..5e9aa0d73947 100644 --- a/src/test/java/seedu/address/logic/commands/EmailCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/EmailCommandTest.java @@ -184,7 +184,8 @@ private static void assertEmailSuccess(String expectedResult, EmailCommand testC CommandResult result = testCommand.execute(); assertEquals(expectedResult, result.feedbackToUser); } catch (UnsupportDesktopException de) { - assertEquals(de, new UnsupportDesktopException(Messages.UNSUPPORTED_DESKTOP)); + // Code is running on unsupported OS + assertEquals(de.getMessage(), Messages.UNSUPPORTED_DESKTOP); } catch (CommandException ce) { throw new AssertionError("Execution of command should not fail.", ce); } From 1033ca9073bb5d9a89b747bd80320c37028151f1 Mon Sep 17 00:00:00 2001 From: Alaru Date: Thu, 15 Mar 2018 09:54:02 +0800 Subject: [PATCH 42/66] Add EmailCommandParserTest --- .../logic/parser/EmailCommandParserTest.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/test/java/seedu/address/logic/parser/EmailCommandParserTest.java diff --git a/src/test/java/seedu/address/logic/parser/EmailCommandParserTest.java b/src/test/java/seedu/address/logic/parser/EmailCommandParserTest.java new file mode 100644 index 000000000000..4f1240baf2e6 --- /dev/null +++ b/src/test/java/seedu/address/logic/parser/EmailCommandParserTest.java @@ -0,0 +1,32 @@ +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 org.junit.Test; + +import seedu.address.logic.commands.EmailCommand; + +/** + * As we are only doing white-box testing, our test cases do not cover path variations + * outside of the EmailCommand code. For example, inputs "1" and "1 abc" take the + * same path through the EmailCommand, and therefore we test only one of them. + * The path variation for those two cases occur inside the ParserUtil, and + * therefore should be covered by the ParserUtilTest. + */ +public class EmailCommandParserTest { + + private EmailCommandParser parser = new EmailCommandParser(); + + @Test + public void parse_validArgs_returnsEmailCommand() { + assertParseSuccess(parser, "1", new EmailCommand(INDEX_FIRST_PERSON)); + } + + @Test + public void parse_invalidArgs_throwsParseException() { + assertParseFailure(parser, "a", String.format(MESSAGE_INVALID_COMMAND_FORMAT, EmailCommand.MESSAGE_USAGE)); + } +} From 3ae9a35c618953c73400354596890a52e1c07c6d Mon Sep 17 00:00:00 2001 From: Alaru Date: Thu, 15 Mar 2018 10:13:20 +0800 Subject: [PATCH 43/66] Update AddressBookParser --- .../seedu/address/logic/parser/AddressBookParserTest.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index 1d3888135e49..94bf958136cc 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -20,6 +20,7 @@ import seedu.address.logic.commands.DeleteCommand; import seedu.address.logic.commands.EditCommand; import seedu.address.logic.commands.EditCommand.EditPersonDescriptor; +import seedu.address.logic.commands.EmailCommand; import seedu.address.logic.commands.ExitCommand; import seedu.address.logic.commands.FindCommand; import seedu.address.logic.commands.HelpCommand; @@ -97,6 +98,13 @@ public void parseCommand_delete_sign() throws Exception { assertEquals(new DeleteCommand(INDEX_FIRST_PERSON), command); } + @Test + public void parseCommand_email() throws Exception { + EmailCommand command = (EmailCommand) parser.parseCommand( + EmailCommand.COMMAND_WORD + " " + INDEX_FIRST_PERSON.getOneBased()); + assertEquals(new EmailCommand(INDEX_FIRST_PERSON), command); + } + @Test public void parseCommand_edit() throws Exception { Person person = new PersonBuilder().build(); From 43a8c8703cf17316ef600dfd7ca8ea8af4cd1a3f Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 15 Mar 2018 11:59:14 +0800 Subject: [PATCH 44/66] Implement Matriculation Number --- docs/DeveloperGuide.adoc | 14 ++- docs/UserGuide.adoc | 20 ++-- .../address/logic/commands/AddCommand.java | 3 + .../address/logic/commands/EditCommand.java | 21 +++- .../address/logic/commands/FindCommand.java | 8 +- .../logic/parser/AddCommandParser.java | 12 ++- .../seedu/address/logic/parser/CliSyntax.java | 1 + .../logic/parser/EditCommandParser.java | 6 +- .../logic/parser/FindCommandParser.java | 4 +- .../address/logic/parser/ParserUtil.java | 27 ++++++ .../java/seedu/address/model/AddressBook.java | 3 +- ...ava => InfoContainsKeywordsPredicate.java} | 14 +-- .../model/person/MatriculationNumber.java | 63 ++++++++++++ .../seedu/address/model/person/Person.java | 11 ++- .../address/model/util/SampleDataUtil.java | 31 +++--- .../address/storage/XmlAdaptedPerson.java | 22 ++++- .../java/seedu/address/ui/PersonCard.java | 3 + src/main/resources/view/PersonListCard.fxml | 1 + .../typicalPersonsAddressBook.xml | 7 ++ .../data/XmlUtilTest/invalidPersonField.xml | 1 + .../data/XmlUtilTest/missingPersonField.xml | 1 + .../data/XmlUtilTest/validAddressBook.xml | 9 ++ src/test/data/XmlUtilTest/validPerson.xml | 1 + .../address/commons/util/XmlUtilTest.java | 7 +- .../logic/commands/CommandTestUtil.java | 15 ++- .../logic/commands/FindCommandTest.java | 12 +-- .../logic/parser/AddCommandParserTest.java | 97 ++++++++++++------- .../logic/parser/AddressBookParserTest.java | 6 +- .../logic/parser/FindCommandParserTest.java | 4 +- .../seedu/address/model/ModelManagerTest.java | 4 +- ...=> InfoContainsKeywordsPredicateTest.java} | 22 ++--- .../address/storage/XmlAdaptedPersonTest.java | 47 +++++++-- .../testutil/EditPersonDescriptorBuilder.java | 10 ++ .../seedu/address/testutil/PersonBuilder.java | 15 ++- .../seedu/address/testutil/PersonUtil.java | 2 + .../address/testutil/TypicalPersons.java | 17 +++- .../systemtests/AddCommandSystemTest.java | 83 +++++++++++----- .../systemtests/EditCommandSystemTest.java | 32 ++++-- .../systemtests/FindCommandSystemTest.java | 5 + 39 files changed, 501 insertions(+), 160 deletions(-) rename src/main/java/seedu/address/model/person/{NameContainsKeywordsPredicate.java => InfoContainsKeywordsPredicate.java} (51%) create mode 100644 src/main/java/seedu/address/model/person/MatriculationNumber.java rename src/test/java/seedu/address/model/person/{NameContainsKeywordsPredicateTest.java => InfoContainsKeywordsPredicateTest.java} (76%) diff --git a/docs/DeveloperGuide.adoc b/docs/DeveloperGuide.adoc index 736c58bbf896..2fe150f9fb12 100644 --- a/docs/DeveloperGuide.adoc +++ b/docs/DeveloperGuide.adoc @@ -196,6 +196,7 @@ image::DeletePersonSdForLogic.png[width="800"] [[Design-Model]] === Model component +(needs new image here that includes MatriculationNumber in person) .Structure of the Model Component image::ModelClassDiagram.png[width="800"] @@ -203,10 +204,15 @@ image::ModelClassDiagram.png[width="800"] 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. -* does not depend on any of the other three components. +* 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. +* Does not depend on any of the other three components. + +The `Person` Class, + +* Stores the information of a specific person(student) in the AddressBook +* Information includes: Name, Matriculation Number, Phone Number, Email, Address and different tags to associate with that person. [[Design-Storage]] === Storage component diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index 0b497b2880b2..e0586daceb4c 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -66,15 +66,15 @@ Format: `help` Adds a person to the address book + Alias: `a` and `+` + -Format: `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]...` +Format: `add n/NAME m/MATRICULATION NUMBER p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]...` [TIP] A person can have any number of tags (including 0) 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/John Doe m/A0111111X p/98765432 e/johnd@example.com a/John street, block 123, #01-01` +* `add n/Betsy Crowe t/friend m/A1234567C e/betsycrowe@example.com a/Newgate Prison p/1234567 t/criminal` === Listing all persons : `list` @@ -86,7 +86,7 @@ Format: `list` Edits an existing person in the address book. + Alias: `e` + -Format: `edit INDEX [n/NAME] [p/PHONE] [e/EMAIL] [a/ADDRESS] [t/TAG]...` +Format: `edit INDEX [n/NAME] [m/MATRICULATION NUMBER] [p/PHONE] [e/EMAIL] [a/ADDRESS] [t/TAG]...` **** * Edits the person at the specified `INDEX`. The index refers to the index number shown in the last person listing. The index *must be a positive integer* 1, 2, 3, ... @@ -103,16 +103,18 @@ Edits the phone number and email address of the 1st person to be `91234567` and * `edit 2 n/Betsy Crower t/` + Edits the name of the 2nd person to be `Betsy Crower` and clears all existing tags. -=== Locating persons by name: `find` +=== Locating persons by name or by matriculation number: `find` Finds persons whose names contain any of the given keywords. + +Or, finds a person whose matriculation number corresponds to the given keyword. + + Alias: `f` + 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` -* Only the name is searched. +* Only the name and the matriculation number 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` **** @@ -120,9 +122,11 @@ Format: `find KEYWORD [MORE_KEYWORDS]` Examples: * `find John` + -Returns `john` and `John Doe` +Returns `john` and `John Doe`. * `find Betsy Tim John` + -Returns any person having names `Betsy`, `Tim`, or `John` +Returns any person having names `Betsy`, `Tim`, or `John`. +* `find A0123456X` + +Returns any person having the matriculation number A0123456X. === Deleting a person : `delete` diff --git a/src/main/java/seedu/address/logic/commands/AddCommand.java b/src/main/java/seedu/address/logic/commands/AddCommand.java index 295f424e74c9..4d613f1d24a9 100644 --- a/src/main/java/seedu/address/logic/commands/AddCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddCommand.java @@ -3,6 +3,7 @@ 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_MATRIC_NUMBER; 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; @@ -23,12 +24,14 @@ public class AddCommand extends UndoableCommand { public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a person to the address book. " + "Parameters: " + PREFIX_NAME + "NAME " + + PREFIX_MATRIC_NUMBER + "MATRIC_NUMBER " + PREFIX_PHONE + "PHONE " + PREFIX_EMAIL + "EMAIL " + PREFIX_ADDRESS + "ADDRESS " + "[" + PREFIX_TAG + "TAG]...\n" + "Example: " + COMMAND_WORD + " " + PREFIX_NAME + "John Doe " + + PREFIX_MATRIC_NUMBER + "A1234567J" + PREFIX_PHONE + "98765432 " + PREFIX_EMAIL + "johnd@example.com " + PREFIX_ADDRESS + "311, Clementi Ave 2, #02-25 " diff --git a/src/main/java/seedu/address/logic/commands/EditCommand.java b/src/main/java/seedu/address/logic/commands/EditCommand.java index 3021c951a5b1..9f2af99da340 100644 --- a/src/main/java/seedu/address/logic/commands/EditCommand.java +++ b/src/main/java/seedu/address/logic/commands/EditCommand.java @@ -3,6 +3,7 @@ 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_MATRIC_NUMBER; 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; @@ -21,6 +22,7 @@ import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.model.person.Address; import seedu.address.model.person.Email; +import seedu.address.model.person.MatriculationNumber; import seedu.address.model.person.Name; import seedu.address.model.person.Person; import seedu.address.model.person.Phone; @@ -41,6 +43,7 @@ public class EditCommand extends UndoableCommand { + "Existing values will be overwritten by the input values.\n" + "Parameters: INDEX (must be a positive integer) " + "[" + PREFIX_NAME + "NAME] " + + "[" + PREFIX_MATRIC_NUMBER + "MATRICULATION NUMBER] " + "[" + PREFIX_PHONE + "PHONE] " + "[" + PREFIX_EMAIL + "EMAIL] " + "[" + PREFIX_ADDRESS + "ADDRESS] " @@ -104,12 +107,14 @@ private static Person createEditedPerson(Person personToEdit, EditPersonDescript assert personToEdit != null; Name updatedName = editPersonDescriptor.getName().orElse(personToEdit.getName()); + MatriculationNumber updatedMatricNumber = + editPersonDescriptor.getMatricNumber().orElse(personToEdit.getMatricNumber()); 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); + return new Person(updatedName, updatedMatricNumber, updatedPhone, updatedEmail, updatedAddress, updatedTags); } @Override @@ -137,6 +142,7 @@ public boolean equals(Object other) { */ public static class EditPersonDescriptor { private Name name; + private MatriculationNumber matricNumber; private Phone phone; private Email email; private Address address; @@ -150,6 +156,7 @@ public EditPersonDescriptor() {} */ public EditPersonDescriptor(EditPersonDescriptor toCopy) { setName(toCopy.name); + setMatricNumber(toCopy.matricNumber); setPhone(toCopy.phone); setEmail(toCopy.email); setAddress(toCopy.address); @@ -160,7 +167,8 @@ public EditPersonDescriptor(EditPersonDescriptor toCopy) { * Returns true if at least one field is edited. */ public boolean isAnyFieldEdited() { - return CollectionUtil.isAnyNonNull(this.name, this.phone, this.email, this.address, this.tags); + return CollectionUtil.isAnyNonNull(this.name, this.matricNumber, this.phone, this.email, + this.address, this.tags); } public void setName(Name name) { @@ -171,6 +179,14 @@ public Optional getName() { return Optional.ofNullable(name); } + public void setMatricNumber(MatriculationNumber matricNumber) { + this.matricNumber = matricNumber; + } + + public Optional getMatricNumber() { + return Optional.ofNullable(matricNumber); + } + public void setPhone(Phone phone) { this.phone = phone; } @@ -228,6 +244,7 @@ public boolean equals(Object other) { EditPersonDescriptor e = (EditPersonDescriptor) other; return getName().equals(e.getName()) + && getMatricNumber().equals(e.getMatricNumber()) && getPhone().equals(e.getPhone()) && getEmail().equals(e.getEmail()) && getAddress().equals(e.getAddress()) diff --git a/src/main/java/seedu/address/logic/commands/FindCommand.java b/src/main/java/seedu/address/logic/commands/FindCommand.java index a73078ed6ea3..79e00bc18b32 100644 --- a/src/main/java/seedu/address/logic/commands/FindCommand.java +++ b/src/main/java/seedu/address/logic/commands/FindCommand.java @@ -1,6 +1,6 @@ package seedu.address.logic.commands; -import seedu.address.model.person.NameContainsKeywordsPredicate; +import seedu.address.model.person.InfoContainsKeywordsPredicate; /** * Finds and lists all persons in address book whose name contains any of the argument keywords. @@ -16,11 +16,9 @@ public class FindCommand extends Command { + "Parameters: KEYWORD [MORE_KEYWORDS]...\n" + "Example: " + COMMAND_WORD + " alice bob charlie"; - private final NameContainsKeywordsPredicate predicate; + private final InfoContainsKeywordsPredicate predicate; - public FindCommand(NameContainsKeywordsPredicate predicate) { - this.predicate = predicate; - } + public FindCommand(InfoContainsKeywordsPredicate predicate) { this.predicate = predicate; } @Override public CommandResult execute() { diff --git a/src/main/java/seedu/address/logic/parser/AddCommandParser.java b/src/main/java/seedu/address/logic/parser/AddCommandParser.java index 3c729b388554..7e08c1fd0ee4 100644 --- a/src/main/java/seedu/address/logic/parser/AddCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/AddCommandParser.java @@ -3,6 +3,7 @@ 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_MATRIC_NUMBER; 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; @@ -15,6 +16,7 @@ import seedu.address.logic.parser.exceptions.ParseException; import seedu.address.model.person.Address; import seedu.address.model.person.Email; +import seedu.address.model.person.MatriculationNumber; import seedu.address.model.person.Name; import seedu.address.model.person.Person; import seedu.address.model.person.Phone; @@ -32,21 +34,25 @@ public class AddCommandParser implements Parser { */ 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_MATRIC_NUMBER, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS, PREFIX_TAG); - if (!arePrefixesPresent(argMultimap, PREFIX_NAME, PREFIX_ADDRESS, PREFIX_PHONE, PREFIX_EMAIL) + if (!arePrefixesPresent(argMultimap, PREFIX_NAME, + PREFIX_MATRIC_NUMBER, PREFIX_ADDRESS, PREFIX_PHONE, PREFIX_EMAIL) || !argMultimap.getPreamble().isEmpty()) { throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE)); } try { Name name = ParserUtil.parseName(argMultimap.getValue(PREFIX_NAME)).get(); + MatriculationNumber matricNumber = + ParserUtil.parseMatricNumber(argMultimap.getValue(PREFIX_MATRIC_NUMBER)).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(); Set tagList = ParserUtil.parseTags(argMultimap.getAllValues(PREFIX_TAG)); - Person person = new Person(name, phone, email, address, tagList); + Person person = new Person(name, matricNumber, phone, email, address, tagList); return new AddCommand(person); } catch (IllegalValueException ive) { diff --git a/src/main/java/seedu/address/logic/parser/CliSyntax.java b/src/main/java/seedu/address/logic/parser/CliSyntax.java index 75b1a9bf1190..7a598f83c1f7 100644 --- a/src/main/java/seedu/address/logic/parser/CliSyntax.java +++ b/src/main/java/seedu/address/logic/parser/CliSyntax.java @@ -7,6 +7,7 @@ public class CliSyntax { /* Prefix definitions */ public static final Prefix PREFIX_NAME = new Prefix("n/"); + public static final Prefix PREFIX_MATRIC_NUMBER = new Prefix("m/"); 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/"); diff --git a/src/main/java/seedu/address/logic/parser/EditCommandParser.java b/src/main/java/seedu/address/logic/parser/EditCommandParser.java index c9cdbed26cf1..4ba65c45908b 100644 --- a/src/main/java/seedu/address/logic/parser/EditCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/EditCommandParser.java @@ -4,6 +4,7 @@ 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_MATRIC_NUMBER; 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; @@ -33,7 +34,8 @@ public class EditCommandParser implements Parser { 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_MATRIC_NUMBER, PREFIX_PHONE, + PREFIX_EMAIL, PREFIX_ADDRESS, PREFIX_TAG); Index index; @@ -46,6 +48,8 @@ public EditCommand parse(String args) throws ParseException { EditPersonDescriptor editPersonDescriptor = new EditPersonDescriptor(); try { ParserUtil.parseName(argMultimap.getValue(PREFIX_NAME)).ifPresent(editPersonDescriptor::setName); + ParserUtil.parseMatricNumber(argMultimap.getValue(PREFIX_MATRIC_NUMBER)) + .ifPresent(editPersonDescriptor::setMatricNumber); ParserUtil.parsePhone(argMultimap.getValue(PREFIX_PHONE)).ifPresent(editPersonDescriptor::setPhone); ParserUtil.parseEmail(argMultimap.getValue(PREFIX_EMAIL)).ifPresent(editPersonDescriptor::setEmail); ParserUtil.parseAddress(argMultimap.getValue(PREFIX_ADDRESS)).ifPresent(editPersonDescriptor::setAddress); diff --git a/src/main/java/seedu/address/logic/parser/FindCommandParser.java b/src/main/java/seedu/address/logic/parser/FindCommandParser.java index b186a967cb94..b5f3d0c50324 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.person.InfoContainsKeywordsPredicate; /** * Parses input arguments and creates a new FindCommand object @@ -27,7 +27,7 @@ public FindCommand parse(String args) throws ParseException { String[] nameKeywords = trimmedArgs.split("\\s+"); - return new FindCommand(new NameContainsKeywordsPredicate(Arrays.asList(nameKeywords))); + return new FindCommand(new InfoContainsKeywordsPredicate(Arrays.asList(nameKeywords))); } } diff --git a/src/main/java/seedu/address/logic/parser/ParserUtil.java b/src/main/java/seedu/address/logic/parser/ParserUtil.java index 5d6d4ae3f7b1..6f9be47c0482 100644 --- a/src/main/java/seedu/address/logic/parser/ParserUtil.java +++ b/src/main/java/seedu/address/logic/parser/ParserUtil.java @@ -12,6 +12,7 @@ import seedu.address.commons.util.StringUtil; import seedu.address.model.person.Address; import seedu.address.model.person.Email; +import seedu.address.model.person.MatriculationNumber; import seedu.address.model.person.Name; import seedu.address.model.person.Phone; import seedu.address.model.tag.Tag; @@ -67,6 +68,32 @@ public static Optional parseName(Optional name) throws IllegalValu return name.isPresent() ? Optional.of(parseName(name.get())) : Optional.empty(); } + /** + * Parses a {@code String matricNumber} into a {@code MatriculationNumber}. + * Leading and trailing whitespaces will be trimmed. + * + * @throws IllegalValueException if the given {@code matricNumber} is invalid. + */ + public static MatriculationNumber parseMatricNumber(String matricNumber) throws IllegalValueException { + requireNonNull(matricNumber); + String trimmedMatricNumber = matricNumber.trim(); + if (!MatriculationNumber.isValidMatricNumber(trimmedMatricNumber)) { + throw new IllegalValueException(MatriculationNumber.MESSAGE_MATRIC_NUMBER_CONSTRAINTS); + } + return new MatriculationNumber(trimmedMatricNumber); + } + + /** + * Parses a {@code Optional matricNumber} into an {@code Optional} + * if {@code matricNumber} is present. + * See header comment of this class regarding the use of {@code Optional} parameters. + */ + public static Optional + parseMatricNumber(Optional matricNumber) throws IllegalValueException { + requireNonNull(matricNumber); + return matricNumber.isPresent() ? Optional.of(parseMatricNumber(matricNumber.get())) : Optional.empty(); + } + /** * Parses a {@code String phone} into a {@code Phone}. * Leading and trailing whitespaces will be trimmed. diff --git a/src/main/java/seedu/address/model/AddressBook.java b/src/main/java/seedu/address/model/AddressBook.java index f8d0260de159..db4265087978 100644 --- a/src/main/java/seedu/address/model/AddressBook.java +++ b/src/main/java/seedu/address/model/AddressBook.java @@ -132,7 +132,8 @@ private Person syncWithMasterTagList(Person person) { final Set correctTagReferences = new HashSet<>(); personTags.forEach(tag -> correctTagReferences.add(masterTagObjects.get(tag))); return new Person( - person.getName(), person.getPhone(), person.getEmail(), person.getAddress(), correctTagReferences); + person.getName(), person.getMatricNumber(), + person.getPhone(), person.getEmail(), person.getAddress(), correctTagReferences); } /** diff --git a/src/main/java/seedu/address/model/person/NameContainsKeywordsPredicate.java b/src/main/java/seedu/address/model/person/InfoContainsKeywordsPredicate.java similarity index 51% rename from src/main/java/seedu/address/model/person/NameContainsKeywordsPredicate.java rename to src/main/java/seedu/address/model/person/InfoContainsKeywordsPredicate.java index 827e2cc106bd..74787d1d9497 100644 --- a/src/main/java/seedu/address/model/person/NameContainsKeywordsPredicate.java +++ b/src/main/java/seedu/address/model/person/InfoContainsKeywordsPredicate.java @@ -6,26 +6,28 @@ import seedu.address.commons.util.StringUtil; /** - * Tests that a {@code Person}'s {@code Name} matches any of the keywords given. + * Tests that a {@code Person}'s {@code Name} and {@code MatriculationNumber} matches any of the keywords given. */ -public class NameContainsKeywordsPredicate implements Predicate { +public class InfoContainsKeywordsPredicate implements Predicate { private final List keywords; - public NameContainsKeywordsPredicate(List keywords) { + public InfoContainsKeywordsPredicate(List keywords) { this.keywords = keywords; } @Override public boolean test(Person person) { return keywords.stream() - .anyMatch(keyword -> StringUtil.containsWordIgnoreCase(person.getName().fullName, keyword)); + .anyMatch(keyword -> StringUtil.containsWordIgnoreCase(person.getName().fullName, keyword)) + || keywords.stream() + .anyMatch(keyword -> StringUtil.containsWordIgnoreCase(person.getMatricNumber().value, keyword)); } @Override public boolean equals(Object other) { return other == this // short circuit if same object - || (other instanceof NameContainsKeywordsPredicate // instanceof handles nulls - && this.keywords.equals(((NameContainsKeywordsPredicate) other).keywords)); // state check + || (other instanceof InfoContainsKeywordsPredicate // instanceof handles nulls + && this.keywords.equals(((InfoContainsKeywordsPredicate) other).keywords)); // state check } } diff --git a/src/main/java/seedu/address/model/person/MatriculationNumber.java b/src/main/java/seedu/address/model/person/MatriculationNumber.java new file mode 100644 index 000000000000..635223308308 --- /dev/null +++ b/src/main/java/seedu/address/model/person/MatriculationNumber.java @@ -0,0 +1,63 @@ +package seedu.address.model.person; + +import static java.util.Objects.requireNonNull; +import static seedu.address.commons.util.AppUtil.checkArgument; + +/** + * Represents a Person's phone number in the address book. + * Guarantees: immutable; is valid as declared in {@link #isValidMatricNumber(String)} + */ +public class MatriculationNumber { + + + public static final String MESSAGE_MATRIC_NUMBER_CONSTRAINTS = + "Matric numbers can only contain capital letters and numbers, and should contain 9 characters"; + public static final String MATRIC_NUMBER_VALIDATION_REGEX_FIRST = "[AU]{1}"; + public static final String MATRIC_NUMBER_VALIDATION_REGEX_SECOND = "\\d{7}"; + public static final String MATRIC_NUMBER_VALIDATION_REGEX_LAST = "[A-Z]{1}"; + public final String value; + + /** + * Constructs a {@code Phone}. + * + * @param matricNumber A valid matriculation number. + */ + public MatriculationNumber(String matricNumber) { + requireNonNull(matricNumber); + checkArgument(isValidMatricNumber(matricNumber), MESSAGE_MATRIC_NUMBER_CONSTRAINTS); + this.value = matricNumber; + } + + /** + * Returns true if a given string is a valid person phone number. + */ + public static boolean isValidMatricNumber(String test) { + if (test.length() != 9) { + return false; + } + String firstCharacter = test.substring(0, 1); + String nextCharacters = test.substring(1, test.length() - 1); + String lastCharacter = test.substring(test.length() - 1, test.length()); + return firstCharacter.matches(MATRIC_NUMBER_VALIDATION_REGEX_FIRST) + && nextCharacters.matches(MATRIC_NUMBER_VALIDATION_REGEX_SECOND) + && lastCharacter.matches(MATRIC_NUMBER_VALIDATION_REGEX_LAST); + } + + @Override + public String toString() { + return value; + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof MatriculationNumber // instanceof handles nulls + && this.value.equals(((MatriculationNumber) 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 index ec9f2aa5e919..f26b507ca4e0 100644 --- a/src/main/java/seedu/address/model/person/Person.java +++ b/src/main/java/seedu/address/model/person/Person.java @@ -16,6 +16,7 @@ public class Person { private final Name name; + private final MatriculationNumber matricNumber; private final Phone phone; private final Email email; private final Address address; @@ -25,9 +26,10 @@ public class Person { /** * Every field must be present and not null. */ - public Person(Name name, Phone phone, Email email, Address address, Set tags) { + public Person(Name name, MatriculationNumber matricNumber, Phone phone, Email email, Address address, Set tags) { requireAllNonNull(name, phone, email, address, tags); this.name = name; + this.matricNumber = matricNumber; this.phone = phone; this.email = email; this.address = address; @@ -39,6 +41,8 @@ public Name getName() { return name; } + public MatriculationNumber getMatricNumber() { return matricNumber; } + public Phone getPhone() { return phone; } @@ -71,6 +75,7 @@ public boolean equals(Object other) { Person otherPerson = (Person) other; return otherPerson.getName().equals(this.getName()) + && otherPerson.getMatricNumber().equals(this.getMatricNumber()) && otherPerson.getPhone().equals(this.getPhone()) && otherPerson.getEmail().equals(this.getEmail()) && otherPerson.getAddress().equals(this.getAddress()); @@ -79,13 +84,15 @@ public boolean equals(Object other) { @Override public int hashCode() { // use this method for custom fields hashing instead of implementing your own - return Objects.hash(name, phone, email, address, tags); + return Objects.hash(name, matricNumber, phone, email, address, tags); } @Override public String toString() { final StringBuilder builder = new StringBuilder(); builder.append(getName()) + .append(" Matriculation Number: ") + .append(getMatricNumber()) .append(" Phone: ") .append(getPhone()) .append(" Email: ") diff --git a/src/main/java/seedu/address/model/util/SampleDataUtil.java b/src/main/java/seedu/address/model/util/SampleDataUtil.java index aea96bfb31f3..8f3498356c19 100644 --- a/src/main/java/seedu/address/model/util/SampleDataUtil.java +++ b/src/main/java/seedu/address/model/util/SampleDataUtil.java @@ -7,6 +7,7 @@ import seedu.address.model.ReadOnlyAddressBook; import seedu.address.model.person.Address; import seedu.address.model.person.Email; +import seedu.address.model.person.MatriculationNumber; import seedu.address.model.person.Name; import seedu.address.model.person.Person; import seedu.address.model.person.Phone; @@ -19,24 +20,30 @@ 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 Person(new Name("Alex Yeoh"), new MatriculationNumber("A1234567X"), + 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"), + getTagSet("1")), + new Person(new Name("Bernice Yu"), new MatriculationNumber("A2234567Y"), + 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"), + getTagSet("2")), + new Person(new Name("Charlotte Oliveiro"), new MatriculationNumber("A1234567X"), + 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"), + getTagSet("exchange")), + new Person(new Name("David Li"), new MatriculationNumber("A3234567J"), + 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"), + getTagSet("retaking")), + new Person(new Name("Irfan Ibrahim"), new MatriculationNumber("A4234567K"), + 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"), + getTagSet("friend")), + new Person(new Name("Roy Balakrishnan"), new MatriculationNumber("A5234567G"), + new Phone("92624417"), new Email("royb@example.com"), new Address("Blk 45 Aljunied Street 85, #11-31"), - getTagSet("colleagues")) + getTagSet("brother")) }; } diff --git a/src/main/java/seedu/address/storage/XmlAdaptedPerson.java b/src/main/java/seedu/address/storage/XmlAdaptedPerson.java index 2cd92dc4fd20..a25d0d31a2c5 100644 --- a/src/main/java/seedu/address/storage/XmlAdaptedPerson.java +++ b/src/main/java/seedu/address/storage/XmlAdaptedPerson.java @@ -11,6 +11,7 @@ import seedu.address.commons.exceptions.IllegalValueException; import seedu.address.model.person.Address; import seedu.address.model.person.Email; +import seedu.address.model.person.MatriculationNumber; import seedu.address.model.person.Name; import seedu.address.model.person.Person; import seedu.address.model.person.Phone; @@ -26,6 +27,8 @@ public class XmlAdaptedPerson { @XmlElement(required = true) private String name; @XmlElement(required = true) + private String matricNumber; + @XmlElement(required = true) private String phone; @XmlElement(required = true) private String email; @@ -44,8 +47,10 @@ public XmlAdaptedPerson() {} /** * Constructs an {@code XmlAdaptedPerson} with the given person details. */ - public XmlAdaptedPerson(String name, String phone, String email, String address, List tagged) { + public XmlAdaptedPerson(String name, String matricNumber, String phone, + String email, String address, List tagged) { this.name = name; + this.matricNumber = matricNumber; this.phone = phone; this.email = email; this.address = address; @@ -61,6 +66,7 @@ public XmlAdaptedPerson(String name, String phone, String email, String address, */ public XmlAdaptedPerson(Person source) { name = source.getName().fullName; + matricNumber = source.getMatricNumber().value; phone = source.getPhone().value; email = source.getEmail().value; address = source.getAddress().value; @@ -89,6 +95,17 @@ public Person toModelType() throws IllegalValueException { } final Name name = new Name(this.name); + if (this.matricNumber == null) { + throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, + MatriculationNumber.class.getSimpleName())); + } + + if (!MatriculationNumber.isValidMatricNumber(this.matricNumber)) { + throw new IllegalValueException(MatriculationNumber.MESSAGE_MATRIC_NUMBER_CONSTRAINTS); + } + + final MatriculationNumber matricNumber = new MatriculationNumber(this.matricNumber); + if (this.phone == null) { throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Phone.class.getSimpleName())); } @@ -114,7 +131,7 @@ public Person toModelType() throws IllegalValueException { final Address address = new Address(this.address); final Set tags = new HashSet<>(personTags); - return new Person(name, phone, email, address, tags); + return new Person(name, matricNumber, phone, email, address, tags); } @Override @@ -129,6 +146,7 @@ public boolean equals(Object other) { XmlAdaptedPerson otherPerson = (XmlAdaptedPerson) other; return Objects.equals(name, otherPerson.name) + && Objects.equals(matricNumber, otherPerson.matricNumber) && Objects.equals(phone, otherPerson.phone) && Objects.equals(email, otherPerson.email) && Objects.equals(address, otherPerson.address) diff --git a/src/main/java/seedu/address/ui/PersonCard.java b/src/main/java/seedu/address/ui/PersonCard.java index 12ef73d54617..23d949a2512e 100644 --- a/src/main/java/seedu/address/ui/PersonCard.java +++ b/src/main/java/seedu/address/ui/PersonCard.java @@ -32,6 +32,8 @@ public class PersonCard extends UiPart { @FXML private Label name; @FXML + private Label matricNumber; + @FXML private Label id; @FXML private Label phone; @@ -47,6 +49,7 @@ public PersonCard(Person person, int displayedIndex) { this.person = person; id.setText(displayedIndex + ". "); name.setText(person.getName().fullName); + matricNumber.setText(person.getMatricNumber().value); phone.setText(person.getPhone().value); address.setText(person.getAddress().value); email.setText(person.getEmail().value); diff --git a/src/main/resources/view/PersonListCard.fxml b/src/main/resources/view/PersonListCard.fxml index f08ea32ad558..51a2dac3743c 100644 --- a/src/main/resources/view/PersonListCard.fxml +++ b/src/main/resources/view/PersonListCard.fxml @@ -28,6 +28,7 @@