Skip to content

Commit

Permalink
Merge branch 'master' into branch-addPageBreaks
Browse files Browse the repository at this point in the history
  • Loading branch information
SwaminathanViswa authored Nov 7, 2024
2 parents 98b91f9 + 8198068 commit 097bd29
Show file tree
Hide file tree
Showing 37 changed files with 564 additions and 236 deletions.
75 changes: 53 additions & 22 deletions docs/DeveloperGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -368,11 +368,11 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli

<br>

**Use case: UC05 - Update contacts**
**Use case: UC05 - Edit contacts**

**MSS**

1. TA chooses to update a contact’s details.
1. TA chooses to edit a contact’s details.
2. KonTActs requests the contact’s identifier.
3. TA enters the identifier of the contact to update.
4. KonTActs displays the current details and requests the changes.
Expand All @@ -386,10 +386,18 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli
- 3a. KonTActs identifies that there is no such contact.

- 3a1. KonTActs requests for the correct data.
- 3a2. TA enters the correct data.
- 3a2. TA enters the new data.
- Steps 3a1-3a2 are repeated until the data entered are correct.

Use case resumes from step 4.

- 4a. KonTActs identifies that the data to be updated is invalid.

- 4a1. KonTActs requests for the correct data.
- 4a2. TA enters new data
- Steps 4a1-4a2 are repeated until the data entered are correct.

Use case resumes from step 5.

<br>

Expand Down Expand Up @@ -476,26 +484,33 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli
1. User chooses to sort the students based on their proficiency.
2. User enters the sort command.
3. KonTActs returns the list of students in the sorted order.

Use case ends.

<br>

**Use case: UC09 - Export contacts**

**Precondition**

1. User must have permission to write to the provided path.
2. User must have enough storage to store the output file.

**MSS**

1. User chooses to export the contact list.
2. KonTActs requests for the file path.
3. User gives the file path.
4. KonTActs exports the contact list in CSV format and shows successful export.
2. User provides the file path.
3. KonTActs exports the contact list in CSV format and shows the number of people successfully exported.

Use case ends.

**Extensions**

- 2a. User selects an unsupported format.
- 2a. User enters an invalid path (e.g .pdf).

- 2a1. KonTActs displays an error message and provides the list of formats that are supported.
- 2a1. KonTActs displays an error message and request for user to provide a valid file path (e.g. must end with .csv)
- 2a2. User provides new file path
- Step 2a1-2a2 are repeated until file path is valid

Use case resumes from step 3.

Expand Down Expand Up @@ -526,7 +541,7 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli

**Precondition**

1. The student that the user wants to tag exists.
1. The student that the user wants to tag is in KonTActs.

**MSS**

Expand All @@ -541,11 +556,11 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli

- 3a. KonTActs detects an error in the entered data.

- 3a1. KonTActs requests for the correct data.
- 3a1. KonTActs displays error message.
- 3a2. User enters new data.
- Steps 3a1-3a2 are repeated until the data entered are correct.

Use case resumes from step 3.
Use case resumes from step 4.

<br>

Expand Down Expand Up @@ -574,27 +589,43 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli

{{ newPage }}

**Use case: UC13 - Import contacts**
**Use case: UC13 - Import contacts from CSV file**

**Precondition**

1. The file is in CSV format and ends with .csv
2. The file contains valid data of at least 1 person
3. The header of the file is in a specific sequence
("Name","Email","Telegram","Tags","Github","Assignments","WeeksPresent")
4. Current user have permissions to access and read the file

**MSS**

1. User chooses to import the contact list.
2. KonTActs requests for the file path.
3. User gives the desired file (by its path).
4. KonTActs import the contact list from the specified file path and shows successful import.
2. User gives the desired file (by its path).
3. KonTActs import the contact list from the specified file path and shows successful import.

Use case ends.

**Extensions**

- 3a. KonTActs detects an unsupported, corrupted file or a file without the valid headers.
- 2a. KonTActs detects an unsupported, corrupted file or a file without the valid headers.

- 3a1. KonTActs indicates it is unable to import from that file and requests for a new file.
- 3a2. User gives a new file.
- Steps 3a1 - 3a2 are repeated until KonTActs is able to import contacts from the file.
- 2a1. KonTActs indicates it is unable to import from that file and gives a more specific error message.
- 2a2. User provides a new file path
- Steps 2a1 - 2a2 are repeated until KonTActs is able to import contacts from the file.

Use case resumes from step 4.
Use case resumes from step 3.

