Source: staff/index.js

/**
 * Represent a staff member in the restaurant system.
 */
class Staff {
    /**
     * Enum for staff roles.
     * @readonly
     * @enum {string}
     */
    static ROLES = {
        OWNER : "Owner",
        MANAGER : "Manager",
        CAPTAIN : "Captain",
        CHEF : "Chef",
        WAITER : "Waiter",
    };

    /**
     * Enum for staff status.
     * @readonly
     * @enum {string}
     */

    static STATUS = {
        ACTIVE : "Active",
        INACTIVE : "Inactive",
        TERMINATED : "Terminated",
        ON_LEAVE : "On Leave",
    };
 
    /**
     * Enum for staff shift timings.
     * @readonly
     * @enum {string}
     */
   
    static SHIFTS = {
        MORNING : "Morning",
        EVENING : "Evening",
        NIGHT : "Night",
    };

    /**
     * Creates a new Staff member
     * @param {string} id - Unique identifier for the staff member.
     * @param {string} name - full name of the staff member.
     * @param {string} contact - contact details (phone/email).
     * @param {string} address -Residential address of the staff member.
     * @param {string} bankDetails -Bank details for payroll transactions.
     * @param {string} role - Role of the staff member(must be one of `Staff.ROLES`).
     * @param {string[]} [access=[]] - List of permission granted to the staff member.
     * @param {number} [payroll = 0] - Monthly salary of the staff member.
     * @param {string} [status = Staff.STATUS.ACTIVE] - employment status.
     * @param {string} [shift = Staff.SHIFTS.MORNING] - Work shift.
     * @param {number} [performanceRating = 0] - Performance rating (0 to 5).
     * @param {string[]} [experience = 0] - Work experience in years.
     * @param {string[]} [languagesSpoken = []] - Languages spoken by the staff member.
     * @throws {Erroe} If an invalid role, status, shift,performance rating, or experience is provided.
     */
    constructor(id, name, contact, address,bankDetails, role, access = [],payroll = 0, status = Staff.STATUS.ACTIVE, shift = Staff.SHIFTS.MORNING, performanceRating = 0, experience = 0, languagesSpoken = []){
        if (!Object.values(Staff.ROLES).includes(role)){
            throw new Error("Invalid role assigned.")
        }
        if(!Object.values(Staff.STATUS).includes(status)){
            throw new Error("Invalid status assigned.");
        }
        if(!Object.values(Staff.SHIFTS).includes(shift)){
            throw new Error("Invalid shift assigned.");
        }

        if(typeof experience != "number" || experience < 0){
            throw new Error("Experience must be a non-negative number.");
        }
        if(typeof performanceRating !== "number" || performanceRating < 0 || performanceRating > 5){
            throw new Error("Performance rating must be between 0 and 5");
        }

        this.id = id;
        this.name = name;
        this.contact = contact;
        this.address = address;
        this.bankDetails = bankDetails;
        this.role = role;
        this.access = access;
        this.payroll = payroll;
        this.status = status;
        this.shift = shift;
        this.performanceRating = performanceRating;
        this.experience = experience;
        this.languagesSpoken = languagesSpoken;
    }

    /**
     * Updates staff member details.
     * @param {Object} details - The details to update.
     * @param {string} [details.name] - Updated name.
     * @param {string} [details.contact] - Updated contact information.
     * @param {string} [details.address] - Updated address.
     * @param {string} [details.bankDetails] - Updated bank details.
     * @param {string} [details.role] - Updated role (must be a valid Staff.ROLES value).
     * @param {string[]} [details.access] - Updated access permissions.
     * @param {number} [details.payroll] - Updated payroll amount.
     * @param {string} [details.status] - Updated status (must be a valid Staff.STATUS value).
     * @param {string} [details.shift] - Updated shift (must be a valid Staff.SHIFTS value).
     * @param {number} [details.performanceRating] - Updated performance rating (0 to 5).
     * @param {number} [details.experience] - Updated experience in years.
     * @param {string[]} [details.languagesSpoken] - Updated languages spoken.
     */
    updateDetails({name,contact,address, bankDetails,role,access,payroll,status,shift,performanceRating,experience,languagesSpoken}){
      if(name) this.name = name;
      if(contact) this.contact = contact;
      if(address) this.address = address;
      if(bankDetails) this.bankDetails = bankDetails;
      if(role && Object.values(Staff.ROLES).includes(role)) this.role = role;
      if(access) this.access = access;
      if(payroll !== undefined && payroll >= 0) this.payroll = payroll;
      if(status && Object.values(Staff.STATUS).includes(status)) this.status = status;
      if(shift && Object.values(Staff.SHIFTS).includes(shift)) this.shift = shift;
      if(performanceRating !== undefined && performanceRating >= 0 && performanceRating <= 5){
         this.performanceRating = performanceRating;
      }
      if(experience !== undefined && experience >= 0) this.experience = experience;
      if(languagesSpoken) this.languagesSpoken = languagesSpoken;
    }

    /**
    * Grants a new access permission to the staff member.
    * @param {string} permission - The permission to add.
    */
    addAccess(permission){
        if(!this.access.includes(permission)){
            this.access.push(permission);
        }
    }

    /**
     * Removes an access permission from the staff member.
     * @param {string} permission - The permission to remove.
     */
    removeAccess(permission){
        this.access = this.access.filter((perm) => perm !== permission);
    }

    /**
     * Retrieves staff member details.
     * @returns {Object} The staff member's details.
     */
    getDetails() {
        return {
            id: this.id,
            name : this.name,
            contact: this.contact,
            address : this.address,
            bankDetails: this.bankDetails,
            role: this.role,
            access: this.access,
            payroll: this.payroll,
            status: this.status,
            shift: this.shift,
            performanceRating: this.performanceRating,
            experience: this.experience,
            languagesSpoken: this.languagesSpoken,
        };
    }
}

export default Staff;