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

Feat: Add leave #62

Merged
merged 19 commits into from
Oct 14, 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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
/build/
src/main/resources/docs/
/bin
/.settings

# IDEA files
/.idea/
Expand Down
17 changes: 9 additions & 8 deletions docs/UserGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,19 +157,20 @@ Examples:
- `list` followed by `claim 1 $/-500` deducts $50 from the claims of the 1st employee in the list.
- `list` followed by `claim 2 $/+60` adds $60 to the claims of the 2nd employee in the list.

### Adding Employee’s Leave: `add_leave`
### Adding Employee’s Leave: `leave`

Adds a new leave for an employee.
Adds leave months for an employee.

Format: `add_leave INDEX m/MONTH`
Format: `leave INDEX m/MONTHS`

- The `INDEX` refers to the index number shown in the displayed employee list.
- The index **must be a positive integer** 1,2,3, ...
- The `MONTH` refers to the month of the leave the employee is taking in integer format (between 1-12).
- The `INDEX` **must be a positive integer** 1,2,3, ...
- The `MONTHS` refers to the month of the leave the employee is taking in integer format (between 1-12).
- Positive `MONTHS` add leaves on the specified months and negative `MONTHS` remove them.

Examples:
- `list` followed by `add_leave 1 m/3` adds a leave on January for the 1st employee in the list.
- `list` followed by `add_leave 3 m/12` adds a leave on December for the 3rd employee in the list.
- `list` followed by `leave 1 m/3,4` adds leaves in March and April for the 1st employee in the list.
- `list` followed by `leave 3 m/11,-12` adds a leave in Nov and removes a leave in Dec for the 3rd employee in the list.

### Viewing all employees' leaves : `view_leave`

