From 2b5aa271892fe65c5538c5725f87af518306d605 Mon Sep 17 00:00:00 2001 From: Prian Kuhanandan Date: Wed, 7 Mar 2018 21:12:32 +0800 Subject: [PATCH 001/133] Add NFRs --- docs/DeveloperGuide.adoc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/DeveloperGuide.adoc b/docs/DeveloperGuide.adoc index 1733af113b29..5f2e231369f5 100644 --- a/docs/DeveloperGuide.adoc +++ b/docs/DeveloperGuide.adoc @@ -852,8 +852,10 @@ _{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. - -_{More to be added}_ +. The system should respond within 3 seconds, even for more intensive procedures such as balance calculation. +. The system should update its records immediately after the user makes an update. +. The system should provide helpful and clear messages to the user when errors occur. +. The system should preserve all data and user preferences when software updates are installed. [appendix] == Glossary From c78ccd6e20df04eee6fe4549cdf29b906ef1796e Mon Sep 17 00:00:00 2001 From: Chen Chongsong Date: Wed, 7 Mar 2018 22:02:32 +0800 Subject: [PATCH 002/133] create a removeTagCommand class to mimic EditCommand --- .../logic/commands/RemoveTagCommand.java | 236 ++++++++++++++++++ .../logic/parser/AddressBookParser.java | 17 +- .../logic/parser/RemoveTagCommandParser.java | 75 ++++++ 3 files changed, 315 insertions(+), 13 deletions(-) create mode 100644 src/main/java/seedu/address/logic/commands/RemoveTagCommand.java create mode 100644 src/main/java/seedu/address/logic/parser/RemoveTagCommandParser.java diff --git a/src/main/java/seedu/address/logic/commands/RemoveTagCommand.java b/src/main/java/seedu/address/logic/commands/RemoveTagCommand.java new file mode 100644 index 000000000000..423c1ea6b9a8 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/RemoveTagCommand.java @@ -0,0 +1,236 @@ +package seedu.address.logic.commands; + +import static java.util.Objects.requireNonNull; +import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS; +import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; +import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PERSONS; + +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; + +import seedu.address.commons.core.Messages; +import seedu.address.commons.core.index.Index; +import seedu.address.commons.util.CollectionUtil; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.person.Address; +import seedu.address.model.person.Email; +import seedu.address.model.person.Name; +import seedu.address.model.person.Person; +import seedu.address.model.person.Phone; +import seedu.address.model.person.exceptions.DuplicatePersonException; +import seedu.address.model.person.exceptions.PersonNotFoundException; +import seedu.address.model.tag.Tag; + +/** + * Edits the details of an existing person in the address book. + */ +public class RemoveTagCommand extends UndoableCommand { + + public static final String COMMAND_WORD = "removetag"; + + 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. " + + "Existing values will be overwritten by the input values.\n" + + "Parameters: INDEX (must be a positive integer) " + + "[" + PREFIX_NAME + "NAME] " + + "[" + PREFIX_PHONE + "PHONE] " + + "[" + PREFIX_EMAIL + "EMAIL] " + + "[" + PREFIX_ADDRESS + "ADDRESS] " + + "[" + PREFIX_TAG + "TAG]...\n" + + "Example: " + COMMAND_WORD + " 1 " + + PREFIX_PHONE + "91234567 " + + PREFIX_EMAIL + "johndoe@example.com"; + + public static final String MESSAGE_EDIT_PERSON_SUCCESS = "Edited Person: %1$s"; + public static final String MESSAGE_NOT_EDITED = "At least one field to edit must be provided."; + public static final String MESSAGE_DUPLICATE_PERSON = "This person already exists in the address book."; + + private final Index index; + private final EditPersonDescriptor editPersonDescriptor; + + private Person personToEdit; + private Person editedPerson; + + /** + * @param index of the person in the filtered person list to edit + * @param editPersonDescriptor details to edit the person with + */ + public RemoveTagCommand(Index index, EditPersonDescriptor editPersonDescriptor) { + requireNonNull(index); + requireNonNull(editPersonDescriptor); + + this.index = index; + this.editPersonDescriptor = new EditPersonDescriptor(editPersonDescriptor); + } + + @Override + public CommandResult executeUndoableCommand() throws CommandException { + try { + model.updatePerson(personToEdit, editedPerson); + } catch (DuplicatePersonException dpe) { + throw new CommandException(MESSAGE_DUPLICATE_PERSON); + } catch (PersonNotFoundException pnfe) { + throw new AssertionError("The target person cannot be missing"); + } + model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS); + return new CommandResult(String.format(MESSAGE_EDIT_PERSON_SUCCESS, editedPerson)); + } + + @Override + protected void preprocessUndoableCommand() throws CommandException { + List lastShownList = model.getFilteredPersonList(); + + if (index.getZeroBased() >= lastShownList.size()) { + throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + } + + personToEdit = lastShownList.get(index.getZeroBased()); + editedPerson = createEditedPerson(personToEdit, editPersonDescriptor); + } + + /** + * Creates and returns a {@code Person} with the details of {@code personToEdit} + * edited with {@code editPersonDescriptor}. + */ + private static Person createEditedPerson(Person personToEdit, EditPersonDescriptor editPersonDescriptor) { + assert personToEdit != null; + + Name updatedName = editPersonDescriptor.getName().orElse(personToEdit.getName()); + Phone updatedPhone = editPersonDescriptor.getPhone().orElse(personToEdit.getPhone()); + Email updatedEmail = editPersonDescriptor.getEmail().orElse(personToEdit.getEmail()); + Address updatedAddress = editPersonDescriptor.getAddress().orElse(personToEdit.getAddress()); + Set updatedTags = editPersonDescriptor.getTags().orElse(personToEdit.getTags()); + + return new Person(updatedName, updatedPhone, updatedEmail, updatedAddress, updatedTags); + } + + @Override + public boolean equals(Object other) { + // short circuit if same object + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof EditCommand)) { + return false; + } + + // state check + RemoveTagCommand e = (RemoveTagCommand) other; + return index.equals(e.index) + && editPersonDescriptor.equals(e.editPersonDescriptor) + && Objects.equals(personToEdit, e.personToEdit); + } + + /** + * Stores the details to edit the person with. Each non-empty field value will replace the + * corresponding field value of the person. + */ + public static class EditPersonDescriptor { + private Name name; + private Phone phone; + private Email email; + private Address address; + private Set tags; + + public EditPersonDescriptor() {} + + /** + * Copy constructor. + * A defensive copy of {@code tags} is used internally. + */ + public EditPersonDescriptor(EditPersonDescriptor toCopy) { + setName(toCopy.name); + setPhone(toCopy.phone); + setEmail(toCopy.email); + setAddress(toCopy.address); + setTags(toCopy.tags); + } + + /** + * 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); + } + + public void setName(Name name) { + this.name = name; + } + + public Optional getName() { + return Optional.ofNullable(name); + } + + public void setPhone(Phone phone) { + this.phone = phone; + } + + public Optional getPhone() { + return Optional.ofNullable(phone); + } + + public void setEmail(Email email) { + this.email = email; + } + + public Optional getEmail() { + return Optional.ofNullable(email); + } + + public void setAddress(Address address) { + this.address = address; + } + + public Optional
getAddress() { + return Optional.ofNullable(address); + } + + /** + * Sets {@code tags} to this object's {@code tags}. + * A defensive copy of {@code tags} is used internally. + */ + public void setTags(Set tags) { + this.tags = (tags != null) ? new HashSet<>(tags) : null; + } + + /** + * Returns an unmodifiable tag set, which throws {@code UnsupportedOperationException} + * if modification is attempted. + * Returns {@code Optional#empty()} if {@code tags} is null. + */ + public Optional> getTags() { + return (tags != null) ? Optional.of(Collections.unmodifiableSet(tags)) : Optional.empty(); + } + + @Override + public boolean equals(Object other) { + // short circuit if same object + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof EditPersonDescriptor)) { + return false; + } + + // state check + EditPersonDescriptor e = (EditPersonDescriptor) other; + + return getName().equals(e.getName()) + && getPhone().equals(e.getPhone()) + && getEmail().equals(e.getEmail()) + && getAddress().equals(e.getAddress()) + && getTags().equals(e.getTags()); + } + } +} diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index b7d57f5db86a..c5eb20fdbbf7 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -6,19 +6,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import seedu.address.logic.commands.AddCommand; -import seedu.address.logic.commands.ClearCommand; -import seedu.address.logic.commands.Command; -import seedu.address.logic.commands.DeleteCommand; -import seedu.address.logic.commands.EditCommand; -import seedu.address.logic.commands.ExitCommand; -import seedu.address.logic.commands.FindCommand; -import seedu.address.logic.commands.HelpCommand; -import seedu.address.logic.commands.HistoryCommand; -import seedu.address.logic.commands.ListCommand; -import seedu.address.logic.commands.RedoCommand; -import seedu.address.logic.commands.SelectCommand; -import seedu.address.logic.commands.UndoCommand; +import seedu.address.logic.commands.*; import seedu.address.logic.parser.exceptions.ParseException; /** @@ -54,6 +42,9 @@ public Command parseCommand(String userInput) throws ParseException { case EditCommand.COMMAND_WORD: return new EditCommandParser().parse(arguments); + case RemoveTagCommand.COMMAND_WORD: + return new RemoveTagCommandParser().parse(arguments); + case SelectCommand.COMMAND_WORD: return new SelectCommandParser().parse(arguments); diff --git a/src/main/java/seedu/address/logic/parser/RemoveTagCommandParser.java b/src/main/java/seedu/address/logic/parser/RemoveTagCommandParser.java new file mode 100644 index 000000000000..7799163a9b0e --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/RemoveTagCommandParser.java @@ -0,0 +1,75 @@ +package seedu.address.logic.parser; + +import seedu.address.commons.core.index.Index; +import seedu.address.commons.exceptions.IllegalValueException; +import seedu.address.logic.commands.RemoveTagCommand; +import seedu.address.logic.commands.RemoveTagCommand.EditPersonDescriptor; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.tag.Tag; + +import java.util.Collection; +import java.util.Collections; +import java.util.Optional; +import java.util.Set; + +import static java.util.Objects.requireNonNull; +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.parser.CliSyntax.*; + +/** + * Parses input arguments and creates a new EditCommand object + */ +public class RemoveTagCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the EditCommand + * and returns an EditCommand object for execution. + * @throws ParseException if the user input does not conform the expected format + */ + public RemoveTagCommand parse(String args) throws ParseException { + requireNonNull(args); + ArgumentMultimap argMultimap = + ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS, PREFIX_TAG); + + Index index; + + try { + index = ParserUtil.parseIndex(argMultimap.getPreamble()); + } catch (IllegalValueException ive) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, RemoveTagCommand.MESSAGE_USAGE)); + } + + EditPersonDescriptor editPersonDescriptor = new EditPersonDescriptor(); + try { + ParserUtil.parseName(argMultimap.getValue(PREFIX_NAME)).ifPresent(editPersonDescriptor::setName); + 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); + parseTagsForEdit(argMultimap.getAllValues(PREFIX_TAG)).ifPresent(editPersonDescriptor::setTags); + } catch (IllegalValueException ive) { + throw new ParseException(ive.getMessage(), ive); + } + + if (!editPersonDescriptor.isAnyFieldEdited()) { + throw new ParseException(RemoveTagCommand.MESSAGE_NOT_EDITED); + } + + return new RemoveTagCommand(index, editPersonDescriptor); + } + + /** + * Parses {@code Collection tags} into a {@code Set} if {@code tags} is non-empty. + * If {@code tags} contain only one element which is an empty string, it will be parsed into a + * {@code Set} containing zero tags. + */ + private Optional> parseTagsForEdit(Collection tags) throws IllegalValueException { + assert tags != null; + + if (tags.isEmpty()) { + return Optional.empty(); + } + Collection tagSet = tags.size() == 1 && tags.contains("") ? Collections.emptySet() : tags; + return Optional.of(ParserUtil.parseTags(tagSet)); + } + +} From 6cbe3ec37458ba3023b8fc2bf58e4da1489bf481 Mon Sep 17 00:00:00 2001 From: Chen Chongsong Date: Wed, 7 Mar 2018 22:26:45 +0800 Subject: [PATCH 003/133] modify the newly added RemoveTagCommand --- .../logic/commands/RemoveTagCommand.java | 19 +++++++++++-------- .../logic/parser/RemoveTagCommandParser.java | 6 +----- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/RemoveTagCommand.java b/src/main/java/seedu/address/logic/commands/RemoveTagCommand.java index 423c1ea6b9a8..6056c24d11d8 100644 --- a/src/main/java/seedu/address/logic/commands/RemoveTagCommand.java +++ b/src/main/java/seedu/address/logic/commands/RemoveTagCommand.java @@ -35,14 +35,9 @@ public class RemoveTagCommand extends UndoableCommand { public static final String COMMAND_WORD = "removetag"; - 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. " - + "Existing values will be overwritten by the input values.\n" + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Removes the specific tags of the person identified " + + "by the index number used in the last person listing.\n" + "Parameters: INDEX (must be a positive integer) " - + "[" + PREFIX_NAME + "NAME] " - + "[" + PREFIX_PHONE + "PHONE] " - + "[" + PREFIX_EMAIL + "EMAIL] " - + "[" + PREFIX_ADDRESS + "ADDRESS] " + "[" + PREFIX_TAG + "TAG]...\n" + "Example: " + COMMAND_WORD + " 1 " + PREFIX_PHONE + "91234567 " @@ -106,7 +101,15 @@ private static Person createEditedPerson(Person personToEdit, EditPersonDescript 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()); + + Set tempTags = editPersonDescriptor.getTags().orElse(personToEdit.getTags()); + HashSet updatedTags = new HashSet(); + + for (Tag t: personToEdit.getTags()) { + if (!tempTags.contains(t)) { + updatedTags.add(t); + } + } return new Person(updatedName, updatedPhone, updatedEmail, updatedAddress, updatedTags); } diff --git a/src/main/java/seedu/address/logic/parser/RemoveTagCommandParser.java b/src/main/java/seedu/address/logic/parser/RemoveTagCommandParser.java index 7799163a9b0e..569eaf90a718 100644 --- a/src/main/java/seedu/address/logic/parser/RemoveTagCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/RemoveTagCommandParser.java @@ -29,7 +29,7 @@ public class RemoveTagCommandParser implements Parser { public RemoveTagCommand 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_TAG); Index index; @@ -41,10 +41,6 @@ public RemoveTagCommand parse(String args) throws ParseException { EditPersonDescriptor editPersonDescriptor = new EditPersonDescriptor(); try { - ParserUtil.parseName(argMultimap.getValue(PREFIX_NAME)).ifPresent(editPersonDescriptor::setName); - 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); parseTagsForEdit(argMultimap.getAllValues(PREFIX_TAG)).ifPresent(editPersonDescriptor::setTags); } catch (IllegalValueException ive) { throw new ParseException(ive.getMessage(), ive); From 5583f442072a93eef5439894fbe9299f37cce457 Mon Sep 17 00:00:00 2001 From: Chen Chongsong Date: Wed, 7 Mar 2018 22:34:36 +0800 Subject: [PATCH 004/133] Revert "Chen Chongsong Enhancement" --- .../logic/commands/RemoveTagCommand.java | 239 ------------------ .../logic/parser/AddressBookParser.java | 17 +- .../logic/parser/RemoveTagCommandParser.java | 71 ------ 3 files changed, 13 insertions(+), 314 deletions(-) delete mode 100644 src/main/java/seedu/address/logic/commands/RemoveTagCommand.java delete mode 100644 src/main/java/seedu/address/logic/parser/RemoveTagCommandParser.java diff --git a/src/main/java/seedu/address/logic/commands/RemoveTagCommand.java b/src/main/java/seedu/address/logic/commands/RemoveTagCommand.java deleted file mode 100644 index 6056c24d11d8..000000000000 --- a/src/main/java/seedu/address/logic/commands/RemoveTagCommand.java +++ /dev/null @@ -1,239 +0,0 @@ -package seedu.address.logic.commands; - -import static java.util.Objects.requireNonNull; -import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS; -import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL; -import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; -import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; -import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; -import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PERSONS; - -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; - -import seedu.address.commons.core.Messages; -import seedu.address.commons.core.index.Index; -import seedu.address.commons.util.CollectionUtil; -import seedu.address.logic.commands.exceptions.CommandException; -import seedu.address.model.person.Address; -import seedu.address.model.person.Email; -import seedu.address.model.person.Name; -import seedu.address.model.person.Person; -import seedu.address.model.person.Phone; -import seedu.address.model.person.exceptions.DuplicatePersonException; -import seedu.address.model.person.exceptions.PersonNotFoundException; -import seedu.address.model.tag.Tag; - -/** - * Edits the details of an existing person in the address book. - */ -public class RemoveTagCommand extends UndoableCommand { - - public static final String COMMAND_WORD = "removetag"; - - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Removes the specific tags of the person identified " - + "by the index number used in the last person listing.\n" - + "Parameters: INDEX (must be a positive integer) " - + "[" + PREFIX_TAG + "TAG]...\n" - + "Example: " + COMMAND_WORD + " 1 " - + PREFIX_PHONE + "91234567 " - + PREFIX_EMAIL + "johndoe@example.com"; - - public static final String MESSAGE_EDIT_PERSON_SUCCESS = "Edited Person: %1$s"; - public static final String MESSAGE_NOT_EDITED = "At least one field to edit must be provided."; - public static final String MESSAGE_DUPLICATE_PERSON = "This person already exists in the address book."; - - private final Index index; - private final EditPersonDescriptor editPersonDescriptor; - - private Person personToEdit; - private Person editedPerson; - - /** - * @param index of the person in the filtered person list to edit - * @param editPersonDescriptor details to edit the person with - */ - public RemoveTagCommand(Index index, EditPersonDescriptor editPersonDescriptor) { - requireNonNull(index); - requireNonNull(editPersonDescriptor); - - this.index = index; - this.editPersonDescriptor = new EditPersonDescriptor(editPersonDescriptor); - } - - @Override - public CommandResult executeUndoableCommand() throws CommandException { - try { - model.updatePerson(personToEdit, editedPerson); - } catch (DuplicatePersonException dpe) { - throw new CommandException(MESSAGE_DUPLICATE_PERSON); - } catch (PersonNotFoundException pnfe) { - throw new AssertionError("The target person cannot be missing"); - } - model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS); - return new CommandResult(String.format(MESSAGE_EDIT_PERSON_SUCCESS, editedPerson)); - } - - @Override - protected void preprocessUndoableCommand() throws CommandException { - List lastShownList = model.getFilteredPersonList(); - - if (index.getZeroBased() >= lastShownList.size()) { - throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); - } - - personToEdit = lastShownList.get(index.getZeroBased()); - editedPerson = createEditedPerson(personToEdit, editPersonDescriptor); - } - - /** - * Creates and returns a {@code Person} with the details of {@code personToEdit} - * edited with {@code editPersonDescriptor}. - */ - private static Person createEditedPerson(Person personToEdit, EditPersonDescriptor editPersonDescriptor) { - assert personToEdit != null; - - Name updatedName = editPersonDescriptor.getName().orElse(personToEdit.getName()); - Phone updatedPhone = editPersonDescriptor.getPhone().orElse(personToEdit.getPhone()); - Email updatedEmail = editPersonDescriptor.getEmail().orElse(personToEdit.getEmail()); - Address updatedAddress = editPersonDescriptor.getAddress().orElse(personToEdit.getAddress()); - - Set tempTags = editPersonDescriptor.getTags().orElse(personToEdit.getTags()); - HashSet updatedTags = new HashSet(); - - for (Tag t: personToEdit.getTags()) { - if (!tempTags.contains(t)) { - updatedTags.add(t); - } - } - - return new Person(updatedName, updatedPhone, updatedEmail, updatedAddress, updatedTags); - } - - @Override - public boolean equals(Object other) { - // short circuit if same object - if (other == this) { - return true; - } - - // instanceof handles nulls - if (!(other instanceof EditCommand)) { - return false; - } - - // state check - RemoveTagCommand e = (RemoveTagCommand) other; - return index.equals(e.index) - && editPersonDescriptor.equals(e.editPersonDescriptor) - && Objects.equals(personToEdit, e.personToEdit); - } - - /** - * Stores the details to edit the person with. Each non-empty field value will replace the - * corresponding field value of the person. - */ - public static class EditPersonDescriptor { - private Name name; - private Phone phone; - private Email email; - private Address address; - private Set tags; - - public EditPersonDescriptor() {} - - /** - * Copy constructor. - * A defensive copy of {@code tags} is used internally. - */ - public EditPersonDescriptor(EditPersonDescriptor toCopy) { - setName(toCopy.name); - setPhone(toCopy.phone); - setEmail(toCopy.email); - setAddress(toCopy.address); - setTags(toCopy.tags); - } - - /** - * 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); - } - - public void setName(Name name) { - this.name = name; - } - - public Optional getName() { - return Optional.ofNullable(name); - } - - public void setPhone(Phone phone) { - this.phone = phone; - } - - public Optional getPhone() { - return Optional.ofNullable(phone); - } - - public void setEmail(Email email) { - this.email = email; - } - - public Optional getEmail() { - return Optional.ofNullable(email); - } - - public void setAddress(Address address) { - this.address = address; - } - - public Optional
getAddress() { - return Optional.ofNullable(address); - } - - /** - * Sets {@code tags} to this object's {@code tags}. - * A defensive copy of {@code tags} is used internally. - */ - public void setTags(Set tags) { - this.tags = (tags != null) ? new HashSet<>(tags) : null; - } - - /** - * Returns an unmodifiable tag set, which throws {@code UnsupportedOperationException} - * if modification is attempted. - * Returns {@code Optional#empty()} if {@code tags} is null. - */ - public Optional> getTags() { - return (tags != null) ? Optional.of(Collections.unmodifiableSet(tags)) : Optional.empty(); - } - - @Override - public boolean equals(Object other) { - // short circuit if same object - if (other == this) { - return true; - } - - // instanceof handles nulls - if (!(other instanceof EditPersonDescriptor)) { - return false; - } - - // state check - EditPersonDescriptor e = (EditPersonDescriptor) other; - - return getName().equals(e.getName()) - && getPhone().equals(e.getPhone()) - && getEmail().equals(e.getEmail()) - && getAddress().equals(e.getAddress()) - && getTags().equals(e.getTags()); - } - } -} diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index c5eb20fdbbf7..b7d57f5db86a 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -6,7 +6,19 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import seedu.address.logic.commands.*; +import seedu.address.logic.commands.AddCommand; +import seedu.address.logic.commands.ClearCommand; +import seedu.address.logic.commands.Command; +import seedu.address.logic.commands.DeleteCommand; +import seedu.address.logic.commands.EditCommand; +import seedu.address.logic.commands.ExitCommand; +import seedu.address.logic.commands.FindCommand; +import seedu.address.logic.commands.HelpCommand; +import seedu.address.logic.commands.HistoryCommand; +import seedu.address.logic.commands.ListCommand; +import seedu.address.logic.commands.RedoCommand; +import seedu.address.logic.commands.SelectCommand; +import seedu.address.logic.commands.UndoCommand; import seedu.address.logic.parser.exceptions.ParseException; /** @@ -42,9 +54,6 @@ public Command parseCommand(String userInput) throws ParseException { case EditCommand.COMMAND_WORD: return new EditCommandParser().parse(arguments); - case RemoveTagCommand.COMMAND_WORD: - return new RemoveTagCommandParser().parse(arguments); - case SelectCommand.COMMAND_WORD: return new SelectCommandParser().parse(arguments); diff --git a/src/main/java/seedu/address/logic/parser/RemoveTagCommandParser.java b/src/main/java/seedu/address/logic/parser/RemoveTagCommandParser.java deleted file mode 100644 index 569eaf90a718..000000000000 --- a/src/main/java/seedu/address/logic/parser/RemoveTagCommandParser.java +++ /dev/null @@ -1,71 +0,0 @@ -package seedu.address.logic.parser; - -import seedu.address.commons.core.index.Index; -import seedu.address.commons.exceptions.IllegalValueException; -import seedu.address.logic.commands.RemoveTagCommand; -import seedu.address.logic.commands.RemoveTagCommand.EditPersonDescriptor; -import seedu.address.logic.parser.exceptions.ParseException; -import seedu.address.model.tag.Tag; - -import java.util.Collection; -import java.util.Collections; -import java.util.Optional; -import java.util.Set; - -import static java.util.Objects.requireNonNull; -import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; -import static seedu.address.logic.parser.CliSyntax.*; - -/** - * Parses input arguments and creates a new EditCommand object - */ -public class RemoveTagCommandParser implements Parser { - - /** - * Parses the given {@code String} of arguments in the context of the EditCommand - * and returns an EditCommand object for execution. - * @throws ParseException if the user input does not conform the expected format - */ - public RemoveTagCommand parse(String args) throws ParseException { - requireNonNull(args); - ArgumentMultimap argMultimap = - ArgumentTokenizer.tokenize(args, PREFIX_TAG); - - Index index; - - try { - index = ParserUtil.parseIndex(argMultimap.getPreamble()); - } catch (IllegalValueException ive) { - throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, RemoveTagCommand.MESSAGE_USAGE)); - } - - EditPersonDescriptor editPersonDescriptor = new EditPersonDescriptor(); - try { - parseTagsForEdit(argMultimap.getAllValues(PREFIX_TAG)).ifPresent(editPersonDescriptor::setTags); - } catch (IllegalValueException ive) { - throw new ParseException(ive.getMessage(), ive); - } - - if (!editPersonDescriptor.isAnyFieldEdited()) { - throw new ParseException(RemoveTagCommand.MESSAGE_NOT_EDITED); - } - - return new RemoveTagCommand(index, editPersonDescriptor); - } - - /** - * Parses {@code Collection tags} into a {@code Set} if {@code tags} is non-empty. - * If {@code tags} contain only one element which is an empty string, it will be parsed into a - * {@code Set} containing zero tags. - */ - private Optional> parseTagsForEdit(Collection tags) throws IllegalValueException { - assert tags != null; - - if (tags.isEmpty()) { - return Optional.empty(); - } - Collection tagSet = tags.size() == 1 && tags.contains("") ? Collections.emptySet() : tags; - return Optional.of(ParserUtil.parseTags(tagSet)); - } - -} From 6cf215af052e6fee1b64a8a39d89eb9b69aa6794 Mon Sep 17 00:00:00 2001 From: Articho28 Date: Wed, 7 Mar 2018 23:03:36 +0800 Subject: [PATCH 005/133] Allowed program to recognize h alias as help command --- src/main/java/seedu/address/logic/commands/HelpCommand.java | 1 + .../java/seedu/address/logic/parser/AddressBookParser.java | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/main/java/seedu/address/logic/commands/HelpCommand.java b/src/main/java/seedu/address/logic/commands/HelpCommand.java index 10febf6d9136..b9e0bb205389 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_SHORTCUT = "h"; 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/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index b7d57f5db86a..e2c8ed2a0670 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -78,6 +78,9 @@ public Command parseCommand(String userInput) throws ParseException { case HelpCommand.COMMAND_WORD: return new HelpCommand(); + case HelpCommand.COMMAND_SHORTCUT: + return new HelpCommand(); + case UndoCommand.COMMAND_WORD: return new UndoCommand(); From 370034ca9b051058d4abd34eca6f1b2c08fa70e8 Mon Sep 17 00:00:00 2001 From: Articho28 Date: Wed, 7 Mar 2018 23:07:42 +0800 Subject: [PATCH 006/133] hi is now shortcut for History Command --- src/main/java/seedu/address/logic/commands/HistoryCommand.java | 1 + .../java/seedu/address/logic/parser/AddressBookParser.java | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/main/java/seedu/address/logic/commands/HistoryCommand.java b/src/main/java/seedu/address/logic/commands/HistoryCommand.java index f87abee5511d..27470095d89f 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_SHORTCUT = "hi"; 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/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index e2c8ed2a0670..8948076373ac 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -72,6 +72,9 @@ public Command parseCommand(String userInput) throws ParseException { case HistoryCommand.COMMAND_WORD: return new HistoryCommand(); + case HistoryCommand.COMMAND_SHORTCUT: + return new HistoryCommand(); + case ExitCommand.COMMAND_WORD: return new ExitCommand(); From 169e1eaeee3edf75962e7c5be9be002c23f0e13d Mon Sep 17 00:00:00 2001 From: Articho28 Date: Wed, 7 Mar 2018 23:09:34 +0800 Subject: [PATCH 007/133] c is now a shortcut for Clear command --- src/main/java/seedu/address/logic/commands/ClearCommand.java | 1 + .../java/seedu/address/logic/parser/AddressBookParser.java | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/main/java/seedu/address/logic/commands/ClearCommand.java b/src/main/java/seedu/address/logic/commands/ClearCommand.java index ceeb7ba913c6..3e55bbf2a9af 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_SHORTCUT = "c"; public static final String MESSAGE_SUCCESS = "Address book has been cleared!"; diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index 8948076373ac..3864e5d47a80 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -63,6 +63,9 @@ public Command parseCommand(String userInput) throws ParseException { case ClearCommand.COMMAND_WORD: return new ClearCommand(); + case ClearCommand.COMMAND_SHORTCUT: + return new ClearCommand(); + case FindCommand.COMMAND_WORD: return new FindCommandParser().parse(arguments); From d1e89def0b58a20194072853b37c876c3a114f37 Mon Sep 17 00:00:00 2001 From: Articho28 Date: Wed, 7 Mar 2018 23:11:56 +0800 Subject: [PATCH 008/133] l is now shortcut for list command --- src/main/java/seedu/address/logic/commands/ListCommand.java | 1 + .../java/seedu/address/logic/parser/AddressBookParser.java | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/main/java/seedu/address/logic/commands/ListCommand.java b/src/main/java/seedu/address/logic/commands/ListCommand.java index 7b6463780824..f234327a78fa 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_SHORTCUT = "l"; public static final String MESSAGE_SUCCESS = "Listed all persons"; diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index 3864e5d47a80..82fd27b8bc24 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -72,6 +72,9 @@ public Command parseCommand(String userInput) throws ParseException { case ListCommand.COMMAND_WORD: return new ListCommand(); + case ListCommand.COMMAND_SHORTCUT: + return new ListCommand(); + case HistoryCommand.COMMAND_WORD: return new HistoryCommand(); From acd295cbc0bf160e1b61c78347e118dbd6d03703 Mon Sep 17 00:00:00 2001 From: Articho28 Date: Wed, 7 Mar 2018 23:16:47 +0800 Subject: [PATCH 009/133] u is shortcut for Undo and r is shortcut for Redo --- src/main/java/seedu/address/logic/commands/RedoCommand.java | 1 + src/main/java/seedu/address/logic/commands/UndoCommand.java | 1 + .../java/seedu/address/logic/parser/AddressBookParser.java | 6 ++++++ 3 files changed, 8 insertions(+) diff --git a/src/main/java/seedu/address/logic/commands/RedoCommand.java b/src/main/java/seedu/address/logic/commands/RedoCommand.java index 7b99d0f372fc..1968d6298909 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_SHORTCUT = "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/UndoCommand.java b/src/main/java/seedu/address/logic/commands/UndoCommand.java index 1f3dcea8bbaa..c54b782c6fb8 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_SHORTCUT = "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 82fd27b8bc24..bd039ab3f6f3 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -93,9 +93,15 @@ public Command parseCommand(String userInput) throws ParseException { case UndoCommand.COMMAND_WORD: return new UndoCommand(); + case UndoCommand.COMMAND_SHORTCUT: + return new UndoCommand(); + case RedoCommand.COMMAND_WORD: return new RedoCommand(); + case RedoCommand.COMMAND_SHORTCUT: + return new RedoCommand(); + default: throw new ParseException(MESSAGE_UNKNOWN_COMMAND); } From 3beb42aa980a042176ea9894359c0a9da5278d02 Mon Sep 17 00:00:00 2001 From: Articho28 Date: Wed, 7 Mar 2018 23:29:57 +0800 Subject: [PATCH 010/133] a is shortcut for add --- src/main/java/seedu/address/logic/commands/AddCommand.java | 1 + .../java/seedu/address/logic/parser/AddressBookParser.java | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/main/java/seedu/address/logic/commands/AddCommand.java b/src/main/java/seedu/address/logic/commands/AddCommand.java index c334710c0ea3..a8a81d52bedb 100644 --- a/src/main/java/seedu/address/logic/commands/AddCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddCommand.java @@ -17,6 +17,7 @@ public class AddCommand extends UndoableCommand { public static final String COMMAND_WORD = "add"; + public static final String COMMAND_SHORTCUT = "a"; 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/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index bd039ab3f6f3..2ac748d2f1bc 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -51,6 +51,9 @@ public Command parseCommand(String userInput) throws ParseException { case AddCommand.COMMAND_WORD: return new AddCommandParser().parse(arguments); + case AddCommand.COMMAND_SHORTCUT: + return new AddCommandParser().parse(arguments); + case EditCommand.COMMAND_WORD: return new EditCommandParser().parse(arguments); From 06dbf2fab68edbec21cad4631f9e13b25ad2c0b6 Mon Sep 17 00:00:00 2001 From: Articho28 Date: Wed, 7 Mar 2018 23:32:11 +0800 Subject: [PATCH 011/133] d is shorcut for delete --- src/main/java/seedu/address/logic/commands/DeleteCommand.java | 1 + .../java/seedu/address/logic/parser/AddressBookParser.java | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/main/java/seedu/address/logic/commands/DeleteCommand.java b/src/main/java/seedu/address/logic/commands/DeleteCommand.java index b539d240001a..1872fb71418d 100644 --- a/src/main/java/seedu/address/logic/commands/DeleteCommand.java +++ b/src/main/java/seedu/address/logic/commands/DeleteCommand.java @@ -17,6 +17,7 @@ public class DeleteCommand extends UndoableCommand { public static final String COMMAND_WORD = "delete"; + public static final String COMMAND_SHORTCUT = "d"; 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/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index 2ac748d2f1bc..582768a0c5ce 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -63,6 +63,9 @@ public Command parseCommand(String userInput) throws ParseException { case DeleteCommand.COMMAND_WORD: return new DeleteCommandParser().parse(arguments); + case DeleteCommand.COMMAND_SHORTCUT: + return new DeleteCommandParser().parse(arguments); + case ClearCommand.COMMAND_WORD: return new ClearCommand(); From 424275aea2a6b381a37a1626aa6c749956082113 Mon Sep 17 00:00:00 2001 From: Articho28 Date: Wed, 7 Mar 2018 23:34:45 +0800 Subject: [PATCH 012/133] e is now shortcut for edit --- src/main/java/seedu/address/logic/commands/EditCommand.java | 1 + .../java/seedu/address/logic/parser/AddressBookParser.java | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/main/java/seedu/address/logic/commands/EditCommand.java b/src/main/java/seedu/address/logic/commands/EditCommand.java index e6c3a3e034bc..82e695678bc2 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_SHORTCUT = "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/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index 582768a0c5ce..26430dab7165 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -57,6 +57,9 @@ public Command parseCommand(String userInput) throws ParseException { case EditCommand.COMMAND_WORD: return new EditCommandParser().parse(arguments); + case EditCommand.COMMAND_SHORTCUT: + return new EditCommandParser().parse(arguments); + case SelectCommand.COMMAND_WORD: return new SelectCommandParser().parse(arguments); From 3634375cfdaf5d266957e1bd8beac784a003c840 Mon Sep 17 00:00:00 2001 From: Articho28 Date: Wed, 7 Mar 2018 23:36:28 +0800 Subject: [PATCH 013/133] f is now shortcut for find --- src/main/java/seedu/address/logic/commands/FindCommand.java | 1 + .../java/seedu/address/logic/parser/AddressBookParser.java | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/main/java/seedu/address/logic/commands/FindCommand.java b/src/main/java/seedu/address/logic/commands/FindCommand.java index b1e671f633d2..42b94dca88e8 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_SHORTCUT = "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/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index 26430dab7165..a01f42e90c60 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -78,6 +78,9 @@ public Command parseCommand(String userInput) throws ParseException { case FindCommand.COMMAND_WORD: return new FindCommandParser().parse(arguments); + case FindCommand.COMMAND_SHORTCUT: + return new FindCommandParser().parse(arguments); + case ListCommand.COMMAND_WORD: return new ListCommand(); From 94509bf7dc76cece8ad111bf38b0ba85ce92912a Mon Sep 17 00:00:00 2001 From: Articho28 Date: Wed, 7 Mar 2018 23:38:23 +0800 Subject: [PATCH 014/133] s is now shortcut for Select --- src/main/java/seedu/address/logic/commands/SelectCommand.java | 1 + .../java/seedu/address/logic/parser/AddressBookParser.java | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/main/java/seedu/address/logic/commands/SelectCommand.java b/src/main/java/seedu/address/logic/commands/SelectCommand.java index 9e3840a9dde6..a9ef8bcd1dce 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_SHORTCUT = "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/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index a01f42e90c60..62833a66a45e 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -63,6 +63,9 @@ public Command parseCommand(String userInput) throws ParseException { case SelectCommand.COMMAND_WORD: return new SelectCommandParser().parse(arguments); + case SelectCommand.COMMAND_SHORTCUT: + return new SelectCommandParser().parse(arguments); + case DeleteCommand.COMMAND_WORD: return new DeleteCommandParser().parse(arguments); From 8fb756b95c8549c8d99d5eb44bcbced15183c657 Mon Sep 17 00:00:00 2001 From: Articho28 Date: Wed, 7 Mar 2018 23:48:01 +0800 Subject: [PATCH 015/133] Updated User Guide to include shortcuts --- docs/UserGuide.adoc | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index 74248917e438..2245ec171c34 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -56,14 +56,15 @@ e.g. typing *`help`* and pressing kbd:[Enter] will open the help window. * Parameters can be in any order e.g. if the command specifies `n/NAME p/PHONE_NUMBER`, `p/PHONE_NUMBER n/NAME` is also acceptable. ==== -=== Viewing help : `help` +=== Viewing help : `help` or `h` Format: `help` -=== Adding a person: `add` +=== Adding a person: `add` or `a` Adds a person to the address book + Format: `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]...` +Format: `a n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]...` [TIP] A person can have any number of tags (including 0) @@ -72,16 +73,21 @@ 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` +* `a n/Betsy Crowe t/friend e/betsycrowe@example.com a/Newgate Prison p/1234567 t/criminal` -=== Listing all persons : `list` + +=== Listing all persons : `list` or `l` Shows a list of all persons in the address book. + -Format: `list` +Format: `list` or `l` -=== Editing a person : `edit` +=== Editing a person : `edit` or `e` Edits an existing person in the address book. + Format: `edit INDEX [n/NAME] [p/PHONE] [e/EMAIL] [a/ADDRESS] [t/TAG]...` +Format: `e INDEX [n/NAME] [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, ... @@ -95,13 +101,13 @@ Examples: * `edit 1 p/91234567 e/johndoe@example.com` + Edits the phone number and email address of the 1st person to be `91234567` and `johndoe@example.com` respectively. -* `edit 2 n/Betsy Crower t/` + +* `edit 2 n/Betsy Crower t/` or `e 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: `find` or `f` Finds persons whose names contain any of the given keywords. + -Format: `find KEYWORD [MORE_KEYWORDS]` +Format: `find KEYWORD [MORE_KEYWORDS]` or `f KEYWORD [MORE_KEYWORDS]` **** * The search is case insensitive. e.g `hans` will match `Hans` @@ -121,7 +127,7 @@ Returns any person having names `Betsy`, `Tim`, or `John` === Deleting a person : `delete` Deletes the specified person from the address book. + -Format: `delete INDEX` +Format: `delete INDEX` or `d INDEX` **** * Deletes the person at the specified `INDEX`. @@ -137,11 +143,13 @@ Deletes the 2nd person in the address book. * `find Betsy` + `delete 1` + Deletes the 1st person in the results of the `find` command. +`d 1` + +Deletes the 1st person in the results of the `find` command. -=== Selecting a person : `select` +=== Selecting a person : `select` or `s` Selects the person identified by the index number used in the last person listing. + -Format: `select INDEX` +Format: `select INDEX` or `s INDEX` **** * Selects the person and loads the Google search page the person at the specified `INDEX`. @@ -158,10 +166,10 @@ Selects the 2nd person in the address book. `select 1` + Selects the 1st person in the results of the `find` command. -=== Listing entered commands : `history` +=== Listing entered commands : `history` or `hi` Lists all the commands that you have entered in reverse chronological order. + -Format: `history` +Format: `history` or `hi` [NOTE] ==== @@ -169,7 +177,7 @@ Pressing the kbd:[↑] and kbd:[↓] arrows will display the previous and ==== // tag::undoredo[] -=== Undoing previous command : `undo` +=== Undoing previous command : `undo` or `u` Restores the address book to the state before the previous _undoable_ command was executed. + Format: `undo` @@ -183,7 +191,7 @@ Examples: * `delete 1` + `list` + -`undo` (reverses the `delete 1` command) + +`undo` or `u` (reverses the `delete 1` command) + * `select 1` + `list` + @@ -218,10 +226,10 @@ The `redo` command fails as there are no `undo` commands executed previously. `redo` (reapplies the `clear` command) + // end::undoredo[] -=== Clearing all entries : `clear` +=== Clearing all entries : `clear` or `c` Clears all entries from the address book. + -Format: `clear` +Format: `clear` or `c` === Exiting the program : `exit` From 3eb8d87e485e812caaeb8fcb794bf0acf804e3a0 Mon Sep 17 00:00:00 2001 From: Articho28 Date: Thu, 8 Mar 2018 00:05:43 +0800 Subject: [PATCH 016/133] Added JUnit test for help shortcut --- .../address/logic/parser/AddressBookParserTest.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index 7466da232666..0e56fd591b51 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -48,12 +48,15 @@ public void parseCommand_add() throws Exception { 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_delete() throws Exception { DeleteCommand command = (DeleteCommand) parser.parseCommand( @@ -90,6 +93,12 @@ public void parseCommand_help() throws Exception { assertTrue(parser.parseCommand(HelpCommand.COMMAND_WORD + " 3") instanceof HelpCommand); } + @Test + public void parseCommand_helpWithShortcut() throws Exception { + assertTrue(parser.parseCommand(HelpCommand.COMMAND_SHORTCUT) instanceof HelpCommand); + assertTrue(parser.parseCommand(HelpCommand.COMMAND_SHORTCUT + " 3") instanceof HelpCommand); + } + @Test public void parseCommand_history() throws Exception { assertTrue(parser.parseCommand(HistoryCommand.COMMAND_WORD) instanceof HistoryCommand); From 7e82e88affff68f59cbf860482c733e0d57ac4a7 Mon Sep 17 00:00:00 2001 From: Articho28 Date: Thu, 8 Mar 2018 00:07:01 +0800 Subject: [PATCH 017/133] Added test for list shortcut --- .../seedu/address/logic/parser/AddressBookParserTest.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index 0e56fd591b51..303310c9d2f4 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -118,6 +118,12 @@ public void parseCommand_list() throws Exception { assertTrue(parser.parseCommand(ListCommand.COMMAND_WORD + " 3") instanceof ListCommand); } + @Test + public void parseCommand_listWithShortcut() throws Exception { + assertTrue(parser.parseCommand(ListCommand.COMMAND_SHORTCUT) instanceof ListCommand); + assertTrue(parser.parseCommand(ListCommand.COMMAND_SHORTCUT + " 3") instanceof ListCommand); + } + @Test public void parseCommand_select() throws Exception { SelectCommand command = (SelectCommand) parser.parseCommand( From dd12262b2f8e16f4f54e1de7f069fcc1d56fc0fd Mon Sep 17 00:00:00 2001 From: Articho28 Date: Thu, 8 Mar 2018 00:08:09 +0800 Subject: [PATCH 018/133] Added test for clear command shortcut --- .../seedu/address/logic/parser/AddressBookParserTest.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index 303310c9d2f4..14bb65bb53f6 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -55,8 +55,12 @@ public void parseCommand_clear() throws Exception { assertTrue(parser.parseCommand(ClearCommand.COMMAND_WORD + " 3") instanceof ClearCommand); } - - + @Test + public void parseCommand_clearWithShortcut() throws Exception { + assertTrue(parser.parseCommand(ClearCommand.COMMAND_SHORTCUT) instanceof ClearCommand); + assertTrue(parser.parseCommand(ClearCommand.COMMAND_SHORTCUT + " 3") instanceof ClearCommand); + } + @Test public void parseCommand_delete() throws Exception { DeleteCommand command = (DeleteCommand) parser.parseCommand( From eb95f6e98584469ca790b20f62ff54e51979d912 Mon Sep 17 00:00:00 2001 From: Articho28 Date: Thu, 8 Mar 2018 00:09:22 +0800 Subject: [PATCH 019/133] Added test for history shortcut --- .../logic/parser/AddressBookParserTest.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index 14bb65bb53f6..00088f456532 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -60,7 +60,7 @@ public void parseCommand_clearWithShortcut() throws Exception { assertTrue(parser.parseCommand(ClearCommand.COMMAND_SHORTCUT) instanceof ClearCommand); assertTrue(parser.parseCommand(ClearCommand.COMMAND_SHORTCUT + " 3") instanceof ClearCommand); } - + @Test public void parseCommand_delete() throws Exception { DeleteCommand command = (DeleteCommand) parser.parseCommand( @@ -116,6 +116,19 @@ public void parseCommand_history() throws Exception { } } + @Test + public void parseCommand_historyWithShortcut() throws Exception { + assertTrue(parser.parseCommand(HistoryCommand.COMMAND_SHORTCUT) instanceof HistoryCommand); + assertTrue(parser.parseCommand(HistoryCommand.COMMAND_SHORTCUT + " 3") instanceof HistoryCommand); + + try { + parser.parseCommand("histories"); + fail("The expected ParseException was not thrown."); + } catch (ParseException pe) { + assertEquals(MESSAGE_UNKNOWN_COMMAND, pe.getMessage()); + } + } + @Test public void parseCommand_list() throws Exception { assertTrue(parser.parseCommand(ListCommand.COMMAND_WORD) instanceof ListCommand); From 957f9197e7bd96fdaa647ce3f8c4b97b508d6c33 Mon Sep 17 00:00:00 2001 From: Articho28 Date: Thu, 8 Mar 2018 00:11:42 +0800 Subject: [PATCH 020/133] Added tests for find, edit, and delete shortcuts --- .../logic/parser/AddressBookParserTest.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index 00088f456532..7ae94d6fe1ca 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -68,6 +68,13 @@ public void parseCommand_delete() throws Exception { assertEquals(new DeleteCommand(INDEX_FIRST_PERSON), command); } + @Test + public void parseCommand_deleteWithShortcut() throws Exception { + DeleteCommand command = (DeleteCommand) parser.parseCommand( + DeleteCommand.COMMAND_SHORTCUT + " " + INDEX_FIRST_PERSON.getOneBased()); + assertEquals(new DeleteCommand(INDEX_FIRST_PERSON), command); + } + @Test public void parseCommand_edit() throws Exception { Person person = new PersonBuilder().build(); @@ -77,6 +84,15 @@ public void parseCommand_edit() throws Exception { assertEquals(new EditCommand(INDEX_FIRST_PERSON, descriptor), command); } + @Test + public void parseCommand_editWithShortcut() throws Exception { + Person person = new PersonBuilder().build(); + EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder(person).build(); + EditCommand command = (EditCommand) parser.parseCommand(EditCommand.COMMAND_SHORTCUT + " " + + INDEX_FIRST_PERSON.getOneBased() + " " + PersonUtil.getPersonDetails(person)); + assertEquals(new EditCommand(INDEX_FIRST_PERSON, descriptor), command); + } + @Test public void parseCommand_exit() throws Exception { assertTrue(parser.parseCommand(ExitCommand.COMMAND_WORD) instanceof ExitCommand); @@ -91,6 +107,14 @@ public void parseCommand_find() throws Exception { assertEquals(new FindCommand(new NameContainsKeywordsPredicate(keywords)), command); } + @Test + public void parseCommand_findWithShortcut() throws Exception { + List keywords = Arrays.asList("foo", "bar", "baz"); + FindCommand command = (FindCommand) parser.parseCommand( + FindCommand.COMMAND_SHORTCUT + " " + 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); From 18e53c4b9fec1fe227d0297ab464aa9e8557991f Mon Sep 17 00:00:00 2001 From: Articho28 Date: Thu, 8 Mar 2018 00:13:25 +0800 Subject: [PATCH 021/133] Added tests for redo, undo, select shortcuts --- .../logic/parser/AddressBookParserTest.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index 7ae94d6fe1ca..7c30767ab278 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -172,18 +172,37 @@ public void parseCommand_select() throws Exception { assertEquals(new SelectCommand(INDEX_FIRST_PERSON), command); } + @Test + public void parseCommand_selectWithShortcut() throws Exception { + SelectCommand command = (SelectCommand) parser.parseCommand( + SelectCommand.COMMAND_SHORTCUT + " " + 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_redoCommandWord_returnsRedoCommandWithShortcut() throws Exception { + assertTrue(parser.parseCommand(RedoCommand.COMMAND_SHORTCUT) instanceof RedoCommand); + assertTrue(parser.parseCommand("redo 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_undoCommandWord_returnsUndoCommandWithShortcut() throws Exception { + assertTrue(parser.parseCommand(UndoCommand.COMMAND_SHORTCUT) instanceof UndoCommand); + assertTrue(parser.parseCommand("undo 3") instanceof UndoCommand); + } + @Test public void parseCommand_unrecognisedInput_throwsParseException() throws Exception { thrown.expect(ParseException.class); From 6f90b276643d2b0d1928ed88cb831c16f8d09040 Mon Sep 17 00:00:00 2001 From: Articho28 Date: Thu, 8 Mar 2018 00:25:31 +0800 Subject: [PATCH 022/133] Added test for add command shortcut --- .../address/logic/parser/AddressBookParserTest.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index 7c30767ab278..d7b17f1598ab 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -47,7 +47,14 @@ public void parseCommand_add() throws Exception { AddCommand command = (AddCommand) parser.parseCommand(PersonUtil.getAddCommand(person)); assertEquals(new AddCommand(person), command); } - + + @Test + public void parseCommand_addWithShortcut() throws Exception { + Person person = new PersonBuilder().build(); + AddCommand command = (AddCommand) parser.parseCommand(AddCommand.COMMAND_SHORTCUT + " " + + PersonUtil.getPersonDetails(person)); + assertEquals(new AddCommand(person), command); + } @Test public void parseCommand_clear() throws Exception { From 302636499e9e8cb1374ab02d9980b9a6e0b8a593 Mon Sep 17 00:00:00 2001 From: Articho28 Date: Thu, 8 Mar 2018 00:52:56 +0800 Subject: [PATCH 023/133] Updated Target user profile, value proposition, and user stories --- docs/DeveloperGuide.adoc | 22 ++++++++++++++++++- .../logic/parser/AddressBookParserTest.java | 2 +- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/docs/DeveloperGuide.adoc b/docs/DeveloperGuide.adoc index 5f2e231369f5..6adbd4e56b1f 100644 --- a/docs/DeveloperGuide.adoc +++ b/docs/DeveloperGuide.adoc @@ -787,8 +787,20 @@ See this https://github.com/se-edu/addressbook-level4/pull/599[PR] for the step- * can type fast * prefers typing over mouse input * is reasonably comfortable using CLI apps +* has a need to manage finances with fellow contacts +* has a need to keep track of personal balance +* has a need to keep track of transactions between contacts +* travels with a group and lends money/borrows money. -*Value proposition*: manage contacts faster than a typical mouse/GUI driven app +*Value proposition*: + +* manage contacts faster than a typical mouse/GUI driven app +* easily keep track of balances and debts between contacts +* easily see your overall balance +* easily see contacts that owe you money +* easily see contacts to which you are in debt +* easily keep track of transactions between contacts +* easily update balance once debts are paid [appendix] == User Stories @@ -811,6 +823,14 @@ Priorities: High (must have) - `* * \*`, Medium (nice to have) - `* \*`, Low (un |`*` |user with many persons in the address book |sort persons by name |locate a person easily |======================================================================= +|`* * *` |user | add/update/settle an amount of money that a contact owes me +|`* * *` |user | check my overall balance +|`* *` |user | see which contacts owe me money +|`* *` |user | see to which of my contacts do I owe money +|`* *` |user | see for which items do I owe a contact / a contact owes me +|`* ` |user | select the currency that I am owed +|`* ` |user | convert my balance into a different currency +|`*` |user | calculate the amount I am owed with an applied interest rate _{More to be added}_ [appendix] diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index d7b17f1598ab..e125512eed19 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -47,7 +47,7 @@ public void parseCommand_add() throws Exception { AddCommand command = (AddCommand) parser.parseCommand(PersonUtil.getAddCommand(person)); assertEquals(new AddCommand(person), command); } - + @Test public void parseCommand_addWithShortcut() throws Exception { Person person = new PersonBuilder().build(); From 94db81b518be6e78a8ab679141027ce7ea7b1d83 Mon Sep 17 00:00:00 2001 From: Articho28 Date: Tue, 13 Mar 2018 18:29:50 +0800 Subject: [PATCH 024/133] Fixed formatting issues in Developper Guide --- docs/DeveloperGuide.adoc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/DeveloperGuide.adoc b/docs/DeveloperGuide.adoc index 6adbd4e56b1f..943e887af67b 100644 --- a/docs/DeveloperGuide.adoc +++ b/docs/DeveloperGuide.adoc @@ -821,17 +821,16 @@ Priorities: High (must have) - `* * \*`, Medium (nice to have) - `* \*`, Low (un |`* *` |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 | add/update/settle an amount of money that a contact owes me |`* * *` |user | check my overall balance -|`* *` |user | see which contacts owe me money -|`* *` |user | see to which of my contacts do I owe money +|`* * *` |user | see which contacts owe me money +|`* * *` |user | see to which of my contacts do I owe money |`* *` |user | see for which items do I owe a contact / a contact owes me |`* ` |user | select the currency that I am owed |`* ` |user | convert my balance into a different currency |`*` |user | calculate the amount I am owed with an applied interest rate -_{More to be added}_ +|======================================================================= [appendix] == Use Cases From c5ed3ab341a979a2622ac826489ef75b2b8de4b0 Mon Sep 17 00:00:00 2001 From: Prian Kuhanandan Date: Tue, 13 Mar 2018 22:48:59 +0800 Subject: [PATCH 025/133] Remove Codacy badge --- README.adoc | 1 - 1 file changed, 1 deletion(-) diff --git a/README.adoc b/README.adoc index 03eff3a4d191..19a41765efb0 100644 --- a/README.adoc +++ b/README.adoc @@ -4,7 +4,6 @@ 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://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://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]] ifdef::env-github[] From 62e5b07b7dd4ebaa24d65ae72ffcbf5d6ca89868 Mon Sep 17 00:00:00 2001 From: Prian Kuhanandan Date: Tue, 13 Mar 2018 23:06:51 +0800 Subject: [PATCH 026/133] Style errors (#10) --- src/main/java/seedu/address/logic/parser/AddressBookParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index 62833a66a45e..f9d1bc6de1d5 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -115,7 +115,7 @@ public Command parseCommand(String userInput) throws ParseException { return new RedoCommand(); case RedoCommand.COMMAND_SHORTCUT: - return new RedoCommand(); + return new RedoCommand(); default: throw new ParseException(MESSAGE_UNKNOWN_COMMAND); From ad3b9ede498a6508f10dd7d3dc99ce397ed6312f Mon Sep 17 00:00:00 2001 From: chenchongsong Date: Wed, 14 Mar 2018 10:14:34 +0800 Subject: [PATCH 027/133] fix user story format --- docs/DeveloperGuide.adoc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/DeveloperGuide.adoc b/docs/DeveloperGuide.adoc index 943e887af67b..4aea446b6d4f 100644 --- a/docs/DeveloperGuide.adoc +++ b/docs/DeveloperGuide.adoc @@ -822,14 +822,14 @@ Priorities: High (must have) - `* * \*`, Medium (nice to have) - `* \*`, Low (un |`*` |user with many persons in the address book |sort persons by name |locate a person easily -|`* * *` |user | add/update/settle an amount of money that a contact owes me -|`* * *` |user | check my overall balance -|`* * *` |user | see which contacts owe me money -|`* * *` |user | see to which of my contacts do I owe money -|`* *` |user | see for which items do I owe a contact / a contact owes me -|`* ` |user | select the currency that I am owed -|`* ` |user | convert my balance into a different currency -|`*` |user | calculate the amount I am owed with an applied interest rate +|`* * *` |user | add/update/settle an amount of money that a contact owes me | +|`* * *` |user | check my overall balance | +|`* * *` |user | see which contacts owe me money | +|`* * *` |user | see to which of my contacts do I owe money | +|`* *` |user | see for which items do I owe a contact / a contact owes me | +|`* ` |user | select the currency that I am owed | +|`* ` |user | convert my balance into a different currency | +|`*` |user | calculate the amount I am owed with an applied interest rate | |======================================================================= [appendix] From 5313f1b5d8c2205871d28e436682694490f954b6 Mon Sep 17 00:00:00 2001 From: chenchongsong Date: Wed, 14 Mar 2018 10:34:43 +0800 Subject: [PATCH 028/133] update use cases --- docs/DeveloperGuide.adoc | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.adoc b/docs/DeveloperGuide.adoc index 4aea446b6d4f..a8743d61a2dd 100644 --- a/docs/DeveloperGuide.adoc +++ b/docs/DeveloperGuide.adoc @@ -863,7 +863,44 @@ Use case ends. + Use case resumes at step 2. -_{More to be added}_ +[discrete] +=== Use case: To Split a Bill Among Multiple People + +*MSS* + +1. User requests to new a bill +2. AddressBook shows the new bill +3. User requests selects who the bill will be splited among +4. AddressBook shows who the bill will be splited among in the contact details ++ +Use case ends. + +*Extensions* + +* 1a. Specified people does not exist. ++ +[none] +** 1a1. AddressBook shows an error message. ++ +Use case resumes at step 2. + +[discrete] +=== Use case: To See Who Owes Me Money + +*MSS* + +1. User requests to see people who owes the user Money +2. AddressBook shows the list of people ++ +Use case ends. + +*Extensions* + +* 1a. No people owe the user money. ++ +[none] +** 1a1. AddressBook shows an message showing that the list is empty. ++ [appendix] == Non Functional Requirements From 5063e9e75758107d556975da3bdf762920970751 Mon Sep 17 00:00:00 2001 From: Artsiom Skliar Date: Thu, 15 Mar 2018 11:19:47 +0800 Subject: [PATCH 029/133] User and Developer Guide Update including instructions on the balance feature. (#24) * Updated userguide to include balance feature * Updated Coming in V2.0 features * Updated Developper Guide for Balance feature --- docs/DeveloperGuide.adoc | 4 ++-- docs/UserGuide.adoc | 20 ++++++++++++++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/docs/DeveloperGuide.adoc b/docs/DeveloperGuide.adoc index 943e887af67b..6a84e9baea6f 100644 --- a/docs/DeveloperGuide.adoc +++ b/docs/DeveloperGuide.adoc @@ -1,4 +1,4 @@ -= AddressBook Level 4 - Developer Guide += TravelBanker - Developer Guide :toc: :toc-title: :toc-placement: preamble @@ -68,7 +68,7 @@ Optionally, you can follow the <> docume ==== Updating documentation to match your fork -After forking the repo, links in the documentation will still point to the `se-edu/addressbook-level4` repo. If you plan to develop this as a separate product (i.e. instead of contributing to the `se-edu/addressbook-level4`) , you should replace the URL in the variable `repoURL` in `DeveloperGuide.adoc` and `UserGuide.adoc` with the URL of your fork. +After forking the repo, links in the documentation will still point to the `CS2103JAN2018/main` repo. If you plan to develop this as a separate product (i.e. instead of contributing to the `CS2103JAN2018/main`) , you should replace the URL in the variable `repoURL` in `DeveloperGuide.adoc` and `UserGuide.adoc` with the URL of your fork. ==== Setting up CI diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index 2245ec171c34..e3bc116e3bae 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -1,4 +1,4 @@ -= AddressBook Level 4 - User Guide += TravelBanker- User Guide :toc: :toc-title: :toc-placement: preamble @@ -17,7 +17,7 @@ By: `Team SE-EDU` Since: `Jun 2016` Licence: `MIT` == Introduction -AddressBook Level 4 (AB4) is for those who *prefer to use a desktop app for managing contacts*. More importantly, AB4 is *optimized for those who prefer to work with a Command Line Interface* (CLI) while still having the benefits of a Graphical User Interface (GUI). If you can type fast, AB4 can get your contact management tasks done faster than traditional GUI apps. Interested? Jump to the <> to get started. Enjoy! +TravelBanker (TB) is for those who *prefer to use a desktop app for managing the money owed by your fellow travellers *. More importantly, TB is *optimized for those who prefer to work with a Command Line Interface* (CLI) while still having the benefits of a Graphical User Interface (GUI). If you can type fast, TB can get your contact management tasks done faster than traditional GUI apps. Interested? Jump to the <> to get started. Enjoy! == Quick Start @@ -42,6 +42,8 @@ e.g. typing *`help`* and pressing kbd:[Enter] will open the help window. * **`delete`**`3` : deletes the 3rd contact shown in the current list * *`exit`* : exits the app +* Except for `exit`, you can also use the first letter of each command to type faster (e.g. `l` for `list`). + . Refer to <> for details of each command. [[Features]] @@ -124,7 +126,7 @@ Returns `john` and `John Doe` * `find Betsy Tim John` + Returns any person having names `Betsy`, `Tim`, or `John` -=== Deleting a person : `delete` +=== Deleting a person : `delete` or `d` Deletes the specified person from the address book. + Format: `delete INDEX` or `d INDEX` @@ -203,7 +205,7 @@ The `undo` command fails as there are no undoable commands executed previously. `undo` (reverses the `clear` command) + `undo` (reverses the `delete 1` command) + -=== Redoing the previously undone command : `redo` +=== Redoing the previously undone command : `redo` or `r` Reverses the most recent `undo` command. + Format: `redo` @@ -238,15 +240,20 @@ Format: `exit` === Saving the data -Address book data are saved in the hard disk automatically after any command that changes the data. + +TravelBanker data are saved in the hard disk automatically after any command that changes the data. + There is no need to save manually. // tag::dataencryption[] -=== Encrypting data files `[coming in v2.0]` +=== Encrypting data files `[Coming in v2.0]` _{explain how the user can enable/disable data encryption}_ // end::dataencryption[] +=== Checking overall balance: `balance` or `b` `[Coming in v2.0]` + +Calculates your total balance. + +Format: `balance` or `b` + == FAQ *Q*: How do I transfer my data to another Computer? + @@ -259,6 +266,7 @@ e.g. `add n/James Ho p/22224444 e/jamesho@example.com a/123, Clementi Rd, 123466 * *Clear* : `clear` * *Delete* : `delete INDEX` + e.g. `delete 3` +* *Balance* : `balance` * *Edit* : `edit INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [a/ADDRESS] [t/TAG]...` + e.g. `edit 2 n/James Lee e/jameslee@example.com` * *Find* : `find KEYWORD [MORE_KEYWORDS]` + From 32afd24577db7c1593aba8199723bdaf2aa944e2 Mon Sep 17 00:00:00 2001 From: Prian Kuhanandan Date: Thu, 15 Mar 2018 11:26:42 +0800 Subject: [PATCH 030/133] Update UserGuide.adoc (#22) --- docs/UserGuide.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index e3bc116e3bae..f796484855f0 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -86,8 +86,8 @@ Format: `list` or `l` === Editing a person : `edit` or `e` Edits an existing person in the address book. + -Format: `edit INDEX [n/NAME] [p/PHONE] [e/EMAIL] [a/ADDRESS] [t/TAG]...` -Format: `e INDEX [n/NAME] [p/PHONE] [e/EMAIL] [a/ADDRESS] [t/TAG]...` +Format: `edit INDEX [n/NAME] [p/PHONE] [e/EMAIL] [a/ADDRESS] [m/MONEY] [t/TAG]...` +Format: `e INDEX [n/NAME] [p/PHONE] [e/EMAIL] [a/ADDRESS] [m/MONEY] [t/TAG]...` From e2fa60c9bd922f797390fe790bd5e973f2f8e147 Mon Sep 17 00:00:00 2001 From: Prian Kuhanandan Date: Sat, 17 Mar 2018 02:44:27 +0800 Subject: [PATCH 031/133] Add money field and add/edit capability (#28) * Initial work to create money field * Ccs v1.1 updatecode (#21) * fix user story format * update use cases * update money field. (storage & JUnit not yet done) * update AddCommand message * fix type error in Travis Cl * fix type error to pass Travis Cl * Merge stashed changes * Small fix * Fix bad merge * Fix tests --- docs/DeveloperGuide.adoc | 55 +++++++++++++--- .../address/logic/commands/AddCommand.java | 3 + .../address/logic/commands/EditCommand.java | 23 ++++++- .../logic/parser/AddCommandParser.java | 16 ++++- .../seedu/address/logic/parser/CliSyntax.java | 1 + .../logic/parser/EditCommandParser.java | 7 +- .../address/logic/parser/ParserUtil.java | 25 +++++++ .../java/seedu/address/model/AddressBook.java | 7 +- .../java/seedu/address/model/money/Money.java | 65 +++++++++++++++++++ .../seedu/address/model/person/Person.java | 16 ++++- .../address/model/util/SampleDataUtil.java | 13 ++-- .../address/storage/XmlAdaptedPerson.java | 16 ++++- .../java/seedu/address/ui/PersonCard.java | 3 + src/main/resources/view/PersonListCard.fxml | 1 + .../invalidAndValidPersonAddressBook.xml | 2 + .../invalidPersonAddressBook.xml | 1 + .../invalidPersonAddressBook.xml | 1 + .../typicalPersonsAddressBook.xml | 7 ++ .../data/XmlUtilTest/invalidPersonField.xml | 1 + .../data/XmlUtilTest/missingPersonField.xml | 1 + src/test/data/XmlUtilTest/tempAddressBook.xml | 1 + .../data/XmlUtilTest/validAddressBook.xml | 9 +++ src/test/data/XmlUtilTest/validPerson.xml | 1 + .../address/commons/util/XmlUtilTest.java | 7 +- .../logic/commands/CommandTestUtil.java | 9 ++- .../logic/parser/AddCommandParserTest.java | 63 ++++++++++-------- .../address/storage/XmlAdaptedPersonTest.java | 23 ++++--- .../testutil/EditPersonDescriptorBuilder.java | 10 +++ .../seedu/address/testutil/PersonBuilder.java | 17 ++++- .../seedu/address/testutil/PersonUtil.java | 2 + .../address/testutil/TypicalPersons.java | 26 ++++---- .../systemtests/AddCommandSystemTest.java | 27 +++++--- .../systemtests/EditCommandSystemTest.java | 14 ++-- 33 files changed, 374 insertions(+), 99 deletions(-) create mode 100644 src/main/java/seedu/address/model/money/Money.java diff --git a/docs/DeveloperGuide.adoc b/docs/DeveloperGuide.adoc index 6a84e9baea6f..9bb707e3cb3e 100644 --- a/docs/DeveloperGuide.adoc +++ b/docs/DeveloperGuide.adoc @@ -822,14 +822,14 @@ Priorities: High (must have) - `* * \*`, Medium (nice to have) - `* \*`, Low (un |`*` |user with many persons in the address book |sort persons by name |locate a person easily -|`* * *` |user | add/update/settle an amount of money that a contact owes me -|`* * *` |user | check my overall balance -|`* * *` |user | see which contacts owe me money -|`* * *` |user | see to which of my contacts do I owe money -|`* *` |user | see for which items do I owe a contact / a contact owes me -|`* ` |user | select the currency that I am owed -|`* ` |user | convert my balance into a different currency -|`*` |user | calculate the amount I am owed with an applied interest rate +|`* * *` |user | add/update/settle an amount of money that a contact owes me | +|`* * *` |user | check my overall balance | +|`* * *` |user | see which contacts owe me money | +|`* * *` |user | see to which of my contacts do I owe money | +|`* *` |user | see for which items do I owe a contact / a contact owes me | +|`* ` |user | select the currency that I am owed | +|`* ` |user | convert my balance into a different currency | +|`*` |user | calculate the amount I am owed with an applied interest rate | |======================================================================= [appendix] @@ -863,7 +863,44 @@ Use case ends. + Use case resumes at step 2. -_{More to be added}_ +[discrete] +=== Use case: To Split a Bill Among Multiple People + +*MSS* + +1. User requests to new a bill +2. AddressBook shows the new bill +3. User requests selects who the bill will be splited among +4. AddressBook shows who the bill will be splited among in the contact details ++ +Use case ends. + +*Extensions* + +* 1a. Specified people does not exist. ++ +[none] +** 1a1. AddressBook shows an error message. ++ +Use case resumes at step 2. + +[discrete] +=== Use case: To See Who Owes Me Money + +*MSS* + +1. User requests to see people who owes the user Money +2. AddressBook shows the list of people ++ +Use case ends. + +*Extensions* + +* 1a. No people owe the user money. ++ +[none] +** 1a1. AddressBook shows an message showing that the list is empty. ++ [appendix] == Non Functional Requirements diff --git a/src/main/java/seedu/address/logic/commands/AddCommand.java b/src/main/java/seedu/address/logic/commands/AddCommand.java index a8a81d52bedb..f449c7217741 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_MONEY; 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; @@ -25,12 +26,14 @@ public class AddCommand extends UndoableCommand { + PREFIX_PHONE + "PHONE " + PREFIX_EMAIL + "EMAIL " + PREFIX_ADDRESS + "ADDRESS " + + PREFIX_MONEY + "MONEY " + "[" + PREFIX_TAG + "TAG]...\n" + "Example: " + COMMAND_WORD + " " + PREFIX_NAME + "John Doe " + PREFIX_PHONE + "98765432 " + PREFIX_EMAIL + "johnd@example.com " + PREFIX_ADDRESS + "311, Clementi Ave 2, #02-25 " + + PREFIX_MONEY + "10 " + PREFIX_TAG + "friends " + PREFIX_TAG + "owesMoney"; diff --git a/src/main/java/seedu/address/logic/commands/EditCommand.java b/src/main/java/seedu/address/logic/commands/EditCommand.java index 82e695678bc2..ca5705ad77c6 100644 --- a/src/main/java/seedu/address/logic/commands/EditCommand.java +++ b/src/main/java/seedu/address/logic/commands/EditCommand.java @@ -3,9 +3,11 @@ 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_MONEY; import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; + import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PERSONS; import java.util.Collections; @@ -19,6 +21,7 @@ import seedu.address.commons.core.index.Index; import seedu.address.commons.util.CollectionUtil; import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.money.Money; import seedu.address.model.person.Address; import seedu.address.model.person.Email; import seedu.address.model.person.Name; @@ -44,10 +47,12 @@ public class EditCommand extends UndoableCommand { + "[" + PREFIX_PHONE + "PHONE] " + "[" + PREFIX_EMAIL + "EMAIL] " + "[" + PREFIX_ADDRESS + "ADDRESS] " + + "[" + PREFIX_MONEY + "BALANCE] " + "[" + PREFIX_TAG + "TAG]...\n" + "Example: " + COMMAND_WORD + " 1 " + PREFIX_PHONE + "91234567 " - + PREFIX_EMAIL + "johndoe@example.com"; + + PREFIX_EMAIL + "johndoe@example.com " + + PREFIX_MONEY + "43.00"; public static final String MESSAGE_EDIT_PERSON_SUCCESS = "Edited Person: %1$s"; public static final String MESSAGE_NOT_EDITED = "At least one field to edit must be provided."; @@ -107,9 +112,10 @@ private static Person createEditedPerson(Person personToEdit, EditPersonDescript Phone updatedPhone = editPersonDescriptor.getPhone().orElse(personToEdit.getPhone()); Email updatedEmail = editPersonDescriptor.getEmail().orElse(personToEdit.getEmail()); Address updatedAddress = editPersonDescriptor.getAddress().orElse(personToEdit.getAddress()); + Money updatedMoney = editPersonDescriptor.getMoney().orElse(personToEdit.getMoney()); Set updatedTags = editPersonDescriptor.getTags().orElse(personToEdit.getTags()); - return new Person(updatedName, updatedPhone, updatedEmail, updatedAddress, updatedTags); + return new Person(updatedName, updatedPhone, updatedEmail, updatedAddress, updatedMoney, updatedTags); } @Override @@ -140,6 +146,7 @@ public static class EditPersonDescriptor { private Phone phone; private Email email; private Address address; + private Money money; private Set tags; public EditPersonDescriptor() {} @@ -153,6 +160,7 @@ public EditPersonDescriptor(EditPersonDescriptor toCopy) { setPhone(toCopy.phone); setEmail(toCopy.email); setAddress(toCopy.address); + setMoney(toCopy.money); setTags(toCopy.tags); } @@ -160,7 +168,7 @@ 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.phone, this.email, this.address, this.money, this.tags); } public void setName(Name name) { @@ -195,6 +203,14 @@ public Optional
getAddress() { return Optional.ofNullable(address); } + public void setMoney(Money money) { + this.money = money; + } + + public Optional getMoney() { + return Optional.ofNullable(money); + } + /** * Sets {@code tags} to this object's {@code tags}. * A defensive copy of {@code tags} is used internally. @@ -231,6 +247,7 @@ public boolean equals(Object other) { && getPhone().equals(e.getPhone()) && getEmail().equals(e.getEmail()) && getAddress().equals(e.getAddress()) + && getMoney().equals(e.getMoney()) && getTags().equals(e.getTags()); } } diff --git a/src/main/java/seedu/address/logic/parser/AddCommandParser.java b/src/main/java/seedu/address/logic/parser/AddCommandParser.java index 3c729b388554..a20a99f530ea 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_MONEY; 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; @@ -13,6 +14,7 @@ import seedu.address.commons.exceptions.IllegalValueException; import seedu.address.logic.commands.AddCommand; import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.money.Money; import seedu.address.model.person.Address; import seedu.address.model.person.Email; import seedu.address.model.person.Name; @@ -32,9 +34,16 @@ 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_PHONE, + PREFIX_EMAIL, + PREFIX_ADDRESS, + PREFIX_MONEY, + PREFIX_TAG); - if (!arePrefixesPresent(argMultimap, PREFIX_NAME, PREFIX_ADDRESS, PREFIX_PHONE, PREFIX_EMAIL) + if (!arePrefixesPresent(argMultimap, PREFIX_NAME, PREFIX_ADDRESS, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_MONEY) || !argMultimap.getPreamble().isEmpty()) { throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE)); } @@ -44,9 +53,10 @@ public AddCommand parse(String args) throws ParseException { 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(); + Money money = ParserUtil.parseMoney(argMultimap.getValue(PREFIX_MONEY)).get(); Set tagList = ParserUtil.parseTags(argMultimap.getAllValues(PREFIX_TAG)); - Person person = new Person(name, phone, email, address, tagList); + Person person = new Person(name, phone, email, address, money, 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..52fd3eab646f 100644 --- a/src/main/java/seedu/address/logic/parser/CliSyntax.java +++ b/src/main/java/seedu/address/logic/parser/CliSyntax.java @@ -10,6 +10,7 @@ public class CliSyntax { public static final Prefix PREFIX_PHONE = new Prefix("p/"); public static final Prefix PREFIX_EMAIL = new Prefix("e/"); public static final Prefix PREFIX_ADDRESS = new Prefix("a/"); + public static final Prefix PREFIX_MONEY = new Prefix("m/"); public static final Prefix PREFIX_TAG = new Prefix("t/"); } diff --git a/src/main/java/seedu/address/logic/parser/EditCommandParser.java b/src/main/java/seedu/address/logic/parser/EditCommandParser.java index c9cdbed26cf1..d7b6f0cb3cdd 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_MONEY; 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; @@ -24,7 +25,6 @@ * Parses input arguments and creates a new EditCommand object */ public class EditCommandParser implements Parser { - /** * Parses the given {@code String} of arguments in the context of the EditCommand * and returns an EditCommand object for execution. @@ -33,8 +33,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_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS, PREFIX_MONEY, + PREFIX_TAG); Index index; try { @@ -49,6 +49,7 @@ public EditCommand parse(String args) throws ParseException { 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); + ParserUtil.parseMoney(argMultimap.getValue(PREFIX_MONEY)).ifPresent(editPersonDescriptor::setMoney); parseTagsForEdit(argMultimap.getAllValues(PREFIX_TAG)).ifPresent(editPersonDescriptor::setTags); } catch (IllegalValueException ive) { throw new ParseException(ive.getMessage(), ive); diff --git a/src/main/java/seedu/address/logic/parser/ParserUtil.java b/src/main/java/seedu/address/logic/parser/ParserUtil.java index 5d6d4ae3f7b1..ec0cfcaee680 100644 --- a/src/main/java/seedu/address/logic/parser/ParserUtil.java +++ b/src/main/java/seedu/address/logic/parser/ParserUtil.java @@ -10,6 +10,7 @@ import seedu.address.commons.core.index.Index; import seedu.address.commons.exceptions.IllegalValueException; import seedu.address.commons.util.StringUtil; +import seedu.address.model.money.Money; import seedu.address.model.person.Address; import seedu.address.model.person.Email; import seedu.address.model.person.Name; @@ -139,6 +140,30 @@ public static Optional parseEmail(Optional email) throws IllegalV return email.isPresent() ? Optional.of(parseEmail(email.get())) : Optional.empty(); } + /** + * Parses a {@code String money} into an {@code Money}. + * Leading and trailing whitespaces will be trimmed. + * + * @throws IllegalValueException if the given {@code money} is invalid. + */ + public static Money parseMoney(String money) throws IllegalValueException { + requireNonNull(money); + String trimmedMoney = money.trim(); + if (!Money.isValidMoney(trimmedMoney)) { + throw new IllegalValueException(Email.MESSAGE_EMAIL_CONSTRAINTS); + } + return new Money(trimmedMoney); + } + + /** + * Parses a {@code Optional money} into an {@code Optional} if {@code money} is present. + * See header comment of this class regarding the use of {@code Optional} parameters. + */ + public static Optional parseMoney(Optional money) throws IllegalValueException { + requireNonNull(money); + return money.isPresent() ? Optional.of(parseMoney(money.get())) : Optional.empty(); + } + /** * Parses a {@code String tag} into a {@code Tag}. * 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..c2956cb929b2 100644 --- a/src/main/java/seedu/address/model/AddressBook.java +++ b/src/main/java/seedu/address/model/AddressBook.java @@ -132,7 +132,12 @@ 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.getPhone(), + person.getEmail(), + person.getAddress(), + person.getMoney(), + correctTagReferences); } /** diff --git a/src/main/java/seedu/address/model/money/Money.java b/src/main/java/seedu/address/model/money/Money.java new file mode 100644 index 000000000000..6ed8cdd8404c --- /dev/null +++ b/src/main/java/seedu/address/model/money/Money.java @@ -0,0 +1,65 @@ +package seedu.address.model.money; + +import static java.util.Objects.requireNonNull; +import static seedu.address.commons.util.AppUtil.checkArgument; + +/** + * Represents a Person's Money Balance in the address book. + * Guarantees: immutable; is valid as declared in {@link #isValidMoney(String)} + */ +public class Money { + public static final String MESSAGE_MONEY_CONSTRAINTS = "Money values should be numbers"; + public static final String MONEY_VALIDATION_REGEX = "-?\\d+(\\.\\d+)?"; + + public final Double balance; + public final String value; + + /** + * Constructs a {@code Money}. + * + * @param balance A valid money balance. + */ + public Money(String balance) { + requireNonNull(balance); + checkArgument(isValidMoney(balance), MESSAGE_MONEY_CONSTRAINTS); + this.balance = Double.parseDouble(balance); + this.value = balance; + } + + @Override + public String toString() { + return value; + } + + /** + * Returns true if a given string is a valid money balance. + */ + public static boolean isValidMoney(String test) { + return test.matches(MONEY_VALIDATION_REGEX); + } + + /** + * Returns true if the user need to pay the contact certain amount of money + * @return true/false + */ + public boolean isNeedPaidMoney() { + return balance < 0.0; + } + + /** + * Returns true if the user need to received certain amount of money from the contact + * @return true/false + */ + public boolean isNeedReceivedMoney() { + return balance > 0.0; + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof Money // instanceof handles nulls + && this.value.equals(((Money) other).value)); // state check + } + + +} diff --git a/src/main/java/seedu/address/model/person/Person.java b/src/main/java/seedu/address/model/person/Person.java index ec9f2aa5e919..076d6e766cb1 100644 --- a/src/main/java/seedu/address/model/person/Person.java +++ b/src/main/java/seedu/address/model/person/Person.java @@ -6,6 +6,7 @@ import java.util.Objects; import java.util.Set; +import seedu.address.model.money.Money; import seedu.address.model.tag.Tag; import seedu.address.model.tag.UniqueTagList; @@ -19,18 +20,20 @@ public class Person { private final Phone phone; private final Email email; private final Address address; + private final Money money; private final UniqueTagList tags; /** * Every field must be present and not null. */ - public Person(Name name, Phone phone, Email email, Address address, Set tags) { + public Person(Name name, Phone phone, Email email, Address address, Money balance, Set tags) { requireAllNonNull(name, phone, email, address, tags); this.name = name; this.phone = phone; this.email = email; this.address = address; + this.money = balance; // protect internal tags from changes in the arg list this.tags = new UniqueTagList(tags); } @@ -51,6 +54,10 @@ public Address getAddress() { return address; } + public Money getMoney() { + return money; + } + /** * Returns an immutable tag set, which throws {@code UnsupportedOperationException} * if modification is attempted. @@ -73,13 +80,14 @@ public boolean equals(Object other) { return otherPerson.getName().equals(this.getName()) && otherPerson.getPhone().equals(this.getPhone()) && otherPerson.getEmail().equals(this.getEmail()) - && otherPerson.getAddress().equals(this.getAddress()); + && otherPerson.getAddress().equals(this.getAddress()) + && otherPerson.getMoney().equals(this.getMoney()); } @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, phone, email, address, money, tags); } @Override @@ -92,6 +100,8 @@ public String toString() { .append(getEmail()) .append(" Address: ") .append(getAddress()) + .append(" Balance: ") + .append(getMoney()) .append(" Tags: "); getTags().forEach(builder::append); return builder.toString(); diff --git a/src/main/java/seedu/address/model/util/SampleDataUtil.java b/src/main/java/seedu/address/model/util/SampleDataUtil.java index aea96bfb31f3..f45f4026645f 100644 --- a/src/main/java/seedu/address/model/util/SampleDataUtil.java +++ b/src/main/java/seedu/address/model/util/SampleDataUtil.java @@ -5,6 +5,7 @@ import seedu.address.model.AddressBook; import seedu.address.model.ReadOnlyAddressBook; +import seedu.address.model.money.Money; import seedu.address.model.person.Address; import seedu.address.model.person.Email; import seedu.address.model.person.Name; @@ -20,22 +21,22 @@ public class SampleDataUtil { public static Person[] getSamplePersons() { return new Person[] { new Person(new Name("Alex Yeoh"), new Phone("87438807"), new Email("alexyeoh@example.com"), - new Address("Blk 30 Geylang Street 29, #06-40"), + new Address("Blk 30 Geylang Street 29, #06-40"), new Money("10"), getTagSet("friends")), new Person(new Name("Bernice Yu"), new Phone("99272758"), new Email("berniceyu@example.com"), - new Address("Blk 30 Lorong 3 Serangoon Gardens, #07-18"), + new Address("Blk 30 Lorong 3 Serangoon Gardens, #07-18"), new Money("10"), getTagSet("colleagues", "friends")), new Person(new Name("Charlotte Oliveiro"), new Phone("93210283"), new Email("charlotte@example.com"), - new Address("Blk 11 Ang Mo Kio Street 74, #11-04"), + new Address("Blk 11 Ang Mo Kio Street 74, #11-04"), new Money("10"), getTagSet("neighbours")), new Person(new Name("David Li"), new Phone("91031282"), new Email("lidavid@example.com"), - new Address("Blk 436 Serangoon Gardens Street 26, #16-43"), + new Address("Blk 436 Serangoon Gardens Street 26, #16-43"), new Money("10"), getTagSet("family")), new Person(new Name("Irfan Ibrahim"), new Phone("92492021"), new Email("irfan@example.com"), - new Address("Blk 47 Tampines Street 20, #17-35"), + new Address("Blk 47 Tampines Street 20, #17-35"), new Money("10"), getTagSet("classmates")), new Person(new Name("Roy Balakrishnan"), new Phone("92624417"), new Email("royb@example.com"), - new Address("Blk 45 Aljunied Street 85, #11-31"), + new Address("Blk 45 Aljunied Street 85, #11-31"), new Money("10"), getTagSet("colleagues")) }; } diff --git a/src/main/java/seedu/address/storage/XmlAdaptedPerson.java b/src/main/java/seedu/address/storage/XmlAdaptedPerson.java index 2cd92dc4fd20..a1c57989c319 100644 --- a/src/main/java/seedu/address/storage/XmlAdaptedPerson.java +++ b/src/main/java/seedu/address/storage/XmlAdaptedPerson.java @@ -9,6 +9,7 @@ import javax.xml.bind.annotation.XmlElement; import seedu.address.commons.exceptions.IllegalValueException; +import seedu.address.model.money.Money; import seedu.address.model.person.Address; import seedu.address.model.person.Email; import seedu.address.model.person.Name; @@ -31,6 +32,8 @@ public class XmlAdaptedPerson { private String email; @XmlElement(required = true) private String address; + @XmlElement + private String balance; @XmlElement private List tagged = new ArrayList<>(); @@ -44,11 +47,13 @@ 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 phone, String email, String address, String balance, + List tagged) { this.name = name; this.phone = phone; this.email = email; this.address = address; + this.balance = balance; if (tagged != null) { this.tagged = new ArrayList<>(tagged); } @@ -64,6 +69,7 @@ public XmlAdaptedPerson(Person source) { phone = source.getPhone().value; email = source.getEmail().value; address = source.getAddress().value; + balance = source.getMoney().value; tagged = new ArrayList<>(); for (Tag tag : source.getTags()) { tagged.add(new XmlAdaptedTag(tag)); @@ -113,8 +119,13 @@ public Person toModelType() throws IllegalValueException { } final Address address = new Address(this.address); + if (!Money.isValidMoney(this.balance)) { + throw new IllegalValueException(Money.MESSAGE_MONEY_CONSTRAINTS); + } + final Money balance = new Money(this.balance); + final Set tags = new HashSet<>(personTags); - return new Person(name, phone, email, address, tags); + return new Person(name, phone, email, address, balance, tags); } @Override @@ -132,6 +143,7 @@ public boolean equals(Object other) { && Objects.equals(phone, otherPerson.phone) && Objects.equals(email, otherPerson.email) && Objects.equals(address, otherPerson.address) + && Objects.equals(balance, otherPerson.balance) && tagged.equals(otherPerson.tagged); } } diff --git a/src/main/java/seedu/address/ui/PersonCard.java b/src/main/java/seedu/address/ui/PersonCard.java index f6727ea83abd..15791d6e5e0e 100644 --- a/src/main/java/seedu/address/ui/PersonCard.java +++ b/src/main/java/seedu/address/ui/PersonCard.java @@ -37,6 +37,8 @@ public class PersonCard extends UiPart { @FXML private Label email; @FXML + private Label money; + @FXML private FlowPane tags; public PersonCard(Person person, int displayedIndex) { @@ -47,6 +49,7 @@ public PersonCard(Person person, int displayedIndex) { phone.setText(person.getPhone().value); address.setText(person.getAddress().value); email.setText(person.getEmail().value); + money.setText(person.getMoney().value); person.getTags().forEach(tag -> tags.getChildren().add(new Label(tag.tagName))); } diff --git a/src/main/resources/view/PersonListCard.fxml b/src/main/resources/view/PersonListCard.fxml index f08ea32ad558..275bf4d76d9e 100644 --- a/src/main/resources/view/PersonListCard.fxml +++ b/src/main/resources/view/PersonListCard.fxml @@ -31,6 +31,7 @@