Added CSV header support and persistence for employees

<SRS> SRS02 : Employee Management </SRS>

<Changes>
 - 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
</Changes>

<Review>
Smitha Mohan
</Review>
This commit is contained in:
2026-04-10 19:41:08 +05:30
parent eac6fa72df
commit c50700e70c
11 changed files with 64 additions and 3 deletions
@@ -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';
}
}
@@ -1,4 +1,5 @@
#pragma once
#include <stdexcept>
#include "FileIO.h"
template <typename T> using objects = std::map<std::string, std::shared_ptr<T>>;
@@ -20,9 +21,19 @@ objects<T> FileManager<T>::load()
{
objects<T> 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 <typename T>
void FileManager<T>::save(const objects<T>& records)
{
std::vector<std::string> lines;
lines.push_back(T::getHeaders());
for (const auto& recordPair : records)
{
lines.push_back(recordPair.second->serialize());
@@ -51,3 +51,8 @@ void ZenvyController::loadStates()
{
m_employeeManagementService->loadEmployees();
}
void ZenvyController::persistStates()
{
m_employeeManagementService->saveEmployees();
}
@@ -56,4 +56,5 @@ public:
//File Management
void loadStates();
void persistStates();
};
@@ -263,3 +263,8 @@ std::shared_ptr<Employee> Employee::deserialize(const std::string& record)
return nullptr;
}
}
std::string Employee::getHeaders()
{
return "EmployeeId,Email,Name,Phone,Password,TeamID,TeamStatus,AccountStatus,EmployeeType";
}
@@ -90,5 +90,6 @@ public:
Enums::EmployeeType getEmployeeType() const;
virtual std::string serialize() const;
static std::shared_ptr<Employee> deserialize(const std::string&);
static std::string getHeaders();
virtual ~Employee() = default;
};
@@ -58,4 +58,9 @@ std::shared_ptr<GeneralEmployee> GeneralEmployee::deserialize(const std::string&
employeeDesignation,
accountStatus
);
}
std::string GeneralEmployee::getHeaders()
{
return "EmployeeId,Email,Name,Phone,Password,TeamID,TeamStatus,AccountStatus,EmployeeType,EmployeeDesignation";
}
@@ -43,5 +43,6 @@ public:
void setDesignation(Enums::EmployeeDesignation designation);
std::string serialize() const override;
static std::shared_ptr<GeneralEmployee> deserialize(const std::string&);
static std::string getHeaders();
~GeneralEmployee() = default;
};
@@ -1,3 +1,4 @@
#include <map>
#include <stdexcept>
#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<Employee> employeeFileManager(Config::File::EMPLOYEES_FILE);
FileManager<GeneralEmployee> generalEmployeeFileManager(Config::File::GENERAL_EMPLOYEES_FILE);
const auto& allEmployees = m_dataStore.getEmployees();
employeeMap employees;
std::map<std::string, std::shared_ptr<GeneralEmployee>> generalEmployees;
for (auto& employeePair : allEmployees)
{
if (employeePair.second->getEmployeeType() == Enums::EmployeeType::GENERAL)
{
generalEmployees.emplace(employeePair.first, std::static_pointer_cast<GeneralEmployee>(employeePair.second));
}
else
{
employees.emplace(employeePair);
}
}
employeeFileManager.save(employees);
generalEmployeeFileManager.save(generalEmployees);
}
@@ -18,4 +18,5 @@ public:
void updateProfile(const std::string&,const std::string&);
std::shared_ptr<const Employee> getCurrentEmployee();
void loadEmployees();
void saveEmployees();
};
@@ -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)