Skip to content

Commit

Permalink
Merge pull request #133 from Rachael-Chan/add-remark
Browse files Browse the repository at this point in the history
Add new remark command
  • Loading branch information
Andrew22Teoh authored Oct 23, 2024
2 parents c8622a3 + 1212440 commit 0ed0cb3
Show file tree
Hide file tree
Showing 28 changed files with 651 additions and 63 deletions.
75 changes: 75 additions & 0 deletions docs/DeveloperGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,81 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli

**Extensions**

* 2a. The list is empty.

Use case ends.

* 3a. The given index is invalid.

* 3a1. SocialBook shows an error message.

Use case resumes at step 2.

**Use case: Edit a contact**

**MSS**

1. User requests to list contacts
2. SocialBook shows a list of contacts
3. User requests to edit a specific contact with specified field(s)
4. SocialBook edits the contact

* 2a. The list is empty.

Use case ends.

* 3a. The given specified field is/are empty.

* 3a1. SocialBook shows an error message.

Use case resumes at step 2.

* 3b. The given index is invalid.

* 3b1. SocialBook shows an error message.

Use case resumes at step 2.

* 3c. There is an error in any of the specified fields.

* 3c1. SocialBook shows an error message.

Use case resumes at step 2.

**Use case: Find a contact**

**MSS**

1. User requests to list contacts
2. SocialBook shows a list of contacts
3. User requests to find a specific contact with specified field(s)
4. SocialBook displays the contact that matches the specified field(s)

* 2a. The list is empty.

Use case ends.

* 3a. The given specified field is/are empty.

* 3a1. SocialBook shows an error message.

Use case resumes at step 2.

* 3b. There is an error in any of the specified fields.

* 3b1. SocialBook shows an error message.

Use case resumes at step 2.

**Use case: Add remarks to a contact**

**MSS**

1. User requests to list contacts
2. SocialBook shows a list of contacts
3. User requests to add remarks to a specific contact
4. SocialBook adds the remark to the specified contact

* 2a. The list is empty.

Use case ends.
Expand Down
15 changes: 14 additions & 1 deletion docs/UserGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,19 @@ Format: `delete INDEX` `delete INDEX INDEX ...`
Examples:
* `list` followed by `delete 2` deletes the 2nd person in the address book.
* `find Betsy` followed by `delete 1` deletes the 1st person in the results of the `find` command.
* `list` followed by `delete 1 2` deletes the 1st and 2nd person in the address book.
* `list` followed by `delete 1 2` deletes the 1st and 2nd person in the address book.

### Adding remarks to person : `remark`

Add remarks to an existing person in the address book.

Format: `remark INDEX r/REMARK`

* Adds remarks to the person at the specified `INDEX`. The index refers to the index number shown in the displayed person list. The index **must be a positive integer** 1, 2, 3, …​

Examples:
* `remark 1 r/Financial Issues` Adds the remark of the 1st person to be `Financial Issues`.
* `remark 1 r/` Clears remarks (if any) of the 1st person.

### Clearing all entries : `clear`

Expand Down Expand Up @@ -226,3 +238,4 @@ Action | Format, Examples
**List** | `list`
**Help** | `help`
**Seed** | `seed`
**Remark** | `remark INDEX r/REMARK`
8 changes: 8 additions & 0 deletions src/main/java/seedu/address/logic/Messages.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public static String format(Person person) {
addTags(builder, person);
addDateOfLastVisit(builder, person);
addEmergencyContact(builder, person);
addRemark(builder, person);

return builder.toString();
}
Expand Down Expand Up @@ -94,4 +95,11 @@ private static void addEmergencyContact(StringBuilder sb, Person person) {
sb.append("; Emergency Contact: ").append(person.getEmergencyContact().get());
}

private static void addRemark(StringBuilder sb, Person person) {
if (!person.hasRemark()) {
return;
}
sb.append("; Remark: ").append(person.getRemark().value);
}

}
7 changes: 5 additions & 2 deletions src/main/java/seedu/address/logic/commands/EditCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import seedu.address.model.person.Name;
import seedu.address.model.person.Person;
import seedu.address.model.person.Phone;
import seedu.address.model.person.Remark;
import seedu.address.model.tag.Tag;

