Skip to content

Commit

Permalink
Merge pull request #117 from woke02/branch-kelly-status-command
Browse files Browse the repository at this point in the history
Add StatusComand and relevent test cases
  • Loading branch information
ZweZeya authored Oct 23, 2024
2 parents ada138a + 559ae4c commit 4e8d317
Show file tree
Hide file tree
Showing 13 changed files with 454 additions and 20 deletions.
110 changes: 110 additions & 0 deletions src/main/java/seedu/hireme/logic/commands/StatusCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package seedu.hireme.logic.commands;

import static java.util.Objects.requireNonNull;

import java.util.List;

import seedu.hireme.commons.core.index.Index;
import seedu.hireme.logic.Messages;
import seedu.hireme.logic.commands.exceptions.CommandException;
import seedu.hireme.model.Model;
import seedu.hireme.model.internshipapplication.InternshipApplication;
import seedu.hireme.model.internshipapplication.Status;

/**
* Changes the status of an internship application identified using its displayed index.
*/
public class StatusCommand extends Command<InternshipApplication> {

/** Command word for accepting an application. */
public static final String COMMAND_WORD_ACCEPT = "/accept";

/** Command word for marking an application as pending. */
public static final String COMMAND_WORD_PENDING = "/pending";

/** Command word for rejecting an application. */
public static final String COMMAND_WORD_REJECT = "/reject";

/**
* Message to display for command usage instructions.
*/
public static final String MESSAGE_USAGE = COMMAND_WORD_ACCEPT
+ " / " + COMMAND_WORD_PENDING + " / " + COMMAND_WORD_REJECT
+ ": Changes the status of the internship application identified by "
+ "the index number used in the displayed list.\n"
+ "Parameters: INDEX (must be a positive integer)\n"
+ "Example: " + COMMAND_WORD_ACCEPT + " 1";

/**
* Message to display upon successful status update.
*/
public static final String MESSAGE_STATUS_CHANGE_SUCCESS = "Updated status of internship application: %1$s to %2$s";

private final Index targetIndex;
private final Status newStatus;

/**
* Constructs a {@code StatusCommand}.
*
* @param targetIndex The index of the internship application to update.
* @param newStatus The new status to set for the internship application.
*/
public StatusCommand(Index targetIndex, Status newStatus) {
this.targetIndex = targetIndex;
this.newStatus = newStatus;
}

/**
* Executes the command to update the status of an internship application.
*
* @param model The model containing the list of internship applications.
* @return A {@code CommandResult} indicating the result of the status update.
* @throws CommandException If the target index is invalid.
*/
@Override
public CommandResult execute(Model<InternshipApplication> model) throws CommandException {
requireNonNull(model);
List<InternshipApplication> lastShownList = model.getFilteredList();

if (targetIndex.getZeroBased() >= lastShownList.size()) {
throw new CommandException(Messages.MESSAGE_INVALID_INTERNSHIP_APPLICATION_DISPLAYED_INDEX);
}

InternshipApplication internshipApplicationToUpdate = lastShownList.get(targetIndex.getZeroBased());
internshipApplicationToUpdate.setStatus(newStatus);
return new CommandResult(String.format(MESSAGE_STATUS_CHANGE_SUCCESS,
Messages.format(internshipApplicationToUpdate), newStatus.getValue()));
}

/**
* Checks if this command is equal to another object.
*
* @param other The other object to compare.
* @return True if both objects are the same or have the same target index and new status, false otherwise.
*/
@Override
public boolean equals(Object other) {
if (other == this) {
return true;
}

if (!(other instanceof StatusCommand)) {
return false;
}

StatusCommand otherStatusCommand = (StatusCommand) other;
return targetIndex.equals(otherStatusCommand.targetIndex)
&& newStatus.equals(otherStatusCommand.newStatus);
}

/**
* Returns the string representation of this command.
*
* @return A string representing this {@code StatusCommand}.
*/
@Override
public String toString() {
return StatusCommand.class.getCanonicalName()
+ "{targetIndex=" + targetIndex + ", newStatus=" + newStatus.getValue() + "}";
}
}
11 changes: 11 additions & 0 deletions src/main/java/seedu/hireme/logic/parser/AddressBookParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@
import seedu.hireme.logic.commands.FindCommand;
import seedu.hireme.logic.commands.HelpCommand;
import seedu.hireme.logic.commands.ListCommand;
import seedu.hireme.logic.commands.StatusCommand;
import seedu.hireme.logic.parser.exceptions.ParseException;
import seedu.hireme.model.internshipapplication.InternshipApplication;
import seedu.hireme.model.internshipapplication.Status;

