Developer Guide
- Acknowledgements
- Setting up, getting started
- Design
- Implementation
- Documentation, logging, testing, configuration, dev-ops
- Appendix: Requirements
-
Planned enhancement
- Stricter rules for adding employees with an identical name
- Enhancing UI Dimensions for Optimal Alignment
- Streamlining Calendar Navigation for User Convenience
- Enhancing Deletion Functionality for User Convenience
- Expanding Leave Tracking Capabilities for Enhanced User Flexibility
- Enhanced Access Control for Leave Deletion
- Appendix: Effort
-
Appendix: Instructions for manual testing
- Launch and shutdown
- Adding a new employee
- Deleting an employee
- Reading specific information about a particular employee
- Finding employee(s) via keyword(s)
- Editing employees’ information
- Adding leave to an employee
- Deleting leave for an employee
- Viewing employee(s) who is on leave on a specific date
- Toggle month changing for calendar
- Adding deductions/benefits to the monthly salary of an employee
- Calculating the monthly payroll of an employee
- Generating a PDF payslip for a specific employee
- Marking attendance for an employee
- Generating attendance report for a specific employee
Acknowledgements
- This project uses a third-party library called itext7, which can help the target user of our app, HR managers, to easily generate payslips as PDF files.
itext7
is released under the AGPL license. - This project also uses a third-party library called JavaWuzzy. It is released under the GNU General Public License v2.0.
- Our user needs to type the reason for a deduction or benefit added. With this library used, they do not need to type the exact wording of the reasons in order to match the Reason enum.
Setting up, getting started
Refer to the guide Setting up and getting started.
Design
.puml
files used to create diagrams in this document docs/diagrams
folder. Refer to the PlantUML Tutorial at se-edu/guides to learn how to create and edit diagrams.
Architecture
The Architecture Diagram given above explains the high-level design of the App.
Given below is a quick overview of main components and how they interact with each other.
Main components of the architecture
Main
(consisting of classes Main
and MainApp
) is in charge of the app launch and shut down.
- At app launch, it initializes the other components in the correct sequence, and connects them up with each other.
- At shut down, it shuts down the other components and invokes cleanup methods where necessary.
The bulk of the app’s work is done by the following four components:
-
UI
: The UI of the App. -
Logic
: The command executor. -
Model
: Holds the data of the App in memory. -
Storage
: Reads data from, and writes data to, the hard disk.
Commons
represents a collection of classes used by multiple other components.
How the architecture components interact with each other
The Sequence Diagram below shows how the components interact with each other for the scenario where the user issues the command delete 1
.
Each of the four main components (also shown in the diagram above),
- defines its API in an
interface
with the same name as the Component. - implements its functionality using a concrete
{Component Name}Manager
class (which follows the corresponding APIinterface
mentioned in the previous point.
For example, the Logic
component defines its API in the Logic.java
interface and implements its functionality using the LogicManager.java
class which follows the Logic
interface. Other components interact with a given component through its interface rather than the concrete class (reason: to prevent outside component’s being coupled to the implementation of a component), as illustrated in the (partial) class diagram below.
The sections below give more details of each component.
UI component
The API of this component is specified in Ui.java
The UI consists of a MainWindow
that is made up of parts e.g.CommandBox
, ResultDisplay
, PersonListPanel
, StatusBarFooter
etc. Most of these, excluding the ClockComponent
, CalendarComponent
and YearMonthComponent
, inherit from the abstract UiPart
class which captures the commonalities between classes that represent parts of the visible GUI.
The UI
component uses the JavaFx UI framework. The layout of these UI parts are defined in matching .fxml
files that are in the src/main/resources/view
folder. For example, the layout of the MainWindow
is specified in MainWindow.fxml
The UI
component,
- executes user commands using the
Logic
component. - listens for changes to
Model
data so that the UI can be updated with the modified data. - develops a live clock feature to provide users with a convenient visual representation of the current time while efficiently managing employee data.
- produces a calendar function, allowing users to easily observe the daily count of employees on leave.
- keeps a reference to the
Logic
component, because theUI
relies on theLogic
to execute commands. - depends on some classes in the
Model
component, as it displaysPerson
object residing in theModel
.
Logic component
API : Logic.java
Here’s a (partial) class diagram of the Logic
component:
The sequence diagram below illustrates the interactions within the Logic
component, taking execute("delete 1")
API call as an example.
DeleteCommandParser
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
How the Logic
component works:
- When
Logic
is called upon to execute a command, it is passed to anAddressBookParser
object which in turn creates a parser that matches the command (e.g.,DeleteCommandParser
) and uses it to parse the command. - This results in a
Command
object (more precisely, an object of one of its subclasses e.g.,DeleteCommand
) which is executed by theLogicManager
. - The command can communicate with the
Model
when it is executed (e.g. to delete a person). - The result of the command execution is encapsulated as a
CommandResult
object which is returned back fromLogic
.
Here are the other classes in Logic
(omitted from the class diagram above) that are used for parsing a user command:
How the parsing works:
- When called upon to parse a user command, the
AddressBookParser
class creates anXYZCommandParser
(XYZ
is a placeholder for the specific command name e.g.,AddCommandParser
) which uses the other classes shown above to parse the user command and create aXYZCommand
object (e.g.,AddCommand
) which theAddressBookParser
returns back as aCommand
object. - All
XYZCommandParser
classes (e.g.,AddCommandParser
,DeleteCommandParser
, …) inherit from theParser
interface so that they can be treated similarly where possible e.g, during testing.
Model component
API : Model.java
The Model
component,
- stores the address book data i.e., all
Person
objects (which are contained in aUniquePersonList
object). - stores the currently ‘selected’
Person
objects (e.g., results of a search query) as a separate filtered list which is exposed to outsiders as an unmodifiableObservableList<Person>
that can be ‘observed’ e.g. the UI can be bound to this list so that the UI automatically updates when the data in the list change. - stores a
UserPref
object that represents the user’s preferences. This is exposed to the outside as aReadOnlyUserPref
objects. - does not depend on any of the other three components (as the
Model
represents data entities of the domain, they should make sense on their own without depending on other components)
Storage component
API : Storage.java
The Storage
component,
- can save both address book data and user preference data in JSON format, and read them back into corresponding objects.
- inherits from both
AddressBookStorage
andUserPrefStorage
, which means it can be treated as either one (if only the functionality of only one is needed). - depends on some classes in the
Model
component (because theStorage
component’s job is to save/retrieve objects that belong to theModel
)
Common classes
Classes used by multiple components are in the seedu.addressbook.commons
package.
Implementation
This section describes some noteworthy details on how certain features are implemented.
Read feature
Implementation
The implementation involves the ReadCommand and some associated classes:
-
ReadCommand
— This class is responsible for executing theread
command. It parses the user input, retrieves information from the model, and passes the results to the UI for display. -
ReadCommandParser
— Responsible for parsing user input and creating a ReadCommand object. It extracts the index of the employee in the last shown list and the requested field. -
PersonCardWithSpecificField
- Since we have to display only one specific field, we created another person card with just one field. This class is responsible for displaying the name of the person and a specific field requested by the user in the UI. It receives the necessary information from the command result and formats it for display.
Displaying a specific field with the new PersonCardWithSpecificField
class.
- Before we execute a command, the
MainWindow
will display a list of person with all their fields as shown below.
- After we execute the command, and it is a
ReadCommand
, theReadCommand
will setCommandResult::isRead
to true. TheMainWindow
of UI will then remove all the existingPersonCard
with aPersonCardWithSpecificField
as shown below.
The following class diagram shows how the different classes interact with one another in the read
Feature:
The following activity diagram summarises the process of reading specific field for a particular employee:
This is the sequence diagram to show how the read operation works.
ReadCommandParser
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
The user enters the command read 1 /a
and executes it. The command is then parsed by AddressBookParser
. The AddressBookParser
parses the input and creates ReadCommandParser
and ReadCommandParser
parses the remaining input(exclude the command word). If it parses successfully, it will eventually create a ReadCommand
. The ReadCommand
is then executed. If the index is not out of bounds, it will call Model#setSpecificPersonToDisplay()
to filter the list to only the specific person. Then it will also call the respective getter to get the specific field from the Person
. After getting the specific field, it will then create a CommandResult
for the UI to display.
Design considerations:
Aspect: Data Retrieval:
-
Alternative 1 (current choice): Retrieve only the specific field of the person being read.
- Pros: Reduces memory usage and may improve performance.
- Cons: Requires more complex implementation and handling of different data retrieval scenarios.
-
Alternative 2: Retrieve the entire person’s data when executing the “Read” command.
- Pros: Simple and consistent with other command implementations.
- Cons: May have performance issues if the person’s data is extensive.
Aspect: Using Index:
-
Alternative 1 (current choice): Use an index to identify the target person for the “Read” command.
- Pros: Faster and more efficient execution when working with a large number of people.
- Cons: This may require users to remember or find the index of the person.
-
Alternative 2: Use the person’s name to identify the target person for the “Read” command.
- Pros: User-friendly, especially when users are more likely to identify persons by name.
- Cons: This may result in slower execution when many persons exist in the address book.
Deductions and Benefits
Implementation
The deductions and benefits feature comprises 2 sub-features:
- Add Deduction Feature
- Add Benefit Feature
1. Add Deduction Feature
The Add Deduction feature is facilitated by Deduction
, DeductCommand
, DeductCommandParser
, Person
, PayrollStorage
, Payroll
and Salary
classes.
The Deduction
class is responsible for storing the deduction data for a specific employee.
The DeductCommand
class is responsible for executing the deduct
command.
The DeductCommandParser
class is responsible for parsing the user input for the deduct
command.
The Person
class is responsible for updating the list of deductions.
The PayrollStorage
class is responsible for storing all payroll data for an employee.
The Payroll
class is responsible for storing the monthly payroll data for an employee, including the starting and ending date of the payroll period.
The Salary
class is responsible for storing the monthly salary data for an employee.
The following class diagram shows how the different classes interact with one another in the Add Deduction Feature:
The user can choose to add a deduction for an employee by entering the index of the employee, or the name of the employee. The DeductCommandParser
class is responsible for parsing the user input for the deduct
command.
The following sequence diagram shows how the DeductCommandParser
class parses the user input:
DeductCommandParser
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
When parsing the input, all relevant parameters are extracted according to their respective prefixes, and put into an ArgumentMultimap
.
The value
and reason
are parsed by ParserUtil
class first, and a Deduction
object is created with the parsed value
and reason
.
If the parameters are not in the correct format, a ParseException
will be thrown.
The following sequence diagrams show how the ParserUtil
class parses the value
and reason
:
After fetching the Deduction
object, DeductCommandParser
class will then try to parse the index
first.
The following sequence diagram shows how the DeductCommandParser
class parses the index
:
If the index
is provided and valid, i.e, is a non-zero unsigned integer, the DeductCommandParser
class will create a DeductCommand
object with the index
and deduction
object, and return it.
However, if the index
is not provided, a ParseException
will be thrown by the ParserUtil
class, and the DeductCommandParser
class will try to parse the name
of the employee.
If the name
parameter is also not provided, a ParseException
will be thrown by the DeductCommandParser
class. Otherwise, the DeductCommandParser
class will create a DeductCommand
object with the name
and deduction
object, and return it.
The following sequence diagram shows how the DeductCommandParser
class parses the name
:
The following sequence diagram shows how the deduct
operation works when the user enters the command deduct 1 /v 150.00 /r absence
, which means adding a deduction of $150.00 for the employee with index 1, with the reason of absence
:
DeductCommandParser
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
After DeductCommandParser
class parses the user input, the DeductCommand
class will be called to execute the command. The DeductCommand
class will then call the Model
component to obtain the list of employees, and then obtain the Person
object to add deduction for.
The following sequence diagram shows the referenced process of adding deduction for an employee:
- The
DeductCommand
calls thegetPayrollStorage()
method to obtain thePayrollStorage
object, which stores allPayroll
objects in an ArrayList. - The
Person
object then calls thegetLatestPayroll()
method to get thePayroll
object with the lateststartDate
in the ArrayList. - Then it calls the
addDeduction()
method of thePayroll
object which calls theaddDeduction()
method of theSalary
object within it. - This creates a new
Deduction
object with the givenvalue
andreason
, then store it into thedeductions
field of theSalary
object, which is an ArrayList ofDeduction
objects.
The following activity diagram summarises the process of adding deduction for an employee:
2. Add Benefit Feature
The Add Benefit feature is facilitated by Benefit
, BenefitCommand
, BenefitCommandParser
, Person
, PayrollStorage
, Payroll
and Salary
classes.
The Benefit
class is responsible for storing the benefit data for a specific employee.
The BenefitCommand
class is responsible for executing the benefit
command.
The BenefitCommandParser
class is responsible for parsing the user input for the benefit
command.
The Person
class is responsible for updating the list of benefits.
The PayrollStorage
class is responsible for storing all payroll data for an employee.
The Payroll
class is responsible for storing the monthly payroll data for an employee, including the starting and ending date of the payroll period.
The Salary
class is responsible for storing the monthly salary data for an employee.
The following class diagram shows how the different classes interact with one another in the Add Benefit Feature:
The user can choose to add a benefit for an employee by entering the index of the employee, or the name of the employee. The BenefitCommandParser
class is responsible for parsing the user input for the benefit
command.
The following sequence diagram shows how the BenefitCommandParser
class parses the user input:
BenefitCommandParser
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
When parsing the input, all relevant parameters are extracted according to their respective prefixes, and put into an ArgumentMultimap
.
The value
and reason
are parsed by ParserUtil
class first, and a Benefit
object is created with the parsed value
and reason
.
If the parameters are not in the correct format, a ParseException
will be thrown.
The following sequence diagrams show how the ParserUtil
class parses the value
and reason
:
After fetching the Benefit
object, BenefitCommandParser
class will then try to parse the index
first.
The following sequence diagram shows how the BenefitCommandParser
class parses the index
:
If the index
is provided and valid, i.e, is a non-zero unsigned integer, the BenefitCommandParser
class will create a BenefitCommand
object with the index
and benefit
object, and return it.
However, if the index
is not provided, a ParseException
will be thrown by the ParserUtil
class, and the BenefitCommandParser
class will try to parse the name
of the employee.
If the name
parameter is also not provided, a ParseException
will be thrown by the BenefitCommandParser
class. Otherwise, the BenefitCommandParser
class will create a BenefitCommand
object with the name
and benefit
object, and return it.
The following sequence diagram shows how the BenefitCommandParser
class parses the name
:
The following sequence diagram shows how the benefit
operation works when the user enters the command benefit 1 /v 150.00 /r bonus
, which means adding a benefit of $150.00 for the employee with index 1, with the reason of bonus
:
BenefitCommandParser
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
After BenefitCommandParser
class parses the user input, the BenefitCommand
class will be called to execute the command. The BenefitCommand
class will then call the Model
component to obtain the list of employees, and then obtain the Person
object to add benefit for.
The following sequence diagram shows the referenced process of adding benefit for an employee:
- The
BenefitCommand
calls thegetPayrollStorage()
method to obtain thePayrollStorage
object, which stores allPayroll
objects in an ArrayList. - The
Person
object then calls thegetLatestPayroll()
method to get thePayroll
object with the lateststartDate
in the ArrayList. - Then it calls the
addBenefit()
method of thePayroll
object which calls theaddBenefit()
method of theSalary
object within it. - This creates a new
Benefit
object with the givenvalue
andreason
, then store it into thebenefits
field of theSalary
object, which is an ArrayList ofBenefit
objects.
The following activity diagram summarises the process of adding benefit for an employee:
Payroll
Implementation
The payroll feature comprises 1 sub-feature:
- Payroll Calculation Feature
1. Payroll Calculation Feature
The proposed payroll calculation feature is facilitated by
Payroll
, PayrollCommand
, PayrollCommandParser
, Person
,
PayrollStorage
, Payroll
, Salary
, Benefit
and Deduction
classes.
The Payroll
class is responsible for storing the monthly payroll data for an employee,
including the starting, ending and payment date of the payroll period. It also includes a Salary
object.
The PayrollCommand
is responsible for executing the payroll
command.
The PayrollCommandParser
is responsible for parsing the user input for the deduct
command.
The PayrollStorge
class is responsible for storing all payroll data for an employee.
The Salary
class is responsible for the monthly salary data for an employee, this class includes compulsory
attributes like Basic Salary, a deduction
and benefit
class.
The Benefit
class is responsible for storing the benefit data for a specific employee.
The Deduction
class is responsible for storing the deduction data for a specific employee
The Person
class is responsible for holding all the data of a specific employee,
including the PayrollStorage
.
The following diagram shows the different classes interact with one another in the calculate payroll feature:
The user can choose to calculate the payroll for an employee by
entering the index of the employee, or the name of the employee.
The PayrollCommandParser
class is responsible for parsing the user input for the payroll command.
The following sequence diagram shows how the PayrollCommandParser class parses the user input:
When parsing the input, the input is first passed into ParserUtil#parseIndex method.
This checks if the input intends to calculate the payroll by using the index of the employee.
If it is by name then a ParseException
will be caught and all relevant parameters are extracted according to their respective prefixes, and put into an ArgumentMultimap
.
The following sequence diagram shows how the DeductCommandParser
class parses the index
:
If the index
is provided and valid, i.e, is a non-zero unsigned integer,
the PayrollCommandParser
class will create a DeductCommand
object with the index
and payroll
object, and return it.
However, if the index
is not provided, a ParseException
will be thrown by the ParserUtil
class, and the PayrollCommandParser
class will try to parse the name
of the employee.
If the name
parameter is also not provided, a ParseException
will be thrown by the PayrollCommandParser
class.
Otherwise, the PayrollCommandParser
class will create a PayrollCommand
object with the name
and Payroll
object, and return it.
The following sequence diagram shows how the PayrollCommandParser
class parses the name
:
The following sequence diagram shows how the payroll
operation works when the user enters
the command payroll 1
, which means calculating the payroll for the employee with the index 1:
PayrollCommandParser
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
After PayrollCommandParser
class parses the user input, the PayrollCommand class will be called to execute the command.
The PayrollCommand class will then call the Model component to obtain the list of employees, and then obtain the Person object to calculate payroll for.
The following sequence diagram shows the referenced process of calculating payroll for an employee:
- The
PayrollCommand
calls thegetLatestPayroll()
method to invoke a method in person object. - The Person object then calls the
getLatestPayroll()
method to get thePayroll
object with the latest startDate in thePayrollStorage
object. - The
PayrollCommand
then calls thegetPayrollString()
method of thePayroll
object to get payroll description of the person. - The
Payroll
object then calls thegetNetSalaryString()
method of theSalary
object to get the details of thedeductions
,benefits
and basic salary.
The following activity diagram summarises the process of payroll calculation for an employee:
Payslip Generation
Implementation
The payslip generation feature is facilitated by PayslipGenerator
, PayslipCommand
and PayslipCommandParser
classes.
The PayslipGenerator
class is responsible for generating the payslip for a specific employee.
The PayslipCommand
class is responsible for executing the payslip
command.
The PayslipCommandParser
class is responsible for parsing the user input for the payslip
command.
The following class diagram shows how the different classes interact with one another in the payslip generation feature:
The user can choose to generate a payslip for an employee by entering the index of the employee, or the name of the employee. The PayslipCommandParser
class is responsible for parsing the user input for the payslip
command.
The following sequence diagram shows how the PayslipCommandParser
class parses the user input:
PayslipCommandParser
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
When parsing the input, all relevant parameters are extracted according to their respective prefixes, and put into an ArgumentMultimap
.
If the user provides a date in the form of dd/mm/yyyy
, the date is parsed by ParserUtil
class first, and a LocalDate
object is created with the parsed date.
If the date is not in the correct format, a ParseException
will be thrown.
The following sequence diagram shows how the ParserUtil
class parses the date:
After fetching the LocalDate
object, if any, PayslipCommandParser
class will then try to parse the index
first.
The following sequence diagram shows how the PayslipCommandParser
class parses the index
:
If the index
is provided and valid, i.e, is a non-zero unsigned integer, the PayslipCommandParser
class will create a PayslipCommand
object with the index
(and monthYear
date, if any), and return it.
However, if the index
is not provided, a ParseException
will be thrown by the ParserUtil
class, and the PayslipCommandParser
class will try to parse the name
of the employee.
If the name
parameter is also not provided, a ParseException
will be thrown by the PayslipCommandParser
class. Otherwise, the PayslipCommandParser
class will create a PayslipCommand
object with the name
(and monthYear
date, if any), and return it.
The following sequence diagram shows how the PayslipCommandParser
class parses the name
:
The following sequence diagram shows how the payslip
operation works when the user enters the command payslip 1 /t 09/10/2023
, which means generating a payslip for the employee with index 1, for the month of October 2020:
PayslipCommandParser
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
The following sequence diagram shows the referenced process of generating a payslip for an employee:
- The
PayslipCommand
calls thegeneratePayslip()
method of thePayslipGenerator
class, which calls thegetFieldMap()
method on itself. - The
getFieldMap()
method then calls thegetPayrollWithStartDate()
method on thePerson
object to obtain thePayroll
object with start date equal to the given one within itsPayrollStorage
object, which stores allPayroll
objects in an ArrayList. If the user does not specify amonthYear
date, thegetFieldMap()
method will call thegetLatestPayroll()
method to get thePayroll
object with the lateststartDate
in the ArrayList. - Then it calls various getter methods on the
Payroll
object to obtain the necessary information for the payslip. - This
getFieldMap()
method then returns aHashMap<String, String>
object with the necessary information for the payslip, and the information is written into a PDF file using theitext7
library.
The following activity diagram summarises the process of generating a payslip for an employee:
Leave Tracking
Implementation
The leave tracking feature comprises 3 sub-features:
- Add Leave Feature
- Delete Leave Feature
- View Leave Feature
1. Add Leave Feature
The Add Leave feature is facilitated by AnnualLeave
, AddLeaveCommand
, AddLeaveCommandParser
and Person
classes.
The AnnualLeave
class is responsible for storing the leave data for a specific employee.
The AddLeaveCommand
class is responsible for executing the addleave
command.
The AddLeaveCommandParser
class is responsible for parsing the user input for the addleave
command.
The Person
class is responsible for updating the list of leave.
The following class diagram shows how the different classes interact with one another in the Add Leave Feature:
The following sequence diagram shows how the addleave
operation works:
AddLeaveCommandParser
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
After AddLeaveCommandParser
class parses the user input, the AddLeaveCommand
class will be called to execute the command. The AddLeaveCommand
class will then call the Model
component to obtain the list of employees, and then obtain the Person object to add leave for this employee, and store the leave as an arraylist in AnnualLeave
.
The following activity diagram summarises the process of adding leave for an employee:
Design considerations:
Aspect: How addleave executes:
-
Alternative 1 (current choice): Saves the dates of the leave added.
- Pros: Easy to trace and track when the leaves are applied, and whether employee is working on specific day.
- Cons: May have performance issues in terms of memory usage.
-
Alternative 2: Saves only the total number of days of leave added.
- Pros: will use less memory (e.g. each employee will only need to store an integer for the total number of days of leave per annul)
- Cons: Not much useful information that can be used (e.g. we do not know the working status of each employee for each day)
2. Delete Leave Feature
The Delete Leave feature is facilitated by AnnualLeave
, DeleteLeaveCommand
, DeleteLeaveCommandParser
and Person
classes.
The AnnualLeave
class is responsible for storing the leave data for a specific employee.
The DeleteLeaveCommand
class is responsible for executing the deleteleave
command.
The DeleteLeaveCommandParser
class is responsible for parsing the user input for the deleteleave
command.
The Person
class is responsible for updating the list of leave.
The following class diagram shows how the different classes interact with one another in the Delete Leave Feature:
The following sequence diagram shows how the deleteleave
operation works:
DeleteLeaveCommandParser
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
After DeleteLeaveCommandParser
class parses the user input, the DeleteLeaveCommand
class will be called to execute the command. The DeleteLeaveCommand
class will then call the Model
component to to obtain the list of employees, and then obtain the Person object to delete the leave from this employee, and update the arraylist of leave in AnnualLeave
.
The following activity diagram summarises the process of adding leave for an employee:
Design considerations:
Aspect: How deleteleave executes:
-
Alternative 1 (current choice): Deletes the dates of the leave only if all of them exist in the employee’s list of leave.
- Pros: Ensures that the leave are always deleted correctly and easy to maintain.
- Cons: May cause inconvenience to users as they will have to know the exact dates to delete.
-
Alternative 2: Deletes all the matching dates of leave as long as they exist in employee’s list of leave, ignoring those that do not exist.
- Pros: Users are able to delete the leave within the range of dates that they entered, provided that they exist.
- Cons: Can be confusing to users as to what have been deleted, and also harder to maintain.
3. View Leave Feature
The View Leave feature is facilitated by ViewLeaveCommandParser
and ViewLeaveCommand
The ViewLeaveCommand
class is responsible for executing the viewleave
command.
The ViewLeaveCommandParser
class is responsible for parsing the user input for the viewleave
command.
The following class diagram shows how the different classes interact with one another in the View Leave Feature:
The following sequence diagram shows how the viewleave
operation works:
ViewLeaveCommandParser
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
After parsing user input, the ViewLeaveCommandParser
creates a ViewLeaveCommand
and executes it. This command then interacts with the Model
to fetch the list of employees. Subsequently, it generates a hashmap where each local date corresponds to a list of employees on leave. By querying this hashmap for the specified date, the command identifies employees on leave. Finally, it creates a CommandResult
containing the names of employees on leave for the given date.
The following activity diagram summarises the process of viewing leave for an employee:
Design considerations:
Aspect: How viewleave executes:
-
Alternative 1 (current choice): View the employee who is on leave on the specific date
- Pros: User gets to know which specific employee is on leave on that date
- Cons: Scanning through a list of names could be less efficient
-
Alternative 2: View the number of employee who is on leave on the specific date
- Pros: Simpler implementation, providing a quick count of employees on leave.
- Cons: Users only obtain the number of employees on leave without individual details.
Attendance
Implementation
The attendance marking feature comprises 2 sub-features:
- Mark attendance feature
- Attendance Report feature
These two features are dependent on the following classes:
- AttendanceStorage
- Attendance
- AttendanceType
Below are the relationships between these classes:
markXYZ()
method above is a placeholder for the different methods: markPresent()
, markAbsent()
, and markLate()
.
Each Person
class references a single AttendanceStorage
object, which contains the storage
– an ArrayList<>
of Attendance
objects associated with the given employee.
The AttendanceType is an enumeration with the values PRESENT
, ABSENT
, LATE
, ON_LEAVE
. Each Attendance
object references an AttendanceType
and a date, such that an Attendance
object consists of the day the attendance was recorded as well as the type of attendance that was recorded.
The AttendanceStorage
only stores Attendances
that are late or absent. Dates that are not in the storage are assumed to be marked as present for that given employee.
1. Mark attendance feature
The mark
mechanism is dependent on the Attendance
class. The Attendance class contains information on the date and AttendanceType
of a Person
. It implements the following operations:
-
Attendance#markAbsent(LocalDate date)
– marks the attendance of the employee on the provided date as absent. -
Attendance#markLate(LocalDate date)
– marks the attendance of the employee on the provided date as late.
Given below is an example usage scenario and how the mechanism behaves at each step.
Step 1. The user executes mark 1 /at LATE
command to mark the 1st employee in the list as late.
Step 2. The mark
command calls MarkCommand#markByIndex()
of the given employee, which calls the Attendance#markAbsent()
of the given Person
class associated with that employee.
This working status is then updated in the GUI as shown below:
The sequence diagram for the example above is as shown below:
MarkCommandParser
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
The following class diagram shows how the different classes interact with one another in the mark
feature:
2. Attendance Report feature
The attendance reporting mechanism is dependent on the AttendanceStorage
class. The AttendanceStorage
is a collection of the Attendance
objects associated with an employee. It implements the following operations:
-
AttendanceStorage#getCount
– counts the number of days the attendance of typeattendanceType
appears in theAttendanceStorage
-
AttendanceStorage#getAttendanceReport
– provides anint[]
of the number of days of each attendance type in the following order: [leave, absent, late]
Given below is an example usage scenario and how the mechanism behaves at each step.
Step 1. The user executes attendance 1
command to retrieve the attendance of the first employee.
Step 2. The attendance
command calls AttendanceCommand#reportByIndex()
of the given employee, which calls the AttendanceStorage#getAttendanceReport()
of the given Person
class associated with that employee.
Sequence diagram is as shown below:
AttendanceCommandParser
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
The following class diagram shows how the different classes interact with one another in the attendance
feature:
Finally, the following activity diagram shows how a user would use both the mark
command and attendance
command to take the attendance of her employees:
Design considerations:
Aspect: How AttendanceStorage is assigned to each Person
-
Alternative 1 (current choice): As an attribute of a Person.
- Pros: Easy to query for a Person’s attendance status
- Cons: May be sub-par performance as it would store identical Attendance objects for each Person.
- (Person A could be absent on 24th Oct, Person B could also absent on 24th Oct, but the current software architecture design does not allow shared usage of the duplicates)
-
Alternative 2: As a UniqueAttendanceList.
- Pros: No copies of Attendance objects having the same attribute values
- Cons: Difficult to reference a Person to each Attendance.
Documentation, logging, testing, configuration, dev-ops
Appendix: Requirements
Product scope
Target user profile:
- Human Resource Managers
- has a need to manage a significant number of employees’ information
- prefer desktop apps over other types
- can type fast
- prefers typing to mouse interactions
- is reasonably comfortable using CLI apps
Value proposition: Contact management app to simplify and centralize information for full-time employees. It offers easy access to essential details such as name, email, phone number, address, bank accounts, salary, joining date, and annual leave. With all the information, the app can help to track employees’ annual leave and also generate their payroll automatically. This helps to reduce errors and enhance overall operational efficiency. This results in time and cost savings, improved organization, and a smoother workflow for your business.
User stories
Priorities: High (must have) - * * *
, Medium (nice to have) - * *
, Low (unlikely to have) - *
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
* * * |
user | add new full-time staff members | maintain an up-to-date database of employees. |
* * * |
user | delete an employee’s information | keep the system clean and organized by removing unused data when employees resign |
* * * |
user | edit employee information (contacts, addresses, bank account, etc.) | keep the system clean and organized by removing unused data when employees resign. |
* * * |
new user | easily access the user guide within the app or platform | quickly learn how to use the application’s features and functionalities effectively |
* * |
user | receive concise and informative error messages | quickly identify my mistake and take corrective actions promptly |
* * |
user | generate a report that shows the total payroll amount received by a specific employee | track the employee’s overall compensation. |
* * |
user | effectively manage employees’ annual leave balances | make sure the employees do not exceed their allocated limits |
* * |
user | read specific information about a particular employee | don’t need to manually scroll through multiple pages to find the required information |
* * |
user | close the application using a command | i can expedite the process without relying on the mouse |
* * |
user | calculate payroll for employees to be automatically based on their join dates and proposed salaries | ensure there are no discrepancies in compensation |
* |
user | have a user-friendly application | I can quickly learn how to use it in a short time |
* |
user | have the ability to sort employees by their join date/salary | make informed decisions and efficiently manage the workforce based on the sorted list. |
* |
user | have an application capable of detecting and preventing the input of duplicate employee information | ensure the system does not mix up or duplicate payroll data and also helps to prevent errors. |
Use cases
(For all use cases below, the System is the ManaGease
and the Actor is the user
, unless specified otherwise)
Use case: UC01 – Add a new full-time employee
Guarantees:
- Entered employee will be added.
MSS
- User requests to add a new employee.
- ManaGease adds employee to the employee database.
-
ManaGease displays a confirmation message that an employee has been added.
Use case ends.
Extensions
-
1a. Invalid parameters are included in the command.
-
1a1. ManaGease shows an error message.
-
Use case continues from Step 1.
Use case ends.
-
-
1b. User does not input a compulsory parameter.
-
1b1. ManaGease shows an error message.
-
1b2. User requests to add a new employee.
-
Steps 1b1 and 1b2 repeat until the user inputs a correct command.
Use case continues from Step 2.
-
-
1c. Identical employee is added to the list.
-
1c1. ManaGease shows an error message, identical employee cannot be added to the list.
Use case ends.
-
Use case: UC02 – List all employees
MSS
- User requests to list all employees.
-
ManaGease displays all the employees in the employee database.
Use case ends.
Extensions
-
2a. Employee database is empty.
-
2a1. ManaGease shows an empty list of employees.
Use case ends.
-
Use case: UC03 – Edit information of existing full-time employee
Pre-conditions:
- Employee to edit should exist in the list.
MSS
- User lists the employees.(UC02)
- ManaGease displays a list of all the employees.
- User requests to edit an existing employee.
- ManaGease edits the information of the specified employee.
-
ManaGease displays a confirmation message that information for employees have been updated.
Use case ends.
Extensions
-
3a. Invalid command parameters are given.
-
3a1. ManaGease shows an error message.
Use case continues from step 3.
-
-
3b. Same information is given to edit the person to.
- 3b1. ManaGease shows an error message, the field to change is the same as the existing one.
Use case: UC04 – View one piece of information on a full-time employee
Guarantees:
- Information required from the specified employee will be displayed for the user.
Pre-conditions:
- Employee to view from the list should exist in the list.
MSS
- User lists the employees.(UC02)
- ManaGease shows a list of all the employees.
- User requests to view one piece of information from an existing employee.
-
ManaGease displays the information for an employee.
Use case ends.
Extensions
-
3a. Invalid command parameters are given.
-
3a1. ManaGease shows an error message.
Use case continues from Step 3.
-
Use case: UC05 – Delete and existing employee
Guarantees:
- Entered employee will be deleted.
Pre-conditions:
- Employee to delete from the list should exist in the list.
MSS
- User lists the employees.(UC02)
- ManaGease shows a list of all the employees.
- User requests to delete an existing employee.
-
ManaGease deletes existing employee.
Use case ends.
Extensions
-
3a. Invalid command parameters are given.
- 3a1. ManaGease shows an error message.
Use case resumes from Step 3.
-
3a. User requests to delete existing member via name.
-
3a1. ManaGease will display a list of members with the same name.
Use case ends.
-
-
3b. User inputs an employee index or name that does not exist in the list.
-
3b1. ManaGease shows an error message.
Use case resumes from Step 3.
-
Use case: UC06 – Add deductions/benefits to the monthly salary of an employee
Guarantees:
- Specified employee’s deductions/benefits for the month will be added.
- The specified employee’s monthly salary will decrease based on the deductions for the month and increase based on the benefits for the month.
Pre-conditions:
- Employee to add deductions/benefits to should be in the list.
MSS
- User lists the employees.(UC02)
- ManaGease shows a list of all the employees.
- User requests to add deductions/benefits to the monthly salary of an employee.
- ManaGease adds deductions/benefits to the monthly salary of an employee.
-
ManaGease displays a confirmation message that deductions/benefits have been added.
Use case ends.
Extensions
-
3a. Invalid command parameters are given.
-
3a1. ManaGease shows an error message.
Use case resumes at Step 3.
-
Use case: UC07 – Generate a PDF payslip for a specific employee
Pre-conditions:
- Employee to generate payslip for to should be in the list.
MSS
- User lists the employees.(UC02)
- ManaGease shows a list of all the employees.
- User requests to generate a payslip for a specific employee.
- ManaGease generates a PDF payslip for the employee.
-
ManaGease displays a confirmation message that a payslip has been generated.
Use case ends.
Extensions
-
3a. Invalid command parameters are given.
-
3a1. ManaGease shows an error message.
Use case resumes at Step 3.
-
-
4a. Template file for the payslip is not found.
-
4a1. ManaGease shows an error message, requesting user to add a template file for payslip.
Use case ends.
-
Use case: UC08 – Add leave for a specific employee
Guarantees:
- Specified employee’s days of leave will be added –– they will be considered taken.
- The employee’s remaining days of leave will reduce by the number of leaves added.
Pre-conditions:
- Employee to add leave to should be in the list.
MSS
- User lists the employees.(UC02)
- ManaGease shows a list of all the employees.
- User requests to add leave for a specific employee.
- ManaGease adds leave for the employee.
-
ManaGease displays a confirmation message that the leave has been added.
Use case ends.
Extensions
-
3a. Invalid command parameters are given.
-
3a1. ManaGease shows an error message.
Use case resumes at Step 3.
-
-
3b. Invalid date(s) are given.
-
3b1. ManaGease shows an error message.
Use case resumes at Step 3.
-
-
3c. Non-existing index given.
-
3c1. ManaGease shows an error message.
Use case resumes at Step 3.
-
Use case: UC09 – Delete leave from a specific employee
Guarantees:
- Specified employee’s days of leave will be deleted –– they will no longer be considered taken.
- The employee’s leave will revert back to the original value before the leave was taken.
Pre-conditions:
- Employee to delete leave from should be in the list.
MSS
- User lists the employees.(UC02)
- ManaGease shows a list of all the employees.
- User requests to delete leave from a specific employee.
- ManaGease deletes leave from the employee.
-
ManaGease displays a confirmation message that the leave has been deleted.
Use case ends.
Extensions
-
3a. Invalid command parameters are given.
-
3a1. ManaGease shows an error message.
Use case resumes at Step 3.
-
-
3b. Invalid/Non-existing date(s) are given.
-
3b1. ManaGease shows an error message.
Use case resumes at Step 3.
-
-
3c. Non-existing index given.
-
3c1. ManaGease shows an error message.
Use case resumes at Step 3.
-
Use case: UC10 – View employee who is on leave on a specific date
Guarantees:
- Employees who are on leave on that specific date will be displayed to the user.
MSS
- User requests to view employees who are on leave on a specific date.
- ManaGease check for employees who are on leave on that specific date.
-
ManaGease displays the employees’ names who are on leave on that specific date.
Use case ends.
Extensions
-
3a. Invalid command parameters are given.
-
3a1. ManaGease shows an error message.
Use case resumes at Step 3.
-
-
3b. Invalid date(s) are given.
-
3b1. ManaGease shows an error message.
Use case resumes at Step 3.
-
Use case: UC11 – Mark an employee’s attendance
MSS
- User lists the employees.(UC02)
- ManaGease shows a list of all the employees.
- User requests to mark an employee’s attendance.
- ManaGease changes the employee’s attendance.
- ManaGease displays a confirmation message that the attendance has been marked.
-
ManaGease changes the working status of the employee as the specified attendance type.
Use case ends
Extensions
-
3a. Invalid command parameters are given.
-
3a1. ManaGease shows an error message.
Use case resumes at step 3.
-
-
3b. Invalid attendance type given
-
3b1. ManaGease shows an error message.
Use case resumes at Step 3.
-
-
3c. User requests to delete existing member via name.
-
3c1. ManaGease will display a list of members with the same name.
Use case ends.
-
-
4a. Employee is currently on leave
-
4a1. ManaGease will display an error message, users are not allowed to mark the attendance of an employee on leave.
Use case ends.
-
Use case: UC12 – Calculate the monthly payroll of an employee
Guarantees:
- Specified employee’s payroll details for the month will be displayed.
Pre-conditions:
- Employee to calculate payroll should be in the list.
MSS
- User lists the employees.(UC02)
- ManaGease shows a list of all the employees.
- User requests to calculate monthly payroll of an employee.
-
ManaGease displays a message containing the payroll details.
Use case ends.
Extensions
-
3a. Invalid command parameters are given.
-
3a1. ManaGease shows an error message.
Use case resumes at Step 3.
-
-
3b. User request to calculate the payroll by name.
- 3b1. The database contains two or more employees with the matching name entered by the user
-
3b2. ManaGease displays the employees with the matching name.
Use case resumes at Step 3.
Non-Functional Requirements
- Should work on any mainstream OS as long as it has Java
11
or above installed. - Should be able to hold up to 1000 persons without a noticeable sluggishness in performance for typical usage.
- The application should be designed with an intuitive and user-friendly interface to cater to HR managers who have not previously used such software.
- The application is designed and available exclusively in the English language.
- The application is not required to handle the printing of the reports.
Glossary
- Mainstream OS: Windows, Linux, Unix, OS-X
- HR manager: Human Resource Manager in the company
- Employee: A staff in the company
Planned enhancement
Stricter rules for adding employees with an identical name
-
Currently, the
add
command allows users to add an employee with the same name as an existing one, but in different cases (e.g. John Tan and john tan), and with other fields identical. However, the two employees should be considered the same as they have the same identity, and the command should be modified. To resolve this, we plan to implement a case-insensitive comparison of the names of the employees. -
This can be done by modifying the
equals()
method in thePerson
class to ignore the case of the name, i.e. changingname.equals(other.name)
toname.toLowerCase().equals(other.name.toLowerCase())
.
Enhancing UI Dimensions for Optimal Alignment
-
Our current UI exhibits alignment issues, such as message wrapping to the next line as shown below, and we aim to ensure optimal alignment.
-
To resolve this, we plan to modify the minWidth, minHeight, maxWidth, and maxHeight parameters of the respective boxes for a more refined and cohesive appearance.
Streamlining Calendar Navigation for User Convenience
-
Currently, users need to input commands to switch between months in the UI calendar.
-
In our future plans, we intend to implement a user-friendly dropdown menu along with dedicated next and previous buttons, providing a more intuitive interface for toggling between months.
Enhancing Deletion Functionality for User Convenience
-
Currently, the
delete
command allows the deletion of employee via index and name. However, for the deletion via name, if there are multiple employees with the same name, i.e., Amy Tan, Amy Teo and Amy Lee, even if you enter the commanddelete /n Amy Lee
, which is the full name of one of these employee, it will return a list of these employees with the name “Amy” rather than directly deleting the employee that matches the full name. -
While this is to allow greater flexibility in searching, in our future implementation, we would allow the deletion of employee using the full name to provide more convenience to the users.
Expanding Leave Tracking Capabilities for Enhanced User Flexibility
-
The current leave tracking system only allows users to track the data for annual leave.
-
To better cater to the users of ManaGease, we will implement the ability to track leave for other types of leave like sick leave, parental leave, compassionate leave, etc.
Enhanced Access Control for Leave Deletion
- Currently, the
deleteleave
command does not allow users to delete leave from employee if the date of leave to delete is already over. This is to reduce the likelihood of any unintended or intended change in leave data. However, to offer users greater flexibility in editing the leave data, we will implement some form of access control to allow certain users to have the ability to delete leave data for dates that are already over.
Appendix: Effort
JavaFX Clock and Calendar Component
- Challenges faced :
-
Component Selection
: AB3 initially uses VBox and HBox for layout, but midway through development, we realized that a GridPane offered a more effective solution, leading to a shift in our approach. -
Synchronization
: Ensuring seamless synchronization with the local date and displaying the number of employees on leave -
Command-Based Month Navigation
: Implementing a command-based system for toggling month changes introduced challenges in managing signals to accurately control the month navigation functionality.
-
- Effort required:
-
Iterative Development
: The need for constant adjustments to the layout and functionality, especially during the transition from VBox and HBox to GridPane, required iterative development and continuous refinement. -
Restarting for Alignment Checks
: Verifying alignment in the JavaFX calendar component demanded frequent restarts, leading to considerable time investment in the development process. -
CSS File Interpretation
: Reading through and comprehending the extensive CSS file became a significant effort, as it was crucial for styling and maintaining the visual integrity of the JavaFX calendar component. -
Command-Based Navigation
: Developing and refining the command-based month navigation system required careful consideration of signal management and user interface responsiveness.
-
- Achievements:
-
Effective Layout with GridPane
: Despite the initial challenges, adopting GridPane significantly improved the layout efficiency of our calendar component, ensuring a visually appealing and well-organized interface. -
Successful Synchronization
: Overcoming synchronization complexities, we successfully implemented a calendar component that accurately reflects the local date and dynamically displays the number of employees on leave.
-
Generation of PDF Payslips
- Challenges faced:
-
Printing information onto a PDF template
: The crux of this feature is to collect different deductions, benefits, and payment dates of an employee’s payroll, and print them onto a PDF template. As such, we decided to use theitext7
library to print information onto the template. -
Reading template file
: The template file is a PDF file, and we had to find a way to read the file and obtain the fields in the template. Since we are releasing ManaGease as a single JAR file, we are not supposed to require our users to download the template file from somewhere else.
-
- Effort required:
-
Understanding itext7 APIs
: We then spent some time learning how to use theitext7
library to print information onto a PDF template, by reading the Developer’s Documentation and JavaDoc. -
Maintaining a map between fields and contents
: Since the library only acts as a PDF reader and writer, we must manually obtain all fields (blank spaces) in the template and fill them with the appropriate information. To do so, we created aHashMap<String, String>
to map the fields to their respective contents. This map is then passed to theitext7
library to print the information onto the template. -
Reading template file
: We have tried many methods to read the template file, e.g., reading it as aFile
object, or anInputStream
object. However, the file could not be read when using the JAR file to test.
-
- Achievements:
-
Reading template file
: We managed to read the template file by using thePaySlipGenerator.class.getClassLoader().getResource("template.pdf").toString()
, which returns aString
. TheString
is then passed into thePdfReader
object. This method allows us to read the template file from the JAR file. -
Printing information onto a PDF template
: We managed to print information onto a PDF template using theitext7
library, and thepayslip
command works as intended.
-
Appendix: Instructions for manual testing
Given below are instructions to test the app manually.
Launch and shutdown
-
Initial launch
1a. Download the jar file and copy into an empty folder
1b. Double-click the jar file Expected: Shows the GUI with a set of sample contacts. The window size may not be optimum.
-
Saving window preferences
2a. Resize the window to an optimum size. Move the window to a different location. Close the window.
2b. Re-launch the app by double-clicking the jar file.
Expected: The most recent window size and location is retained.
Adding a new employee
-
Adding a new employee to the list
i. Prerequisites:
- The employee should not already exist in ManaGease, and detection is based on avoiding duplicate names.
ii. Test case:
add /n Jane Smith /e jane@email.com /p 12345678 /a 123 Main St /b 123456789 /jd 12/09/2023 /s 1000.00 /l 10
- Expected: Employee is added to ManaGease. Details of the new employee are shown in the result box. A newly added employee will be positioned at the bottom of the employee card list.
iii. Test case:
add /n Jane Smith /e jane@email.com /p 12345678 /a 123 Main St /b 123456789 /jd 12/09/2023 /s 1000.00
- Expected: As there’s a missing field, the system will not allow the addition of the employee. Error details are shown in the result box.
Deleting an employee
-
Deleting an employee while all employees are being shown
i. Prerequisites:
- List all employees using the
list
command. Multiple employees in the list.
ii. Test case:
delete 1
- Expected: The first employee is deleted from the list. Details of the deleted employee are shown in the result box.
iii. Test case:
delete 0
- Expected: No employee is deleted. Error details are shown in the result box.
iv. Other incorrect delete commands to try:
delete
,delete x
,...
(where x is larger than the list size, excluding negative, non-integer and extremely large integers)- Expected: Similar to previous.
- List all employees using the
Reading specific information about a particular employee
-
Reading specific information about a particular employee while all employees are being shown
i. Prerequisites:
- List all employees using the
list
command. Multiple employees in the list.
ii. Test case:
read 1 /a
- Expected: The first employee and his/her address will be shown on the employee card. A success message is shown in the result box.
iii. Test case:
read 1
- Expected: No information is shown. Error details are shown in the result box.
iv. Other incorrect read commands to try:
read
,read x /e
(where x is larger than the list size, excluding negative, non-integer and extremely large integers)- Expected: Similar to previous.
- List all employees using the
Finding employee(s) via keyword(s)
-
Finding employee(s) via keyword(s)
i. Prerequisites:
- The keyword must be at least one of the employee’s names.
ii. Test case:
find David
- Expected: The employees’ card with a name that contained David will be shown. A success message is shown in the result box.
iii. Test case:
find Dacid Jane
- Expected: The employees’ card with a name that contained David and Jane will be shown. A success message is shown in the result box.
iv. Other incorrect read commands to try:
find
- Expected: Similar to previous.
Editing employees’ information
-
Editing the name of an employee
i. Prerequisites:
- List all employees using the
list
command. Multiple employees in the list. - The employee must exist in the list
ii. Test case:
edit 1 /n Barack Obama
- Expected: The first employee’s name is changed to Barack Obama. A success message with the details of the employees is shown in the result box.
iii. Test case:
edit 1 /n
- Expected: Name does not change. Error details are shown in the result box.
iv. Other incorrect edit commands to try:
edit 1 /n John@~!
,edit x /n Barack Obama
(where x is larger than the list size, excluding negative, non-integer and extremely large integers)- Expected: Similar to previous.
- List all employees using the
-
Editing the email address of an employee
i. Prerequisites:
- List all employees using the
list
command. Multiple employees in the list. - The employee must exist in the list
ii. Test case:
edit 1 /e nihao@yahoo.com
- Expected: The first employee’s email address is changed to nihao@yahoo.com. A success message with the details of the employees is shown in the result box
iii. Test case:
edit 1 /e
- Expected: Email address does not change. Error details are shown in the result box.
iv. Other incorrect edit commands to try:
edit 1 /e nihaogmailcom
,edit x /e nihao@yahoo.com
(where x is larger than the list size, excluding negative, non-integer and extremely large integers)- Expected: Similar to previous.
- List all employees using the
-
Editing the phone number of an employee
i. Prerequisites:
- List all employees using the
list
command. Multiple employees in the list. - The employee must exist in the list
ii. Test case:
edit 1 /p 88881111
- Expected: The first employee’s phone number is changed to 88881111. A success message with the details of the employees is shown in the result box
iii. Test case:
edit 1 /p
- Expected: Name does not change. Error details are shown in the result box.
iv. Other incorrect edit commands to try:
edit 1 /p y
(where y is less than 3 digits),edit x /p 88881111
(where x is larger than the list size, excluding negative, non-integer and extremely large integers)- Expected: Similar to previous.
- List all employees using the
-
Editing the address of an employee
i. Prerequisites:
- List all employees using the
list
command. Multiple employees in the list. - The employee must exist in the list
ii. Test case:
edit 1 /a 123 Bukit Batok SouthWest
- Expected: The first employee’s address is changed to 123 Bukit Batok SouthWest. A success message with the details of the employees is shown in the result box
iii. Test case:
edit 1 /a
- Expected: Address does not change. Error details are shown in the result box.
iv. Other incorrect edit commands to try:
edit x /a 123 Bukit Batok SouthWest
(where x is larger than the list size, excluding negative, non-integer and extremely large integers)- Expected: Similar to previous.
- List all employees using the
-
Editing the bank account number of an employee
i. Prerequisites:
- List all employees using the
list
command. Multiple employees in the list. - The employee must exist in the list
ii. Test case:
edit 1 /b 123456789
- Expected: The first employee’s bank account number is changed to 123456789. A success message with the details of the employees is shown in the result box
iii. Test case:
edit 1 /b
- Expected: Bank account number does not change. Error details are shown in the result box.
iv. Other incorrect edit commands to try:
edit 1 /b y
(where y is less than 5 digits or more than 17 digits),edit x /b 123456789
(where x is larger than the list size, excluding negative, non-integer and extremely large integers)- Expected: Similar to previous.
- List all employees using the
-
Editing the join date of an employee
i. Prerequisites:
- List all employees using the
list
command. Multiple employees in the list. - The employee must exist in the list
ii. Test case:
edit 1 /jd 12/11/2023
- Expected: The first employee’s join date is changed to 12/11/2023. A success message with the details of the employees is shown in the result box
iii. Test case:
edit 1 /jd
- Expected: Join date does not change. Error details are shown in the result box.
iv. Other incorrect edit commands to try:
edit 1 /jd 15 Dec 2023
,edit x /jd 12/11/2023
(where x is larger than the list size, excluding negative, non-integer and extremely large integers)- Expected: Similar to previous.
- List all employees using the
-
Editing the basic salary of an employee
i. Prerequisites:
- List all employees using the
list
command. Multiple employees in the list. - The employee must exist in the list
ii. Test case:
edit 1 /s 2000.00
- Expected: The first employee’s basic salary is changed to 2000.00. A success message with the details of the employees is shown in the result box
iii. Test case:
edit 1 /s
- Expected: Basic salary does not change. Error details are shown in the result box.
iv. Other incorrect edit commands to try:
edit 1 /s 2000
,edit 1 /s -500.00
,edit x /s 2000.00
(where x is larger than the list size, excluding negative, non-integer and extremely large integers)- Expected: Similar to previous.
- List all employees using the
-
Editing the promised annual leave number of an employee
i. Prerequisites:
- List all employees using the
list
command. Multiple employees in the list. - The employee must exist in the list
ii. Test case:
edit 1 /l 15
- Expected: The first employee’s promised annual leave number is changed to 15. A success message with the details of the employees is shown in the result box
iii. Test case:
edit 1 /l
- Expected: The promised annual leave number does not change. Error details are shown in the result box.
iv. Other incorrect edit commands to try:
edit 1 /l -15
,edit x /l 15
(where x is larger than the list size, excluding negative, non-integer and extremely large integers)- Expected: Similar to previous.
- List all employees using the
-
Editing multiple fields of an employee
i. Prerequisites:
- List all employees using the
list
command. Multiple employees in the list. - The employee must exist in the list
ii. Test case:
edit 1 /n Jack Ma /p 12341234
- Expected: The first employee’s name is changed to Jack Ma and his phone number is changed to 12341234. A success message with the details of the employees is shown in the result box
iii. Test case:
edit 1 /n Jack Ma /p 12341234 /b 123456789 /l 2
- Expected: The first employee’s name is changed to Jack Ma, his phone number is changed to 12341234, his bank account number is changed to 123456789 and his promised annual leave number is changed to 2. A success message with the details of the employees is shown in the result box
iv. Other incorrect edit commands to try:
edit 1 /n /p 12341234 /b 123456789
,edit x /n Jack Ma /p 12341234
(where x is larger than the list size, excluding negative, non-integer and extremely large integers)- Expected: Similar to previous.
- List all employees using the
Adding leave to an employee
-
Adding one leave to an employee while all persons are being shown
i. Prerequisites:
- List all persons using the
list
command. Multiple persons in the list. - The employee should possess a minimum of one leave balance.
ii. Test case:
addleave 1 /on 13/11/2023
- Expected: One leave is added to the first employee on the list. A success message with the details of the employee and leave balance for the current year and next year is shown in the result box.
iii. Test case:
addleave 1 /on 35/11/2023
- Expected: No leave is added. Error details are shown in the result box.
iv. Other incorrect addleave commands to try:
addleave
,addleave x /on 13/11/2023
(where x is larger than the list size, excluding negative, non-integer and extremely large integers),addleave 1 /on DATE
(DATE is where the date has already passed)- Expected: Similar to previous.
- List all persons using the
-
Adding multiple leaves to an employee while all persons are being shown
i. Prerequisites:
- List all persons using the
list
command. Multiple persons in the list. - The employee should have at least the specified number of leave days available in their balance for the application to be processed.
ii. Test case:
addleave 1 /from 13/11/2023 /to 15/11/2023
- Expected: Multiple leaves is added to the first employee on the list. A success message with the details of the employee and leave balance for the current year and next year is shown in the result box.
iii. Test case:
addleave 1 /from 35/11/2023 /to 15/11/20233
- Expected: No leave is added. Error details are shown in the result box.
iv. Other incorrect addleave commands to try:
addleave
,addleave x /from 13/11/2023
,addleave x /to 14/11/2023
,addleave x /from 13/11/2023 /to 14/11/2023
(where x is larger than the list size, excluding negative, non-integer and extremely large integers),addleave 1 /on DATE
(DATE is where the date has already passed)- Expected: Similar to previous.
- List all persons using the
Deleting leave for an employee
-
Deleting one leave to an employee while all persons are being shown
i. Prerequisites:
- List all persons using the
list
command. Multiple persons in the list. - The employee should be originally on leave on the date.
ii. Test case:
deleteleave 1 /on 13/11/2023
- Expected: One leave is deleted for the first employee on the list. A success message with the details of the employee and leave balance for the current year and next year is shown in the result box.
iii. Test case:
deleteleave 1 /on 35/11/2023
- Expected: No leave is deleted. Error details are shown in the result box.
iv. Other incorrect deleteleave commands to try:
deleteleave
,deleteleave x /on 13/11/2023
(where x is larger than the list size, excluding negative, non-integer and extremely large integers),deleteleave 1 /on DATE
(DATE is where the date has already passed)- Expected: Similar to previous.
- List all persons using the
-
Deleting multiple leaves for an employee while all persons are being shown
i. Prerequisites:
- List all persons using the
list
command. Multiple persons in the list. - The employee should be originally on leave on those dates.
ii. Test case:
deleteleave 1 /from 13/11/2023 /to 15/11/2023
- Expected: Multiple leaves are deleted for the first employee on the list. A success message with the details of the employee and leave balance for the current year and next year is shown in the result box.
iii. Test case:
deleteleave 1 /from 35/11/2023 /to 15/11/20233
- Expected: No leave is added. Error details are shown in the result box.
iv. Other incorrect deleteleave commands to try:
deleteleave
,deleteleave x /from 13/11/2023
,deleteleave x /to 14/11/2023
,deleteleave x /from 13/11/2023 /to 14/11/2023
(where x is larger than the list size, excluding negative, non-integer and extremely large integers),deleteleave 1 /on DATE
(DATE is where the date has already passed)- Expected: Similar to previous.
- List all persons using the
Viewing employee(s) who is on leave on a specific date
-
Viewing employee(s) who is on leave on a specific date
i. Prerequisites:
- There should be at least one employee on leave on the specified date.
ii. Test case:
viewleave /on 13/11/2023
- Expected: A success message with the name(s) of the employee(s) on leave on the specified date is shown in the result box.
iii. Test case:
viewleave /on 35/11/2023
- Expected: Error details are shown in the result box.
iv. Other incorrect deleteleave commands to try:
viewleave
,viewleave /on
- Expected: Similar to previous.
Toggle month changing for calendar
-
Toggle to the next month
i. Test case:
nm
- Expected: The calendar should transition to the calendar of the next month.
-
Toggle to the previous month
i. Test case:
pm
- Expected: The calendar should transition to the calendar of the previous month.
-
Toggle to the current month
i. Test case:
cm
- Expected: The calendar should transition to the calendar of the current month.
Adding deductions/benefits to the monthly salary of an employee
-
Adding deductions to the monthly salary of an employee
i. Prerequisites:
- List all employees using the
list
command. Multiple employees in the list. - The employee should exist in the list.
ii. Test case:
deduct 1 /v 100.00 /r cpf
- Expected: A deduction of $100.00 is added to the first employee’s monthly salary. A success message with the deductions of the employee is shown in the result box.
iii. Test case:
deduct 1 /v 100.00 /r
- Expected: Reason is missing. Error details are shown in the result box.
iv. Test case:
deduct 1 /v 100.00 /r bonus
- Expected: Reason is invalid for deductions. Error details are shown in the result box.
v. Test case:
deduct 1 /v 100 /r cpf
- Expected: Value (Payment) is in an invalid format. Error details are shown in the result box.
vi. Test case:
deduct 1 /v 100.00
ordeduct 1
- Expected: Reason prefix is missing. Error details are shown in the result box.
vii. Test case:
deduct
- Expected: Index or name is missing. Error details are shown in the result box.
- List all employees using the
-
Adding benefits to the monthly salary of an employee
i. Prerequisites:
- List all employees using the
list
command. Multiple employees in the list. - The employee should exist in the list.
ii. Test case:
benefit 1 /v 100.00 /r bonus
- Expected: A benefit of $100.00 is added to the first employee’s monthly salary. A success message with the benefits of the employee is shown in the result box.
iii. Test case:
benefit 1 /v 100.00 /r
- Expected: Reason is missing. Error details are shown in the result box.
iv. Test case:
benefit 1 /v 100.00 /r cpf
- Expected: Reason is invalid for benefits. Error details are shown in the result box.
v. Test case:
benefit 1 /v 100 /r bonus
- Expected: Value (Payment) is in an invalid format. Error details are shown in the result box.
vi. Test case:
benefit 1 /v 100.00
orbenefit 1
- Expected: Reason prefix is missing. Error details are shown in the result box.
vii. Test case:
benefit
- Expected: Index or name is missing. Error details are shown in the result box.
- List all employees using the
Calculating the monthly payroll of an employee
- Calculating payroll for a specific employee
i. Prerequisites:
- List all employees using the
list
command. Multiple employees in the list. - The employee should exist in the list.
ii. Test case:
payroll 1
- Expected: A success message showing the payroll details of first employee in the list.
iii. Test case:
payroll /n
- Expected: Name is missing. Error details are shown in the result box.
iv. Test case:
payroll
- Expected: Index or name is missing. Error details are shown in the result box.
- List all employees using the
Generating a PDF payslip for a specific employee
-
Generating a PDF payslip for a specific employee
i. Prerequisites:
- List all employees using the
list
command. Multiple employees in the list. - The employee should exist in the list.
ii. Test case:
payslip 1
- Expected: A PDF payslip for the first employee is generated under
payslips/
. A success message is shown in the result box.
iii. Test case:
payslip 1 /t 17/11/2023
- Expected: A PDF payslip for the first employee is generated under
payslips/
for the specified month. A success message is shown in the result box.
iv. Test case:
payslip 1 /t 35/11/2023
- Expected: Invalid date provided. Error details are shown in the result box.
v. Test case:
payslip 1 /t
- Expected: Date is missing. Error details are shown in the result box.
vi. Test case:
payslip 1 /t 17/11/2024
- Expected: Date is in the future, and there is no payroll for the employee for the given payroll period. Error details are shown in the result box.
- List all employees using the
Marking attendance for an employee
-
Marking the attendance of an employee
i. Prerequisites:
- List all employees using the
list
command. Multiple employees in the list. - The employee should exist in the list.
ii. Test case:
mark 1 /at late
- Expected: The first employee is marked as late. A success message is shown in the result box.
iii. Test case:
mark /n John /at late
- Expected: The employee named “John” is marked as late. A success message is shown in the result box.
iv. Test case:
mark 1 /at idk
- Expected: Invalid attendance type provided. Error details are shown in the result box.
v. Test case:
mark 1
- Expected: The attendance type is not provided. Error details are shown in the result box.
vi. Test case:
mark 1 /at
- Expected: The attendance type is not provided. Error details are as shown in the result box.
vii. Test case:
mark /at present
- Expected: The index and name is not provided. Error details are as shown in the result box.
viii. Test case:
mark /n /at late
- Expected: No name provided. Error details are as shown in the result box.
- List all employees using the
Generating attendance report for a specific employee
-
Reporting the attendance of an employee.
i. Prerequisites:
- List all employees using the
list
command. Multiple employees in the list. - The employee should exist in the list.
ii. Test case:
attendance 1
- Expected: The first employee’s attendance report is shown in the result box.
iii. Test case:
attendance /n John
- Expected: The employee named “John”’s attendance report is shown in the result box.
iv. Test case:
attendance
- Expected: The index and name is not provided. Error details are shown in the result box.
v. Test case:
attendance /n
- Expected: The name is not provided. Error details are shown in the result box.
- List all employees using the