/**
Expand Down Expand Up @@ -111,9 +112,11 @@ private static Person createEditedPerson(Person personToEdit, EditPersonDescript
.orElse(personToEdit.getDateOfLastVisit());
Optional<EmergencyContact> updatedEmergencyContact = editPersonDescriptor.getEmergencyContact()
.orElse(personToEdit.getEmergencyContact());
// remark not edited in edit command; Use remark command to edit remarks
Remark remark = personToEdit.getRemark();

return new Person(updatedName, updatedPhone, updatedEmail, updatedAddress, updatedTags,
updatedDateOfLastVisit, updatedEmergencyContact);
return new Person(updatedName, updatedPhone, updatedEmail, updatedAddress,
updatedTags, updatedDateOfLastVisit, updatedEmergencyContact, remark);
}

@Override
Expand Down
93 changes: 93 additions & 0 deletions src/main/java/seedu/address/logic/commands/RemarkCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package seedu.address.logic.commands;

import static seedu.address.commons.util.CollectionUtil.requireAllNonNull;
import static seedu.address.logic.parser.CliSyntax.PREFIX_REMARK;
import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PERSONS;

import java.util.List;

import seedu.address.commons.core.index.Index;
import seedu.address.logic.Messages;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.model.Model;
import seedu.address.model.person.Person;
import seedu.address.model.person.Remark;

/**
* 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_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 that is not 0) "
+ PREFIX_REMARK + "[REMARK]\n"
+ "Example: " + COMMAND_WORD + " 1 "
+ PREFIX_REMARK + "Likes to swim.";

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;

/**
* @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) {
requireAllNonNull(index, remark);

this.index = index;
this.remark = remark;
}

@Override
public CommandResult execute(Model model) throws CommandException {
List<Person> 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(),
personToEdit.getDateOfLastVisit(), personToEdit.getEmergencyContact(), 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.value.isEmpty() ? MESSAGE_ADD_REMARK_SUCCESS : MESSAGE_DELETE_REMARK_SUCCESS;
return String.format(message, Messages.format(personToEdit));
}

@Override
public boolean equals(Object other) {
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);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import seedu.address.model.person.Name;
import seedu.address.model.person.Person;
import seedu.address.model.person.Phone;
import seedu.address.model.person.Remark;
import seedu.address.model.tag.Tag;

/**
Expand Down Expand Up @@ -56,7 +57,10 @@ public AddCommand parse(String args) throws ParseException {
Optional<EmergencyContact> emergencyContact = ParserUtil
.parseEmergencyContact(argMultimap.getValue(PREFIX_EMERGENCY_CONTACT));

Person person = new Person(name, phone, email, address, tagList, dateOfLastVisit, emergencyContact);
// Remark set to empty when adding new contacts; Use Remark command to add remarks
Remark remark = new Remark("");

Person person = new Person(name, phone, email, address, tagList, dateOfLastVisit, emergencyContact, remark);

return new AddCommand(person);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,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.commands.SeedCommand;
import seedu.address.logic.parser.exceptions.ParseException;

Expand Down Expand Up @@ -84,6 +85,9 @@ public Command parseCommand(String userInput) throws ParseException {
case SeedCommand.COMMAND_WORD:
return new SeedCommand();

case RemarkCommand.COMMAND_WORD:
return new RemarkCommandParser().parse(arguments);

default:
logger.finer("This user input caused a ParseException: " + userInput);
throw new ParseException(MESSAGE_UNKNOWN_COMMAND);
Expand Down
1 change: 1 addition & 0 deletions src/main/java/seedu/address/logic/parser/CliSyntax.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ public class CliSyntax {
public static final Prefix PREFIX_TAG = new Prefix("t/");
public static final Prefix PREFIX_DATEOFLASTVISIT = new Prefix("d/");
public static final Prefix PREFIX_EMERGENCY_CONTACT = new Prefix("ec/");
public static final Prefix PREFIX_REMARK = new Prefix("r/");

}
36 changes: 36 additions & 0 deletions src/main/java/seedu/address/logic/parser/RemarkCommandParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package seedu.address.logic.parser;

import static java.util.Objects.requireNonNull;
import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.address.logic.parser.CliSyntax.PREFIX_REMARK;

import seedu.address.commons.core.index.Index;
import seedu.address.commons.exceptions.IllegalValueException;
import seedu.address.logic.commands.RemarkCommand;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.person.Remark;

/**
* Parses input arguments and creates a new {@code RemarkCommand} object
*/
public class RemarkCommandParser implements Parser<RemarkCommand> {
/**
* Parses the given {@code String} of arguments in the context of the {@code RemarkCommand}
* and returns a {@code RemarkCommand} object for execution.
* @throws ParseException if the user input does not conform the expected format
*/
public RemarkCommand parse(String args) throws ParseException {
requireNonNull(args);
ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_REMARK);

Index index;
try {
index = ParserUtil.parseIndex(argMultimap.getPreamble());
} catch (IllegalValueException ive) {
throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, RemarkCommand.MESSAGE_USAGE), ive);
}