/**
* Parses user input.
Expand Down Expand Up @@ -59,6 +61,15 @@ public Command<InternshipApplication> parseCommand(String userInput) throws Pars
case DeleteCommand.COMMAND_WORD:
return new DeleteCommandParser().parse(arguments);

case StatusCommand.COMMAND_WORD_ACCEPT:
return new StatusCommandParser(Status.ACCEPTED).parse(arguments);

case StatusCommand.COMMAND_WORD_PENDING:
return new StatusCommandParser(Status.PENDING).parse(arguments);

case StatusCommand.COMMAND_WORD_REJECT:
return new StatusCommandParser(Status.REJECTED).parse(arguments);

case ClearCommand.COMMAND_WORD:
return new ClearCommand();

Expand Down
43 changes: 43 additions & 0 deletions src/main/java/seedu/hireme/logic/parser/StatusCommandParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package seedu.hireme.logic.parser;

import static seedu.hireme.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;

import seedu.hireme.commons.core.index.Index;
import seedu.hireme.logic.commands.StatusCommand;
import seedu.hireme.logic.parser.exceptions.ParseException;
import seedu.hireme.model.internshipapplication.Status;

/**
* Parses input arguments and creates a new StatusCommand object
*/
public class StatusCommandParser implements Parser<StatusCommand> {

private final Status status;

public StatusCommandParser(Status status) {
this.status = status;
}

/**
* Parses the given {@code String} of arguments in the context of the StatusCommand
* and returns a StatusCommand object for execution.
* @throws ParseException if the user input does not conform to the expected format
*/
public StatusCommand parse(String args) throws ParseException {
try {
// Parse index from the arguments
Index index = ParserUtil.parseIndex(args.trim());

// Ensure the status is one of the allowed values (PENDING, ACCEPTED, REJECTED)
if (status == null || !(status == Status.PENDING || status == Status.ACCEPTED
|| status == Status.REJECTED)) {
throw new ParseException(Status.MESSAGE_CONSTRAINTS);
}

return new StatusCommand(index, status);

} catch (ParseException pe) {
throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, StatusCommand.MESSAGE_USAGE), pe);
}
}
}
10 changes: 7 additions & 3 deletions src/main/java/seedu/hireme/model/ModelManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -131,16 +131,20 @@ public void updateFilteredList(Predicate<T> predicate) {

@Override
public boolean equals(Object other) {

// Check if the objects are the same instance
if (other == this) {
return true;
}

// instanceof handles nulls
if (!(other instanceof ModelManager<?> otherModelManager)) {
// Check if the other object is an instance of ModelManager and not null
if (!(other instanceof ModelManager<?>)) {
return false;
}

// Cast the other object to ModelManager
ModelManager<?> otherModelManager = (ModelManager<?>) other;

// Compare the state of addressBook, userPrefs, and filtered lists
return addressBook.equals(otherModelManager.addressBook)
&& userPrefs.equals(otherModelManager.userPrefs)
&& filtered.equals(otherModelManager.filtered);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class InternshipApplication implements HireMeComparable<InternshipApplica
private final Company company;
private final Date dateOfApplication;
private final Role role;
private final Status status;
private Status status;

/**
* Constructs an {@code InternshipApplication} with the specified company, date of application, and role.
Expand All @@ -39,7 +39,7 @@ public InternshipApplication(Company company, Date dateOfApplication, Role role)
}

/**
* Constructs an {@code InternshipApplication} with the specified company, date of application, and role.
* Constructs an {@code InternshipApplication} with the specified company, date of application, role, and status.
* All fields must be present and not null.
*
* @param company The company offering the internship.
Expand All @@ -61,7 +61,7 @@ public InternshipApplication(Company company, Date dateOfApplication, Role role,
/**
* Returns the company associated with the internship application.
*
* @return The company object.
* @return The {@code Company} object.
*/
public Company getCompany() {
return company;
Expand All @@ -70,7 +70,7 @@ public Company getCompany() {
/**
* Returns the name of the company.
*
* @return The name object of the company.
* @return The {@code Name} object of the company.
*/
public Name getCompanyName() {
return company.getName();
Expand All @@ -88,7 +88,7 @@ public String getCompanyNameValue() {
/**
* Returns the date of application for the internship.
*
* @return The date of application.
* @return The {@code Date} of application.
*/
public Date getDateOfApplication() {
return dateOfApplication;
Expand All @@ -97,24 +97,33 @@ public Date getDateOfApplication() {
/**
* Returns the role applied for in the internship.
*
* @return The role object.
* @return The {@code Role} object.
*/
public Role getRole() {
return role;
}

/**
* Returns the status ofthe internship.
* Returns the status of the internship.
*
* @return The status enum.
* @return The {@code Status} enum.
*/
public Status getStatus() {
return status;
}

/**
* Updates the status of the internship application.
*
* @param status The new status to be set.
*/
public void setStatus(Status status) {
this.status = requireNonNull(status);
}

/**
* Returns true if both internship applications have the same company, date of application, and role.
* Defines a weaker notion of equality between two internship applications.
* This defines a weaker notion of equality between two internship applications.
*
* @param otherInternship The other internship application to compare.
* @return True if the specified internship application is the same as the current one, false otherwise.
Expand All @@ -128,12 +137,13 @@ public boolean isSame(InternshipApplication otherInternship) {
return otherInternship != null
&& otherInternship.getCompany().equals(getCompany())
&& otherInternship.getDateOfApplication().equals(getDateOfApplication())
&& otherInternship.getRole().equals(getRole());
&& otherInternship.getRole().equals(getRole())
&& otherInternship.getStatus().equals(getStatus());
}

/**
* Returns true if both internship applications have the same identity and data fields.
* Defines a stronger notion of equality between two internship applications.
* This defines a stronger notion of equality between two internship applications.
*
* @param other The other object to compare.
* @return True if the specified object is equal to the current internship application, false otherwise.
Expand All @@ -151,17 +161,18 @@ public boolean equals(Object other) {
InternshipApplication otherInternship = (InternshipApplication) other;
return company.equals(otherInternship.company)
&& dateOfApplication.equals(otherInternship.dateOfApplication)
&& role.equals(otherInternship.role);
&& role.equals(otherInternship.role)
&& status.equals(otherInternship.status);
}

/**
* Returns the hash code of the internship application based on the company, date of application, and role.
* Returns the hash code of the internship application based on the company, date of application, role, and status.
*
* @return The hash code of the internship application.
*/
@Override
public int hashCode() {
return Objects.hash(company, dateOfApplication, role);
return Objects.hash(company, dateOfApplication, role, status);
}

/**
Expand All @@ -182,6 +193,30 @@ public String toString() {
tsb.add("Role", role);
}

if (status != null) {
tsb.add("Status", status);
}

return tsb.toString();
}

/**
* Creates and returns a deep copy of this {@code InternshipApplication}.
* <p>
* The deep copy ensures that the new {@code InternshipApplication} is a completely independent
* copy, meaning any changes to the new object will not affect the original object.
* This method creates a new {@code Company} instance to avoid sharing mutable state, but since
* {@code String} and {@code Status} are immutable, those are shared directly.
* </p>
*
* @return A new {@code InternshipApplication} instance with the same values as this instance.
*/
public InternshipApplication deepCopy() {
return new InternshipApplication(
new Company(this.company.getEmail(), this.company.getName()), // Deep copy of mutable Company
this.dateOfApplication, // String is immutable, safe to share reference
this.role, // String is immutable, safe to share reference
this.status // Status is immutable (enum), safe to share reference
);
}
}
Loading

0 comments on commit 4e8d317

Please sign in to comment.