diff --git a/src/main/java/seedu/address/logic/commands/FindClientTypeCommand.java b/src/main/java/seedu/address/logic/commands/FindClientTypeCommand.java new file mode 100644 index 00000000000..230e6e6eda1 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/FindClientTypeCommand.java @@ -0,0 +1,49 @@ +package seedu.address.logic.commands; + +import static java.util.Objects.requireNonNull; + +import seedu.address.commons.util.ToStringBuilder; +import seedu.address.logic.Messages; +import seedu.address.model.Model; +import seedu.address.model.person.ClientTypeContainsKeywordsPredicate; + +/** + * Finds and lists all persons in address book whose client_type contains any of the argument keywords. + * Keyword matching is case insensitive. + */ +public class FindClientTypeCommand extends Command { + + public static final String COMMAND_WORD = "fc"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all persons whose names contain any of " + + "the specified keywords (case-insensitive) and displays them as a list with index numbers.\n" + + "Parameters: CLIENT_TYPE [MORE_CLIENT_TYPES]...\n" + + "Example: " + COMMAND_WORD + "Investment Plan 1"; + + private final ClientTypeContainsKeywordsPredicate predicate; + + public FindClientTypeCommand(ClientTypeContainsKeywordsPredicate predicate) { + this.predicate = predicate; + } + + + @Override + public CommandResult execute(Model model) { + requireNonNull(model); + model.updateFilteredPersonList(predicate); + return new CommandResult( + String.format(Messages.MESSAGE_PERSONS_LISTED_OVERVIEW, model.getFilteredPersonList().size())); + } + + @Override + public boolean equals(Object other) { + return true; + } + + @Override + public String toString() { + return new ToStringBuilder(this) + .add("predicate", predicate) + .toString(); + } +} diff --git a/src/main/java/seedu/address/logic/parser/ClientHubParser.java b/src/main/java/seedu/address/logic/parser/ClientHubParser.java index bcb9765d9f8..91771f7f720 100644 --- a/src/main/java/seedu/address/logic/parser/ClientHubParser.java +++ b/src/main/java/seedu/address/logic/parser/ClientHubParser.java @@ -14,6 +14,7 @@ import seedu.address.logic.commands.DeleteCommand; import seedu.address.logic.commands.EditCommand; import seedu.address.logic.commands.ExitCommand; +import seedu.address.logic.commands.FindClientTypeCommand; import seedu.address.logic.commands.FindCommand; import seedu.address.logic.commands.FindPhoneCommand; import seedu.address.logic.commands.HelpCommand; @@ -81,6 +82,9 @@ public Command parseCommand(String userInput) throws ParseException { case FindPhoneCommand.COMMAND_WORD: return new FindPhoneCommandParser().parse(arguments); + case FindClientTypeCommand.COMMAND_WORD: + return new FindClientTypeCommandParser().parse(arguments); + default: logger.finer("This user input caused a ParseException: " + userInput); throw new ParseException(MESSAGE_UNKNOWN_COMMAND); diff --git a/src/main/java/seedu/address/logic/parser/FindClientTypeCommandParser.java b/src/main/java/seedu/address/logic/parser/FindClientTypeCommandParser.java new file mode 100644 index 00000000000..8e77f3b82a0 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/FindClientTypeCommandParser.java @@ -0,0 +1,33 @@ +package seedu.address.logic.parser; + +import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; + +import java.util.Arrays; + +import seedu.address.logic.commands.FindClientTypeCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.person.ClientTypeContainsKeywordsPredicate; + +/** + * Parses input arguments and creates a new FindCommand object + */ +public class FindClientTypeCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the FindCommand + * and returns a FindCommand object for execution. + * @throws ParseException if the user input does not conform the expected format + */ + public FindClientTypeCommand parse(String args) throws ParseException { + String trimmedArgs = args.trim(); + if (trimmedArgs.isEmpty()) { + throw new ParseException( + String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindClientTypeCommand.MESSAGE_USAGE)); + } + + String[] nameKeywords = trimmedArgs.split("\\s+"); + + return new FindClientTypeCommand(new ClientTypeContainsKeywordsPredicate(Arrays.asList(nameKeywords))); + } + +} diff --git a/src/main/java/seedu/address/model/person/ClientTypeContainsKeywordsPredicate.java b/src/main/java/seedu/address/model/person/ClientTypeContainsKeywordsPredicate.java new file mode 100644 index 00000000000..cca343a11d1 --- /dev/null +++ b/src/main/java/seedu/address/model/person/ClientTypeContainsKeywordsPredicate.java @@ -0,0 +1,49 @@ +package seedu.address.model.person; + +import java.util.List; +import java.util.Set; +import java.util.function.Predicate; + +import seedu.address.commons.util.ToStringBuilder; +import seedu.address.model.clienttype.ClientType; + +/** + * Tests that a {@code Person}'s {@code Name} matches any of the keywords given. + */ +public class ClientTypeContainsKeywordsPredicate implements Predicate { + private final List keywords; + + public ClientTypeContainsKeywordsPredicate(List keywords) { + this.keywords = keywords; + } + + @Override + public boolean test(Person person) { + Set personClientTypes = person.getClientTypes(); + return keywords.stream() + .anyMatch(keyword -> personClientTypes.stream().anyMatch(clientType -> + clientType.clientTypeName.toLowerCase().startsWith(keyword.toLowerCase())) + ); + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof ClientTypeContainsKeywordsPredicate)) { + return false; + } + + ClientTypeContainsKeywordsPredicate otherNameContainsKeywordsPredicate = + (ClientTypeContainsKeywordsPredicate) other; + return keywords.equals(otherNameContainsKeywordsPredicate.keywords); + } + + @Override + public String toString() { + return new ToStringBuilder(this).add("keywords", keywords).toString(); + } +}