- 2b. KonTActs detects invalid content in CSV file (e.g. Name/Email that does not comply with requirement,
Duplicate names)

- 2b1. KonTActs indicates it is unable to import from that file and gives a more specific error message.
- 2b2. User provides a new file path or update their CSV file
- Steps 2b1 - 2b2 are repeated until KonTActs is able to import contacts from the file.

Use case resumes from step 3.

- \*a. At any time, User chooses to cancel the import.

- \*a1. KonTActs stops the import.
Expand Down Expand Up @@ -639,11 +670,11 @@ Actor: TA

* **Contact**: An individual (e.g. student) stored in the system, typically having details regarding them such as their name, github username and etc.

* **Easy to use for new users**: intuitive commands that are easy to understand and UI that is easy to navigate.
* **Easy to use for new users**: Intuitive commands that are easy to understand and UI that is easy to navigate.

* **Mainstream OS**: Windows, Linux, Unix, MacOS.

* **Average typing speed**: about 40 words per minute.
* **Average typing speed**: About 40 words per minute.

* **Uptime**: The system should be operational during that period of time.

Expand Down
13 changes: 8 additions & 5 deletions docs/UserGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,14 @@ To get started,
| [**Mark**](#marking-a-student-as-present-mark) | `mark name/NAME week/WEEK_NUMBER` <br> e.g. `mark name/John Doe week/1` |
| [**Unmark**](#unmarking-a-student-as-present-unmark) | `unmark name/NAME week/WEEK_NUMBER` <br> e.g. `unmark name/John Doe week/1` |
| [**Sort**](#sorting-the-displayed-list-sort) | `sort FIELD order/ORDER` <br> e.g. `sort name order/asc` |
| [**Import**](#importing-data-from-csv-file-import) | `import path/CSV FILE PATH` <br> e.g `import path/user/data/xxx.csv` |
| [**Export**](#exporting-data-into-csv-file-export) | `export path/DESIRED FILE DESTINATION` <br> e.g `export path/user/data/xxx.csv` |
| [**Import**](#importing-data-from-csv-file-import) | `import path/CSV_FILE_PATH` <br> e.g `import path/user/data/xxx.csv` |
| [**Export**](#exporting-data-into-csv-file-export) | `export path/DESIRED_FILE_DESTINATION` <br> e.g `export path/user/data/xxx.csv` |
| [**Command History**](#accessing-command-history-and) | <kbd>↑</kbd> and <kbd>↓</kbd> |## Features
| [**Add grade**](#adding-grades-to-a-contact-addgrade) | `addGrade name/NAME assignment/ASSIGNMENT_NAME score/SCORE` <br> e.g. `addGrade n/JohnDoe assignment/Ex01 score/5` |
| [**Remove grade**](#removing-grades-from-a-contact-removegrade) | `removeGrade name/NAME assignment/ASSIGNMENT_NAME` <br> e.g. `removeGrade name/John Doe assignment/Ex01` |

{{ newPage }}

|
--------------------------------------------------------------------------------------------------------------------
## <i class="fa-solid fa-bolt-lightning"></i> Parameter shortcuts

Expand Down Expand Up @@ -654,8 +654,10 @@ Imports contacts based on CSV file. Importing a file will replace ALL existing c
"Assignments", "WeeksPresent"} (Case-insensitive)
* The CSV file must contain information about at least 1 person
* The data fields for Name, Email, Telegram, Github is compulsory
* Tags format: enclose tag in square brackets ("[tag]"). If a person has multiple tags, separate the tags within the same entry
with commas. (e.g."[tag1],[tag2],[tag3].....")
* Do note that each of these field have their own restrictions
[(refer above)](#i-classfa-solid-fa-user-plusi-adding-a-person-add)
* Tags format: enclose tag in square brackets ("[tag]"). If a person has multiple tags, separate the tags within
the same entry with commas. (e.g."[tag1],[tag2],[tag3].....")
* Duplicate tags will be ignored (e.g."[Group1],[Group1]" will be treated as "[Group1]")
* This field can be empty (will be treated as no tags for specific person)
* Assignment format: Assignment name and assignment score should be separated with "|" (e.g. Ex01|10). If multiple
Expand Down Expand Up @@ -710,6 +712,7 @@ Exports contacts based on contacts and their details stored in KonTActs.

* File path can be relative or absolute but must end with .csv
</box>
* You must have write permission in order to export CSV file to specified location

<box type="definition" icon=":fa-solid-book:" light>

Expand Down
17 changes: 15 additions & 2 deletions src/main/java/seedu/address/logic/commands/AddGradeCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,18 @@ public static AddGradeCommand showAssignmentDefault() {
return showAssignmentDefault;
}

/**
* Creates a new {@code Person} object with an updated assignment and score added to the existing person's record.
*
* This method updates the assignments of the given person by adding a new assignment with the specified name and
* score.
* A new {@code Person} object is returned with the updated assignments.
*
* @param person The original {@code Person} object to which the grade will be added.
* @param assignmentName The name of the assignment to be added.
* @param score The score for the assignment to be added.
* @return A new {@code Person} object with the updated assignment and score.
*/
private static Person createGradeToAddToPerson(Person person, String assignmentName, float score) {
assert person != null;
Name name = person.getName();
Expand Down Expand Up @@ -117,8 +129,9 @@ public CommandResult execute(Model model) throws CommandException {
throw new CommandException("Invalid assignment name: " + assignmentName + "\n" + HELP_MESSAGE);
}

if (score > model.maxScore(assignmentName) || score < 0) {
throw new CommandException("Score must be between 0.0 and " + model.maxScore(assignmentName));
// check if score is valid
if (score > model.getMaxScore(assignmentName) || score < 0) {
throw new CommandException("Score must be between 0.0 and " + model.getMaxScore(assignmentName));
}

Person person = model.getPerson(personName)
Expand Down
11 changes: 5 additions & 6 deletions src/main/java/seedu/address/logic/commands/ExportCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,11 @@ public class ExportCommand extends Command {
public static final String COMMAND_WORD = "export";
public static final String COMMAND_WORD_SHORT_FORM = "ex";

public static final String MESSAGE_USAGE = COMMAND_WORD + " or " + COMMAND_WORD_SHORT_FORM
+ ": Exports person data to a CSV file.\n"
+ "Parameters: FILE_PATH"
+ "[" + PREFIX_PATH + "FILE_PATH]\n"
+ "Example: " + COMMAND_WORD + " " + PREFIX_PATH + "data/persons.csv\n"
+ "Example: " + COMMAND_WORD_SHORT_FORM + " " + PREFIX_PATH + "data/persons.csv";
public static final String MESSAGE_USAGE = "Exports person data to a CSV file.\n"
+ "Command: " + COMMAND_WORD + " or " + COMMAND_WORD_SHORT_FORM + "\n"
+ "Parameters: " + PREFIX_PATH + "FILE_PATH\n"
+ "Example: " + COMMAND_WORD + " " + PREFIX_PATH + "data/persons.csv\n"
+ "Example: " + COMMAND_WORD_SHORT_FORM + " " + PREFIX_PATH.getShortPrefix() + "data/persons.csv";

private final String filePath;

Expand Down
21 changes: 10 additions & 11 deletions src/main/java/seedu/address/logic/commands/ImportCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,18 @@ public class ImportCommand extends Command {
public static final String COMMAND_WORD = "import";
public static final String COMMAND_WORD_SHORT_FORM = "im";

public static final String MESSAGE_USAGE = COMMAND_WORD + " or " + COMMAND_WORD_SHORT_FORM
+ ": Imports person data from a CSV file.\n"
+ "Parameters: FILE_PATH"
+ "[" + PREFIX_PATH + "FILE_PATH]\n"
+ "Example: " + COMMAND_WORD + " " + PREFIX_PATH + "data/persons.csv\n"
+ "Example: " + COMMAND_WORD_SHORT_FORM + " " + PREFIX_PATH + "data/persons.csv";
public static final String MESSAGE_USAGE = "Imports person data from a CSV file.\n"
+ "Command: " + COMMAND_WORD + " or " + COMMAND_WORD_SHORT_FORM + "\n"
+ "Parameters: " + PREFIX_PATH + "FILE_PATH\n"
+ "Example: " + COMMAND_WORD + " " + PREFIX_PATH + "data/persons.csv\n"
+ "Example: " + COMMAND_WORD_SHORT_FORM + " " + PREFIX_PATH.getShortPrefix() + "data/persons.csv";
public static final String CORRECT_HEADER_USAGE =
"Header of CSV file should be Name, Email, Telegram, Tags, Github, Assignments, WeeksPresent"
+ " (Case insensitive, Order sensitive)";
public static final String MESSAGE_READING_ERROR = "Error reading from the CSV file path: ";
private static final String MESSAGE_INVALID_CSV = "Invalid CSV format, ensure that all necessary data are present.";
private static final String MESSAGE_MISSING_PERSON_DATA = "There is no person data present.";
private static final String MESSAGE_NULL_FIELDS = "Please ensure that there is no null fields";

private final String csvFilePath;

/**
Expand Down Expand Up @@ -83,20 +82,20 @@ public CommandResult execute(Model model) throws CommandException {
}
model.replaceAllPersons(newPersons);
} catch (IOException e) {
throw new CommandException("Error reading from the CSV file path: " + e.getMessage()
throw new CommandException(MESSAGE_READING_ERROR + e.getMessage()
+ "\nPlease check file path provided again");
} catch (DuplicatePersonException e) {
throw new CommandException("Error reading from the CSV file " + e.getMessage()
throw new CommandException(MESSAGE_READING_ERROR + e.getMessage()
+ "\nPlease ensure that there are no duplicate person in the CSV file");
} catch (CsvValidationException | CommandException e) {
throw new CommandException("Error reading from the CSV file: " + e.getMessage());
throw new CommandException(MESSAGE_READING_ERROR + e.getMessage());
} catch (NullPointerException e) {
throw new CommandException(MESSAGE_NULL_FIELDS);
}

// Replace all existing person with those present in the CSV file.

return new CommandResult(String.format("Successfully imported %d persons.", newPersons.size()));
return new CommandResult(String.format("Successfully imported %d person.", newPersons.size()));
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,12 @@ public AddGradeCommand parse(String args) throws ParseException {

argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME, PREFIX_SCORE, PREFIX_ASSIGNMENT);

// Get and validate the assignment name
// Get assignment name
String assignmentName = argMultimap.getValue(PREFIX_ASSIGNMENT).orElse("").trim();
if (assignmentName.isEmpty()) {
throw new ParseException("Assignment name cannot be empty.");
}

// Get and validate the score as a string
// Get score as a string
String scoreString = argMultimap.getValue(PREFIX_SCORE).orElse("").trim();
if (scoreString.isEmpty()) {
throw new ParseException("Score cannot be empty.");
}
// Throws exception if fields are empty
checkAssignmentString(assignmentName, scoreString);

float score;
try {
Expand All @@ -59,6 +54,22 @@ public AddGradeCommand parse(String args) throws ParseException {
return new AddGradeCommand(name, score, assignmentName);
}

/**
* Checks if the assignment name and score string are valid (not empty).
*
* @param assignmentName the name of the assignment to check.
* @param scoreString the score string to check.
* @throws ParseException if either the assignment name or score string is empty.
*/
private static void checkAssignmentString(String assignmentName, String scoreString) throws ParseException {
if (assignmentName.isEmpty()) {
throw new ParseException("Assignment name cannot be empty.");
}

if (scoreString.isEmpty()) {
throw new ParseException("Score cannot be empty.");
}
}
/**
* Returns true if none of the prefixes contains empty {@code Optional} values in the given
* {@code ArgumentMultimap}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ private static void processAssignment(String assignment, Map<String, Assignment>
}

// Throws Command exception if score is invalid (not parser exception because this happens during execution)
if (asgnScore > model.maxScore(asgnName) || asgnScore < 0) {
throw new CommandException("Score must be between 0.0 and " + model.maxScore(asgnName));
if (asgnScore > model.getMaxScore(asgnName) || asgnScore < 0) {
throw new CommandException("Score must be between 0.0 and " + model.getMaxScore(asgnName));
}

assignments.put(asgnName, new Assignment(asgnName, asgnScore));
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/seedu/address/logic/parser/CsvRowParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class CsvRowParser {
+ CORRECT_HEADER_USAGE;

private static final String MESSAGE_INVALID_EXTRA_COLUMNS = "There are extra columns!\n"
+ "Please ensure there is only be 8 corresponding header/data columns\n"
+ "Please ensure there is only 7 corresponding header/data columns\n"
+ CORRECT_HEADER_USAGE;

private static final String MESSAGE_INVALID_INSUFFICIENT_COLUMNS = "There are lesser columns in header than "
Expand Down Expand Up @@ -54,7 +54,7 @@ public static void checkHeaders(String[] headers, String[] expectedHeaders) thro
}

for (String header : headers) {
if (header.isEmpty() && headers.length <= 8) {
if (header.isEmpty() && headers.length < 7) {
throw new CommandException(MESSAGE_INVALID_HEADERS);
}
}
Expand Down
Loading

0 comments on commit 097bd29

Please sign in to comment.