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\OutputHelper.h" />
<ClInclude Include="utilities\Timestamp.h" />
<ClInclude Include="utilities\Utility.h" />
<ClInclude Include="utilities\Validator.h" />
<ClInclude Include="utilities\Vector.h" />
<ClInclude Include="views\AdminMenu.h" />
@@ -233,5 +233,8 @@
<ClInclude Include="models\ComboPackage.h">
<Filter>Header Files\Models</Filter>
</ClInclude>
<ClInclude Include="utilities\Utility.h">
<Filter>Header Files\Utilities</Filter>
</ClInclude>
</ItemGroup>
</Project>
@@ -1,4 +1,5 @@
#include "Controller.h"
#include "User.h"
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()
{
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)
@@ -110,6 +117,14 @@ void Controller::completeJob(const std::string& jobID)
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)
@@ -3,6 +3,7 @@
#include <string>
#include "Enums.h"
#include "UserManagementService.h"
#include "ServiceManagementService.h"
class Service;
class ComboPackage;
@@ -17,6 +18,7 @@ class Controller
{
private:
UserManagementService m_userManagementService;
ServiceManagementService m_serviceManagementService;
public:
bool login(const std::string& username, const std::string& password);
void logout();
@@ -7,7 +7,7 @@ JobCard::JobCard()
m_booking(nullptr),
m_service(nullptr),
m_technician(nullptr),
m_status(ServiceJobStatus()) {}
m_status(util::ServiceJobStatus()) {}
JobCard::JobCard(const std::string& bookingId,
ServiceBooking* booking,
@@ -16,7 +16,7 @@ JobCard::JobCard(const std::string& bookingId,
const std::string& technicianId,
User* technician,
const util::Timestamp& assignedDate,
ServiceJobStatus status,
util::ServiceJobStatus status,
const util::Timestamp& completionDate
)
: m_id("JC" + std::to_string(++m_uid)),
@@ -70,7 +70,7 @@ const util::Timestamp& JobCard::getAssignedDate() const
return m_assignedDate;
}
ServiceJobStatus JobCard::getStatus() const
util::ServiceJobStatus JobCard::getStatus() const
{
return m_status;
}
@@ -120,7 +120,7 @@ void JobCard::setAssignedDate(const util::Timestamp& assignedDate)
m_assignedDate = assignedDate;
}
void JobCard::setStatus(ServiceJobStatus status)
void JobCard::setStatus(util::ServiceJobStatus status)
{
m_status = status;
}
@@ -1,13 +1,12 @@
#pragma once
#include <string>
#include "Timestamp.h"
#include "Enums.h"
class ServiceBooking;
class Service;
class User;
enum class ServiceJobStatus : int;
class JobCard
{
private:
@@ -20,9 +19,8 @@ private:
std::string m_technicianId;
User* m_technician;
util::Timestamp m_assignedDate;
ServiceJobStatus m_status;
util::ServiceJobStatus m_status;
util::Timestamp m_completionDate;
public:
JobCard();
JobCard(const std::string& bookingId,
@@ -32,7 +30,7 @@ public:
const std::string& technicianId,
User* technician,
const util::Timestamp& assignedDate,
ServiceJobStatus status,
util::ServiceJobStatus status,
const util::Timestamp& completionDate
);
const std::string& getId() const;
@@ -43,7 +41,7 @@ public:
const std::string& getTechnicianId() const;
User* getTechnician() const;
const util::Timestamp& getAssignedDate() const;
ServiceJobStatus getStatus() const;
util::ServiceJobStatus getStatus() const;
const util::Timestamp& getCompletionDate() const;
void setId(const std::string& id);
void setBookingId(const std::string& bookingId);
@@ -53,6 +51,6 @@ public:
void setTechnicianId(const std::string& technicianId);
void setTechnician(User* technician);
void setAssignedDate(const util::Timestamp& assignedDate);
void setStatus(ServiceJobStatus status);
void setStatus(util::ServiceJobStatus status);
void setCompletionDate(const util::Timestamp& completionDate);
};
@@ -18,7 +18,7 @@ ServiceBooking::ServiceBooking(
const std::string& vehicleBrand,
const std::string& vehicleModel,
const std::string& assignedTechnicianId,
const std::string& assignedTechnician,
User* assignedTechnician,
double discountPercentage
)
: m_id("SRV" + std::to_string(++m_uid)),
@@ -80,7 +80,7 @@ const std::string& ServiceBooking::getAssignedTechnicianId() const
return m_assignedTechnicianId;
}
const std::string& ServiceBooking::getAssignedTechnician() const
User* ServiceBooking::getAssignedTechnician() const
{
return m_assignedTechnician;
}
@@ -135,7 +135,7 @@ void ServiceBooking::setAssignedTechnicianId(const std::string& assignedTechnici
m_assignedTechnicianId = assignedTechnicianId;
}
void ServiceBooking::setAssignedTechnician(const std::string& assignedTechnician)
void ServiceBooking::setAssignedTechnician(User* assignedTechnician)
{
m_assignedTechnician = assignedTechnician;
}
@@ -19,7 +19,7 @@ private:
std::string m_vehicleBrand;
std::string m_vehicleModel;
std::string m_assignedTechnicianId;
std::string m_assignedTechnician;
User* m_assignedTechnician;
double m_discountPercentage;
public:
ServiceBooking();
@@ -34,7 +34,7 @@ public:
const std::string& vehicleBrand,
const std::string& vehicleModel,
const std::string& assignedTechnicianId,
const std::string& assignedTechnician,
User* assignedTechnician,
double discountPercentage
);
const std::string& getId() const;
@@ -46,7 +46,7 @@ public:
const std::string& getVehicleBrand() const;
const std::string& getVehicleModel() const;
const std::string& getAssignedTechnicianId() const;
const std::string& getAssignedTechnician() const;
User* getAssignedTechnician() const;
double getDiscountPercentage() const;
void setId(const std::string& id);
void setStatus(const util::ServiceJobStatus& status);
@@ -57,6 +57,6 @@ public:
void setVehicleBrand(const std::string& vehicleBrand);
void setVehicleModel(const std::string& vehicleModel);
void setAssignedTechnicianId(const std::string& assignedTechnicianId);
void setAssignedTechnician(const std::string& assignedTechnician);
void setAssignedTechnician(User* assignedTechnician);
void setDiscountPercentage(double discountPercentage);
};
@@ -1 +1,100 @@
#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 "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
{
PENDING,
STARTED,
COMPLETED
COMPLETED,
CANCELLED
};
enum class State
@@ -121,10 +123,14 @@ namespace util
{
switch (status)
{
case ServiceJobStatus::PENDING:
return "PENDING";
case ServiceJobStatus::STARTED:
return "STARTED";
case ServiceJobStatus::COMPLETED:
return "COMPLETED";
case ServiceJobStatus::CANCELLED:
return "CANCELLED";
}
throw std::invalid_argument("Invalid ServiceJobStatus");
}
@@ -139,6 +145,14 @@ namespace util
{
return ServiceJobStatus::COMPLETED;
}
if (value == "PENDING")
{
return ServiceJobStatus::PENDING;
}
if (value == "CANCELLED")
{
return ServiceJobStatus::CANCELLED;
}
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 "InputHelper.h"
#include "OutputHelper.h"
#include "User.h"
#include "Validator.h"
void AdminMenu::showMenu()
@@ -105,8 +106,79 @@ void AdminMenu::addTechnician()
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()
{
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()