From 2aaeae83322223fc29b04c633d970c0ea6461c43 Mon Sep 17 00:00:00 2001 From: Jason Date: Wed, 25 Oct 2023 21:08:51 +0800 Subject: [PATCH 01/18] Create and test Status class --- .../seedu/address/model/meeting/Status.java | 63 +++++++++++++++++++ .../address/model/meeting/StatusTest.java | 44 +++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 src/main/java/seedu/address/model/meeting/Status.java create mode 100644 src/test/java/seedu/address/model/meeting/StatusTest.java diff --git a/src/main/java/seedu/address/model/meeting/Status.java b/src/main/java/seedu/address/model/meeting/Status.java new file mode 100644 index 00000000000..65c6a5cf437 --- /dev/null +++ b/src/main/java/seedu/address/model/meeting/Status.java @@ -0,0 +1,63 @@ +package seedu.address.model.meeting; + +/** + * Contains a Boolean representing whether a meeting is completed. + */ +public class Status { + + private Boolean isComplete; + + /** + * Constructs a {@code Status} field representing whether a meeting is complete. + */ + public Status(Boolean isComplete) { + this.isComplete = isComplete; + } + + /** + * Returns the current status + */ + public Boolean get() { + return isComplete; + } + + /** + * Changes the completion status to true + * + * @throws IllegalStateException if it is already completed + */ + public void mark() { + if(isComplete) { + throw new IllegalStateException(); + } + + isComplete = true; + } + + @Override + public int hashCode() { + return isComplete.hashCode(); + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + if (!(other instanceof Status)) { + return false; + } + + Status completed = (Status) other; + return isComplete.equals(completed.isComplete); + } + + /** + * Format state as text for viewing. + */ + @Override + public String toString() { + return isComplete + " "; + } +} diff --git a/src/test/java/seedu/address/model/meeting/StatusTest.java b/src/test/java/seedu/address/model/meeting/StatusTest.java new file mode 100644 index 00000000000..ef7e07377d5 --- /dev/null +++ b/src/test/java/seedu/address/model/meeting/StatusTest.java @@ -0,0 +1,44 @@ +package seedu.address.model.meeting; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +public class StatusTest { + + @Test + public void constructor() { + Status status = new Status(false); + assertEquals(Boolean.FALSE, status.get()); + } + + @Test + public void mark_completed_throwsIllegalStateException() { + Status status = new Status(true); + assertThrows(IllegalStateException.class, () -> status.mark()); + } + + @Test + public void equals() { + Status status = new Status(false); + + // same values -> returns true + assertTrue(status.equals(new Status(false))); + + // same object -> returns true + assertTrue(status.equals(status)); + + // null -> returns false + assertFalse(status.equals(null)); + + // different types -> returns false + assertFalse(status.equals(5.0f)); + + // different values -> returns false + assertFalse(status.equals(new Status(true))); + } + +} From 8e6f6e0b8bb9a56234fd0e2d7c3890160653cbc7 Mon Sep 17 00:00:00 2001 From: Jason Date: Wed, 25 Oct 2023 21:45:04 +0800 Subject: [PATCH 02/18] Add Status field to Meeting and test --- .../commands/AddMeetingContactCommand.java | 2 +- .../logic/commands/EditMeetingCommand.java | 3 +- .../commands/RemoveMeetingContactCommand.java | 2 +- .../logic/parser/AddMeetingCommandParser.java | 2 +- .../seedu/address/model/meeting/Meeting.java | 12 ++++++- .../seedu/address/model/meeting/Status.java | 1 + .../address/model/util/SampleDataUtil.java | 4 +-- .../address/storage/JsonAdaptedMeeting.java | 20 ++++++++--- .../storage/JsonAdaptedMeetingTest.java | 35 ++++++++++++------- .../address/testutil/MeetingBuilder.java | 18 ++++++++-- 10 files changed, 72 insertions(+), 27 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/AddMeetingContactCommand.java b/src/main/java/seedu/address/logic/commands/AddMeetingContactCommand.java index b348a8fa54e..90956474d43 100644 --- a/src/main/java/seedu/address/logic/commands/AddMeetingContactCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddMeetingContactCommand.java @@ -79,7 +79,7 @@ static Meeting addAttendee(Meeting meeting, Attendee attendeeToAdd) { Set updatedAttendees = new LinkedHashSet<>(meeting.getAttendees()); updatedAttendees.add(attendeeToAdd); Meeting updatedMeeting = new Meeting(meeting.getTitle(), meeting.getLocation(), meeting.getStart(), - meeting.getEnd(), updatedAttendees, meeting.getTags()); + meeting.getEnd(), updatedAttendees, meeting.getTags(), meeting.getStatus()); return updatedMeeting; } diff --git a/src/main/java/seedu/address/logic/commands/EditMeetingCommand.java b/src/main/java/seedu/address/logic/commands/EditMeetingCommand.java index 0dc569cad03..5ecdc747fc6 100644 --- a/src/main/java/seedu/address/logic/commands/EditMeetingCommand.java +++ b/src/main/java/seedu/address/logic/commands/EditMeetingCommand.java @@ -102,12 +102,13 @@ static Meeting createEditedMeeting(Meeting meetingToEdit, LocalDateTime updatedEnd = editMeetingDescriptor.getEnd().orElse(meetingToEdit.getEnd()); Set attendees = meetingToEdit.getAttendees(); Set updatedTags = editMeetingDescriptor.getTags().orElse(meetingToEdit.getTags()); + Boolean status = meetingToEdit.getStatus(); if (!MeetingTime.isValidMeetingTime(updatedStart, updatedEnd)) { throw new CommandException(MeetingTime.MESSAGE_CONSTRAINTS); } - return new Meeting(updatedTitle, updatedLocation, updatedStart, updatedEnd, attendees, updatedTags); + return new Meeting(updatedTitle, updatedLocation, updatedStart, updatedEnd, attendees, updatedTags, status); } @Override diff --git a/src/main/java/seedu/address/logic/commands/RemoveMeetingContactCommand.java b/src/main/java/seedu/address/logic/commands/RemoveMeetingContactCommand.java index 2b12de4252e..e0f0c163370 100644 --- a/src/main/java/seedu/address/logic/commands/RemoveMeetingContactCommand.java +++ b/src/main/java/seedu/address/logic/commands/RemoveMeetingContactCommand.java @@ -68,7 +68,7 @@ static Meeting removeAttendee(Meeting meeting, Attendee attendeeToRemove) { Set updatedAttendees = new LinkedHashSet<>(meeting.getAttendees()); updatedAttendees.remove(attendeeToRemove); Meeting updatedMeeting = new Meeting(meeting.getTitle(), meeting.getLocation(), meeting.getStart(), - meeting.getEnd(), updatedAttendees, meeting.getTags()); + meeting.getEnd(), updatedAttendees, meeting.getTags(), meeting.getStatus()); return updatedMeeting; } diff --git a/src/main/java/seedu/address/logic/parser/AddMeetingCommandParser.java b/src/main/java/seedu/address/logic/parser/AddMeetingCommandParser.java index 03d10653920..2781a7cceb7 100644 --- a/src/main/java/seedu/address/logic/parser/AddMeetingCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/AddMeetingCommandParser.java @@ -51,7 +51,7 @@ public AddMeetingCommand parse(String args) throws ParseException { Set attendeeList = ParserUtil.parseAttendees(argMultimap.getAllValues(PREFIX_NAME)); Set tagList = ParserUtil.parseTags(argMultimap.getAllValues(PREFIX_TAG)); - Meeting meeting = new Meeting(title, location, start, end, attendeeList, tagList); + Meeting meeting = new Meeting(title, location, start, end, attendeeList, tagList, false); return new AddMeetingCommand(meeting); } diff --git a/src/main/java/seedu/address/model/meeting/Meeting.java b/src/main/java/seedu/address/model/meeting/Meeting.java index a5a3ebacb23..3bc33a13d06 100644 --- a/src/main/java/seedu/address/model/meeting/Meeting.java +++ b/src/main/java/seedu/address/model/meeting/Meeting.java @@ -24,17 +24,19 @@ public class Meeting { private final MeetingTime meetingTime; private final Set attendees; private final Set tags; + private final Status status; /** * Every field must be present and not null. */ public Meeting(Title title, Location location, LocalDateTime start, LocalDateTime end, Set attendees, - Set tags) { + Set tags, Boolean status) { this.title = title; this.location = location; this.meetingTime = new MeetingTime(start, end); this.attendees = new LinkedHashSet<>(attendees); this.tags = new HashSet<>(tags); + this.status = new Status(status); } public Title getTitle() { @@ -57,6 +59,14 @@ public MeetingTime getMeetingTime() { return meetingTime; } + public Boolean getStatus() { + return status.get(); + } + + public void mark() { + status.mark(); + } + public boolean withinSpecifiedTime(LocalDateTime start, LocalDateTime end) { return !meetingTime.getStart().isBefore(start) && !meetingTime.getEnd().isAfter(end); } diff --git a/src/main/java/seedu/address/model/meeting/Status.java b/src/main/java/seedu/address/model/meeting/Status.java index 65c6a5cf437..fdc0b2e8e4f 100644 --- a/src/main/java/seedu/address/model/meeting/Status.java +++ b/src/main/java/seedu/address/model/meeting/Status.java @@ -5,6 +5,7 @@ */ public class Status { + public static final String MESSAGE_CONSTRAINTS = "Status must be exactly 'true' or 'false'"; private Boolean isComplete; /** diff --git a/src/main/java/seedu/address/model/util/SampleDataUtil.java b/src/main/java/seedu/address/model/util/SampleDataUtil.java index 5a8e97063db..b59cae29943 100644 --- a/src/main/java/seedu/address/model/util/SampleDataUtil.java +++ b/src/main/java/seedu/address/model/util/SampleDataUtil.java @@ -54,11 +54,11 @@ public static Meeting[] getSampleMeetings() { new Meeting(new Title("Test Meeting 1"), new Location("Room 1"), LocalDateTime.parse("02.10.2023 1000", FORMAT), LocalDateTime.parse("03.10.2023 1000", FORMAT), - getAttendeeSet("Alex Yeoh"), getTagSet("work")), + getAttendeeSet("Alex Yeoh"), getTagSet("work"), false), new Meeting(new Title("Test Meeting 2"), new Location("Room 2"), LocalDateTime.parse("02.10.2023 1000", FORMAT), LocalDateTime.parse("02.10.2023 1000", FORMAT), - getAttendeeSet(), getTagSet()), + getAttendeeSet(), getTagSet(), false), }; } diff --git a/src/main/java/seedu/address/storage/JsonAdaptedMeeting.java b/src/main/java/seedu/address/storage/JsonAdaptedMeeting.java index 702ee11d3cb..8a06536e540 100644 --- a/src/main/java/seedu/address/storage/JsonAdaptedMeeting.java +++ b/src/main/java/seedu/address/storage/JsonAdaptedMeeting.java @@ -16,6 +16,7 @@ import seedu.address.model.meeting.Location; import seedu.address.model.meeting.Meeting; import seedu.address.model.meeting.MeetingTime; +import seedu.address.model.meeting.Status; import seedu.address.model.meeting.Title; import seedu.address.model.tag.Tag; @@ -32,6 +33,7 @@ class JsonAdaptedMeeting { private final String end; private final List attendees = new ArrayList<>(); private final List tags = new ArrayList<>(); + private final String status; /** * Constructs a {@code JsonAdaptedPerson} with the given person details. @@ -40,7 +42,7 @@ class JsonAdaptedMeeting { public JsonAdaptedMeeting(@JsonProperty("title") String title, @JsonProperty("location") String location, @JsonProperty("start") String start, @JsonProperty("end") String end, @JsonProperty("attendees") List attendees, - @JsonProperty("tags") List tags) { + @JsonProperty("tags") List tags, @JsonProperty("status") String status) { this.title = title; this.location = location; @@ -52,6 +54,7 @@ public JsonAdaptedMeeting(@JsonProperty("title") String title, @JsonProperty("lo if (tags != null) { this.tags.addAll(tags); } + this.status = status; } /** @@ -68,6 +71,7 @@ public JsonAdaptedMeeting(Meeting source) { tags.addAll(source.getTags().stream() .map(JsonAdaptedTag::new) .collect(Collectors.toList())); + status = source.getStatus().toString(); } /** @@ -80,11 +84,13 @@ public Meeting toModelType() throws IllegalValueException { for (JsonAdaptedAttendee person : attendees) { meetingAttendees.add(person.toModelType()); } + final Set modelAttendees = new HashSet<>(meetingAttendees); final List meetingTags = new ArrayList<>(); for (JsonAdaptedTag tag : tags) { meetingTags.add(tag.toModelType()); } + final Set modelTags = new HashSet<>(meetingTags); if (title == null) { throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, @@ -118,10 +124,16 @@ public Meeting toModelType() throws IllegalValueException { final LocalDateTime modelStart = LocalDateTime.parse(start); final LocalDateTime modelEnd = LocalDateTime.parse(end); - final Set modelAttendees = new HashSet<>(meetingAttendees); + if (status == null) { + throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, + Status.class.getSimpleName())); + } + if (status != Boolean.FALSE.toString() && status != Boolean.TRUE.toString()) { + throw new IllegalValueException(Status.MESSAGE_CONSTRAINTS); + } + final Boolean modelStatus = Boolean.parseBoolean(status); - final Set modelTags = new HashSet<>(meetingTags); - return new Meeting(modelTitle, modelLocation, modelStart, modelEnd, modelAttendees, modelTags); + return new Meeting(modelTitle, modelLocation, modelStart, modelEnd, modelAttendees, modelTags, modelStatus); } } diff --git a/src/test/java/seedu/address/storage/JsonAdaptedMeetingTest.java b/src/test/java/seedu/address/storage/JsonAdaptedMeetingTest.java index e04d623b48a..d22bbc0c609 100644 --- a/src/test/java/seedu/address/storage/JsonAdaptedMeetingTest.java +++ b/src/test/java/seedu/address/storage/JsonAdaptedMeetingTest.java @@ -26,11 +26,13 @@ public class JsonAdaptedMeetingTest { private static final String INVALID_END = "88.88.8888 8888"; private static final String INVALID_ATTENDEE = " "; private static final String INVALID_TAG = "#friend"; - + private static final String INVALID_STATUS = "untrue"; + private static final String VALID_TITLE = MEETING1.getTitle().toString(); private static final String VALID_LOCATION = MEETING1.getLocation().toString(); private static final String VALID_START = MEETING1.getStart().toString(); private static final String VALID_END = MEETING1.getEnd().toString(); + private static final String VALID_STATUS = MEETING1.getStatus().toString(); private static final Meeting EDITED_MEETING_1 = new MeetingBuilder(MEETING1).withAttendees("Alice Pauline").build(); private static final List VALID_ATTENDEE = EDITED_MEETING_1.getAttendees().stream() @@ -40,14 +42,14 @@ public class JsonAdaptedMeetingTest { @Test public void toModelType_validMeetingDetails_returnsMeeting() throws Exception { - JsonAdaptedMeeting meeting = new JsonAdaptedMeeting(EDITED_MEETING_1); - assertEquals(EDITED_MEETING_1, meeting.toModelType()); + JsonAdaptedMeeting meeting = new JsonAdaptedMeeting(MEETING1); + assertEquals(MEETING1, meeting.toModelType()); } @Test public void toModelType_invalidTitle_throwsIllegalValueException() throws IllegalValueException { JsonAdaptedMeeting meeting = new JsonAdaptedMeeting(INVALID_TITLE, VALID_LOCATION, VALID_START, VALID_END, - VALID_ATTENDEE, VALID_TAGS); + VALID_ATTENDEE, VALID_TAGS, "false"); String expectedMessage = Title.MESSAGE_CONSTRAINTS; assertThrows(IllegalValueException.class, expectedMessage, meeting::toModelType); } @@ -55,7 +57,7 @@ public void toModelType_invalidTitle_throwsIllegalValueException() throws Illega @Test public void toModelType_nullTitle_throwsIllegalValueException() { JsonAdaptedMeeting meeting = new JsonAdaptedMeeting(null, VALID_LOCATION, VALID_START, VALID_END, - VALID_ATTENDEE, VALID_TAGS); + VALID_ATTENDEE, VALID_TAGS, VALID_STATUS); String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Title.class.getSimpleName()); assertThrows(IllegalValueException.class, expectedMessage, meeting::toModelType); } @@ -63,7 +65,7 @@ public void toModelType_nullTitle_throwsIllegalValueException() { @Test public void toModelType_invalidLocation_throwsIllegalValueException() { JsonAdaptedMeeting meeting = new JsonAdaptedMeeting(VALID_TITLE, INVALID_LOCATION, VALID_START, VALID_END, - VALID_ATTENDEE, VALID_TAGS); + VALID_ATTENDEE, VALID_TAGS, VALID_STATUS); String expectedMessage = Location.MESSAGE_CONSTRAINTS; assertThrows(IllegalValueException.class, expectedMessage, meeting::toModelType); } @@ -71,7 +73,7 @@ public void toModelType_invalidLocation_throwsIllegalValueException() { @Test public void toModelType_nullLocation_throwsIllegalValueException() { JsonAdaptedMeeting meeting = new JsonAdaptedMeeting(VALID_TITLE, null, VALID_START, VALID_END, VALID_ATTENDEE, - VALID_TAGS); + VALID_TAGS, VALID_STATUS); String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Location.class.getSimpleName()); assertThrows(IllegalValueException.class, expectedMessage, meeting::toModelType); } @@ -79,7 +81,7 @@ public void toModelType_nullLocation_throwsIllegalValueException() { @Test public void toModelType_invalidStart_throwsIllegalValueException() { JsonAdaptedMeeting meeting = new JsonAdaptedMeeting(VALID_TITLE, VALID_LOCATION, INVALID_START, VALID_END, - VALID_ATTENDEE, VALID_TAGS); + VALID_ATTENDEE, VALID_TAGS, VALID_STATUS); String expectedMessage = MeetingTime.MESSAGE_CONSTRAINTS; assertThrows(IllegalValueException.class, expectedMessage, meeting::toModelType); } @@ -87,7 +89,7 @@ public void toModelType_invalidStart_throwsIllegalValueException() { @Test public void toModelType_nullStart_throwsIllegalValueException() { JsonAdaptedMeeting meeting = new JsonAdaptedMeeting(VALID_TITLE, VALID_LOCATION, null, VALID_END, - VALID_ATTENDEE, VALID_TAGS); + VALID_ATTENDEE, VALID_TAGS, VALID_STATUS); String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, LocalDateTime.class.getSimpleName()); assertThrows(IllegalValueException.class, expectedMessage, meeting::toModelType); } @@ -95,7 +97,7 @@ public void toModelType_nullStart_throwsIllegalValueException() { @Test public void toModelType_invalidEnd_throwsIllegalValueException() { JsonAdaptedMeeting meeting = new JsonAdaptedMeeting(VALID_TITLE, VALID_LOCATION, VALID_START, INVALID_END, - VALID_ATTENDEE, VALID_TAGS); + VALID_ATTENDEE, VALID_TAGS, VALID_STATUS); String expectedMessage = MeetingTime.MESSAGE_CONSTRAINTS; assertThrows(IllegalValueException.class, expectedMessage, meeting::toModelType); } @@ -103,7 +105,7 @@ public void toModelType_invalidEnd_throwsIllegalValueException() { @Test public void toModelType_nullEnd_throwsIllegalValueException() { JsonAdaptedMeeting meeting = new JsonAdaptedMeeting(VALID_TITLE, VALID_LOCATION, null, VALID_END, - VALID_ATTENDEE, VALID_TAGS); + VALID_ATTENDEE, VALID_TAGS, VALID_STATUS); String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, LocalDateTime.class.getSimpleName()); assertThrows(IllegalValueException.class, expectedMessage, meeting::toModelType); } @@ -113,7 +115,7 @@ public void toModelType_invalidAttendees_throwsIllegalValueException() { List invalidAttendees = new ArrayList<>(VALID_ATTENDEE); invalidAttendees.add(new JsonAdaptedAttendee(INVALID_ATTENDEE)); JsonAdaptedMeeting meeting = new JsonAdaptedMeeting(VALID_TITLE, VALID_LOCATION, VALID_START, VALID_END, - invalidAttendees, VALID_TAGS); + invalidAttendees, VALID_TAGS, VALID_STATUS); assertThrows(IllegalValueException.class, meeting::toModelType); } @@ -122,7 +124,14 @@ public void toModelType_invalidTags_throwsIllegalValueException() { List invalidTags = new ArrayList<>(VALID_TAGS); invalidTags.add(new JsonAdaptedTag(INVALID_TAG)); JsonAdaptedMeeting meeting = new JsonAdaptedMeeting(VALID_TITLE, VALID_LOCATION, VALID_START, VALID_END, - VALID_ATTENDEE, invalidTags); + VALID_ATTENDEE, invalidTags, VALID_STATUS); + assertThrows(IllegalValueException.class, meeting::toModelType); + } + + @Test + public void toModelType_invalidStatus_throwsIllegalValueException() { + JsonAdaptedMeeting meeting = new JsonAdaptedMeeting(VALID_TITLE, VALID_LOCATION, VALID_START, VALID_END, + VALID_ATTENDEE, VALID_TAGS, INVALID_STATUS); assertThrows(IllegalValueException.class, meeting::toModelType); } diff --git a/src/test/java/seedu/address/testutil/MeetingBuilder.java b/src/test/java/seedu/address/testutil/MeetingBuilder.java index 4061c053978..3433b19eb16 100644 --- a/src/test/java/seedu/address/testutil/MeetingBuilder.java +++ b/src/test/java/seedu/address/testutil/MeetingBuilder.java @@ -23,12 +23,15 @@ public class MeetingBuilder { public static final String DEFAULT_LOCATION = "Room 1"; public static final LocalDateTime DEFAULT_START = LocalDateTime.parse("02.10.2023 1000", FORMAT); public static final LocalDateTime DEFAULT_END = LocalDateTime.parse("03.10.2023 1000", FORMAT); + public static final Boolean DEFAULT_STATUS = false; + private Title title; private Location location; private LocalDateTime start; private LocalDateTime end; private Set attendees; private Set tags; + private Boolean status; /** * Creates a {@code MeetingBuilder} with the default details. @@ -40,6 +43,7 @@ public MeetingBuilder() { end = DEFAULT_END; attendees = new LinkedHashSet<>(); tags = new HashSet<>(); + status = DEFAULT_STATUS; } /** @@ -87,7 +91,7 @@ public MeetingBuilder withStart(String start) { } /** - * Sets the {@code start} of the {@code Meeting} that we are building. + * Sets the {@code end} of the {@code Meeting} that we are building. */ public MeetingBuilder withEnd(String end) { this.end = LocalDateTime.parse(end, FORMAT); @@ -95,14 +99,22 @@ public MeetingBuilder withEnd(String end) { } /** - * Sets the {@code Phone} of the {@code Person} that we are building. + * Sets the {@code Location} of the {@code Meeting} that we are building. */ public MeetingBuilder withLocation(String location) { this.location = new Location(location); return this; } + /** + * Sets the {@code Status} of the {@code Meeting} that we are building. + */ + public MeetingBuilder withLocation(Boolean status) { + this.status = status; + return this; + } + public Meeting build() { - return new Meeting(title, location, start, end, attendees, tags); + return new Meeting(title, location, start, end, attendees, tags, status); } } From db598eda918a283721d3590bd40ce1ac589170dc Mon Sep 17 00:00:00 2001 From: Jason Date: Thu, 26 Oct 2023 16:09:04 +0800 Subject: [PATCH 03/18] Change Status of meeting to MeetingStatus --- .../logic/commands/EditMeetingCommand.java | 3 +- .../logic/parser/AddMeetingCommandParser.java | 4 ++- .../seedu/address/model/meeting/Meeting.java | 14 ++++----- .../{Status.java => MeetingStatus.java} | 30 ++++--------------- .../address/model/util/SampleDataUtil.java | 5 ++-- .../address/storage/JsonAdaptedMeeting.java | 8 ++--- .../address/model/meeting/StatusTest.java | 17 ++++------- .../address/testutil/MeetingBuilder.java | 7 +++-- 8 files changed, 31 insertions(+), 57 deletions(-) rename src/main/java/seedu/address/model/meeting/{Status.java => MeetingStatus.java} (58%) diff --git a/src/main/java/seedu/address/logic/commands/EditMeetingCommand.java b/src/main/java/seedu/address/logic/commands/EditMeetingCommand.java index 5ecdc747fc6..3cc3e9aa1f4 100644 --- a/src/main/java/seedu/address/logic/commands/EditMeetingCommand.java +++ b/src/main/java/seedu/address/logic/commands/EditMeetingCommand.java @@ -25,6 +25,7 @@ import seedu.address.model.meeting.Attendee; import seedu.address.model.meeting.Location; import seedu.address.model.meeting.Meeting; +import seedu.address.model.meeting.MeetingStatus; import seedu.address.model.meeting.MeetingTime; import seedu.address.model.meeting.Title; import seedu.address.model.tag.Tag; @@ -102,7 +103,7 @@ static Meeting createEditedMeeting(Meeting meetingToEdit, LocalDateTime updatedEnd = editMeetingDescriptor.getEnd().orElse(meetingToEdit.getEnd()); Set attendees = meetingToEdit.getAttendees(); Set updatedTags = editMeetingDescriptor.getTags().orElse(meetingToEdit.getTags()); - Boolean status = meetingToEdit.getStatus(); + MeetingStatus status = meetingToEdit.getStatus(); if (!MeetingTime.isValidMeetingTime(updatedStart, updatedEnd)) { throw new CommandException(MeetingTime.MESSAGE_CONSTRAINTS); diff --git a/src/main/java/seedu/address/logic/parser/AddMeetingCommandParser.java b/src/main/java/seedu/address/logic/parser/AddMeetingCommandParser.java index 2781a7cceb7..04a97c74e0e 100644 --- a/src/main/java/seedu/address/logic/parser/AddMeetingCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/AddMeetingCommandParser.java @@ -17,6 +17,7 @@ import seedu.address.model.meeting.Attendee; import seedu.address.model.meeting.Location; import seedu.address.model.meeting.Meeting; +import seedu.address.model.meeting.MeetingStatus; import seedu.address.model.meeting.MeetingTime; import seedu.address.model.meeting.Title; import seedu.address.model.tag.Tag; @@ -50,8 +51,9 @@ public AddMeetingCommand parse(String args) throws ParseException { } Set attendeeList = ParserUtil.parseAttendees(argMultimap.getAllValues(PREFIX_NAME)); Set tagList = ParserUtil.parseTags(argMultimap.getAllValues(PREFIX_TAG)); + MeetingStatus status = new MeetingStatus(false); - Meeting meeting = new Meeting(title, location, start, end, attendeeList, tagList, false); + Meeting meeting = new Meeting(title, location, start, end, attendeeList, tagList, status); return new AddMeetingCommand(meeting); } diff --git a/src/main/java/seedu/address/model/meeting/Meeting.java b/src/main/java/seedu/address/model/meeting/Meeting.java index 3bc33a13d06..d98d0b5152c 100644 --- a/src/main/java/seedu/address/model/meeting/Meeting.java +++ b/src/main/java/seedu/address/model/meeting/Meeting.java @@ -24,19 +24,19 @@ public class Meeting { private final MeetingTime meetingTime; private final Set attendees; private final Set tags; - private final Status status; + private final MeetingStatus status; /** * Every field must be present and not null. */ public Meeting(Title title, Location location, LocalDateTime start, LocalDateTime end, Set attendees, - Set tags, Boolean status) { + Set tags, MeetingStatus status) { this.title = title; this.location = location; this.meetingTime = new MeetingTime(start, end); this.attendees = new LinkedHashSet<>(attendees); this.tags = new HashSet<>(tags); - this.status = new Status(status); + this.status = status; } public Title getTitle() { @@ -59,12 +59,8 @@ public MeetingTime getMeetingTime() { return meetingTime; } - public Boolean getStatus() { - return status.get(); - } - - public void mark() { - status.mark(); + public MeetingStatus getStatus() { + return status; } public boolean withinSpecifiedTime(LocalDateTime start, LocalDateTime end) { diff --git a/src/main/java/seedu/address/model/meeting/Status.java b/src/main/java/seedu/address/model/meeting/MeetingStatus.java similarity index 58% rename from src/main/java/seedu/address/model/meeting/Status.java rename to src/main/java/seedu/address/model/meeting/MeetingStatus.java index fdc0b2e8e4f..eb0650a26ef 100644 --- a/src/main/java/seedu/address/model/meeting/Status.java +++ b/src/main/java/seedu/address/model/meeting/MeetingStatus.java @@ -3,38 +3,18 @@ /** * Contains a Boolean representing whether a meeting is completed. */ -public class Status { +public class MeetingStatus { public static final String MESSAGE_CONSTRAINTS = "Status must be exactly 'true' or 'false'"; - private Boolean isComplete; + public final Boolean isComplete; /** * Constructs a {@code Status} field representing whether a meeting is complete. */ - public Status(Boolean isComplete) { + public MeetingStatus(Boolean isComplete) { this.isComplete = isComplete; } - /** - * Returns the current status - */ - public Boolean get() { - return isComplete; - } - - /** - * Changes the completion status to true - * - * @throws IllegalStateException if it is already completed - */ - public void mark() { - if(isComplete) { - throw new IllegalStateException(); - } - - isComplete = true; - } - @Override public int hashCode() { return isComplete.hashCode(); @@ -46,11 +26,11 @@ public boolean equals(Object other) { return true; } - if (!(other instanceof Status)) { + if (!(other instanceof MeetingStatus)) { return false; } - Status completed = (Status) other; + MeetingStatus completed = (MeetingStatus) other; return isComplete.equals(completed.isComplete); } diff --git a/src/main/java/seedu/address/model/util/SampleDataUtil.java b/src/main/java/seedu/address/model/util/SampleDataUtil.java index b59cae29943..b1fe448062a 100644 --- a/src/main/java/seedu/address/model/util/SampleDataUtil.java +++ b/src/main/java/seedu/address/model/util/SampleDataUtil.java @@ -13,6 +13,7 @@ import seedu.address.model.meeting.Attendee; import seedu.address.model.meeting.Location; import seedu.address.model.meeting.Meeting; +import seedu.address.model.meeting.MeetingStatus; import seedu.address.model.meeting.Title; import seedu.address.model.person.Email; import seedu.address.model.person.Name; @@ -54,11 +55,11 @@ public static Meeting[] getSampleMeetings() { new Meeting(new Title("Test Meeting 1"), new Location("Room 1"), LocalDateTime.parse("02.10.2023 1000", FORMAT), LocalDateTime.parse("03.10.2023 1000", FORMAT), - getAttendeeSet("Alex Yeoh"), getTagSet("work"), false), + getAttendeeSet("Alex Yeoh"), getTagSet("work"), new MeetingStatus(false)), new Meeting(new Title("Test Meeting 2"), new Location("Room 2"), LocalDateTime.parse("02.10.2023 1000", FORMAT), LocalDateTime.parse("02.10.2023 1000", FORMAT), - getAttendeeSet(), getTagSet(), false), + getAttendeeSet(), getTagSet(), new MeetingStatus(false)), }; } diff --git a/src/main/java/seedu/address/storage/JsonAdaptedMeeting.java b/src/main/java/seedu/address/storage/JsonAdaptedMeeting.java index 8a06536e540..7274a93603a 100644 --- a/src/main/java/seedu/address/storage/JsonAdaptedMeeting.java +++ b/src/main/java/seedu/address/storage/JsonAdaptedMeeting.java @@ -16,7 +16,7 @@ import seedu.address.model.meeting.Location; import seedu.address.model.meeting.Meeting; import seedu.address.model.meeting.MeetingTime; -import seedu.address.model.meeting.Status; +import seedu.address.model.meeting.MeetingStatus; import seedu.address.model.meeting.Title; import seedu.address.model.tag.Tag; @@ -126,12 +126,12 @@ public Meeting toModelType() throws IllegalValueException { if (status == null) { throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, - Status.class.getSimpleName())); + MeetingStatus.class.getSimpleName())); } if (status != Boolean.FALSE.toString() && status != Boolean.TRUE.toString()) { - throw new IllegalValueException(Status.MESSAGE_CONSTRAINTS); + throw new IllegalValueException(MeetingStatus.MESSAGE_CONSTRAINTS); } - final Boolean modelStatus = Boolean.parseBoolean(status); + final MeetingStatus modelStatus = new MeetingStatus(Boolean.parseBoolean(status)); return new Meeting(modelTitle, modelLocation, modelStart, modelEnd, modelAttendees, modelTags, modelStatus); } diff --git a/src/test/java/seedu/address/model/meeting/StatusTest.java b/src/test/java/seedu/address/model/meeting/StatusTest.java index ef7e07377d5..477f230b91a 100644 --- a/src/test/java/seedu/address/model/meeting/StatusTest.java +++ b/src/test/java/seedu/address/model/meeting/StatusTest.java @@ -2,7 +2,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; @@ -11,22 +10,16 @@ public class StatusTest { @Test public void constructor() { - Status status = new Status(false); - assertEquals(Boolean.FALSE, status.get()); - } - - @Test - public void mark_completed_throwsIllegalStateException() { - Status status = new Status(true); - assertThrows(IllegalStateException.class, () -> status.mark()); + MeetingStatus status = new MeetingStatus(false); + assertEquals(Boolean.FALSE, status.isComplete); } @Test public void equals() { - Status status = new Status(false); + MeetingStatus status = new MeetingStatus(false); // same values -> returns true - assertTrue(status.equals(new Status(false))); + assertTrue(status.equals(new MeetingStatus(false))); // same object -> returns true assertTrue(status.equals(status)); @@ -38,7 +31,7 @@ public void equals() { assertFalse(status.equals(5.0f)); // different values -> returns false - assertFalse(status.equals(new Status(true))); + assertFalse(status.equals(new MeetingStatus(true))); } } diff --git a/src/test/java/seedu/address/testutil/MeetingBuilder.java b/src/test/java/seedu/address/testutil/MeetingBuilder.java index 3433b19eb16..f9bda7903e9 100644 --- a/src/test/java/seedu/address/testutil/MeetingBuilder.java +++ b/src/test/java/seedu/address/testutil/MeetingBuilder.java @@ -10,6 +10,7 @@ import seedu.address.model.meeting.Attendee; import seedu.address.model.meeting.Location; import seedu.address.model.meeting.Meeting; +import seedu.address.model.meeting.MeetingStatus; import seedu.address.model.meeting.Title; import seedu.address.model.tag.Tag; import seedu.address.model.util.SampleDataUtil; @@ -31,7 +32,7 @@ public class MeetingBuilder { private LocalDateTime end; private Set attendees; private Set tags; - private Boolean status; + private MeetingStatus status; /** * Creates a {@code MeetingBuilder} with the default details. @@ -43,7 +44,7 @@ public MeetingBuilder() { end = DEFAULT_END; attendees = new LinkedHashSet<>(); tags = new HashSet<>(); - status = DEFAULT_STATUS; + status = new MeetingStatus(DEFAULT_STATUS); } /** @@ -110,7 +111,7 @@ public MeetingBuilder withLocation(String location) { * Sets the {@code Status} of the {@code Meeting} that we are building. */ public MeetingBuilder withLocation(Boolean status) { - this.status = status; + this.status = new MeetingStatus(status); return this; } From 19798d75237a7145fe589318a0e317432237f625 Mon Sep 17 00:00:00 2001 From: Jason Date: Thu, 26 Oct 2023 16:29:09 +0800 Subject: [PATCH 04/18] Update Meeting equality --- src/main/java/seedu/address/model/meeting/Meeting.java | 4 ++-- src/main/java/seedu/address/model/meeting/MeetingStatus.java | 2 +- src/test/java/seedu/address/model/meeting/MeetingTest.java | 3 ++- src/test/java/seedu/address/testutil/MeetingBuilder.java | 1 + 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/seedu/address/model/meeting/Meeting.java b/src/main/java/seedu/address/model/meeting/Meeting.java index d98d0b5152c..a58310f85f1 100644 --- a/src/main/java/seedu/address/model/meeting/Meeting.java +++ b/src/main/java/seedu/address/model/meeting/Meeting.java @@ -121,7 +121,7 @@ public boolean equals(Object other) { Meeting otherMeeting = (Meeting) other; return title.equals(otherMeeting.title) && location.equals(otherMeeting.location) && meetingTime.equals(otherMeeting.meetingTime) && attendees.equals(otherMeeting.attendees) - && tags.equals(otherMeeting.tags); + && tags.equals(otherMeeting.tags) && status.equals(otherMeeting.status); } @Override @@ -134,7 +134,7 @@ public int hashCode() { public String toString() { return new ToStringBuilder(this).add("title", title).add("location", location) .add("start", meetingTime.getStart()).add("end", meetingTime.getEnd()).add("attendees", attendees) - .add("tags", tags).toString(); + .add("tags", tags).add("status", status).toString(); } /** diff --git a/src/main/java/seedu/address/model/meeting/MeetingStatus.java b/src/main/java/seedu/address/model/meeting/MeetingStatus.java index eb0650a26ef..011ecaad3e6 100644 --- a/src/main/java/seedu/address/model/meeting/MeetingStatus.java +++ b/src/main/java/seedu/address/model/meeting/MeetingStatus.java @@ -39,6 +39,6 @@ public boolean equals(Object other) { */ @Override public String toString() { - return isComplete + " "; + return isComplete.toString(); } } diff --git a/src/test/java/seedu/address/model/meeting/MeetingTest.java b/src/test/java/seedu/address/model/meeting/MeetingTest.java index 533bbe09674..9427d620675 100644 --- a/src/test/java/seedu/address/model/meeting/MeetingTest.java +++ b/src/test/java/seedu/address/model/meeting/MeetingTest.java @@ -84,7 +84,8 @@ public void equals() { public void toStringMethod() { String expected = Meeting.class.getCanonicalName() + "{title=" + MEETING1.getTitle() + ", location=" + MEETING1.getLocation() + ", start=" + MEETING1.getStart() + ", end=" + MEETING1.getEnd() - + ", attendees=" + MEETING1.getAttendees() + ", tags=" + MEETING1.getTags() + "}"; + + ", attendees=" + MEETING1.getAttendees() + ", tags=" + MEETING1.getTags() + ", status=" + + MEETING1.getStatus() + "}"; assertEquals(expected, MEETING1.toString()); } } diff --git a/src/test/java/seedu/address/testutil/MeetingBuilder.java b/src/test/java/seedu/address/testutil/MeetingBuilder.java index f9bda7903e9..23dab96b575 100644 --- a/src/test/java/seedu/address/testutil/MeetingBuilder.java +++ b/src/test/java/seedu/address/testutil/MeetingBuilder.java @@ -57,6 +57,7 @@ public MeetingBuilder(Meeting meetingToCopy) { end = meetingToCopy.getEnd(); attendees = new LinkedHashSet<>(meetingToCopy.getAttendees()); tags = new HashSet<>(meetingToCopy.getTags()); + status = meetingToCopy.getStatus(); } /** From d1be72436505126672426d09fa6797dd1a3962b8 Mon Sep 17 00:00:00 2001 From: Jason Date: Thu, 26 Oct 2023 16:40:25 +0800 Subject: [PATCH 05/18] Add Mark command and tests --- .../logic/commands/MarkMeetingCommand.java | 82 +++++++++++++ .../commands/MarkMeetingCommandTest.java | 116 ++++++++++++++++++ .../address/testutil/MeetingBuilder.java | 2 +- 3 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 src/main/java/seedu/address/logic/commands/MarkMeetingCommand.java create mode 100644 src/test/java/seedu/address/logic/commands/MarkMeetingCommandTest.java diff --git a/src/main/java/seedu/address/logic/commands/MarkMeetingCommand.java b/src/main/java/seedu/address/logic/commands/MarkMeetingCommand.java new file mode 100644 index 00000000000..57c97c143e5 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/MarkMeetingCommand.java @@ -0,0 +1,82 @@ +package seedu.address.logic.commands; + +import static java.util.Objects.requireNonNull; + +import java.util.List; + +import seedu.address.commons.core.index.Index; +import seedu.address.commons.util.ToStringBuilder; +import seedu.address.logic.Messages; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.meeting.Meeting; +import seedu.address.model.meeting.MeetingStatus; + +/** + * Marks a meeting as complete. + */ +public class MarkMeetingCommand extends Command { + + public static final String COMMAND_WORD = "mark"; + + public static final String MESSAGE_MARK_MEETING_SUCCESS = "Meeting marked as complete: %1$s"; + + public static final String MESSAGE_MEETING_ALREADY_COMPLETE = "Meeting has already been marked as complete."; + + public static final String MESSAGE_USAGE = COMMAND_WORD + + ": Marks the meeting identified by the index number used in the displayed meetings list as complete.\n" + + "Parameters: INDEX (must be a positive integer)\n" + "Example: " + COMMAND_WORD + "1"; + + private final Index targetIndex; + + public MarkMeetingCommand(Index targetIndex) { + this.targetIndex = targetIndex; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + List lastShownList = model.getFilteredMeetingList(); + + if (targetIndex.getZeroBased() >= lastShownList.size()) { + throw new CommandException(Messages.MESSAGE_INVALID_MEETING_DISPLAYED_INDEX); + } + + Meeting meetingToMark = lastShownList.get(targetIndex.getZeroBased()); + Meeting updatedMeeting = markMeeting(meetingToMark); + model.setMeeting(meetingToMark, updatedMeeting); + + return new CommandResult(String.format(MESSAGE_MARK_MEETING_SUCCESS, Messages.format(meetingToMark))); + } + + static Meeting markMeeting(Meeting meeting) throws CommandException{ + if(meeting.getStatus().isComplete) { + throw new CommandException(MESSAGE_MEETING_ALREADY_COMPLETE); + } + + Meeting markedMeeting = new Meeting(meeting.getTitle(), meeting.getLocation(), meeting.getStart(), + meeting.getEnd(), meeting.getAttendees(), meeting.getTags(), new MeetingStatus(true)); + + return markedMeeting; + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof MarkMeetingCommand)) { + return false; + } + + MarkMeetingCommand otherMarkMeetingCommand = (MarkMeetingCommand) other; + return targetIndex.equals(otherMarkMeetingCommand.targetIndex); + } + + @Override + public String toString() { + return new ToStringBuilder(this).add("targetIndex", targetIndex).toString(); + } +} diff --git a/src/test/java/seedu/address/logic/commands/MarkMeetingCommandTest.java b/src/test/java/seedu/address/logic/commands/MarkMeetingCommandTest.java new file mode 100644 index 00000000000..77f343f6e2c --- /dev/null +++ b/src/test/java/seedu/address/logic/commands/MarkMeetingCommandTest.java @@ -0,0 +1,116 @@ +package seedu.address.logic.commands; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure; +import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; +import static seedu.address.logic.commands.CommandTestUtil.showMeetingAtIndex; +import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_MEETING; +import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_MEETING; +import static seedu.address.testutil.TypicalMeetings.getTypicalAddressBook; + +import org.junit.jupiter.api.Test; + +import seedu.address.commons.core.index.Index; +import seedu.address.logic.Messages; +import seedu.address.model.Model; +import seedu.address.model.ModelManager; +import seedu.address.model.UserPrefs; +import seedu.address.model.meeting.Meeting; +import seedu.address.testutil.MeetingBuilder; + +/** + * Contains integration tests (interaction with the Model) and unit tests for {@code MarkMeetingCommand}. + */ +public class MarkMeetingCommandTest { + + private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); + + @Test + public void execute_validIndexUnfilteredList_success() { + Meeting meetingToMark = model.getFilteredMeetingList().get(INDEX_FIRST_MEETING.getZeroBased()); + MarkMeetingCommand markMeetingCommand = new MarkMeetingCommand(INDEX_FIRST_MEETING); + + String expectedMessage = String.format(MarkMeetingCommand.MESSAGE_MARK_MEETING_SUCCESS, + Messages.format(meetingToMark)); + + ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); + Meeting markedMeeting = new MeetingBuilder(meetingToMark).withStatus(true).build(); + expectedModel.setMeeting(meetingToMark, markedMeeting); + + assertCommandSuccess(markMeetingCommand, model, expectedMessage, expectedModel); + } + + @Test + public void execute_invalidIndexUnfilteredList_throwsCommandException() { + Index outOfBoundIndex = Index.fromOneBased(model.getFilteredMeetingList().size() + 1); + MarkMeetingCommand markMeetingCommand = new MarkMeetingCommand(outOfBoundIndex); + + assertCommandFailure(markMeetingCommand, model, Messages.MESSAGE_INVALID_MEETING_DISPLAYED_INDEX); + } + + @Test + public void execute_validIndexFilteredList_success() { + showMeetingAtIndex(model, INDEX_FIRST_MEETING); + + Meeting meetingToMark = model.getFilteredMeetingList().get(INDEX_FIRST_MEETING.getZeroBased()); + MarkMeetingCommand markMeetingCommand = new MarkMeetingCommand(INDEX_FIRST_MEETING); + + String expectedMessage = String.format(MarkMeetingCommand.MESSAGE_MARK_MEETING_SUCCESS, + Messages.format(meetingToMark)); + + ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); + Meeting markedMeeting = new MeetingBuilder(meetingToMark).withStatus(true).build(); + expectedModel.setMeeting(meetingToMark, markedMeeting); + showMeetingAtIndex(expectedModel, INDEX_FIRST_MEETING); + + assertCommandSuccess(markMeetingCommand, model, expectedMessage, expectedModel); + } + + @Test + public void execute_invalidIndexFilteredList_throwsCommandException() { + showMeetingAtIndex(model, INDEX_FIRST_MEETING); + + Index outOfBoundIndex = INDEX_SECOND_MEETING; + System.out.println("hi"); + System.out.println(outOfBoundIndex.getZeroBased()); + System.out.println(model.getAddressBook().getMeetingList().size()); + // ensures that outOfBoundIndex is still in bounds of address book list + assertTrue(outOfBoundIndex.getZeroBased() < model.getAddressBook().getMeetingList().size()); + + MarkMeetingCommand markMeetingCommand = new MarkMeetingCommand(outOfBoundIndex); + + assertCommandFailure(markMeetingCommand, model, Messages.MESSAGE_INVALID_MEETING_DISPLAYED_INDEX); + } + + @Test + public void equals() { + MarkMeetingCommand markFirstCommand = new MarkMeetingCommand(INDEX_FIRST_MEETING); + MarkMeetingCommand markSecondCommand = new MarkMeetingCommand(INDEX_SECOND_MEETING); + + // same object -> returns true + assertTrue(markFirstCommand.equals(markFirstCommand)); + + // same values -> returns true + MarkMeetingCommand markFirstCommandCopy = new MarkMeetingCommand(INDEX_FIRST_MEETING); + assertTrue(markFirstCommand.equals(markFirstCommandCopy)); + + // different types -> returns false + assertFalse(markFirstCommand.equals(1)); + + // null -> returns false + assertFalse(markFirstCommand.equals(null)); + + // different meeting -> returns false + assertFalse(markFirstCommand.equals(markSecondCommand)); + } + + @Test + public void toStringMethod() { + Index targetIndex = Index.fromOneBased(1); + MarkMeetingCommand markMeetingCommand = new MarkMeetingCommand(targetIndex); + String expected = MarkMeetingCommand.class.getCanonicalName() + "{targetIndex=" + targetIndex + "}"; + assertEquals(expected, markMeetingCommand.toString()); + } +} diff --git a/src/test/java/seedu/address/testutil/MeetingBuilder.java b/src/test/java/seedu/address/testutil/MeetingBuilder.java index 23dab96b575..86a87fd4242 100644 --- a/src/test/java/seedu/address/testutil/MeetingBuilder.java +++ b/src/test/java/seedu/address/testutil/MeetingBuilder.java @@ -111,7 +111,7 @@ public MeetingBuilder withLocation(String location) { /** * Sets the {@code Status} of the {@code Meeting} that we are building. */ - public MeetingBuilder withLocation(Boolean status) { + public MeetingBuilder withStatus(Boolean status) { this.status = new MeetingStatus(status); return this; } From 83e62cb6ae3d23cbb5e209e1ab1ac206845e4ad7 Mon Sep 17 00:00:00 2001 From: Jason Date: Thu, 26 Oct 2023 16:44:15 +0800 Subject: [PATCH 06/18] Add parser for Mark command and tests --- .../parser/MarkMeetingCommandParser.java | 29 ++++++++++++++++ .../parser/MarkMeetingCommandParserTest.java | 33 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 src/main/java/seedu/address/logic/parser/MarkMeetingCommandParser.java create mode 100644 src/test/java/seedu/address/logic/parser/MarkMeetingCommandParserTest.java diff --git a/src/main/java/seedu/address/logic/parser/MarkMeetingCommandParser.java b/src/main/java/seedu/address/logic/parser/MarkMeetingCommandParser.java new file mode 100644 index 00000000000..07deae8d5be --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/MarkMeetingCommandParser.java @@ -0,0 +1,29 @@ +package seedu.address.logic.parser; + +import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; + +import seedu.address.commons.core.index.Index; +import seedu.address.logic.commands.MarkMeetingCommand; +import seedu.address.logic.parser.exceptions.ParseException; + +/** + * Parses input arguments and creates a new MarkMeetingCommand object + */ +public class MarkMeetingCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the MarkMeetingCommand + * and returns a MarkMeetingCommand object for execution. + * @throws ParseException if the user input does not conform the expected format + */ + public MarkMeetingCommand parse(String args) throws ParseException { + try { + Index index = ParserUtil.parseIndex(args); + return new MarkMeetingCommand(index); + } catch (ParseException pe) { + throw new ParseException( + String.format(MESSAGE_INVALID_COMMAND_FORMAT, MarkMeetingCommand.MESSAGE_USAGE), pe); + } + } + +} diff --git a/src/test/java/seedu/address/logic/parser/MarkMeetingCommandParserTest.java b/src/test/java/seedu/address/logic/parser/MarkMeetingCommandParserTest.java new file mode 100644 index 00000000000..0b1f192f72b --- /dev/null +++ b/src/test/java/seedu/address/logic/parser/MarkMeetingCommandParserTest.java @@ -0,0 +1,33 @@ +package seedu.address.logic.parser; + +import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure; +import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess; +import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_MEETING; + +import org.junit.jupiter.api.Test; + +import seedu.address.logic.commands.MarkMeetingCommand; + +/** + * As we are only doing white-box testing, our test cases do not cover path variations + * outside of the MarkMeetingCommand code. For example, inputs "1" and "1 abc" take the + * same path through the MarkMeetingCommand, and therefore we test only one of them. + * The path variation for those two cases occur inside the ParserUtil, and + * therefore should be covered by the ParserUtilTest. + */ +public class MarkMeetingCommandParserTest { + + private MarkMeetingCommandParser parser = new MarkMeetingCommandParser(); + + @Test + public void parse_validArgs_returnsMarkCommand() { + assertParseSuccess(parser, "1", new MarkMeetingCommand(INDEX_FIRST_MEETING)); + } + + @Test + public void parse_invalidArgs_throwsParseException() { + assertParseFailure(parser, "a", + String.format(MESSAGE_INVALID_COMMAND_FORMAT, MarkMeetingCommand.MESSAGE_USAGE)); + } +} From d1fe2324e753fccae65f7093ea9ead0d842c7fbc Mon Sep 17 00:00:00 2001 From: Jason Date: Tue, 31 Oct 2023 11:02:00 +0800 Subject: [PATCH 07/18] Hook mark command into address book --- .../java/seedu/address/logic/parser/AddressBookParser.java | 4 ++++ .../seedu/address/logic/parser/AddressBookParserTest.java | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index f68222c4328..cfa1715ea18 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -23,6 +23,7 @@ import seedu.address.logic.commands.HelpCommand; import seedu.address.logic.commands.ListCommand; import seedu.address.logic.commands.ListMeetingCommand; +import seedu.address.logic.commands.MarkMeetingCommand; import seedu.address.logic.commands.RemarkCommand; import seedu.address.logic.commands.RemoveMeetingContactCommand; import seedu.address.logic.commands.ViewContactCommand; @@ -117,6 +118,9 @@ public Command parseCommand(String userInput) throws ParseException { case FindMeetingCommand.COMMAND_WORD: return new FindMeetingCommandParser().parse(arguments); + case MarkMeetingCommand.COMMAND_WORD: + return new MarkMeetingCommandParser().parse(arguments); + default: logger.finer("This user input caused a ParseException: " + userInput); throw new ParseException(MESSAGE_UNKNOWN_COMMAND); diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index b8d1f796381..eda8e55a9ec 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -27,6 +27,7 @@ import seedu.address.logic.commands.HelpCommand; import seedu.address.logic.commands.ListCommand; import seedu.address.logic.commands.ListMeetingCommand; +import seedu.address.logic.commands.MarkMeetingCommand; import seedu.address.logic.commands.RemoveMeetingContactCommand; import seedu.address.logic.commands.ViewContactCommand; import seedu.address.logic.commands.ViewMeetingCommand; @@ -147,6 +148,11 @@ public void parseCommand_rmmc() throws Exception { RemoveMeetingContactCommand.COMMAND_WORD + " 1 1") instanceof RemoveMeetingContactCommand); } + @Test + public void parseCommand_mark() throws Exception { + assertTrue(parser.parseCommand(MarkMeetingCommand.COMMAND_WORD + " 1") instanceof MarkMeetingCommand); + } + @Test public void parseCommand_unrecognisedInput_throwsParseException() { assertThrows(ParseException.class, String.format(MESSAGE_INVALID_COMMAND_FORMAT, HelpCommand.MESSAGE_USAGE), ( From 77a33bed225a77f46438a6563b25537a2c415e95 Mon Sep 17 00:00:00 2001 From: Jason Date: Tue, 31 Oct 2023 11:14:18 +0800 Subject: [PATCH 08/18] Fix logger and storage bugs --- src/main/java/seedu/address/logic/Messages.java | 2 ++ .../java/seedu/address/logic/commands/MarkMeetingCommand.java | 2 +- src/main/java/seedu/address/storage/JsonAdaptedMeeting.java | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/address/logic/Messages.java b/src/main/java/seedu/address/logic/Messages.java index a87a265da52..daa4ef645d3 100644 --- a/src/main/java/seedu/address/logic/Messages.java +++ b/src/main/java/seedu/address/logic/Messages.java @@ -69,6 +69,8 @@ public static String format(Meeting meeting) { .append(meeting.getEnd()) .append("; Attendees: "); meeting.getAttendees().forEach(builder::append); + builder.append("; Completed: ") + .append(meeting.getStatus()); return builder.toString(); } diff --git a/src/main/java/seedu/address/logic/commands/MarkMeetingCommand.java b/src/main/java/seedu/address/logic/commands/MarkMeetingCommand.java index 57c97c143e5..2b239d9da28 100644 --- a/src/main/java/seedu/address/logic/commands/MarkMeetingCommand.java +++ b/src/main/java/seedu/address/logic/commands/MarkMeetingCommand.java @@ -46,7 +46,7 @@ public CommandResult execute(Model model) throws CommandException { Meeting updatedMeeting = markMeeting(meetingToMark); model.setMeeting(meetingToMark, updatedMeeting); - return new CommandResult(String.format(MESSAGE_MARK_MEETING_SUCCESS, Messages.format(meetingToMark))); + return new CommandResult(String.format(MESSAGE_MARK_MEETING_SUCCESS, Messages.format(updatedMeeting))); } static Meeting markMeeting(Meeting meeting) throws CommandException{ diff --git a/src/main/java/seedu/address/storage/JsonAdaptedMeeting.java b/src/main/java/seedu/address/storage/JsonAdaptedMeeting.java index 7274a93603a..030f7d17ddc 100644 --- a/src/main/java/seedu/address/storage/JsonAdaptedMeeting.java +++ b/src/main/java/seedu/address/storage/JsonAdaptedMeeting.java @@ -128,7 +128,7 @@ public Meeting toModelType() throws IllegalValueException { throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, MeetingStatus.class.getSimpleName())); } - if (status != Boolean.FALSE.toString() && status != Boolean.TRUE.toString()) { + if (!status.equals(Boolean.FALSE.toString()) && !status.equals(Boolean.TRUE.toString())) { throw new IllegalValueException(MeetingStatus.MESSAGE_CONSTRAINTS); } final MeetingStatus modelStatus = new MeetingStatus(Boolean.parseBoolean(status)); From bc299c56a621747bed9bc7063fe60cada3207ee4 Mon Sep 17 00:00:00 2001 From: LoMaply Date: Wed, 1 Nov 2023 13:05:09 +0800 Subject: [PATCH 09/18] Fix User Guide errors due to merging --- docs/UserGuide.md | 160 +++++++++++++++++++--------------------------- 1 file changed, 64 insertions(+), 96 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 80957f00dcc..73b6d164126 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -3,7 +3,7 @@ layout: page title: OutBook User Guide --- -OutBook is an app that allows freelance insurance agents to manage their numerous contacts and meeting schedule. It is optimised for Command Line Interface (CLI) aims to significantly reduce the time needed for organizational tasks. +OutBook is an app that allows freelance insurance agents to manage their numerous contacts and meeting schedule. It is optimised for Command Line Interface (CLI) and aims to significantly reduce the time needed for organizational tasks. This guide is to help you explore and learn about what are its features and how to use them. Outbook has 2 lists which are used to track contacts and meetings respectively. These list can be filtered to show the specific data you need. @@ -60,7 +60,7 @@ It is able to add, edit and delete any contacts and meetings you want. As well a **:information_source: Notes about the command format:**
* Words in `UPPER_CASE` are the parameters to be supplied by you.
- e.g. in `add n/NAME`, `NAME` is a parameter which can be used as `add n/John Doe`. + e.g. in `addc n/NAME`, `NAME` is a parameter which can be used as `addc n/John Doe`. * Items in square brackets are optional.
e.g `n/NAME [t/TAG]` can be used as `n/John Doe t/friend` or as `n/John Doe`. @@ -71,7 +71,7 @@ It is able to add, edit and delete any contacts and meetings you want. As well a * You can place parameters in any order.
e.g. if the command specifies `n/NAME p/PHONE_NUMBER`, `p/PHONE_NUMBER n/NAME` is also acceptable. -* Any extraneous parameters you place for commands that do not take in parameters (such as `help`, `list`, `exit` and `clear`) will be ignored.
+* Any extraneous parameters you place for commands that do not take in parameters (such as `help`, `listc`, `exit` and `clear`) will be ignored.
e.g. if you type `help 123`, it will be interpreted as `help`. * If you are using a PDF version of this document, be careful when copying and pasting commands that span multiple lines as space characters surrounding line-breaks may be omitted when copied over to the application. @@ -93,17 +93,12 @@ Format: `help` Adds a contact to OutBook. -<<<<<<< HEAD -Format: `addc n/NAME p/PHONE_NUMBER e/EMAIL l/LAST_CONTACTED_TIME s/STATUS [r/REMARK][t/TAG]…​` -======= Format: `addc n/NAME p/PHONE_NUMBER e/EMAIL lc/LAST_CONTACTED_TIME [s/STATUS] [r/REMARK] [t/TAG]…​` ->>>>>>> master - -* NAME, PHONE_NUMBER, EMAIL and LAST_CONTACTED_TIME are compulsory fields. STATUS, REMARK and TAG are optional. -* PHONE_NUMBER must contain only numbers, and be at least 3 digits long. -* EMAIL must be of the format local-part@domain and adhere to the following constraints: - 1. The local-part should only contain alphanumeric characters and these special characters, excluding the parentheses, (+_.-). +* `NAME`, `PHONE_NUMBER`, `EMAIL` and `LAST_CONTACTED_TIME` are compulsory fields. `STATUS`, `REMARK` and `TAG` are optional. +* `PHONE_NUMBER` must contain only numbers, and be at least 3 digits long. +* `EMAIL` must be of the format local-part@domain and adhere to the following constraints: + 1. The local-part should only contain alphanumeric characters and the following special characters `+ _ . -`. 2. The local-part may not start or end with any special characters. 3. The domain name is made up of domain labels separated by periods. The domain name must: @@ -111,9 +106,9 @@ Format: `addc n/NAME p/PHONE_NUMBER e/EMAIL lc/LAST_CONTACTED_TIME [s/STATUS] [r - have each domain label start and end with alphanumeric characters - have each domain label consist of alphanumeric characters, separated only by hyphen -* LAST_CONTACTED_TIME must contain both date and time and adhere to the dd.MM.yyyy HHmm format. - - For instance, 1st October 2023, 10:00am will be written as 01.10.2023 1000. -* STATUS, if included, must be one of { NIL, Prospective, Active, Inactive, Claimant, Renewal } or blank. +* `LAST_CONTACTED_TIME` must contain both date and time and adhere to the `DD.MM.YYYY HHMM` format. + - eg. 1st October 2023, 10:00am will be written as `01.10.2023 1000`. +* STATUS, if included, must be one of `NIL, Prospective, Active, Inactive, Claimant, Renewal` or blank.
:bulb: **Tip:** @@ -127,11 +122,7 @@ You can put any number of tags (including 0) on a contact. ### Listing all persons : `listc` -<<<<<<< HEAD -Shows you a list of all contacts in OutBook. -======= Shows a list of all contacts in OutBook. Contacts are sorted by LAST_CONTACTED_TIME by default. ->>>>>>> master Format: `listc` @@ -155,7 +146,7 @@ Examples: Edits an existing contact in OutBook. -Format: `editc INDEX [n/NAME] [p/PHONE] [e/EMAIL] [lc/LAST_CONTACTED_TIME] [s/STATUS] [s/REMARK] [t/TAG]…​` +Format: `editc INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [l/LAST_CONTACTED_TIME] [s/STATUS] [r/REMARK] [t/TAG]…​` * Edits the contact 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, …​ * All fields are optional, but at least one must be provided. @@ -169,6 +160,9 @@ Examples: * `editc 2 n/Betsy Crower t/` Edits the name of the 2nd person to be `Betsy Crower` and clears all existing tags. +
+ + ### Viewing detailed contact information : `viewc` Views detailed information of a contact in OutBook. @@ -180,61 +174,31 @@ Format: `viewc INDEX` * The index **must be a positive integer** 1, 2, 3, …​ * Displays contact Name, Phone, Email, Last Contacted Time, Status, Remarks and Tags. * The displayed contact is reset when the `deletec` and `findc` commands are used. +* The displayed contact may change when `editc` is used in a way that modifies the order of the displayed person list, such as by editing the `LAST_CONTACTED_DATE`. This is intentional as the `editc` command is meant to display information based on the contact list index. Examples: * `viewc 2` Displays detailed information related to the 2nd contact on the list. -
- -### Editing a contact : `editc` - -Edits an existing contact in OutBook. - -Format: `editc INDEX [n/NAME] [p/PHONE] [e/EMAIL] [l/LAST_CONTACTED_TIME] [s/STATUS] [r/REMARK] [t/TAG]…​` - -* Edits the contact 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, …​ -* All fields are optional, but at least one must be provided. -* Existing values will be updated to the input values. -* When editing tags, the existing tags of the person will be removed i.e adding of tags is not cumulative. -* You can remove all the person’s tags by typing `t/` without - specifying any tags after it. - -Examples: -* `editc 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. -* `editc 2 n/Betsy Crower t/` Edits the name of the 2nd person to be `Betsy Crower` and clears all existing tags. - - -### Remarking a contact : `remark` - -Adds a remark to a contact. - -Format: `remark INDEX r/REMARK` - -* Adds a remark to the contact specified with `INDEX`. The index refers to the index number shown in the displayed person list. The index**must be a positive integer** 1, 2, 3, …​ -* Existing remark will be replaced with `REMARK`. -* You can remove an existing remark by typing `r/`. - -*Examples: -* `remark 1 r/Owes me a favour` Replaces the previous remark for the 1st contact with "Owes me a favour". -



+ ### Search for persons using contact fields: `findc` -Find persons whose contact details match the keywords specified for at least 1 of these fields: name, phone, email, status, tag +Find persons whose contact details match the keywords specified for at least 1 of these fields: `NAME`, `PHONE_NUMBER`, `EMAIL`, `STATUS`, `TAG`. Format: `findc [n/KEYWORDS] [p/KEYWORDS] [e/KEYWORDS] [lc/DATETIME] [s/KEYWORDS] [t/KEYWORDS]` -* The search is case-insensitive. e.g `shop` will match `SHOP` -* The order of the keywords does not matter. e.g. `Shop Meet` will match `Meet Shop` -* For name, status and tags, only full words will be matched e.g. `Meet` will not match `Meeting` -* For email, any characters (alphanumeric, special characters) will be matched e.g. `_` will match `m_e@gmail.com` -* For phone, the entire length of the input digits will be matched e.g. `913` will match `90091300` but not `90103000` -* For last contacted time, the input must adhere to the dd.MM.yyyy HHmm format e.g. 9th October 2023 10.30am will be `09.10.2023 1030` -* For a single field, a Person must match at least one keyword to be returned as a result (i.e. `OR` search). - e.g. `John Doe` will return `John Lee`, `James Doe` -* If there are multiple fields specified, the Person must match at least one keyword in each field to be returned as a result (i.e. `AND` search). - e.g. `n/John Doe s/Active` will return `Name: John Lee, Status: Active` +* The search is case-insensitive. e.g `shop` will match `SHOP`. +* The order of the keywords does not matter. e.g. `Shop Meet` will match `Meet Shop`. +* For `NAME`, `STATUS` and `TAG`, only full words will be matched e.g. `Meet` will not match `Meeting`. +* For `EMAIL`, any characters (alphanumeric, special characters) will be matched e.g. `_` will match `m_e@gmail.com`. +* For `PHONE_NUMBER`, the entire length of the input digits will be matched e.g. `913` will match `90091300` but not `90103000`. +* For `LAST_CONTACTED_TIME`, the input must adhere to the `DD.MM.YYYY HHMM` format. + - e.g. 9th October 2023, 10.30am will be written as `09.10.2023 1030`. +* If only one field is provided, all Persons matching at least one keyword will be returned (i.e. `OR` search). + - e.g. `John Doe` will return `John Lee`, `James Doe`. +* If multiple fields are provided, only Persons matching at least one keyword in each field will be returned (i.e. `AND` search). + - e.g. `n/John Doe s/active` will return `Name: John Lee, Status: Active` but not `Name: James Doe, Status: Claimant`. Examples: * `findc n/alice` returns `Alice` and `alice tan` @@ -246,6 +210,7 @@ Examples:
+ ## Meeting commands ### Adding a meeting: `addm` @@ -255,8 +220,8 @@ Meetings are sorted by start time given. Format: `addm m/TITLE a/LOCATION s/START e/END [t/TAG]…​` -* START and END must contain both date and time and adhere to the dd.MM.yyyy HHmm format. - - For instance, 1st October 2023, 10:00am will be written as 01.10.2023 1000. +* `START` and `END` must contain both date and time and adhere to the `DD.MM.YYYY HHMM` format. + - eg. 1st October 2023, 10:00am will be written as `01.10.2023 1000`. Examples: * `addm m/Lunch a/Cafeteria s/20.09.2023 1200 e/20.09.2023 1300` @@ -313,26 +278,29 @@ Format: `viewm INDEX` * The index **must be a positive integer** 1, 2, 3, …​ * Displays meeting Title, Location, Start/End, Attendees and Tags. * The displayed meeting is reset when the `deletem` and `findm` commands are used. +* The displayed meeting may change when `editm` is used in a way that modifies the order of the displayed meeting list, such as by editing the `START`. This is intentional as the `editm` command is meant to display information based on the meeting list index. Examples: * `viewm 2` Displays detailed information related to the 2nd meeting on the list, including current attendees. +
+ ### Search for Meetings using meeting fields: `findm` -Find meetings which details match the keywords you specified for at least 1 of these fields: title, location, attendee, tag; and fall within the start and end time you give. +Find meetings with details matching the keywords you specified for at least 1 of these fields: `TITLE`, `LOCATION`, `ATTENDEE_NAME`, `TAG`; and falls within the `START` and `END` time you give. -Format: `findm [m/KEYWORDS] [a/KEYWORDS] [t/KEYWORDS] [n/ATTENDEENAME] [s/START e/END]` +Format: `findm [m/KEYWORDS] [a/KEYWORDS] [t/KEYWORDS] [n/ATTENDEE_NAME] [s/START e/END]` -* The search is case-insensitive. e.g `shop` will match `SHOP` -* The order of the keywords does not matter. e.g. `Shop Meet` will match `Meet Shop` -* Title, location, tags and attendees are searched, within the time frame given by START and END -* Only full words will be matched e.g. `Meet` will not match `Meeting` -* For a single field, a Meeting must match at least one keyword will be returned (i.e. `OR` search). - e.g. `Shop Meet` will return `Meeting: Shop at mall`, `Meeting: Meet client` -* If there are multiple fields the meeting must match at least one keyword for each field to be returned (i.e. `AND` search). - e.g. `m/Shop Meet a/Mall` will return `Meeting: Shop at mall, Location:Mall` +* The search is case-insensitive. e.g `shop` will match `SHOP`. +* The order of the keywords does not matter. e.g. `Shop Meet` will match `Meet Shop`. +* `TITLE`, `LOCATION`, `TAG` and `ATTENDEE_NAME` are searched, within the time frame given by `START` and `END`. +* Only full words will be matched e.g. `Meet` will not match `Meeting`. +* If only one field is provided, all Meetings matching at least one keyword will be returned (i.e. `OR` search). + e.g. `m/Shop Meet` will return `Meeting: Shop at mall`, `Meeting: Meet client`. +* If multiple fields are provided, only Meetings matching at least one keyword in each field will be returned (i.e. `AND` search). + e.g. `m/Shop Meet a/Mall` will return `Meeting: Shop at mall, Location: Mall` but not `Meeting: Meet client, Location: Park`. Examples: * `findm m/project` returns `project` and `Project work` @@ -352,7 +320,7 @@ Adds a contact to a meeting as an attendee. Format: `addmc MEETING_INDEX CONTACT_INDEX` -* Adds the contact you specified with `CONTACT_INDEX` to a meeting specified with `MEETING_INDEX`. +* Adds the contact you specified with `CONTACT_INDEX` to a meeting specified with `MEETING_INDEX`. * `MEETING_INDEX` refers to the index number shown in the displayed meeting list. * `CONTACT_INDEX` refers to the index number shown in the displayed contact list. * The indexes **must be positive integers** 1, 2, 3, …​ @@ -423,22 +391,22 @@ If your changes to the data file makes its format invalid, OutBook will discard ## Command summary -| Action | Format, Examples | -|---------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| **Add contact** | `addc n/NAME p/PHONE_NUMBER e/EMAIL l/LAST_CONTACTED_TIME o/ORGANISATION [r/REMARK] [t/TAG]…​`
e.g., `add n/James Ho p/22224444 e/jamesho@example.com l/09.09.2023 0000 o/NUS t/friend t/colleague` | -| **Add contact to meeting** | `addmc MEETING_INDEX CONTACT_INDEX`
e.g., `addmc 2 1` | -| **Add meeting** | `addm m/TITLE a/LOCATION s/START e/END [t/TAG]…​`
e.g., `addm m/Lunch a/Cafeteria s/20.09.2023 1200 e/20.09.2023 1300` | -| **Clear** | `clear` | -| **Delete contact** | `deletec INDEX`
e.g., `deletec 3` | -| **Delete meeting** | `deletem INDEX`
e.g., `deletem 3` | -| **Edit contact** | `editc INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [l/LAST_CONTACTED_TIME] [o/ORGANISATION] [r/REMARK] [t/TAG]…​`
e.g.,`editc 2 n/James Lee e/jameslee@example.com` | -| **Edit meeting** | `editm INDEX [m/TITLE] [a/LOCATION] [s/START] [e/END] [t/TAG]…​`
e.g.,`editm 1 a/Hawker Centre s/15.09.2023 1500` | -| **Find contact** | `findc KEYWORD [MORE_KEYWORDS]`
e.g., `findc James Jake` | -| **Find meeting** | `findm [m/KEYWORDS] [a/KEYWORDS] [t/KEYWORDS] [n/ATTENDEENAME] [s/START e/END]`
e.g., `findm m/Zoom Meet s/09.09.2023 0000 e/09.10.2023 0000` | -| **Help** | `help` | -| **List contacts** | `listc` | -| **List meetings** | `listm` | -| **Remove contact from meeting** | `rmmc MEETING_INDEX ATTENDEE_INDEX`
e.g., `rmmc 2 2` | -| **View contact details** | `viewc INDEX`
e.g., `viewc 4` | -| **View meeting details** | `viewm INDEX`
e.g., `viewm 4` | -| **Exit** | `exit` | +| Action | Format, Examples | +|---------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| **Add contact** | `addc n/NAME p/PHONE_NUMBER e/EMAIL lc/LAST_CONTACTED_TIME [r/REMARK] [t/TAG]…​`
e.g., `add n/James Ho p/22224444 e/jamesho@example.com l/09.09.2023 0000 o/NUS t/friend t/colleague` | +| **Add contact to meeting** | `addmc MEETING_INDEX CONTACT_INDEX`
e.g., `addmc 2 1` | +| **Add meeting** | `addm m/TITLE a/LOCATION s/START e/END [t/TAG]…​`
e.g., `addm m/Lunch a/Cafeteria s/20.09.2023 1200 e/20.09.2023 1300` | +| **Clear** | `clear` | +| **Delete contact** | `deletec INDEX`
e.g., `deletec 3` | +| **Delete meeting** | `deletem INDEX`
e.g., `deletem 3` | +| **Edit contact** | `editc INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [lc/LAST_CONTACTED_TIME] [r/REMARK] [t/TAG]…​`
e.g.,`editc 2 n/James Lee e/jameslee@example.com` | +| **Edit meeting** | `editm INDEX [m/TITLE] [a/LOCATION] [s/START] [e/END] [t/TAG]…​`
e.g.,`editm 1 a/Hawker Centre s/15.09.2023 1500` | +| **Find contact** | `findc [n/KEYWORDS] [p/KEYWORDS] [e/KEYWORDS] [lc/LAST_CONTACTED_TIME] [s/KEYWORDS] [t/KEYWORDS]`
e.g., `findc n/James Jake s/active claimant` | +| **Find meeting** | `findm [m/KEYWORDS] [a/KEYWORDS] [t/KEYWORDS] [n/ATTENDEE_NAME] [s/START e/END]`
e.g., `findm m/Zoom Meet s/09.09.2023 0000 e/09.10.2023 0000` | +| **Help** | `help` | +| **List contacts** | `listc` | +| **List meetings** | `listm` | +| **Remove contact from meeting** | `rmmc MEETING_INDEX ATTENDEE_INDEX`
e.g., `rmmc 2 2` | +| **View contact details** | `viewc INDEX`
e.g., `viewc 4` | +| **View meeting details** | `viewm INDEX`
e.g., `viewm 4` | +| **Exit** | `exit` | From 75ee9508c7e28d733dacae37fa2d46a43a25fc1d Mon Sep 17 00:00:00 2001 From: Jason Date: Wed, 1 Nov 2023 14:14:38 +0800 Subject: [PATCH 10/18] Add UI elements for meeting status --- .../java/seedu/address/ui/MeetingCard.java | 7 +++++ .../resources/view/MeetingScheduleCard.fxml | 29 ++++++++++--------- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/main/java/seedu/address/ui/MeetingCard.java b/src/main/java/seedu/address/ui/MeetingCard.java index 50b1eb487fa..242de1f7d44 100644 --- a/src/main/java/seedu/address/ui/MeetingCard.java +++ b/src/main/java/seedu/address/ui/MeetingCard.java @@ -50,6 +50,8 @@ public class MeetingCard extends UiPart { private Label end; @FXML private FlowPane tags; + @FXML + private Label status; /** * Creates a {@code MeetingCode} with the given {@code Meeting} and index to display. @@ -71,5 +73,10 @@ public MeetingCard(Meeting meeting, int displayedIndex) { meeting.getTags().stream() .sorted(Comparator.comparing(tag -> tag.tagName)) .forEach(tag -> tags.getChildren().add(new Label(tag.tagName))); + if (meeting.getStatus().isComplete) { + status.setText("[COMPLETE]"); + } else { + status.setText(""); + } } } diff --git a/src/main/resources/view/MeetingScheduleCard.fxml b/src/main/resources/view/MeetingScheduleCard.fxml index 05516b4f736..1d18c636628 100644 --- a/src/main/resources/view/MeetingScheduleCard.fxml +++ b/src/main/resources/view/MeetingScheduleCard.fxml @@ -28,23 +28,26 @@
### Viewing help : `help` @@ -97,59 +97,54 @@ Adds a contact to OutBook. Format: `addc n/NAME p/PHONE_NUMBER e/EMAIL l/LAST_CONTACTED_TIME s/STATUS [r/REMARK][t/TAG]…​` ======= Format: `addc n/NAME p/PHONE_NUMBER e/EMAIL lc/LAST_CONTACTED_TIME [s/STATUS] [r/REMARK] [t/TAG]…​` ->>>>>>> master +> > > > > > > master + +- NAME, PHONE_NUMBER, EMAIL and LAST_CONTACTED_TIME are compulsory fields. STATUS, REMARK and TAG are optional. +- PHONE_NUMBER must contain only numbers, and be at least 3 digits long. +- EMAIL must be of the format local-part@domain and adhere to the following constraints: -* NAME, PHONE_NUMBER, EMAIL and LAST_CONTACTED_TIME are compulsory fields. STATUS, REMARK and TAG are optional. -* PHONE_NUMBER must contain only numbers, and be at least 3 digits long. -* EMAIL must be of the format local-part@domain and adhere to the following constraints: - 1. The local-part should only contain alphanumeric characters and these special characters, excluding the parentheses, (+_.-). + 1. The local-part should only contain alphanumeric characters and these special characters, excluding the parentheses, (+\_.-). 2. The local-part may not start or end with any special characters. 3. The domain name is made up of domain labels separated by periods. The domain name must: - - end with a domain label at least 2 characters long - - have each domain label start and end with alphanumeric characters - - have each domain label consist of alphanumeric characters, separated only by hyphen - -* LAST_CONTACTED_TIME must contain both date and time and adhere to the dd.MM.yyyy HHmm format. - - For instance, 1st October 2023, 10:00am will be written as 01.10.2023 1000. -* STATUS, if included, must be one of { NIL, Prospective, Active, Inactive, Claimant, Renewal } or blank. + - end with a domain label at least 2 characters long + - have each domain label start and end with alphanumeric characters + - have each domain label consist of alphanumeric characters, separated only by hyphen +- LAST_CONTACTED_TIME must contain both date and time and adhere to the dd.MM.yyyy HHmm format. + - For instance, 1st October 2023, 10:00am will be written as 01.10.2023 1000. +- STATUS, if included, must be one of { NIL, Prospective, Active, Inactive, Claimant, Renewal } or blank.
:bulb: **Tip:** You can put any number of tags (including 0) on a contact.
-* `addc n/John Doe p/98765432 e/johnd@example.com lc/01.10.2023 1000` -* `addc n/Betsy Crowe t/friend e/betsycrowe@example.com p/1234567 lc/01.01.2023 0100 t/Professor` +- `addc n/John Doe p/98765432 e/johnd@example.com lc/01.10.2023 1000` +- `addc n/Betsy Crowe t/friend e/betsycrowe@example.com p/1234567 lc/01.01.2023 0100 t/Professor`

### Listing all persons : `listc` -<<<<<<< HEAD -Shows you a list of all contacts in OutBook. -======= Shows a list of all contacts in OutBook. Contacts are sorted by LAST_CONTACTED_TIME by default. ->>>>>>> master Format: `listc` - ### Deleting a person : `deletec` Deletes a contact from OutBook. Format: `deletec INDEX` -* Deletes the contact at the specified `INDEX`. -* The index refers to the index number shown in the displayed person list. -* The index **must be a positive integer** 1, 2, 3, …​ +- Deletes the contact 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: -* `listc` followed by `delete 2` deletes the 2nd person in the results of the `listc` command. -* `findc Betsy` followed by `delete 1` deletes the 1st person in the results of the `findc` command. +- `listc` followed by `delete 2` deletes the 2nd person in the results of the `listc` command. +- `findc Betsy` followed by `delete 1` deletes the 1st person in the results of the `findc` command. ### Editing a contact : `editc` @@ -157,17 +152,17 @@ Edits an existing contact in OutBook. Format: `editc INDEX [n/NAME] [p/PHONE] [e/EMAIL] [lc/LAST_CONTACTED_TIME] [s/STATUS] [s/REMARK] [t/TAG]…​` -* Edits the contact 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, …​ -* All fields are optional, but at least one must be provided. -* Existing values will be updated to the input values. -* When editing tags, the existing tags of the person will be removed i.e adding of tags is not cumulative. -* You can remove all the person’s tags by typing `t/` without - specifying any tags after it. +- Edits the contact 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, …​ +- All fields are optional, but at least one must be provided. +- Existing values will be updated to the input values. +- When editing tags, the existing tags of the person will be removed i.e adding of tags is not cumulative. +- You can remove all the person’s tags by typing `t/` without + specifying any tags after it. Examples: -* `editc 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. -* `editc 2 n/Betsy Crower t/` Edits the name of the 2nd person to be `Betsy Crower` and clears all existing tags. +- `editc 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. +- `editc 2 n/Betsy Crower t/` Edits the name of the 2nd person to be `Betsy Crower` and clears all existing tags. ### Viewing detailed contact information : `viewc` @@ -175,15 +170,15 @@ Views detailed information of a contact in OutBook. Format: `viewc INDEX` -* Views detailed information of the contact 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, …​ -* Displays contact Name, Phone, Email, Last Contacted Time, Status, Remarks and Tags. -* The displayed contact is reset when the `deletec` and `findc` commands are used. +- Views detailed information of the contact 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, …​ +- Displays contact Name, Phone, Email, Last Contacted Time, Status, Remarks and Tags. +- The displayed contact is reset when the `deletec` and `findc` commands are used. Examples: -* `viewc 2` Displays detailed information related to the 2nd contact on the list. +- `viewc 2` Displays detailed information related to the 2nd contact on the list.
@@ -193,17 +188,17 @@ Edits an existing contact in OutBook. Format: `editc INDEX [n/NAME] [p/PHONE] [e/EMAIL] [l/LAST_CONTACTED_TIME] [s/STATUS] [r/REMARK] [t/TAG]…​` -* Edits the contact 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, …​ -* All fields are optional, but at least one must be provided. -* Existing values will be updated to the input values. -* When editing tags, the existing tags of the person will be removed i.e adding of tags is not cumulative. -* You can remove all the person’s tags by typing `t/` without - specifying any tags after it. +- Edits the contact 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, …​ +- All fields are optional, but at least one must be provided. +- Existing values will be updated to the input values. +- When editing tags, the existing tags of the person will be removed i.e adding of tags is not cumulative. +- You can remove all the person’s tags by typing `t/` without + specifying any tags after it. Examples: -* `editc 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. -* `editc 2 n/Betsy Crower t/` Edits the name of the 2nd person to be `Betsy Crower` and clears all existing tags. +- `editc 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. +- `editc 2 n/Betsy Crower t/` Edits the name of the 2nd person to be `Betsy Crower` and clears all existing tags. ### Remarking a contact : `remark` @@ -211,38 +206,40 @@ Adds a remark to a contact. Format: `remark INDEX r/REMARK` -* Adds a remark to the contact specified with `INDEX`. The index refers to the index number shown in the displayed person list. The index**must be a positive integer** 1, 2, 3, …​ -* Existing remark will be replaced with `REMARK`. -* You can remove an existing remark by typing `r/`. +- Adds a remark to the contact specified with `INDEX`. The index refers to the index number shown in the displayed person list. The index**must be a positive integer** 1, 2, 3, …​ +- Existing remark will be replaced with `REMARK`. +- You can remove an existing remark by typing `r/`. + +\*Examples: -*Examples: -* `remark 1 r/Owes me a favour` Replaces the previous remark for the 1st contact with "Owes me a favour". +- `remark 1 r/Owes me a favour` Replaces the previous remark for the 1st contact with "Owes me a favour".



### Search for persons using contact fields: `findc` + Find persons whose contact details match the keywords specified for at least 1 of these fields: name, phone, email, status, tag Format: `findc [n/KEYWORDS] [p/KEYWORDS] [e/KEYWORDS] [lc/DATETIME] [s/KEYWORDS] [t/KEYWORDS]` -* The search is case-insensitive. e.g `shop` will match `SHOP` -* The order of the keywords does not matter. e.g. `Shop Meet` will match `Meet Shop` -* For name, status and tags, only full words will be matched e.g. `Meet` will not match `Meeting` -* For email, any characters (alphanumeric, special characters) will be matched e.g. `_` will match `m_e@gmail.com` -* For phone, the entire length of the input digits will be matched e.g. `913` will match `90091300` but not `90103000` -* For last contacted time, the input must adhere to the dd.MM.yyyy HHmm format e.g. 9th October 2023 10.30am will be `09.10.2023 1030` -* For a single field, a Person must match at least one keyword to be returned as a result (i.e. `OR` search). +- The search is case-insensitive. e.g `shop` will match `SHOP` +- The order of the keywords does not matter. e.g. `Shop Meet` will match `Meet Shop` +- For name, status and tags, only full words will be matched e.g. `Meet` will not match `Meeting` +- For email, any characters (alphanumeric, special characters) will be matched e.g. `_` will match `m_e@gmail.com` +- For phone, the entire length of the input digits will be matched e.g. `913` will match `90091300` but not `90103000` +- For last contacted time, the input must adhere to the dd.MM.yyyy HHmm format e.g. 9th October 2023 10.30am will be `09.10.2023 1030` +- For a single field, a Person must match at least one keyword to be returned as a result (i.e. `OR` search). e.g. `John Doe` will return `John Lee`, `James Doe` -* If there are multiple fields specified, the Person must match at least one keyword in each field to be returned as a result (i.e. `AND` search). +- If there are multiple fields specified, the Person must match at least one keyword in each field to be returned as a result (i.e. `AND` search). e.g. `n/John Doe s/Active` will return `Name: John Lee, Status: Active` Examples: -* `findc n/alice` returns `Alice` and `alice tan` -* `findc p/51` returns `95163890` and `40351` -* `findc e/_@GMAIL` returns `alice_@gmail.com` -* `findc p/9 s/inactive claimant t/friend` returns persons with a `9` in their phone number, whose status is either `inactive` or `claimant`, and has a `friend` tag - ![result for 'findContact'](images/findContactResult.png) +- `findc n/alice` returns `Alice` and `alice tan` +- `findc p/51` returns `95163890` and `40351` +- `findc e/_@GMAIL` returns `alice_@gmail.com` +- `findc p/9 s/inactive claimant t/friend` returns persons with a `9` in their phone number, whose status is either `inactive` or `claimant`, and has a `friend` tag + ![result for 'findContact'](images/findContactResult.png)
@@ -255,12 +252,13 @@ Meetings are sorted by start time given. Format: `addm m/TITLE a/LOCATION s/START e/END [t/TAG]…​` -* START and END must contain both date and time and adhere to the dd.MM.yyyy HHmm format. - - For instance, 1st October 2023, 10:00am will be written as 01.10.2023 1000. +- START and END must contain both date and time and adhere to the dd.MM.yyyy HHmm format. + - For instance, 1st October 2023, 10:00am will be written as 01.10.2023 1000. Examples: -* `addm m/Lunch a/Cafeteria s/20.09.2023 1200 e/20.09.2023 1300` -* `addm m/CS2103T meeting a/Zoom call url s/20.09.2023 1000 e/20.09.2023 1200` + +- `addm m/Lunch a/Cafeteria s/20.09.2023 1200 e/20.09.2023 1300` +- `addm m/CS2103T meeting a/Zoom call url s/20.09.2023 1000 e/20.09.2023 1200` ### Listing all meetings : `listm` @@ -268,21 +266,20 @@ Shows a list of all meetings in OutBook. Meetings are sorted by START by default Format: `listm` - ### Deleting a meeting : `deletem` Deletes a meeting from OutBook. Format: `deletem INDEX` -* Deletes the meeting at the specified `INDEX`. -* The index refers to the index number shown in the displayed meeting list. -* The index **must be a positive integer** 1, 2, 3, …​ +- Deletes the meeting at the specified `INDEX`. +- The index refers to the index number shown in the displayed meeting list. +- The index **must be a positive integer** 1, 2, 3, …​ Examples: -* `listm` followed by `deletem 2` deletes the 2nd meeting in the results of the `listm` command. -* `findm m/Project` followed by `deletem 1` deletes the 1st meeting in the results of the `findm` command. +- `listm` followed by `deletem 2` deletes the 2nd meeting in the results of the `listm` command. +- `findm m/Project` followed by `deletem 1` deletes the 1st meeting in the results of the `findm` command. ### Editing a meeting : `editm` @@ -290,17 +287,17 @@ Edits an existing meeting in OutBook. Format: `editm INDEX [m/TITLE] [a/LOCATION] [s/START] [e/END] [t/TAG]…​` -* Edits the meeting at the specified `INDEX`. The index refers to the index number shown in the displayed meeting list. The index **must be a positive integer** 1, 2, 3, …​ -* At least one of the optional fields must be provided. -* Existing values will be updated to the input values. -* When editing tags, the existing tags of the meeting will be removed i.e adding of tags is not cumulative. -* You can remove all the meeting’s tags by typing `t/` without +- Edits the meeting at the specified `INDEX`. The index refers to the index number shown in the displayed meeting list. The index **must be a positive integer** 1, 2, 3, …​ +- At least one of the optional fields must be provided. +- Existing values will be updated to the input values. +- When editing tags, the existing tags of the meeting will be removed i.e adding of tags is not cumulative. +- You can remove all the meeting’s tags by typing `t/` without specifying any tags after it. Examples: -* `editm 1 a/Hawker Centre s/15.09.2023 1500` Edits the location and start of the 1st meeting to be `Hawker Centre` and `15.09.2023 1500` respectively. -* `editm 2 m/Zoom meeting t/` Edits the title of the 2nd meeting to be `Zoom meeting` and clears all existing tags. +- `editm 1 a/Hawker Centre s/15.09.2023 1500` Edits the location and start of the 1st meeting to be `Hawker Centre` and `15.09.2023 1500` respectively. +- `editm 2 m/Zoom meeting t/` Edits the title of the 2nd meeting to be `Zoom meeting` and clears all existing tags. ### Viewing detailed meeting information : `viewm` @@ -308,14 +305,15 @@ Views detailed information of a meeting in OutBook. Format: `viewm INDEX` -* Views detailed information of the meeting at the specified `INDEX`. -* The index refers to the index number shown in the displayed meeting list. -* The index **must be a positive integer** 1, 2, 3, …​ -* Displays meeting Title, Location, Start/End, Attendees and Tags. -* The displayed meeting is reset when the `deletem` and `findm` commands are used. +- Views detailed information of the meeting at the specified `INDEX`. +- The index refers to the index number shown in the displayed meeting list. +- The index **must be a positive integer** 1, 2, 3, …​ +- Displays meeting Title, Location, Start/End, Attendees and Tags. +- The displayed meeting is reset when the `deletem` and `findm` commands are used. Examples: -* `viewm 2` Displays detailed information related to the 2nd meeting on the list, including current attendees. + +- `viewm 2` Displays detailed information related to the 2nd meeting on the list, including current attendees.
@@ -325,21 +323,22 @@ Find meetings which details match the keywords you specified for at least 1 of t Format: `findm [m/KEYWORDS] [a/KEYWORDS] [t/KEYWORDS] [n/ATTENDEENAME] [s/START e/END]` -* The search is case-insensitive. e.g `shop` will match `SHOP` -* The order of the keywords does not matter. e.g. `Shop Meet` will match `Meet Shop` -* Title, location, tags and attendees are searched, within the time frame given by START and END -* Only full words will be matched e.g. `Meet` will not match `Meeting` -* For a single field, a Meeting must match at least one keyword will be returned (i.e. `OR` search). +- The search is case-insensitive. e.g `shop` will match `SHOP` +- The order of the keywords does not matter. e.g. `Shop Meet` will match `Meet Shop` +- Title, location, tags and attendees are searched, within the time frame given by START and END +- Only full words will be matched e.g. `Meet` will not match `Meeting` +- For a single field, a Meeting must match at least one keyword will be returned (i.e. `OR` search). e.g. `Shop Meet` will return `Meeting: Shop at mall`, `Meeting: Meet client` -* If there are multiple fields the meeting must match at least one keyword for each field to be returned (i.e. `AND` search). - e.g. `m/Shop Meet a/Mall` will return `Meeting: Shop at mall, Location:Mall` +- If there are multiple fields the meeting must match at least one keyword for each field to be returned (i.e. `AND` search). + e.g. `m/Shop Meet a/Mall` will return `Meeting: Shop at mall, Location:Mall` Examples: -* `findm m/project` returns `project` and `Project work` -* `findm m/zoom meeting` returns `Zoom session`, `Zoom meeting`, `Meeting advisor` -* `findm s/09.09.2023 0000 e/09.10.2023 0000` returns all meetings between 09.09.2023 0000 and 09.10.2023 0000
-* `findm m/Meeting s/09.09.2023 0000 e/09.10.2023 0000` returns `Zoom meeting`, `Meeting advisor`, if these meetings start after 09.09.2023 0000 and end before 09.10.2023 0000 - + +- `findm m/project` returns `project` and `Project work` +- `findm m/zoom meeting` returns `Zoom session`, `Zoom meeting`, `Meeting advisor` +- `findm s/09.09.2023 0000 e/09.10.2023 0000` returns all meetings between 09.09.2023 0000 and 09.10.2023 0000
+- `findm m/Meeting s/09.09.2023 0000 e/09.10.2023 0000` returns `Zoom meeting`, `Meeting advisor`, if these meetings start after 09.09.2023 0000 and end before 09.10.2023 0000 +
![result for 'findAlexMeeting'](images/findAlexMeetingResult.png) @@ -352,15 +351,16 @@ Adds a contact to a meeting as an attendee. Format: `addmc MEETING_INDEX CONTACT_INDEX` -* Adds the contact you specified with `CONTACT_INDEX` to a meeting specified with `MEETING_INDEX`. -* `MEETING_INDEX` refers to the index number shown in the displayed meeting list. -* `CONTACT_INDEX` refers to the index number shown in the displayed contact list. -* The indexes **must be positive integers** 1, 2, 3, …​ -* Both `MEETING_INDEX` & `CONTACT_INDEX` must refer to the index of an existing meeting and contact respectively. -* Contact name will be listed in the detailed description of meetings when `viewm` is used. +- Adds the contact you specified with `CONTACT_INDEX` to a meeting specified with `MEETING_INDEX`. +- `MEETING_INDEX` refers to the index number shown in the displayed meeting list. +- `CONTACT_INDEX` refers to the index number shown in the displayed contact list. +- The indexes **must be positive integers** 1, 2, 3, …​ +- Both `MEETING_INDEX` & `CONTACT_INDEX` must refer to the index of an existing meeting and contact respectively. +- Contact name will be listed in the detailed description of meetings when `viewm` is used. Examples: -* `addmc 3 1` adds the 1st contact as an attendee to the 3rd meeting in OutBook. + +- `addmc 3 1` adds the 1st contact as an attendee to the 3rd meeting in OutBook. ### Remove contact from meeting: `rmmc` @@ -368,16 +368,29 @@ Removes a contact from a meeting. Format: `rmmc MEETING_INDEX ATTENDEE_INDEX` -* Removes a contact at the specified `ATTENDEE_INDEX` to the meeting at the specified `MEETING_INDEX`. -* `MEETING_INDEX` refers to the index number shown in the displayed meeting list. -* `ATTENDEE_INDEX` refers to the index number of the attendee as shown in `viewm`. -* The indexes **must be positive integers** 1, 2, 3, …​ -* Both `MEETING_INDEX` & `ATTENDEE_INDEX` must refer to the index of an existing meeting or attendee. +- Removes a contact at the specified `ATTENDEE_INDEX` to the meeting at the specified `MEETING_INDEX`. +- `MEETING_INDEX` refers to the index number shown in the displayed meeting list. +- `ATTENDEE_INDEX` refers to the index number of the attendee as shown in `viewm`. +- The indexes **must be positive integers** 1, 2, 3, …​ +- Both `MEETING_INDEX` & `ATTENDEE_INDEX` must refer to the index of an existing meeting or attendee. Examples: -* `rmmc 3 2` removes the 2nd attendee from the 3rd meeting in OutBook. -



+- `rmmc 3 2` removes the 2nd attendee from the 3rd meeting in OutBook. + +### Marking a meeting as complete : `mark` + +Marks a meeting in OutBook as complete. All attendees of the meeting will have their LC (last contacted) field updated to the end time of the meeting. + +Format: `mark INDEX` + +- Marks the meeting at the specified `INDEX` as complete. +- The index refers to the index number shown in the displayed meeting list. +- The index **must be a positive integer** 1, 2, 3, …​ + +Examples: + +- `listm` followed by `mark 2` marks the 2nd meeting in the results of the `listm` command. ### Clearing all entries : `clear` @@ -403,8 +416,8 @@ OutBook data are saved automatically as a JSON file `[JAR file location]/data/ou If your changes to the data file makes its format invalid, OutBook will discard all data and start with an empty data file at the next run. Hence, it is recommended to take a backup of the file before editing it. +--- ---------------------------------------------------------------------------------------------------------------------
## FAQ @@ -412,27 +425,28 @@ If your changes to the data file makes its format invalid, OutBook will discard **Q**: How do I transfer my data to another Computer?
**A**: Install the app in the other computer and overwrite the empty data file it creates with the file that contains the data of your previous OutBook home folder. --------------------------------------------------------------------------------------------------------------------- +--- ## Known issues 1. **When using multiple screens**, if you move the application to a secondary screen, and later switch to using only the primary screen, the GUI will open off-screen. The remedy is to delete the `preferences.json` file created by the application before running the application again. --------------------------------------------------------------------------------------------------------------------- +--- +
## Command summary | Action | Format, Examples | -|---------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| **Add contact** | `addc n/NAME p/PHONE_NUMBER e/EMAIL l/LAST_CONTACTED_TIME o/ORGANISATION [r/REMARK] [t/TAG]…​`
e.g., `add n/James Ho p/22224444 e/jamesho@example.com l/09.09.2023 0000 o/NUS t/friend t/colleague` | +| ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Add contact** | `addc n/NAME p/PHONE_NUMBER e/EMAIL l/LAST_CONTACTED_TIME o/ORGANISATION [r/REMARK] [t/TAG]…​`
e.g., `add n/James Ho p/22224444 e/jamesho@example.com l/09.09.2023 0000 o/NUS t/friend t/colleague` | | **Add contact to meeting** | `addmc MEETING_INDEX CONTACT_INDEX`
e.g., `addmc 2 1` | -| **Add meeting** | `addm m/TITLE a/LOCATION s/START e/END [t/TAG]…​`
e.g., `addm m/Lunch a/Cafeteria s/20.09.2023 1200 e/20.09.2023 1300` | +| **Add meeting** | `addm m/TITLE a/LOCATION s/START e/END [t/TAG]…​`
e.g., `addm m/Lunch a/Cafeteria s/20.09.2023 1200 e/20.09.2023 1300` | | **Clear** | `clear` | | **Delete contact** | `deletec INDEX`
e.g., `deletec 3` | | **Delete meeting** | `deletem INDEX`
e.g., `deletem 3` | -| **Edit contact** | `editc INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [l/LAST_CONTACTED_TIME] [o/ORGANISATION] [r/REMARK] [t/TAG]…​`
e.g.,`editc 2 n/James Lee e/jameslee@example.com` | -| **Edit meeting** | `editm INDEX [m/TITLE] [a/LOCATION] [s/START] [e/END] [t/TAG]…​`
e.g.,`editm 1 a/Hawker Centre s/15.09.2023 1500` | +| **Edit contact** | `editc INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [l/LAST_CONTACTED_TIME] [o/ORGANISATION] [r/REMARK] [t/TAG]…​`
e.g.,`editc 2 n/James Lee e/jameslee@example.com` | +| **Edit meeting** | `editm INDEX [m/TITLE] [a/LOCATION] [s/START] [e/END] [t/TAG]…​`
e.g.,`editm 1 a/Hawker Centre s/15.09.2023 1500` | | **Find contact** | `findc KEYWORD [MORE_KEYWORDS]`
e.g., `findc James Jake` | | **Find meeting** | `findm [m/KEYWORDS] [a/KEYWORDS] [t/KEYWORDS] [n/ATTENDEENAME] [s/START e/END]`
e.g., `findm m/Zoom Meet s/09.09.2023 0000 e/09.10.2023 0000` | | **Help** | `help` | @@ -441,4 +455,5 @@ If your changes to the data file makes its format invalid, OutBook will discard | **Remove contact from meeting** | `rmmc MEETING_INDEX ATTENDEE_INDEX`
e.g., `rmmc 2 2` | | **View contact details** | `viewc INDEX`
e.g., `viewc 4` | | **View meeting details** | `viewm INDEX`
e.g., `viewm 4` | +| **Mark meeting as complete** | `mark INDEX`
e.g., `mark 4` | | **Exit** | `exit` | diff --git a/docs/team/jason-raiin.md b/docs/team/jason-raiin.md index 6040360fbf8..d8bc9e85c86 100644 --- a/docs/team/jason-raiin.md +++ b/docs/team/jason-raiin.md @@ -12,36 +12,40 @@ My contributions to the project are listed below. - **New Feature**: Remove contact from meeting command - Added command and parser - - Thorough testing +- **New Feature**: Mark meeting command + - Added command and parser + - Updates last contacted time for contacts - **Code contributed**: [RepoSense link](https://nus-cs2103-ay2324s1.github.io/tp-dashboard/?search=jason-raiin&breakdown=true) - **Project management**: - - - to be added soon + - Contributed issues + - Reviewed PRs - **Enhancements to existing features**: - - - Add Tag to meetings: logic and UI + - Add Tags field to meetings - Convert Tag to factory class with no duplicates + - Added Status field to meetings - **Documentation**: - User Guide - - Remove meeting contact command + - `rmmc` command + - `mark` command - Minor edits - Developer Guide + - `rmmc` command + - `mark` command - User profile - Value proposition - User stories - Use cases - **Community**: - - to be added soon - **Tools**: - - Added util method `parseIndexes` + - Improved methods for `typicalMeetings` and `typicalAddressBook` diff --git a/src/test/java/seedu/address/logic/commands/FindMeetingCommandTest.java b/src/test/java/seedu/address/logic/commands/FindMeetingCommandTest.java index 8e430adb514..30ab630b947 100644 --- a/src/test/java/seedu/address/logic/commands/FindMeetingCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/FindMeetingCommandTest.java @@ -36,8 +36,8 @@ public class FindMeetingCommandTest { private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); private Model expectedModel = new ModelManager(getTypicalAddressBook(), new UserPrefs()); private LocalDateTime start = LocalDateTime.of(LocalDate.of(0001, 01, 01), LocalTime.of(00, 00)); - private LocalDateTime startOn30 = LocalDateTime.of(LocalDate.of(2023, 9, 30), LocalTime.of(10, 00)); - private LocalDateTime endOn30 = LocalDateTime.of(LocalDate.of(2023, 9, 30), LocalTime.of(12, 00)); + private LocalDateTime startOn30 = LocalDateTime.of(LocalDate.of(2023, 11, 30), LocalTime.of(10, 00)); + private LocalDateTime endOn30 = LocalDateTime.of(LocalDate.of(2023, 11, 30), LocalTime.of(12, 00)); private LocalDateTime start2 = LocalDateTime.of(LocalDate.of(0001, 01, 02), LocalTime.of(00, 00)); private LocalDateTime end = LocalDateTime.of(LocalDate.of(9999, 12, 31), LocalTime.of(23, 59)); @Test @@ -188,7 +188,7 @@ public void execute_multipleTitleMultipleLocationMultipleAttendeeMultipleTagKeyw public void execute_titleLocationAttendeeTagTimeKeywords_oneMeetingFound() { String expectedMessage = String.format(MESSAGE_MEETINGS_LISTED_OVERVIEW, 1); GeneralMeetingPredicate predicate = - preparePredicate(new String[]{"ABCDE CS2101", "Zoom com", "Alice Benson", "work important"}, + preparePredicate(new String[]{"ABCDE CS2101", "Zoom com", "", "work important"}, startOn30, endOn30); FindMeetingCommand command = new FindMeetingCommand(predicate); expectedModel.updateFilteredMeetingList(predicate); diff --git a/src/test/java/seedu/address/logic/commands/ViewMeetingCommandTest.java b/src/test/java/seedu/address/logic/commands/ViewMeetingCommandTest.java index 29297c61b75..95fc605c829 100644 --- a/src/test/java/seedu/address/logic/commands/ViewMeetingCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/ViewMeetingCommandTest.java @@ -34,8 +34,8 @@ public void execute_validIndexUnfilteredList_success() { String expectedMessage = String.format(Messages.MESSAGE_MEETING_VIEWED_OVERVIEW, meetingToView.getTitle()); String expectedDisplayString = "Title: CS2101 meeting\n" + "Location: Zoom call url\n" - + "Start: 20 September 2023, 1000\n" - + "End: 20 September 2023, 1200\n" + + "Start: 20 November 2023, 1000\n" + + "End: 20 November 2023, 1200\n" + "Attendees: [\n1: Daniel Meier \n2: Elle Meyer " + "\n3: Fiona Kunz \n4: George Best]\n"; From cdbc32aeb2c73c55481ccd5aee14b546b0079f87 Mon Sep 17 00:00:00 2001 From: Jason Date: Thu, 2 Nov 2023 16:55:54 +0800 Subject: [PATCH 17/18] Fix checkstyles --- docs/DeveloperGuide.md | 20 +++++++++---------- docs/team/jason-raiin.md | 8 ++++---- docs/team/lomaply.md | 2 +- .../java/seedu/address/model/AddressBook.java | 2 +- .../model/person/UniquePersonList.java | 2 +- .../address/storage/JsonAdaptedMeeting.java | 2 +- .../AddMeetingContactCommandTest.java | 2 +- .../logic/commands/DeleteCommandTest.java | 2 +- .../commands/DeleteMeetingCommandTest.java | 2 +- .../logic/commands/EditCommandTest.java | 2 +- .../commands/EditMeetingCommandTest.java | 2 +- .../logic/commands/FindCommandTest.java | 2 +- .../logic/commands/ListCommandTest.java | 2 +- .../commands/ListMeetingCommandTest.java | 2 +- .../commands/MarkMeetingCommandTest.java | 3 +-- .../RemoveMeetingContactCommandTest.java | 2 +- .../commands/ViewContactCommandTest.java | 2 +- .../commands/ViewMeetingCommandTest.java | 4 ++-- .../seedu/address/model/AddressBookTest.java | 2 +- .../seedu/address/model/ModelManagerTest.java | 2 +- .../address/model/meeting/StatusTest.java | 1 - .../model/person/UniquePersonListTest.java | 2 +- .../storage/JsonAdaptedMeetingTest.java | 2 +- .../address/testutil/TypicalAddressBook.java | 4 ++++ 24 files changed, 39 insertions(+), 37 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 4cd87f917f5..ce456a40992 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -344,31 +344,31 @@ _{more aspects and alternatives to be added}_ ### Keeping track of last meeting with contact -Keeping track of the user's last meeting with their contact is facilitated by the addition of a `LastContactedTime` object to `Person`. -Thus, each instance of `Person` will contain an immutable `LastContactedTime` object that stores the user's last meeting with that contact. +Keeping track of the user's last meeting with their contact is facilitated by the addition of a `LastContactedTime` object to `Person`. +Thus, each instance of `Person` will contain an immutable `LastContactedTime` object that stores the user's last meeting with that contact. The following steps shows how `LastContactedTime` is implemented and utilized in the application. Step 1. The user inputs the `addc` command into the `CommandBox` input field, with the added field `l/[LAST_CONTACTED_TIME]`. -The following diagram summarizes steps 2 to 6: +The following diagram summarizes steps 2 to 6: -Step 2. Entering a correct command with the `Enter` key then calls `execute` on `LogicManager`. -Step 3. `LogicManager` then calls `AddressBookParser#parseCommand(commandText)` on the `commandText` String, which recognizes that it is an `addc` command. -Step 4. `AddressBookParser` then calls `AddCommandParser#parse()` on the command arguments. -Step 5. `AddCommandParser` then calls `ParserUtil#parseContactTime()` which parses the last contacted time and returns a `LocalDateTime` object called `lastContactedTime`. +Step 2. Entering a correct command with the `Enter` key then calls `execute` on `LogicManager`. +Step 3. `LogicManager` then calls `AddressBookParser#parseCommand(commandText)` on the `commandText` String, which recognizes that it is an `addc` command. +Step 4. `AddressBookParser` then calls `AddCommandParser#parse()` on the command arguments. +Step 5. `AddCommandParser` then calls `ParserUtil#parseContactTime()` which parses the last contacted time and returns a `LocalDateTime` object called `lastContactedTime`. Step 6. The `lastContactedTime` object is then passed to the `Person` constructor, which creates a new `Person` that calls the `LastContactedTime` constructor with it. The following diagram summarizes steps 7 and 8: -Step 7. The completed `Person` is passed to an `AddCommand` constructor which return a new `AddCommand` that can be executed. -Step 8. `LogicManager` then executes the `AddCommand` on the application model. +Step 7. The completed `Person` is passed to an `AddCommand` constructor which return a new `AddCommand` that can be executed. +Step 8. `LogicManager` then executes the `AddCommand` on the application model. Step 9. Futher execution is carried out, which like before adds the `Person` object to the list of `Person`s in the `Model`, and updates the `Storage` with this new `Person`. #### Design Consideration: Updating last meeting with contact -Solution: +Solution: This is facilitated by the addition of the `MarkDoneCommand`. When a meeting is marked as done, the attendees of the meeting will be updated with their LastContactedTime field updated to the end time of the meeting. --- diff --git a/docs/team/jason-raiin.md b/docs/team/jason-raiin.md index d8bc9e85c86..d1df38938a7 100644 --- a/docs/team/jason-raiin.md +++ b/docs/team/jason-raiin.md @@ -14,13 +14,13 @@ My contributions to the project are listed below. - Added command and parser - **New Feature**: Mark meeting command - - Added command and parser - - Updates last contacted time for contacts + - Added command and parser + - Updates last contacted time for contacts - **Code contributed**: [RepoSense link](https://nus-cs2103-ay2324s1.github.io/tp-dashboard/?search=jason-raiin&breakdown=true) - **Project management**: - - Contributed issues + - Contributed issues - Reviewed PRs - **Enhancements to existing features**: @@ -48,4 +48,4 @@ My contributions to the project are listed below. - **Tools**: - Added util method `parseIndexes` - - Improved methods for `typicalMeetings` and `typicalAddressBook` + - Improved methods for `typicalMeetings` and `typicalAddressBook` diff --git a/docs/team/lomaply.md b/docs/team/lomaply.md index 4b2c3aeba4f..694c0c44381 100644 --- a/docs/team/lomaply.md +++ b/docs/team/lomaply.md @@ -26,7 +26,7 @@ My contributions to the project are listed below. - Review and merge pull requests - **Enhancements to existing features**: - + - Sort contacts by last contacted time - New Command - "editm" diff --git a/src/main/java/seedu/address/model/AddressBook.java b/src/main/java/seedu/address/model/AddressBook.java index a0a8f8a4cb1..e0386d24421 100644 --- a/src/main/java/seedu/address/model/AddressBook.java +++ b/src/main/java/seedu/address/model/AddressBook.java @@ -110,7 +110,7 @@ public void addMeeting(Meeting m) { } /** - * Returns the person with the given name + * Returns the person with the given name * or throws {@code IndexOutOfBoundsException} if it does not exist. */ public Person getPerson(String name) { diff --git a/src/main/java/seedu/address/model/person/UniquePersonList.java b/src/main/java/seedu/address/model/person/UniquePersonList.java index 27888ef326a..22536919254 100644 --- a/src/main/java/seedu/address/model/person/UniquePersonList.java +++ b/src/main/java/seedu/address/model/person/UniquePersonList.java @@ -67,7 +67,7 @@ public void add(Person toAdd) { } /** - * Returns the person with the given name + * Returns the person with the given name * or throws {@code IndexOutOfBoundsException} if it does not exist. */ public Person getPerson(String fullName) { diff --git a/src/main/java/seedu/address/storage/JsonAdaptedMeeting.java b/src/main/java/seedu/address/storage/JsonAdaptedMeeting.java index 030f7d17ddc..a9b8f4bfb24 100644 --- a/src/main/java/seedu/address/storage/JsonAdaptedMeeting.java +++ b/src/main/java/seedu/address/storage/JsonAdaptedMeeting.java @@ -15,8 +15,8 @@ import seedu.address.model.meeting.Attendee; import seedu.address.model.meeting.Location; import seedu.address.model.meeting.Meeting; -import seedu.address.model.meeting.MeetingTime; import seedu.address.model.meeting.MeetingStatus; +import seedu.address.model.meeting.MeetingTime; import seedu.address.model.meeting.Title; import seedu.address.model.tag.Tag; diff --git a/src/test/java/seedu/address/logic/commands/AddMeetingContactCommandTest.java b/src/test/java/seedu/address/logic/commands/AddMeetingContactCommandTest.java index 2ebef293940..154e1968d33 100644 --- a/src/test/java/seedu/address/logic/commands/AddMeetingContactCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/AddMeetingContactCommandTest.java @@ -5,12 +5,12 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook; import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_MEETING; import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON; import static seedu.address.testutil.TypicalIndexes.INDEX_OUT_OF_BOUNDS; import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_MEETING; import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_PERSON; -import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook; import org.junit.jupiter.api.Test; diff --git a/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java b/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java index 9bfafe4d562..9972e6d344b 100644 --- a/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java @@ -6,9 +6,9 @@ import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure; import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; import static seedu.address.logic.commands.CommandTestUtil.showPersonAtIndex; +import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook; import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON; import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_PERSON; -import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook; import org.junit.jupiter.api.Test; diff --git a/src/test/java/seedu/address/logic/commands/DeleteMeetingCommandTest.java b/src/test/java/seedu/address/logic/commands/DeleteMeetingCommandTest.java index 3cfe47dbc38..48753377d0d 100644 --- a/src/test/java/seedu/address/logic/commands/DeleteMeetingCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/DeleteMeetingCommandTest.java @@ -6,9 +6,9 @@ import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure; import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; import static seedu.address.logic.commands.CommandTestUtil.showMeetingAtIndex; +import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook; import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_MEETING; import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_MEETING; -import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook; import org.junit.jupiter.api.Test; diff --git a/src/test/java/seedu/address/logic/commands/EditCommandTest.java b/src/test/java/seedu/address/logic/commands/EditCommandTest.java index bbed119c88f..a241e51b30f 100644 --- a/src/test/java/seedu/address/logic/commands/EditCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/EditCommandTest.java @@ -11,9 +11,9 @@ import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure; import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; import static seedu.address.logic.commands.CommandTestUtil.showPersonAtIndex; +import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook; import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON; import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_PERSON; -import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook; import org.junit.jupiter.api.Test; diff --git a/src/test/java/seedu/address/logic/commands/EditMeetingCommandTest.java b/src/test/java/seedu/address/logic/commands/EditMeetingCommandTest.java index 5190988429b..4d78b94bace 100644 --- a/src/test/java/seedu/address/logic/commands/EditMeetingCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/EditMeetingCommandTest.java @@ -12,9 +12,9 @@ import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure; import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; import static seedu.address.logic.commands.CommandTestUtil.showMeetingAtIndex; +import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook; import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_MEETING; import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_MEETING; -import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook; import org.junit.jupiter.api.Test; diff --git a/src/test/java/seedu/address/logic/commands/FindCommandTest.java b/src/test/java/seedu/address/logic/commands/FindCommandTest.java index 970e90a54aa..94885d928d9 100644 --- a/src/test/java/seedu/address/logic/commands/FindCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/FindCommandTest.java @@ -6,6 +6,7 @@ import static seedu.address.logic.Messages.MESSAGE_PERSONS_LISTED_OVERVIEW; import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; import static seedu.address.logic.parser.ParserUtil.FORMAT; +import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook; import static seedu.address.testutil.TypicalPersons.ALICE; import static seedu.address.testutil.TypicalPersons.BENSON; import static seedu.address.testutil.TypicalPersons.CARL; @@ -14,7 +15,6 @@ import static seedu.address.testutil.TypicalPersons.FIONA; import static seedu.address.testutil.TypicalPersons.GEORGE; import static seedu.address.testutil.TypicalPersons.HOON; -import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook; import java.time.LocalDate; import java.time.LocalDateTime; diff --git a/src/test/java/seedu/address/logic/commands/ListCommandTest.java b/src/test/java/seedu/address/logic/commands/ListCommandTest.java index 409e1291836..12d9e84b7fb 100644 --- a/src/test/java/seedu/address/logic/commands/ListCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/ListCommandTest.java @@ -2,8 +2,8 @@ import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; import static seedu.address.logic.commands.CommandTestUtil.showPersonAtIndex; -import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON; import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook; +import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/src/test/java/seedu/address/logic/commands/ListMeetingCommandTest.java b/src/test/java/seedu/address/logic/commands/ListMeetingCommandTest.java index 3e0dd67f041..8e70beea92e 100644 --- a/src/test/java/seedu/address/logic/commands/ListMeetingCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/ListMeetingCommandTest.java @@ -2,8 +2,8 @@ import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; import static seedu.address.logic.commands.CommandTestUtil.showMeetingAtIndex; -import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON; import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook; +import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/src/test/java/seedu/address/logic/commands/MarkMeetingCommandTest.java b/src/test/java/seedu/address/logic/commands/MarkMeetingCommandTest.java index 27e3115a821..2a8e3fd5465 100644 --- a/src/test/java/seedu/address/logic/commands/MarkMeetingCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/MarkMeetingCommandTest.java @@ -10,13 +10,12 @@ import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook; import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_MEETING; import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON; +import static seedu.address.testutil.TypicalIndexes.INDEX_OUT_OF_BOUNDS; import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_MEETING; import java.time.LocalDateTime; import java.util.Iterator; -import static seedu.address.testutil.TypicalIndexes.INDEX_OUT_OF_BOUNDS; - import org.junit.jupiter.api.Test; import seedu.address.commons.core.index.Index; diff --git a/src/test/java/seedu/address/logic/commands/RemoveMeetingContactCommandTest.java b/src/test/java/seedu/address/logic/commands/RemoveMeetingContactCommandTest.java index 1b391589067..6ec89228801 100644 --- a/src/test/java/seedu/address/logic/commands/RemoveMeetingContactCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/RemoveMeetingContactCommandTest.java @@ -5,12 +5,12 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook; import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_MEETING; import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON; import static seedu.address.testutil.TypicalIndexes.INDEX_OUT_OF_BOUNDS; import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_MEETING; import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_PERSON; -import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook; import java.util.Arrays; diff --git a/src/test/java/seedu/address/logic/commands/ViewContactCommandTest.java b/src/test/java/seedu/address/logic/commands/ViewContactCommandTest.java index e8c3eb9cc9a..c0fb5c2c5ae 100644 --- a/src/test/java/seedu/address/logic/commands/ViewContactCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/ViewContactCommandTest.java @@ -6,9 +6,9 @@ import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure; import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; import static seedu.address.logic.commands.CommandTestUtil.showPersonAtIndex; +import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook; import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON; import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_PERSON; -import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook; import org.junit.jupiter.api.Test; diff --git a/src/test/java/seedu/address/logic/commands/ViewMeetingCommandTest.java b/src/test/java/seedu/address/logic/commands/ViewMeetingCommandTest.java index 95fc605c829..ac305f4c127 100644 --- a/src/test/java/seedu/address/logic/commands/ViewMeetingCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/ViewMeetingCommandTest.java @@ -6,9 +6,9 @@ import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure; import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; import static seedu.address.logic.commands.CommandTestUtil.showMeetingAtIndex; +import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook; import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_MEETING; import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_MEETING; -import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook; import org.junit.jupiter.api.Test; @@ -36,7 +36,7 @@ public void execute_validIndexUnfilteredList_success() { + "Location: Zoom call url\n" + "Start: 20 November 2023, 1000\n" + "End: 20 November 2023, 1200\n" - + "Attendees: [\n1: Daniel Meier \n2: Elle Meyer " + + "Attendees: [\n1: Daniel Meier \n2: Elle Meyer " + "\n3: Fiona Kunz \n4: George Best]\n"; ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); diff --git a/src/test/java/seedu/address/model/AddressBookTest.java b/src/test/java/seedu/address/model/AddressBookTest.java index f883c7d30a4..85f3cf950b3 100644 --- a/src/test/java/seedu/address/model/AddressBookTest.java +++ b/src/test/java/seedu/address/model/AddressBookTest.java @@ -5,8 +5,8 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND; import static seedu.address.testutil.Assert.assertThrows; -import static seedu.address.testutil.TypicalPersons.ALICE; import static seedu.address.testutil.TypicalAddressBook.getTypicalAddressBook; +import static seedu.address.testutil.TypicalPersons.ALICE; import java.util.Arrays; import java.util.Collection; diff --git a/src/test/java/seedu/address/model/ModelManagerTest.java b/src/test/java/seedu/address/model/ModelManagerTest.java index bed2c32174a..66b41f5e5de 100644 --- a/src/test/java/seedu/address/model/ModelManagerTest.java +++ b/src/test/java/seedu/address/model/ModelManagerTest.java @@ -88,7 +88,7 @@ public void hasPerson_personInAddressBook_returnsTrue() { modelManager.addPerson(ALICE); assertTrue(modelManager.hasPerson(ALICE)); } - + @Test public void getPerson_isInList_success() { modelManager.addPerson(ALICE); diff --git a/src/test/java/seedu/address/model/meeting/StatusTest.java b/src/test/java/seedu/address/model/meeting/StatusTest.java index 477f230b91a..8ac6743a95a 100644 --- a/src/test/java/seedu/address/model/meeting/StatusTest.java +++ b/src/test/java/seedu/address/model/meeting/StatusTest.java @@ -33,5 +33,4 @@ public void equals() { // different values -> returns false assertFalse(status.equals(new MeetingStatus(true))); } - } diff --git a/src/test/java/seedu/address/model/person/UniquePersonListTest.java b/src/test/java/seedu/address/model/person/UniquePersonListTest.java index ef6c30d644e..777ea1265e4 100644 --- a/src/test/java/seedu/address/model/person/UniquePersonListTest.java +++ b/src/test/java/seedu/address/model/person/UniquePersonListTest.java @@ -61,7 +61,7 @@ public void add_duplicatePerson_throwsDuplicatePersonException() { uniquePersonList.add(ALICE); assertThrows(DuplicatePersonException.class, () -> uniquePersonList.add(ALICE)); } - + @Test public void getPerson_isInList_success() { uniquePersonList.add(ALICE); diff --git a/src/test/java/seedu/address/storage/JsonAdaptedMeetingTest.java b/src/test/java/seedu/address/storage/JsonAdaptedMeetingTest.java index d22bbc0c609..e5106d817d9 100644 --- a/src/test/java/seedu/address/storage/JsonAdaptedMeetingTest.java +++ b/src/test/java/seedu/address/storage/JsonAdaptedMeetingTest.java @@ -27,7 +27,7 @@ public class JsonAdaptedMeetingTest { private static final String INVALID_ATTENDEE = " "; private static final String INVALID_TAG = "#friend"; private static final String INVALID_STATUS = "untrue"; - + private static final String VALID_TITLE = MEETING1.getTitle().toString(); private static final String VALID_LOCATION = MEETING1.getLocation().toString(); private static final String VALID_START = MEETING1.getStart().toString(); diff --git a/src/test/java/seedu/address/testutil/TypicalAddressBook.java b/src/test/java/seedu/address/testutil/TypicalAddressBook.java index 0476eb553b3..7d9f3466915 100644 --- a/src/test/java/seedu/address/testutil/TypicalAddressBook.java +++ b/src/test/java/seedu/address/testutil/TypicalAddressBook.java @@ -4,6 +4,10 @@ import seedu.address.model.meeting.Meeting; import seedu.address.model.person.Person; +/** + * A utility class containing a list of {@code AddressBook} objects to be used in + * tests. + */ public class TypicalAddressBook { private TypicalAddressBook() { } // prevents instantiation From d13925a70e90ce272b367a65a8b76ffa0e59fd10 Mon Sep 17 00:00:00 2001 From: Jason Date: Thu, 2 Nov 2023 20:38:39 +0800 Subject: [PATCH 18/18] Fix merge errors --- docs/UserGuide.md | 8 ++++---- .../seedu/address/logic/commands/FindMeetingCommand.java | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 07522233517..0868f42a758 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -37,7 +37,7 @@ It is able to add, edit and delete any contacts and meetings you want. As well a - `listc` : Lists all contacts. - - `addc n/John Doe p/98765432 e/johnd@example.com l/10.10.2023 1000 o/NUS` : Adds a contact named `John Doe` to OutBook. + - `addc n/John Doe p/98765432 e/johnd@example.com lc/10.10.2023 1000 o/NUS` : Adds a contact named `John Doe` to OutBook. - `deletec 3` : Deletes the 3rd contact shown in the contact list. @@ -145,7 +145,7 @@ Examples: Edits an existing contact in OutBook. -Format: `editc INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [l/LAST_CONTACTED_TIME] [s/STATUS] [r/REMARK] [t/TAG]…​` +Format: `editc INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [lc/LAST_CONTACTED_TIME] [s/STATUS] [r/REMARK] [t/TAG]…​` - Edits the contact 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, …​ - All fields are optional, but at least one must be provided. @@ -178,7 +178,7 @@ Format: `viewc INDEX` * The displayed contact may change when `editc` is used in a way that modifies the order of the displayed person list, such as by editing the `LAST_CONTACTED_DATE`. This is intentional as the `editc` command is meant to display information based on the contact list index. Examples: - +* `viewc 2` Displays detailed information related to the 2nd contact on the list.



@@ -408,7 +408,7 @@ If your changes to the data file makes its format invalid, OutBook will discard | Action | Format, Examples | |---------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| **Add contact** | `addc n/NAME p/PHONE_NUMBER e/EMAIL lc/LAST_CONTACTED_TIME [r/REMARK] [t/TAG]…​`
e.g., `add n/James Ho p/22224444 e/jamesho@example.com l/09.09.2023 0000 o/NUS t/friend t/colleague` | +| **Add contact** | `addc n/NAME p/PHONE_NUMBER e/EMAIL lc/LAST_CONTACTED_TIME [r/REMARK] [t/TAG]…​`
e.g., `add n/James Ho p/22224444 e/jamesho@example.com lc/09.09.2023 0000 o/NUS t/friend t/colleague` | | **Add contact to meeting** | `addmc MEETING_INDEX CONTACT_INDEX`
e.g., `addmc 2 1` | | **Add meeting** | `addm m/TITLE a/LOCATION s/START e/END [t/TAG]…​`
e.g., `addm m/Lunch a/Cafeteria s/20.09.2023 1200 e/20.09.2023 1300` | | **Clear** | `clear` | diff --git a/src/main/java/seedu/address/logic/commands/FindMeetingCommand.java b/src/main/java/seedu/address/logic/commands/FindMeetingCommand.java index a7f06bef8d1..ae87b33ca79 100644 --- a/src/main/java/seedu/address/logic/commands/FindMeetingCommand.java +++ b/src/main/java/seedu/address/logic/commands/FindMeetingCommand.java @@ -34,7 +34,7 @@ public class FindMeetingCommand extends Command { * @param predicate The predicate that will be used by the FindMeetingCommand object. */ public FindMeetingCommand(GeneralMeetingPredicate predicate) { - assert predicate != null; + requireNonNull(predicate); this.predicate = predicate; }