From 6f8bcab3a41a1669624a5d354425e03849758a38 Mon Sep 17 00:00:00 2001 From: cleon Date: Fri, 13 Oct 2023 18:32:52 +0800 Subject: [PATCH 1/7] add income field to cli --- docs/UserGuide.md | 10 ++-- .../java/seedu/lovebook/logic/Messages.java | 2 + .../lovebook/logic/commands/AddCommand.java | 8 +-- .../lovebook/logic/commands/EditCommand.java | 28 +++++---- .../logic/parser/AddCommandParser.java | 22 +++---- .../lovebook/logic/parser/CliSyntax.java | 2 + .../lovebook/logic/parser/ParserUtil.java | 37 ++++++++---- .../seedu/lovebook/model/person/Date.java | 14 ++++- .../seedu/lovebook/model/person/Income.java | 58 +++++++++++++++++++ .../lovebook/storage/JsonAdaptedPerson.java | 20 +++++-- .../java/seedu/lovebook/ui/PersonCard.java | 6 +- src/main/resources/view/PersonListCard.fxml | 3 +- .../lovebook/testutil/PersonBuilder.java | 22 +++++-- 13 files changed, 169 insertions(+), 63 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index d67c685e38c..e4e4a17878e 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -81,7 +81,7 @@ Parameter constraints: - Horoscope should be a non-empty string. Example: -`NewD name/Cleon age/22 gender/F height/1.76 horoscope/Taurus income/3000` +`newD name/Cleon age/22 gender/F height/1.76 horoscope/Taurus income/3000` Expected output: `New date has been successfully added!` @@ -89,7 +89,7 @@ Output if error: Please follow the required format to add a new date (New date /name Adam /age 123 /gender F /horoscope Cancer) ### Edit existing dates -Format: `EditD INDEX METRIC/NEW ARG` +Format: `editD INDEX METRIC/NEW ARG` Parameter constraints: - The index must be a positive integer, and be within the range of the recorded dates @@ -98,9 +98,9 @@ Parameter constraints: - User can edit up to n number of metrics in one command line, where n refers to the number of metrics available Example: -- `EditD 3 name/Cleon` (editing 1 metric) -- `EditD 3 name/Cleon horoscope/Cancer` (editing 2 metrics) -- `EditD 3 horoscope/Cancer name/Cleon` (sequence doesn't matter) +- `editD 3 name/Cleon` (editing 1 metric) +- `editD 3 name/Cleon horoscope/Cancer` (editing 2 metrics) +- `editD 3 horoscope/Cancer name/Cleon` (sequence doesn't matter) Expected Output: `The date information has been successfully updated!` diff --git a/src/main/java/seedu/lovebook/logic/Messages.java b/src/main/java/seedu/lovebook/logic/Messages.java index b99db497330..61a74208aaa 100644 --- a/src/main/java/seedu/lovebook/logic/Messages.java +++ b/src/main/java/seedu/lovebook/logic/Messages.java @@ -43,6 +43,8 @@ public static String format(Date date) { .append(date.getGender()) .append("; Height: ") .append(date.getHeight()) + .append("; Income: ") + .append(date.getIncome()) .append("; Tags: "); date.getTags().forEach(builder::append); return builder.toString(); diff --git a/src/main/java/seedu/lovebook/logic/commands/AddCommand.java b/src/main/java/seedu/lovebook/logic/commands/AddCommand.java index cc19a80790c..bd31f7e6e46 100644 --- a/src/main/java/seedu/lovebook/logic/commands/AddCommand.java +++ b/src/main/java/seedu/lovebook/logic/commands/AddCommand.java @@ -1,11 +1,7 @@ package seedu.lovebook.logic.commands; import static java.util.Objects.requireNonNull; -import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_AGE; -import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_GENDER; -import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_HEIGHT; -import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_NAME; -import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_TAG; +import static seedu.lovebook.logic.parser.CliSyntax.*; import seedu.lovebook.commons.util.ToStringBuilder; import seedu.lovebook.logic.Messages; @@ -26,12 +22,14 @@ public class AddCommand extends Command { + PREFIX_AGE + "AGE " + PREFIX_GENDER + "GENDER " + PREFIX_HEIGHT + "HEIGHT " + + PREFIX_INCOME + "INCOME " + "[" + PREFIX_TAG + "TAG]...\n" + "Example: " + COMMAND_WORD + " " + PREFIX_NAME + "John Doe " + PREFIX_AGE + "21 " + PREFIX_GENDER + "M " + PREFIX_HEIGHT + "23124 " + + PREFIX_INCOME + "3000 " + PREFIX_TAG + "friends " + PREFIX_TAG + "owesMoney"; diff --git a/src/main/java/seedu/lovebook/logic/commands/EditCommand.java b/src/main/java/seedu/lovebook/logic/commands/EditCommand.java index 2ed361a48da..a4aef53225d 100644 --- a/src/main/java/seedu/lovebook/logic/commands/EditCommand.java +++ b/src/main/java/seedu/lovebook/logic/commands/EditCommand.java @@ -1,11 +1,7 @@ package seedu.lovebook.logic.commands; import static java.util.Objects.requireNonNull; -import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_AGE; -import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_GENDER; -import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_HEIGHT; -import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_NAME; -import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_TAG; +import static seedu.lovebook.logic.parser.CliSyntax.*; import static seedu.lovebook.model.Model.PREDICATE_SHOW_ALL_PERSONS; import java.util.Collections; @@ -21,11 +17,7 @@ import seedu.lovebook.logic.Messages; import seedu.lovebook.logic.commands.exceptions.CommandException; import seedu.lovebook.model.Model; -import seedu.lovebook.model.person.Age; -import seedu.lovebook.model.person.Date; -import seedu.lovebook.model.person.Gender; -import seedu.lovebook.model.person.Height; -import seedu.lovebook.model.person.Name; +import seedu.lovebook.model.person.*; import seedu.lovebook.model.tag.Tag; /** @@ -43,6 +35,7 @@ public class EditCommand extends Command { + "[" + PREFIX_AGE + "AGE] " + "[" + PREFIX_GENDER + "GENDER] " + "[" + PREFIX_HEIGHT + "HEIGHT] " + + "[" + PREFIX_INCOME + "INCOME] " + "[" + PREFIX_TAG + "TAG]...\n" + "Example: " + COMMAND_WORD + " 1 " + PREFIX_AGE + "91234567 " @@ -99,9 +92,10 @@ private static Date createEditedPerson(Date dateToEdit, EditPersonDescriptor edi Age updatedAge = editPersonDescriptor.getAge().orElse(dateToEdit.getAge()); Gender updatedGender = editPersonDescriptor.getGender().orElse(dateToEdit.getGender()); Height updatedHeight = editPersonDescriptor.getHeight().orElse(dateToEdit.getHeight()); + Income updatedIncome = editPersonDescriptor.getIncome().orElse(dateToEdit.getIncome()); Set updatedTags = editPersonDescriptor.getTags().orElse(dateToEdit.getTags()); - return new Date(updatedName, updatedAge, updatedGender, updatedHeight, updatedTags); + return new Date(updatedName, updatedAge, updatedGender, updatedHeight, updatedIncome, updatedTags); } @Override @@ -137,6 +131,7 @@ public static class EditPersonDescriptor { private Age age; private Gender gender; private Height height; + private Income income; private Set tags; public EditPersonDescriptor() {} @@ -150,6 +145,7 @@ public EditPersonDescriptor(EditPersonDescriptor toCopy) { setAge(toCopy.age); setGender(toCopy.gender); setHeight(toCopy.height); + setIncome(toCopy.income); setTags(toCopy.tags); } @@ -188,10 +184,18 @@ public void setHeight(Height height) { this.height = height; } + public void setIncome(Income income) { + this.income = income; + } + public Optional getHeight() { return Optional.ofNullable(height); } + public Optional getIncome() { + return Optional.ofNullable(income); + } + /** * Sets {@code tags} to this object's {@code tags}. * A defensive copy of {@code tags} is used internally. @@ -225,6 +229,7 @@ public boolean equals(Object other) { && Objects.equals(age, otherEditPersonDescriptor.age) && Objects.equals(gender, otherEditPersonDescriptor.gender) && Objects.equals(height, otherEditPersonDescriptor.height) + && Objects.equals(income, otherEditPersonDescriptor.income) && Objects.equals(tags, otherEditPersonDescriptor.tags); } @@ -235,6 +240,7 @@ public String toString() { .add("age", age) .add("gender", gender) .add("height", height) + .add("income", income) .add("tags", tags) .toString(); } diff --git a/src/main/java/seedu/lovebook/logic/parser/AddCommandParser.java b/src/main/java/seedu/lovebook/logic/parser/AddCommandParser.java index a90784249c0..f646d1f5936 100644 --- a/src/main/java/seedu/lovebook/logic/parser/AddCommandParser.java +++ b/src/main/java/seedu/lovebook/logic/parser/AddCommandParser.java @@ -1,22 +1,14 @@ package seedu.lovebook.logic.parser; import static seedu.lovebook.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; -import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_AGE; -import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_GENDER; -import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_HEIGHT; -import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_NAME; -import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_TAG; +import static seedu.lovebook.logic.parser.CliSyntax.*; import java.util.Set; import java.util.stream.Stream; import seedu.lovebook.logic.commands.AddCommand; import seedu.lovebook.logic.parser.exceptions.ParseException; -import seedu.lovebook.model.person.Age; -import seedu.lovebook.model.person.Date; -import seedu.lovebook.model.person.Gender; -import seedu.lovebook.model.person.Height; -import seedu.lovebook.model.person.Name; +import seedu.lovebook.model.person.*; import seedu.lovebook.model.tag.Tag; /** @@ -31,21 +23,23 @@ public class AddCommandParser implements Parser { */ public AddCommand parse(String args) throws ParseException { ArgumentMultimap argMultimap = - ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_AGE, PREFIX_GENDER, PREFIX_HEIGHT, PREFIX_TAG); + ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_AGE, PREFIX_GENDER, PREFIX_HEIGHT, PREFIX_INCOME, + PREFIX_TAG); - if (!arePrefixesPresent(argMultimap, PREFIX_NAME, PREFIX_HEIGHT, PREFIX_AGE, PREFIX_GENDER) + if (!arePrefixesPresent(argMultimap, PREFIX_NAME, PREFIX_HEIGHT, PREFIX_AGE, PREFIX_GENDER, PREFIX_INCOME) || !argMultimap.getPreamble().isEmpty()) { throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE)); } - argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME, PREFIX_AGE, PREFIX_GENDER, PREFIX_HEIGHT); + argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME, PREFIX_AGE, PREFIX_GENDER, PREFIX_HEIGHT, PREFIX_INCOME); Name name = ParserUtil.parseName(argMultimap.getValue(PREFIX_NAME).get()); Age age = ParserUtil.parseAge(argMultimap.getValue(PREFIX_AGE).get()); Gender gender = ParserUtil.parseGender(argMultimap.getValue(PREFIX_GENDER).get()); Height height = ParserUtil.parseAddress(argMultimap.getValue(PREFIX_HEIGHT).get()); + Income income = ParserUtil.parseIncome(argMultimap.getValue(PREFIX_INCOME).get()); Set tagList = ParserUtil.parseTags(argMultimap.getAllValues(PREFIX_TAG)); - Date date = new Date(name, age, gender, height, tagList); + Date date = new Date(name, age, gender, height, income, tagList); return new AddCommand(date); } diff --git a/src/main/java/seedu/lovebook/logic/parser/CliSyntax.java b/src/main/java/seedu/lovebook/logic/parser/CliSyntax.java index a049474f963..39867e8e17b 100644 --- a/src/main/java/seedu/lovebook/logic/parser/CliSyntax.java +++ b/src/main/java/seedu/lovebook/logic/parser/CliSyntax.java @@ -10,6 +10,8 @@ public class CliSyntax { public static final Prefix PREFIX_AGE = new Prefix("age/"); public static final Prefix PREFIX_GENDER = new Prefix("gender/"); public static final Prefix PREFIX_HEIGHT = new Prefix("a/"); + + public static final Prefix PREFIX_INCOME = new Prefix("income/"); public static final Prefix PREFIX_TAG = new Prefix("t/"); } diff --git a/src/main/java/seedu/lovebook/logic/parser/ParserUtil.java b/src/main/java/seedu/lovebook/logic/parser/ParserUtil.java index a6e11df2bd1..4a4f7cc385d 100644 --- a/src/main/java/seedu/lovebook/logic/parser/ParserUtil.java +++ b/src/main/java/seedu/lovebook/logic/parser/ParserUtil.java @@ -9,10 +9,7 @@ import seedu.lovebook.commons.core.index.Index; import seedu.lovebook.commons.util.StringUtil; import seedu.lovebook.logic.parser.exceptions.ParseException; -import seedu.lovebook.model.person.Age; -import seedu.lovebook.model.person.Gender; -import seedu.lovebook.model.person.Height; -import seedu.lovebook.model.person.Name; +import seedu.lovebook.model.person.*; import seedu.lovebook.model.tag.Tag; /** @@ -65,6 +62,21 @@ public static Age parseAge(String age) throws ParseException { return new Age(trimmedAge); } + /** + * Parses a {@code String gender} into an {@code Gender}. + * Leading and trailing whitespaces will be trimmed. + * + * @throws ParseException if the given {@code gender} is invalid. + */ + public static Gender parseGender(String gender) throws ParseException { + requireNonNull(gender); + String trimmedGender = gender.trim(); + if (!Gender.isValidGender(trimmedGender)) { + throw new ParseException(Gender.MESSAGE_CONSTRAINTS); + } + return new Gender(trimmedGender); + } + /** * Parses a {@code String lovebook} into an {@code Height}. * Leading and trailing whitespaces will be trimmed. @@ -81,20 +93,21 @@ public static Height parseAddress(String height) throws ParseException { } /** - * Parses a {@code String gender} into an {@code Gender}. + * Parses a {@code String income} into an {@code Income}. * Leading and trailing whitespaces will be trimmed. * - * @throws ParseException if the given {@code gender} is invalid. + * @throws ParseException if the given {@code lovebook} is invalid. */ - public static Gender parseGender(String gender) throws ParseException { - requireNonNull(gender); - String trimmedGender = gender.trim(); - if (!Gender.isValidGender(trimmedGender)) { - throw new ParseException(Gender.MESSAGE_CONSTRAINTS); + public static Income parseIncome(String income) throws ParseException { + requireNonNull(income); + String trimmedIncome = income.trim(); + if (!Height.isValidHeight(trimmedIncome)) { + throw new ParseException(Height.MESSAGE_CONSTRAINTS); } - return new Gender(trimmedGender); + return new Income(income); } + /** * Parses a {@code String tag} into a {@code Tag}. * Leading and trailing whitespaces will be trimmed. diff --git a/src/main/java/seedu/lovebook/model/person/Date.java b/src/main/java/seedu/lovebook/model/person/Date.java index f1893b1ea42..1eda232acb9 100644 --- a/src/main/java/seedu/lovebook/model/person/Date.java +++ b/src/main/java/seedu/lovebook/model/person/Date.java @@ -23,17 +23,20 @@ public class Date { // Data fields private final Height height; + + private final Income income; private final Set tags = new HashSet<>(); /** * Every field must be present and not null. */ - public Date(Name name, Age age, Gender gender, Height height, Set tags) { + public Date(Name name, Age age, Gender gender, Height height, Income income, Set tags) { requireAllNonNull(name, age, gender, height, tags); this.name = name; this.age = age; this.gender = gender; this.height = height; + this.income = income; this.tags.addAll(tags); } @@ -45,6 +48,7 @@ public Date() { this.age = null; this.gender = null; this.height = null; + this.income = null; } public Name getName() { @@ -63,6 +67,10 @@ public Height getHeight() { return height; } + public Income getIncome() { + return income; + } + /** * Returns an immutable tag set, which throws {@code UnsupportedOperationException} * if modification is attempted. @@ -104,13 +112,14 @@ public boolean equals(Object other) { && age.equals(otherDate.age) && gender.equals(otherDate.gender) && height.equals(otherDate.height) + && income.equals(otherDate.income) && tags.equals(otherDate.tags); } @Override public int hashCode() { // use this method for custom fields hashing instead of implementing your own - return Objects.hash(name, age, gender, height, tags); + return Objects.hash(name, age, gender, height, income, tags); } @Override @@ -120,6 +129,7 @@ public String toString() { .add("age", age) .add("gender", gender) .add("height", height) + .add("income", income) .add("tags", tags) .toString(); } diff --git a/src/main/java/seedu/lovebook/model/person/Income.java b/src/main/java/seedu/lovebook/model/person/Income.java index a52d163db27..31026ee955c 100644 --- a/src/main/java/seedu/lovebook/model/person/Income.java +++ b/src/main/java/seedu/lovebook/model/person/Income.java @@ -1,7 +1,65 @@ package seedu.lovebook.model.person; +import static java.util.Objects.requireNonNull; +import static seedu.lovebook.commons.util.AppUtil.checkArgument; + /** * Represents the date's income in the lovebook book. */ public class Income { + + public static final String MESSAGE_CONSTRAINTS = "Income can only take on positive values" + + ", and it should not be blank"; + + /* + * The first character of the lovebook must not be a whitespace, + * otherwise " " (a blank string) becomes a valid input. + */ + public static final String VALIDATION_REGEX = "^[1-9]\\d*$"; + + public final String value; + + /** + * Constructs an {@code Income}. + * + * @param income A valid income that is a positive integer. + */ + public Income(String income) { + requireNonNull(income); + checkArgument(isValidIncome(income), MESSAGE_CONSTRAINTS); + value = income; + } + + /** + * Returns true if a given string is a valid gender. + */ + public static boolean isValidIncome(String test) { + return test.matches(VALIDATION_REGEX); + } + + @Override + public String toString() { + return value; + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof Income)) { + return false; + } + + Income otherIncome = (Income) other; + return value.equals(otherIncome.value); + } + + @Override + public int hashCode() { + return value.hashCode(); + } + } diff --git a/src/main/java/seedu/lovebook/storage/JsonAdaptedPerson.java b/src/main/java/seedu/lovebook/storage/JsonAdaptedPerson.java index 1d67f3bd70e..f28ce8a3649 100644 --- a/src/main/java/seedu/lovebook/storage/JsonAdaptedPerson.java +++ b/src/main/java/seedu/lovebook/storage/JsonAdaptedPerson.java @@ -10,11 +10,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import seedu.lovebook.commons.exceptions.IllegalValueException; -import seedu.lovebook.model.person.Age; -import seedu.lovebook.model.person.Date; -import seedu.lovebook.model.person.Gender; -import seedu.lovebook.model.person.Height; -import seedu.lovebook.model.person.Name; +import seedu.lovebook.model.person.*; import seedu.lovebook.model.tag.Tag; /** @@ -28,6 +24,7 @@ class JsonAdaptedPerson { private final String age; private final String gender; private final String height; + private final String income; private final List tags = new ArrayList<>(); /** @@ -36,11 +33,13 @@ class JsonAdaptedPerson { @JsonCreator public JsonAdaptedPerson(@JsonProperty("name") String name, @JsonProperty("age") String age, @JsonProperty("gender") String gender, @JsonProperty("height") String height, + @JsonProperty("income") String income, @JsonProperty("tags") List tags) { this.name = name; this.age = age; this.gender = gender; this.height = height; + this.income = income; if (tags != null) { this.tags.addAll(tags); } @@ -54,6 +53,7 @@ public JsonAdaptedPerson(Date source) { age = source.getAge().value; gender = source.getGender().value; height = source.getHeight().value; + income = source.getIncome().value; tags.addAll(source.getTags().stream() .map(JsonAdaptedTag::new) .collect(Collectors.toList())); @@ -102,8 +102,16 @@ public Date toModelType() throws IllegalValueException { } final Height modelHeight = new Height(height); + if (income == null) { + throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Income.class.getSimpleName())); + } + if (!Income.isValidIncome(income)) { + throw new IllegalValueException(Income.MESSAGE_CONSTRAINTS); + } + final Income modelIncome = new Income(income); + final Set modelTags = new HashSet<>(personTags); - return new Date(modelName, modelAge, modelGender, modelHeight, modelTags); + return new Date(modelName, modelAge, modelGender, modelHeight, modelIncome, modelTags); } } diff --git a/src/main/java/seedu/lovebook/ui/PersonCard.java b/src/main/java/seedu/lovebook/ui/PersonCard.java index 7f62463d134..529f84ad597 100644 --- a/src/main/java/seedu/lovebook/ui/PersonCard.java +++ b/src/main/java/seedu/lovebook/ui/PersonCard.java @@ -36,6 +36,9 @@ public class PersonCard extends UiPart { private Label age; @FXML private Label height; + + @FXML + private Label income; @FXML private Label gender; @FXML @@ -50,8 +53,9 @@ public PersonCard(Date date, int displayedIndex) { id.setText(displayedIndex + ". "); name.setText(date.getName().fullName); age.setText(date.getAge().value); - height.setText(date.getHeight().value); gender.setText(date.getGender().value); + height.setText(date.getHeight().value); + income.setText(date.getIncome().value); date.getTags().stream() .sorted(Comparator.comparing(tag -> tag.tagName)) .forEach(tag -> tags.getChildren().add(new Label(tag.tagName))); diff --git a/src/main/resources/view/PersonListCard.fxml b/src/main/resources/view/PersonListCard.fxml index 5034c5a6a4f..1be0a00a6fb 100644 --- a/src/main/resources/view/PersonListCard.fxml +++ b/src/main/resources/view/PersonListCard.fxml @@ -29,8 +29,9 @@