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

Batch student status update #62

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
37 changes: 19 additions & 18 deletions docs/UserGuide.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@

| Layout | Page |
| --- | --- |
| User Guide | Link |
| Quick start | Link |
| Features | Link |
| Command Summary | Link |
| Quick Links |
|-----------------|
| Glossary |
| User Guide |
| Quick start |
| Features |
| Command Summary |


Ultimate DivocTracker is a desktop app for managing COVID-19 contacts in school admin, optimized for use via a Command Line Interface (CLI) while still having the benefits of a Graphical User Interface (GUI). If you can type fast, Ultimate DivocTracker can get your contact management tasks done faster than traditional GUI apps.
Expand All @@ -15,8 +16,8 @@ Ultimate DivocTracker is a desktop app for managing COVID-19 contacts in school
- Adding a student: add
- Listing all students: list
- Find students by name: find_by_name
- Find student by status: find_by_status
- Find student by class: find_by_class
- Find student by status: findstatus
- Find student by class: findclasscode
- Deleting a student: delete_student
- Update COVID-19 status: update_status
- Exiting the program : exit
Expand Down Expand Up @@ -53,22 +54,22 @@ Find an existing student in the application by their name
- Example:
- `find_by_name john`

## Find a student by status: `find_by_status`
## Find a student by status: `findstatus`
Find an existing student in the application by their Covid-19 Status
- Format: `find_by_status STATUS`
- Format: `findstatus STATUS`
- Returns a list of students with the specified `STATUS`
- `STATUS` is case-insensitive
- Example:
- `find_by_status positive`
- `find_by_status negative`
- `findstatus positive`
- `findstatus negative`

## Find student by class: `find_by_class`
## Find student by class: `findclasscode`
Finds an existing student in the address book by their class.
- Format: `find_by_class CLASS`
- Format: `findclasscode CLASS`
- Returns a list of students with the specified `CLASS`.
- `CLASS` is case-insensitive
- Example:
- `find_by_class 4A`
- `findclasscode 4A`