Expand Down Expand Up @@ -242,7 +243,7 @@ If your changes to the data file makes its format invalid, HR Insight will disca
| **Find** | `find KEYWORD [MORE_KEYWORDS]`<br> e.g., `find James Jake` |
| **List** | `list [d/DEPARTMENT]` |
| **Claim** | `claim INDEX $/CLAIM_AMOUNT` <br> e.g., `claim 1 $/-500` |
| **Add Leave** | `add_leave INDEX m/MONTH` <br> e.g., `add_leave 1 m/3` |
| **Add Leave** | `leave INDEX m/MONTHS` <br> e.g., `leave 1 m/3,-4` |
| **Help** | `help` |
| **View Leave** | `view_leave INDEX m/Month d/DEPARTMENT` <br> e.g.,`view_leave m/10 d/IT` |
| **View Birthdays** | `birthday [m/MONTH]` <br> e.g., `birthday 10` |
4 changes: 2 additions & 2 deletions src/main/java/seedu/address/logic/Messages.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ public class Messages {

public static final String MESSAGE_UNKNOWN_COMMAND = "Unknown command";
public static final String MESSAGE_INVALID_COMMAND_FORMAT = "Invalid command format! \n%1$s";
public static final String MESSAGE_INVALID_PERSON_DISPLAYED_INDEX = "The person index provided is invalid";
public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d persons listed!";
public static final String MESSAGE_INVALID_PERSON_DISPLAYED_INDEX = "The employee index provided is invalid";
public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d employees listed!";
public static final String MESSAGE_DUPLICATE_FIELDS = "Multiple values specified for the "
+ "following single-valued field(s): ";
public static final String MESSAGE_OVER_CLAIM = "Claim is REJECTED as the amount is greater than "
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/seedu/address/logic/commands/AddCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public class AddCommand extends Command {
+ PREFIX_DOB + "1999-07-23";

public static final String MESSAGE_SUCCESS = "New employee added: %1$s";
public static final String MESSAGE_DUPLICATE_PERSON = "This person already exists in the address book";
public static final String MESSAGE_DUPLICATE_PERSON = "The employee already exists in the address book";

private final Person toAdd;

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

import static java.util.Objects.requireNonNull;
import static seedu.address.logic.parser.CliSyntax.PREFIX_MONTH;
import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PERSONS;

import java.util.List;

import seedu.address.commons.core.index.Index;
import seedu.address.commons.util.ToStringBuilder;
import seedu.address.logic.Messages;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.model.Model;
import seedu.address.model.person.Leave;
import seedu.address.model.person.Person;

/**
* Adds leave months for an employee.
*/
public class LeaveCommand extends Command {

public static final String COMMAND_WORD = "leave";

public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds leave months for an employee.\n"
+ "Parameters: INDEX (must be a positive integer) " + PREFIX_MONTH + "MONTHS\n"
+ "Format: MONTHS must be integers separated by commas without spaces. "
+ "1: Jan, 2: Feb, ..., 12: Dec.\n"
+ "Positive MONTHS add leaves on the specified months and negative MONTHS remove them.\n"
+ "Example: " + COMMAND_WORD + " 1 "
+ PREFIX_MONTH + "3,-4 to add leave in March and remove leave in April for the 1st employee in the list.";

public static final String MESSAGE_AMBIGUOUS = "Please check your MONTHS. Ambiguous leave(s) assignment.\n";
public static final String MESSAGE_EMPTY = "MONTHS cannot be empty.\n";
public static final String MESSAGE_INVALID_MONTH = "Please check your MONTHS. Invalid month provided.\n";
public static final String MESSAGE_LEAVE_SUCCESS = "Leave(s) successfully updated for employee: %1$s.\n"
+ "Current leave(s): %2$s";
public static final String MESSAGE_NOT_A_NUMBER = "Please check your MONTHS. Some is not a number.\n";
public static final String MESSAGE_NOT_EDITED = "The employee's leave(s) does not change from previous state: %1$s";
public static final String MESSAGE_SPACES_DETECTED = "Spaces detected in your MONTHS.\n";

private final Index index;
private final String change;

/**
* Constructs a LeaveCommand to update the {@code Leave} of a {@code Person}
* with the given index.
* @param index
* @param change
*/
public LeaveCommand(Index index, String change) {
requireNonNull(index);
requireNonNull(change);

this.index = index;
this.change = change;
}

@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
List<Person> lastShownList = model.getFilteredPersonList();

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

Person oldPerson = lastShownList.get(index.getZeroBased());
Leave oldLeave = oldPerson.getLeave();
Leave newLeave = oldLeave.update(change);

if (oldLeave.equals(newLeave)) {
throw new CommandException(String.format(MESSAGE_NOT_EDITED, oldLeave.toString()));
}

Person newPerson = new Person(oldPerson.getName(), oldPerson.getPhone(), oldPerson.getEmail(),
oldPerson.getAddress(), oldPerson.getSalary(), oldPerson.getClaimBudget(),
oldPerson.getDepartment(), oldPerson.getDob(), newLeave);

model.setPerson(oldPerson, newPerson);
model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
return new CommandResult(String.format(MESSAGE_LEAVE_SUCCESS, newPerson.getName(), newLeave.toString()));
}

@Override
public boolean equals(Object other) {
if (other == this) {
return true;
}

// instanceof handles nulls
if (!(other instanceof LeaveCommand)) {
return false;
}

LeaveCommand otherCommand = (LeaveCommand) other;
return index.equals(otherCommand.index)
&& change.equals(otherCommand.change);
}

@Override
public String toString() {
return new ToStringBuilder(this)
.add("index", index)
.add("leave", change)
.toString();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package seedu.address.logic.parser;

import static java.util.Objects.requireNonNull;
import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS;
import static seedu.address.logic.parser.CliSyntax.PREFIX_CLAIM_BUDGET;
Expand Down Expand Up @@ -34,6 +35,7 @@ public class AddCommandParser implements Parser<AddCommand> {
* @throws ParseException if the user input does not conform the expected format
*/
public AddCommand parse(String args) throws ParseException {
requireNonNull(args);
ArgumentMultimap argMultimap =
ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS,
PREFIX_SALARY, PREFIX_CLAIM_BUDGET, PREFIX_DEPARTMENT, PREFIX_DOB);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import seedu.address.logic.commands.ExitCommand;
import seedu.address.logic.commands.FindCommand;
import seedu.address.logic.commands.HelpCommand;
import seedu.address.logic.commands.LeaveCommand;
import seedu.address.logic.commands.ListCommand;
import seedu.address.logic.parser.exceptions.ParseException;

Expand Down Expand Up @@ -81,6 +82,9 @@ public Command parseCommand(String userInput) throws ParseException {
case ClaimCommand.COMMAND_WORD:
return new ClaimCommandParser().parse(arguments);

case LeaveCommand.COMMAND_WORD:
return new LeaveCommandParser().parse(arguments);

default:
logger.finer("This user input caused a ParseException: " + userInput);
throw new ParseException(MESSAGE_UNKNOWN_COMMAND);
Expand Down
1 change: 1 addition & 0 deletions src/main/java/seedu/address/logic/parser/CliSyntax.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public class CliSyntax {
public static final Prefix PREFIX_CLAIM_BUDGET = new Prefix("b/");
public static final Prefix PREFIX_DEPARTMENT = new Prefix("d/");
public static final Prefix PREFIX_DOB = new Prefix("dob/");
public static final Prefix PREFIX_MONTH = new Prefix("m/");
public static final Prefix PREFIX_TAG = new Prefix("t/");
public static final Prefix PREFIX_CLAIM_AMOUNT = new Prefix("$/");
}
77 changes: 77 additions & 0 deletions src/main/java/seedu/address/logic/parser/LeaveCommandParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package seedu.address.logic.parser;

import static java.util.Objects.requireNonNull;
import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.address.logic.parser.CliSyntax.PREFIX_MONTH;

import seedu.address.commons.core.index.Index;
import seedu.address.logic.commands.LeaveCommand;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.person.Leave;

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

/**
* Parses the given {@code String} of arguments in the context of the LeaveCommand
* and returns an LeaveCommand object for execution.
* @throws ParseException if the user input does not conform the expected format
*/
public LeaveCommand parse(String args) throws ParseException {
requireNonNull(args);
System.out.println(args);
ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_MONTH);

Index index;
try {
index = ParserUtil.parseIndex(argMultimap.getPreamble());
} catch (ParseException pe) {
throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, LeaveCommand.MESSAGE_USAGE), pe);
}
argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_MONTH);
if (argMultimap.getValue(PREFIX_MONTH).isPresent()) {
return new LeaveCommand(index, parseLeave(argMultimap.getValue(PREFIX_MONTH).get()));
} else {
throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, LeaveCommand.MESSAGE_USAGE));
}
}

