Skip to content

Commit

Permalink
Merge pull request #167 from choowengyan/fix/duplicate-prefix
Browse files Browse the repository at this point in the history
v1.3 Fix EditCommand to disallow duplicated prefixes for Name, PreferredName and PID
  • Loading branch information
guohuang88 authored Apr 4, 2024
2 parents 025f5eb + ed9ace6 commit 38ab77c
Show file tree
Hide file tree
Showing 9 changed files with 211 additions and 9 deletions.
6 changes: 6 additions & 0 deletions docs/DeveloperGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,9 @@ The `AddCommand` class is responsible for adding new patient's information in th
* `tag` field is optional in the AddCommand and can be added later on using the `AddTagsCommand`.
* If any of the fields are repeated during the adding of patient or missing fields, error message will be thrown.

The activity diagram below outlines the steps involved when a user initiates a Add command.
<puml src="diagrams/AddActivityDiagram.puml" alt="AddActivityDiagram" />

#### Example Usage Scenario

Given below is an example usage scenario and how the group creation mechanism behaves at each step.
Expand Down Expand Up @@ -484,6 +487,9 @@ The `EditCommand` class is responsible for editing current patient's information
* Fields such as `foodPreference`, `familyCondition`, `hobby` and `tag` can be repeated for multiple inputs.
* If the fields for `patientHospitalId`, `name` and `preferredName` are repeated during the editing of patient, error message will be thrown.

The activity diagram below outlines the steps involved when a user initiates a Edit command.
<puml src="diagrams/EditActivityDiagram.puml" alt="EditActivityDiagram" />

#### Example Usage Scenario