String remark = argMultimap.getValue(PREFIX_REMARK).orElse("");
return new RemarkCommand(index, new Remark(remark));
}
}
27 changes: 22 additions & 5 deletions src/main/java/seedu/address/model/person/Person.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,23 @@ public class Person {
private final Set<Tag> tags = new HashSet<>();
private final Optional<DateOfLastVisit> dateOfLastVisit;
private final Optional<EmergencyContact> emergencyContact;
private final Remark remark;

/**
* Every field must be present and not null.
*/
public Person(Name name, Phone phone, Optional<Email> email, Optional<Address> address, Set<Tag> tags,
Optional<DateOfLastVisit> dateOfLastVisit, Optional<EmergencyContact> emergencyContact) {
requireAllNonNull(name, phone, email, address, tags, dateOfLastVisit);
Optional<DateOfLastVisit> dateOfLastVisit, Optional<EmergencyContact> emergencyContact,
Remark remark) {
requireAllNonNull(name, phone, email, address, tags, dateOfLastVisit, remark);
this.name = name;
this.phone = phone;
this.email = email;
this.address = address;
this.tags.addAll(tags);
this.dateOfLastVisit = dateOfLastVisit;
this.emergencyContact = emergencyContact;
this.remark = remark;
}

public Name getName() {
Expand Down Expand Up @@ -92,6 +95,17 @@ public Set<Tag> getTags() {
return Collections.unmodifiableSet(tags);
}

/**
* Returns whether the Person has a remark.
*/
public boolean hasRemark() {
return remark.isPresent();
}

public Remark getRemark() {
return remark;
}

/**
* Returns true if both persons have the same name. This defines a weaker notion of equality between two
* persons.
Expand Down Expand Up @@ -135,20 +149,23 @@ public boolean equals(Object other) {
return name.equals(otherPerson.name) && phone.equals(otherPerson.phone)
&& email.equals(otherPerson.email) && address.equals(otherPerson.address)
&& tags.equals(otherPerson.tags) && dateOfLastVisit.equals(otherPerson.dateOfLastVisit)
&& emergencyContact.equals(otherPerson.emergencyContact);
&& emergencyContact.equals(otherPerson.emergencyContact)
&& remark.equals(otherPerson.remark);
}

@Override
public int hashCode() {
// use this method for custom fields hashing instead of implementing your own
return Objects.hash(name, phone, email, address, tags, dateOfLastVisit, emergencyContact);
return Objects.hash(name, phone, email, address, tags, dateOfLastVisit,
emergencyContact, remark);
}

@Override
public String toString() {
return new ToStringBuilder(this).add("name", name).add("phone", phone).add("email", email)
.add("address", address).add("tags", tags).add("dateOfLastVisit", dateOfLastVisit)
.add("emergencyContact", emergencyContact).toString();
.add("emergencyContact", emergencyContact)
.add("remark", remark).toString();
}

}
Loading

0 comments on commit 0ed0cb3

Please sign in to comment.