Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add special tags for doctors and patients #153

Merged
merged 2 commits into from
Nov 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading