Add View Payslip feature for employees

<UserStory> EMP010 : View Payslip </UserStory>

<Changes>
- Added Timestamp support to Payroll and Payslip models
- Implemented getPayslipForMonth flow from Controller to Service
- Enabled payslip retrieval based on year and month
- Updated menus to allow payslip viewing
- Enhanced MenuHelper with a unified viewPayslip helper
- Added date-based filtering using Timestamp utilities
</Changes>

<Review>
Smitha Mohan
</Review>
This commit is contained in:
Princy Jerin
2026-04-14 18:11:29 +05:30
committed by Joel Thomas
parent 5318b9eed6
commit b9b83ad429
15 changed files with 118 additions and 9 deletions
@@ -76,3 +76,11 @@ void ZenvyController::persistStates()
m_payslipManagementService->savePayrolls();
m_payslipManagementService->savePayslips();
}
std::pair<std::shared_ptr<Payroll>, std::shared_ptr<Payslip>>
ZenvyController::getPayslipForMonth(const std::string& employeeId, int year, int month)
{
return m_payslipManagementService->getPayslipForMonth(employeeId, month, year);
}
@@ -62,6 +62,8 @@ public:
//Payslip management
void updateSalary(const std::string&, double, double, double, double, double);
void generatePayslips();
std::pair<std::shared_ptr<Payroll>, std::shared_ptr<Payslip>>
getPayslipForMonth(const std::string&, int, int);
//File Management
void loadStates();
@@ -19,7 +19,7 @@ Payroll::Payroll(const std::string& id,
m_houseRentAllowance(houseRentAllowance),
m_foodAllowance(foodAllowance),
m_employeePFContribution(employeePFContribution),
m_employerPFContribution(employerPFContribution)
m_employerPFContribution(employerPFContribution)
{
int idNumber = util::extractNumber(m_id);
if (idNumber > m_uid)
@@ -118,7 +118,6 @@ std::shared_ptr<Payroll> Payroll::deserialize(const std::string& record)
std::getline(serializedPayroll, foodAllowanceString, ',');
std::getline(serializedPayroll, employeePFString, ',');
std::getline(serializedPayroll, employerPFString, ',');
try
{
double basicSalary = std::stod(basicSalaryString);
@@ -145,4 +144,4 @@ std::shared_ptr<Payroll> Payroll::deserialize(const std::string& record)
std::string Payroll::getHeaders()
{
return "PayrollId,EmployeeId,BasicSalary,HouseRentAllowance,FoodAllowance,EmployeePFContribution,EmployerPFContribution";
}
}
@@ -1,6 +1,7 @@
#pragma once
#include <string>
#include <memory>
#include "Timestamp.h"
class Payroll
{
@@ -13,6 +14,7 @@ private:
double m_foodAllowance;
double m_employeePFContribution;
double m_employerPFContribution;
util::Timestamp m_timestamp;
public:
Payroll()
: m_id("PR" + std::to_string(++m_uid)),
@@ -87,6 +87,30 @@ void PayslipManagementService::savePayrolls()
payrollFileManager.save(payrolls);
}
std::pair<std::shared_ptr<Payroll>, std::shared_ptr<Payslip>>
PayslipManagementService::getPayslipForMonth(const std::string& employeeId, int year, int month)
{
auto& payrolls = m_dataStore.getPayrolls();
auto& payslips = m_dataStore.getPayslips();
for (const auto& payrollsPair : payrolls)
{
const auto& payroll = payrollsPair.second;
if (payroll->getEmployeeId() == employeeId)
{
auto iterator = payslips.find(payroll->getId());
if (iterator != payslips.end())
{
const auto& payslip = iterator->second;
if (payslip->getTimestamp().getYear() == year && payslip->getTimestamp().getMonth() == month)
{
return { payroll, payslip };
}
}
}
}
return { nullptr, nullptr };
}
void PayslipManagementService::loadPayslips()
{
FileManager<Payslip> payslipFileManager(Config::File::PAYSLIP_FILE);
@@ -15,4 +15,6 @@ public:
void savePayrolls();
void loadPayslips();
void savePayslips();
std::pair<std::shared_ptr<Payroll>, std::shared_ptr<Payslip>>
getPayslipForMonth(const std::string&, int, int);
};
@@ -40,6 +40,21 @@ double util::Timestamp::getDurationInSeconds(const Timestamp& startTimestamp, co
return std::difftime(endTimestamp.m_time, startTimestamp.m_time);
}
int util::Timestamp::getYear() const
{
return 0;
}
int util::Timestamp::getMonth() const
{
return 0;
}
int util::Timestamp::getDay() const
{
return 0;
}
int util::Timestamp::getDateAsInt() const
{
std::tm timeStruct{};
@@ -16,6 +16,9 @@ namespace util
static double getDurationInHours(const Timestamp&, const Timestamp&);
static double getDurationInMinutes(const Timestamp&, const Timestamp&);
static double getDurationInSeconds(const Timestamp&, const Timestamp&);
int getYear() const;
int getMonth() const;
int getDay() const;
int getDateAsInt() const;
int getMonth() const;
int getYear() const;
@@ -33,14 +33,14 @@ bool EmployeeMenu::handleOperation(int choice)
{
switch (choice)
{
/*
case 1:
/*case 1:
m_zenvyController.applyLeave();
break;
break;*/
case 2:
m_zenvyController.viewPayslip();
viewPayslip(m_zenvyController);
break;
case 3:
/*case 3:
m_zenvyController.viewPayslipHistory();
break;
case 4 :
@@ -32,6 +32,9 @@ bool HRManagerMenu::handleOperation(int choice)
{
switch (choice)
{
case 2:
viewPayslip(m_zenvyController);
break;
case 4:
viewEmployees(m_zenvyController);
break;
@@ -32,6 +32,9 @@ bool ITExecutiveMenu::handleOperation(int choice)
{
switch (choice)
{
case 2:
viewPayslip(m_zenvyController);
break;
case 4:
viewEmployees(m_zenvyController);
break;
+40 -1
View File
@@ -296,4 +296,43 @@ inline void searchEmployee(std::shared_ptr<ZenvyController> m_zenvyController)
std::cout << "No Employee found with this name" << std::endl;
}
util::pressEnter();
}
}
inline void viewPayslip(std::shared_ptr<ZenvyController> controller)
{
int year, month;
util::clear();
std::cout << "Enter the year: ";
util::read(year);
std::cout << "\nEnter the month: ";
util::read(month);
auto employee = controller->getCurrentEmployee();
if (!employee)
{
std::cout << "No authenticated employee.\n";
util::pressEnter();
return;
}
auto result = controller->getPayslipForMonth(employee->getId(), year, month);
auto payroll = result.first;
auto payslip = result.second;
if (payroll && payslip)
{
std::cout << "\nPayslip for " << employee->getEmployeeName()
<< " (" << year << "-" << std::setw(2) << std::setfill('0') << month << ")\n\n";
std::cout << "Basic Salary : " << payroll->getBasicSalary() << "\n";
std::cout << "House Rent Allowance : " << payroll->getHouseRentAllowance() << "\n";
std::cout << "Food Allowance : " << payroll->getFoodAllowance() << "\n";
std::cout << "Employee PF Contribution : " << payroll->getEmployeePFContribution() << "\n";
std::cout << "Employer PF Contribution : " << payroll->getEmployerPFContribution() << "\n";
std::cout << "----------------------------------------\n";
std::cout << "Net Salary (after deductions): " << payslip->getSalary() << "\n";
std::cout << "Generated on: " << payslip->getTimestamp().toString() << "\n";
}
else
{
std::cout << "Payslip not available for " << year << "-" << month << ".\n";
}
util::pressEnter();
}
@@ -32,6 +32,9 @@ bool TalentExecutiveMenu::handleOperation(int choice)
{
switch (choice)
{
case 2:
viewPayslip(m_zenvyController);
break;
case 4:
viewEmployees(m_zenvyController);
break;
@@ -32,6 +32,9 @@ bool TeamExecutiveMenu::handleOperation(int choice)
{
switch (choice)
{
case 2:
viewPayslip(m_zenvyController);
break;
case 4:
viewEmployees(m_zenvyController);
break;
@@ -32,6 +32,9 @@ bool TeamLeadMenu::handleOperation(int choice)
{
switch (choice)
{
case 2:
viewPayslip(m_zenvyController);
break;
case 7:
viewEmployees(m_zenvyController);
break;