From 47d8c1e0fc19929fdc9710f32f103c6593810a87 Mon Sep 17 00:00:00 2001 From: R-D-D-D Date: Wed, 9 Oct 2019 23:50:29 +0800 Subject: [PATCH] added remark command --- .../address/logic/commands/EditCommand.java | 19 +++-- .../address/logic/commands/RemarkCommand.java | 85 +++++++++++++++++++ .../logic/parser/AddCommandParser.java | 14 ++- .../logic/parser/AddressBookParser.java | 4 + .../seedu/address/logic/parser/CliSyntax.java | 1 + .../address/logic/parser/ParserUtil.java | 14 ++- .../logic/parser/RemarkCommandParser.java | 39 +++++++++ .../seedu/address/model/person/Person.java | 13 ++- .../seedu/address/model/person/Remark.java | 51 +++++++++++ .../address/model/util/SampleDataUtil.java | 18 ++-- .../address/storage/JsonAdaptedPerson.java | 23 +++-- .../java/seedu/address/ui/PersonCard.java | 3 + src/main/resources/view/PersonListCard.fxml | 1 + .../seedu/address/testutil/PersonBuilder.java | 2 +- 14 files changed, 247 insertions(+), 40 deletions(-) create mode 100644 src/main/java/seedu/address/logic/commands/RemarkCommand.java create mode 100644 src/main/java/seedu/address/logic/parser/RemarkCommandParser.java create mode 100644 src/main/java/seedu/address/model/person/Remark.java diff --git a/src/main/java/seedu/address/logic/commands/EditCommand.java b/src/main/java/seedu/address/logic/commands/EditCommand.java index 7e36114902f..c1b7ad1ab89 100644 --- a/src/main/java/seedu/address/logic/commands/EditCommand.java +++ b/src/main/java/seedu/address/logic/commands/EditCommand.java @@ -19,11 +19,7 @@ import seedu.address.commons.util.CollectionUtil; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.model.Model; -import seedu.address.model.person.Address; -import seedu.address.model.person.Email; -import seedu.address.model.person.Name; -import seedu.address.model.person.Person; -import seedu.address.model.person.Phone; +import seedu.address.model.person.*; import seedu.address.model.tag.Tag; /** @@ -98,8 +94,9 @@ private static Person createEditedPerson(Person personToEdit, EditPersonDescript Email updatedEmail = editPersonDescriptor.getEmail().orElse(personToEdit.getEmail()); Address updatedAddress = editPersonDescriptor.getAddress().orElse(personToEdit.getAddress()); Set updatedTags = editPersonDescriptor.getTags().orElse(personToEdit.getTags()); + Remark updatedRemark = editPersonDescriptor.getRemark().orElse(personToEdit.getRemark()); - return new Person(updatedName, updatedPhone, updatedEmail, updatedAddress, updatedTags); + return new Person(updatedName, updatedPhone, updatedEmail, updatedAddress, updatedTags, updatedRemark); } @Override @@ -130,6 +127,7 @@ public static class EditPersonDescriptor { private Email email; private Address address; private Set tags; + private Remark remark; public EditPersonDescriptor() {} @@ -143,6 +141,7 @@ public EditPersonDescriptor(EditPersonDescriptor toCopy) { setEmail(toCopy.email); setAddress(toCopy.address); setTags(toCopy.tags); + } /** @@ -184,6 +183,14 @@ public Optional
getAddress() { return Optional.ofNullable(address); } + public void setRemark(Remark remark) { + this.remark = remark; + } + + public Optional getRemark() { + return Optional.ofNullable(remark); + } + /** * Sets {@code tags} to this object's {@code tags}. * A defensive copy of {@code tags} is used internally. diff --git a/src/main/java/seedu/address/logic/commands/RemarkCommand.java b/src/main/java/seedu/address/logic/commands/RemarkCommand.java new file mode 100644 index 00000000000..ff945f29aa8 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/RemarkCommand.java @@ -0,0 +1,85 @@ +package seedu.address.logic.commands; + +import seedu.address.commons.core.Messages; +import seedu.address.commons.core.index.Index; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.person.Person; +import seedu.address.model.person.Remark; +import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PERSONS; + + +import java.util.List; + +/** + * Changes the remark of an existing person in the address book. + */ + +public class RemarkCommand extends Command { + public static final String COMMAND_WORD = "remark"; + public static final String MESSAGE_ARGUMENTS = "Index: %1$d, Remark: %2$s"; + public static final String MESSAGE_ADD_REMARK_SUCCESS = "Added remark to Person: %1$s"; + public static final String MESSAGE_DELETE_REMARK_SUCCESS = "Removed remark from Person: %1$s"; + private final Index index; + private final Remark remark; + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Edits the remark of the person identified" + + " by the index number used in the last person listing. " + + "Existing remark will be overwritten by the input.\n" + + "Parameters: INDEX (must be a positive integer) " + + "r/ [REMARK]\n" + "Example: " + "remark" + " 1 " + + "r/ Likes to swim."; + + /** + * @param index of the person in the filtered person list to edit the remark + * @param remark of the person to be updated to + */ + public RemarkCommand(Index index, Remark remark) { + this.index = index; + this.remark = remark; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + List lastShownList = model.getFilteredPersonList(); + + if (index.getZeroBased() >= lastShownList.size()) { + throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + } + + Person personToEdit = lastShownList.get(index.getZeroBased()); + Person editedPerson = new Person(personToEdit.getName(), personToEdit.getPhone(), personToEdit.getEmail(), + personToEdit.getAddress(), personToEdit.getTags(), remark); + + model.setPerson(personToEdit, editedPerson); + model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS); + + return new CommandResult(generateSuccessMessage(editedPerson)); + } + + /** + * Generates a command execution success message based on whether the remark is added to or removed from + * {@code personToEdit}. + */ + private String generateSuccessMessage(Person personToEdit) { + String message = !remark.remark.isEmpty() ? MESSAGE_ADD_REMARK_SUCCESS : MESSAGE_DELETE_REMARK_SUCCESS; + return String.format(message, personToEdit); + } + + @Override + public boolean equals(Object other) { + // short circuit if same object + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof RemarkCommand)) { + return false; + } + + // state check + RemarkCommand e = (RemarkCommand) other; + return index.equals(e.index) + && remark.equals(e.remark); + } +} \ No newline at end of file diff --git a/src/main/java/seedu/address/logic/parser/AddCommandParser.java b/src/main/java/seedu/address/logic/parser/AddCommandParser.java index 3b8bfa035e8..430af65657a 100644 --- a/src/main/java/seedu/address/logic/parser/AddCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/AddCommandParser.java @@ -6,17 +6,14 @@ 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.logic.parser.CliSyntax.PREFIX_REMARK; import java.util.Set; import java.util.stream.Stream; import seedu.address.logic.commands.AddCommand; import seedu.address.logic.parser.exceptions.ParseException; -import seedu.address.model.person.Address; -import seedu.address.model.person.Email; -import seedu.address.model.person.Name; -import seedu.address.model.person.Person; -import seedu.address.model.person.Phone; +import seedu.address.model.person.*; import seedu.address.model.tag.Tag; /** @@ -31,9 +28,9 @@ 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_TAG, PREFIX_REMARK); - if (!arePrefixesPresent(argMultimap, PREFIX_NAME, PREFIX_ADDRESS, PREFIX_PHONE, PREFIX_EMAIL) + if (!arePrefixesPresent(argMultimap, PREFIX_NAME, PREFIX_ADDRESS, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_REMARK) || !argMultimap.getPreamble().isEmpty()) { throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE)); } @@ -43,8 +40,9 @@ public AddCommand parse(String args) throws ParseException { Email email = ParserUtil.parseEmail(argMultimap.getValue(PREFIX_EMAIL).get()); Address address = ParserUtil.parseAddress(argMultimap.getValue(PREFIX_ADDRESS).get()); Set tagList = ParserUtil.parseTags(argMultimap.getAllValues(PREFIX_TAG)); + Remark remark = ParserUtil.parseRemark(argMultimap.getValue(PREFIX_REMARK).get()); - Person person = new Person(name, phone, email, address, tagList); + Person person = new Person(name, phone, email, address, tagList, remark); return new AddCommand(person); } diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index 1e466792b46..b650f13a6b9 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -15,6 +15,7 @@ import seedu.address.logic.commands.FindCommand; import seedu.address.logic.commands.HelpCommand; import seedu.address.logic.commands.ListCommand; +import seedu.address.logic.commands.RemarkCommand; import seedu.address.logic.parser.exceptions.ParseException; /** @@ -68,6 +69,9 @@ public Command parseCommand(String userInput) throws ParseException { case HelpCommand.COMMAND_WORD: return new HelpCommand(); + case RemarkCommand.COMMAND_WORD: + return new RemarkCommandParser().parse(arguments); + default: throw new ParseException(MESSAGE_UNKNOWN_COMMAND); } diff --git a/src/main/java/seedu/address/logic/parser/CliSyntax.java b/src/main/java/seedu/address/logic/parser/CliSyntax.java index 75b1a9bf119..96be13b3772 100644 --- a/src/main/java/seedu/address/logic/parser/CliSyntax.java +++ b/src/main/java/seedu/address/logic/parser/CliSyntax.java @@ -11,5 +11,6 @@ public class CliSyntax { public static final Prefix PREFIX_EMAIL = new Prefix("e/"); public static final Prefix PREFIX_ADDRESS = new Prefix("a/"); public static final Prefix PREFIX_TAG = new Prefix("t/"); + public static final Prefix PREFIX_REMARK = new Prefix("r/"); } diff --git a/src/main/java/seedu/address/logic/parser/ParserUtil.java b/src/main/java/seedu/address/logic/parser/ParserUtil.java index b117acb9c55..908d51738a2 100644 --- a/src/main/java/seedu/address/logic/parser/ParserUtil.java +++ b/src/main/java/seedu/address/logic/parser/ParserUtil.java @@ -9,10 +9,7 @@ import seedu.address.commons.core.index.Index; import seedu.address.commons.util.StringUtil; import seedu.address.logic.parser.exceptions.ParseException; -import seedu.address.model.person.Address; -import seedu.address.model.person.Email; -import seedu.address.model.person.Name; -import seedu.address.model.person.Phone; +import seedu.address.model.person.*; import seedu.address.model.tag.Tag; /** @@ -95,6 +92,15 @@ public static Email parseEmail(String email) throws ParseException { return new Email(trimmedEmail); } + public static Remark parseRemark(String remark) throws ParseException { + requireNonNull(remark); + String trimmedEmail = remark.trim(); + if (!Remark.isValidRemark(trimmedEmail)) { + throw new ParseException(Remark.MESSAGE_CONSTRAINTS); + } + return new Remark(trimmedEmail); + } + /** * Parses a {@code String tag} into a {@code Tag}. * Leading and trailing whitespaces will be trimmed. diff --git a/src/main/java/seedu/address/logic/parser/RemarkCommandParser.java b/src/main/java/seedu/address/logic/parser/RemarkCommandParser.java new file mode 100644 index 00000000000..d07ca3e5be4 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/RemarkCommandParser.java @@ -0,0 +1,39 @@ +package seedu.address.logic.parser; + +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; + +import java.util.Arrays; +import static java.util.Objects.requireNonNull; + +import seedu.address.commons.exceptions.IllegalValueException; +import seedu.address.logic.commands.RemarkCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.person.NameContainsKeywordsPredicate; +import static seedu.address.logic.parser.CliSyntax.PREFIX_REMARK; +import seedu.address.commons.core.index.Index; +import seedu.address.model.person.Remark; + +/** + * Parses input arguments and creates a new RemarkCommand object + */ +public class RemarkCommandParser implements Parser { + + public RemarkCommand parse(String args) throws ParseException { + requireNonNull(args); + ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, + PREFIX_REMARK); + + Index index; + try { + index = ParserUtil.parseIndex(argMultimap.getPreamble()); + } catch (IllegalValueException ive) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, + RemarkCommand.MESSAGE_USAGE), ive); + } + + Remark remark = new Remark(argMultimap.getValue(PREFIX_REMARK).orElse("")); + + return new RemarkCommand(index, remark); + } + +} diff --git a/src/main/java/seedu/address/model/person/Person.java b/src/main/java/seedu/address/model/person/Person.java index 557a7a60cd5..1fbb1004749 100644 --- a/src/main/java/seedu/address/model/person/Person.java +++ b/src/main/java/seedu/address/model/person/Person.java @@ -19,6 +19,7 @@ public class Person { private final Name name; private final Phone phone; private final Email email; + private final Remark remark; // Data fields private final Address address; @@ -27,7 +28,8 @@ public class Person { /** * Every field must be present and not null. */ - public Person(Name name, Phone phone, Email email, Address address, Set tags) { + public Person(Name name, Phone phone, Email email, Address address, Set tags, Remark remark) { + this.remark = remark; requireAllNonNull(name, phone, email, address, tags); this.name = name; this.phone = phone; @@ -52,6 +54,8 @@ public Address getAddress() { return address; } + public Remark getRemark() { return remark; } + /** * Returns an immutable tag set, which throws {@code UnsupportedOperationException} * if modification is attempted. @@ -93,13 +97,14 @@ public boolean equals(Object other) { && otherPerson.getPhone().equals(getPhone()) && otherPerson.getEmail().equals(getEmail()) && otherPerson.getAddress().equals(getAddress()) - && otherPerson.getTags().equals(getTags()); + && otherPerson.getTags().equals(getTags()) + && otherPerson.getRemark().equals(getRemark()); } @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, tags, remark); } @Override @@ -112,6 +117,8 @@ public String toString() { .append(getEmail()) .append(" Address: ") .append(getAddress()) + .append("Remark: ") + .append(getRemark()) .append(" Tags: "); getTags().forEach(builder::append); return builder.toString(); diff --git a/src/main/java/seedu/address/model/person/Remark.java b/src/main/java/seedu/address/model/person/Remark.java new file mode 100644 index 00000000000..140d64a8dec --- /dev/null +++ b/src/main/java/seedu/address/model/person/Remark.java @@ -0,0 +1,51 @@ +package seedu.address.model.person; + +import static java.util.Objects.requireNonNull; +import static seedu.address.commons.util.AppUtil.checkArgument; + +/** + * Represents a Person's remark in the address book. + * Guarantees: immutable; is valid as declared in {@link #isValidRemark(String)} + */ +public class Remark { + + public static final String MESSAGE_CONSTRAINTS = + "Phone numbers should only contain numbers, and it should be at least 3 digits long"; + public final String remark; + + /** + * Constructs a {@code Remark}. + * + * @param remark A valid phone number. + */ + public Remark(String remark) { + requireNonNull(remark); + checkArgument(isValidRemark(remark), MESSAGE_CONSTRAINTS); + this.remark = remark; + } + + /** + * Returns true if a given string is a valid remark. + */ + public static boolean isValidRemark(String test) { + return !test.isEmpty(); + } + + @Override + public String toString() { + return remark; + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof Phone // instanceof handles nulls + && remark.equals(((Remark) other).remark)); // state check + } + + @Override + public int hashCode() { + return remark.hashCode(); + } + +} diff --git a/src/main/java/seedu/address/model/util/SampleDataUtil.java b/src/main/java/seedu/address/model/util/SampleDataUtil.java index 1806da4facf..dbc97b0b1d6 100644 --- a/src/main/java/seedu/address/model/util/SampleDataUtil.java +++ b/src/main/java/seedu/address/model/util/SampleDataUtil.java @@ -6,11 +6,7 @@ import seedu.address.model.AddressBook; import seedu.address.model.ReadOnlyAddressBook; -import seedu.address.model.person.Address; -import seedu.address.model.person.Email; -import seedu.address.model.person.Name; -import seedu.address.model.person.Person; -import seedu.address.model.person.Phone; +import seedu.address.model.person.*; import seedu.address.model.tag.Tag; /** @@ -21,22 +17,22 @@ public static Person[] getSamplePersons() { return new Person[] { new Person(new Name("Alex Yeoh"), new Phone("87438807"), new Email("alexyeoh@example.com"), new Address("Blk 30 Geylang Street 29, #06-40"), - getTagSet("friends")), + getTagSet("friends"), new Remark("$remark")), new Person(new Name("Bernice Yu"), new Phone("99272758"), new Email("berniceyu@example.com"), new Address("Blk 30 Lorong 3 Serangoon Gardens, #07-18"), - getTagSet("colleagues", "friends")), + getTagSet("colleagues", "friends"), new Remark("$remark")), new Person(new Name("Charlotte Oliveiro"), new Phone("93210283"), new Email("charlotte@example.com"), new Address("Blk 11 Ang Mo Kio Street 74, #11-04"), - getTagSet("neighbours")), + getTagSet("neighbours"), new Remark("$remark")), new Person(new Name("David Li"), new Phone("91031282"), new Email("lidavid@example.com"), new Address("Blk 436 Serangoon Gardens Street 26, #16-43"), - getTagSet("family")), + getTagSet("family"), new Remark("$remark")), new Person(new Name("Irfan Ibrahim"), new Phone("92492021"), new Email("irfan@example.com"), new Address("Blk 47 Tampines Street 20, #17-35"), - getTagSet("classmates")), + getTagSet("classmates"), new Remark("$remark")), new Person(new Name("Roy Balakrishnan"), new Phone("92624417"), new Email("royb@example.com"), new Address("Blk 45 Aljunied Street 85, #11-31"), - getTagSet("colleagues")) + getTagSet("colleagues"), new Remark("$remark")) }; } diff --git a/src/main/java/seedu/address/storage/JsonAdaptedPerson.java b/src/main/java/seedu/address/storage/JsonAdaptedPerson.java index a6321cec2ea..8966b3c4879 100644 --- a/src/main/java/seedu/address/storage/JsonAdaptedPerson.java +++ b/src/main/java/seedu/address/storage/JsonAdaptedPerson.java @@ -10,11 +10,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import seedu.address.commons.exceptions.IllegalValueException; -import seedu.address.model.person.Address; -import seedu.address.model.person.Email; -import seedu.address.model.person.Name; -import seedu.address.model.person.Person; -import seedu.address.model.person.Phone; +import seedu.address.model.person.*; import seedu.address.model.tag.Tag; /** @@ -28,6 +24,7 @@ class JsonAdaptedPerson { private final String phone; private final String email; private final String address; + private final String remark; private final List tagged = new ArrayList<>(); /** @@ -35,12 +32,13 @@ class JsonAdaptedPerson { */ @JsonCreator public JsonAdaptedPerson(@JsonProperty("name") String name, @JsonProperty("phone") String phone, - @JsonProperty("email") String email, @JsonProperty("address") String address, + @JsonProperty("email") String email, @JsonProperty("address") String address, @JsonProperty("remark") String remark, @JsonProperty("tagged") List tagged) { this.name = name; this.phone = phone; this.email = email; this.address = address; + this.remark = remark; if (tagged != null) { this.tagged.addAll(tagged); } @@ -54,6 +52,7 @@ public JsonAdaptedPerson(Person source) { phone = source.getPhone().value; email = source.getEmail().value; address = source.getAddress().value; + remark = source.getRemark().remark; tagged.addAll(source.getTags().stream() .map(JsonAdaptedTag::new) .collect(Collectors.toList())); @@ -100,10 +99,20 @@ public Person toModelType() throws IllegalValueException { if (!Address.isValidAddress(address)) { throw new IllegalValueException(Address.MESSAGE_CONSTRAINTS); } + + if (remark == null) { + throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Remark.class.getSimpleName())); + } + if (!Remark.isValidRemark(remark)) { + throw new IllegalValueException(Address.MESSAGE_CONSTRAINTS); + } + final Address modelAddress = new Address(address); + final Remark modelRemark = new Remark(remark); + final Set modelTags = new HashSet<>(personTags); - return new Person(modelName, modelPhone, modelEmail, modelAddress, modelTags); + return new Person(modelName, modelPhone, modelEmail, modelAddress, modelTags, modelRemark); } } diff --git a/src/main/java/seedu/address/ui/PersonCard.java b/src/main/java/seedu/address/ui/PersonCard.java index 0684b088868..6111585b525 100644 --- a/src/main/java/seedu/address/ui/PersonCard.java +++ b/src/main/java/seedu/address/ui/PersonCard.java @@ -40,6 +40,8 @@ public class PersonCard extends UiPart { private Label email; @FXML private FlowPane tags; + @FXML + private Label remark; public PersonCard(Person person, int displayedIndex) { super(FXML); @@ -49,6 +51,7 @@ public PersonCard(Person person, int displayedIndex) { phone.setText(person.getPhone().value); address.setText(person.getAddress().value); email.setText(person.getEmail().value); + remark.setText(person.getRemark().remark); person.getTags().stream() .sorted(Comparator.comparing(tag -> tag.tagName)) .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 f08ea32ad55..d1a7eb614f8 100644 --- a/src/main/resources/view/PersonListCard.fxml +++ b/src/main/resources/view/PersonListCard.fxml @@ -31,6 +31,7 @@