## Updating persons status: `update_status`
Updates persons status to the given status.
Expand Down Expand Up @@ -111,8 +112,8 @@ AddressBook data are saved as a JSON file `[JAR file location]/data/addressbook.
| Delete a student | `delete_student INDEX`<br/>e.g., `delete_student 3` |
| Edit | `edit INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [a/ADDRESS]`<br/>e.g., `edit 2 n/James Lee e/[email protected]` |
| Find by name | `find_by_name NAME [MORE_NAME]`<br/>e.g., `find_by_name James Jake` |
| Find by status | `find_by_status STATUS`<br/>e.g., `find_by_status positive` |
| Find by class | `find_by_class CLASS`<br/>e.g., `find_by_class 4A` |
| Find by status | `findstatus STATUS`<br/>e.g., `find_by_status positive` |
| Find by class | `findclasscode CLASS`<br/>e.g., `find_by_class 4A` |
| List | `list` |
| Update status | `update_status INDEX STATUS`<br/>e.g., `update_status 54 positive` |
| Exit | `exit`
| Exit | `exit` |
10 changes: 7 additions & 3 deletions docs/team/fenway17.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,19 @@ Given below are my contributions to the project.
* Highlights: Status can be `"Positive"`, `"Negative"` or `"Close-Contact"`
* Credits: *{Collaborators: Yong Rui, Zi Foong}*

* **New Feature**: --
* **New Feature**: Command to find persons by Class Code (Pull request [\#56](https://github.com/AY2122S2-CS2103T-T12-1/tp/pull/56))
* What it does: Find a list of persons that match the Class Code given.
* Justification: Allows admins and users to find all persons in the same class
* Highlights: Given Class Code can be part of the full Class Code
* Credits: *{}*

* **Code contributed**: [RepoSense link]()

* **Project management**:
* Managed releases `--` - `--` (-- releases) on GitHub

* **Enhancements to existing features**:
* -- (Pull requests [\#--](), [\#--]())
* Fixed multiple checkstyle errors (Pull request [\#49](https://github.com/AY2122S2-CS2103T-T12-1/tp/pull/49))
* -- (Pull requests [\#--](), [\#--]())

* **Documentation**:
Expand All @@ -36,7 +40,7 @@ Given below are my contributions to the project.
* Added use cases for developer guide [\#27](https://github.com/AY2122S2-CS2103T-T12-1/tp/pull/27)

* **Community**:
* PRs reviewed (with non-trivial review comments): [\#32](https://github.com/AY2122S2-CS2103T-T12-1/tp/pull/32)
* PRs reviewed (with non-trivial review comments): [\#32](https://github.com/AY2122S2-CS2103T-T12-1/tp/pull/32) [\#63](https://github.com/AY2122S2-CS2103T-T12-1/tp/pull/63)
* Contributed to forum discussions (examples: [1](), [2](), [3](), [4]())
* Reported bugs and suggestions for other teams in the class (examples: [1](), [2](), [3]())
* Some parts of the -- feature I added was adopted by several other class mates ([1](), [2]())
Expand Down
23 changes: 16 additions & 7 deletions docs/team/lzf834.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,29 @@
---
layout: page
title: Zi Foong's Project Portfolio Page
Zi Foong's Project Portfolio Page
---
| Content |
|------------------|
| New Features |
| Code Contributed |
| Enhancements |
| Documentations |
| Community |

### Project: Ultimate Divoc Tracker
Ultimate Divoc Tracker is a desktop app for managing COVID-19 contacts in school admin, optimized for use via a Command Line Interface (CLI) while still having the benefits of a Graphical User Interface (GUI). If you can type fast, Ultimate DivocTracker can get your contact management tasks done faster than traditional GUI apps.

Given below are my contributions to the project.

* **New Feature**: Find Students by their Covid-19 Status -- (Pull Request [\#55](https://github.com/AY2122S2-CS2103T-T12-1/tp/pull/55))
* What it does: Allows the user to find students by their status
* Justification: Track students with specific statuses e.g. `Positive` or `Close-Contact`
* Credits: *{Collaborators: Yong Rui, Zi Foong}*

* **New Feature**: Status attribute for persons -- (Pull Request [\#32](https://github.com/AY2122S2-CS2103T-T12-1/tp/pull/32))
* What it does: Gives each person in the list a status attribute denoting their COVID-19 status.
* Justification: Track COVID-19 status of each person
* Highlights: Status can be `"Positive"`, `"Negative"` or `"Close-Contact"`
* Highlights: Status can be `Positive`, `Negative` or `Close-Contact`
* Credits: *{Collaborators: Yong Rui, Zi Foong}*

* **New Feature**: `To be added soon`
* **Code contributed**: [RepoSense link]()
* **Project management**:
* Managed releases `To be added soon`
Expand All @@ -25,8 +34,9 @@ Given below are my contributions to the project.
* User Guide:
* Update AboutUs.md [\#18](https://github.com/AY2122S2-CS2103T-T12-1/tp/pull/18)
* Update Readme.md [\#18](https://github.com/AY2122S2-CS2103T-T12-1/tp/pull/18)
* Update for new features `findstatus` and `findclasscode`
* Developer Guide:
* Editted Glossary
* Edited Glossary
* Added User Profile, User Stories and Value Prepositions [\#25](https://github.com/AY2122S2-CS2103T-T12-1/tp/pull/25)
* **Community**:
* PRs reviewed (with non-trivial review comments): [\#32](https://github.com/AY2122S2-CS2103T-T12-1/tp/pull/32)
Expand All @@ -36,4 +46,3 @@ Given below are my contributions to the project.
* **Tools**:
* `To be added soon`
* `To be added soon`
* _{you can add/remove categories in the list above}_
23 changes: 22 additions & 1 deletion src/main/java/seedu/address/logic/commands/EditCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import javafx.collections.ObservableList;
import seedu.address.commons.core.Messages;
import seedu.address.commons.core.index.Index;
import seedu.address.commons.util.CollectionUtil;
Expand Down Expand Up @@ -75,6 +77,7 @@ public EditCommand(Index index, EditPersonDescriptor editPersonDescriptor) {
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
List<Person> lastShownList = model.getFilteredPersonList();
ObservableList<Person> studentList = model.getAddressBook().getPersonList();

if (index.getZeroBased() >= lastShownList.size()) {
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
Expand All @@ -88,6 +91,24 @@ public CommandResult execute(Model model) throws CommandException {
}

model.setPerson(personToEdit, editedPerson);

if (personToEdit.getStatus().toString().equals(Status.NEGATIVE)
&& editedPerson.getStatus().toString().equals(Status.POSITIVE)) {

List<Person> filteredByClassCodeList = studentList.stream()
.filter(student -> student.getClassCode().toString().equals(editedPerson.getClassCode().toString())
&& !student.isSamePerson(editedPerson))
.collect(Collectors.toList());

for (int i = 0; i < filteredByClassCodeList.size(); i++) {
Person currentPerson = filteredByClassCodeList.get(i);
EditPersonDescriptor tempDescriptor = new EditPersonDescriptor();
tempDescriptor.setStatus(new Status(Status.CLOSE_CONTACT));
Person editedPersonStatus = createEditedPerson(currentPerson, tempDescriptor);
model.setPerson(currentPerson, editedPersonStatus);
}
}
Comment on lines +95 to +110

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also handle the case where a student's status has changed from positive to negative? When a student has recovered, their classmates' status should be negative instead of close contact if there is no more positive student in the class.


model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
return new CommandResult(String.format(MESSAGE_EDIT_PERSON_SUCCESS, editedPerson));
}
Expand Down Expand Up @@ -162,7 +183,7 @@ public EditPersonDescriptor(EditPersonDescriptor toCopy) {
* Returns true if at least one field is edited.
*/
public boolean isAnyFieldEdited() {
return CollectionUtil.isAnyNonNull(name, phone, email, address, tags);
return CollectionUtil.isAnyNonNull(name, phone, email, address, tags, status, classCode);
}

public void setName(Name name) {
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/seedu/address/model/person/Status.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ public class Status {
public static final String MESSAGE_CONSTRAINTS =
"Status should only be Positive, Negative or Close-Contact";
private static final String[] STATUS_INPUT = {"Positive", "Negative", "Close-Contact"};
public static final String POSITIVE = STATUS_INPUT[0];
public static final String NEGATIVE = STATUS_INPUT[1];
public static final String CLOSE_CONTACT = STATUS_INPUT[2];
public final String value;

/**
Expand Down
67 changes: 67 additions & 0 deletions src/test/java/seedu/address/logic/commands/FindStatusTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package seedu.address.logic.commands;

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.commons.core.Messages.MESSAGE_PERSONS_LISTED_OVERVIEW;
import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;

import java.util.Arrays;
import java.util.Collections;

import org.junit.jupiter.api.Test;

import seedu.address.model.Model;
import seedu.address.model.ModelManager;
import seedu.address.model.UserPrefs;
import seedu.address.model.person.StatusContainsKeywordsPredicate;

public class FindStatusTest {
private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
private Model expectedModel = new ModelManager(getTypicalAddressBook(), new UserPrefs());

@Test
public void equals() {
StatusContainsKeywordsPredicate firstPredicate =
new StatusContainsKeywordsPredicate(Collections.singletonList("Positive"));
StatusContainsKeywordsPredicate secondPredicate =
new StatusContainsKeywordsPredicate(Collections.singletonList("Negative"));

FindStatusCommand findFirstCommand = new FindStatusCommand(firstPredicate);
FindStatusCommand findSecondCommand = new FindStatusCommand(secondPredicate);

// same object -> returns true
assertTrue(findFirstCommand.equals(findFirstCommand));

// same values -> returns true
FindStatusCommand findFirstCommandCopy = new FindStatusCommand(firstPredicate);
assertTrue(findFirstCommand.equals(findFirstCommandCopy));

// different types -> returns false
assertFalse(findFirstCommand.equals(1));

// null -> returns false
assertFalse(findFirstCommand.equals(null));

// different person -> returns false
assertFalse(findFirstCommand.equals(findSecondCommand));
}

@Test
public void execute_zeroKeywords_noPersonFound() {
String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 0);
StatusContainsKeywordsPredicate predicate = preparePredicate(" ");
FindStatusCommand command = new FindStatusCommand(predicate);
expectedModel.updateFilteredPersonList(predicate);
assertCommandSuccess(command, model, expectedMessage, expectedModel);
assertEquals(Collections.emptyList(), model.getFilteredPersonList());
}

/**
* Parses {@code userInput} into a {@code StatusContainsKeywordsPredicate}.
*/
private StatusContainsKeywordsPredicate preparePredicate(String userInput) {
return new StatusContainsKeywordsPredicate(Arrays.asList(userInput.split("\\s+")));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package seedu.address.logic.parser;

import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure;
import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess;

import java.util.Arrays;

import org.junit.jupiter.api.Test;

import seedu.address.logic.commands.FindStatusCommand;
import seedu.address.model.person.StatusContainsKeywordsPredicate;

public class FindStatusCommandParserTest {
private FindStatusCommandParser parser = new FindStatusCommandParser();

@Test
public void parse_emptyArg_throwsParseException() {
assertParseFailure(parser, " ", String.format(MESSAGE_INVALID_COMMAND_FORMAT,
FindStatusCommand.MESSAGE_USAGE));

// multiple whitespaces between keywords
assertParseFailure(parser, " \n Positive \n \t Negative \t", String.format(
MESSAGE_INVALID_COMMAND_FORMAT, FindStatusCommand.ERRMSG_STATUS));
}

@Test
public void parse_validArgs_returnsFindCommand() {
// no leading and trailing whitespaces
FindStatusCommand expectedFindStatusCommand =
new FindStatusCommand(new StatusContainsKeywordsPredicate(Arrays.asList("Positive")));
assertParseSuccess(parser, "Positive", expectedFindStatusCommand);

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package seedu.address.model.person;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.junit.jupiter.api.Test;

import seedu.address.testutil.PersonBuilder;

public class StatusContainsKeywordsPredicateTest {
@Test
public void equals() {
List<String> firstPredicateKeywordList = Collections.singletonList("Positive");
List<String> secondPredicateKeywordList = Arrays.asList("Positive", "Negative");

StatusContainsKeywordsPredicate firstPredicate = new
StatusContainsKeywordsPredicate(firstPredicateKeywordList);
StatusContainsKeywordsPredicate secondPredicate = new
StatusContainsKeywordsPredicate(secondPredicateKeywordList);

// same object -> returns true
assertTrue(firstPredicate.equals(firstPredicate));

// same values -> returns true
StatusContainsKeywordsPredicate firstPredicateCopy = new
StatusContainsKeywordsPredicate(firstPredicateKeywordList);
assertTrue(firstPredicate.equals(firstPredicateCopy));

// different types -> returns false
assertFalse(firstPredicate.equals(1));

// null -> returns false
assertFalse(firstPredicate.equals(null));

// different person -> returns false
assertFalse(firstPredicate.equals(secondPredicate));
}

@Test
public void test_statusContainsKeywords_returnsTrue() {
// One keyword
StatusContainsKeywordsPredicate predicate = new
StatusContainsKeywordsPredicate(Collections.singletonList("Positive"));
assertTrue(predicate.test(new PersonBuilder().withStatus("Positive").build()));

// Exception thrown for >1 word in status
try {
new PersonBuilder().withStatus("Positive Negative").build();
} catch (Exception e) {
assertTrue(e.getMessage() == Status.MESSAGE_CONSTRAINTS);
}

// Exception thrown for non-conforming syntax in status
try {
new PersonBuilder().withStatus("Pos").build();
} catch (Exception e) {
assertTrue(e.getMessage() == Status.MESSAGE_CONSTRAINTS);
}
}
}
Loading