From 587b72db6c02038bc4b08151f01833614728d533 Mon Sep 17 00:00:00 2001 From: Han Bin Date: Wed, 23 Oct 2024 16:25:15 +0800 Subject: [PATCH 01/10] Add Force functionality for Tags and Weddings Add Force functionality to Deleting and Assigning Tags --- .../java/seedu/address/logic/Messages.java | 6 +++ .../logic/commands/AssignWeddingCommand.java | 1 + .../logic/commands/DeleteTagCommand.java | 45 ++++++++++++++++++- .../logic/commands/DeleteWeddingCommand.java | 44 +++++++++++++++++- .../address/logic/commands/TagCommand.java | 25 ++++++++++- .../logic/parser/DeleteTagCommandParser.java | 9 +++- .../parser/DeleteWeddingCommandParser.java | 9 +++- .../logic/parser/TagCommandParser.java | 10 ++++- .../java/seedu/address/model/AddressBook.java | 3 ++ .../java/seedu/address/model/tag/Tag.java | 3 ++ .../address/storage/JsonAdaptedPerson.java | 3 +- 11 files changed, 145 insertions(+), 13 deletions(-) diff --git a/src/main/java/seedu/address/logic/Messages.java b/src/main/java/seedu/address/logic/Messages.java index 6d4eb530dd4..045f23b3fdb 100644 --- a/src/main/java/seedu/address/logic/Messages.java +++ b/src/main/java/seedu/address/logic/Messages.java @@ -32,6 +32,12 @@ public class Messages { + "the person's wedding list."; public static final String MESSAGE_FORCE_ASSIGN_WEDDING_TO_CONTACT = "Use f/ to force the assignment of wedding(s)." + " This will create the required Wedding objects."; + public static final String MESSAGE_FORCE_DELETE_WEDDING = "Use f/ to force the deletion of wedding." + + " This will unassign all people for the Wedding object."; + public static final String MESSAGE_FORCE_TAG_TO_CONTACT = "Use f/ to force the tagging of contacts." + + " This will create the require Tags."; + public static final String MESSAGE_FORCE_DELETE_TAG = "Use f/ to force the deletion of tags." + + " This will unassign all contacts with the Tag."; /** * Returns an error message indicating the duplicate prefixes. diff --git a/src/main/java/seedu/address/logic/commands/AssignWeddingCommand.java b/src/main/java/seedu/address/logic/commands/AssignWeddingCommand.java index 3c775dc0905..c07ff45e2a6 100644 --- a/src/main/java/seedu/address/logic/commands/AssignWeddingCommand.java +++ b/src/main/java/seedu/address/logic/commands/AssignWeddingCommand.java @@ -92,6 +92,7 @@ public CommandResult execute(Model model) throws CommandException { MESSAGE_WEDDING_NOT_FOUND + "\n" + MESSAGE_FORCE_ASSIGN_WEDDING_TO_CONTACT); } } + wedding.increasePeopleCount(); } Set updatedWeddings = new HashSet<>(personToEdit.getWeddings()); diff --git a/src/main/java/seedu/address/logic/commands/DeleteTagCommand.java b/src/main/java/seedu/address/logic/commands/DeleteTagCommand.java index 87a94b5dfbb..46b5a8b2021 100644 --- a/src/main/java/seedu/address/logic/commands/DeleteTagCommand.java +++ b/src/main/java/seedu/address/logic/commands/DeleteTagCommand.java @@ -3,12 +3,14 @@ import static java.util.Objects.requireNonNull; import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; +import java.util.HashSet; import java.util.List; 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.person.Person; import seedu.address.model.tag.Tag; /** @@ -27,11 +29,26 @@ public class DeleteTagCommand extends Command { public static final String MESSAGE_DELETE_TAG_FAILURE_NOT_FOUND = "The Tag: %1$s does not exist"; private final Tag targetTag; + private boolean force = false; + /** + * Initialises a DeleteTagCommand object with default force is false + * @param targetTag A tag object as the target + */ public DeleteTagCommand(Tag targetTag) { this.targetTag = targetTag; } + /** + * Initialises a DeleteTagCommand object with a specific force + * @param targetTag A Tag object as the target + * @param force A boolean representing if the command should be forced + */ + public DeleteTagCommand(Tag targetTag, boolean force) { + this.targetTag = targetTag; + this.force = force; + } + @Override public CommandResult execute(Model model) throws CommandException { requireNonNull(model); @@ -43,11 +60,35 @@ public CommandResult execute(Model model) throws CommandException { model.deleteTag(tag); return new CommandResult(String.format(MESSAGE_DELETE_TAG_SUCCESS, Messages.format(targetTag))); } else { - throw new CommandException( - String.format(MESSAGE_DELETE_TAG_FAILURE_STILL_TAGGED, Messages.format(targetTag))); + if (this.force) { + for (Person person : model.getFilteredPersonList()) { + HashSet personTags = new HashSet<>(person.getTags()); + if (personTags.contains(tag)) { + personTags.remove(tag); + Person newPerson = new Person( + person.getName(), + person.getPhone(), + person.getEmail(), + person.getAddress(), + personTags, + person.getWeddings() + ); + model.setPerson(person, newPerson); + model.updateFilteredPersonList(Model.PREDICATE_SHOW_ALL_PERSONS); + } + } + model.deleteTag(tag); + return new CommandResult(String.format(MESSAGE_DELETE_TAG_SUCCESS, Messages.format(targetTag))); + } else { + throw new CommandException( + String.format(MESSAGE_DELETE_TAG_FAILURE_STILL_TAGGED, Messages.format(targetTag)) + + ".\n" + + Messages.MESSAGE_FORCE_DELETE_TAG); + } } } } + model.updateFilteredTagList(Model.PREDICATE_SHOW_ALL_TAGS); throw new CommandException(String.format(MESSAGE_DELETE_TAG_FAILURE_NOT_FOUND, Messages.format(targetTag))); } diff --git a/src/main/java/seedu/address/logic/commands/DeleteWeddingCommand.java b/src/main/java/seedu/address/logic/commands/DeleteWeddingCommand.java index 49e95089ad2..958410d4f8d 100644 --- a/src/main/java/seedu/address/logic/commands/DeleteWeddingCommand.java +++ b/src/main/java/seedu/address/logic/commands/DeleteWeddingCommand.java @@ -3,12 +3,14 @@ import static java.util.Objects.requireNonNull; import static seedu.address.logic.parser.CliSyntax.PREFIX_WEDDING; +import java.util.HashSet; import java.util.List; 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.person.Person; import seedu.address.model.wedding.Wedding; /** @@ -28,11 +30,26 @@ public class DeleteWeddingCommand extends Command { public static final String MESSAGE_DELETE_WEDDING_FAILURE_NOT_FOUND = "The Wedding: %1$s does not exist"; private final Wedding targetWedding; + private boolean force = false; + /** + * Initialises a DeleteWeddingCommand object with default force is false + * @param wedding A wedding object as the target + */ public DeleteWeddingCommand(Wedding wedding) { targetWedding = wedding; } + /** + * Initialises a DeleteWeddingCommand object with a specific force + * @param wedding A wedding object as the target + * @param force A boolean representing if the command should be forced + */ + public DeleteWeddingCommand(Wedding wedding, boolean force) { + this.targetWedding = wedding; + this.force = force; + } + @Override public CommandResult execute(Model model) throws CommandException { requireNonNull(model); @@ -45,8 +62,31 @@ public CommandResult execute(Model model) throws CommandException { return new CommandResult(String.format(MESSAGE_DELETE_WEDDING_SUCCESS, Messages.format(targetWedding))); } else { - throw new CommandException( - String.format(MESSAGE_DELETE_WEDDING_FAILURE_STILL_USED, Messages.format(targetWedding))); + if (this.force) { + for (Person person : model.getFilteredPersonList()) { + HashSet personWeddings = new HashSet<>(person.getWeddings()); + if (personWeddings.contains(wedding)) { + personWeddings.remove(wedding); + Person newPerson = new Person( + person.getName(), + person.getPhone(), + person.getEmail(), + person.getAddress(), + person.getTags(), + personWeddings + ); + model.setPerson(person, newPerson); + model.updateFilteredPersonList(Model.PREDICATE_SHOW_ALL_PERSONS); + } + } + model.deleteWedding(wedding); + return new CommandResult(String.format(MESSAGE_DELETE_WEDDING_SUCCESS, + Messages.format(targetWedding))); + } else { + throw new CommandException( + String.format(MESSAGE_DELETE_WEDDING_FAILURE_STILL_USED, + Messages.format(targetWedding))); + } } } } diff --git a/src/main/java/seedu/address/logic/commands/TagCommand.java b/src/main/java/seedu/address/logic/commands/TagCommand.java index 372b0b331bb..e5cc4842c03 100644 --- a/src/main/java/seedu/address/logic/commands/TagCommand.java +++ b/src/main/java/seedu/address/logic/commands/TagCommand.java @@ -12,6 +12,7 @@ import java.util.stream.Collectors; import seedu.address.commons.core.index.Index; +import seedu.address.logic.Messages; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.model.Model; import seedu.address.model.person.Person; @@ -34,7 +35,7 @@ public class TagCommand extends Command { private final Index index; private final HashSet tagsToAdd; - + private boolean force = false; /** * Constructs a {@code TagCommand} to add tags to a person. @@ -49,6 +50,21 @@ public TagCommand(Index index, HashSet tagsToAdd) { this.tagsToAdd = tagsToAdd; } + /** + * Constructs a {@code TagCommand} to add tags to a person. + * + * @param index The index of the person in the person list. + * @param tagsToAdd The list of tags to be added. + * @param force A boolean representing if the command should be forced. + */ + public TagCommand(Index index, HashSet tagsToAdd, boolean force) { + requireNonNull(index); + requireNonNull(tagsToAdd); + this.index = index; + this.tagsToAdd = tagsToAdd; + this.force = force; + } + /** * Generates a command execution success message showing the added tags and the person. * @@ -74,7 +90,12 @@ public CommandResult execute(Model model) throws CommandException { for (Tag tag : tagsToAdd) { if (!model.hasTag(tag)) { - throw new CommandException(MESSAGE_TAG_NOT_FOUND); + if (this.force) { + CreateTagCommand createTagCommand = new CreateTagCommand(tag); + createTagCommand.execute(model); + } else { + throw new CommandException(MESSAGE_TAG_NOT_FOUND + ".\n" + Messages.MESSAGE_FORCE_TAG_TO_CONTACT); + } } } diff --git a/src/main/java/seedu/address/logic/parser/DeleteTagCommandParser.java b/src/main/java/seedu/address/logic/parser/DeleteTagCommandParser.java index 4b564139b67..a66a02e8c41 100644 --- a/src/main/java/seedu/address/logic/parser/DeleteTagCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/DeleteTagCommandParser.java @@ -1,6 +1,7 @@ package seedu.address.logic.parser; import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.parser.CliSyntax.PREFIX_FORCE; import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; import java.util.stream.Stream; @@ -20,7 +21,7 @@ public class DeleteTagCommandParser implements Parser { */ public DeleteTagCommand parse(String args) throws ParseException { ArgumentMultimap argMultimap = - ArgumentTokenizer.tokenize(args, PREFIX_TAG); + ArgumentTokenizer.tokenize(args, PREFIX_TAG, PREFIX_FORCE); if (!arePrefixesPresent(argMultimap, PREFIX_TAG) || !argMultimap.getPreamble().isEmpty()) { @@ -29,7 +30,11 @@ public DeleteTagCommand parse(String args) throws ParseException { argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_TAG); Tag tag = ParserUtil.parseTag(argMultimap.getValue(PREFIX_TAG).get()); - return new DeleteTagCommand(tag); + if (arePrefixesPresent(argMultimap, PREFIX_FORCE)) { + return new DeleteTagCommand(tag, true); + } else { + return new DeleteTagCommand(tag); + } } /** diff --git a/src/main/java/seedu/address/logic/parser/DeleteWeddingCommandParser.java b/src/main/java/seedu/address/logic/parser/DeleteWeddingCommandParser.java index 4e6278dfb6c..5be851c7d2f 100644 --- a/src/main/java/seedu/address/logic/parser/DeleteWeddingCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/DeleteWeddingCommandParser.java @@ -1,6 +1,7 @@ package seedu.address.logic.parser; import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.parser.CliSyntax.PREFIX_FORCE; import static seedu.address.logic.parser.CliSyntax.PREFIX_WEDDING; import java.util.stream.Stream; @@ -20,7 +21,7 @@ public class DeleteWeddingCommandParser implements Parser */ public DeleteWeddingCommand parse(String args) throws ParseException { ArgumentMultimap argMultimap = - ArgumentTokenizer.tokenize(args, PREFIX_WEDDING); + ArgumentTokenizer.tokenize(args, PREFIX_WEDDING, PREFIX_FORCE); if (!arePrefixesPresent(argMultimap, PREFIX_WEDDING) || !argMultimap.getPreamble().isEmpty()) { @@ -29,7 +30,11 @@ public DeleteWeddingCommand parse(String args) throws ParseException { argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_WEDDING); Wedding wedding = ParserUtil.parseWedding(argMultimap.getValue(PREFIX_WEDDING).get()); - return new DeleteWeddingCommand(wedding); + if (arePrefixesPresent(argMultimap, PREFIX_FORCE)) { + return new DeleteWeddingCommand(wedding, true); + } else { + return new DeleteWeddingCommand(wedding); + } } /** diff --git a/src/main/java/seedu/address/logic/parser/TagCommandParser.java b/src/main/java/seedu/address/logic/parser/TagCommandParser.java index 1f7ecd93330..045c405754e 100644 --- a/src/main/java/seedu/address/logic/parser/TagCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/TagCommandParser.java @@ -1,7 +1,9 @@ package seedu.address.logic.parser; import static java.util.Objects.requireNonNull; +import static seedu.address.logic.parser.CliSyntax.PREFIX_FORCE; import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; +import static seedu.address.logic.parser.CreateWeddingCommandParser.arePrefixesPresent; import java.util.HashSet; import java.util.Set; @@ -28,10 +30,14 @@ public class TagCommandParser implements Parser { public TagCommand parse(String args) throws ParseException { requireNonNull(args); - ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_TAG); + ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_TAG, PREFIX_FORCE); Pair> indexAndTags = TaggingCommandParserUtil.parseIndexAndTags(argMultimap, TagCommand.MESSAGE_USAGE); - return new TagCommand(indexAndTags.getKey(), new HashSet<>(indexAndTags.getValue())); + if (arePrefixesPresent(argMultimap, PREFIX_FORCE)) { + return new TagCommand(indexAndTags.getKey(), new HashSet<>(indexAndTags.getValue()), true); + } else { + return new TagCommand(indexAndTags.getKey(), new HashSet<>(indexAndTags.getValue())); + } } } diff --git a/src/main/java/seedu/address/model/AddressBook.java b/src/main/java/seedu/address/model/AddressBook.java index d7100716686..0fb96d9ae3d 100644 --- a/src/main/java/seedu/address/model/AddressBook.java +++ b/src/main/java/seedu/address/model/AddressBook.java @@ -205,8 +205,11 @@ public void initialiseTags() { for (Person person : persons) { Set tagForPerson = person.getTags(); for (Tag tag : tagForPerson) { + tag.increaseTaggedCount(); if (!this.hasTag(tag)) { this.addTag(tag); + } else { + this.setTag(tag, tag); } } } diff --git a/src/main/java/seedu/address/model/tag/Tag.java b/src/main/java/seedu/address/model/tag/Tag.java index 6dda59a6d8a..0fabe8e162d 100644 --- a/src/main/java/seedu/address/model/tag/Tag.java +++ b/src/main/java/seedu/address/model/tag/Tag.java @@ -60,6 +60,9 @@ public void decreaseTaggedCount() { taggedCount--; } + public int getTagCount() { + return taggedCount; + } /** * Returns true if the tag can be deleted. * The tag can be deleted if TaggedCount is 0. diff --git a/src/main/java/seedu/address/storage/JsonAdaptedPerson.java b/src/main/java/seedu/address/storage/JsonAdaptedPerson.java index 989b6914e56..d031c73c0f9 100644 --- a/src/main/java/seedu/address/storage/JsonAdaptedPerson.java +++ b/src/main/java/seedu/address/storage/JsonAdaptedPerson.java @@ -78,7 +78,8 @@ public Person toModelType() throws IllegalValueException { final List personWeddings = new ArrayList<>(); for (JsonAdaptedTag tag : tags) { - personTags.add(tag.toModelType()); + Tag toAdd = tag.toModelType(); + personTags.add(toAdd); } for (JsonAdaptedWedding wedding : weddings) { From 3e1637bc647244ab411fa522e57874f90f1fabdd Mon Sep 17 00:00:00 2001 From: Han Bin Date: Wed, 23 Oct 2024 17:12:34 +0800 Subject: [PATCH 02/10] Edited testcase Edited testcase of Tags to support force functionality. --- .../java/seedu/address/logic/commands/DeleteTagCommandTest.java | 1 - src/test/java/seedu/address/logic/commands/TagCommandTest.java | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/java/seedu/address/logic/commands/DeleteTagCommandTest.java b/src/test/java/seedu/address/logic/commands/DeleteTagCommandTest.java index b614ada6ec4..009ed1e2618 100644 --- a/src/test/java/seedu/address/logic/commands/DeleteTagCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/DeleteTagCommandTest.java @@ -29,7 +29,6 @@ public void execute_validDeleteTagCommand_success() { ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); expectedModel.deleteTag(tagToDelete); - assertCommandSuccess(deleteTagCommand, model, expectedMessage, expectedModel); } diff --git a/src/test/java/seedu/address/logic/commands/TagCommandTest.java b/src/test/java/seedu/address/logic/commands/TagCommandTest.java index 4ca3098af1b..0ff147dfb2d 100644 --- a/src/test/java/seedu/address/logic/commands/TagCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/TagCommandTest.java @@ -107,7 +107,7 @@ public void execute_invalidIndexUnfilteredList_failure() { public void execute_nonExistentTag_failure() { HashSet tagsToAdd = new HashSet(Arrays.asList(new Tag(new TagName("nonExistentTag")))); TagCommand tagCommand = new TagCommand(INDEX_FIRST_PERSON, tagsToAdd); - String expectedMessage = Messages.MESSAGE_TAG_NOT_FOUND; + String expectedMessage = Messages.MESSAGE_TAG_NOT_FOUND + ".\n" + Messages.MESSAGE_FORCE_TAG_TO_CONTACT; CommandTestUtil.assertCommandFailure(tagCommand, model, expectedMessage); } From 111b582e54ba14bdaf840e039ec68c30dd0cebc6 Mon Sep 17 00:00:00 2001 From: Han Bin Date: Wed, 23 Oct 2024 18:08:22 +0800 Subject: [PATCH 03/10] Edit error message for DeleteWeddingCommand.java Edit error message for consistency. --- .../seedu/address/logic/commands/DeleteWeddingCommand.java | 6 +++++- .../address/logic/commands/DeleteWeddingCommandTest.java | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/DeleteWeddingCommand.java b/src/main/java/seedu/address/logic/commands/DeleteWeddingCommand.java index 958410d4f8d..fdabc80d289 100644 --- a/src/main/java/seedu/address/logic/commands/DeleteWeddingCommand.java +++ b/src/main/java/seedu/address/logic/commands/DeleteWeddingCommand.java @@ -85,11 +85,15 @@ public CommandResult execute(Model model) throws CommandException { } else { throw new CommandException( String.format(MESSAGE_DELETE_WEDDING_FAILURE_STILL_USED, - Messages.format(targetWedding))); + Messages.format(targetWedding)) + + ".\n" + + Messages.MESSAGE_FORCE_DELETE_WEDDING + ); } } } } + model.updateFilteredWeddingList(Model.PREDICATE_SHOW_ALL_WEDDINGS); throw new CommandException(String.format(MESSAGE_DELETE_WEDDING_FAILURE_NOT_FOUND, Messages.format(targetWedding))); } diff --git a/src/test/java/seedu/address/logic/commands/DeleteWeddingCommandTest.java b/src/test/java/seedu/address/logic/commands/DeleteWeddingCommandTest.java index 7be526db9c3..cb8b1670d1b 100644 --- a/src/test/java/seedu/address/logic/commands/DeleteWeddingCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/DeleteWeddingCommandTest.java @@ -20,7 +20,7 @@ public class DeleteWeddingCommandTest { private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); @Test - public void execute_validDeleteWeddingCommand_success() { + public void execute_validDeleteWeddingCommand() { Wedding weddingToDelete = model.getFilteredWeddingList().get(0); DeleteWeddingCommand deleteWeddingCommand = new DeleteWeddingCommand(weddingToDelete); From cdc8aa848dd8409bb7e5fccec612247d6bc1af88 Mon Sep 17 00:00:00 2001 From: Han Bin Date: Wed, 23 Oct 2024 21:23:56 +0800 Subject: [PATCH 04/10] Edit test for DeleteWeddingCommand.java Edit test cases for DeleteWeddingCommandTest.java --- .../seedu/address/logic/commands/DeleteWeddingCommandTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/seedu/address/logic/commands/DeleteWeddingCommandTest.java b/src/test/java/seedu/address/logic/commands/DeleteWeddingCommandTest.java index cb8b1670d1b..365cd0a24ef 100644 --- a/src/test/java/seedu/address/logic/commands/DeleteWeddingCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/DeleteWeddingCommandTest.java @@ -22,7 +22,7 @@ public class DeleteWeddingCommandTest { @Test public void execute_validDeleteWeddingCommand() { Wedding weddingToDelete = model.getFilteredWeddingList().get(0); - DeleteWeddingCommand deleteWeddingCommand = new DeleteWeddingCommand(weddingToDelete); + DeleteWeddingCommand deleteWeddingCommand = new DeleteWeddingCommand(weddingToDelete, true); String expectedMessage = String.format(DeleteWeddingCommand.MESSAGE_DELETE_WEDDING_SUCCESS, Messages.format(weddingToDelete)); From 248c637e5e304a2eabf502bd22c7efa03862cac7 Mon Sep 17 00:00:00 2001 From: Han Bin Date: Thu, 24 Oct 2024 15:38:28 +0800 Subject: [PATCH 05/10] Fix Error Message in Test Fix error message in TagCommandTest.java --- src/main/java/seedu/address/logic/commands/TagCommand.java | 2 +- .../logic/commands/wedding/UnassignWeddingCommand.java | 5 +++++ .../java/seedu/address/logic/parser/TagCommandParser.java | 2 +- .../java/seedu/address/logic/commands/TagCommandTest.java | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/TagCommand.java b/src/main/java/seedu/address/logic/commands/TagCommand.java index e5cc4842c03..fa2ecde4434 100644 --- a/src/main/java/seedu/address/logic/commands/TagCommand.java +++ b/src/main/java/seedu/address/logic/commands/TagCommand.java @@ -94,7 +94,7 @@ public CommandResult execute(Model model) throws CommandException { CreateTagCommand createTagCommand = new CreateTagCommand(tag); createTagCommand.execute(model); } else { - throw new CommandException(MESSAGE_TAG_NOT_FOUND + ".\n" + Messages.MESSAGE_FORCE_TAG_TO_CONTACT); + throw new CommandException(MESSAGE_TAG_NOT_FOUND + "\n" + Messages.MESSAGE_FORCE_TAG_TO_CONTACT); } } } diff --git a/src/main/java/seedu/address/logic/commands/wedding/UnassignWeddingCommand.java b/src/main/java/seedu/address/logic/commands/wedding/UnassignWeddingCommand.java index deb84418f40..b22c9c73054 100644 --- a/src/main/java/seedu/address/logic/commands/wedding/UnassignWeddingCommand.java +++ b/src/main/java/seedu/address/logic/commands/wedding/UnassignWeddingCommand.java @@ -82,6 +82,11 @@ public CommandResult execute(Model model) throws CommandException { if (!updatedWeddings.containsAll(weddingsToRemove)) { throw new CommandException(MESSAGE_WEDDING_NOT_FOUND_IN_CONTACT); } + for (Wedding wedding : updatedWeddings) { + if (weddingsToRemove.contains(wedding)) { + wedding.decreasePeopleCount(); + } + } updatedWeddings.removeAll(weddingsToRemove); Person editedPerson = new Person( diff --git a/src/main/java/seedu/address/logic/parser/TagCommandParser.java b/src/main/java/seedu/address/logic/parser/TagCommandParser.java index 045c405754e..25064ba10af 100644 --- a/src/main/java/seedu/address/logic/parser/TagCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/TagCommandParser.java @@ -3,7 +3,7 @@ import static java.util.Objects.requireNonNull; import static seedu.address.logic.parser.CliSyntax.PREFIX_FORCE; import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; -import static seedu.address.logic.parser.CreateWeddingCommandParser.arePrefixesPresent; +import static seedu.address.logic.parser.wedding.CreateWeddingCommandParser.arePrefixesPresent; import java.util.HashSet; import java.util.Set; diff --git a/src/test/java/seedu/address/logic/commands/TagCommandTest.java b/src/test/java/seedu/address/logic/commands/TagCommandTest.java index afc030828d3..0a201004eff 100644 --- a/src/test/java/seedu/address/logic/commands/TagCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/TagCommandTest.java @@ -108,7 +108,7 @@ public void execute_invalidIndexUnfilteredList_failure() { public void execute_nonExistentTag_failure() { HashSet tagsToAdd = new HashSet<>(List.of(new Tag(new TagName("nonExistentTag")))); TagCommand tagCommand = new TagCommand(INDEX_FIRST, tagsToAdd); - String expectedMessage = Messages.MESSAGE_TAG_NOT_FOUND; + String expectedMessage = Messages.MESSAGE_TAG_NOT_FOUND + '\n' + Messages.MESSAGE_FORCE_TAG_TO_CONTACT; CommandTestUtil.assertCommandFailure(tagCommand, model, expectedMessage); } From 6e43ee80fe9530cb819c62df9ab6fa316a2795c7 Mon Sep 17 00:00:00 2001 From: Han Bin Date: Thu, 24 Oct 2024 15:43:38 +0800 Subject: [PATCH 06/10] Update equals method in AssignWeddingCommand.java Update equals method to support the force field. --- .../address/logic/commands/wedding/AssignWeddingCommand.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/address/logic/commands/wedding/AssignWeddingCommand.java b/src/main/java/seedu/address/logic/commands/wedding/AssignWeddingCommand.java index cb970a056b2..0283df928a4 100644 --- a/src/main/java/seedu/address/logic/commands/wedding/AssignWeddingCommand.java +++ b/src/main/java/seedu/address/logic/commands/wedding/AssignWeddingCommand.java @@ -125,6 +125,7 @@ public boolean equals(Object other) { } AssignWeddingCommand otherCommand = (AssignWeddingCommand) other; - return index.equals(otherCommand.index) && weddingsToAdd.equals(((AssignWeddingCommand) other).weddingsToAdd); + return index.equals(otherCommand.index) && weddingsToAdd.equals(((AssignWeddingCommand) other).weddingsToAdd) + && this.force == otherCommand.force; } } From c841c6a7c2a1892802fc763ee16ea333489d11ba Mon Sep 17 00:00:00 2001 From: Han Bin Date: Thu, 24 Oct 2024 15:46:42 +0800 Subject: [PATCH 07/10] Fix merge conflicts with Task Fix merge conflicts when implementing Task. --- .../java/seedu/address/logic/commands/DeleteTagCommand.java | 3 ++- .../address/logic/commands/wedding/DeleteWeddingCommand.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/DeleteTagCommand.java b/src/main/java/seedu/address/logic/commands/DeleteTagCommand.java index 46b5a8b2021..bd653498dc5 100644 --- a/src/main/java/seedu/address/logic/commands/DeleteTagCommand.java +++ b/src/main/java/seedu/address/logic/commands/DeleteTagCommand.java @@ -71,7 +71,8 @@ public CommandResult execute(Model model) throws CommandException { person.getEmail(), person.getAddress(), personTags, - person.getWeddings() + person.getWeddings(), + person.getTasks() ); model.setPerson(person, newPerson); model.updateFilteredPersonList(Model.PREDICATE_SHOW_ALL_PERSONS); diff --git a/src/main/java/seedu/address/logic/commands/wedding/DeleteWeddingCommand.java b/src/main/java/seedu/address/logic/commands/wedding/DeleteWeddingCommand.java index 89b29f585a8..9feba2082e0 100644 --- a/src/main/java/seedu/address/logic/commands/wedding/DeleteWeddingCommand.java +++ b/src/main/java/seedu/address/logic/commands/wedding/DeleteWeddingCommand.java @@ -75,7 +75,8 @@ public CommandResult execute(Model model) throws CommandException { person.getEmail(), person.getAddress(), person.getTags(), - personWeddings + personWeddings, + person.getTasks() ); model.setPerson(person, newPerson); model.updateFilteredPersonList(Model.PREDICATE_SHOW_ALL_PERSONS); From 050e1afeda03d5a47c6e0c6c0da3ce1eec105aaa Mon Sep 17 00:00:00 2001 From: Han Bin Date: Thu, 24 Oct 2024 16:03:51 +0800 Subject: [PATCH 08/10] Add more comprehensive test case for deleting tags Test force feature in DeleteTagCommand.java. Test validity of deleting in DeleteTagCommand.java. --- .../logic/commands/DeleteTagCommand.java | 8 +++---- .../logic/commands/DeleteTagCommandTest.java | 24 +++++++++++++++++-- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/DeleteTagCommand.java b/src/main/java/seedu/address/logic/commands/DeleteTagCommand.java index bd653498dc5..fc1ee8478c0 100644 --- a/src/main/java/seedu/address/logic/commands/DeleteTagCommand.java +++ b/src/main/java/seedu/address/logic/commands/DeleteTagCommand.java @@ -24,9 +24,9 @@ public class DeleteTagCommand extends Command { + "Parameters: " + PREFIX_TAG + "TAG (must exist in the AddressBook)\n" + "Example: " + COMMAND_WORD + " " + PREFIX_TAG + "florist"; - public static final String MESSAGE_DELETE_TAG_SUCCESS = "Deleted Tag: %1$s"; - public static final String MESSAGE_DELETE_TAG_FAILURE_STILL_TAGGED = "The Tag: %1$s is still used"; - public static final String MESSAGE_DELETE_TAG_FAILURE_NOT_FOUND = "The Tag: %1$s does not exist"; + public static final String MESSAGE_DELETE_TAG_SUCCESS = "Deleted Tag: %1$s."; + public static final String MESSAGE_DELETE_TAG_FAILURE_STILL_TAGGED = "The Tag: %1$s is still used."; + public static final String MESSAGE_DELETE_TAG_FAILURE_NOT_FOUND = "The Tag: %1$s does not exist."; private final Tag targetTag; private boolean force = false; @@ -83,7 +83,7 @@ public CommandResult execute(Model model) throws CommandException { } else { throw new CommandException( String.format(MESSAGE_DELETE_TAG_FAILURE_STILL_TAGGED, Messages.format(targetTag)) - + ".\n" + + "\n" + Messages.MESSAGE_FORCE_DELETE_TAG); } } diff --git a/src/test/java/seedu/address/logic/commands/DeleteTagCommandTest.java b/src/test/java/seedu/address/logic/commands/DeleteTagCommandTest.java index 009ed1e2618..58318e99a62 100644 --- a/src/test/java/seedu/address/logic/commands/DeleteTagCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/DeleteTagCommandTest.java @@ -32,7 +32,28 @@ public void execute_validDeleteTagCommand_success() { assertCommandSuccess(deleteTagCommand, model, expectedMessage, expectedModel); } - @Test void execute_invalidNotFoundDeleteTagCommand() { + @Test + public void execute_validDeleteTagCommandStillInUse_failure() { + Tag tagToDelete = model.getFilteredTagList().get(3); + DeleteTagCommand deleteTagCommand = new DeleteTagCommand(tagToDelete); + String expectedMessage = String.format( + DeleteTagCommand.MESSAGE_DELETE_TAG_FAILURE_STILL_TAGGED, Messages.format(tagToDelete)) + + "\n" + + Messages.MESSAGE_FORCE_DELETE_TAG; + assertCommandFailure(deleteTagCommand, model, expectedMessage); + } + + @Test + public void execute_validDeleteTagCommandStillInUseForce_success() { + Tag tagToDelete = model.getFilteredTagList().get(3); + DeleteTagCommand deleteTagCommand = new DeleteTagCommand(tagToDelete, true); + String expectedMessage = String.format( + DeleteTagCommand.MESSAGE_DELETE_TAG_SUCCESS, Messages.format(tagToDelete)); + assertCommandSuccess(deleteTagCommand, model, expectedMessage, model); + } + + @Test + public void execute_invalidNotFoundDeleteTagCommand() { Tag tagToDelete = model.getFilteredTagList().get(0); String expectedMessage = String.format(DeleteTagCommand.MESSAGE_DELETE_TAG_FAILURE_NOT_FOUND, @@ -45,7 +66,6 @@ public void execute_validDeleteTagCommand_success() { assertCommandFailure(expectedDeleteTagCommand, expectedModel, expectedMessage); } - @Test public void equals() { DeleteTagCommand deleteFloristTagCommand = new DeleteTagCommand(FLORIST); From f430c9510747a2ab7008fb8572b52d2a41ac7fa6 Mon Sep 17 00:00:00 2001 From: Han Bin Date: Thu, 24 Oct 2024 16:14:12 +0800 Subject: [PATCH 09/10] Add more comprehensive test case for assigning tags Test force feature in TagCommand.java. --- .../logic/commands/TagCommandTest.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/test/java/seedu/address/logic/commands/TagCommandTest.java b/src/test/java/seedu/address/logic/commands/TagCommandTest.java index 7e5f0a27c54..db22e01e27c 100644 --- a/src/test/java/seedu/address/logic/commands/TagCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/TagCommandTest.java @@ -56,6 +56,35 @@ public void execute_validTagsUnfilteredList_success() { CommandTestUtil.assertCommandSuccess(tagCommand, model, expectedMessage, expectedModel); } + @Test + public void execute_validTagsUnfilteredListWithForce_success() { + Person personToEdit = model.getFilteredPersonList().get(INDEX_FIRST.getZeroBased()); + HashSet tagsToAdd = new HashSet<>(List.of(new Tag(new TagName("colleague")))); + + // Ensure the model has the tag before adding it to the person + + TagCommand tagCommand = new TagCommand(INDEX_FIRST, tagsToAdd, true); + + String expectedMessage = String.format(Messages.MESSAGE_ADD_TAG_SUCCESS, + "colleague", personToEdit.getName().toString()); + + Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); + Set updatedTags = new HashSet<>(personToEdit.getTags()); + updatedTags.addAll(tagsToAdd); + Person editedPerson = new Person( + personToEdit.getName(), + personToEdit.getPhone(), + personToEdit.getEmail(), + personToEdit.getAddress(), + updatedTags, + personToEdit.getWeddings(), + personToEdit.getTasks()); + expectedModel.setPerson(personToEdit, editedPerson); + expectedModel.addTag(new Tag(new TagName("colleague"))); + + CommandTestUtil.assertCommandSuccess(tagCommand, model, expectedMessage, expectedModel); + } + @Test public void execute_validMultipleTagsUnfilteredList_success() { From b05059568d8f5bf3fd7052652208354672b533f2 Mon Sep 17 00:00:00 2001 From: Han Bin Date: Thu, 24 Oct 2024 16:31:55 +0800 Subject: [PATCH 10/10] Add more comprehensive test cases Test force feature in DeleteWeddingCommand.java. --- .../java/seedu/address/model/AddressBook.java | 1 + .../wedding/DeleteWeddingCommandTest.java | 24 ++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/address/model/AddressBook.java b/src/main/java/seedu/address/model/AddressBook.java index 3a057bbe4b0..314ce584e18 100644 --- a/src/main/java/seedu/address/model/AddressBook.java +++ b/src/main/java/seedu/address/model/AddressBook.java @@ -293,6 +293,7 @@ public void initialiseWeddings() { if (!this.hasWedding(wedding)) { this.addWedding(wedding); } + wedding.increasePeopleCount(); } } } diff --git a/src/test/java/seedu/address/logic/commands/wedding/DeleteWeddingCommandTest.java b/src/test/java/seedu/address/logic/commands/wedding/DeleteWeddingCommandTest.java index 01b028a4824..175cc019148 100644 --- a/src/test/java/seedu/address/logic/commands/wedding/DeleteWeddingCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/wedding/DeleteWeddingCommandTest.java @@ -8,12 +8,16 @@ import static seedu.address.testutil.TypicalWeddings.AMY_WEDDING; import static seedu.address.testutil.TypicalWeddings.BOB_WEDDING; +import java.util.HashSet; + import org.junit.jupiter.api.Test; +import javafx.collections.ObservableList; import seedu.address.logic.Messages; import seedu.address.model.Model; import seedu.address.model.ModelManager; import seedu.address.model.UserPrefs; +import seedu.address.model.person.Person; import seedu.address.model.wedding.Wedding; public class DeleteWeddingCommandTest { @@ -21,7 +25,7 @@ public class DeleteWeddingCommandTest { @Test public void execute_validDeleteWeddingCommand() { - Wedding weddingToDelete = model.getFilteredWeddingList().get(0); + Wedding weddingToDelete = model.getFilteredWeddingList().get(2); DeleteWeddingCommand deleteWeddingCommand = new DeleteWeddingCommand(weddingToDelete, true); String expectedMessage = String.format(DeleteWeddingCommand.MESSAGE_DELETE_WEDDING_SUCCESS, @@ -29,6 +33,24 @@ public void execute_validDeleteWeddingCommand() { ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); expectedModel.deleteWedding(weddingToDelete); + ObservableList peopleInModel = expectedModel.getFilteredPersonList(); + for (Person person : expectedModel.getFilteredPersonList()) { + HashSet personWeddings = new HashSet<>(person.getWeddings()); + if (personWeddings.contains(weddingToDelete)) { + personWeddings.remove(weddingToDelete); + Person newPerson = new Person( + person.getName(), + person.getPhone(), + person.getEmail(), + person.getAddress(), + person.getTags(), + personWeddings, + person.getTasks() + ); + expectedModel.setPerson(person, newPerson); + expectedModel.updateFilteredPersonList(Model.PREDICATE_SHOW_ALL_PERSONS); + } + } assertCommandSuccess(deleteWeddingCommand, model, expectedMessage, expectedModel); }