From d29e38ef7529a66ee6a463faa3f262a587a37a8a Mon Sep 17 00:00:00 2001 From: Joel Thomas Date: Thu, 9 Apr 2026 20:32:48 +0530 Subject: [PATCH 1/9] Added FileManager DLL and cleanup code SRS02 : Employee Management - Created FileIO for reading and writing files - Created FileManager to use FileIO - Set up Trenser.FileManager as a DLL - Linked DLL with Trenser.Zenvy project - Fixed duplicate function issue by marking deactivateEmployee as inline - Cleaned up unused methods in controller and service Smitha Mohan --- .../Trenser.FileManager/FileIO.cpp | 28 +++++++++++++ .../Trenser.FileManager/FileIO.h | 18 ++++++++ .../Trenser.FileManager/FileManager.h | 41 +++++++++++++++++++ .../Trenser.FileManager.vcxproj | 3 ++ .../Trenser.FileManager.vcxproj.filters | 9 ++++ Trenser.FileManager/Trenser.FileManager/pch.h | 5 +++ .../Trenser.Zenvy/Trenser.Zenvy.vcxproj | 13 +++++- .../Trenser.Zenvy.vcxproj.filters | 6 +++ .../controllers/ZenvyController.cpp | 4 -- .../controllers/ZenvyController.h | 1 - .../services/EmployeeManagementService.cpp | 19 ++++++--- .../services/EmployeeManagementService.h | 1 - .../Trenser.Zenvy/views/MenuHelper.h | 2 +- 13 files changed, 137 insertions(+), 13 deletions(-) create mode 100644 Trenser.FileManager/Trenser.FileManager/FileIO.cpp create mode 100644 Trenser.FileManager/Trenser.FileManager/FileIO.h create mode 100644 Trenser.FileManager/Trenser.FileManager/FileManager.h diff --git a/Trenser.FileManager/Trenser.FileManager/FileIO.cpp b/Trenser.FileManager/Trenser.FileManager/FileIO.cpp new file mode 100644 index 0000000..321f449 --- /dev/null +++ b/Trenser.FileManager/Trenser.FileManager/FileIO.cpp @@ -0,0 +1,28 @@ +#include "pch.h" +#include "FileIO.h" + +std::vector FileIO::readAllLines(const std::string& path) +{ + std::ifstream file(path); + if (!file.is_open()) + throw std::runtime_error("Failed to open file " + path); + + std::vector lines; + std::string line; + + while (std::getline(file, line)) + lines.push_back(line); + + return lines; +} + +void FileIO::writeAllLines(const std::string& path, + const std::vector& lines) +{ + std::ofstream file(path, std::ios::trunc); + if (!file.is_open()) + throw std::runtime_error("Failed to open file " + path); + + for (const auto& line : lines) + file << line << '\n'; +} \ No newline at end of file diff --git a/Trenser.FileManager/Trenser.FileManager/FileIO.h b/Trenser.FileManager/Trenser.FileManager/FileIO.h new file mode 100644 index 0000000..c628003 --- /dev/null +++ b/Trenser.FileManager/Trenser.FileManager/FileIO.h @@ -0,0 +1,18 @@ +#pragma once +#include +#include +#include +#include +#include + +#ifdef TRENSERFILEMANAGER_EXPORTS +#define TRENSERFILEMANAGER_API __declspec(dllexport) +#else +#define TRENSERFILEMANAGER_API __declspec(dllimport) +#endif + +class TRENSERFILEMANAGER_API FileIO { +public: + static std::vector readAllLines(const std::string& path); + static void writeAllLines(const std::string& path, const std::vector& lines); +}; diff --git a/Trenser.FileManager/Trenser.FileManager/FileManager.h b/Trenser.FileManager/Trenser.FileManager/FileManager.h new file mode 100644 index 0000000..2facd05 --- /dev/null +++ b/Trenser.FileManager/Trenser.FileManager/FileManager.h @@ -0,0 +1,41 @@ +#pragma once +#include "FileIO.h" + +template using objects = std::map>; + +template +class FileManager +{ +private: + std::string m_filePath; +public: + FileManager() : m_filePath("") {} + FileManager(const std::string& filePath) : m_filePath(filePath) {} + objects load(); + void save(const objects&); +}; + +template +objects FileManager::load() +{ + objects records; + auto lines = FileIO::readAllLines(m_filePath); + for (const auto& record : lines) + { + auto object = T::deserialize(record); + records[object->getId()] = object; + } + return records; +} + +template +void FileManager::save(const objects& records) +{ + std::vector lines; + + for (const auto& recordPair : records) + { + lines.push_back(recordPair.second->serialize()); + } + FileIO::writeAllLines(m_filePath, lines); +} diff --git a/Trenser.FileManager/Trenser.FileManager/Trenser.FileManager.vcxproj b/Trenser.FileManager/Trenser.FileManager/Trenser.FileManager.vcxproj index c7c45c3..7511f8e 100644 --- a/Trenser.FileManager/Trenser.FileManager/Trenser.FileManager.vcxproj +++ b/Trenser.FileManager/Trenser.FileManager/Trenser.FileManager.vcxproj @@ -135,11 +135,14 @@ + + + Create Create diff --git a/Trenser.FileManager/Trenser.FileManager/Trenser.FileManager.vcxproj.filters b/Trenser.FileManager/Trenser.FileManager/Trenser.FileManager.vcxproj.filters index 1e57c7b..8faaab1 100644 --- a/Trenser.FileManager/Trenser.FileManager/Trenser.FileManager.vcxproj.filters +++ b/Trenser.FileManager/Trenser.FileManager/Trenser.FileManager.vcxproj.filters @@ -21,6 +21,12 @@ Header Files + + Header Files + + + Header Files + @@ -29,5 +35,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/Trenser.FileManager/Trenser.FileManager/pch.h b/Trenser.FileManager/Trenser.FileManager/pch.h index 885d5d6..a4ee448 100644 --- a/Trenser.FileManager/Trenser.FileManager/pch.h +++ b/Trenser.FileManager/Trenser.FileManager/pch.h @@ -9,5 +9,10 @@ // add headers that you want to pre-compile here #include "framework.h" +#include +#include +#include +#include +#include #endif //PCH_H diff --git a/Trenser.Zenvy/Trenser.Zenvy/Trenser.Zenvy.vcxproj b/Trenser.Zenvy/Trenser.Zenvy/Trenser.Zenvy.vcxproj index 2792535..1e57272 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/Trenser.Zenvy.vcxproj +++ b/Trenser.Zenvy/Trenser.Zenvy/Trenser.Zenvy.vcxproj @@ -102,12 +102,17 @@ true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true - $(ProjectDir)models;$(ProjectDir)controllers;$(ProjectDir)services;$(ProjectDir)utilities;$(ProjectDir)factories;$(ProjectDir)datastores;$(ProjectDir)views;%(AdditionalIncludeDirectories) + $(ProjectDir)models;$(ProjectDir)controllers;$(ProjectDir)services;$(ProjectDir)utilities;$(ProjectDir)factories;$(ProjectDir)datastores;$(ProjectDir)views;%(AdditionalIncludeDirectories);..\..\Trenser.FileManager\Trenser.FileManager Console true + ..\..\Trenser.FileManager\$(IntDir);%(AdditionalLibraryDirectories) + Trenser.FileManager.lib;%(AdditionalDependencies) + + xcopy /y /d "..\..\Trenser.FileManager\$(IntDir)Trenser.FileManager.dll" "$(OutDir)" + @@ -117,11 +122,17 @@ true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true + ;..\..\Trenser.FileManager\Trenser.FileManager Console true + ..\..\Trenser.FileManager\$(IntDir);%(AdditionalLibraryDirectories) + Trenser.FileManager.lib;%(AdditionalDependencies) + + xcopy /y /d "..\..\Trenser.FileManager\$(IntDir)Trenser.FileManager.dll" "$(OutDir)" + diff --git a/Trenser.Zenvy/Trenser.Zenvy/Trenser.Zenvy.vcxproj.filters b/Trenser.Zenvy/Trenser.Zenvy/Trenser.Zenvy.vcxproj.filters index 0def00c..d03337b 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/Trenser.Zenvy.vcxproj.filters +++ b/Trenser.Zenvy/Trenser.Zenvy/Trenser.Zenvy.vcxproj.filters @@ -195,6 +195,9 @@ Views + + Services + @@ -344,6 +347,9 @@ Views + + Services + diff --git a/Trenser.Zenvy/Trenser.Zenvy/controllers/ZenvyController.cpp b/Trenser.Zenvy/Trenser.Zenvy/controllers/ZenvyController.cpp index 6b5d67a..9cc6be1 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/controllers/ZenvyController.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/controllers/ZenvyController.cpp @@ -42,10 +42,6 @@ std::shared_ptr ZenvyController::getCurrentEmployee() return m_employeeManagementService->getCurrentEmployee(); } -std::shared_ptr ZenvyController::getEmployee(const std::string& id) -{ -} - Employees ZenvyController::getEmployees() { return m_employeeManagementService->getEmployees(); diff --git a/Trenser.Zenvy/Trenser.Zenvy/controllers/ZenvyController.h b/Trenser.Zenvy/Trenser.Zenvy/controllers/ZenvyController.h index cb355c6..66ec402 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/controllers/ZenvyController.h +++ b/Trenser.Zenvy/Trenser.Zenvy/controllers/ZenvyController.h @@ -48,7 +48,6 @@ public: void createEmployee(Enums::EmployeeType, Enums::EmployeeDesignation, const std::string&, const std::string&, const std::string&); bool deactivateEmployee(const std::string&); Employees getEmployees(); - std::shared_ptr getEmployee(const std::string&); std::shared_ptr getCurrentEmployee(); void updateProfile(const std::string&,const std::string&); diff --git a/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.cpp b/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.cpp index 29ef5b5..eaca66a 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.cpp @@ -116,11 +116,20 @@ bool EmployeeManagementService::deactivateEmployee(const std::string& id) Employees EmployeeManagementService::getEmployees() { - -} - -std::shared_ptr EmployeeManagementService::getEmployee(const std::string& id) -{ + Employees result; + auto& employees = m_dataStore.getEmployees(); + if (employees.size() <= 0) + { + return result; + } + for (const auto& iterator : employees) + { + if (iterator.second->getEmployeeAccountStatus() == Enums::AccountStatus::ACTIVE) + { + result.push_back(iterator.second); + } + } + return result; } std::shared_ptr EmployeeManagementService::getCurrentEmployee() diff --git a/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.h b/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.h index 14c8131..388c99c 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.h +++ b/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.h @@ -15,7 +15,6 @@ public: void createEmployee(Enums::EmployeeType, Enums::EmployeeDesignation, const std::string&, const std::string&, const std::string&); bool deactivateEmployee(const std::string&); Employees getEmployees(); - std::shared_ptr getEmployee(const std::string&); void updateProfile(const std::string&,const std::string&); std::shared_ptr getCurrentEmployee(); }; diff --git a/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.h b/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.h index 6df1fce..32a923c 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.h +++ b/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.h @@ -76,7 +76,7 @@ inline std::map> listEmployees(const std::s return employeeList; } -void deactivateEmployee(const std::shared_ptr& controller) +inline void deactivateEmployee(const std::shared_ptr& controller) { auto employeeList = listEmployees(controller); if (employeeList.empty()) From 451ed4fec2cfbb7f614b82adee26c5159ddff36b Mon Sep 17 00:00:00 2001 From: Joel Thomas Date: Fri, 10 Apr 2026 13:17:50 +0530 Subject: [PATCH 2/9] Added employee persistence, serialization, and file loading support SRS02 : Employee Management MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Implemented serialization and deserialization for Employee and GeneralEmployee models - Added FileManager integration to load employees from CSV files - Introduced ApplicationConfig entries for employee file paths - Updated Employee ID handling (getEmployeeId → getId) across project - Modified FileIO to auto-create file if not found instead of throwing exception - Added constructors for all employee types to support deserialization - Implemented loadEmployees in service and loadStates in controller - Ensured default admin creation if none exists during load - Added StringHelper utility for extracting numeric IDs - Extended Enums with string conversion and parsing utilities - Added initial CSV files for Employee and GeneralEmployee data - Improved login error message formatting and minor cleanup - Setup gitignore to not track csv files --- .gitignore | 3 + .../Trenser.FileManager/FileIO.cpp | 10 +- .../Trenser.FileManager/FileManager.h | 2 +- Trenser.Zenvy/Trenser.Zenvy/Trenser.Zenvy.cpp | 1 + .../Trenser.Zenvy/Trenser.Zenvy.vcxproj | 2 + .../Trenser.Zenvy.vcxproj.filters | 6 + .../controllers/ZenvyController.cpp | 5 + .../controllers/ZenvyController.h | 3 + Trenser.Zenvy/Trenser.Zenvy/models/Admin.h | 19 ++- .../Trenser.Zenvy/models/Employee.cpp | 135 +++++++++++++++++- Trenser.Zenvy/Trenser.Zenvy/models/Employee.h | 37 ++++- .../Trenser.Zenvy/models/FinanceExecutive.h | 18 ++- .../Trenser.Zenvy/models/GeneralEmployee.cpp | 50 +++++++ .../Trenser.Zenvy/models/GeneralEmployee.h | 32 ++++- .../Trenser.Zenvy/models/HRManager.h | 17 +++ .../Trenser.Zenvy/models/ITExecutive.h | 19 ++- .../Trenser.Zenvy/models/TeamExecutive.h | 17 +++ .../services/ApplicationConfig.h | 6 + .../services/EmployeeManagementService.cpp | 31 +++- .../services/EmployeeManagementService.h | 1 + Trenser.Zenvy/Trenser.Zenvy/utilities/Enums.h | 117 +++++++++++++++ .../Trenser.Zenvy/utilities/StringHelper.cpp | 15 ++ .../Trenser.Zenvy/utilities/StringHelper.h | 7 + .../views/FinanceExecutiveMenu.cpp | 4 +- .../Trenser.Zenvy/views/MenuHelper.h | 4 +- .../Trenser.Zenvy/views/UserInterface.cpp | 11 +- 26 files changed, 549 insertions(+), 23 deletions(-) create mode 100644 Trenser.Zenvy/Trenser.Zenvy/utilities/StringHelper.cpp create mode 100644 Trenser.Zenvy/Trenser.Zenvy/utilities/StringHelper.h diff --git a/.gitignore b/.gitignore index 47a94ef..fe37065 100644 --- a/.gitignore +++ b/.gitignore @@ -426,3 +426,6 @@ FodyWeavers.xsd *.msix *.msm *.msp + +# CSV Files +*.csv diff --git a/Trenser.FileManager/Trenser.FileManager/FileIO.cpp b/Trenser.FileManager/Trenser.FileManager/FileIO.cpp index 321f449..ac79d03 100644 --- a/Trenser.FileManager/Trenser.FileManager/FileIO.cpp +++ b/Trenser.FileManager/Trenser.FileManager/FileIO.cpp @@ -5,14 +5,14 @@ std::vector FileIO::readAllLines(const std::string& path) { std::ifstream file(path); if (!file.is_open()) - throw std::runtime_error("Failed to open file " + path); - - std::vector lines; + { + std::ofstream newFile(path); + newFile.close(); + file.open(path); + } std::vector lines; std::string line; - while (std::getline(file, line)) lines.push_back(line); - return lines; } diff --git a/Trenser.FileManager/Trenser.FileManager/FileManager.h b/Trenser.FileManager/Trenser.FileManager/FileManager.h index 2facd05..50a9fbf 100644 --- a/Trenser.FileManager/Trenser.FileManager/FileManager.h +++ b/Trenser.FileManager/Trenser.FileManager/FileManager.h @@ -1,7 +1,7 @@ #pragma once #include "FileIO.h" -template using objects = std::map>; +template using objects = std::map>; template class FileManager diff --git a/Trenser.Zenvy/Trenser.Zenvy/Trenser.Zenvy.cpp b/Trenser.Zenvy/Trenser.Zenvy/Trenser.Zenvy.cpp index 4413069..9c953a9 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/Trenser.Zenvy.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/Trenser.Zenvy.cpp @@ -1,4 +1,5 @@ #include "UserInterface.h" +#include "FileManager.h" int main() { UserInterface userInterFace; diff --git a/Trenser.Zenvy/Trenser.Zenvy/Trenser.Zenvy.vcxproj b/Trenser.Zenvy/Trenser.Zenvy/Trenser.Zenvy.vcxproj index 1e57272..f3f2e5f 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/Trenser.Zenvy.vcxproj +++ b/Trenser.Zenvy/Trenser.Zenvy/Trenser.Zenvy.vcxproj @@ -177,6 +177,7 @@ + @@ -229,6 +230,7 @@ + diff --git a/Trenser.Zenvy/Trenser.Zenvy/Trenser.Zenvy.vcxproj.filters b/Trenser.Zenvy/Trenser.Zenvy/Trenser.Zenvy.vcxproj.filters index d03337b..1c6dff6 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/Trenser.Zenvy.vcxproj.filters +++ b/Trenser.Zenvy/Trenser.Zenvy/Trenser.Zenvy.vcxproj.filters @@ -198,6 +198,9 @@ Services + + Utilities + @@ -350,6 +353,9 @@ Services + + Utilities + diff --git a/Trenser.Zenvy/Trenser.Zenvy/controllers/ZenvyController.cpp b/Trenser.Zenvy/Trenser.Zenvy/controllers/ZenvyController.cpp index 9cc6be1..7d587e6 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/controllers/ZenvyController.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/controllers/ZenvyController.cpp @@ -46,3 +46,8 @@ Employees ZenvyController::getEmployees() { return m_employeeManagementService->getEmployees(); } + +void ZenvyController::loadStates() +{ + m_employeeManagementService->loadEmployees(); +} diff --git a/Trenser.Zenvy/Trenser.Zenvy/controllers/ZenvyController.h b/Trenser.Zenvy/Trenser.Zenvy/controllers/ZenvyController.h index 66ec402..2f8c137 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/controllers/ZenvyController.h +++ b/Trenser.Zenvy/Trenser.Zenvy/controllers/ZenvyController.h @@ -53,4 +53,7 @@ public: //Payslip management void updateSalary(const std::string&, double, double, double, double, double); + + //File Management + void loadStates(); }; diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/Admin.h b/Trenser.Zenvy/Trenser.Zenvy/models/Admin.h index 5b869b0..c483a61 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/Admin.h +++ b/Trenser.Zenvy/Trenser.Zenvy/models/Admin.h @@ -10,6 +10,23 @@ public: const std::string& phone, const std::string& email, std::shared_ptr payroll - ) :Employee(name, phone, email, Enums::EmployeeType::GENERAL, payroll) {}; + ) :Employee(name, phone, email, Enums::EmployeeType::ADMIN, payroll) {}; + Admin(const std::string& id, + const std::string& name, + const std::string& phone, + const std::string& password, + const std::string& email, + const std::string& teamId, + Enums::TeamStatus teamStatus, + Enums::AccountStatus accountStatus) + : Employee(id, + name, + phone, + password, + email, + teamId, + teamStatus, + Enums::EmployeeType::ADMIN, + accountStatus) {} ~Admin() = default; }; diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/Employee.cpp b/Trenser.Zenvy/Trenser.Zenvy/models/Employee.cpp index 57db7a9..f673458 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/Employee.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/models/Employee.cpp @@ -1,8 +1,45 @@ +#include #include "Employee.h" +#include "Factory.h" +#include "StringHelper.h" +#include "Admin.h" +#include "HRManager.h" +#include "ITExecutive.h" +#include "TalentExecutive.h" +#include "TeamExecutive.h" +#include "FinanceExecutive.h" +#include "GeneralEmployee.h" int Employee::m_uid = 0; -const std::string& Employee::getEmployeeId() const +Employee::Employee(const std::string& id, + const std::string& name, + const std::string& phone, + const std::string& password, + const std::string& email, + const std::string& teamId, + Enums::TeamStatus teamStatus, + Enums::EmployeeType employeeType, + Enums::AccountStatus accountStatus) + : m_id(id), + m_password(password), + m_name(name), + m_phone(phone), + m_email(email), + m_accountStatus(accountStatus), + m_teamStatus(teamStatus), + m_teamId(teamId), + m_employeeType(employeeType), + m_payroll() +{ + int idNumber = util::extractNumber(m_id); + if (idNumber > m_uid) + { + m_uid = idNumber; + } +} + +const std::string& Employee::getId() const { return m_id; } @@ -130,3 +167,99 @@ Enums::EmployeeType Employee::getEmployeeType() const { return m_employeeType; } + +std::string Employee::serialize() const +{ + std::ostringstream serializedEmployee; + serializedEmployee << m_id << ',' + << m_email << ',' + << m_name << ',' + << m_phone << ',' + << m_password << ',' + << m_teamId << ',' + << Enums::getTeamStatusString(m_teamStatus) << ',' + << Enums::getAccountStatusString(m_accountStatus) << ',' + << Enums::getEmployeeTypeString(m_employeeType); + return serializedEmployee.str(); +} + +std::shared_ptr Employee::deserialize(const std::string& record) +{ + std::string id, name, phone, password, email; + std::string teamId, teamStatusString, accountStatusString, employeeTypeString; + std::istringstream serializedEmployee(record); + getline(serializedEmployee, id, ','); + getline(serializedEmployee, email, ','); + getline(serializedEmployee, name, ','); + getline(serializedEmployee, phone, ','); + getline(serializedEmployee, password, ','); + getline(serializedEmployee, teamId, ','); + getline(serializedEmployee, teamStatusString, ','); + getline(serializedEmployee, accountStatusString, ','); + getline(serializedEmployee, employeeTypeString, ','); + Enums::TeamStatus teamStatus = Enums::getTeamStatus(teamStatusString); + Enums::AccountStatus accountStatus = Enums::getAccountStatus(accountStatusString); + Enums::EmployeeType employeeType = Enums::getEmployeeType(employeeTypeString); + switch (employeeType) + { + case Enums::EmployeeType::IT: + return Factory::getObject( + id, + name, + phone, + password, + email, + teamId, + teamStatus, + accountStatus + ); + case Enums::EmployeeType::FINANCE: + return Factory::getObject( + id, + name, + phone, + password, + email, + teamId, + teamStatus, + accountStatus + ); + case Enums::EmployeeType::HR: + return Factory::getObject( + id, + name, + phone, + password, + email, + teamId, + teamStatus, + accountStatus + ); + case Enums::EmployeeType::TEAM: + return Factory::getObject( + id, + name, + phone, + password, + email, + teamId, + teamStatus, + accountStatus + ); + case Enums::EmployeeType::ADMIN: + return Factory::getObject( + id, + name, + phone, + password, + email, + teamId, + teamStatus, + accountStatus + ); + case Enums::EmployeeType::GENERAL: + throw std::runtime_error("Cannot deserialize GeneralEmployee!"); + default: + return nullptr; + } +} diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/Employee.h b/Trenser.Zenvy/Trenser.Zenvy/models/Employee.h index b690f7c..6900943 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/Employee.h +++ b/Trenser.Zenvy/Trenser.Zenvy/models/Employee.h @@ -14,7 +14,7 @@ using leaveMap = std::map>; class Employee { -private: +protected: static int m_uid; std::string m_id; std::string m_password; @@ -30,14 +30,41 @@ private: leaveMap m_leaves; Enums::EmployeeType m_employeeType; public: - Employee() : m_id("EMP" + std::to_string(++m_uid)), m_password(Config::Authentication::DEFAULT_PASSWORD), m_name(""), m_phone(""), m_email(""), m_accountStatus(Enums::AccountStatus::ACTIVE), m_teamStatus(Enums::TeamStatus::NOT_IN_TEAM), m_teamId(""), m_employeeType(Enums::EmployeeType::GENERAL) {} + Employee() + : m_id("EMP" + std::to_string(++m_uid)), + m_password(Config::Authentication::DEFAULT_PASSWORD), + m_name(""), + m_phone(""), + m_email(""), + m_accountStatus(Enums::AccountStatus::ACTIVE), + m_teamStatus(Enums::TeamStatus::NOT_IN_TEAM), + m_teamId(""), + m_employeeType(Enums::EmployeeType::GENERAL) {} Employee(const std::string& name, const std::string& phone, const std::string& email, Enums::EmployeeType employeeType, std::shared_ptr payroll) - : m_id("EMP" + std::to_string(++m_uid)), m_password(Config::Authentication::DEFAULT_PASSWORD), m_name(name), m_phone(phone), m_email(email), m_accountStatus(Enums::AccountStatus::ACTIVE), m_teamStatus(Enums::TeamStatus::NOT_IN_TEAM), m_teamId(""), m_employeeType(employeeType), m_payroll(payroll) { } - const std::string& getEmployeeId() const; + : m_id("EMP" + std::to_string(++m_uid)), + m_password(Config::Authentication::DEFAULT_PASSWORD), + m_name(name), + m_phone(phone), + m_email(email), + m_accountStatus(Enums::AccountStatus::ACTIVE), + m_teamStatus(Enums::TeamStatus::NOT_IN_TEAM), + m_teamId(""), + m_employeeType(employeeType), + m_payroll(payroll) {} + Employee(const std::string& id, + const std::string& name, + const std::string& phone, + const std::string& password, + const std::string& email, + const std::string& teamId, + Enums::TeamStatus teamStatus, + Enums::EmployeeType employeeType, + Enums::AccountStatus accountStatus); + const std::string& getId() const; const std::string& getEmployeePassword() const; const std::string& getEmployeeName() const; const std::string& getEmployeePhone() const; @@ -61,5 +88,7 @@ public: void addAttendance(std::shared_ptr attendance); void addLeave(std::shared_ptr leave); Enums::EmployeeType getEmployeeType() const; + virtual std::string serialize() const; + static std::shared_ptr deserialize(const std::string&); virtual ~Employee() = default; }; \ No newline at end of file diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/FinanceExecutive.h b/Trenser.Zenvy/Trenser.Zenvy/models/FinanceExecutive.h index 6713881..e877627 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/FinanceExecutive.h +++ b/Trenser.Zenvy/Trenser.Zenvy/models/FinanceExecutive.h @@ -1,5 +1,4 @@ #pragma once -#include #include "Employee.h" class FinanceExecutive : public Employee @@ -12,6 +11,23 @@ public: const std::string& email, std::shared_ptr payroll ) :Employee(name, phone, email, Enums::EmployeeType::FINANCE, payroll) {}; + FinanceExecutive(const std::string& id, + const std::string& name, + const std::string& phone, + const std::string& password, + const std::string& email, + const std::string& teamId, + Enums::TeamStatus teamStatus, + Enums::AccountStatus accountStatus) + : Employee(id, + name, + phone, + password, + email, + teamId, + teamStatus, + Enums::EmployeeType::FINANCE, + accountStatus) {} ~FinanceExecutive() = default; }; diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/GeneralEmployee.cpp b/Trenser.Zenvy/Trenser.Zenvy/models/GeneralEmployee.cpp index 46f9e61..455665b 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/GeneralEmployee.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/models/GeneralEmployee.cpp @@ -1,4 +1,6 @@ +#include #include "GeneralEmployee.h" +#include "Factory.h" Enums::EmployeeDesignation GeneralEmployee::getDesignation() const { @@ -8,4 +10,52 @@ Enums::EmployeeDesignation GeneralEmployee::getDesignation() const void GeneralEmployee::setDesignation(Enums::EmployeeDesignation designation) { m_designation = designation; +} + +std::string GeneralEmployee::serialize() const +{ + std::ostringstream serializedEmployee; + serializedEmployee << m_id << ',' + << m_email << ',' + << m_name << ',' + << m_phone << ',' + << m_password << ',' + << m_teamId << ',' + << Enums::getTeamStatusString(m_teamStatus) << ',' + << Enums::getAccountStatusString(m_accountStatus) << ',' + << Enums::getEmployeeTypeString(m_employeeType) << ',' + << Enums::getEmployeeDesignationString(m_designation); + return serializedEmployee.str(); +} + +std::shared_ptr GeneralEmployee::deserialize(const std::string& record) +{ + std::string id, name, phone, password, email; + std::string teamId, teamStatusString, accountStatusString, employeeTypeString, employeeDesignationString; + std::istringstream serializedEmployee(record); + getline(serializedEmployee, id, ','); + getline(serializedEmployee, email, ','); + getline(serializedEmployee, name, ','); + getline(serializedEmployee, phone, ','); + getline(serializedEmployee, password, ','); + getline(serializedEmployee, teamId, ','); + getline(serializedEmployee, teamStatusString, ','); + getline(serializedEmployee, accountStatusString, ','); + getline(serializedEmployee, employeeTypeString, ','); + getline(serializedEmployee, employeeDesignationString, ','); + Enums::TeamStatus teamStatus = Enums::getTeamStatus(teamStatusString); + Enums::AccountStatus accountStatus = Enums::getAccountStatus(accountStatusString); + Enums::EmployeeType employeeType = Enums::getEmployeeType(employeeTypeString); + Enums::EmployeeDesignation employeeDesignation = Enums::getEmployeeDesignation(employeeDesignationString); + return Factory::getObject( + id, + name, + phone, + password, + email, + teamId, + teamStatus, + employeeDesignation, + accountStatus + ); } \ No newline at end of file diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/GeneralEmployee.h b/Trenser.Zenvy/Trenser.Zenvy/models/GeneralEmployee.h index c413eac..1277fff 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/GeneralEmployee.h +++ b/Trenser.Zenvy/Trenser.Zenvy/models/GeneralEmployee.h @@ -7,13 +7,41 @@ class GeneralEmployee : public Employee private: Enums::EmployeeDesignation m_designation; public: - GeneralEmployee() : m_designation(Enums::EmployeeDesignation::JUNIOR) {} + GeneralEmployee() + : m_designation(Enums::EmployeeDesignation::JUNIOR) {} GeneralEmployee(const std::string& name, const std::string& phone, const std::string& email, std::shared_ptr payroll, - Enums::EmployeeDesignation designation) : Employee(name, phone, email, Enums::EmployeeType::GENERAL, payroll), m_designation(designation) {} + Enums::EmployeeDesignation designation) + : Employee(name, + phone, + email, + Enums::EmployeeType::GENERAL, + payroll), + m_designation(designation) {} + GeneralEmployee(const std::string& id, + const std::string& name, + const std::string& phone, + const std::string& password, + const std::string& email, + const std::string& teamId, + Enums::TeamStatus teamStatus, + Enums::EmployeeDesignation employeeDesignation, + Enums::AccountStatus accountStatus) + : Employee(id, + name, + phone, + password, + email, + teamId, + teamStatus, + Enums::EmployeeType::GENERAL, + accountStatus), + m_designation(employeeDesignation) {} Enums::EmployeeDesignation getDesignation() const; void setDesignation(Enums::EmployeeDesignation designation); + std::string serialize() const override; + static std::shared_ptr deserialize(const std::string&); ~GeneralEmployee() = default; }; \ No newline at end of file diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/HRManager.h b/Trenser.Zenvy/Trenser.Zenvy/models/HRManager.h index 1c9ae17..43f572c 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/HRManager.h +++ b/Trenser.Zenvy/Trenser.Zenvy/models/HRManager.h @@ -11,6 +11,23 @@ public: const std::string& email, std::shared_ptr payroll ) :Employee(name, phone, email, Enums::EmployeeType::HR, payroll) {}; + HRManager(const std::string& id, + const std::string& name, + const std::string& phone, + const std::string& password, + const std::string& email, + const std::string& teamId, + Enums::TeamStatus teamStatus, + Enums::AccountStatus accountStatus) + : Employee(id, + name, + phone, + password, + email, + teamId, + teamStatus, + Enums::EmployeeType::HR, + accountStatus) {} ~HRManager() = default; }; diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/ITExecutive.h b/Trenser.Zenvy/Trenser.Zenvy/models/ITExecutive.h index 7cecff3..a69f673 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/ITExecutive.h +++ b/Trenser.Zenvy/Trenser.Zenvy/models/ITExecutive.h @@ -10,7 +10,24 @@ public: const std::string& phone, const std::string& email, std::shared_ptr payroll - ) :Employee(name, phone, email, Enums::EmployeeType::GENERAL, payroll) {}; + ) :Employee(name, phone, email, Enums::EmployeeType::IT, payroll) {}; + ITExecutive(const std::string& id, + const std::string& name, + const std::string& phone, + const std::string& password, + const std::string& email, + const std::string& teamId, + Enums::TeamStatus teamStatus, + Enums::AccountStatus accountStatus) + : Employee(id, + name, + phone, + password, + email, + teamId, + teamStatus, + Enums::EmployeeType::IT, + accountStatus) {} ~ITExecutive() = default; }; diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/TeamExecutive.h b/Trenser.Zenvy/Trenser.Zenvy/models/TeamExecutive.h index 03f321b..3f79197 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/TeamExecutive.h +++ b/Trenser.Zenvy/Trenser.Zenvy/models/TeamExecutive.h @@ -11,6 +11,23 @@ public: const std::string& email, std::shared_ptr payroll ) :Employee(name, phone, email, Enums::EmployeeType::TEAM, payroll) {}; + TeamExecutive(const std::string& id, + const std::string& name, + const std::string& phone, + const std::string& password, + const std::string& email, + const std::string& teamId, + Enums::TeamStatus teamStatus, + Enums::AccountStatus accountStatus) + : Employee(id, + name, + phone, + password, + email, + teamId, + teamStatus, + Enums::EmployeeType::TEAM, + accountStatus) {} ~TeamExecutive() = default; }; diff --git a/Trenser.Zenvy/Trenser.Zenvy/services/ApplicationConfig.h b/Trenser.Zenvy/Trenser.Zenvy/services/ApplicationConfig.h index 15f54e6..c725431 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/services/ApplicationConfig.h +++ b/Trenser.Zenvy/Trenser.Zenvy/services/ApplicationConfig.h @@ -30,4 +30,10 @@ namespace Config constexpr double EXECUTIVE_EMPLOYEE_PF_CONTRIBUTION = 0.0; constexpr double EXECUTIVE_EMPLOYER_PF_CONTRIBUTION = 0.0; } + + namespace File + { + constexpr const char* EMPLOYEES_FILE = "files/Employee.csv"; + constexpr const char* GENERAL_EMPLOYEES_FILE = "files/GeneralEmployee.csv"; + } } diff --git a/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.cpp b/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.cpp index eaca66a..1c9919d 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.cpp @@ -10,6 +10,8 @@ #include "TeamExecutive.h" #include "FinanceExecutive.h" #include "GeneralEmployee.h" +#include "FileManager.h" +#include "ApplicationConfig.h" void EmployeeManagementService::createEmployee(Enums::EmployeeType employeeType, Enums::EmployeeDesignation employeeDesignation, const std::string& email, const std::string& name, const std::string& phone) { @@ -93,7 +95,7 @@ void EmployeeManagementService::createEmployee(Enums::EmployeeType employeeType, default: throw std::runtime_error("Invalid Employee Type"); } - m_dataStore.getEmployees().emplace(std::make_pair(employee->getEmployeeId(), employee)); + m_dataStore.getEmployees().emplace(std::make_pair(employee->getId(), employee)); } bool EmployeeManagementService::deactivateEmployee(const std::string& id) @@ -142,4 +144,29 @@ void EmployeeManagementService::updateProfile(const std::string& name,const std: std::shared_ptr employee = m_dataStore.getAuthenticatedEmployee(); employee->setEmployeeName(name); employee->setEmployeePhone(phone); -} \ No newline at end of file +} + +void EmployeeManagementService::loadEmployees() +{ + FileManager employeeFileManager(Config::File::EMPLOYEES_FILE); + FileManager generalEmployeeFileManager(Config::File::GENERAL_EMPLOYEES_FILE); + bool isAdminFound = false; + auto& employees = m_dataStore.getEmployees(); + auto employeesMap = employeeFileManager.load(); + auto generalEmployeesMap = generalEmployeeFileManager.load(); + employees.insert(employeesMap.begin(), employeesMap.end()); + employees.insert(generalEmployeesMap.begin(), generalEmployeesMap.end()); + for (auto& employeePair : employees) + { + if (employeePair.second->getEmployeeType() == Enums::EmployeeType::ADMIN) + { + isAdminFound = true; + break; + } + } + if (!isAdminFound) + { + auto admin = Factory::getObject("Admin", "", "admin@trenser.com", nullptr); + employees.emplace(std::make_pair(admin->getId(), admin)); + } +} diff --git a/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.h b/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.h index 388c99c..cb2daf5 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.h +++ b/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.h @@ -17,4 +17,5 @@ public: Employees getEmployees(); void updateProfile(const std::string&,const std::string&); std::shared_ptr getCurrentEmployee(); + void loadEmployees(); }; diff --git a/Trenser.Zenvy/Trenser.Zenvy/utilities/Enums.h b/Trenser.Zenvy/Trenser.Zenvy/utilities/Enums.h index ace8792..5154ddd 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/utilities/Enums.h +++ b/Trenser.Zenvy/Trenser.Zenvy/utilities/Enums.h @@ -1,4 +1,5 @@ #pragma once +#include namespace Enums { @@ -89,4 +90,120 @@ namespace Enums { USER_NOT_FOUND, INVALID_PASSWORD }; + + inline std::string getAccountStatusString(AccountStatus status) + { + switch (status) + { + case AccountStatus::ACTIVE: + return "ACTIVE"; + case AccountStatus::INACTIVE: + return "INACTIVE"; + default: + return "UNKNOWN"; + } + } + + inline std::string getEmployeeTypeString(EmployeeType type) + { + switch (type) + { + case EmployeeType::GENERAL: + return "GENERAL"; + case EmployeeType::IT: + return "IT"; + case EmployeeType::FINANCE: + return "FINANCE"; + case EmployeeType::TAG: + return "TAG"; + case EmployeeType::HR: + return "HR"; + case EmployeeType::TEAM: + return "TEAM"; + case EmployeeType::ADMIN: + return "ADMIN"; + case EmployeeType::INVALID: + return "INVALID"; + default: + return "UNKNOWN"; + } + } + + inline std::string getTeamStatusString(TeamStatus status) + { + switch (status) + { + case TeamStatus::IN_TEAM: + return "IN_TEAM"; + case TeamStatus::NOT_IN_TEAM: + return "NOT_IN_TEAM"; + default: + return "UNKNOWN"; + } + } + + inline std::string getEmployeeDesignationString(EmployeeDesignation designation) + { + switch (designation) + { + case EmployeeDesignation::JUNIOR: + return "JUNIOR"; + case EmployeeDesignation::SENIOR: + return "SENIOR"; + case EmployeeDesignation::TEAM_LEAD: + return "TEAM_LEAD"; + case EmployeeDesignation::INVALID: + return "INVALID"; + default: + return "UNKNOWN"; + } + } + + inline AccountStatus getAccountStatus(const std::string& input) + { + if (input == "ACTIVE") + return AccountStatus::ACTIVE; + if (input == "INACTIVE") + return AccountStatus::INACTIVE; + return AccountStatus::INACTIVE; + } + + inline EmployeeType getEmployeeType(const std::string& input) + { + if (input == "GENERAL") + return EmployeeType::GENERAL; + if (input == "IT") + return EmployeeType::IT; + if (input == "FINANCE") + return EmployeeType::FINANCE; + if (input == "TAG") + return EmployeeType::TAG; + if (input == "HR") + return EmployeeType::HR; + if (input == "TEAM") + return EmployeeType::TEAM; + if (input == "ADMIN") + return EmployeeType::ADMIN; + return EmployeeType::INVALID; + } + + inline TeamStatus getTeamStatus(const std::string& str) + { + if (str == "IN_TEAM") + return TeamStatus::IN_TEAM; + if (str == "NOT_IN_TEAM") + return TeamStatus::NOT_IN_TEAM; + return TeamStatus::NOT_IN_TEAM; + } + + inline EmployeeDesignation getEmployeeDesignation(const std::string& input) + { + if (input == "JUNIOR") + return EmployeeDesignation::JUNIOR; + if (input == "SENIOR") + return EmployeeDesignation::SENIOR; + if (input == "TEAM_LEAD") + return EmployeeDesignation::TEAM_LEAD; + return EmployeeDesignation::INVALID; + } } diff --git a/Trenser.Zenvy/Trenser.Zenvy/utilities/StringHelper.cpp b/Trenser.Zenvy/Trenser.Zenvy/utilities/StringHelper.cpp new file mode 100644 index 0000000..00af011 --- /dev/null +++ b/Trenser.Zenvy/Trenser.Zenvy/utilities/StringHelper.cpp @@ -0,0 +1,15 @@ +#include "StringHelper.h" +#include + +int util::extractNumber(const std::string& input) +{ + int result = 0; + for (char character : input) + { + if (std::isdigit(static_cast(character))) + { + result = result * 10 + (character - '0'); + } + } + return result; +} diff --git a/Trenser.Zenvy/Trenser.Zenvy/utilities/StringHelper.h b/Trenser.Zenvy/Trenser.Zenvy/utilities/StringHelper.h new file mode 100644 index 0000000..12df49a --- /dev/null +++ b/Trenser.Zenvy/Trenser.Zenvy/utilities/StringHelper.h @@ -0,0 +1,7 @@ +#pragma once +#include + +namespace util +{ + int extractNumber(const std::string&); +} diff --git a/Trenser.Zenvy/Trenser.Zenvy/views/FinanceExecutiveMenu.cpp b/Trenser.Zenvy/Trenser.Zenvy/views/FinanceExecutiveMenu.cpp index 285c3c3..65f0c94 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/views/FinanceExecutiveMenu.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/views/FinanceExecutiveMenu.cpp @@ -49,7 +49,7 @@ std::string FinanceExecutiveMenu::getSelectedUserId() for (const auto& employee : employeeList) { std::cout << std::left << std::setw(6) << employee.first - << std::setw(15) << employee.second->getEmployeeId() + << std::setw(15) << employee.second->getId() << std::setw(25) << employee.second->getEmployeeName() << std::endl; } @@ -58,7 +58,7 @@ std::string FinanceExecutiveMenu::getSelectedUserId() auto employeeIterator = employeeList.find(choice); if (employeeIterator != employeeList.end()) { - return (employeeIterator->second->getEmployeeId()); + return (employeeIterator->second->getId()); } else { diff --git a/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.h b/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.h index 32a923c..4dd21c7 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.h +++ b/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.h @@ -63,7 +63,7 @@ inline std::map> listEmployees(const std::s { std::cout << std::left << std::setw(5) << index - << std::setw(15) << activeEmployees->getEmployeeId() + << std::setw(15) << activeEmployees->getId() << std::setw(25) << activeEmployees->getEmployeeName() << "\n"; employeeList[index] = activeEmployees; @@ -90,7 +90,7 @@ inline void deactivateEmployee(const std::shared_ptr& controlle auto iterator = employeeList.find(choice); if (iterator != employeeList.end()) { - std::string id = iterator->second->getEmployeeId(); + std::string id = iterator->second->getId(); bool success = controller->deactivateEmployee(id); if (success) { diff --git a/Trenser.Zenvy/Trenser.Zenvy/views/UserInterface.cpp b/Trenser.Zenvy/Trenser.Zenvy/views/UserInterface.cpp index adea852..8c29245 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/views/UserInterface.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/views/UserInterface.cpp @@ -19,6 +19,15 @@ void UserInterface::run() { bool isMenuActive = true; + try + { + m_controller->loadStates(); + } + catch (const std::exception& e) + { + std::cout << "Exception: " << e.what() << std::endl; + return; + } while (isMenuActive) { try @@ -94,7 +103,7 @@ void UserInterface::login() } else { - std::cout << "\nInvalid Password"; + std::cout << "Error: Invalid Password\n"; util::pressEnter(); return; } From 03be8f81d2993711800859605598dbfd7b31785d Mon Sep 17 00:00:00 2001 From: Joel Thomas Date: Fri, 10 Apr 2026 13:33:41 +0530 Subject: [PATCH 3/9] Refactored employee creation menu and centralized helper logic SRS02 : Employee Management - Removed duplicate employee creation helper functions from AdminMenu and HRManagerMenu - Centralized employee creation flow into MenuHelper.cpp - Updated createEmployee to use current employee type for access control - Fixed parameter order bug in createEmployee (email, name, phone) - Improved menu titles for all roles (removed generic system header) - Added util::pressEnter() for better UX on invalid input across menus - Added newline before pause in InputHelper::pressEnter - Cleaned up minor formatting issues --- .../services/EmployeeManagementService.cpp | 2 +- .../Trenser.Zenvy/utilities/InputHelper.h | 1 + .../Trenser.Zenvy/views/AdminMenu.cpp | 82 +------------- .../Trenser.Zenvy/views/EmployeeMenu.cpp | 3 +- .../views/FinanceExecutiveMenu.cpp | 3 +- .../Trenser.Zenvy/views/HRManagerMenu.cpp | 87 +-------------- .../Trenser.Zenvy/views/ITExecutiveMenu.cpp | 3 +- .../Trenser.Zenvy/views/MenuHelper.cpp | 102 ++++++++++++++++++ .../Trenser.Zenvy/views/MenuHelper.h | 4 +- .../views/TalentExecutiveMenu.cpp | 3 +- .../Trenser.Zenvy/views/TeamExecutiveMenu.cpp | 3 +- .../Trenser.Zenvy/views/TeamLeadMenu.cpp | 3 +- 12 files changed, 125 insertions(+), 171 deletions(-) diff --git a/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.cpp b/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.cpp index 1c9919d..3de8fcd 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.cpp @@ -13,7 +13,7 @@ #include "FileManager.h" #include "ApplicationConfig.h" -void EmployeeManagementService::createEmployee(Enums::EmployeeType employeeType, Enums::EmployeeDesignation employeeDesignation, const std::string& email, const std::string& name, const std::string& phone) +void EmployeeManagementService::createEmployee(Enums::EmployeeType employeeType, Enums::EmployeeDesignation employeeDesignation, const std::string& email, const std::string& name, const std::string& phone) { std::shared_ptr authenticatedEmployee = m_dataStore.getAuthenticatedEmployee(); if (!authenticatedEmployee) diff --git a/Trenser.Zenvy/Trenser.Zenvy/utilities/InputHelper.h b/Trenser.Zenvy/Trenser.Zenvy/utilities/InputHelper.h index 559acda..26128c1 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/utilities/InputHelper.h +++ b/Trenser.Zenvy/Trenser.Zenvy/utilities/InputHelper.h @@ -25,6 +25,7 @@ namespace util inline void pressEnter() { + std::cout << std::endl; system("pause"); } } \ No newline at end of file diff --git a/Trenser.Zenvy/Trenser.Zenvy/views/AdminMenu.cpp b/Trenser.Zenvy/Trenser.Zenvy/views/AdminMenu.cpp index 44388bf..2d7ffd9 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/views/AdminMenu.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/views/AdminMenu.cpp @@ -4,87 +4,6 @@ #include "OutputHelper.h" #include "MenuHelper.h" -static Enums::EmployeeType getEmployeeType() -{ - int choice; - util::clear(); - std::cout << "Select Employee Type" - "\n1. HR Employee" - "\n2. IT Executive" - "\n3. Team Executive" - "\n4. Finance Executive" - "\n5. Talent Executive" - "\n6. General Employee"; - util::read(choice); - switch (choice) - { - case 1: - return Enums::EmployeeType::HR; - case 2: - return Enums::EmployeeType::IT; - case 3: - return Enums::EmployeeType::TEAM; - case 4: - return Enums::EmployeeType::FINANCE; - case 5: - return Enums::EmployeeType::TAG; - case 6: - return Enums::EmployeeType::GENERAL; - default: - return Enums::EmployeeType::INVALID; - } -} - -static Enums::EmployeeDesignation getEmployeeDesignation() -{ - int choice; - util::clear(); - std::cout << "Select Employee Designation" - "\n1. SENIOR" - "\n2. JUNIOR"; - util::read(choice); - switch (choice) - { - case 1: - return Enums::EmployeeDesignation::SENIOR; - case 2: - return Enums::EmployeeDesignation::JUNIOR; - default: - return Enums::EmployeeDesignation::INVALID; - } -} - -static void createEmployee(std::shared_ptr controller) -{ - Enums::EmployeeType employeeType = getEmployeeType(); - Enums::EmployeeDesignation employeeDesignation = Enums::EmployeeDesignation::INVALID; - std::string name, email, phone; - switch (employeeType) - { - case Enums::EmployeeType::INVALID: - std::cout << "Invalid Choice"; - util::pressEnter(); - return; - case Enums::EmployeeType::GENERAL: - employeeDesignation = getEmployeeDesignation(); - if (employeeDesignation == Enums::EmployeeDesignation::INVALID) - { - std::cout << "Invalid Choice"; - util::pressEnter(); - return; - } - break; - } - std::cout << "Enter Name: "; - util::read(name); - std::cout << "Enter Email: "; - util::read(email); - std::cout << "Enter Phone: "; - util::read(phone); - controller->createEmployee(employeeType, employeeDesignation, name, email, phone); - std::cout << "\nCreated Employee Successfully."; -} - void AdminMenu::run() { bool isMenuActive = true; @@ -129,6 +48,7 @@ bool AdminMenu::handleOperation(int choice) return false; default: std::cout << "Enter a valid choice!" << std::endl; + util::pressEnter(); } return true; } diff --git a/Trenser.Zenvy/Trenser.Zenvy/views/EmployeeMenu.cpp b/Trenser.Zenvy/Trenser.Zenvy/views/EmployeeMenu.cpp index 5b82b20..e54b282 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/views/EmployeeMenu.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/views/EmployeeMenu.cpp @@ -13,7 +13,7 @@ void EmployeeMenu::run() { int choice; util::clear(); - std::cout << "Zenvy - The HR Management System\n1. Apply Leave\n2. View Payslip\n3. View Payslip History\n4. Raise Ticke\n5. View Ticket\n6. View Ticket History\n7. View Employees\n8. Search Employee\n9. View Team Members\n10. Book Meeting Room\n11. View Booking History\n12. View Notification\n13. View Announcements\n14. Update Profile\n15. Logout\nEnter your Choice: "; + std::cout << "Employee Menu\n1. Apply Leave\n2. View Payslip\n3. View Payslip History\n4. Raise Ticke\n5. View Ticket\n6. View Ticket History\n7. View Employees\n8. Search Employee\n9. View Team Members\n10. Book Meeting Room\n11. View Booking History\n12. View Notification\n13. View Announcements\n14. Update Profile\n15. Logout\nEnter your Choice: "; util::read(choice); if (!handleOperation(choice)) { @@ -79,6 +79,7 @@ bool EmployeeMenu::handleOperation(int choice) return false; default: std::cout << "Enter a valid choice!" << std::endl; + util::pressEnter(); } return true; } diff --git a/Trenser.Zenvy/Trenser.Zenvy/views/FinanceExecutiveMenu.cpp b/Trenser.Zenvy/Trenser.Zenvy/views/FinanceExecutiveMenu.cpp index 65f0c94..28c7f74 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/views/FinanceExecutiveMenu.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/views/FinanceExecutiveMenu.cpp @@ -13,7 +13,7 @@ void FinanceExecutiveMenu::run() { int choice; util::clear(); - std::cout << "Zenvy - The HR Management System\n1. Apply Leave\n2. View Payslip\n3. View Payslip History\n4. View Employees\n5. Search Employee\n6. View Notification\n7. View Announcements\n8. Resolve Ticket\n9. Generate Payslip\n10. Update Payroll\n11. Update Profile\n12. Logout\nEnter your Choice: "; + std::cout << "Finance Executive Menu\n1. Apply Leave\n2. View Payslip\n3. View Payslip History\n4. View Employees\n5. Search Employee\n6. View Notification\n7. View Announcements\n8. Resolve Ticket\n9. Generate Payslip\n10. Update Payroll\n11. Update Profile\n12. Logout\nEnter your Choice: "; util::read(choice); if (!handleOperation(choice)) { @@ -130,6 +130,7 @@ bool FinanceExecutiveMenu::handleOperation(int choice) return false; default: std::cout << "Enter a valid choice!" << std::endl; + util::pressEnter(); } return true; } diff --git a/Trenser.Zenvy/Trenser.Zenvy/views/HRManagerMenu.cpp b/Trenser.Zenvy/Trenser.Zenvy/views/HRManagerMenu.cpp index 8d51e73..654997c 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/views/HRManagerMenu.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/views/HRManagerMenu.cpp @@ -4,84 +4,6 @@ #include "OutputHelper.h" #include "MenuHelper.h" -static Enums::EmployeeType getEmployeeType() -{ - int choice; - util::clear(); - std::cout << "Select Employee Type" - "\n1. IT Executive" - "\n2. Team Executive" - "\n3. Finance Executive" - "\n4. Talent Executive" - "\n5. General Employee"; - util::read(choice); - switch (choice) - { - case 1: - return Enums::EmployeeType::IT; - case 2: - return Enums::EmployeeType::TEAM; - case 3: - return Enums::EmployeeType::FINANCE; - case 4: - return Enums::EmployeeType::TAG; - case 5: - return Enums::EmployeeType::GENERAL; - default: - return Enums::EmployeeType::INVALID; - } -} - -static Enums::EmployeeDesignation getEmployeeDesignation() -{ - int choice; - util::clear(); - std::cout << "Select Employee Designation" - "\n1. SENIOR" - "\n2. JUNIOR"; - util::read(choice); - switch (choice) - { - case 1: - return Enums::EmployeeDesignation::SENIOR; - case 2: - return Enums::EmployeeDesignation::JUNIOR; - default: - return Enums::EmployeeDesignation::INVALID; - } -} - -static void createEmployee(std::shared_ptr controller) -{ - Enums::EmployeeType employeeType = getEmployeeType(); - Enums::EmployeeDesignation employeeDesignation = Enums::EmployeeDesignation::INVALID; - std::string name, email, phone; - switch (employeeType) - { - case Enums::EmployeeType::INVALID: - std::cout << "Invalid Choice"; - util::pressEnter(); - return; - case Enums::EmployeeType::GENERAL: - employeeDesignation = getEmployeeDesignation(); - if (employeeDesignation == Enums::EmployeeDesignation::INVALID) - { - std::cout << "Invalid Choice"; - util::pressEnter(); - return; - } - break; - } - std::cout << "Enter Name: "; - util::read(name); - std::cout << "Enter Email: "; - util::read(email); - std::cout << "Enter Phone: "; - util::read(phone); - controller->createEmployee(employeeType, employeeDesignation, name, email, phone); - std::cout << "\nCreated Employee Successfully."; -} - void HRManagerMenu::run() { bool isMenuActive = true; @@ -91,7 +13,7 @@ void HRManagerMenu::run() { int choice; util::clear(); - std::cout << "Zenvy - The HR Management System\n1. Apply Leave\n2. View Payslip\n3. View Payslip History\n4. View Employees\n5. Search Employee\n6. View Notification\n7. View Announcements\n8. Create Employee\n9. Regularize Attendance\n10. Update Leave Request\n11. Register CandidateAsEmployee\n12. Update Profile\n13. Deactivate Employee\n14. Logout\nEnter your Choice: "; + std::cout << "HR Manager Menu\n1. Apply Leave\n2. View Payslip\n3. View Payslip History\n4. View Employees\n5. Search Employee\n6. View Notification\n7. View Announcements\n8. Create Employee\n9. Regularize Attendance\n10. Update Leave Request\n11. Register CandidateAsEmployee\n12. Update Profile\n13. Deactivate Employee\n14. Logout\nEnter your Choice: "; util::read(choice); if (!handleOperation(choice)) { @@ -130,11 +52,11 @@ bool HRManagerMenu::handleOperation(int choice) break; case 7: m_zenvyController.viewAnnouncements(); - break; + break;*/ case 8: - m_zenvyController.createEmployee(); + createEmployee(m_zenvyController); break; - case 9: + /*case 9: m_zenvyController.regularizeAttenance(); break; case 10: @@ -152,6 +74,7 @@ bool HRManagerMenu::handleOperation(int choice) return false; default: std::cout << "Enter a valid choice!" << std::endl; + util::pressEnter(); } return true; } diff --git a/Trenser.Zenvy/Trenser.Zenvy/views/ITExecutiveMenu.cpp b/Trenser.Zenvy/Trenser.Zenvy/views/ITExecutiveMenu.cpp index 962b372..90ae17b 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/views/ITExecutiveMenu.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/views/ITExecutiveMenu.cpp @@ -13,7 +13,7 @@ void ITExecutiveMenu::run() { int choice; util::clear(); - std::cout << "Zenvy - The HR Management System\n1. Apply Leave\n2. View Payslip\n3. View Payslip History\n4. View Employees\n5. Search Employee\n6. View Notification\n7. View Announcements\n8. Resolve Ticket\n9. Update Profile\n10. Logout\nEnter your Choice: "; + std::cout << "IT Executive Menu\n1. Apply Leave\n2. View Payslip\n3. View Payslip History\n4. View Employees\n5. Search Employee\n6. View Notification\n7. View Announcements\n8. Resolve Ticket\n9. Update Profile\n10. Logout\nEnter your Choice: "; util::read(choice); if (!handleOperation(choice)) { @@ -63,6 +63,7 @@ bool ITExecutiveMenu::handleOperation(int choice) return false; default: std::cout << "Enter a valid choice!" << std::endl; + util::pressEnter(); } return true; } diff --git a/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.cpp b/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.cpp index 36b2e02..6ec6f00 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.cpp @@ -1 +1,103 @@ +#include #include "MenuHelper.h" + +static Enums::EmployeeType getEmployeeType(Enums::EmployeeType employeeType) +{ + int choice; + util::clear(); + static const std::map> employeeTypeOptions = { + { Enums::EmployeeType::ADMIN, { + Enums::EmployeeType::HR, + Enums::EmployeeType::IT, + Enums::EmployeeType::TEAM, + Enums::EmployeeType::FINANCE, + Enums::EmployeeType::TAG, + Enums::EmployeeType::GENERAL + }}, + { Enums::EmployeeType::HR, { + Enums::EmployeeType::IT, + Enums::EmployeeType::TEAM, + Enums::EmployeeType::FINANCE, + Enums::EmployeeType::TAG, + Enums::EmployeeType::GENERAL + }} + }; + static const std::map labels = { + { Enums::EmployeeType::HR, "HR Employee" }, + { Enums::EmployeeType::IT, "IT Executive" }, + { Enums::EmployeeType::TEAM, "Team Executive" }, + { Enums::EmployeeType::FINANCE, "Finance Executive" }, + { Enums::EmployeeType::TAG, "Talent Executive" }, + { Enums::EmployeeType::GENERAL, "General Employee" } + }; + auto it = employeeTypeOptions.find(employeeType); + if (it == employeeTypeOptions.end()) + { + throw std::runtime_error("You do not have the authority to create a new Employee!"); + } + const auto& options = it->second; + std::cout << "Select Employee Type\n"; + for (int index = 0; index < options.size(); ++index) + { + std::cout << index + 1 << ". " << labels.at(options[index]) << "\n"; + } + std::cout << "Enter Choice: "; + util::read(choice); + if (choice >= 1 && choice <= options.size()) + { + return options[choice - 1]; + } + return Enums::EmployeeType::INVALID; +} + +static Enums::EmployeeDesignation getEmployeeDesignation() +{ + int choice; + util::clear(); + std::cout << "Select Employee Designation" + "\n1. SENIOR" + "\n2. JUNIOR" + "\nEnter Choice: "; + util::read(choice); + switch (choice) + { + case 1: + return Enums::EmployeeDesignation::SENIOR; + case 2: + return Enums::EmployeeDesignation::JUNIOR; + default: + return Enums::EmployeeDesignation::INVALID; + } +} + +void createEmployee(std::shared_ptr controller) +{ + auto currentEmployee = controller->getCurrentEmployee(); + Enums::EmployeeType employeeType = getEmployeeType(currentEmployee->getEmployeeType()); + Enums::EmployeeDesignation employeeDesignation = Enums::EmployeeDesignation::INVALID; + std::string name, email, phone; + switch (employeeType) + { + case Enums::EmployeeType::INVALID: + std::cout << "Invalid Choice"; + util::pressEnter(); + return; + case Enums::EmployeeType::GENERAL: + employeeDesignation = getEmployeeDesignation(); + if (employeeDesignation == Enums::EmployeeDesignation::INVALID) + { + std::cout << "Invalid Choice"; + util::pressEnter(); + return; + } + break; + } + std::cout << "Enter Name: "; + util::read(name); + std::cout << "Enter Email: "; + util::read(email); + std::cout << "Enter Phone: "; + util::read(phone); + controller->createEmployee(employeeType, employeeDesignation, email, name, phone); + std::cout << "\nCreated Employee Successfully."; +} diff --git a/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.h b/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.h index 4dd21c7..b861d6a 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.h +++ b/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.h @@ -9,6 +9,9 @@ #include "MenuHelper.h" #include "InputHelper.h" #include "OutputHelper.h" +#include "Enums.h" + +void createEmployee(std::shared_ptr controller); inline void updateProfile(std::shared_ptr m_zenvyController) { @@ -48,7 +51,6 @@ inline void updateProfile(std::shared_ptr m_zenvyController) } } - inline std::map> listEmployees(const std::shared_ptr& controller) { auto employees = controller->getEmployees(); diff --git a/Trenser.Zenvy/Trenser.Zenvy/views/TalentExecutiveMenu.cpp b/Trenser.Zenvy/Trenser.Zenvy/views/TalentExecutiveMenu.cpp index 70ca2d2..055d4f1 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/views/TalentExecutiveMenu.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/views/TalentExecutiveMenu.cpp @@ -13,7 +13,7 @@ void TalentExecutiveMenu::run() { int choice; util::clear(); - std::cout << "Zenvy - The HR Management System\n1. Apply Leave\n2. View Payslip\n3. View Payslip History\n4. View Employees\n5. Search Employee\n6. View Notification\n7. View Announcements\n8. Create New Job\n9. View Job Opening\n10. Add Candidate\n11. UpdateCandidate Status\n12. View Shortlisted Candidate\n13. Update Profile\n14. Logout\nEnter your Choice: "; + std::cout << "Talent Executive Menu\n1. Apply Leave\n2. View Payslip\n3. View Payslip History\n4. View Employees\n5. Search Employee\n6. View Notification\n7. View Announcements\n8. Create New Job\n9. View Job Opening\n10. Add Candidate\n11. UpdateCandidate Status\n12. View Shortlisted Candidate\n13. Update Profile\n14. Logout\nEnter your Choice: "; util::read(choice); if (!handleOperation(choice)) { @@ -75,6 +75,7 @@ bool TalentExecutiveMenu::handleOperation(int choice) return false; default: std::cout << "Enter a valid choice!" << std::endl; + util::pressEnter(); } return true; } diff --git a/Trenser.Zenvy/Trenser.Zenvy/views/TeamExecutiveMenu.cpp b/Trenser.Zenvy/Trenser.Zenvy/views/TeamExecutiveMenu.cpp index b085c52..5b709b8 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/views/TeamExecutiveMenu.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/views/TeamExecutiveMenu.cpp @@ -13,7 +13,7 @@ void TeamExecutiveMenu::run() { int choice; util::clear(); - std::cout << "Zenvy - The HR Management System\n1. Apply Leave\n2. View Payslip\n3. View Payslip History\n4. View Employees\n5. Search Employee\n6. View Notification\n7. View Announcements\n8. Create Team\n9. Update Team\n10. Remove Team\n11. Assign Employee\n12. Unassign Employee\n13. View Teams\n14. Update Profile\n15. Logout\nEnter your Choice: "; + std::cout << "Team Executive Menu\n1. Apply Leave\n2. View Payslip\n3. View Payslip History\n4. View Employees\n5. Search Employee\n6. View Notification\n7. View Announcements\n8. Create Team\n9. Update Team\n10. Remove Team\n11. Assign Employee\n12. Unassign Employee\n13. View Teams\n14. Update Profile\n15. Logout\nEnter your Choice: "; util::read(choice); if (!handleOperation(choice)) { @@ -78,6 +78,7 @@ bool TeamExecutiveMenu::handleOperation(int choice) return false; default: std::cout << "Enter a valid choice!" << std::endl; + util::pressEnter(); } return true; } diff --git a/Trenser.Zenvy/Trenser.Zenvy/views/TeamLeadMenu.cpp b/Trenser.Zenvy/Trenser.Zenvy/views/TeamLeadMenu.cpp index d03c7f4..e32c751 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/views/TeamLeadMenu.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/views/TeamLeadMenu.cpp @@ -13,7 +13,7 @@ void TeamLeadMenu::run() { int choice; util::clear(); - std::cout << "Zenvy - The HR Management System\n1. Apply Leave\n2. View Payslip\n3. View Payslip History\n4. Raise Ticke\n5. View Ticket\n6. View Ticket History\n7. View Employees\n8. Search Employee\n9. View Team Members\n10. Book Meeting Room\n11. View Booking History\n12. View Notification\n13. View Announcements\n4. Regularize Attendance\n15. Update Leave Request\n16. Update Profile\n17. Logout\nEnter your Choice: "; + std::cout << "Team Lead Menu\n1. Apply Leave\n2. View Payslip\n3. View Payslip History\n4. Raise Ticke\n5. View Ticket\n6. View Ticket History\n7. View Employees\n8. Search Employee\n9. View Team Members\n10. Book Meeting Room\n11. View Booking History\n12. View Notification\n13. View Announcements\n4. Regularize Attendance\n15. Update Leave Request\n16. Update Profile\n17. Logout\nEnter your Choice: "; util::read(choice); if (!handleOperation(choice)) { @@ -84,6 +84,7 @@ bool TeamLeadMenu::handleOperation(int choice) return false; default: std::cout << "Enter a valid choice!" << std::endl; + util::pressEnter(); } return true; } From eac6fa72dffc54f40030c6d07e89422bc6028ee8 Mon Sep 17 00:00:00 2001 From: Joel Thomas Date: Fri, 10 Apr 2026 16:43:28 +0530 Subject: [PATCH 4/9] Added validation checks for employee creation SRS02 : Employee Management - Added helper function to check for existing active employee of a given type - Enforced business rule to allow only one active employee per non-general type - Added duplicate email validation before employee creation - Added duplicate phone number validation before employee creation Smitha Mohan --- .../services/EmployeeManagementService.cpp | 53 ++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.cpp b/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.cpp index 3de8fcd..97297ad 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.cpp @@ -13,8 +13,48 @@ #include "FileManager.h" #include "ApplicationConfig.h" +static bool hasActiveEmployeeOfType(Enums::EmployeeType employeeType, const employeeMap& employees) +{ + for (const auto& employeePair : employees) + { + const auto& employee = employeePair.second; + if (employee->getEmployeeType() == employeeType && employee->getEmployeeAccountStatus() == Enums::AccountStatus::ACTIVE) + { + return true; + } + } + return false; +} + +static bool isEmailDuplicate(const std::string& email, const employeeMap& employees) +{ + for (const auto& employeePair : employees) + { + const auto& employee = employeePair.second; + if (employee->getEmployeeEmail() == email) + { + return true; + } + } + return false; +} + +static bool isPhoneDuplicate(const std::string& phone, const employeeMap& employees) +{ + for (const auto& employeePair : employees) + { + const auto& employee = employeePair.second; + if (employee->getEmployeePhone() == phone) + { + return true; + } + } + return false; +} + void EmployeeManagementService::createEmployee(Enums::EmployeeType employeeType, Enums::EmployeeDesignation employeeDesignation, const std::string& email, const std::string& name, const std::string& phone) { + auto& employees = m_dataStore.getEmployees(); std::shared_ptr authenticatedEmployee = m_dataStore.getAuthenticatedEmployee(); if (!authenticatedEmployee) { @@ -23,6 +63,10 @@ void EmployeeManagementService::createEmployee(Enums::EmployeeType employeeType, Enums::EmployeeType authenticatedEmployeeType = authenticatedEmployee->getEmployeeType(); std::shared_ptr employee; std::shared_ptr payroll; + if (employeeType != Enums::EmployeeType::GENERAL && hasActiveEmployeeOfType(employeeType, employees)) + { + throw std::runtime_error("Cannot create more than one employee of type " + Enums::getEmployeeTypeString(employeeType)); + } if (!util::isEmailValid(email)) { throw std::runtime_error("Invalid Email"); @@ -31,6 +75,14 @@ void EmployeeManagementService::createEmployee(Enums::EmployeeType employeeType, { throw std::runtime_error("Invalid Phone"); } + if (isEmailDuplicate(email, employees)) + { + throw std::runtime_error("Duplicate Email"); + } + if (isPhoneDuplicate(phone, employees)) + { + throw std::runtime_error("Duplicate Phone Number!"); + } switch (employeeType) { case Enums::EmployeeType::HR: @@ -42,7 +94,6 @@ void EmployeeManagementService::createEmployee(Enums::EmployeeType employeeType, Config::Payroll::HR_MANAGER_EMPLOYER_PF_CONTRIBUTION); employee = Factory::getObject(name, phone, email, payroll); break; - case Enums::EmployeeType::IT: case Enums::EmployeeType::FINANCE: case Enums::EmployeeType::TEAM: From c50700e70c6f41a7dc0c031899f5ccc2111367b7 Mon Sep 17 00:00:00 2001 From: Joel Thomas Date: Fri, 10 Apr 2026 19:41:08 +0530 Subject: [PATCH 5/9] Added CSV header support and persistence for employees SRS02 : Employee Management - Added header handling in FileManager load by skipping first line during deserialization - Added support for writing headers using T::getHeaders() in FileManager save - Implemented getHeaders() for Employee and GeneralEmployee models - Added saveEmployees functionality in EmployeeManagementService - Added persistStates method in ZenvyController - Added deserialization failure check with exception handling - Minor formatting cleanup in FileIO Smitha Mohan --- .../Trenser.FileManager/FileIO.cpp | 3 +-- .../Trenser.FileManager/FileManager.h | 13 ++++++++++- .../controllers/ZenvyController.cpp | 5 ++++ .../controllers/ZenvyController.h | 1 + .../Trenser.Zenvy/models/Employee.cpp | 5 ++++ Trenser.Zenvy/Trenser.Zenvy/models/Employee.h | 1 + .../Trenser.Zenvy/models/GeneralEmployee.cpp | 5 ++++ .../Trenser.Zenvy/models/GeneralEmployee.h | 1 + .../services/EmployeeManagementService.cpp | 23 +++++++++++++++++++ .../services/EmployeeManagementService.h | 1 + .../Trenser.Zenvy/views/UserInterface.cpp | 9 ++++++++ 11 files changed, 64 insertions(+), 3 deletions(-) diff --git a/Trenser.FileManager/Trenser.FileManager/FileIO.cpp b/Trenser.FileManager/Trenser.FileManager/FileIO.cpp index ac79d03..8697eb3 100644 --- a/Trenser.FileManager/Trenser.FileManager/FileIO.cpp +++ b/Trenser.FileManager/Trenser.FileManager/FileIO.cpp @@ -22,7 +22,6 @@ void FileIO::writeAllLines(const std::string& path, std::ofstream file(path, std::ios::trunc); if (!file.is_open()) throw std::runtime_error("Failed to open file " + path); - for (const auto& line : lines) file << line << '\n'; -} \ No newline at end of file +} diff --git a/Trenser.FileManager/Trenser.FileManager/FileManager.h b/Trenser.FileManager/Trenser.FileManager/FileManager.h index 50a9fbf..1c9f3b2 100644 --- a/Trenser.FileManager/Trenser.FileManager/FileManager.h +++ b/Trenser.FileManager/Trenser.FileManager/FileManager.h @@ -1,4 +1,5 @@ #pragma once +#include #include "FileIO.h" template using objects = std::map>; @@ -20,9 +21,19 @@ objects FileManager::load() { objects records; auto lines = FileIO::readAllLines(m_filePath); + bool isHeader = true; for (const auto& record : lines) { + if (isHeader) + { + isHeader = false; + continue; + } auto object = T::deserialize(record); + if (!object) + { + throw std::runtime_error("Failed to deserialize record"); + } records[object->getId()] = object; } return records; @@ -32,7 +43,7 @@ template void FileManager::save(const objects& records) { std::vector lines; - + lines.push_back(T::getHeaders()); for (const auto& recordPair : records) { lines.push_back(recordPair.second->serialize()); diff --git a/Trenser.Zenvy/Trenser.Zenvy/controllers/ZenvyController.cpp b/Trenser.Zenvy/Trenser.Zenvy/controllers/ZenvyController.cpp index 7d587e6..9d21818 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/controllers/ZenvyController.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/controllers/ZenvyController.cpp @@ -51,3 +51,8 @@ void ZenvyController::loadStates() { m_employeeManagementService->loadEmployees(); } + +void ZenvyController::persistStates() +{ + m_employeeManagementService->saveEmployees(); +} diff --git a/Trenser.Zenvy/Trenser.Zenvy/controllers/ZenvyController.h b/Trenser.Zenvy/Trenser.Zenvy/controllers/ZenvyController.h index 2f8c137..1ed7415 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/controllers/ZenvyController.h +++ b/Trenser.Zenvy/Trenser.Zenvy/controllers/ZenvyController.h @@ -56,4 +56,5 @@ public: //File Management void loadStates(); + void persistStates(); }; diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/Employee.cpp b/Trenser.Zenvy/Trenser.Zenvy/models/Employee.cpp index f673458..fb6e023 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/Employee.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/models/Employee.cpp @@ -263,3 +263,8 @@ std::shared_ptr Employee::deserialize(const std::string& record) return nullptr; } } + +std::string Employee::getHeaders() +{ + return "EmployeeId,Email,Name,Phone,Password,TeamID,TeamStatus,AccountStatus,EmployeeType"; +} diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/Employee.h b/Trenser.Zenvy/Trenser.Zenvy/models/Employee.h index 6900943..46657c1 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/Employee.h +++ b/Trenser.Zenvy/Trenser.Zenvy/models/Employee.h @@ -90,5 +90,6 @@ public: Enums::EmployeeType getEmployeeType() const; virtual std::string serialize() const; static std::shared_ptr deserialize(const std::string&); + static std::string getHeaders(); virtual ~Employee() = default; }; \ No newline at end of file diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/GeneralEmployee.cpp b/Trenser.Zenvy/Trenser.Zenvy/models/GeneralEmployee.cpp index 455665b..2392097 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/GeneralEmployee.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/models/GeneralEmployee.cpp @@ -58,4 +58,9 @@ std::shared_ptr GeneralEmployee::deserialize(const std::string& employeeDesignation, accountStatus ); +} + +std::string GeneralEmployee::getHeaders() +{ + return "EmployeeId,Email,Name,Phone,Password,TeamID,TeamStatus,AccountStatus,EmployeeType,EmployeeDesignation"; } \ No newline at end of file diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/GeneralEmployee.h b/Trenser.Zenvy/Trenser.Zenvy/models/GeneralEmployee.h index 1277fff..61b1a06 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/GeneralEmployee.h +++ b/Trenser.Zenvy/Trenser.Zenvy/models/GeneralEmployee.h @@ -43,5 +43,6 @@ public: void setDesignation(Enums::EmployeeDesignation designation); std::string serialize() const override; static std::shared_ptr deserialize(const std::string&); + static std::string getHeaders(); ~GeneralEmployee() = default; }; \ No newline at end of file diff --git a/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.cpp b/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.cpp index 97297ad..6dd1b45 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.cpp @@ -1,3 +1,4 @@ +#include #include #include "EmployeeManagementService.h" #include "Factory.h" @@ -221,3 +222,25 @@ void EmployeeManagementService::loadEmployees() employees.emplace(std::make_pair(admin->getId(), admin)); } } + +void EmployeeManagementService::saveEmployees() +{ + FileManager employeeFileManager(Config::File::EMPLOYEES_FILE); + FileManager generalEmployeeFileManager(Config::File::GENERAL_EMPLOYEES_FILE); + const auto& allEmployees = m_dataStore.getEmployees(); + employeeMap employees; + std::map> generalEmployees; + for (auto& employeePair : allEmployees) + { + if (employeePair.second->getEmployeeType() == Enums::EmployeeType::GENERAL) + { + generalEmployees.emplace(employeePair.first, std::static_pointer_cast(employeePair.second)); + } + else + { + employees.emplace(employeePair); + } + } + employeeFileManager.save(employees); + generalEmployeeFileManager.save(generalEmployees); +} diff --git a/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.h b/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.h index cb2daf5..03f3848 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.h +++ b/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.h @@ -18,4 +18,5 @@ public: void updateProfile(const std::string&,const std::string&); std::shared_ptr getCurrentEmployee(); void loadEmployees(); + void saveEmployees(); }; diff --git a/Trenser.Zenvy/Trenser.Zenvy/views/UserInterface.cpp b/Trenser.Zenvy/Trenser.Zenvy/views/UserInterface.cpp index 8c29245..ae98311 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/views/UserInterface.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/views/UserInterface.cpp @@ -47,6 +47,15 @@ void UserInterface::run() util::pressEnter(); } } + try + { + m_controller->persistStates(); + } + catch (const std::exception& e) + { + std::cout << "Exception: " << e.what() << std::endl; + return; + } } bool UserInterface::handleOperation(int choice) From 1d94f1680cae5f19d55a5fc5679518454134a3c5 Mon Sep 17 00:00:00 2001 From: Joel Thomas Date: Fri, 10 Apr 2026 20:29:55 +0530 Subject: [PATCH 6/9] Refactored validation logic and centralized employee validators SRS02 : Employee Management - Moved employee validation logic (active type check, email and phone duplication) to Validator utility - Updated service to use util::hasActiveEmployeeOfType, util::isEmailDuplicate, and util::isPhoneDuplicate - Integrated validator usage in MenuHelper for input validation - Cleaned up formatting and minor inconsistencies Smitha Mohan --- .../services/EmployeeManagementService.cpp | 45 +---------- .../Trenser.Zenvy/utilities/Validator.cpp | 53 ++++++++++++- .../Trenser.Zenvy/utilities/Validator.h | 10 +++ .../Trenser.Zenvy/views/MenuHelper.h | 78 +++++++++++-------- 4 files changed, 111 insertions(+), 75 deletions(-) diff --git a/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.cpp b/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.cpp index 6dd1b45..4fe4ddc 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.cpp @@ -14,45 +14,6 @@ #include "FileManager.h" #include "ApplicationConfig.h" -static bool hasActiveEmployeeOfType(Enums::EmployeeType employeeType, const employeeMap& employees) -{ - for (const auto& employeePair : employees) - { - const auto& employee = employeePair.second; - if (employee->getEmployeeType() == employeeType && employee->getEmployeeAccountStatus() == Enums::AccountStatus::ACTIVE) - { - return true; - } - } - return false; -} - -static bool isEmailDuplicate(const std::string& email, const employeeMap& employees) -{ - for (const auto& employeePair : employees) - { - const auto& employee = employeePair.second; - if (employee->getEmployeeEmail() == email) - { - return true; - } - } - return false; -} - -static bool isPhoneDuplicate(const std::string& phone, const employeeMap& employees) -{ - for (const auto& employeePair : employees) - { - const auto& employee = employeePair.second; - if (employee->getEmployeePhone() == phone) - { - return true; - } - } - return false; -} - void EmployeeManagementService::createEmployee(Enums::EmployeeType employeeType, Enums::EmployeeDesignation employeeDesignation, const std::string& email, const std::string& name, const std::string& phone) { auto& employees = m_dataStore.getEmployees(); @@ -64,7 +25,7 @@ void EmployeeManagementService::createEmployee(Enums::EmployeeType employeeType, Enums::EmployeeType authenticatedEmployeeType = authenticatedEmployee->getEmployeeType(); std::shared_ptr employee; std::shared_ptr payroll; - if (employeeType != Enums::EmployeeType::GENERAL && hasActiveEmployeeOfType(employeeType, employees)) + if (employeeType != Enums::EmployeeType::GENERAL && util::hasActiveEmployeeOfType(employeeType, employees)) { throw std::runtime_error("Cannot create more than one employee of type " + Enums::getEmployeeTypeString(employeeType)); } @@ -76,11 +37,11 @@ void EmployeeManagementService::createEmployee(Enums::EmployeeType employeeType, { throw std::runtime_error("Invalid Phone"); } - if (isEmailDuplicate(email, employees)) + if (util::isEmailDuplicate(email, employees)) { throw std::runtime_error("Duplicate Email"); } - if (isPhoneDuplicate(phone, employees)) + if (util::isPhoneDuplicate(phone, employees)) { throw std::runtime_error("Duplicate Phone Number!"); } diff --git a/Trenser.Zenvy/Trenser.Zenvy/utilities/Validator.cpp b/Trenser.Zenvy/Trenser.Zenvy/utilities/Validator.cpp index 9d14b40..dd52e33 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/utilities/Validator.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/utilities/Validator.cpp @@ -1,6 +1,6 @@ -#include #include #include "Validator.h" +#include "Employee.h" #include "ApplicationConfig.h" bool util::isPhoneNumberValid(const std::string& phoneNumber) { @@ -69,3 +69,54 @@ bool util::isPasswordValid(const std::string& password) } return hasUpper && hasLower && hasDigit && hasSpecial; } + +bool util::hasActiveEmployeeOfType(Enums::EmployeeType employeeType, const std::map> & employees) +{ + for (const auto& employeePair : employees) + { + const auto& employee = employeePair.second; + if (employee->getEmployeeType() == employeeType && employee->getEmployeeAccountStatus() == Enums::AccountStatus::ACTIVE) + { + return true; + } + } + return false; +} + +bool util::isEmailDuplicate(const std::string& email, const std::map>& employees) +{ + for (const auto& employeePair : employees) + { + const auto& employee = employeePair.second; + if (employee->getEmployeeEmail() == email) + { + return true; + } + } + return false; +} + +bool util::isPhoneDuplicate(const std::string& phone, const std::map>& employees) +{ + for (const auto& employeePair : employees) + { + const auto& employee = employeePair.second; + if (employee->getEmployeePhone() == phone) + { + return true; + } + } + return false; +} + +bool util::isPhoneDuplicate(const std::string& phone, const std::vector>& employees) +{ + for (const auto& employee : employees) + { + if (employee->getEmployeePhone() == phone) + { + return true; + } + } + return false; +} diff --git a/Trenser.Zenvy/Trenser.Zenvy/utilities/Validator.h b/Trenser.Zenvy/Trenser.Zenvy/utilities/Validator.h index fbdf962..588b820 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/utilities/Validator.h +++ b/Trenser.Zenvy/Trenser.Zenvy/utilities/Validator.h @@ -1,11 +1,21 @@ #pragma once #include +#include +#include +#include #include #include +#include "Enums.h" + +class Employee; namespace util { bool isPhoneNumberValid(const std::string&); bool isEmailValid(const std::string&); bool isPasswordValid(const std::string&); + bool hasActiveEmployeeOfType(Enums::EmployeeType, const std::map>&); + bool isEmailDuplicate(const std::string&, const std::map>&); + bool isPhoneDuplicate(const std::string&, const std::map>&); + bool isPhoneDuplicate(const std::string&, const std::vector>&); } \ No newline at end of file diff --git a/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.h b/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.h index b861d6a..aef9716 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.h +++ b/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.h @@ -9,45 +9,59 @@ #include "MenuHelper.h" #include "InputHelper.h" #include "OutputHelper.h" +#include "Validator.h" #include "Enums.h" void createEmployee(std::shared_ptr controller); inline void updateProfile(std::shared_ptr m_zenvyController) { - int choice; - std::string name, phone; - name = m_zenvyController->getCurrentEmployee()->getEmployeeName(); - phone = m_zenvyController->getCurrentEmployee()->getEmployeePhone(); - while (true) + int choice; + std::string name, phone; + name = m_zenvyController->getCurrentEmployee()->getEmployeeName(); + phone = m_zenvyController->getCurrentEmployee()->getEmployeePhone(); + while (true) { - util::clear(); - std::cout << "Please choose the information you want to update:\n" - "1. Name\n" - "2. Phone Number\n" - "3. Exit\n" - "Enter your choice: "; - util::read(choice); - switch (choice) - { - case 1: - std::cout << "Enter your updated Name :"; - util::read(name); - m_zenvyController->updateProfile(name, phone); - std::cout << "Profile Updated Successfully\n"; - break; - case 2: - std::cout << "Enter your updated phone Number :"; - util::read(phone); - m_zenvyController->updateProfile(name, phone); - std::cout << "Profile Updated Successfully\n"; - break; - case 3: - return; - default: - std::cout << "Enter a valid choice!" << std::endl; - break; - } + util::clear(); + std::cout << "Please choose the information you want to update:\n" + "1. Name\n" + "2. Phone Number\n" + "3. Exit\n" + "Enter your choice: "; + util::read(choice); + switch (choice) + { + case 1: + std::cout << "Enter your updated Name: "; + util::read(name); + m_zenvyController->updateProfile(name, phone); + std::cout << "Profile Updated Successfully\n"; + util::pressEnter(); + break; + case 2: + std::cout << "Enter your updated phone Number: "; + util::read(phone); + if (!util::isPhoneNumberValid(phone)) + { + std::cout << "Error: Invalid Phone Number"; + util::pressEnter(); + } + if (util::isPhoneDuplicate(phone, m_zenvyController->getEmployees())) + { + std::cout << "Error: Duplicate Phone Number!"; + util::pressEnter(); + return; + } + m_zenvyController->updateProfile(name, phone); + std::cout << "Profile Updated Successfully\n"; + util::pressEnter(); + break; + case 3: + return; + default: + std::cout << "Enter a valid choice!" << std::endl; + break; + } } } From 47b44ccaa02378bf9e9e6e0bdf9f3db6198666bc Mon Sep 17 00:00:00 2001 From: Joel Thomas Date: Sat, 11 Apr 2026 12:13:23 +0530 Subject: [PATCH 7/9] Added payroll persistance and updated Talent Acquisition role SRS02 : Employee Management - Added Payroll getHeaders, serialize and deserialize functions - Stored payrolls in DataStore - Loaded and saved payrolls along with employees - Linked payroll to employees during creation and load - Added employeeId to Payroll - Renamed TAG role to TALENT_ACQUISITION across the project - Added missing TalentExecutive case in Employee deserialization - Added constructor to TalentExecutive for FileManager integration - Renamed ID counters to m_uid for consistency - Updated salary values in ApplicationConfig Smitha Mohan --- .../controllers/ZenvyController.cpp | 2 + .../Trenser.Zenvy/datastores/DataStore.cpp | 5 +- .../Trenser.Zenvy/datastores/DataStore.h | 4 + .../Trenser.Zenvy/models/Announcement.cpp | 2 +- .../Trenser.Zenvy/models/Announcement.h | 6 +- .../Trenser.Zenvy/models/Attendance.cpp | 2 +- .../Trenser.Zenvy/models/Attendance.h | 6 +- .../Trenser.Zenvy/models/Booking.cpp | 2 +- Trenser.Zenvy/Trenser.Zenvy/models/Booking.h | 6 +- .../Trenser.Zenvy/models/Candidate.cpp | 2 +- .../Trenser.Zenvy/models/Candidate.h | 6 +- .../Trenser.Zenvy/models/Employee.cpp | 11 +++ .../Trenser.Zenvy/models/JobListing.cpp | 2 +- .../Trenser.Zenvy/models/JobListing.h | 6 +- Trenser.Zenvy/Trenser.Zenvy/models/Leave.cpp | 2 +- Trenser.Zenvy/Trenser.Zenvy/models/Leave.h | 6 +- .../Trenser.Zenvy/models/Notification.cpp | 2 +- .../Trenser.Zenvy/models/Notification.h | 6 +- .../Trenser.Zenvy/models/Payroll.cpp | 94 ++++++++++++++++++- Trenser.Zenvy/Trenser.Zenvy/models/Payroll.h | 33 ++++++- .../Trenser.Zenvy/models/Payslip.cpp | 2 +- Trenser.Zenvy/Trenser.Zenvy/models/Payslip.h | 6 +- Trenser.Zenvy/Trenser.Zenvy/models/Room.cpp | 2 +- Trenser.Zenvy/Trenser.Zenvy/models/Room.h | 6 +- .../Trenser.Zenvy/models/TalentExecutive.h | 20 +++- Trenser.Zenvy/Trenser.Zenvy/models/Team.cpp | 2 +- Trenser.Zenvy/Trenser.Zenvy/models/Team.h | 6 +- Trenser.Zenvy/Trenser.Zenvy/models/Ticket.cpp | 2 +- Trenser.Zenvy/Trenser.Zenvy/models/Ticket.h | 6 +- .../services/ApplicationConfig.h | 41 ++++---- .../services/EmployeeManagementService.cpp | 6 +- .../services/PayslipManagementService.cpp | 28 ++++++ .../services/PayslipManagementService.h | 2 + Trenser.Zenvy/Trenser.Zenvy/utilities/Enums.h | 10 +- .../Trenser.Zenvy/views/MenuHelper.cpp | 6 +- .../Trenser.Zenvy/views/UserInterface.cpp | 2 +- 36 files changed, 269 insertions(+), 83 deletions(-) diff --git a/Trenser.Zenvy/Trenser.Zenvy/controllers/ZenvyController.cpp b/Trenser.Zenvy/Trenser.Zenvy/controllers/ZenvyController.cpp index 9d21818..d3d8a51 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/controllers/ZenvyController.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/controllers/ZenvyController.cpp @@ -50,9 +50,11 @@ Employees ZenvyController::getEmployees() void ZenvyController::loadStates() { m_employeeManagementService->loadEmployees(); + m_payslipManagementService->loadPayrolls(); } void ZenvyController::persistStates() { m_employeeManagementService->saveEmployees(); + m_payslipManagementService->savePayrolls(); } diff --git a/Trenser.Zenvy/Trenser.Zenvy/datastores/DataStore.cpp b/Trenser.Zenvy/Trenser.Zenvy/datastores/DataStore.cpp index 40b473f..dadcfdc 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/datastores/DataStore.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/datastores/DataStore.cpp @@ -27,4 +27,7 @@ employeeMap& DataStore::getEmployees() return m_employees; } - +payrollMap& DataStore::getPayrolls() +{ + return m_payrolls; +} diff --git a/Trenser.Zenvy/Trenser.Zenvy/datastores/DataStore.h b/Trenser.Zenvy/Trenser.Zenvy/datastores/DataStore.h index 750d741..d05d5f4 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/datastores/DataStore.h +++ b/Trenser.Zenvy/Trenser.Zenvy/datastores/DataStore.h @@ -18,8 +18,10 @@ #include "Notification.h" #include "Announcement.h" #include "Faq.h" +#include "Payroll.h" using employeeMap = std::map>; +using payrollMap = std::map>; using logMap = std::map>; class DataStore @@ -27,6 +29,7 @@ class DataStore private: std::shared_ptr m_authenticatedEmployee; employeeMap m_employees; + payrollMap m_payrolls; logMap m_logs; DataStore() = default; public: @@ -36,6 +39,7 @@ public: DataStore(DataStore&&) = delete; DataStore& operator=(DataStore&&) = delete; employeeMap& getEmployees(); + payrollMap& getPayrolls(); logMap& getLogs(); std::shared_ptr& getAuthenticatedEmployee(); void setAuthenticatedEmployee(std::shared_ptr < Employee>); diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/Announcement.cpp b/Trenser.Zenvy/Trenser.Zenvy/models/Announcement.cpp index 2b61e80..403222b 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/Announcement.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/models/Announcement.cpp @@ -1,6 +1,6 @@ #include "Announcement.h" -int Announcement::m_anid = 0; +int Announcement::m_uid = 0; const std::string& Announcement::getAnnouncementId() const { diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/Announcement.h b/Trenser.Zenvy/Trenser.Zenvy/models/Announcement.h index 5d69bdb..5c46514 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/Announcement.h +++ b/Trenser.Zenvy/Trenser.Zenvy/models/Announcement.h @@ -5,14 +5,14 @@ class Announcement { private: - static int m_anid; + static int m_uid; std::string m_id; util::Timestamp m_timestamp; std::string m_message; public: - Announcement() : m_id("AN" + std::to_string(++m_anid)), m_timestamp(), m_message("") {} + Announcement() : m_id("AN" + std::to_string(++m_uid)), m_timestamp(), m_message("") {} Announcement(const std::string& message) - : m_id("AN" + std::to_string(++m_anid)), m_message(message) {} + : m_id("AN" + std::to_string(++m_uid)), m_message(message) {} const std::string& getAnnouncementId() const; const util::Timestamp& getAnnouncementTimestamp() const; const std::string& getAnnouncementMessage() const; diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/Attendance.cpp b/Trenser.Zenvy/Trenser.Zenvy/models/Attendance.cpp index a6220dd..b4a51ef 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/Attendance.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/models/Attendance.cpp @@ -1,6 +1,6 @@ #include "Attendance.h" -int Attendance::m_aid = 0; +int Attendance::m_uid = 0; const std::string& Attendance::getAttendanceId() const { diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/Attendance.h b/Trenser.Zenvy/Trenser.Zenvy/models/Attendance.h index 9f6d481..013fb0b 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/Attendance.h +++ b/Trenser.Zenvy/Trenser.Zenvy/models/Attendance.h @@ -5,15 +5,15 @@ class Attendance { private: - static int m_aid; + static int m_uid; std::string m_id; util::Timestamp m_loginTime; util::Timestamp m_logoutTime; public: - Attendance() : m_id("AD" + std::to_string(++m_aid)), m_loginTime(), m_logoutTime() {} + Attendance() : m_id("AD" + std::to_string(++m_uid)), m_loginTime(), m_logoutTime() {} Attendance(const util::Timestamp& loginTime, const util::Timestamp& logoutTime) - : m_id("AD" + std::to_string(++m_aid)), m_loginTime(loginTime), m_logoutTime(logoutTime) {} + : m_id("AD" + std::to_string(++m_uid)), m_loginTime(loginTime), m_logoutTime(logoutTime) {} const std::string& getAttendanceId() const; const util::Timestamp& getLoginTime() const; const util::Timestamp& getLogoutTime() const; diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/Booking.cpp b/Trenser.Zenvy/Trenser.Zenvy/models/Booking.cpp index 4c0dcb0..1b0f141 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/Booking.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/models/Booking.cpp @@ -1,6 +1,6 @@ #include "Booking.h" -int Booking::m_bid = 0; +int Booking::m_uid = 0; const std::string& Booking::getBookingId() const { diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/Booking.h b/Trenser.Zenvy/Trenser.Zenvy/models/Booking.h index c8bc55c..2100841 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/Booking.h +++ b/Trenser.Zenvy/Trenser.Zenvy/models/Booking.h @@ -7,19 +7,19 @@ class Booking { private: - static int m_bid; + static int m_uid; std::string m_id; util::Timestamp m_startTime; util::Timestamp m_endTime; std::string m_employeeId; std::shared_ptr m_team; public: - Booking() : m_id("BK" + std::to_string(++m_bid)), m_startTime(), m_endTime(), m_employeeId(""), m_team(nullptr) {} + Booking() : m_id("BK" + std::to_string(++m_uid)), m_startTime(), m_endTime(), m_employeeId(""), m_team(nullptr) {} Booking(const util::Timestamp& startTime, const util::Timestamp& endTime, const std::string& employeeId, std::shared_ptr team) - : m_id("BK" + std::to_string(++m_bid)), m_startTime(startTime), m_endTime(endTime), m_employeeId(employeeId), m_team(team) {} + : m_id("BK" + std::to_string(++m_uid)), m_startTime(startTime), m_endTime(endTime), m_employeeId(employeeId), m_team(team) {} const std::string& getBookingId() const; const util::Timestamp& getStartTime() const; const util::Timestamp& getEndTime() const; diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/Candidate.cpp b/Trenser.Zenvy/Trenser.Zenvy/models/Candidate.cpp index c48c2a1..779652f 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/Candidate.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/models/Candidate.cpp @@ -1,6 +1,6 @@ #include "Candidate.h" -int Candidate::m_cid = 0; +int Candidate::m_uid = 0; const std::string& Candidate::getCandidateId() const { diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/Candidate.h b/Trenser.Zenvy/Trenser.Zenvy/models/Candidate.h index 646a8ef..db55250 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/Candidate.h +++ b/Trenser.Zenvy/Trenser.Zenvy/models/Candidate.h @@ -5,19 +5,19 @@ class Candidate { private: - static int m_cid; + static int m_uid; std::string m_id; std::string m_name; long int m_phone; std::string m_qualification; Enums::CandidateStatus m_status; public: - Candidate() : m_id("CD" + std::to_string(++m_cid)), m_name(""), m_phone(0), m_qualification(""), m_status(Enums::CandidateStatus::PENDING) {} + Candidate() : m_id("CD" + std::to_string(++m_uid)), m_name(""), m_phone(0), m_qualification(""), m_status(Enums::CandidateStatus::PENDING) {} Candidate(const std::string& name, long int phone, const std::string& qualification, Enums::CandidateStatus status) - : m_id("CD" + std::to_string(++m_cid)), m_name(name), m_phone(phone), m_qualification(qualification), m_status(status) {} + : m_id("CD" + std::to_string(++m_uid)), m_name(name), m_phone(phone), m_qualification(qualification), m_status(status) {} const std::string& getCandidateId() const; const std::string& getCandidateName() const; long int getCandidatePhone() const; diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/Employee.cpp b/Trenser.Zenvy/Trenser.Zenvy/models/Employee.cpp index fb6e023..8b5aa80 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/Employee.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/models/Employee.cpp @@ -246,6 +246,17 @@ std::shared_ptr Employee::deserialize(const std::string& record) teamStatus, accountStatus ); + case Enums::EmployeeType::TALENT_ACQUISITION: + return Factory::getObject( + id, + name, + phone, + password, + email, + teamId, + teamStatus, + accountStatus + ); case Enums::EmployeeType::ADMIN: return Factory::getObject( id, diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/JobListing.cpp b/Trenser.Zenvy/Trenser.Zenvy/models/JobListing.cpp index 5c2f704..c2152cb 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/JobListing.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/models/JobListing.cpp @@ -1,6 +1,6 @@ #include "JobListing.h" -int JobListing::m_jid = 0; +int JobListing::m_uid = 0; const std::string& JobListing::getJobId() const { diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/JobListing.h b/Trenser.Zenvy/Trenser.Zenvy/models/JobListing.h index 7310897..61af21d 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/JobListing.h +++ b/Trenser.Zenvy/Trenser.Zenvy/models/JobListing.h @@ -9,7 +9,7 @@ using candidateMap = std::map>; class JobListing { private: - static int m_jid; + static int m_uid; std::string m_id; std::string m_name; std::string m_description; @@ -17,13 +17,13 @@ private: int m_numberOfVacancies; candidateMap m_candidates; public: - JobListing() : m_id("JL" + std::to_string(++m_jid)), m_name(""), m_description(""), m_status(Enums::JobListingStatus::CLOSED), m_numberOfVacancies(0) {} + JobListing() : m_id("JL" + std::to_string(++m_uid)), m_name(""), m_description(""), m_status(Enums::JobListingStatus::CLOSED), m_numberOfVacancies(0) {} JobListing(const std::string& name, const std::string& description, Enums::JobListingStatus status, int numberOfVacancies, const candidateMap& candidates) - : m_id("JL" + std::to_string(++m_jid)), m_name(name), m_description(description), m_status(status), m_numberOfVacancies(numberOfVacancies), m_candidates(candidates) {} + : m_id("JL" + std::to_string(++m_uid)), m_name(name), m_description(description), m_status(status), m_numberOfVacancies(numberOfVacancies), m_candidates(candidates) {} const std::string& getJobId() const; const std::string& getJobName() const; const std::string& getJobDescription() const; diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/Leave.cpp b/Trenser.Zenvy/Trenser.Zenvy/models/Leave.cpp index 1163bcb..bbb0ff2 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/Leave.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/models/Leave.cpp @@ -1,6 +1,6 @@ #include "Leave.h" -int Leave::m_lid = 0; +int Leave::m_uid = 0; const std::string& Leave::getLeaveId() const { diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/Leave.h b/Trenser.Zenvy/Trenser.Zenvy/models/Leave.h index b745dbf..4c50bf1 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/Leave.h +++ b/Trenser.Zenvy/Trenser.Zenvy/models/Leave.h @@ -6,7 +6,7 @@ class Leave { private: - static int m_lid; + static int m_uid; std::string m_id; std::string m_employeeId; util::Timestamp m_timestamp; @@ -16,12 +16,12 @@ private: static int m_numberOfMedicalLeave; Enums::LeaveType m_leaveType; public: - Leave() : m_id("LV" + std::to_string(++m_lid)), m_employeeId(""), m_timestamp(), m_reason(""), m_leaveType(Enums::LeaveType::GENERAL) {} + Leave() : m_id("LV" + std::to_string(++m_uid)), m_employeeId(""), m_timestamp(), m_reason(""), m_leaveType(Enums::LeaveType::GENERAL) {} Leave(const std::string& employeeId, const util::Timestamp& timestamp, const std::string& reason, Enums::LeaveType leaveType) - : m_id("LV" + std::to_string(++m_lid)), m_employeeId(employeeId), m_timestamp(timestamp), m_reason(reason), m_leaveType(leaveType) {} + : m_id("LV" + std::to_string(++m_uid)), m_employeeId(employeeId), m_timestamp(timestamp), m_reason(reason), m_leaveType(leaveType) {} const std::string& getLeaveId() const; const std::string& getEmployeeId() const; const util::Timestamp& getTimestamp() const; diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/Notification.cpp b/Trenser.Zenvy/Trenser.Zenvy/models/Notification.cpp index dae35ee..2f63026 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/Notification.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/models/Notification.cpp @@ -1,6 +1,6 @@ #include "Notification.h" -int Notification::m_nid = 0; +int Notification::m_uid = 0; const std::string& Notification::getNotificationId() const { diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/Notification.h b/Trenser.Zenvy/Trenser.Zenvy/models/Notification.h index 000f381..194183d 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/Notification.h +++ b/Trenser.Zenvy/Trenser.Zenvy/models/Notification.h @@ -6,18 +6,18 @@ class Notification { private: - static int m_nid; + static int m_uid; std::string m_id; std::string m_employeeId; std::string m_message; util::Timestamp m_timestamp; Enums::NotificationStatus m_notificationStatus; public: - Notification() : m_id("NF" + std::to_string(++m_nid)), m_employeeId(""), m_message(""), m_timestamp(), m_notificationStatus(Enums::NotificationStatus::UNREAD) {} + Notification() : m_id("NF" + std::to_string(++m_uid)), m_employeeId(""), m_message(""), m_timestamp(), m_notificationStatus(Enums::NotificationStatus::UNREAD) {} Notification(const std::string& employeeId, const std::string& message, Enums::NotificationStatus notificationStatus) - : m_id("NF" + std::to_string(++m_nid)), m_employeeId(employeeId), m_message(message), m_notificationStatus(notificationStatus) {} + : m_id("NF" + std::to_string(++m_uid)), m_employeeId(employeeId), m_message(message), m_notificationStatus(notificationStatus) {} const std::string& getNotificationId() const; const std::string& getEmployeeId() const; const std::string& getNotificationMessage() const; diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/Payroll.cpp b/Trenser.Zenvy/Trenser.Zenvy/models/Payroll.cpp index fe439d6..aacf36e 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/Payroll.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/models/Payroll.cpp @@ -1,12 +1,48 @@ +#include +#include #include "Payroll.h" +#include "StringHelper.h" +#include "Factory.h" -int Payroll::m_prid = 0; +int Payroll::m_uid = 0; -const std::string& Payroll::getPayrollId() const +Payroll::Payroll(const std::string& id, + const std::string& employeeId, + double basicSalary, + double houseRentAllowance, + double foodAllowance, + double employeePFContribution, + double employerPFContribution) + : m_id("PR" + std::to_string(++m_uid)), + m_employeeId(employeeId), + m_basicSalary(basicSalary), + m_houseRentAllowance(houseRentAllowance), + m_foodAllowance(foodAllowance), + m_employeePFContribution(employeePFContribution), + m_employerPFContribution(employerPFContribution) +{ + int idNumber = util::extractNumber(m_id); + if (idNumber > m_uid) + { + m_uid = idNumber; + } +} + +const std::string& Payroll::getId() const { return m_id; } +const std::string& Payroll::getEmployeeId() const +{ + return m_employeeId; +} + +void Payroll::setEmployeeId(const std::string& employeeId) +{ + m_employeeId = employeeId; +} + double Payroll::getBasicSalary() const { return m_basicSalary; @@ -55,4 +91,58 @@ void Payroll::setEmployeePFContribution(double value) void Payroll::setEmployerPFContribution(double value) { m_employerPFContribution = value; +} + +std::string Payroll::serialize() const +{ + std::ostringstream serializedPayroll; + serializedPayroll << m_id << ',' + << m_employeeId << ',' + << m_basicSalary << ',' + << m_houseRentAllowance << ',' + << m_foodAllowance << ',' + << m_employeePFContribution << ',' + << m_employerPFContribution; + return serializedPayroll.str(); +} + +std::shared_ptr Payroll::deserialize(const std::string& record) +{ + std::string id, employeeId; + std::string basicSalaryStr, houseRentAllowanceString, foodAllowanceString, employeePFString, employerPFString; + std::istringstream serializedPayroll(record); + std::getline(serializedPayroll, id, ','); + std::getline(serializedPayroll, employeeId, ','); + std::getline(serializedPayroll, basicSalaryStr, ','); + std::getline(serializedPayroll, houseRentAllowanceString, ','); + std::getline(serializedPayroll, foodAllowanceString, ','); + std::getline(serializedPayroll, employeePFString, ','); + std::getline(serializedPayroll, employerPFString, ','); + + try + { + double basicSalary = std::stod(basicSalaryStr); + double houseRentAllowance = std::stod(houseRentAllowanceString); + double foodAllowance = std::stod(foodAllowanceString); + double employeePFContribution = std::stod(employeePFString); + double employerPFContribution = std::stod(employerPFString); + return Factory::getObject( + id, + employeeId, + basicSalary, + houseRentAllowance, + foodAllowance, + employeePFContribution, + employerPFContribution + ); + } + catch (...) + { + throw std::runtime_error("Failed to deserialize Payroll object"); + } +} + +std::string Payroll::getHeaders() +{ + return "PayrollId,EmployeeId,BasicSalary,HouseRentAllowance,FoodAllowance,EmployeePFContribution,EmployerPFContribution"; } \ No newline at end of file diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/Payroll.h b/Trenser.Zenvy/Trenser.Zenvy/models/Payroll.h index 8aaae92..6b063c8 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/Payroll.h +++ b/Trenser.Zenvy/Trenser.Zenvy/models/Payroll.h @@ -1,25 +1,47 @@ #pragma once #include +#include class Payroll { private: - static int m_prid; + static int m_uid; std::string m_id; + std::string m_employeeId; double m_basicSalary; double m_houseRentAllowance; double m_foodAllowance; double m_employeePFContribution; double m_employerPFContribution; public: - Payroll() : m_id("PR" + std::to_string(++m_prid)), m_basicSalary(0.0), m_houseRentAllowance(0.0), m_foodAllowance(0.0), m_employeePFContribution(0.0), m_employerPFContribution(0.0) {} + Payroll() + : m_id("PR" + std::to_string(++m_uid)), + m_basicSalary(0.0), + m_houseRentAllowance(0.0), + m_foodAllowance(0.0), + m_employeePFContribution(0.0), + m_employerPFContribution(0.0) {} Payroll(double basicSalary, double houseRentAllowance, double foodAllowance, double employeePFContribution, double employerPFContribution) - : m_id("PR" + std::to_string(++m_prid)), m_basicSalary(basicSalary), m_houseRentAllowance(houseRentAllowance), m_foodAllowance(foodAllowance), m_employeePFContribution(employeePFContribution), m_employerPFContribution(employerPFContribution) {} - const std::string& getPayrollId() const; + : m_id("PR" + std::to_string(++m_uid)), + m_basicSalary(basicSalary), + m_houseRentAllowance(houseRentAllowance), + m_foodAllowance(foodAllowance), + m_employeePFContribution(employeePFContribution), + m_employerPFContribution(employerPFContribution) {} + Payroll(const std::string& id, + const std::string& employeeId, + double basicSalary, + double houseRentAllowance, + double foodAllowance, + double employeePFContribution, + double employerPFContribution); + const std::string& getId() const; + const std::string& getEmployeeId() const; + void setEmployeeId(const std::string&); double getBasicSalary() const; double getHouseRentAllowance() const; double getFoodAllowance() const; @@ -30,4 +52,7 @@ public: void setFoodAllowance(double); void setEmployeePFContribution(double); void setEmployerPFContribution(double); + virtual std::string serialize() const; + static std::shared_ptr deserialize(const std::string&); + static std::string getHeaders(); }; \ No newline at end of file diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/Payslip.cpp b/Trenser.Zenvy/Trenser.Zenvy/models/Payslip.cpp index fd40ee6..614e525 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/Payslip.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/models/Payslip.cpp @@ -1,6 +1,6 @@ #include "Payslip.h" -int Payslip::m_pid = 0; +int Payslip::m_uid = 0; const std::string& Payslip::getPayslipId() const { diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/Payslip.h b/Trenser.Zenvy/Trenser.Zenvy/models/Payslip.h index 78e37b1..10dc3bf 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/Payslip.h +++ b/Trenser.Zenvy/Trenser.Zenvy/models/Payslip.h @@ -4,12 +4,12 @@ class Payslip { private: - static int m_pid; + static int m_uid; std::string m_id; double m_salary; public: - Payslip() : m_id("PS" + std::to_string(++m_pid)), m_salary(0.0) {} - Payslip(const double salary) : m_id("PS" + std::to_string(++m_pid)), m_salary(salary) {} + Payslip() : m_id("PS" + std::to_string(++m_uid)), m_salary(0.0) {} + Payslip(const double salary) : m_id("PS" + std::to_string(++m_uid)), m_salary(salary) {} const std::string& getPayslipId() const; double getSalary() const; void setPayslipId(const std::string& id); diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/Room.cpp b/Trenser.Zenvy/Trenser.Zenvy/models/Room.cpp index 8134102..b5c4d50 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/Room.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/models/Room.cpp @@ -1,6 +1,6 @@ #include "Room.h" -int Room::m_rid = 0; +int Room::m_uid = 0; const std::string& Room::getRoomId() const { diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/Room.h b/Trenser.Zenvy/Trenser.Zenvy/models/Room.h index e0084e9..1dfe66a 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/Room.h +++ b/Trenser.Zenvy/Trenser.Zenvy/models/Room.h @@ -8,13 +8,13 @@ using bookingMap = std::map>; class Room { private: - static int m_rid; + static int m_uid; std::string m_id; std::string m_name; bookingMap m_bookings; public: - Room() : m_id("RM" + std::to_string(++m_rid)), m_name("") {} - Room(const std::string& name) : m_id("RM" + std::to_string(++m_rid)), m_name(name) {} + Room() : m_id("RM" + std::to_string(++m_uid)), m_name("") {} + Room(const std::string& name) : m_id("RM" + std::to_string(++m_uid)), m_name(name) {} const std::string& getRoomId() const; const std::string& getRoomName() const; const bookingMap& getBookings() const; diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/TalentExecutive.h b/Trenser.Zenvy/Trenser.Zenvy/models/TalentExecutive.h index 2352f7a..90bc664 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/TalentExecutive.h +++ b/Trenser.Zenvy/Trenser.Zenvy/models/TalentExecutive.h @@ -10,7 +10,25 @@ public: const std::string& phone, const std::string& email, std::shared_ptr payroll - ) :Employee(name, phone, email, Enums::EmployeeType::TAG, payroll) {}; + ) :Employee(name, phone, email, Enums::EmployeeType::TALENT_ACQUISITION, payroll) {}; + TalentExecutive(const std::string& id, + const std::string& name, + const std::string& phone, + const std::string& password, + const std::string& email, + const std::string& teamId, + Enums::TeamStatus teamStatus, + Enums::AccountStatus accountStatus) + : Employee(id, + name, + phone, + password, + email, + teamId, + teamStatus, + Enums::EmployeeType::TALENT_ACQUISITION, + accountStatus) { + } ~TalentExecutive() = default; }; diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/Team.cpp b/Trenser.Zenvy/Trenser.Zenvy/models/Team.cpp index fce9fd5..abf8a23 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/Team.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/models/Team.cpp @@ -1,6 +1,6 @@ #include "Team.h" -int Team::m_tmid = 0; +int Team::m_uid = 0; const std::string& Team::getTeamId() const { diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/Team.h b/Trenser.Zenvy/Trenser.Zenvy/models/Team.h index b4782cd..fca1698 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/Team.h +++ b/Trenser.Zenvy/Trenser.Zenvy/models/Team.h @@ -8,19 +8,19 @@ using employeeMap = std::map>; class Team { private: - static int m_tmid; + static int m_uid; std::string m_id; std::string m_name; std::shared_ptr m_lead; employeeMap m_employees; int m_maximumNumberOfEmployees; public: - Team() : m_id("TM" + std::to_string(++m_tmid)), m_name(""), m_lead(nullptr), m_maximumNumberOfEmployees(0) {} + Team() : m_id("TM" + std::to_string(++m_uid)), m_name(""), m_lead(nullptr), m_maximumNumberOfEmployees(0) {} Team( const std::string& name, std::shared_ptr lead, int maximumNumberOfEmployees) - : m_id("TM" + std::to_string(++m_tmid)), m_name(name), m_lead(lead), m_maximumNumberOfEmployees(maximumNumberOfEmployees) { + : m_id("TM" + std::to_string(++m_uid)), m_name(name), m_lead(lead), m_maximumNumberOfEmployees(maximumNumberOfEmployees) { } const std::string& getTeamId() const; const std::string& getTeamName() const; diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/Ticket.cpp b/Trenser.Zenvy/Trenser.Zenvy/models/Ticket.cpp index 431093e..84fd042 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/Ticket.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/models/Ticket.cpp @@ -1,6 +1,6 @@ #include "Ticket.h" -int Ticket::m_tid = 0; +int Ticket::m_uid = 0; const std::string& Ticket::getTicketId() const { diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/Ticket.h b/Trenser.Zenvy/Trenser.Zenvy/models/Ticket.h index 1ab88aa..56d39af 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/Ticket.h +++ b/Trenser.Zenvy/Trenser.Zenvy/models/Ticket.h @@ -5,20 +5,20 @@ class Ticket { private: - static int m_tid; + static int m_uid; std::string m_id; Enums::TicketType m_type; std::string m_description; Enums::TicketStatus m_status; std::string m_employeeId; public: - Ticket() : m_id("TKT" + std::to_string(++m_tid)), m_type(Enums::TicketType::UNKNOWN), m_description(""), m_status(Enums::TicketStatus::OPEN), m_employeeId("") {} + Ticket() : m_id("TKT" + std::to_string(++m_uid)), m_type(Enums::TicketType::UNKNOWN), m_description(""), m_status(Enums::TicketStatus::OPEN), m_employeeId("") {} Ticket( Enums::TicketType type, const std::string& description, const std::string& employeeId, Enums::TicketStatus status) - : m_id("TKT" + std::to_string(++m_tid)), m_type(type), m_description(description), m_status(status), m_employeeId(employeeId) {} + : m_id("TKT" + std::to_string(++m_uid)), m_type(type), m_description(description), m_status(status), m_employeeId(employeeId) {} const std::string& getTicketId() const; Enums::TicketType getTicketType() const; const std::string& getDescription() const; diff --git a/Trenser.Zenvy/Trenser.Zenvy/services/ApplicationConfig.h b/Trenser.Zenvy/Trenser.Zenvy/services/ApplicationConfig.h index c725431..25231c2 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/services/ApplicationConfig.h +++ b/Trenser.Zenvy/Trenser.Zenvy/services/ApplicationConfig.h @@ -9,31 +9,32 @@ namespace Config namespace Payroll { - constexpr double SENIOR_BASIC_SALARY = 0.0; - constexpr double SENIOR_HOUSE_RENT_ALLOWANCE = 0.0; - constexpr double SENIOR_FOOD_ALLOWANCE = 0.0; - constexpr double SENIOR_EMPLOYEE_PF_CONTRIBUTION = 0.0; - constexpr double SENIOR_EMPLOYER_PF_CONTRIBUTION = 0.0; - constexpr double JUNIOR_BASIC_SALARY = 0.0; - constexpr double JUNIOR_HOUSE_RENT_ALLOWANCE = 0.0; - constexpr double JUNIOR_FOOD_ALLOWANCE = 0.0; - constexpr double JUNIOR_EMPLOYEE_PF_CONTRIBUTION = 0.0; - constexpr double JUNIOR_EMPLOYER_PF_CONTRIBUTION = 0.0; - constexpr double HR_MANAGER_BASIC_SALARY = 0.0; - constexpr double HR_MANAGER_HOUSE_RENT_ALLOWANCE = 0.0; - constexpr double HR_MANAGER_FOOD_ALLOWANCE = 0.0; - constexpr double HR_MANAGER_EMPLOYEE_PF_CONTRIBUTION = 0.0; - constexpr double HR_MANAGER_EMPLOYER_PF_CONTRIBUTION = 0.0; - constexpr double EXECUTIVE_BASIC_SALARY = 0.0; - constexpr double EXECUTIVE_HOUSE_RENT_ALLOWANCE = 0.0; - constexpr double EXECUTIVE_FOOD_ALLOWANCE = 0.0; - constexpr double EXECUTIVE_EMPLOYEE_PF_CONTRIBUTION = 0.0; - constexpr double EXECUTIVE_EMPLOYER_PF_CONTRIBUTION = 0.0; + constexpr double SENIOR_BASIC_SALARY = 80000.0; + constexpr double SENIOR_HOUSE_RENT_ALLOWANCE = 32000.0; + constexpr double SENIOR_FOOD_ALLOWANCE = 3000.0; + constexpr double SENIOR_EMPLOYEE_PF_CONTRIBUTION = 9600.0; + constexpr double SENIOR_EMPLOYER_PF_CONTRIBUTION = 9600.0; + constexpr double JUNIOR_BASIC_SALARY = 25000.0; + constexpr double JUNIOR_HOUSE_RENT_ALLOWANCE = 10000.0; + constexpr double JUNIOR_FOOD_ALLOWANCE = 1500.0; + constexpr double JUNIOR_EMPLOYEE_PF_CONTRIBUTION = 3000.0; + constexpr double JUNIOR_EMPLOYER_PF_CONTRIBUTION = 3000.0; + constexpr double HR_MANAGER_BASIC_SALARY = 60000.0; + constexpr double HR_MANAGER_HOUSE_RENT_ALLOWANCE = 24000.0; + constexpr double HR_MANAGER_FOOD_ALLOWANCE = 2500.0; + constexpr double HR_MANAGER_EMPLOYEE_PF_CONTRIBUTION = 7200.0; + constexpr double HR_MANAGER_EMPLOYER_PF_CONTRIBUTION = 7200.0; + constexpr double EXECUTIVE_BASIC_SALARY = 45000.0; + constexpr double EXECUTIVE_HOUSE_RENT_ALLOWANCE = 18000.0; + constexpr double EXECUTIVE_FOOD_ALLOWANCE = 2000.0; + constexpr double EXECUTIVE_EMPLOYEE_PF_CONTRIBUTION = 5400.0; + constexpr double EXECUTIVE_EMPLOYER_PF_CONTRIBUTION = 5400.0; } namespace File { constexpr const char* EMPLOYEES_FILE = "files/Employee.csv"; constexpr const char* GENERAL_EMPLOYEES_FILE = "files/GeneralEmployee.csv"; + constexpr const char* PAYROLL_FILE = "files/Payroll.csv"; } } diff --git a/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.cpp b/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.cpp index 4fe4ddc..ae453c7 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/services/EmployeeManagementService.cpp @@ -59,7 +59,7 @@ void EmployeeManagementService::createEmployee(Enums::EmployeeType employeeType, case Enums::EmployeeType::IT: case Enums::EmployeeType::FINANCE: case Enums::EmployeeType::TEAM: - case Enums::EmployeeType::TAG: + case Enums::EmployeeType::TALENT_ACQUISITION: util::enforceAuthorization(authenticatedEmployeeType, Enums::EmployeeType::ADMIN, Enums::EmployeeType::HR); payroll = Factory::getObject(Config::Payroll::EXECUTIVE_BASIC_SALARY, Config::Payroll::EXECUTIVE_HOUSE_RENT_ALLOWANCE, @@ -77,7 +77,7 @@ void EmployeeManagementService::createEmployee(Enums::EmployeeType employeeType, case Enums::EmployeeType::TEAM: employee = Factory::getObject(name, phone, email, payroll); break; - case Enums::EmployeeType::TAG: + case Enums::EmployeeType::TALENT_ACQUISITION: employee = Factory::getObject (name, phone, email, payroll); break; } @@ -108,6 +108,8 @@ void EmployeeManagementService::createEmployee(Enums::EmployeeType employeeType, default: throw std::runtime_error("Invalid Employee Type"); } + payroll->setEmployeeId(employee->getId()); + m_dataStore.getPayrolls().emplace(std::make_pair(payroll->getId(), payroll)); m_dataStore.getEmployees().emplace(std::make_pair(employee->getId(), employee)); } diff --git a/Trenser.Zenvy/Trenser.Zenvy/services/PayslipManagementService.cpp b/Trenser.Zenvy/Trenser.Zenvy/services/PayslipManagementService.cpp index 6e4bc99..dd6bc1c 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/services/PayslipManagementService.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/services/PayslipManagementService.cpp @@ -1,6 +1,9 @@ +#include #include "PayslipManagementService.h" +#include "ApplicationConfig.h" #include "AuthorizationHelper.h" #include "Enums.h" +#include "FileManager.h" void PayslipManagementService::updateSalary(const std::string& employeeId, double basicSalary, double houseRentAllowance, double foodAllowance, double employeePFContribution, double employerPFContribution) { @@ -18,4 +21,29 @@ void PayslipManagementService::updateSalary(const std::string& employeeId, doubl { throw std::runtime_error("Employee not found, unable to update the salary"); } +} + +void PayslipManagementService::loadPayrolls() +{ + FileManager payrollFileManager(Config::File::PAYROLL_FILE); + auto& payrolls = m_dataStore.getPayrolls(); + auto& employees = m_dataStore.getEmployees(); + auto payrollObjects = payrollFileManager.load(); + for (const auto& payrollPair : payrollObjects) + { + auto employeeIterator = employees.find(payrollPair.second->getEmployeeId()); + if (employeeIterator == employees.end()) + { + throw std::runtime_error("Payroll Object not associated with an existing employee"); + } + employeeIterator->second->setEmployeePayroll(payrollPair.second); + } + payrolls.insert(payrollObjects.begin(), payrollObjects.end()); +} + +void PayslipManagementService::savePayrolls() +{ + FileManager payrollFileManager(Config::File::PAYROLL_FILE); + auto& payrolls = m_dataStore.getPayrolls(); + payrollFileManager.save(payrolls); } \ No newline at end of file diff --git a/Trenser.Zenvy/Trenser.Zenvy/services/PayslipManagementService.h b/Trenser.Zenvy/Trenser.Zenvy/services/PayslipManagementService.h index 768c2a3..fd91da1 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/services/PayslipManagementService.h +++ b/Trenser.Zenvy/Trenser.Zenvy/services/PayslipManagementService.h @@ -10,4 +10,6 @@ private: public: PayslipManagementService() : m_dataStore(DataStore::getInstance()) {}; void updateSalary(const std::string&, double, double, double, double, double); + void loadPayrolls(); + void savePayrolls(); }; diff --git a/Trenser.Zenvy/Trenser.Zenvy/utilities/Enums.h b/Trenser.Zenvy/Trenser.Zenvy/utilities/Enums.h index 5154ddd..2021b68 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/utilities/Enums.h +++ b/Trenser.Zenvy/Trenser.Zenvy/utilities/Enums.h @@ -76,7 +76,7 @@ namespace Enums { GENERAL, IT, FINANCE, - TAG, + TALENT_ACQUISITION, HR, TEAM, ADMIN, @@ -114,8 +114,8 @@ namespace Enums { return "IT"; case EmployeeType::FINANCE: return "FINANCE"; - case EmployeeType::TAG: - return "TAG"; + case EmployeeType::TALENT_ACQUISITION: + return "TALENT_ACQUISITION"; case EmployeeType::HR: return "HR"; case EmployeeType::TEAM: @@ -176,8 +176,8 @@ namespace Enums { return EmployeeType::IT; if (input == "FINANCE") return EmployeeType::FINANCE; - if (input == "TAG") - return EmployeeType::TAG; + if (input == "TALENT_ACQUISITION") + return EmployeeType::TALENT_ACQUISITION; if (input == "HR") return EmployeeType::HR; if (input == "TEAM") diff --git a/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.cpp b/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.cpp index 6ec6f00..d183fdf 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.cpp @@ -11,14 +11,14 @@ static Enums::EmployeeType getEmployeeType(Enums::EmployeeType employeeType) Enums::EmployeeType::IT, Enums::EmployeeType::TEAM, Enums::EmployeeType::FINANCE, - Enums::EmployeeType::TAG, + Enums::EmployeeType::TALENT_ACQUISITION, Enums::EmployeeType::GENERAL }}, { Enums::EmployeeType::HR, { Enums::EmployeeType::IT, Enums::EmployeeType::TEAM, Enums::EmployeeType::FINANCE, - Enums::EmployeeType::TAG, + Enums::EmployeeType::TALENT_ACQUISITION, Enums::EmployeeType::GENERAL }} }; @@ -27,7 +27,7 @@ static Enums::EmployeeType getEmployeeType(Enums::EmployeeType employeeType) { Enums::EmployeeType::IT, "IT Executive" }, { Enums::EmployeeType::TEAM, "Team Executive" }, { Enums::EmployeeType::FINANCE, "Finance Executive" }, - { Enums::EmployeeType::TAG, "Talent Executive" }, + { Enums::EmployeeType::TALENT_ACQUISITION, "Talent Executive" }, { Enums::EmployeeType::GENERAL, "General Employee" } }; auto it = employeeTypeOptions.find(employeeType); diff --git a/Trenser.Zenvy/Trenser.Zenvy/views/UserInterface.cpp b/Trenser.Zenvy/Trenser.Zenvy/views/UserInterface.cpp index ae98311..f420867 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/views/UserInterface.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/views/UserInterface.cpp @@ -151,7 +151,7 @@ void UserInterface::login() menu.run(); break; } - case Enums::EmployeeType::TAG: + case Enums::EmployeeType::TALENT_ACQUISITION: { TalentExecutiveMenu menu; menu.run(); From 66c80fd055cfd665d93a42f047522adf7768e85d Mon Sep 17 00:00:00 2001 From: Joel Thomas Date: Sat, 11 Apr 2026 12:58:09 +0530 Subject: [PATCH 8/9] Fixed payroll ID handling and improved payroll update flow SRS02 : Employee Management - Fixed Payroll constructor to use given ID during deserialization - Cleaned up salary update logic in PayslipManagementService - Improved employee selection display in Finance menu - Added employee type column in selection list - Fixed typo in Employee menu (Ticket) - Added confirmation message after payroll update Smitha Mohan --- Trenser.Zenvy/Trenser.Zenvy/models/Payroll.cpp | 2 +- .../services/PayslipManagementService.cpp | 11 ++++++----- .../Trenser.Zenvy/views/EmployeeMenu.cpp | 2 +- .../views/FinanceExecutiveMenu.cpp | 17 ++++++++++++----- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/Trenser.Zenvy/Trenser.Zenvy/models/Payroll.cpp b/Trenser.Zenvy/Trenser.Zenvy/models/Payroll.cpp index aacf36e..3291519 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/models/Payroll.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/models/Payroll.cpp @@ -13,7 +13,7 @@ Payroll::Payroll(const std::string& id, double foodAllowance, double employeePFContribution, double employerPFContribution) - : m_id("PR" + std::to_string(++m_uid)), + : m_id(id), m_employeeId(employeeId), m_basicSalary(basicSalary), m_houseRentAllowance(houseRentAllowance), diff --git a/Trenser.Zenvy/Trenser.Zenvy/services/PayslipManagementService.cpp b/Trenser.Zenvy/Trenser.Zenvy/services/PayslipManagementService.cpp index dd6bc1c..ecc326d 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/services/PayslipManagementService.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/services/PayslipManagementService.cpp @@ -11,11 +11,12 @@ void PayslipManagementService::updateSalary(const std::string& employeeId, doubl auto employee = m_dataStore.getEmployees().find(employeeId); if (employee != m_dataStore.getEmployees().end() && employee->second->getEmployeeType() != Enums::EmployeeType::ADMIN) { - (employee->second)->getPayroll()->setBasicSalary(basicSalary); - (employee->second)->getPayroll()->setHouseRentAllowance(houseRentAllowance); - (employee->second)->getPayroll()->setFoodAllowance(foodAllowance); - (employee->second)->getPayroll()->setEmployeePFContribution(employeePFContribution); - (employee->second)->getPayroll()->setEmployerPFContribution(employerPFContribution); + auto payroll = employee->second->getPayroll(); + payroll->setBasicSalary(basicSalary); + payroll->setHouseRentAllowance(houseRentAllowance); + payroll->setFoodAllowance(foodAllowance); + payroll->setEmployeePFContribution(employeePFContribution); + payroll->setEmployerPFContribution(employerPFContribution); } else { diff --git a/Trenser.Zenvy/Trenser.Zenvy/views/EmployeeMenu.cpp b/Trenser.Zenvy/Trenser.Zenvy/views/EmployeeMenu.cpp index e54b282..7673756 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/views/EmployeeMenu.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/views/EmployeeMenu.cpp @@ -13,7 +13,7 @@ void EmployeeMenu::run() { int choice; util::clear(); - std::cout << "Employee Menu\n1. Apply Leave\n2. View Payslip\n3. View Payslip History\n4. Raise Ticke\n5. View Ticket\n6. View Ticket History\n7. View Employees\n8. Search Employee\n9. View Team Members\n10. Book Meeting Room\n11. View Booking History\n12. View Notification\n13. View Announcements\n14. Update Profile\n15. Logout\nEnter your Choice: "; + std::cout << "Employee Menu\n1. Apply Leave\n2. View Payslip\n3. View Payslip History\n4. Raise Ticket\n5. View Ticket\n6. View Ticket History\n7. View Employees\n8. Search Employee\n9. View Team Members\n10. Book Meeting Room\n11. View Booking History\n12. View Notification\n13. View Announcements\n14. Update Profile\n15. Logout\nEnter your Choice: "; util::read(choice); if (!handleOperation(choice)) { diff --git a/Trenser.Zenvy/Trenser.Zenvy/views/FinanceExecutiveMenu.cpp b/Trenser.Zenvy/Trenser.Zenvy/views/FinanceExecutiveMenu.cpp index 28c7f74..428fce9 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/views/FinanceExecutiveMenu.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/views/FinanceExecutiveMenu.cpp @@ -34,6 +34,8 @@ std::string FinanceExecutiveMenu::getSelectedUserId() std::map> employeeList; int index = 0; auto allEmployees = m_zenvyController->getEmployees(); + util::clear(); + std::cout << "Select the Employee\n"; for (auto& currentEmployee : allEmployees) { if (currentEmployee->getEmployeeType() == Enums::EmployeeType::ADMIN) @@ -43,14 +45,16 @@ std::string FinanceExecutiveMenu::getSelectedUserId() employeeList[++index] = currentEmployee; } std::cout << std::left - << std::setw(6) << "Index" - << std::setw(15) << "Employee Id" - << std::setw(25) << "Name" << std::endl; + << std::setw(10) << "Index" + << std::setw(15) << "Employee ID" + << std::setw(20) << "Name" + << std::setw(20) << "Employee Type" << std::endl; for (const auto& employee : employeeList) { - std::cout << std::left << std::setw(6) << employee.first + std::cout << std::left << std::setw(10) << employee.first << std::setw(15) << employee.second->getId() - << std::setw(25) << employee.second->getEmployeeName() + << std::setw(20) << employee.second->getEmployeeName() + << std::setw(20) << Enums::getEmployeeTypeString(employee.second->getEmployeeType()) << std::endl; } std::cout << "Enter the Index: "; @@ -71,6 +75,7 @@ void FinanceExecutiveMenu::updatePayroll() std::string employeeId; double basicSalary, houseRentAllowance, foodAllowance, employeePFContribution, employerPFContribution; employeeId = getSelectedUserId(); + util::clear(); if (employeeId != "") { std::cout << "Enter the New Basic Salary: "; util::read(basicSalary); @@ -83,6 +88,8 @@ void FinanceExecutiveMenu::updatePayroll() std::cout << "Enter the New EmplyerPFContribution: "; util::read(employerPFContribution); m_zenvyController->updateSalary(employeeId, basicSalary, houseRentAllowance, foodAllowance, employeePFContribution, employerPFContribution); + std::cout << "Payroll Updated"; + util::pressEnter(); } else { throw std::runtime_error("Unexpected error occured"); From aa21853a653315d69bde5fcca6ba62a05651e134 Mon Sep 17 00:00:00 2001 From: Joel Thomas Date: Sat, 11 Apr 2026 14:59:41 +0530 Subject: [PATCH 9/9] Refactored employee selection and cleaned up menu logic SRS02 : Employee Management - Removed getSelectedUserId() from FinanceExecutiveMenu - Added reusable selectEmployeeId() in MenuHelper - Simplified deactivateEmployee() using common selection logic - Fixed missing break in HRManagerMenu Smitha Mohan --- .../views/FinanceExecutiveMenu.cpp | 44 +---------- .../views/FinanceExecutiveMenu.h | 1 - .../Trenser.Zenvy/views/HRManagerMenu.cpp | 1 + .../Trenser.Zenvy/views/MenuHelper.cpp | 1 + .../Trenser.Zenvy/views/MenuHelper.h | 73 +++++++++---------- 5 files changed, 38 insertions(+), 82 deletions(-) diff --git a/Trenser.Zenvy/Trenser.Zenvy/views/FinanceExecutiveMenu.cpp b/Trenser.Zenvy/Trenser.Zenvy/views/FinanceExecutiveMenu.cpp index 428fce9..9563f5e 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/views/FinanceExecutiveMenu.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/views/FinanceExecutiveMenu.cpp @@ -28,53 +28,11 @@ void FinanceExecutiveMenu::run() } } -std::string FinanceExecutiveMenu::getSelectedUserId() -{ - int choice; - std::map> employeeList; - int index = 0; - auto allEmployees = m_zenvyController->getEmployees(); - util::clear(); - std::cout << "Select the Employee\n"; - for (auto& currentEmployee : allEmployees) - { - if (currentEmployee->getEmployeeType() == Enums::EmployeeType::ADMIN) - { - continue; - } - employeeList[++index] = currentEmployee; - } - std::cout << std::left - << std::setw(10) << "Index" - << std::setw(15) << "Employee ID" - << std::setw(20) << "Name" - << std::setw(20) << "Employee Type" << std::endl; - for (const auto& employee : employeeList) - { - std::cout << std::left << std::setw(10) << employee.first - << std::setw(15) << employee.second->getId() - << std::setw(20) << employee.second->getEmployeeName() - << std::setw(20) << Enums::getEmployeeTypeString(employee.second->getEmployeeType()) - << std::endl; - } - std::cout << "Enter the Index: "; - util::read(choice); - auto employeeIterator = employeeList.find(choice); - if (employeeIterator != employeeList.end()) - { - return (employeeIterator->second->getId()); - } - else - { - throw std::runtime_error("Invalid Index"); - } -} - void FinanceExecutiveMenu::updatePayroll() { std::string employeeId; double basicSalary, houseRentAllowance, foodAllowance, employeePFContribution, employerPFContribution; - employeeId = getSelectedUserId(); + employeeId = selectEmployeeId(m_zenvyController->getEmployees()); util::clear(); if (employeeId != "") { std::cout << "Enter the New Basic Salary: "; diff --git a/Trenser.Zenvy/Trenser.Zenvy/views/FinanceExecutiveMenu.h b/Trenser.Zenvy/Trenser.Zenvy/views/FinanceExecutiveMenu.h index 1b3ad71..a5a2016 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/views/FinanceExecutiveMenu.h +++ b/Trenser.Zenvy/Trenser.Zenvy/views/FinanceExecutiveMenu.h @@ -13,7 +13,6 @@ public: FinanceExecutiveMenu() : m_zenvyController(std::make_shared()) {}; void run(); bool handleOperation(int); - std::string getSelectedUserId(); void updatePayroll(); }; diff --git a/Trenser.Zenvy/Trenser.Zenvy/views/HRManagerMenu.cpp b/Trenser.Zenvy/Trenser.Zenvy/views/HRManagerMenu.cpp index 654997c..541527e 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/views/HRManagerMenu.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/views/HRManagerMenu.cpp @@ -70,6 +70,7 @@ bool HRManagerMenu::handleOperation(int choice) break; case 13: deactivateEmployee(m_zenvyController); + break; case 14: return false; default: diff --git a/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.cpp b/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.cpp index d183fdf..37da2d2 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.cpp +++ b/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.cpp @@ -100,4 +100,5 @@ void createEmployee(std::shared_ptr controller) util::read(phone); controller->createEmployee(employeeType, employeeDesignation, email, name, phone); std::cout << "\nCreated Employee Successfully."; + util::pressEnter(); } diff --git a/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.h b/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.h index aef9716..a4c2fff 100644 --- a/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.h +++ b/Trenser.Zenvy/Trenser.Zenvy/views/MenuHelper.h @@ -65,60 +65,57 @@ inline void updateProfile(std::shared_ptr m_zenvyController) } } -inline std::map> listEmployees(const std::shared_ptr& controller) +inline std::string selectEmployeeId(std::vector> allEmployees) { - auto employees = controller->getEmployees(); + int choice; std::map> employeeList; + int index = 0; + util::clear(); + std::cout << "Select the Employee\n"; + for (auto& currentEmployee : allEmployees) + { + if (currentEmployee->getEmployeeType() == Enums::EmployeeType::ADMIN) + { + continue; + } + employeeList[++index] = currentEmployee; + } std::cout << std::left - << std::setw(5) << "Index" - << std::setw(15) << "ID" - << std::setw(25) << "Name" - << "\n"; - int index = 1; - for (auto& activeEmployees : employees) + << std::setw(10) << "Index" + << std::setw(15) << "Employee ID" + << std::setw(20) << "Name" + << std::setw(20) << "Employee Type" << std::endl; + for (const auto& employee : employeeList) { - std::cout << std::left - << std::setw(5) << index - << std::setw(15) << activeEmployees->getId() - << std::setw(25) << activeEmployees->getEmployeeName() - << "\n"; - employeeList[index] = activeEmployees; - ++index; + std::cout << std::left << std::setw(10) << employee.first + << std::setw(15) << employee.second->getId() + << std::setw(20) << employee.second->getEmployeeName() + << std::setw(20) << Enums::getEmployeeTypeString(employee.second->getEmployeeType()) + << std::endl; } - if (employeeList.empty()) + std::cout << "Enter the Index: "; + util::read(choice); + auto employeeIterator = employeeList.find(choice); + if (employeeIterator != employeeList.end()) { - std::cout << "No active employees available.\n"; + return (employeeIterator->second->getId()); + } + else + { + throw std::runtime_error("Invalid Index"); } - return employeeList; } inline void deactivateEmployee(const std::shared_ptr& controller) { - auto employeeList = listEmployees(controller); - if (employeeList.empty()) - { - return; - } - int choice; - util::clear(); - std::cout << "\nEnter the index of the employee to deactivate: "; - util::read(choice); - auto iterator = employeeList.find(choice); - if (iterator != employeeList.end()) - { - std::string id = iterator->second->getId(); - bool success = controller->deactivateEmployee(id); - if (success) + if(controller->deactivateEmployee(selectEmployeeId(controller->getEmployees()))) { std::cout << "Employee deactivated successfully\n"; + util::pressEnter(); } else { std::cout << "Employee not found\n"; + util::pressEnter(); } - } - else - { - std::cout << "Invalid index.\n"; - } }