# Question 3: Object Oriented Programming [5 Marks]

**Assessment:** FA1 Mock Hands-On (PMIS-FA-1-Generic-Mock)  
**Package / Classes:** `Course`, `Certification`, `Employee`

---

## Problem Description
**"UpSkill"** global educational organization offers training and certification. To get certified, users must take a prerequisite course and pay fees for both. Automate fee calculation based on the given class diagram.

---

## Class Diagram

```mermaid
classDiagram
    class Course {
        -courseAuthor: String
        -skillRequisite: boolean
        -courseName: String
        +Course(courseAuthor: String, skillRequisite: boolean, courseName: String)
        +getCourseAuthor(): String
        +identifyCourseFee(): int
        +toString(): String
    }

    class Certification {
        -counter: int
        -certificationId: String
        -course: Course
        -modeOfCertification: String
        -certificationFee: double
        +Certification(course: Course, modeOfCertification: String)
        +getCertificationId(): String
        +getCertificationFee(): double
        +getCourse(): Course
        +setCertificationId(certificationId: String): void
        +setCertificationFee(certificationFee: double): void
        +generateCertificationId(): void
        +identifyModeOfCertificationFee(): int
        +toString(): String
    }

    class Employee {
        -courseTypeArr: String[][] $
        -employeeName: String
        -employeeType: String
        -orgName: String
        -reqCourseType: String
        +Employee(course: Course, modeOfCertification: String, employeeName: String, employeeType: String, orgName: String, reqCourseType: String)
        +validateEmployee(): boolean
        +identifyDiscountPercent(certification: Certification): Integer
        +calculateTotalFee(certification: Certification): void
        +toString(): String
    }

    Certification o-- Course : aggregates
    Employee --|> Certification : extends
```

---

## Important Notes & Constraints
- **DO NOT** include any extra instance/static variables and instance/static methods in the given classes.
- **Case-sensitive** comparison is to be done if not explicitly mentioned otherwise.
- **DO NOT** change any value or case of the given variables.
- **NO NEED** to validate the assumption.
- In the derived classes, the order of passing arguments to the constructor would be **base class variables followed by derived class variables**.
- `courseTypeArr` is a static array `(String[][])` where the first array contains available course types and second array contains the corresponding fee:
  ```java
  String[][] courseTypeArr = {
      {"Concept Based", "Hands-On", "Hybrid"},
      {"200.0", "500.0", "1000.0"}
  };
  ```

---

## Method Specifications

### 1. `Course` Class
| Method Name | Implementation Details |
|---|---|
| `identifyCourseFee(): int` | Code provided, no need to implement |

### 2. `Certification` Class
| Method Name | Implementation Details |
|---|---|
| `generateCertificationId(): void` | Code provided, no need to implement |
| `identifyModeOfCertificationFee(): int` | Code provided, no need to implement |

### 3. `Employee` Class
| Method Name | Implementation Details |
|---|---|
| `validateEmployee(): boolean` | Code provided, no need to implement |
| `identifyDiscountPercent(certification: Certification): Integer` | Code provided, **enhance as per requirement** |
| `calculateTotalFee(certification: Certification): void` | **Need to be implemented** |

---

## Implementation Requirements

### Method: `identifyDiscountPercent(certification: Certification): Integer`
The current implementation of this method sets discount of `10` if the employee is valid (`validateEmployee() == true`). Otherwise, it sets it to `0`.
Enhance the logic to update the discount percent and return the same as per the requirements below:
1. If the mode fee identified by `identifyModeOfCertificationFee()` method of `Certification` class is at least **350 currency**, then provide an additional discount of **5**.
2. Identify additional discount based on the course fee determined by `identifyCourseFee()` method of `Course` class, as per the table below:

| Course Fee | Additional Discount |
|---|---|
| 4500 and above | 10 |
| Between 3500 (inclusive) and 4500 (exclusive) | 8 |
| Between 2500 (inclusive) and 3500 (exclusive) | 5 |

3. Return the final discount percent.

---

### Method: `calculateTotalFee(certification: Certification): void`
1. Invoke the `identifyCourseFee()` method of `Course` class to identify `courseFee` (double).
2. Identify `basicFee` (int) as **5000** currency.
3. Invoke the `validateEmployee()` method.
4. If the invoked method returns `true` AND `courseFee` is not `-1.0`:
   - For `reqCourseType` present as one of the elements of the first array of `courseTypeArr`, identify `cost` (double) as the corresponding fee from the second array of `courseTypeArr`. Perform **case-sensitive** comparison.
   - Update the `cost` by adding the identified `basicFee` and `courseFee`.
   - Check if `employeeType` is `"Trainee"` and `orgName` is `"Infosys"` (case-insensitive). If so, update `cost` by deducting an amount of **2000.0** currency.
   - Set the `certificationFee` of `Certification` class with the identified `cost`.
   - Invoke `generateCertificationId()` method of `Certification` class to generate the `certificationId`.
5. Otherwise:
   - Set `certificationFee` to `-1.0`.
   - Set `certificationId` to `"NA"` in uppercase.

---

## Example Walkthrough
If:
- `employeeName` = `"Jasmine"`
- `employeeType` = `"TraiNEe"`
- `orgName` = `"InFosYs"`
- `reqCourseType` = `"Hands-On"`
- `courseAuthor` = `"Peter"`
- `skillRequisite` = `true`
- `courseName` = `"Ethical-Hacking"`
- `modeOfCertification` = `"Desk"`

Then:
- `identifyModeOfCertificationFee()` would be 350 currency.
- `identifyCourseFee()` would be 2500 currency.
- `identifyDiscountPercent()`: Base (10) + Mode fee >= 350 (5) + Course fee 2500 (5) = **20%**.
- `calculateTotalFee()`:
  - Base course type fee for "Hands-On" = 500.0
  - Add basicFee (5000) + courseFee (2500) = 8000.0
  - Trainee & Infosys deduction = -2000.0
  - `certificationFee` = **6000.0** currency
  - `certificationId` = **"PE1001"** (first certification id generated).