private String parseLeave(String arg) throws ParseException {
arg = arg.trim();
if (arg.length() == 0) {
throw new ParseException(LeaveCommand.MESSAGE_EMPTY + LeaveCommand.MESSAGE_USAGE);
}
int len = arg.split("\\s+").length;
if (len > 1) {
throw new ParseException(LeaveCommand.MESSAGE_SPACES_DETECTED + LeaveCommand.MESSAGE_USAGE);
}
StringBuilder months = new StringBuilder(Leave.NO_LEAVE);
String[] args = arg.split(",");
for (int i = 0; i < args.length; i++) {
if (args[i].length() > 3) {
throw new ParseException(LeaveCommand.MESSAGE_INVALID_MONTH + LeaveCommand.MESSAGE_USAGE);
}
try {
if (args[i].charAt(0) == '-') {
Integer month = Integer.valueOf(args[i].substring(1));
if (months.charAt(month - 1) == '+') {
throw new ParseException(LeaveCommand.MESSAGE_AMBIGUOUS + LeaveCommand.MESSAGE_USAGE);
}
months.setCharAt(month - 1, '-');
} else {
Integer month = Integer.valueOf(args[i]);
if (months.charAt(month - 1) == '-') {
throw new ParseException(LeaveCommand.MESSAGE_AMBIGUOUS + LeaveCommand.MESSAGE_USAGE);
}
months.setCharAt(month - 1, '+');
}
} catch (NumberFormatException e) {
throw new ParseException(LeaveCommand.MESSAGE_NOT_A_NUMBER + LeaveCommand.MESSAGE_USAGE);
}
}
return months.toString();
}

}
Loading
Loading