Given below is an example usage scenario and how the group creation mechanism behaves at each step.
Expand Down
20 changes: 15 additions & 5 deletions docs/UserGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,15 @@ Format: `add id/PATIENT_HOSPITAL_ID n/NAME p/PREFERRED_NAME f/FOOD_PREFERENCE+ c
<box type="tip" seamless>

**Tip:**
* A patient can have any number of tags (including 0)
* A patient can have more than 1 `f/FOOD_PREFERENCE`, `c/FAMILY_CONDITION` and `h/HOBBY`
* Parameters can be in any order
* All command keywords, that is `‘add’`, `‘id/’`, `‘n/’`, `‘p/’`, `‘f/’`, `‘c/’` and `‘h/’` are case-sensitive (to standardise keyword arguments)
* The `add` command accepts parameters which consists of:
* `patientHospitalId` integer,
* `name`, `preferredName` String with only alphabets character,
* `foodPreference`, `familyCondition`, `hobby` String and all kinds of characters,
* `tag` which are alphanumeric.
* A patient can have any number of tags (including 0).
* A patient can have more than 1 `f/FOOD_PREFERENCE`, `c/FAMILY_CONDITION` and `h/HOBBY`.
* Parameters can be in any order.
* All command keywords, that is `‘add’`, `‘id/’`, `‘n/’`, `‘p/’`, `‘f/’`, `‘c/’` and `‘h/’` are case-sensitive (to standardise keyword arguments).

</box>

Expand Down Expand Up @@ -128,7 +133,12 @@ Format: `edit INDEX [id/PATIENT_HOSPITAL_ID] [n/NAME] [p/PREFERRED_NAME] [f/FOOD
* Edits the patient at the specified `INDEX`. The index refers to the index number shown in the displayed patient list. The index **must be a positive integer** 1, 2, 3, …​
* At least one of the optional fields must be provided.
* Existing values will be updated to the input values.
* Editing a patient can have repeated fields for `f/FOOD_PREFERENCE`, `c/FAMILY_CONDITION` and `h/HOBBY`
* * The `edit` command accepts parameters which consists of:
* `patientHospitalId` integer,
* `name`, `preferredName` String with only alphabets character,
* `foodPreference`, `familyCondition`, `hobby` String and all kinds of characters
* `tag` which are alphanumeric.
* Editing a patient can have repeated fields for `f/FOOD_PREFERENCE`, `c/FAMILY_CONDITION`, `h/HOBBY` and `t/TAG`.
* When editing tags, the existing tags of the patient will be removed i.e adding of tags is not cumulative.
* You can remove all the patient’s tags by typing `t/` without specifying any tags after it.

Expand Down
37 changes: 37 additions & 0 deletions docs/diagrams/AddActivityDiagram.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
@startuml

start
:User wants to add a patient;
:User runs the "add" command with id/PATIENT_HOSPITAL_ID n/NAME p/PREFERRED_NAME f/FOOD_PREFERENCE c/FAMILY_CONDITION h/HOBBY;
if () then ([Required prefixes present])
if () then ([Valid command format])
:PatientSync checks if the input format for the respective prefix is valid;
if () then ([Valid input format])
:PatientSync creates Patient object;
if () then ([Valid Patient Hospital ID])
:PatientSync adds patient to model;
:PatientSync generates success message;
:PatientSync returns success message to output;
else ([else])
:PatientSync throws command exception;
:PatientSync generates error message;
:PatientSync returns error message;
endif
else ([else])
:PatientSync throws parse exception;
:PatientSync generates error message;
:PatientSync returns error message;
endif
else ([else])
:PatientSync throws parse exception;
:PatientSync generates error message;
:PatientSync returns error message;
endif
else ([else])
:PatientSync throws parse exception;
:PatientSync generates error message;
:PatientSync returns error message;
endif
:PatientSync displays output message on GUI;
stop
@enduml
35 changes: 35 additions & 0 deletions docs/diagrams/EditActivityDiagram.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
@startuml
start
:User wants to edit information (eg. hobby) of a patient;
:User runs the "edit" command with patient index, details of fields (eg. hobby with command h/Reading h/Singing);
if () then ([else])
:PatientSync throws an error;
:PatientSync adds error message to output;
else ([Valid command format])
:PatientSync checks if the patient index is valid;
if () then ([else])
:PatientSync throws an error;
:PatientSync adds error message to output;
else ([Valid patient index])
:PatientSync checks if the prefix(s) is valid;
if () then ([else])
:PatientSync throws an error;
:PatientSync adds error message to output;
else ([Valid prefix])
:PatientSync checks if the input format for the respective prefix is valid;
if () then ([else])
:PatientSync throws an error;
:PatientSync adds error message to output;
else ([Valid input format])
:PatientSync generates the information to be edited;
:PatientSync edits the specified event;
:PatientSync updates the set of events for the patient;
:PatientSync updates the displayed patient list;
:PatientSync adds success message to output;
endif
endif
endif
endif
:PatientSync displays output message on GUI;
stop
@enduml
10 changes: 10 additions & 0 deletions src/main/java/seedu/address/logic/commands/AddCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
import static seedu.address.logic.parser.CliSyntax.PREFIX_PREFERRED_NAME;
import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG;

import java.util.logging.Level;
import java.util.logging.Logger;

import seedu.address.commons.core.LogsCenter;
import seedu.address.commons.util.ToStringBuilder;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.model.Model;
Expand Down Expand Up @@ -44,6 +48,8 @@ public class AddCommand extends Command {

public static final String MESSAGE_DUPLICATE_PATIENT = "This patient already exists in the address book";

private static final Logger logger = LogsCenter.getLogger(AddCommand.class);

private final Patient toAdd;

/**
Expand All @@ -56,13 +62,17 @@ public AddCommand(Patient patient) {

@Override
public CommandResult execute(Model model) throws CommandException {
logger.log(Level.INFO, "Attempting to execute AddCommand.");
requireNonNull(model);

if (model.hasPatient(toAdd)) {
throw new CommandException(MESSAGE_DUPLICATE_PATIENT);
}
logger.log(Level.INFO, "Patient is a new entry.");

model.addPatient(toAdd);
logger.log(Level.INFO, "Patient details successfully added.");

return new CommandResult(String.format(MESSAGE_SUCCESS, toAdd.getName(), toAdd.getPatientHospitalId()));
}

Expand Down
10 changes: 10 additions & 0 deletions src/main/java/seedu/address/logic/commands/EditCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@

import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import seedu.address.commons.core.LogsCenter;
import seedu.address.commons.core.index.Index;
import seedu.address.commons.util.ToStringBuilder;
import seedu.address.logic.Messages;
Expand Down Expand Up @@ -54,6 +57,7 @@ public class EditCommand extends Command {
public static final String MESSAGE_EDIT_PATIENT_SUCCESS = "Edited Patient: %1$s";
public static final String MESSAGE_NOT_EDITED = "At least one field to edit must be provided.";
public static final String MESSAGE_DUPLICATE_PATIENT = "This patient already exists in the address book.";
private static final Logger logger = LogsCenter.getLogger(EditCommand.class);

private final Index index;
private final EditPatientDescriptor editPatientDescriptor;
Expand All @@ -63,6 +67,7 @@ public class EditCommand extends Command {
* @param editPatientDescriptor details to edit the patient with
*/
public EditCommand(Index index, EditPatientDescriptor editPatientDescriptor) {
logger.log(Level.INFO, "Attempting to execute EditCommand.");
requireNonNull(index);
requireNonNull(editPatientDescriptor);

Expand All @@ -76,18 +81,22 @@ public CommandResult execute(Model model) throws CommandException {
List<Patient> lastShownList = model.getFilteredPatientList();

if (index.getZeroBased() >= lastShownList.size()) {
logger.log(Level.WARNING, "Invalid patient index for EditCommand: " + index.getOneBased());
throw new CommandException(Messages.MESSAGE_INVALID_PATIENT_DISPLAYED_INDEX);
}
logger.log(Level.INFO, "Target index is valid.");

Patient patientToEdit = lastShownList.get(index.getZeroBased());
Patient editedPatient = createEditedPatient(patientToEdit, editPatientDescriptor);

if (!patientToEdit.isSamePatient(editedPatient) && model.hasPatient(editedPatient)) {
throw new CommandException(MESSAGE_DUPLICATE_PATIENT);
}
logger.log(Level.INFO, "Target patient to edit is valid.");

model.setPatient(patientToEdit, editedPatient);
model.updateFilteredPatientList(PREDICATE_SHOW_ALL_PATIENTS);
logger.log(Level.INFO, "Patient details successfully updated.");
return new CommandResult(String.format(MESSAGE_EDIT_PATIENT_SUCCESS, Messages.format(editedPatient)));
}

Expand All @@ -112,6 +121,7 @@ static Patient createEditedPatient(Patient patientToEdit, EditPatientDescriptor
Set<Event> updatedEvents = editPatientDescriptor.getEvents()
.orElse(patientToEdit.getEvents());

logger.log(Level.INFO, "Attempting to update the information on the patient with the updated fields");
return new Patient(originalPatientHospitalId, updatedName, updatedPreferredName, updatedFoodPreferences,
updatedFamilyConditions, updatedHobbies, updatedTags, updatedEvents);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@
import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG;

import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Stream;

import seedu.address.commons.core.LogsCenter;
import seedu.address.logic.commands.AddCommand;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.patient.FamilyCondition;
Expand All @@ -27,21 +30,26 @@
* Parses input arguments and creates a new AddCommand object
*/
public class AddCommandParser implements Parser<AddCommand> {
private static final Logger logger = LogsCenter.getLogger(AddCommandParser.class);

/**
* Parses the given {@code String} of arguments in the context of the AddCommand
* and returns an AddCommand object for execution.
* @throws ParseException if the user input does not conform the expected format
*/
public AddCommand parse(String args) throws ParseException {
logger.info("Received arguments: " + args + " for AddCommand; Attempting to parse..");

ArgumentMultimap argMultimap =
ArgumentTokenizer.tokenize(args, PREFIX_PID, PREFIX_NAME, PREFIX_PREFERRED_NAME, PREFIX_FOOD_PREFERENCE,
PREFIX_FAMILY_CONDITION, PREFIX_HOBBY, PREFIX_TAG);

if (!arePrefixesPresent(argMultimap, PREFIX_PID, PREFIX_NAME, PREFIX_PREFERRED_NAME, PREFIX_FOOD_PREFERENCE,
PREFIX_FAMILY_CONDITION, PREFIX_HOBBY) || !argMultimap.getPreamble().isEmpty()) {
logger.log(Level.WARNING, "Required prefix(s) not found in AddCommand");
throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE));
}
logger.info("All prefixes required are present.");

argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_PID, PREFIX_NAME, PREFIX_PREFERRED_NAME);

Expand All @@ -58,6 +66,7 @@ public AddCommand parse(String args) throws ParseException {
Patient patient = new Patient(patientHospitalId, name, preferredName, foodPreferenceList, familyConditionList,
hobbyList, tagList);

logger.info("All arguments received are valid");
return new AddCommand(patient);
}

Expand Down
10 changes: 10 additions & 0 deletions src/main/java/seedu/address/logic/parser/EditCommandParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
import java.util.Collections;
import java.util.Optional;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import seedu.address.commons.core.LogsCenter;
import seedu.address.commons.core.index.Index;
import seedu.address.logic.commands.EditCommand;
import seedu.address.logic.parser.exceptions.ParseException;
Expand All @@ -28,25 +31,31 @@
* Parses input arguments and creates a new EditCommand object
*/
public class EditCommandParser implements Parser<EditCommand> {
private static final Logger logger = LogsCenter.getLogger(EditCommandParser.class);

/**
* Parses the given {@code String} of arguments in the context of the EditCommand
* and returns an EditCommand object for execution.
* @throws ParseException if the user input does not conform the expected format
*/
public EditCommand parse(String args) throws ParseException {
logger.log(Level.INFO, "Received arguments: " + args + " for EditCommand; Attempting to parse..");
requireNonNull(args);

ArgumentMultimap argMultimap =
ArgumentTokenizer.tokenize(args, PREFIX_PID, PREFIX_NAME, PREFIX_PREFERRED_NAME, PREFIX_FOOD_PREFERENCE,
PREFIX_FAMILY_CONDITION, PREFIX_HOBBY, PREFIX_TAG);

argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_PID, PREFIX_NAME, PREFIX_PREFERRED_NAME);

Index index;

try {
index = ParserUtil.parseIndex(argMultimap.getPreamble());
} catch (ParseException pe) {
throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, EditCommand.MESSAGE_USAGE), pe);
}
logger.log(Level.INFO, "Patient Index is valid.");

EditPatientDescriptor editPatientDescriptor = new EditPatientDescriptor();

Expand Down Expand Up @@ -76,6 +85,7 @@ public EditCommand parse(String args) throws ParseException {
throw new ParseException(EditCommand.MESSAGE_NOT_EDITED);
}

logger.log(Level.INFO, "All arguments are valid.");
return new EditCommand(index, editPatientDescriptor);
}

Expand Down
Loading

0 comments on commit 38ab77c

Please sign in to comment.