diff --git a/src/main/java/seedu/address/logic/commands/AddOrganizationCommand.java b/src/main/java/seedu/address/logic/commands/AddOrganizationCommand.java deleted file mode 100644 index c12f5cd4233..00000000000 --- a/src/main/java/seedu/address/logic/commands/AddOrganizationCommand.java +++ /dev/null @@ -1,14 +0,0 @@ -package seedu.address.logic.commands; - -import seedu.address.model.person.Contact; - -/** - * Adds an organisation to the address book. - */ -public class AddOrganizationCommand extends AddCommand { - - public AddOrganizationCommand(Contact contact) { - super(contact); - } - -} diff --git a/src/main/java/seedu/address/logic/parser/AddCommandParser.java b/src/main/java/seedu/address/logic/parser/AddCommandParser.java index 42e398ddd8d..3ac767b5dd9 100644 --- a/src/main/java/seedu/address/logic/parser/AddCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/AddCommandParser.java @@ -18,7 +18,6 @@ import java.util.Set; import seedu.address.logic.commands.AddCommand; -import seedu.address.logic.commands.AddOrganizationCommand; import seedu.address.logic.parser.exceptions.ParseException; import seedu.address.model.person.Address; import seedu.address.model.person.Contact; @@ -63,7 +62,7 @@ public AddCommand parse(String args) throws ParseException { if (argMultimap.hasFlag(FLAG_ORGANIZATION)) { Organization organization = parseAsOrganization(argMultimap); - return new AddOrganizationCommand(organization); + return new AddCommand(organization); } else if (argMultimap.hasFlag(FLAG_RECRUITER)) { Recruiter recruiter = parseAsRecruiter(argMultimap); return new AddCommand(recruiter); @@ -136,7 +135,8 @@ private Organization parseAsOrganization(ArgumentMultimap argMultimap) throws Pa Status status = ParserUtil.parseOptionally( argMultimap.getValue(FLAG_STATUS), ParserUtil::parseStatus); Set tagList = ParserUtil.parseTags(argMultimap.getAllValues(FLAG_TAG)); + Set ridList = Set.of(); // TODO: This should be dynamically determined from oid in Recruiter. - return new Organization(name, id, phone, email, url, address, tagList, status, position); + return new Organization(name, id, phone, email, url, address, tagList, status, position, ridList); } } diff --git a/src/main/java/seedu/address/logic/parser/CliSyntax.java b/src/main/java/seedu/address/logic/parser/CliSyntax.java index 102e770c62b..72f0f75c279 100644 --- a/src/main/java/seedu/address/logic/parser/CliSyntax.java +++ b/src/main/java/seedu/address/logic/parser/CliSyntax.java @@ -19,5 +19,7 @@ public class CliSyntax { public static final Flag FLAG_ID = new Flag("id"); public static final Flag FLAG_RECURSIVE = new Flag("recursive"); public static final Flag FLAG_ORGANIZATION_ID = new Flag("oid"); + public static final Flag FLAG_RECRUITER_ID = new Flag("rid"); + } diff --git a/src/main/java/seedu/address/logic/parser/ParserUtil.java b/src/main/java/seedu/address/logic/parser/ParserUtil.java index 851c6b6b13e..e8208634970 100644 --- a/src/main/java/seedu/address/logic/parser/ParserUtil.java +++ b/src/main/java/seedu/address/logic/parser/ParserUtil.java @@ -188,6 +188,19 @@ public static Set parseTags(Collection tags) throws ParseException return tagSet; } + /** + * Parses {@code Collection ids} into a {@code Set}. + */ + public static Set parseIds(Collection ids) throws ParseException { + requireNonNull(ids); + final Set idSet = new HashSet<>(); + for (String idName : ids) { + idSet.add(parseId(idName)); + } + return idSet; + } + + /** * References a function that parses a string into an expected output within the {@link ParserUtil} utility class. * @param The return result. diff --git a/src/main/java/seedu/address/model/person/Organization.java b/src/main/java/seedu/address/model/person/Organization.java index f7474dee3d6..179ff241e7d 100644 --- a/src/main/java/seedu/address/model/person/Organization.java +++ b/src/main/java/seedu/address/model/person/Organization.java @@ -1,5 +1,7 @@ package seedu.address.model.person; +import java.util.Collections; +import java.util.HashSet; import java.util.Objects; import java.util.Optional; import java.util.Set; @@ -18,6 +20,9 @@ public class Organization extends Contact { private final Optional status; private final Optional position; + private final Set rids = new HashSet<>(); + + /** * Name and id fields must be non-null. * Tags must be non-null but can be empty as well. @@ -25,11 +30,13 @@ public class Organization extends Contact { */ public Organization( Name name, Id id, Phone phone, Email email, Url url, - Address address, Set tags, Status status, Position position + Address address, Set tags, Status status, Position position, + Set rids ) { super(name, id, phone, email, url, address, tags); this.status = Optional.ofNullable(status); this.position = Optional.ofNullable(position); + this.rids.addAll(rids); } @Override @@ -45,6 +52,13 @@ public Optional getPosition() { return position; } + /** + * Returns an immutable tag set, which throws {@code UnsupportedOperationException} + * if modification is attempted. + */ + public Set getRecruiterIds() { + return Collections.unmodifiableSet(rids); + } @Override public boolean equals(Object other) { if (other == this) { diff --git a/src/main/java/seedu/address/model/util/SampleDataUtil.java b/src/main/java/seedu/address/model/util/SampleDataUtil.java index 9878dba1a01..9c52297a5ac 100644 --- a/src/main/java/seedu/address/model/util/SampleDataUtil.java +++ b/src/main/java/seedu/address/model/util/SampleDataUtil.java @@ -65,4 +65,13 @@ public static Set getTagSet(String... strings) { .collect(Collectors.toSet()); } + /** + * Returns a id set containing the list of strings given. + */ + public static Set getIdSet(String... strings) { + return Arrays.stream(strings) + .map(Id::new) + .collect(Collectors.toSet()); + } + } diff --git a/src/main/java/seedu/address/storage/JsonAdaptedContact.java b/src/main/java/seedu/address/storage/JsonAdaptedContact.java index 6ce8be7cec0..83d78726fed 100644 --- a/src/main/java/seedu/address/storage/JsonAdaptedContact.java +++ b/src/main/java/seedu/address/storage/JsonAdaptedContact.java @@ -44,6 +44,7 @@ class JsonAdaptedContact { private String oid; private final List tags = new ArrayList<>(); + /** * Constructs a {@code JsonAdaptedContact} with the given contact details. */ @@ -158,6 +159,8 @@ public Contact toModelType() throws IllegalValueException { switch (modelType) { case ORGANIZATION: { + final Set modelRids = new HashSet<>(); + if (status != null && !Status.isValidStatus(status)) { throw new IllegalValueException(Status.MESSAGE_CONSTRAINTS); } @@ -170,7 +173,7 @@ public Contact toModelType() throws IllegalValueException { return new Organization( modelName, modelId, modelPhone, modelEmail, modelUrl, modelAddress, - modelTags, modelStatus, modelPosition + modelTags, modelStatus, modelPosition, modelRids ); } case RECRUITER: { diff --git a/src/main/java/seedu/address/storage/JsonAdaptedId.java b/src/main/java/seedu/address/storage/JsonAdaptedId.java new file mode 100644 index 00000000000..6e4ac8102dc --- /dev/null +++ b/src/main/java/seedu/address/storage/JsonAdaptedId.java @@ -0,0 +1,49 @@ +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.person.Id; + +/** + * Jackson-friendly version of {@link Id}. + */ +class JsonAdaptedId { + + private final String idName; + + /** + * Constructs a {@code JsonAdaptedId} with the given {@code idName}. + */ + @JsonCreator + public JsonAdaptedId(String idName) { + this.idName = idName; + } + + /** + * Converts a given {@code Id} into this class for Jackson use. + */ + public JsonAdaptedId(Id source) { + idName = source.value; + } + + @JsonValue + public String getIdName() { + return idName; + } + + /** + * Converts this Jackson-friendly adapted tag object into the model's {@code Id} object. + * + * @throws IllegalValueException if there were any data constraints violated in the adapted tag. + */ + public Id toModelType() throws IllegalValueException { + if (!Id.isValidId(idName)) { + throw new IllegalValueException(Id.MESSAGE_CONSTRAINTS); + } + return new Id(idName); + } + +} + diff --git a/src/test/java/seedu/address/model/person/OrganizationTest.java b/src/test/java/seedu/address/model/person/OrganizationTest.java new file mode 100644 index 00000000000..c1534f339d7 --- /dev/null +++ b/src/test/java/seedu/address/model/person/OrganizationTest.java @@ -0,0 +1,106 @@ +package seedu.address.model.person; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB; +import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_BOB; +import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_BOB; +import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB; +import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND; +import static seedu.address.testutil.Assert.assertThrows; +import static seedu.address.testutil.TypicalContacts.ALICE; +import static seedu.address.testutil.TypicalContacts.BOB; + +import org.junit.jupiter.api.Test; + +import seedu.address.testutil.ContactBuilder; + +public class OrganizationTest { + + @Test + public void asObservableList_modifyList_throwsUnsupportedOperationException() { + Contact contact = new ContactBuilder().build(); + assertThrows(UnsupportedOperationException.class, () -> contact.getTags().remove(0)); + } + + @Test + public void isSameContact() { + // same object -> returns true + assertTrue(ALICE.isSameContact(ALICE)); + + // null -> returns false + assertFalse(ALICE.isSameContact(null)); + + // same name, all other attributes different -> returns true + Contact editedAlice = new ContactBuilder(ALICE).withPhone(VALID_PHONE_BOB).withEmail(VALID_EMAIL_BOB) + .withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND).build(); + assertTrue(ALICE.isSameContact(editedAlice)); + + // different name, all other attributes same -> returns false + editedAlice = new ContactBuilder(ALICE).withName(VALID_NAME_BOB).build(); + assertFalse(ALICE.isSameContact(editedAlice)); + + // name differs in case, all other attributes same -> returns false + Contact editedBob = new ContactBuilder(BOB).withName(VALID_NAME_BOB.toLowerCase()).build(); + assertFalse(BOB.isSameContact(editedBob)); + + // name has trailing spaces, all other attributes same -> returns false + String nameWithTrailingSpaces = VALID_NAME_BOB + " "; + editedBob = new ContactBuilder(BOB).withName(nameWithTrailingSpaces).build(); + assertFalse(BOB.isSameContact(editedBob)); + } + + @Test + public void equals() { + // same values -> returns true + Contact aliceCopy = new ContactBuilder(ALICE).build(); + assertTrue(ALICE.equals(aliceCopy)); + + // same object -> returns true + assertTrue(ALICE.equals(ALICE)); + + // null -> returns false + assertFalse(ALICE.equals(null)); + + // different type -> returns false + assertFalse(ALICE.equals(5)); + + // different contact -> returns false + assertFalse(ALICE.equals(BOB)); + + // different name -> returns false + Contact editedAlice = new ContactBuilder(ALICE).withName(VALID_NAME_BOB).build(); + assertFalse(ALICE.equals(editedAlice)); + + // different phone -> returns false + editedAlice = new ContactBuilder(ALICE).withPhone(VALID_PHONE_BOB).build(); + assertFalse(ALICE.equals(editedAlice)); + + // different email -> returns false + editedAlice = new ContactBuilder(ALICE).withEmail(VALID_EMAIL_BOB).build(); + assertFalse(ALICE.equals(editedAlice)); + + // different address -> returns false + editedAlice = new ContactBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).build(); + assertFalse(ALICE.equals(editedAlice)); + + // different tags -> returns false + editedAlice = new ContactBuilder(ALICE).withTags(VALID_TAG_HUSBAND).build(); + assertFalse(ALICE.equals(editedAlice)); + } + + @Test + public void toStringMethod() { + String expected = Contact.class.getCanonicalName() + + "{name=" + ALICE.getName() + + ", type=" + ALICE.getType() + + ", id=" + ALICE.getId() + + ", phone=" + ALICE.getPhone() + + ", email=" + ALICE.getEmail() + + ", url=" + ALICE.getUrl() + + ", address=" + ALICE.getAddress() + + ", tags=" + ALICE.getTags() + "}"; + assertEquals(expected, ALICE.toString()); + } +} diff --git a/src/test/java/seedu/address/storage/JsonAdaptedContactTest.java b/src/test/java/seedu/address/storage/JsonAdaptedContactTest.java index 7c9b701f4cd..812c85e57ef 100644 --- a/src/test/java/seedu/address/storage/JsonAdaptedContactTest.java +++ b/src/test/java/seedu/address/storage/JsonAdaptedContactTest.java @@ -5,6 +5,7 @@ import static seedu.address.storage.JsonAdaptedContact.MISSING_FIELD_MESSAGE_FORMAT; import static seedu.address.testutil.Assert.assertThrows; import static seedu.address.testutil.TypicalContacts.BENSON; +import static seedu.address.testutil.TypicalContacts.JESUS; import java.util.ArrayList; import java.util.List; @@ -41,11 +42,15 @@ public class JsonAdaptedContactTest { private static final String VALID_URL = BENSON.getUrl().get().value; private static final String VALID_ADDRESS = BENSON.getAddress().get().value; private static final String VALID_OID = "78a36caf-6d42-4fd2-a017-7f6a92fa3155"; - private static final List VALID_TAGS = BENSON.getTags().stream() .map(JsonAdaptedTag::new) .collect(Collectors.toList()); + + private static final List VALID_RIDS = JESUS.getRecruiterIds().stream() + .map(JsonAdaptedId::new) + .collect(Collectors.toList()); + @Test public void toModelType_validContactDetails_returnsContact() throws Exception { JsonAdaptedContact person = new JsonAdaptedContact(BENSON); diff --git a/src/test/java/seedu/address/testutil/ContactBuilder.java b/src/test/java/seedu/address/testutil/ContactBuilder.java index 3ddb559290b..a8e8ff8280e 100644 --- a/src/test/java/seedu/address/testutil/ContactBuilder.java +++ b/src/test/java/seedu/address/testutil/ContactBuilder.java @@ -9,7 +9,6 @@ import seedu.address.model.person.Id; import seedu.address.model.person.Name; import seedu.address.model.person.Phone; -import seedu.address.model.person.Status; import seedu.address.model.person.Url; import seedu.address.model.tag.Tag; import seedu.address.model.util.SampleDataUtil; @@ -25,7 +24,6 @@ public class ContactBuilder { public static final String DEFAULT_EMAIL = "amy@gmail.com"; public static final String DEFAULT_URL = "www.google.com"; public static final String DEFAULT_ADDRESS = "123, Jurong West Ave 6, #08-111"; - public static final String DEFAULT_STATUS = "Applied"; private Name name; private Id id; @@ -33,7 +31,6 @@ public class ContactBuilder { private Email email; private Url url; private Address address; - private Status status; private Set tags; /** @@ -46,7 +43,6 @@ public ContactBuilder() { email = new Email(DEFAULT_EMAIL); url = new Url(DEFAULT_URL); address = new Address(DEFAULT_ADDRESS); - status = new Status(DEFAULT_STATUS); tags = new HashSet<>(); } @@ -79,13 +75,7 @@ public ContactBuilder withId(String id) { return this; } - /** - * Sets the {@code Status} of the {@code Contact} that we are building. - */ - public ContactBuilder withStatus(String status) { - this.status = status == null ? null : new Status(status); - return this; - } + /** * Parses the {@code tags} into a {@code Set} and set it to the {@code Contact} that we are building. diff --git a/src/test/java/seedu/address/testutil/OrganizationBuilder.java b/src/test/java/seedu/address/testutil/OrganizationBuilder.java new file mode 100644 index 00000000000..ba5480887ca --- /dev/null +++ b/src/test/java/seedu/address/testutil/OrganizationBuilder.java @@ -0,0 +1,118 @@ +package seedu.address.testutil; + +import java.util.HashSet; +import java.util.Set; + +import seedu.address.model.person.Contact; +import seedu.address.model.person.Id; +import seedu.address.model.person.Organization; +import seedu.address.model.person.Position; +import seedu.address.model.person.Status; +import seedu.address.model.util.SampleDataUtil; + +/** + * A utility class to help with building Organization objects. + */ +public class OrganizationBuilder extends ContactBuilder { + public static final String DEFAULT_STATUS = "Applied"; + public static final String DEFAULT_POSITION = "Manager"; + private Position position; + private Set rids; + private Status status; + + + /** + * Creates a {@code OrganizationBuilder} with the default details. + */ + public OrganizationBuilder() { + super(); + position = new Position(DEFAULT_POSITION); + status = new Status(DEFAULT_STATUS); + rids = new HashSet<>(); + } + + /** + * Initializes the OrganizationBuilder with the data of {@code organizationToCopy}. + */ + public OrganizationBuilder(Organization organizationToCopy) { + super(organizationToCopy); + } + + @Override + public OrganizationBuilder withId(String id) { + return (OrganizationBuilder) super.withId(id); + } + + @Override + public OrganizationBuilder withAddress(String address) { + return (OrganizationBuilder) super.withAddress(address); + } + + @Override + public OrganizationBuilder withEmail(String email) { + return (OrganizationBuilder) super.withEmail(email); + } + + @Override + public OrganizationBuilder withName(String name) { + return (OrganizationBuilder) super.withName(name); + } + + @Override + public OrganizationBuilder withPhone(String phone) { + return (OrganizationBuilder) super.withPhone(phone); + } + + @Override + public OrganizationBuilder withTags(String... tags) { + return (OrganizationBuilder) super.withTags(tags); + } + + @Override + public OrganizationBuilder withUrl(String url) { + return (OrganizationBuilder) super.withUrl(url); + } + + /** + * Parses the {@code tags} into a {@code Set} and set it to the {@code Contact} that we are building. + */ + public OrganizationBuilder withRids(String ... rids) { + this.rids = SampleDataUtil.getIdSet(rids); + return this; + } + + + /** + * Sets the {@code Status} of the {@code Contact} that we are building. + */ + public OrganizationBuilder withStatus(String status) { + this.status = new Status(status); + return this; + } + + /** + * Sets the {@code Status} of the {@code Contact} that we are building. + */ + public OrganizationBuilder withPosition(String position) { + this.status = new Status(position); + return this; + } + + @Override + public Organization build() { + Contact contact = super.build(); + return new Organization( + contact.getName(), + contact.getId(), + contact.getPhone().orElse(null), + contact.getEmail().orElse(null), + contact.getUrl().orElse(null), + contact.getAddress().orElse(null), + contact.getTags(), + status, + position, + rids + ); + } + +} diff --git a/src/test/java/seedu/address/testutil/TypicalContacts.java b/src/test/java/seedu/address/testutil/TypicalContacts.java index 3a6248d9c83..fce9e83d7c6 100644 --- a/src/test/java/seedu/address/testutil/TypicalContacts.java +++ b/src/test/java/seedu/address/testutil/TypicalContacts.java @@ -21,6 +21,7 @@ import seedu.address.model.AddressBook; import seedu.address.model.person.Contact; +import seedu.address.model.person.Organization; /** * A utility class containing a list of {@code Contact} objects to be used in tests. @@ -41,7 +42,6 @@ public class TypicalContacts { .withAddress("311, Clementi Ave 2, #02-25") .withEmail("johnd@example.com") .withPhone("98765432") - .withStatus("Applied") .withTags("owesMoney", "friends").build(); public static final Contact CARL = new ContactBuilder() .withName("Carl Kurz") @@ -75,6 +75,15 @@ public class TypicalContacts { .withEmail("anna@example.com") .withAddress("4th street").build(); + public static final Organization JESUS = new OrganizationBuilder() + .withName("Jesus Christ") + .withId("test_7-123") + .withPhone("9482442") + .withEmail("anna@example.com") + .withAddress("4th street") + .withRids("cat") + .build(); + // Manually added public static final Contact HOON = new ContactBuilder().withName("Hoon Meier").withPhone("8482424") .withEmail("stefan@example.com").withAddress("little india").build();