From adcc3c3c412fd7bc04ce930d87f2631a281ce176 Mon Sep 17 00:00:00 2001 From: ZShunRen Date: Mon, 21 Oct 2024 12:53:13 +0800 Subject: [PATCH 01/13] Change equality check in person --- .../seedu/address/model/person/Person.java | 18 +++++++++++------- .../seedu/address/model/status/Status.java | 2 ++ 2 files changed, 13 insertions(+), 7 deletions(-) create mode 100644 src/main/java/seedu/address/model/status/Status.java diff --git a/src/main/java/seedu/address/model/person/Person.java b/src/main/java/seedu/address/model/person/Person.java index defe47ece5b..e425df7b430 100644 --- a/src/main/java/seedu/address/model/person/Person.java +++ b/src/main/java/seedu/address/model/person/Person.java @@ -5,6 +5,7 @@ import java.util.Objects; import seedu.address.commons.util.ToStringBuilder; +import seedu.address.model.status.Status; import seedu.address.model.tier.Tier; /** @@ -17,18 +18,20 @@ public class Person { private final Name name; private final Phone phone; private final Email email; - - // Data fields private final Address address; private final Job job; + // Data fields + private final Income income; private final Tier tier; private final Remark remark; + private final Status status; + /** * Every field must be present and not null. */ @@ -79,6 +82,10 @@ public Remark getRemark() { return remark; } + public Status getStatus() { + return status; + } + /** * Returns true if both persons have the same name. * This defines a weaker notion of equality between two persons. @@ -110,11 +117,7 @@ public boolean equals(Object other) { } Person otherPerson = (Person) other; - return name.equals(otherPerson.name) - && phone.equals(otherPerson.phone) - && email.equals(otherPerson.email) - && address.equals(otherPerson.address) - && job.equals(otherPerson.job); + return isSamePerson(otherPerson); } @Override @@ -134,6 +137,7 @@ public String toString() { .add("income", income) .add("tier", tier) .add("remark", remark) + .add("status", status) .toString(); } diff --git a/src/main/java/seedu/address/model/status/Status.java b/src/main/java/seedu/address/model/status/Status.java new file mode 100644 index 00000000000..45ffc97bd9c --- /dev/null +++ b/src/main/java/seedu/address/model/status/Status.java @@ -0,0 +1,2 @@ +package seedu.address.model.status;public class Status { +} From 762ea6115484b7553b16b5f3c18ca2ecb845f1b0 Mon Sep 17 00:00:00 2001 From: ZShunRen Date: Mon, 21 Oct 2024 12:55:39 +0800 Subject: [PATCH 02/13] Adjust whitespacing in person --- .../java/seedu/address/model/person/Person.java | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/main/java/seedu/address/model/person/Person.java b/src/main/java/seedu/address/model/person/Person.java index e425df7b430..9706ea436fd 100644 --- a/src/main/java/seedu/address/model/person/Person.java +++ b/src/main/java/seedu/address/model/person/Person.java @@ -18,20 +18,14 @@ public class Person { private final Name name; private final Phone phone; private final Email email; - private final Address address; - - private final Job job; // Data fields - + private final Address address; + private final Job job; private final Income income; - private final Tier tier; - private final Remark remark; - private final Status status; - /** * Every field must be present and not null. */ @@ -82,10 +76,6 @@ public Remark getRemark() { return remark; } - public Status getStatus() { - return status; - } - /** * Returns true if both persons have the same name. * This defines a weaker notion of equality between two persons. @@ -137,7 +127,6 @@ public String toString() { .add("income", income) .add("tier", tier) .add("remark", remark) - .add("status", status) .toString(); } From ddb60ae1e3c2182219642797bfb984d84d5f0106 Mon Sep 17 00:00:00 2001 From: Zheng Shun Ren <107254834+ZShunRen@users.noreply.github.com> Date: Mon, 21 Oct 2024 14:06:13 +0800 Subject: [PATCH 03/13] Delete Status.java --- src/main/java/seedu/address/model/status/Status.java | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 src/main/java/seedu/address/model/status/Status.java diff --git a/src/main/java/seedu/address/model/status/Status.java b/src/main/java/seedu/address/model/status/Status.java deleted file mode 100644 index 45ffc97bd9c..00000000000 --- a/src/main/java/seedu/address/model/status/Status.java +++ /dev/null @@ -1,2 +0,0 @@ -package seedu.address.model.status;public class Status { -} From 967946263a3c3823bf0de0cee4984243f98405e6 Mon Sep 17 00:00:00 2001 From: Zheng Shun Ren <107254834+ZShunRen@users.noreply.github.com> Date: Mon, 21 Oct 2024 14:07:41 +0800 Subject: [PATCH 04/13] Update Person.java Remove status which will be added in another PR. --- src/main/java/seedu/address/model/person/Person.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/seedu/address/model/person/Person.java b/src/main/java/seedu/address/model/person/Person.java index 9706ea436fd..fa1b5264f3c 100644 --- a/src/main/java/seedu/address/model/person/Person.java +++ b/src/main/java/seedu/address/model/person/Person.java @@ -5,7 +5,6 @@ import java.util.Objects; import seedu.address.commons.util.ToStringBuilder; -import seedu.address.model.status.Status; import seedu.address.model.tier.Tier; /** From 2682a45ecbf2401feb60dfb202f8708c57af63ab Mon Sep 17 00:00:00 2001 From: ZShunRen Date: Mon, 21 Oct 2024 14:11:04 +0800 Subject: [PATCH 05/13] Change person test --- src/test/java/seedu/address/model/person/PersonTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/seedu/address/model/person/PersonTest.java b/src/test/java/seedu/address/model/person/PersonTest.java index adc3fc4f5af..df0842414f1 100644 --- a/src/test/java/seedu/address/model/person/PersonTest.java +++ b/src/test/java/seedu/address/model/person/PersonTest.java @@ -84,7 +84,7 @@ public void equals() { // different job -> returns false editedAlice = new PersonBuilder(ALICE).withJob(VALID_JOB_BOB).build(); - assertFalse(ALICE.equals(editedAlice)); + assertTrue(ALICE.equals(editedAlice)); // different tier -> returns true editedAlice = new PersonBuilder(ALICE).withTier("Silver").build(); From f93dca087fd7bee7590336c0a50d8b8db860cad3 Mon Sep 17 00:00:00 2001 From: ZShunRen Date: Mon, 21 Oct 2024 18:16:46 +0800 Subject: [PATCH 06/13] Add status attribute + other minor fixes There is no way to indicate if follow-up action is needed for a particular customer, which is usually the case with financial services. Adding the status attribute helps the user differentiate between clients who may need follow-up action, and works in tandem with remark, where case details can be inserted. Other small changes include: - Refactoring `Person::isSamePerson` method to use name, phone and email as checks for equality. - Refactoring `Person::equals` method to use `Person::isSamePerson` method when checking for equality, which makes the code more maintainable as equality logic is only specified once. --- .../java/seedu/address/logic/Messages.java | 4 +- .../address/logic/commands/AddCommand.java | 7 +- .../logic/commands/CommandCommons.java | 1 + .../address/logic/commands/EditCommand.java | 30 +++++-- .../logic/parser/AddCommandParser.java | 12 ++- .../seedu/address/logic/parser/CliSyntax.java | 1 + .../logic/parser/EditCommandParser.java | 9 +- .../address/logic/parser/ParserUtil.java | 16 ++++ .../seedu/address/model/person/Person.java | 14 ++- .../seedu/address/model/status/Status.java | 89 +++++++++++++++++++ .../address/model/util/SampleDataUtil.java | 14 +-- .../address/storage/JsonAdaptedPerson.java | 20 ++++- .../address/storage/JsonAdaptedStatus.java | 52 +++++++++++ .../java/seedu/address/ui/PersonCard.java | 25 +++++- src/main/resources/view/DarkTheme.css | 26 ++++-- src/main/resources/view/PersonListCard.fxml | 2 +- .../commands/EditPersonDescriptorTest.java | 5 +- .../address/model/person/PersonTest.java | 8 +- .../storage/JsonAdaptedPersonTest.java | 25 +++--- .../seedu/address/testutil/PersonBuilder.java | 12 +-- .../seedu/address/testutil/PersonUtil.java | 2 +- 21 files changed, 311 insertions(+), 63 deletions(-) create mode 100644 src/main/java/seedu/address/model/status/Status.java create mode 100644 src/main/java/seedu/address/storage/JsonAdaptedStatus.java diff --git a/src/main/java/seedu/address/logic/Messages.java b/src/main/java/seedu/address/logic/Messages.java index 6174a241348..f477bed1ef8 100644 --- a/src/main/java/seedu/address/logic/Messages.java +++ b/src/main/java/seedu/address/logic/Messages.java @@ -52,7 +52,9 @@ public static String format(Person person) { .append("; Tier: ") .append(person.getTier()) .append("; Remark: ") - .append(person.getRemark()); + .append(person.getRemark()) + .append("; Status: ") + .append(person.getStatus()); return builder.toString(); } diff --git a/src/main/java/seedu/address/logic/commands/AddCommand.java b/src/main/java/seedu/address/logic/commands/AddCommand.java index 668cf152221..f7c49b0887d 100644 --- a/src/main/java/seedu/address/logic/commands/AddCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddCommand.java @@ -8,6 +8,7 @@ import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; import static seedu.address.logic.parser.CliSyntax.PREFIX_NEW_REMARK; import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_STATUS; import static seedu.address.logic.parser.CliSyntax.PREFIX_TIER; import seedu.address.commons.util.ToStringBuilder; @@ -32,7 +33,8 @@ public class AddCommand extends Command { + PREFIX_JOB + "JOB " + PREFIX_INCOME + "INCOME " + "[" + PREFIX_TIER + "TIER]...\n" - + "[" + PREFIX_NEW_REMARK + "NEW REMARK]...\n" + + "[" + PREFIX_NEW_REMARK + "NEW REMARK]..." + + "[" + PREFIX_STATUS + "STATUS]...\n" + "Example: " + COMMAND_WORD + " " + PREFIX_NAME + "John Doe " + PREFIX_PHONE + "98765432 " @@ -41,7 +43,8 @@ public class AddCommand extends Command { + PREFIX_JOB + "doctor " + PREFIX_INCOME + "300 " + PREFIX_TIER + "GOLD " - + PREFIX_NEW_REMARK + "He is very smart "; + + PREFIX_NEW_REMARK + "He is very smart " + + PREFIX_STATUS + "NON_URGENT"; public static final String MESSAGE_SUCCESS = "New person added: %1$s"; public static final String MESSAGE_DUPLICATE_PERSON = "This person already exists in the address book"; diff --git a/src/main/java/seedu/address/logic/commands/CommandCommons.java b/src/main/java/seedu/address/logic/commands/CommandCommons.java index d0fd738fa37..c4179d1efad 100644 --- a/src/main/java/seedu/address/logic/commands/CommandCommons.java +++ b/src/main/java/seedu/address/logic/commands/CommandCommons.java @@ -6,5 +6,6 @@ public final class CommandCommons { public static final String DEFAULT_TIER = ""; public static final String DEFAULT_REMARK = "NA"; + public static final String DEFAULT_STATUS = "NONE"; } diff --git a/src/main/java/seedu/address/logic/commands/EditCommand.java b/src/main/java/seedu/address/logic/commands/EditCommand.java index 1e3312eb9a0..1940938a828 100644 --- a/src/main/java/seedu/address/logic/commands/EditCommand.java +++ b/src/main/java/seedu/address/logic/commands/EditCommand.java @@ -9,6 +9,7 @@ import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; import static seedu.address.logic.parser.CliSyntax.PREFIX_NEW_REMARK; import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_STATUS; import static seedu.address.logic.parser.CliSyntax.PREFIX_TIER; import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PERSONS; @@ -30,6 +31,7 @@ import seedu.address.model.person.Person; import seedu.address.model.person.Phone; import seedu.address.model.person.Remark; +import seedu.address.model.status.Status; import seedu.address.model.tier.Tier; /** @@ -52,6 +54,7 @@ public class EditCommand extends Command { + "[" + PREFIX_TIER + "TIER]...\n" + "[" + PREFIX_NEW_REMARK + "NEW REMARK] " + "[" + PREFIX_APPEND_REMARK + "ADD-ON TO EXISTING REMARK] " + + "[" + PREFIX_STATUS + "STATUS] " + "Example: " + COMMAND_WORD + " 1 " + PREFIX_PHONE + "91234567 " + PREFIX_EMAIL + "johndoe@example.com"; @@ -109,7 +112,7 @@ private static Person createEditedPerson(Person personToEdit, EditPersonDescript Address updatedAddress = editPersonDescriptor.getAddress().orElse(personToEdit.getAddress()); Job updatedJob = editPersonDescriptor.getJob().orElse(personToEdit.getJob()); Income updatedIncome = editPersonDescriptor.getIncome().orElse(personToEdit.getIncome()); - Tier updatedTier = editPersonDescriptor.getTiers().orElse(personToEdit.getTier()); + Tier updatedTier = editPersonDescriptor.getTier().orElse(personToEdit.getTier()); Remark updatedRemark; if (editPersonDescriptor.getAppendedRemark().isPresent()) { updatedRemark = Remark.combineRemarks(personToEdit.getRemark(), @@ -117,8 +120,9 @@ private static Person createEditedPerson(Person personToEdit, EditPersonDescript } else { updatedRemark = editPersonDescriptor.getNewRemark().orElse(personToEdit.getRemark()); } + Status updatedStatus = editPersonDescriptor.getStatus().orElse(personToEdit.getStatus()); return new Person(updatedName, updatedPhone, updatedEmail, updatedAddress, updatedJob, updatedIncome, - updatedTier, updatedRemark); + updatedTier, updatedRemark, updatedStatus); } @Override @@ -159,6 +163,7 @@ public static class EditPersonDescriptor { private Tier tier; private Remark remark; private Remark appendedRemark; + private Status status; public EditPersonDescriptor() {} /** @@ -175,13 +180,15 @@ public EditPersonDescriptor(EditPersonDescriptor toCopy) { setTier(toCopy.tier); setNewRemark(toCopy.remark); setAppendedRemark(toCopy.appendedRemark); + setStatus(toCopy.status); } /** * Returns true if at least one field is edited. */ public boolean isAnyFieldEdited() { - return CollectionUtil.isAnyNonNull(name, phone, email, address, job, income, tier, remark, appendedRemark); + return CollectionUtil.isAnyNonNull(name, phone, email, address, job, income, tier, remark, appendedRemark, + status); } public void setName(Name name) { @@ -235,8 +242,8 @@ public Optional getIncome() { * Sets {@code tags} to this object's {@code tags}. * A defensive copy of {@code tags} is used internally. */ - public void setTier(Tier tiers) { - this.tier = tiers; + public void setTier(Tier tier) { + this.tier = tier; } /** @@ -244,7 +251,7 @@ public void setTier(Tier tiers) { * if modification is attempted. * Returns {@code Optional#empty()} if {@code tags} is null. */ - public Optional getTiers() { + public Optional getTier() { return (tier != null) ? Optional.of(tier) : Optional.empty(); } @@ -263,6 +270,13 @@ public void setAppendedRemark(Remark remark) { public Optional getAppendedRemark() { return Optional.ofNullable(appendedRemark); } + public void setStatus(Status status) { + this.status = status; + } + + public Optional getStatus() { + return Optional.ofNullable(this.status); + } @Override public boolean equals(Object other) { @@ -284,7 +298,8 @@ public boolean equals(Object other) { && Objects.equals(income, otherEditPersonDescriptor.income) && Objects.equals(tier, otherEditPersonDescriptor.tier) && Objects.equals(remark, otherEditPersonDescriptor.remark) - && Objects.equals(appendedRemark, otherEditPersonDescriptor.appendedRemark); + && Objects.equals(appendedRemark, otherEditPersonDescriptor.appendedRemark) + && Objects.equals(status, otherEditPersonDescriptor.status); } @Override @@ -298,6 +313,7 @@ public String toString() { .add("income", income) .add("tier", tier) .add("remark", remark) + .add("status", status) .toString(); } } diff --git a/src/main/java/seedu/address/logic/parser/AddCommandParser.java b/src/main/java/seedu/address/logic/parser/AddCommandParser.java index 22fd04f598c..aa6c74c8480 100644 --- a/src/main/java/seedu/address/logic/parser/AddCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/AddCommandParser.java @@ -8,6 +8,7 @@ import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; import static seedu.address.logic.parser.CliSyntax.PREFIX_NEW_REMARK; import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_STATUS; import static seedu.address.logic.parser.CliSyntax.PREFIX_TIER; import java.util.stream.Stream; @@ -23,6 +24,7 @@ import seedu.address.model.person.Person; import seedu.address.model.person.Phone; import seedu.address.model.person.Remark; +import seedu.address.model.status.Status; import seedu.address.model.tier.Tier; /** @@ -39,7 +41,7 @@ public class AddCommandParser implements Parser { public AddCommand parse(String args) throws ParseException { ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS, PREFIX_JOB, - PREFIX_INCOME, PREFIX_TIER, PREFIX_NEW_REMARK); + PREFIX_INCOME, PREFIX_TIER, PREFIX_NEW_REMARK, PREFIX_STATUS); if (!arePrefixesPresent(argMultimap, PREFIX_NAME, PREFIX_ADDRESS, PREFIX_JOB, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_INCOME) @@ -48,17 +50,19 @@ public AddCommand parse(String args) throws ParseException { } argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS, PREFIX_JOB, - PREFIX_INCOME, PREFIX_TIER, PREFIX_NEW_REMARK); + PREFIX_INCOME, PREFIX_TIER, PREFIX_NEW_REMARK, PREFIX_STATUS); Name name = ParserUtil.parseName(argMultimap.getValue(PREFIX_NAME).get()); Phone phone = ParserUtil.parsePhone(argMultimap.getValue(PREFIX_PHONE).get()); Email email = ParserUtil.parseEmail(argMultimap.getValue(PREFIX_EMAIL).get()); Address address = ParserUtil.parseAddress(argMultimap.getValue(PREFIX_ADDRESS).get()); Job job = ParserUtil.parseJob(argMultimap.getValue(PREFIX_JOB).get()); Income income = ParserUtil.parseIncome(argMultimap.getValue(PREFIX_INCOME).get()); - Tier tier = ParserUtil.parseTier(argMultimap.getValue(PREFIX_TIER).orElse("")); + Tier tier = ParserUtil.parseTier(argMultimap.getValue(PREFIX_TIER).orElse(CommandCommons.DEFAULT_TIER)); Remark remark = ParserUtil.parseNewRemark(argMultimap.getValue(PREFIX_NEW_REMARK) .orElse(CommandCommons.DEFAULT_REMARK)); - Person person = new Person(name, phone, email, address, job, income, tier, remark); + Status status = + ParserUtil.parseStatus(argMultimap.getValue(PREFIX_STATUS).orElse(CommandCommons.DEFAULT_STATUS)); + Person person = new Person(name, phone, email, address, job, income, tier, remark, status); return new AddCommand(person); } diff --git a/src/main/java/seedu/address/logic/parser/CliSyntax.java b/src/main/java/seedu/address/logic/parser/CliSyntax.java index 76adad589f6..8da65495ec3 100644 --- a/src/main/java/seedu/address/logic/parser/CliSyntax.java +++ b/src/main/java/seedu/address/logic/parser/CliSyntax.java @@ -16,5 +16,6 @@ public class CliSyntax { public static final Prefix PREFIX_REMARK = new Prefix("r/"); public static final Prefix PREFIX_NEW_REMARK = new Prefix("rn/"); public static final Prefix PREFIX_APPEND_REMARK = new Prefix("ra/"); + public static final Prefix PREFIX_STATUS = new Prefix("s/"); } diff --git a/src/main/java/seedu/address/logic/parser/EditCommandParser.java b/src/main/java/seedu/address/logic/parser/EditCommandParser.java index 61ea8447a65..ce89e81767c 100644 --- a/src/main/java/seedu/address/logic/parser/EditCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/EditCommandParser.java @@ -10,6 +10,7 @@ import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; import static seedu.address.logic.parser.CliSyntax.PREFIX_NEW_REMARK; import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_STATUS; import static seedu.address.logic.parser.CliSyntax.PREFIX_TIER; import seedu.address.commons.core.index.Index; @@ -32,7 +33,7 @@ public EditCommand parse(String args) throws ParseException { requireNonNull(args); ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS, - PREFIX_INCOME, PREFIX_JOB, PREFIX_TIER, PREFIX_NEW_REMARK, PREFIX_APPEND_REMARK); + PREFIX_INCOME, PREFIX_JOB, PREFIX_TIER, PREFIX_NEW_REMARK, PREFIX_APPEND_REMARK, PREFIX_STATUS); Index index; @@ -49,7 +50,7 @@ public EditCommand parse(String args) throws ParseException { } argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS, - PREFIX_INCOME, PREFIX_JOB, PREFIX_TIER, PREFIX_NEW_REMARK, PREFIX_APPEND_REMARK); + PREFIX_INCOME, PREFIX_JOB, PREFIX_TIER, PREFIX_NEW_REMARK, PREFIX_APPEND_REMARK, PREFIX_STATUS); EditPersonDescriptor editPersonDescriptor = new EditPersonDescriptor(); @@ -81,6 +82,10 @@ public EditCommand parse(String args) throws ParseException { editPersonDescriptor.setAppendedRemark(ParserUtil.parseNewRemark( argMultimap.getValue(PREFIX_APPEND_REMARK).get())); } + if (argMultimap.getValue(PREFIX_STATUS).isPresent()) { + editPersonDescriptor.setStatus((ParserUtil.parseStatus( + argMultimap.getValue(PREFIX_STATUS).get()))); + } if (!editPersonDescriptor.isAnyFieldEdited()) { throw new ParseException(EditCommand.MESSAGE_NOT_EDITED); diff --git a/src/main/java/seedu/address/logic/parser/ParserUtil.java b/src/main/java/seedu/address/logic/parser/ParserUtil.java index aedd8f9ea6e..fe4eea9526b 100644 --- a/src/main/java/seedu/address/logic/parser/ParserUtil.java +++ b/src/main/java/seedu/address/logic/parser/ParserUtil.java @@ -12,6 +12,7 @@ import seedu.address.model.person.Name; import seedu.address.model.person.Phone; import seedu.address.model.person.Remark; +import seedu.address.model.status.Status; import seedu.address.model.tier.Tier; import seedu.address.model.util.IncomeComparisonOperator; @@ -174,6 +175,21 @@ public static Tier parseTier(String tier) throws ParseException { return new Tier(trimmedTier); } + /** + * Parses a {@code String status} into a {@code Status}. + * Leading and trailing whitespaces are trimmed. + * + * @throws ParseException if the given {@code status} is invalid. + */ + public static Status parseStatus(String status) throws ParseException { + requireNonNull(status); + String trimmedStatus = status.trim(); + if (!Status.isValidStatus(trimmedStatus)) { + throw new ParseException(Status.MESSAGE_CONSTRAINTS); + } + return new Status(trimmedStatus); + } + /** * Parses a {@code String operator} into a {@code IncomeComparisonOperator}. * Leading and trailing whitespaces will be trimmed. diff --git a/src/main/java/seedu/address/model/person/Person.java b/src/main/java/seedu/address/model/person/Person.java index fa1b5264f3c..25bcfa05789 100644 --- a/src/main/java/seedu/address/model/person/Person.java +++ b/src/main/java/seedu/address/model/person/Person.java @@ -5,6 +5,7 @@ import java.util.Objects; import seedu.address.commons.util.ToStringBuilder; +import seedu.address.model.status.Status; import seedu.address.model.tier.Tier; /** @@ -24,13 +25,13 @@ public class Person { private final Income income; private final Tier tier; private final Remark remark; - + private final Status status; /** * Every field must be present and not null. */ public Person(Name name, Phone phone, Email email, Address address, Job job, Income income, - Tier tier, Remark remark) { - requireAllNonNull(name, phone, email, address, tier, remark); + Tier tier, Remark remark, Status status) { + requireAllNonNull(name, phone, email, address, tier, remark, status); this.name = name; this.phone = phone; this.email = email; @@ -39,6 +40,7 @@ public Person(Name name, Phone phone, Email email, Address address, Job job, Inc this.income = income; this.tier = tier; this.remark = remark; + this.status = status; } public Name getName() { @@ -62,6 +64,9 @@ public Job getJob() { public Income getIncome() { return income; } + public Status getStatus() { + return status; + } /** * Returns an immutable tier, which throws {@code UnsupportedOperationException} @@ -112,7 +117,7 @@ public boolean equals(Object other) { @Override public int hashCode() { // use this method for custom fields hashing instead of implementing your own - return Objects.hash(name, phone, email, address, job, tier); + return Objects.hash(name, phone, email, address, job, tier, remark, status); } @Override @@ -126,6 +131,7 @@ public String toString() { .add("income", income) .add("tier", tier) .add("remark", remark) + .add("status", status) .toString(); } diff --git a/src/main/java/seedu/address/model/status/Status.java b/src/main/java/seedu/address/model/status/Status.java new file mode 100644 index 00000000000..9cf6840777e --- /dev/null +++ b/src/main/java/seedu/address/model/status/Status.java @@ -0,0 +1,89 @@ +package seedu.address.model.status; + +import static java.util.Objects.requireNonNull; +import static seedu.address.commons.util.AppUtil.checkArgument; + +/** + * Represents a Status in the address book. + * Guarantees: immutable; name is valid as declared in {@link #isValidStatus(String)} + */ +public class Status { + + public static final String MESSAGE_CONSTRAINTS = "The statuses are only none, non-urgent and urgent. Please use " + + "only one of them"; + + public final StatusEnum status; + + /** + * Constructs a {@code Status}. + * + * @param statusString A valid status value, which is found in the {@code StatusEnum} + */ + public Status(String statusString) { + requireNonNull(statusString); + checkArgument(isValidStatus(statusString), MESSAGE_CONSTRAINTS); + if (statusString.isEmpty()) { + this.status = StatusEnum.NONE; + } else { + this.status = StatusEnum.valueOf(statusString.toUpperCase()); + } + } + + /** + * Returns true if a given string is a valid status value. + * + * @param test The string to be tested + */ + public static boolean isValidStatus(String test) { + if (test.isEmpty()) { + return true; // assign None + } + for (StatusEnum currentEnum: StatusEnum.values()) { + if (currentEnum.name().equals(test.toUpperCase())) { + return true; + } + } + return false; + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + if (!(other instanceof Status)) { + return false; + } + + Status otherStatus = (Status) other; + return this.status.equals(otherStatus.status); + } + + @Override + public int hashCode() { + return status.hashCode(); + } + + @Override + public String toString() { + return "[" + this.status.toString() + "]"; + } + + /** + * Formats the status into a string form, without square brackets. + * @return The string value of the status without brackets + */ + public String toParsableString() { + return status.toString(); + } + + /** + * Represent what values Status can take. + */ + public enum StatusEnum { + NONE, + NON_URGENT, + URGENT + } +} diff --git a/src/main/java/seedu/address/model/util/SampleDataUtil.java b/src/main/java/seedu/address/model/util/SampleDataUtil.java index 0bf6c22b69e..89dec6f7e89 100644 --- a/src/main/java/seedu/address/model/util/SampleDataUtil.java +++ b/src/main/java/seedu/address/model/util/SampleDataUtil.java @@ -10,6 +10,7 @@ import seedu.address.model.person.Person; import seedu.address.model.person.Phone; import seedu.address.model.person.Remark; +import seedu.address.model.status.Status; import seedu.address.model.tier.Tier; /** @@ -20,22 +21,23 @@ public static Person[] getSamplePersons() { return new Person[] { new Person(new Name("Alex Yeoh"), new Phone("87438807"), new Email("alexyeoh@example.com"), new Address("Blk 30 Geylang Street 29, #06-40"), new Job("Software Engineer"), new Income(19), - new Tier("GOLD"), new Remark("Has a lambo")), + new Tier("GOLD"), new Remark("Has a lambo"), new Status("NON_URGENT")), new Person(new Name("Bernice Yu"), new Phone("99272758"), new Email("berniceyu@example.com"), new Address("Blk 30 Lorong 3 Serangoon Gardens, #07-18"), new Job("Prime Minister"), new Income(20), - new Tier("SILVER"), new Remark("Father is the prime minister")), + new Tier("SILVER"), new Remark("Father is the prime minister"), + new Status("URGENT")), new Person(new Name("Charlotte Oliveiro"), new Phone("93210283"), new Email("charlotte@example.com"), new Address("Blk 11 Ang Mo Kio Street 74, #11-04"), new Job("Designer"), new Income(1500), - new Tier("BRONZE"), new Remark("")), + new Tier("BRONZE"), new Remark(""), new Status("NON_URGENT")), new Person(new Name("David Li"), new Phone("91031282"), new Email("lidavid@example.com"), new Address("Blk 436 Serangoon Gardens Street 26, #16-43"), new Job("Accountant"), new Income(1200), - new Tier("BRONZE"), new Remark("")), + new Tier("BRONZE"), new Remark(""), new Status("")), new Person(new Name("Irfan Ibrahim"), new Phone("92492021"), new Email("irfan@example.com"), new Address("Blk 47 Tampines Street 20, #17-35"), new Job("Macs Burger Flipper"), new Income(20), - new Tier("REJECT"), new Remark("")), + new Tier("REJECT"), new Remark(""), new Status("URGENT")), new Person(new Name("Roy Balakrishnan"), new Phone("92624417"), new Email("royb@example.com"), new Address("Blk 45 Aljunied Street 85, #11-31"), new Job("PowerPoint Master"), new Income(30), - new Tier("REJECT"), new Remark("")) + new Tier("REJECT"), new Remark(""), new Status("")) }; } diff --git a/src/main/java/seedu/address/storage/JsonAdaptedPerson.java b/src/main/java/seedu/address/storage/JsonAdaptedPerson.java index 7b5ad49bbb6..552331035c9 100644 --- a/src/main/java/seedu/address/storage/JsonAdaptedPerson.java +++ b/src/main/java/seedu/address/storage/JsonAdaptedPerson.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import seedu.address.commons.exceptions.IllegalValueException; +import seedu.address.logic.commands.CommandCommons; import seedu.address.model.person.Address; import seedu.address.model.person.Email; import seedu.address.model.person.Income; @@ -12,6 +13,7 @@ import seedu.address.model.person.Person; import seedu.address.model.person.Phone; import seedu.address.model.person.Remark; +import seedu.address.model.status.Status; import seedu.address.model.tier.Tier; /** @@ -29,6 +31,7 @@ class JsonAdaptedPerson { private final String incomeString; private final String remark; private final JsonAdaptedTier assignedTier; + private final JsonAdaptedStatus assignedStatus; /** * Constructs a {@code JsonAdaptedPerson} with the given person details. @@ -38,15 +41,18 @@ public JsonAdaptedPerson(@JsonProperty("name") String name, @JsonProperty("phone @JsonProperty("email") String email, @JsonProperty("address") String address, @JsonProperty("job") String job, @JsonProperty("income") String incomeString, @JsonProperty("assignedTier") JsonAdaptedTier assignedTier, - @JsonProperty("remark") String remark) { + @JsonProperty("remark") String remark, + @JsonProperty("assignedStatus") JsonAdaptedStatus assignedStatus) { this.name = name; this.phone = phone; this.email = email; this.address = address; this.job = job; this.incomeString = incomeString; - this.remark = remark; this.assignedTier = assignedTier != null ? assignedTier : new JsonAdaptedTier(""); + this.remark = remark; + this.assignedStatus = assignedStatus != null ? assignedStatus + : new JsonAdaptedStatus(CommandCommons.DEFAULT_STATUS); } /** @@ -62,6 +68,10 @@ public JsonAdaptedPerson(Person source) { remark = source.getRemark().value; Tier tier = source.getTier(); assignedTier = tier != null ? new JsonAdaptedTier(tier) : new JsonAdaptedTier(""); + Status status = source.getStatus(); + assignedStatus = status != null ? new JsonAdaptedStatus(status) + : new JsonAdaptedStatus(CommandCommons.DEFAULT_STATUS); + } /** @@ -125,8 +135,12 @@ public Person toModelType() throws IllegalValueException { } final Remark modelRemark = new Remark(remark); + if (assignedStatus == null) { + throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Status.class.getSimpleName())); + } + final Status modelStatus = assignedStatus.toModelType(); return new Person(modelName, modelPhone, modelEmail, modelAddress, modelJob, - modelIncome, modelTier, modelRemark); + modelIncome, modelTier, modelRemark, modelStatus); } } diff --git a/src/main/java/seedu/address/storage/JsonAdaptedStatus.java b/src/main/java/seedu/address/storage/JsonAdaptedStatus.java new file mode 100644 index 00000000000..eacc6b6d514 --- /dev/null +++ b/src/main/java/seedu/address/storage/JsonAdaptedStatus.java @@ -0,0 +1,52 @@ +package seedu.address.storage; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import seedu.address.commons.exceptions.IllegalValueException; +import seedu.address.model.status.Status; + +/** + * Jackson-friendly version of {@link Status}. + */ +class JsonAdaptedStatus { + + private final String status; + + /** + * Constructs a {@code JsonAdaptedTag} with the given {@code status}. + */ + @JsonCreator + public JsonAdaptedStatus(String status) { + this.status = status; + } + + /** + * Converts a given {@code Tier} into this class for Jackson use. + */ + public JsonAdaptedStatus(Status source) { + status = source.toParsableString(); + } + + @JsonValue + public String getStatusName() { + return status; + } + + @Override + public String toString() { + return status; + } + + /** + * Converts this Jackson-friendly adapted tier object into the model's {@code Status} object. + * + * @throws IllegalValueException if there were any data constraints violated in the adapted Status. + */ + public Status toModelType() throws IllegalValueException { + if (!Status.isValidStatus(status)) { + throw new IllegalValueException(Status.MESSAGE_CONSTRAINTS); + } + return new Status(status); + } +} diff --git a/src/main/java/seedu/address/ui/PersonCard.java b/src/main/java/seedu/address/ui/PersonCard.java index 2a0fd281d7e..3d78a311c9e 100644 --- a/src/main/java/seedu/address/ui/PersonCard.java +++ b/src/main/java/seedu/address/ui/PersonCard.java @@ -7,6 +7,7 @@ import javafx.scene.layout.Region; import javafx.scene.layout.VBox; import seedu.address.model.person.Person; +import seedu.address.model.status.Status; /** * An UI component that displays information of a {@code Person}. @@ -39,7 +40,9 @@ public class PersonCard extends UiPart { @FXML private Label remark; @FXML - private FlowPane assignedTier; + private FlowPane assignedStatus; + @FXML + private FlowPane assignedStatusAndTier; @FXML private VBox cardFields; /** @@ -50,6 +53,7 @@ public PersonCard(Person person, int displayedIndex) { this.person = person; id.setText(displayedIndex + ". "); createFields(); + createStatus(); createTier(); } private void createFields() { @@ -78,7 +82,24 @@ private void createTier() { } if (tierLabel != null) { // Add the label to the FlowPane - assignedTier.getChildren().add(tierLabel); + assignedStatusAndTier.getChildren().add(tierLabel); + } + } + + private void createStatus() { + Label statusLabel = new Label(person.getStatus().toParsableString()); + + // Apply a different style class based on the status value + Status.StatusEnum status = person.getStatus().status; + switch (status) { + case NONE -> statusLabel.getStyleClass().add("none-status"); + case NON_URGENT -> statusLabel.getStyleClass().add("nonUrgent-status"); + case URGENT -> statusLabel.getStyleClass().add("urgent-status"); + default -> statusLabel = null; + } + if (statusLabel != null) { + assignedStatusAndTier.getChildren().add(statusLabel); + } } } diff --git a/src/main/resources/view/DarkTheme.css b/src/main/resources/view/DarkTheme.css index a299de39ecd..e83e860eef0 100644 --- a/src/main/resources/view/DarkTheme.css +++ b/src/main/resources/view/DarkTheme.css @@ -342,29 +342,41 @@ -fx-background-radius: 0; } -#assignedTier { +#assignedStatusAndTier { -fx-hgap: 7; -fx-vgap: 3; } -#assignedTier .gold-tier { +#assignedStatusAndTier .gold-tier { -fx-background-color: #B59410; } -#assignedTier .silver-tier { +#assignedStatusAndTier .silver-tier { -fx-background-color: #71706e; } -#assignedTier .bronze-tier { +#assignedStatusAndTier .bronze-tier { -fx-background-color: #804a00; } -#assignedTier .reject-tier { +#assignedStatusAndTier .reject-tier { -fx-background-color: #8B0000; } -#assignedTier .label { - -fx-text-fill: white; +#assignedStatusAndTier .none-status { + -fx-background-color: #009E60; +} + +#assignedStatusAndTier .nonUrgent-status { + -fx-background-color: #c46210; +} + +#assignedStatusAndTier .urgent-status { + -fx-background-color: #FF2400; +} + +#assignedStatusAndTier .label { + -fx-text-fillx: white; -fx-padding: 1 3 1 3; -fx-border-radius: 2; -fx-background-radius: 2; diff --git a/src/main/resources/view/PersonListCard.fxml b/src/main/resources/view/PersonListCard.fxml index d0a801b3f92..09e9096c423 100644 --- a/src/main/resources/view/PersonListCard.fxml +++ b/src/main/resources/view/PersonListCard.fxml @@ -28,7 +28,7 @@