Skip to content

Commit

Permalink
Merge pull request #153 from kohkaijie/new-tags
Browse files Browse the repository at this point in the history
Add special tags for doctors and patients
  • Loading branch information
Mohammed-Faizzzz committed Nov 2, 2023
2 parents 2f1dc7e + 7150975 commit 1da56dc
Show file tree
Hide file tree
Showing 28 changed files with 417 additions and 151 deletions.
42 changes: 42 additions & 0 deletions src/main/java/seedu/address/logic/commands/EditCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,23 @@ private Person getPersonToEdit(Model model) throws CommandException {
private Person getEditedPerson(Model model, Person personToEdit) throws CommandException {
Person editedPerson;
if (personToEdit instanceof Patient) {
if (editPersonDescriptor.getTags().isPresent()
&& !editPersonDescriptor.isValidPatientTagList(editPersonDescriptor.getTags().get())) {
logger.warning("Invalid tag for patient");
throw new CommandException("Please enter a valid patient tag.");
}
editedPerson = createEditedPatient((Patient) personToEdit, editPersonDescriptor);
} else {
assert personToEdit.isDoctor();
if (editPersonDescriptor.getCondition().isPresent() || editPersonDescriptor.getBloodType().isPresent()) {
logger.warning("Error thrown - tried to edit condition / bloodtype of doctor");
throw new CommandException("Doctors cannot have Condition or BloodType fields.");
}
if (editPersonDescriptor.getTags().isPresent()
&& !editPersonDescriptor.isValidDoctorTagList(editPersonDescriptor.getTags().get())) {
logger.warning(editPersonDescriptor.getTags().toString());
throw new CommandException("Please enter valid Doctor tags.");
}
editedPerson = createEditedDoctor((Doctor) personToEdit, editPersonDescriptor);
}
if (!personToEdit.isSamePerson(editedPerson) && model.hasPerson(editedPerson)) {
Expand Down Expand Up @@ -343,6 +353,38 @@ public Optional<BloodType> getBloodType() {
return Optional.ofNullable(bloodType);
}

/**
* Ensures the set of tags contains only valid patient tags.
*
* @param tagSet The set of tags to be validated.
* @return true if the tag set is valid (contains zero or one valid patient tag), false otherwise.
*/
public boolean isValidPatientTagList(Set<Tag> tagSet) {
if (tagSet.size() > 1) {
return false;
}
for (Tag tag : tagSet) {
if (!tag.isValidPatientTag()) {
return false;
}
}
return true;
}

/**
* Ensures the set of tags contains only valid doctor tags.
*
* @param tagSet The set of tags to be validated.
* @return true if the tag set is valid (contains no duplicate doctor tags), false otherwise.
*/
public boolean isValidDoctorTagList(Set<Tag> tagSet) {
for (Tag tag : tagSet) {
if (!tag.isValidDoctorTag()) {
return false;
}
}
return true;
}

/**
* Sets {@code tags} to this object's {@code tags}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public AddDoctorCommand parse(String userInput) throws ParseException {
Remark remark = new Remark(""); // add command does not allow adding remarks straight away
Gender gender = ParserUtil.parseGender(argMultimap.getValue(PREFIX_GENDER).get());
Ic ic = ParserUtil.parseIc(argMultimap.getValue(PREFIX_NRIC).get());
Set<Tag> tagList = ParserUtil.parseTags(argMultimap.getAllValues(PREFIX_TAG));
Set<Tag> tagList = ParserUtil.parseDoctorTags(argMultimap.getAllValues(PREFIX_TAG));
// appointments need to be added separately, so we initialise doctors with empty appointments
Set<Appointment> appointmentList = new HashSet<>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public AddPatientCommand parse(String args) throws ParseException {
throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddPatientCommand.MESSAGE_USAGE));
}

argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS,
argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS, PREFIX_TAG,
PREFIX_GENDER, PREFIX_NRIC, PREFIX_CONDITION, PREFIX_BLOODTYPE, PREFIX_EMERGENCY_CONTACT);
Name name = ParserUtil.parseName(argMultimap.getValue(PREFIX_NAME).get());
Phone phone = ParserUtil.parsePhone(argMultimap.getValue(PREFIX_PHONE).get());
Expand All @@ -71,7 +71,7 @@ public AddPatientCommand parse(String args) throws ParseException {
Ic ic = ParserUtil.parseIc(argMultimap.getValue(PREFIX_NRIC).get());
BloodType bloodType = ParserUtil.parseBloodType(argMultimap.getValue(PREFIX_BLOODTYPE).get());
Condition condition = ParserUtil.parseCondition(argMultimap.getValue(PREFIX_CONDITION).get());
Set<Tag> tagList = ParserUtil.parseTags(argMultimap.getAllValues(PREFIX_TAG));
Set<Tag> tagList = ParserUtil.parsePatientTags(argMultimap.getAllValues(PREFIX_TAG));
// appointments need to be added separately, so we initialise patients with empty appointments
Set<Appointment> appointmentList = new HashSet<>();
Patient patient =
Expand Down
115 changes: 106 additions & 9 deletions src/main/java/seedu/address/logic/parser/ParserUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -135,28 +135,125 @@ public static Gender parseGender(String gender) throws ParseException {
}

/**
* Parses a {@code String tag} into a {@code Tag}.
* Leading and trailing whitespaces will be trimmed.
* Parses a string to create a {@code Tag} object after processing the input string.
* The input string is trimmed and converted to uppercase. If the tag name is a valid
* patient tag name, it is prefixed with "priority: " before being used to create the tag.
*
* @throws ParseException if the given {@code tag} is invalid.
* @param tag The string to be parsed into a Tag object.
* @return A Tag object representing the input string.
* @throws NullPointerException if the tag parameter is null.
*/
public static Tag parseTag(String tag) throws ParseException {
public static Tag parseTag(String tag) {
requireNonNull(tag);
String trimmedTag = tag.trim();
if (!Tag.isValidTagName(trimmedTag)) {
throw new ParseException(Tag.MESSAGE_CONSTRAINTS);
String trimmedTag = tag.trim().toUpperCase();
if (Tag.isValidPatientTagName(trimmedTag)) {
trimmedTag = "priority: " + trimmedTag;
}
return new Tag(trimmedTag);
}

/**
* Parses {@code Collection<String> tags} into a {@code Set<Tag>}.
* Parses a collection of strings to create a set of {@code Tag} objects.
* Each string in the collection is processed to create a Tag. If a duplicate tag is found,
* a ParseException is thrown.
*
* @param tags The collection of strings to be parsed into Tag objects.
* @return A set of Tag objects.
* @throws ParseException if a duplicate tag is detected.
* @throws NullPointerException if the tags parameter is null.
*/
public static Set<Tag> parseTags(Collection<String> tags) throws ParseException {
requireNonNull(tags);
final Set<Tag> tagSet = new HashSet<>();
for (String tagName : tags) {
tagSet.add(parseTag(tagName));
Tag toAdd = parseTag(tagName);
if (tagSet.contains(toAdd)) {
throw new ParseException(Tag.DUPLICATE_TAG);
}
tagSet.add(toAdd);
}
return tagSet;
}

/**
* Parses a string to create a {@code Tag} object representing a patient tag.
* The tag name is validated to be a valid patient tag name, prefixed with "priority: ".
* If the tag name is not valid, a ParseException is thrown.
*
* @param tag The string to be parsed into a patient Tag object.
* @return A Tag object representing the patient tag.
* @throws ParseException if the tag name is not a valid patient tag name.
* @throws NullPointerException if the tag parameter is null.
*/
public static Tag parsePatientTag(String tag) throws ParseException {
requireNonNull(tag);
String trimmedTag = tag.trim().toUpperCase();
if (!Tag.isValidPatientTagName(trimmedTag)) {
throw new ParseException(Tag.INVALID_PATIENT_TAG);
}
return new Tag("priority: " + trimmedTag);
}

/**
* Parses a collection of strings to create a set of {@code Tag} objects representing patient tags.
* If more than one tag is provided, a ParseException is thrown since patients should only have one tag.
* Each tag is validated to be a proper patient tag.
*
* @param tags The collection of strings to be parsed into patient Tag objects.
* @return A set of Tag objects representing the patient tags.
* @throws ParseException if the collection contains more than one tag or if the tag is not valid.
* @throws NullPointerException if the tags parameter is null.
*/
public static Set<Tag> parsePatientTags(Collection<String> tags) throws ParseException {
requireNonNull(tags);
final Set<Tag> tagSet = new HashSet<>();
if (tags.size() > 1) {
throw new ParseException(Tag.EXTRA_PATIENT_TAG);
}
for (String tagName : tags) {
tagSet.add(parsePatientTag(tagName));
}
return tagSet;
}

/**
* Parses a string to create a {@code Tag} object representing a doctor tag.
* The tag name is validated to be a valid doctor tag name. If the tag name is not valid,
* a ParseException is thrown.
*
* @param tag The string to be parsed into a doctor Tag object.
* @return A Tag object representing the doctor tag.
* @throws ParseException if the tag name is not a valid doctor tag name.
* @throws NullPointerException if the tag parameter is null.
*/
public static Tag parseDoctorTag(String tag) throws ParseException {
requireNonNull(tag);
String trimmedTag = tag.trim().toUpperCase();
if (!Tag.isValidDoctorTagName(trimmedTag)) {
throw new ParseException(Tag.INVALID_DOCTOR_TAG);
}
return new Tag(trimmedTag);
}

/**
* Parses a collection of strings to create a set of {@code Tag} objects representing doctor tags.
* Duplicate tags are not allowed, and if found, a ParseException is thrown.
* Each tag is validated to be a proper doctor tag.
*
* @param tags The collection of strings to be parsed into doctor Tag objects.
* @return A set of Tag objects representing the doctor tags.
* @throws ParseException if a duplicate tag is detected or if the tag is not valid.
* @throws NullPointerException if the tags parameter is null.
*/
public static Set<Tag> parseDoctorTags(Collection<String> tags) throws ParseException {
requireNonNull(tags);
final Set<Tag> tagSet = new HashSet<>();
for (String tagName : tags) {
Tag toAdd = parseDoctorTag(tagName);
if (tagSet.contains(toAdd)) {
throw new ParseException(Tag.DUPLICATE_TAG);
}
tagSet.add(toAdd);
}
return tagSet;
}
Expand Down
55 changes: 47 additions & 8 deletions src/main/java/seedu/address/model/tag/Tag.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
package seedu.address.model.tag;

import static java.util.Objects.requireNonNull;
import static seedu.address.commons.util.AppUtil.checkArgument;

/**
* Represents a Tag in the address book.
* Guarantees: immutable; name is valid as declared in {@link #isValidTagName(String)}
* Guarantees: immutable; name is valid as declared in {@link #isValidPatientTagName(String)}
*/
public class Tag {

public static final String MESSAGE_CONSTRAINTS = "Tags names should be alphanumeric";
public static final String VALIDATION_REGEX = "\\p{Alnum}+";
public static final String DUPLICATE_TAG = "Doctors should not have duplicate tags!";
public static final String EXTRA_PATIENT_TAG = "Each Patient should only have one priority tag!";
public static final String INVALID_PATIENT_TAG = "Patient tag should be a valid priority level: Low, Medium or"
+ " High.";
public static final String INVALID_DOCTOR_TAG = "Doctor tag should be a valid specialisation.";

public final String tagName;

Expand All @@ -21,15 +23,52 @@ public class Tag {
*/
public Tag(String tagName) {
requireNonNull(tagName);
checkArgument(isValidTagName(tagName), MESSAGE_CONSTRAINTS);
this.tagName = tagName;
}

/**
* Returns true if a given string is a valid tag name.
* Returns true if a given string is a valid patient tag name.
*/
public static boolean isValidTagName(String test) {
return test.matches(VALIDATION_REGEX);
public static boolean isValidPatientTagName(String test) {
for (ValidPatientTags tag : ValidPatientTags.values()) {
if (tag.name().equals(test)) {
return true;
}
}
return false;
}

/**
* Returns true if a given string is a valid patient tag name.
*/
public static boolean isValidFullPatientTagName(String test) {
for (ValidPatientTags tag : ValidPatientTags.values()) {
String fullTagName = "priority: " + tag;
if (fullTagName.equals(test)) {
return true;
}
}
return false;
}

/**
* Returns true if a given string is a valid doctor tag name.
*/
public static boolean isValidDoctorTagName(String test) {
for (ValidDoctorTags tag : ValidDoctorTags.values()) {
if (tag.name().equals(test)) {
return true;
}
}
return false;
}

public boolean isValidPatientTag() {
return isValidFullPatientTagName(tagName);
}

public boolean isValidDoctorTag() {
return isValidDoctorTagName(tagName);
}

@Override
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/seedu/address/model/tag/ValidDoctorTags.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package seedu.address.model.tag;

/**
* Enumeration of valid doctor specializations for doctor tags.
* These specializations are used to categorize doctors by their field of expertise.
*/
public enum ValidDoctorTags {
CARDIOLOGIST, ORTHOPEDIC, PEDIATRICIAN, DERMATOLOGIST, NEUROLOGIST, GENERAL_PRACTITIONER, PSYCHIATRIST, SURGEON
}
8 changes: 8 additions & 0 deletions src/main/java/seedu/address/model/tag/ValidPatientTags.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package seedu.address.model.tag;

/**
* Enumeration of valid priority levels for patient tags.
*/
public enum ValidPatientTags {
LOW, MEDIUM, HIGH
}
14 changes: 7 additions & 7 deletions src/main/java/seedu/address/model/util/SampleDataUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,42 +43,42 @@ public static Patient[] getSamplePatients() {
new Email("alexyeoh@example.com"), new Address("Blk 30 Geylang Street 29, #06-40"),
EMPTY_REMARK, new Gender("M"), new Ic("S1111111Z"), new Condition("Unknown"),
new BloodType("O+"), getAppointmentSet(APPOINTMENT_1, APPOINTMENT_2),
getTagSet("friends")),
getTagSet("priority: LOW")),
new Patient(new Name("Bernice Yu"), new Phone("99272758"), new Phone("87438807"),
new Email("berniceyu@example.com"), new Address("Blk 30 Lorong 3 Serangoon Gardens, #07-18"),
EMPTY_REMARK, new Gender("F"), new Ic("S1111112Z"), new Condition("Unknown"),
new BloodType("O+"), getAppointmentSet(APPOINTMENT_3),
getTagSet("colleagues", "friends")),
getTagSet("priority: LOW")),
new Patient(new Name("Charlotte Oliveiro"), new Phone("93210283"), new Phone("87438807"),
new Email("charlotte@example.com"), new Address("Blk 11 Ang Mo Kio Street 74, #11-04"),
EMPTY_REMARK, new Gender("F"), new Ic("S1111113Z"), new Condition("Unknown"),
new BloodType("O+"), EMPTY_APPOINTMENTS,
getTagSet("neighbours")),
getTagSet("priority: MEDIUM")),
new Patient(new Name("David Li"), new Phone("91031282"), new Phone("87438807"),
new Email("lidavid@example.com"), new Address("Blk 436 Serangoon Gardens Street 26, #16-43"),
EMPTY_REMARK, new Gender("M"), new Ic("S1111114Z"), new Condition("Unknown"),
new BloodType("O+"), EMPTY_APPOINTMENTS,
getTagSet("family")),
getTagSet("priority: MEDIUM")),
new Patient(new Name("Irfan Ibrahim"), new Phone("92492021"), new Phone("87438807"),
new Email("irfan@example.com"), new Address("Blk 47 Tampines Street 20, #17-35"), EMPTY_REMARK,
new Gender("M"), new Ic("S1111115Z"), new Condition("Unknown"), new BloodType("O+"),
EMPTY_APPOINTMENTS, getTagSet("classmates")),
new Patient(new Name("Roy Balakrishnan"), new Phone("92624417"), new Phone("87438807"),
new Email("royb@example.com"), new Address("Blk 45 Aljunied Street 85, #11-31"), EMPTY_REMARK,
new Gender("M"), new Ic("S1111116Z"), new Condition("Unknown"), new BloodType("O+"),
EMPTY_APPOINTMENTS, getTagSet("colleagues"))
EMPTY_APPOINTMENTS, getTagSet("priority: HIGH"))
};
}

public static Doctor[] getSampleDoctors() {
return new Doctor[] {
new Doctor(new Name("Adam Lim"), new Phone("87438000"), new Email("adamlim@example.com"),
new Address("Blk 30 Geylang Street 29, #06-40"), EMPTY_REMARK, new Gender("M"),
new Ic("S8811111Z"), getAppointmentSet(APPOINTMENT_1), getTagSet("GP")),
new Ic("S8811111Z"), getAppointmentSet(APPOINTMENT_1), getTagSet("SURGEON")),
new Doctor(new Name("Bernard Tan"), new Phone("99272000"), new Email("bernardtan@example.com"),
new Address("Blk 30 Lorong 3 Serangoon Gardens, #07-18"), EMPTY_REMARK, new Gender("M"),
new Ic("S8811112Z"), getAppointmentSet(APPOINTMENT_2, APPOINTMENT_3),
getTagSet("ENTspecialist"))
getTagSet("CARDIOLOGIST"))
};
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/seedu/address/storage/JsonAdaptedDoctor.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public Doctor toModelType() throws IllegalValueException {
final Ic modelIc = checkIc();
final List<Tag> personTags = new ArrayList<>();
for (JsonAdaptedTag tag : this.getTags()) {
personTags.add(tag.toModelType());
personTags.add(tag.toModelDoctorType());
}
final Set<Tag> modelTags = new HashSet<>(personTags);
final List<Appointment> personAppointments = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public Patient toModelType() throws IllegalValueException {
final Ic modelIc = checkIc();
final List<Tag> personTags = new ArrayList<>();
for (JsonAdaptedTag tag : this.getTags()) {
personTags.add(tag.toModelType());
personTags.add(tag.toModelPatientType());
}
final Set<Tag> modelTags = new HashSet<>(personTags);
final Condition modelCondition = checkCondition();
Expand Down
Loading

0 comments on commit 1da56dc

Please sign in to comment.