Merge branch 'feature-admin-management-adm002' into feature-admin-management

This commit is contained in:
Avinash Rajesh
2026-05-21 18:55:23 +05:30
13 changed files with 268 additions and 20 deletions
@@ -176,6 +176,7 @@
<ClInclude Include="utilities\Map.h" /> <ClInclude Include="utilities\Map.h" />
<ClInclude Include="utilities\OutputHelper.h" /> <ClInclude Include="utilities\OutputHelper.h" />
<ClInclude Include="utilities\Timestamp.h" /> <ClInclude Include="utilities\Timestamp.h" />
<ClInclude Include="utilities\Utility.h" />
<ClInclude Include="utilities\Validator.h" /> <ClInclude Include="utilities\Validator.h" />
<ClInclude Include="utilities\Vector.h" /> <ClInclude Include="utilities\Vector.h" />
<ClInclude Include="views\AdminMenu.h" /> <ClInclude Include="views\AdminMenu.h" />
@@ -233,5 +233,8 @@
<ClInclude Include="models\ComboPackage.h"> <ClInclude Include="models\ComboPackage.h">
<Filter>Header Files\Models</Filter> <Filter>Header Files\Models</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="utilities\Utility.h">
<Filter>Header Files\Utilities</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>
@@ -1,4 +1,5 @@
#include "Controller.h" #include "Controller.h"
#include "User.h"
bool Controller::login(const std::string& username, const std::string& password) bool Controller::login(const std::string& username, const std::string& password)
{ {
@@ -79,7 +80,13 @@ util::Map<std::string, const ServiceBooking*> Controller::getServiceBookingsByUs
util::Map<std::string, const User*> Controller::getUsers() util::Map<std::string, const User*> Controller::getUsers()
{ {
return util::Map<std::string, const User*>(); auto listOfUsers = m_userManagementService.getUsers();
util::Map<std::string, const User*> readOnlyUserList;
for (int iterator = 0; iterator < listOfUsers.getSize(); iterator++)
{
readOnlyUserList.insert(listOfUsers.getKeyAt(iterator), listOfUsers.getValueAt(iterator));
}
return readOnlyUserList;
} }
util::Map<std::string, const User*> Controller::getUsers(util::UserType userType) util::Map<std::string, const User*> Controller::getUsers(util::UserType userType)
@@ -110,6 +117,14 @@ void Controller::completeJob(const std::string& jobID)
void Controller::removeUser(const std::string& userID) void Controller::removeUser(const std::string& userID)
{ {
User* user = m_userManagementService.getUser(userID);
if (!user)
{
throw std::runtime_error("Error User not Found.\n");
}
m_serviceManagementService.cancelCustomerServiceBookings(userID);
m_serviceManagementService.cancelTechnicianJobs(userID);
m_userManagementService.removeUser(userID);
} }
void Controller::createComboPackage(const std::string& name, const util::Vector<std::string>& serviceIDs, double discountPercentage) void Controller::createComboPackage(const std::string& name, const util::Vector<std::string>& serviceIDs, double discountPercentage)
@@ -3,6 +3,7 @@
#include <string> #include <string>
#include "Enums.h" #include "Enums.h"
#include "UserManagementService.h" #include "UserManagementService.h"
#include "ServiceManagementService.h"
class Service; class Service;
class ComboPackage; class ComboPackage;
@@ -17,6 +18,7 @@ class Controller
{ {
private: private:
UserManagementService m_userManagementService; UserManagementService m_userManagementService;
ServiceManagementService m_serviceManagementService;
public: public:
bool login(const std::string& username, const std::string& password); bool login(const std::string& username, const std::string& password);
void logout(); void logout();
@@ -7,7 +7,7 @@ JobCard::JobCard()
m_booking(nullptr), m_booking(nullptr),
m_service(nullptr), m_service(nullptr),
m_technician(nullptr), m_technician(nullptr),
m_status(ServiceJobStatus()) {} m_status(util::ServiceJobStatus()) {}
JobCard::JobCard(const std::string& bookingId, JobCard::JobCard(const std::string& bookingId,
ServiceBooking* booking, ServiceBooking* booking,
@@ -16,7 +16,7 @@ JobCard::JobCard(const std::string& bookingId,
const std::string& technicianId, const std::string& technicianId,
User* technician, User* technician,
const util::Timestamp& assignedDate, const util::Timestamp& assignedDate,
ServiceJobStatus status, util::ServiceJobStatus status,
const util::Timestamp& completionDate const util::Timestamp& completionDate
) )
: m_id("JC" + std::to_string(++m_uid)), : m_id("JC" + std::to_string(++m_uid)),
@@ -70,7 +70,7 @@ const util::Timestamp& JobCard::getAssignedDate() const
return m_assignedDate; return m_assignedDate;
} }
ServiceJobStatus JobCard::getStatus() const util::ServiceJobStatus JobCard::getStatus() const
{ {
return m_status; return m_status;
} }
@@ -120,7 +120,7 @@ void JobCard::setAssignedDate(const util::Timestamp& assignedDate)
m_assignedDate = assignedDate; m_assignedDate = assignedDate;
} }
void JobCard::setStatus(ServiceJobStatus status) void JobCard::setStatus(util::ServiceJobStatus status)
{ {
m_status = status; m_status = status;
} }
@@ -1,13 +1,12 @@
#pragma once #pragma once
#include <string> #include <string>
#include "Timestamp.h" #include "Timestamp.h"
#include "Enums.h"
class ServiceBooking; class ServiceBooking;
class Service; class Service;
class User; class User;
enum class ServiceJobStatus : int;
class JobCard class JobCard
{ {
private: private:
@@ -20,9 +19,8 @@ private:
std::string m_technicianId; std::string m_technicianId;
User* m_technician; User* m_technician;
util::Timestamp m_assignedDate; util::Timestamp m_assignedDate;
ServiceJobStatus m_status; util::ServiceJobStatus m_status;
util::Timestamp m_completionDate; util::Timestamp m_completionDate;
public: public:
JobCard(); JobCard();
JobCard(const std::string& bookingId, JobCard(const std::string& bookingId,
@@ -32,7 +30,7 @@ public:
const std::string& technicianId, const std::string& technicianId,
User* technician, User* technician,
const util::Timestamp& assignedDate, const util::Timestamp& assignedDate,
ServiceJobStatus status, util::ServiceJobStatus status,
const util::Timestamp& completionDate const util::Timestamp& completionDate
); );
const std::string& getId() const; const std::string& getId() const;
@@ -43,7 +41,7 @@ public:
const std::string& getTechnicianId() const; const std::string& getTechnicianId() const;
User* getTechnician() const; User* getTechnician() const;
const util::Timestamp& getAssignedDate() const; const util::Timestamp& getAssignedDate() const;
ServiceJobStatus getStatus() const; util::ServiceJobStatus getStatus() const;
const util::Timestamp& getCompletionDate() const; const util::Timestamp& getCompletionDate() const;
void setId(const std::string& id); void setId(const std::string& id);
void setBookingId(const std::string& bookingId); void setBookingId(const std::string& bookingId);
@@ -53,6 +51,6 @@ public:
void setTechnicianId(const std::string& technicianId); void setTechnicianId(const std::string& technicianId);
void setTechnician(User* technician); void setTechnician(User* technician);
void setAssignedDate(const util::Timestamp& assignedDate); void setAssignedDate(const util::Timestamp& assignedDate);
void setStatus(ServiceJobStatus status); void setStatus(util::ServiceJobStatus status);
void setCompletionDate(const util::Timestamp& completionDate); void setCompletionDate(const util::Timestamp& completionDate);
}; };
@@ -18,7 +18,7 @@ ServiceBooking::ServiceBooking(
const std::string& vehicleBrand, const std::string& vehicleBrand,
const std::string& vehicleModel, const std::string& vehicleModel,
const std::string& assignedTechnicianId, const std::string& assignedTechnicianId,
const std::string& assignedTechnician, User* assignedTechnician,
double discountPercentage double discountPercentage
) )
: m_id("SRV" + std::to_string(++m_uid)), : m_id("SRV" + std::to_string(++m_uid)),
@@ -80,7 +80,7 @@ const std::string& ServiceBooking::getAssignedTechnicianId() const
return m_assignedTechnicianId; return m_assignedTechnicianId;
} }
const std::string& ServiceBooking::getAssignedTechnician() const User* ServiceBooking::getAssignedTechnician() const
{ {
return m_assignedTechnician; return m_assignedTechnician;
} }
@@ -135,7 +135,7 @@ void ServiceBooking::setAssignedTechnicianId(const std::string& assignedTechnici
m_assignedTechnicianId = assignedTechnicianId; m_assignedTechnicianId = assignedTechnicianId;
} }
void ServiceBooking::setAssignedTechnician(const std::string& assignedTechnician) void ServiceBooking::setAssignedTechnician(User* assignedTechnician)
{ {
m_assignedTechnician = assignedTechnician; m_assignedTechnician = assignedTechnician;
} }
@@ -19,7 +19,7 @@ private:
std::string m_vehicleBrand; std::string m_vehicleBrand;
std::string m_vehicleModel; std::string m_vehicleModel;
std::string m_assignedTechnicianId; std::string m_assignedTechnicianId;
std::string m_assignedTechnician; User* m_assignedTechnician;
double m_discountPercentage; double m_discountPercentage;
public: public:
ServiceBooking(); ServiceBooking();
@@ -34,7 +34,7 @@ public:
const std::string& vehicleBrand, const std::string& vehicleBrand,
const std::string& vehicleModel, const std::string& vehicleModel,
const std::string& assignedTechnicianId, const std::string& assignedTechnicianId,
const std::string& assignedTechnician, User* assignedTechnician,
double discountPercentage double discountPercentage
); );
const std::string& getId() const; const std::string& getId() const;
@@ -46,7 +46,7 @@ public:
const std::string& getVehicleBrand() const; const std::string& getVehicleBrand() const;
const std::string& getVehicleModel() const; const std::string& getVehicleModel() const;
const std::string& getAssignedTechnicianId() const; const std::string& getAssignedTechnicianId() const;
const std::string& getAssignedTechnician() const; User* getAssignedTechnician() const;
double getDiscountPercentage() const; double getDiscountPercentage() const;
void setId(const std::string& id); void setId(const std::string& id);
void setStatus(const util::ServiceJobStatus& status); void setStatus(const util::ServiceJobStatus& status);
@@ -57,6 +57,6 @@ public:
void setVehicleBrand(const std::string& vehicleBrand); void setVehicleBrand(const std::string& vehicleBrand);
void setVehicleModel(const std::string& vehicleModel); void setVehicleModel(const std::string& vehicleModel);
void setAssignedTechnicianId(const std::string& assignedTechnicianId); void setAssignedTechnicianId(const std::string& assignedTechnicianId);
void setAssignedTechnician(const std::string& assignedTechnician); void setAssignedTechnician(User* assignedTechnician);
void setDiscountPercentage(double discountPercentage); void setDiscountPercentage(double discountPercentage);
}; };
@@ -1 +1,100 @@
#include "ServiceManagementService.h" #include "ServiceManagementService.h"
#include "DataStore.h"
#include "ServiceBooking.h"
#include "JobCard.h"
#include "Service.h"
#include "InventoryItem.h"
void ServiceManagementService::cancelCustomerServiceBookings(const std::string& userID)
{
const int INCREMENT_VALUE = 1;
auto& users = m_dataStore.getUsers();
int userIndex = users.find(userID);
if (userIndex == -1)
{
throw std::runtime_error("User not found: " + userID);
}
User* user = users.getValueAt(userIndex);
if (user == nullptr)
{
throw std::runtime_error("User not found: " + userID);
}
util::UserType type = user->getUserType();
auto& bookings = DataStore::getInstance().getServiceBookings();
for (int bookingIterator = 0; bookingIterator < bookings.getSize(); bookingIterator++)
{
ServiceBooking* booking = bookings.getValueAt(bookingIterator);
if (booking != nullptr &&
(booking->getCustomerId() == userID || booking->getAssignedTechnicianId() == userID))
{
if (booking->getStatus() == util::ServiceJobStatus::PENDING ||
booking->getStatus() == util::ServiceJobStatus::STARTED)
{
if (type == util::UserType::CUSTOMER)
{
booking->setStatus(util::ServiceJobStatus::CANCELLED);
booking->setCustomer(nullptr);
booking->setCustomerId("");
User* assignedTechnician = booking->getAssignedTechnician();
sendNotification(assignedTechnician, "Customer Service Cancelled", "Uh?Oh. The customer has cancelled their service booking. Your assigned job card has been cancelled and the inventory has been restocked.");
}
else if (type == util::UserType::TECHNICIAN)
{
booking->setStatus(util::ServiceJobStatus::PENDING);
sendNotification(booking->getCustomer(), "Technician Unavailable", "Your assigned technician is no longer available. Your booking has been reset to pending, and we will reassign a new technician shortly.");
}
booking->setAssignedTechnician(nullptr);
booking->setAssignedTechnicianId("");
const auto& ListOfServices = booking->getServices();
for (int serviceIterator = 0; serviceIterator < ListOfServices.getSize(); serviceIterator++)
{
Service* service = ListOfServices.getValueAt(serviceIterator);
if (service != nullptr)
{
const auto& items = service->getRequiredInventoryItems();
for (int itemIterator = 0; itemIterator < items.getSize(); itemIterator++)
{
InventoryItem* item = items.getValueAt(itemIterator);
if (item != nullptr)
{
item->setQuantity(item->getQuantity() + INCREMENT_VALUE);
}
}
}
}
}
}
}
}
void ServiceManagementService::cancelTechnicianJobs(const std::string& technicianID)
{
const int INCREMENT_VALUE = 1;
auto& jobs = m_dataStore.getJobCards();
for (int jobIterator = 0; jobIterator < jobs.getSize(); jobIterator++)
{
JobCard* job = jobs.getValueAt(jobIterator);
if (job != nullptr && job->getTechnicianId() == technicianID)
{
if (job->getStatus() == util::ServiceJobStatus::PENDING || job->getStatus() == util::ServiceJobStatus::STARTED)
{
job->setStatus(util::ServiceJobStatus::CANCELLED);
sendNotification(job->getTechnician(), "Job Cancelled", "The Job has cancelled. Your job card has been cancelled and the inventory has been restocked.");
Service* service = job->getService();
if (service != nullptr)
{
const auto& items = service->getRequiredInventoryItems();
for (int itemIterator = 0; itemIterator < items.getSize(); itemIterator++)
{
InventoryItem* item = items.getValueAt(itemIterator);
if (item != nullptr)
{
item->setQuantity(item->getQuantity() + INCREMENT_VALUE);
}
}
}
}
}
}
}
@@ -1 +1,30 @@
#include "UserManagementService.h" #include "UserManagementService.h"
#include "User.h"
util::Map<std::string, User*> UserManagementService::getUsers()
{
return m_dataStore.getUsers();
}
User* UserManagementService::getUser(const std::string& userID)
{
int index = m_dataStore.getUsers().find(userID);
if (index != -1)
{
return m_dataStore.getUsers().getValueAt(index);
}
return nullptr;
}
void UserManagementService::removeUser(const std::string& userID)
{
int index = m_dataStore.getUsers().find(userID);
if (index != -1)
{
User* user = m_dataStore.getUsers().getValueAt(index);
if (user != nullptr)
{
user->setState(util::State::INACTIVE);
}
}
}
@@ -24,8 +24,10 @@ namespace util
enum class ServiceJobStatus enum class ServiceJobStatus
{ {
PENDING,
STARTED, STARTED,
COMPLETED COMPLETED,
CANCELLED
}; };
enum class State enum class State
@@ -121,10 +123,14 @@ namespace util
{ {
switch (status) switch (status)
{ {
case ServiceJobStatus::PENDING:
return "PENDING";
case ServiceJobStatus::STARTED: case ServiceJobStatus::STARTED:
return "STARTED"; return "STARTED";
case ServiceJobStatus::COMPLETED: case ServiceJobStatus::COMPLETED:
return "COMPLETED"; return "COMPLETED";
case ServiceJobStatus::CANCELLED:
return "CANCELLED";
} }
throw std::invalid_argument("Invalid ServiceJobStatus"); throw std::invalid_argument("Invalid ServiceJobStatus");
} }
@@ -139,6 +145,14 @@ namespace util
{ {
return ServiceJobStatus::COMPLETED; return ServiceJobStatus::COMPLETED;
} }
if (value == "PENDING")
{
return ServiceJobStatus::PENDING;
}
if (value == "CANCELLED")
{
return ServiceJobStatus::CANCELLED;
}
throw std::invalid_argument("Invalid ServiceJobStatus string"); throw std::invalid_argument("Invalid ServiceJobStatus string");
} }
@@ -0,0 +1,15 @@
#pragma once
#include "Service.h"
#include "InventoryItem.h"
inline double calculatePartsCost(const Service* service)
{
double cost = 0;
auto& requiredInventoryItems = service->getRequiredInventoryItems();
int requiredInventoryItemsSize = requiredInventoryItems.getSize();
for (int index = 0; index < requiredInventoryItemsSize; index++)
{
cost += requiredInventoryItems.getValueAt(index)->getPrice();
}
return cost;
}
@@ -2,6 +2,7 @@
#include "AdminMenu.h" #include "AdminMenu.h"
#include "InputHelper.h" #include "InputHelper.h"
#include "OutputHelper.h" #include "OutputHelper.h"
#include "User.h"
#include "Validator.h" #include "Validator.h"
void AdminMenu::showMenu() void AdminMenu::showMenu()
@@ -105,8 +106,79 @@ void AdminMenu::addTechnician()
util::pressEnter(); util::pressEnter();
} }
static util::Map<std::string, const User*>
filterActiveUsers(const util::Map<std::string, const User*>& listOfUsers)
{
util::Map<std::string, const User*> activeUsers;
int inventorySize = listOfUsers.getSize();
for (int index = 0; index < inventorySize; index++)
{
const User* user = listOfUsers.getValueAt(index);
if (user != nullptr && user->getState() != util::State::INACTIVE)
{
activeUsers.insert(user->getId(), user);
}
}
return activeUsers;
}
static void displayAllActiveUsers(util::Map<std::string, const User*>& activeUsers, int activeUserCount)
{
std::cout << std::left << std::setw(10) << "Index"
<< std::setw(15) << "User ID"
<< std::setw(25) << "Username"
<< std::setw(25) << "User Type"
<< std::endl;
for (int iterator = 0; iterator < activeUserCount; iterator++)
{
const User* user = activeUsers.getValueAt(iterator);
if (user != nullptr)
{
std::cout << std::left << std::setw(10) << (iterator + 1)
<< std::setw(15) << user->getId()
<< std::setw(25) << user->getUserName()
<< std::setw(25) << util::getUserTypeString(user->getUserType())
<< std::endl;
}
else
{
std::cout << "No users found.\n";
util::pressEnter();
return;
}
}
}
void AdminMenu::removeUser() void AdminMenu::removeUser()
{ {
util::clear();
int indexChoice;
auto listOfUsers = m_controller.getUsers();
auto listOfActiveUsers = filterActiveUsers(listOfUsers);
int activeUserCount = listOfActiveUsers.getSize();
if (activeUserCount < 1)
{
std::cout << "No Active users." << std::endl;
util::pressEnter();
return;
}
displayAllActiveUsers(listOfActiveUsers, activeUserCount);
std::cout << "Enter the index of the user to delete : ";
util::read(indexChoice);
if (indexChoice < 1 || indexChoice > activeUserCount)
{
std::cout << "Error Invaild index.\n" << std::endl;
util::pressEnter();
return;
}
const User* userToRemove = listOfActiveUsers.getValueAt(indexChoice - 1);
if (userToRemove != nullptr)
{
std::string userIdToRemove = userToRemove->getId();
m_controller.removeUser(userIdToRemove);
std::cout << userToRemove->getUserName() << " removed Successfully.\n";
}
util::pressEnter();
} }
void AdminMenu::createComboPackages() void AdminMenu::createComboPackages()