Compare commits
69 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 931aa4c406 | |||
| c5ada405e6 | |||
| d6b4310de6 | |||
| 451085e9c2 | |||
| 4657d3e8d1 | |||
| b1b6125d88 | |||
| e739ec6ee2 | |||
| f78e02ed3d | |||
| 807490443e | |||
| b7bc1f574d | |||
| b25b3d59cf | |||
| c1bd2a6ef1 | |||
| 859f7bbeaa | |||
| d6cc6fc04f | |||
| 62cd7dcc89 | |||
| c67bf962c1 | |||
| efd8b32a5f | |||
| 01596e825e | |||
| fb50aeba47 | |||
| defee9aa15 | |||
| 67e5917a57 | |||
| 83e2bed432 | |||
| a9c8ec93b7 | |||
| 13b7d6d40a | |||
| 665e83d56a | |||
| 8268b90d82 | |||
| 7646ce6644 | |||
| 05499e4890 | |||
| 3b82648e45 | |||
| 937ba2e7cf | |||
| f63e4056f2 | |||
| febfa45e4a | |||
| 33cbb1dac3 | |||
| 80b91f3f1b | |||
| a87af89a8a | |||
| f1ca8c2a58 | |||
| d55bbb6349 | |||
| ae488f5670 | |||
| d8f7e46180 | |||
| 3d7944f77d | |||
| 9439202c5a | |||
| e6faa63b88 | |||
| 31e660bc9e | |||
| 5fd0a47459 | |||
| fb509ccb3f | |||
| 8d07b11eae | |||
| 1e11903cca | |||
| 19acbed1fd | |||
| 089fe496b2 | |||
| 9ee392ab3c | |||
| ef5125d445 | |||
| 1c717bb9fa | |||
| 6392191c14 | |||
| f1d146a37c | |||
| 0519690043 | |||
| 0adb864329 | |||
| a3ad4d2e00 | |||
| 86fd32bd2b | |||
| fceb1cbec6 | |||
| 53ff70a85f | |||
| 4a4309d585 | |||
| 61f70a54f6 | |||
| 461857f971 | |||
| cb3bed4050 | |||
| 8162a2fe3d | |||
| fc7bb2569b | |||
| 70e1ef66d4 | |||
| e7f1b51d05 | |||
| 9b7d9cf7c1 |
+185
-12
@@ -6,12 +6,16 @@ Description: Implementation file containing the method definitions of the
|
|||||||
Author: Trenser
|
Author: Trenser
|
||||||
Date:19-May-2026
|
Date:19-May-2026
|
||||||
*/
|
*/
|
||||||
#include <stdexcept>
|
#include "ComboPackage.h"
|
||||||
#include "Controller.h"
|
#include "Controller.h"
|
||||||
#include "Enums.h"
|
#include "Enums.h"
|
||||||
|
#include "InventoryItem.h"
|
||||||
|
#include "Invoice.h"
|
||||||
|
#include "JobCard.h"
|
||||||
|
#include "Service.h"
|
||||||
|
#include "ServiceBooking.h"
|
||||||
#include "User.h"
|
#include "User.h"
|
||||||
#include "ComboPackage.h"
|
#include <stdexcept>
|
||||||
#include "User.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Function: login
|
Function: login
|
||||||
@@ -106,9 +110,23 @@ void Controller::updateUserDetails(const std::string& email, const std::string&
|
|||||||
m_userManagementService.updateUserDetails(authenticatedUser->getId(), email, phone);
|
m_userManagementService.updateUserDetails(authenticatedUser->getId(), email, phone);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: getServices
|
||||||
|
Description: Retrieves all available services in read-only form.
|
||||||
|
Parameters:
|
||||||
|
- None
|
||||||
|
Returns:
|
||||||
|
- util::Map<std::string, const Service*> containing all services
|
||||||
|
*/
|
||||||
util::Map<std::string, const Service*> Controller::getServices()
|
util::Map<std::string, const Service*> Controller::getServices()
|
||||||
{
|
{
|
||||||
return util::Map<std::string, const Service*>();
|
util::Map<std::string, Service*> currentServices = m_serviceManagementService.getServices();
|
||||||
|
util::Map<std::string, const Service*> readOnlyServices;
|
||||||
|
for (int iterator = 0; iterator < currentServices.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
readOnlyServices.insert(currentServices.getValueAt(iterator)->getId(), currentServices.getValueAt(iterator));
|
||||||
|
}
|
||||||
|
return readOnlyServices;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -227,14 +245,42 @@ void Controller::addInventoryItemStock(const std::string& selectedItemId, int qu
|
|||||||
m_inventoryManagementService.addInventoryItemStock(selectedItemId, quantity);
|
m_inventoryManagementService.addInventoryItemStock(selectedItemId, quantity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: getServiceBookings
|
||||||
|
Description: Retrieves all service bookings in read-only form.
|
||||||
|
Parameters:
|
||||||
|
- None
|
||||||
|
Returns:
|
||||||
|
- util::Map<std::string, const ServiceBooking*> containing service bookings
|
||||||
|
*/
|
||||||
util::Map<std::string, const ServiceBooking*> Controller::getServiceBookings()
|
util::Map<std::string, const ServiceBooking*> Controller::getServiceBookings()
|
||||||
{
|
{
|
||||||
return util::Map<std::string, const ServiceBooking*>();
|
auto serviceBookings = m_serviceManagementService.getServiceBookings();
|
||||||
|
util::Map<std::string, const ServiceBooking*> readOnlyServiceBookings;
|
||||||
|
for (int iterator = 0; iterator < serviceBookings.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
readOnlyServiceBookings.insert(serviceBookings.getKeyAt(iterator), serviceBookings.getValueAt(iterator));
|
||||||
|
}
|
||||||
|
return readOnlyServiceBookings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: getServiceBookingsByUser
|
||||||
|
Description: Retrieves all service bookings for a specific user.
|
||||||
|
Parameters:
|
||||||
|
- userID: std::string, the user ID
|
||||||
|
Returns:
|
||||||
|
- util::Map<std::string, const ServiceBooking*> containing bookings for the user
|
||||||
|
*/
|
||||||
util::Map<std::string, const ServiceBooking*> Controller::getServiceBookingsByUser(const std::string userID)
|
util::Map<std::string, const ServiceBooking*> Controller::getServiceBookingsByUser(const std::string userID)
|
||||||
{
|
{
|
||||||
return util::Map<std::string, const ServiceBooking*>();
|
util::Map<std::string, const ServiceBooking*> readOnlyServiceBookingsByUserMap;
|
||||||
|
util::Map<std::string, ServiceBooking*> currentServiceBookingsByUser = m_serviceManagementService.getServiceBookings(userID);
|
||||||
|
for (int iterator = 0; iterator < currentServiceBookingsByUser.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
readOnlyServiceBookingsByUserMap.insert(currentServiceBookingsByUser.getValueAt(iterator)->getId(), currentServiceBookingsByUser.getValueAt(iterator));
|
||||||
|
}
|
||||||
|
return readOnlyServiceBookingsByUserMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -255,30 +301,100 @@ util::Map<std::string, const User*> Controller::getUsers()
|
|||||||
return readOnlyUserList;
|
return readOnlyUserList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: getUsers
|
||||||
|
Description: Retrieves users filtered by user type.
|
||||||
|
Parameters:
|
||||||
|
- userType: util::UserType, type of user (CUSTOMER, TECHNICIAN, ADMIN)
|
||||||
|
Returns:
|
||||||
|
- util::Map<std::string, const User*> containing users of the specified type
|
||||||
|
*/
|
||||||
util::Map<std::string, const User*> Controller::getUsers(util::UserType userType)
|
util::Map<std::string, const User*> Controller::getUsers(util::UserType userType)
|
||||||
{
|
{
|
||||||
return util::Map<std::string, const User*>();
|
auto userMap = m_userManagementService.getUsers(userType);
|
||||||
|
util::Map<std::string, const User*> readOnlyUserMap;
|
||||||
|
for (int iterator = 0; iterator < userMap.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
readOnlyUserMap.insert(userMap.getKeyAt(iterator), userMap.getValueAt(iterator));
|
||||||
|
}
|
||||||
|
return readOnlyUserMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: createJobCard
|
||||||
|
Description: Creates a job card for a service booking assigned to a technician.
|
||||||
|
Parameters:
|
||||||
|
- bookingID: std::string, ID of the service booking
|
||||||
|
- technicianID: std::string, ID of the technician
|
||||||
|
- serviceID: std::string, ID of the service
|
||||||
|
Returns:
|
||||||
|
- void
|
||||||
|
*/
|
||||||
void Controller::createJobCard(const std::string& bookingID, const std::string& technicianID, const std::string& serviceID)
|
void Controller::createJobCard(const std::string& bookingID, const std::string& technicianID, const std::string& serviceID)
|
||||||
{
|
{
|
||||||
|
m_serviceManagementService.createJobCard(bookingID, technicianID, serviceID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: createService
|
||||||
|
Description: Creates a new service with associated inventory items and labor cost.
|
||||||
|
Parameters:
|
||||||
|
- name: std::string, name of the service
|
||||||
|
- inventoryItemIDs: Vector of inventory item IDs
|
||||||
|
- laborCost: double, labor cost
|
||||||
|
Returns:
|
||||||
|
- void
|
||||||
|
*/
|
||||||
void Controller::createService(const std::string& name, const util::Vector<std::string>& inventoryItemIDs, double laborCost)
|
void Controller::createService(const std::string& name, const util::Vector<std::string>& inventoryItemIDs, double laborCost)
|
||||||
{
|
{
|
||||||
|
m_serviceManagementService.createService(name, inventoryItemIDs, laborCost);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: removeService
|
||||||
|
Description: Removes a service from the system by ID.
|
||||||
|
Parameters:
|
||||||
|
- serviceID: std::string, ID of the service
|
||||||
|
Returns:
|
||||||
|
- void
|
||||||
|
*/
|
||||||
void Controller::removeService(const std::string& serviceID)
|
void Controller::removeService(const std::string& serviceID)
|
||||||
{
|
{
|
||||||
|
m_serviceManagementService.removeService(serviceID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: getJobCardsByUser
|
||||||
|
Description: Retrieves job cards assigned to the authenticated technician.
|
||||||
|
Parameters:
|
||||||
|
- None
|
||||||
|
Returns:
|
||||||
|
- util::Map<std::string, const JobCard*> containing job cards
|
||||||
|
*/
|
||||||
util::Map<std::string, const JobCard*> Controller::getJobCardsByUser()
|
util::Map<std::string, const JobCard*> Controller::getJobCardsByUser()
|
||||||
{
|
{
|
||||||
return util::Map<std::string, const JobCard*>();
|
const User* currentUser = getAuthenticatedUser();
|
||||||
|
auto jobCardsAssignedToTechnician = m_serviceManagementService.getJobCards(currentUser->getId());
|
||||||
|
util::Map<std::string, const JobCard*> readOnlyJobCardMap;
|
||||||
|
for (int iterator = 0; iterator < jobCardsAssignedToTechnician.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
JobCard* currentJobCard = jobCardsAssignedToTechnician.getValueAt(iterator);
|
||||||
|
readOnlyJobCardMap.insert(currentJobCard->getId(), currentJobCard);
|
||||||
|
}
|
||||||
|
return readOnlyJobCardMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: completeJob
|
||||||
|
Description: Marks a job card as completed.
|
||||||
|
Parameters:
|
||||||
|
- jobID: std::string, ID of the job card
|
||||||
|
Returns:
|
||||||
|
- void
|
||||||
|
*/
|
||||||
void Controller::completeJob(const std::string& jobID)
|
void Controller::completeJob(const std::string& jobID)
|
||||||
{
|
{
|
||||||
|
m_serviceManagementService.completeJob(jobID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -293,10 +409,8 @@ void Controller::removeUser(const std::string& userID)
|
|||||||
User* user = m_userManagementService.getUser(userID);
|
User* user = m_userManagementService.getUser(userID);
|
||||||
if (!user)
|
if (!user)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Error User not Found.\n");
|
throw std::runtime_error("Error: User not Found.\n");
|
||||||
}
|
}
|
||||||
m_serviceManagementService.cancelCustomerServiceBookings(userID);
|
|
||||||
m_serviceManagementService.cancelTechnicianJobs(userID);
|
|
||||||
m_userManagementService.removeUser(userID);
|
m_userManagementService.removeUser(userID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,13 +440,72 @@ void Controller::removeComboPackage(const std::string& comboPackageID)
|
|||||||
m_serviceManagementService.removeComboPackage(comboPackageID);
|
m_serviceManagementService.removeComboPackage(comboPackageID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: getInvoicesByUser
|
||||||
|
Description: Retrieves all invoices associated with the currently authenticated user.
|
||||||
|
Converts them into a read-only map before returning.
|
||||||
|
Parameters:
|
||||||
|
- None
|
||||||
|
Returns:
|
||||||
|
- util::Map<std::string, const Invoice*> containing the user’s invoices
|
||||||
|
*/
|
||||||
util::Map<std::string, const Invoice*> Controller::getInvoicesByUser()
|
util::Map<std::string, const Invoice*> Controller::getInvoicesByUser()
|
||||||
{
|
{
|
||||||
return util::Map<std::string, const Invoice*>();
|
User* currentUser = m_authenticationManagementService.getAuthenticatedUser();
|
||||||
|
util::Map<std::string, Invoice*> currentUserInvoices = m_paymentManagementService.getInvoices(currentUser->getId());
|
||||||
|
util::Map<std::string, const Invoice*> userInvoicesReadOnly;
|
||||||
|
for (int iterator = 0; iterator < currentUserInvoices.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
Invoice* currentInvoice = currentUserInvoices.getValueAt(iterator);
|
||||||
|
userInvoicesReadOnly.insert(currentInvoice->getId(), currentInvoice);
|
||||||
|
}
|
||||||
|
return userInvoicesReadOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: getAllInvoices
|
||||||
|
Description: Retrieves all invoices from the PaymentManagementService and returns them as a read-only map.
|
||||||
|
Parameters:
|
||||||
|
- none
|
||||||
|
Returns:
|
||||||
|
- util::Map<std::string, const Invoice*>: Map of invoice IDs to invoice objects
|
||||||
|
*/
|
||||||
|
util::Map<std::string, const Invoice*> Controller::getAllInvoices()
|
||||||
|
{
|
||||||
|
auto invoices = m_paymentManagementService.getAllInvoice();
|
||||||
|
util::Map<std::string, const Invoice*> readOnlyInvoice;
|
||||||
|
for (int iterator = 0; iterator < invoices.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
readOnlyInvoice.insert(invoices.getKeyAt(iterator), invoices.getValueAt(iterator));
|
||||||
|
}
|
||||||
|
return readOnlyInvoice;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: confirmPayment
|
||||||
|
Description: Delegates payment confirmation for a given invoice ID to the PaymentManagementService.
|
||||||
|
Parameters:
|
||||||
|
- invoiceID: std::string, ID of the invoice to confirm
|
||||||
|
Returns:
|
||||||
|
- void
|
||||||
|
*/
|
||||||
|
void Controller::confirmPayment(std::string invoiceID)
|
||||||
|
{
|
||||||
|
m_paymentManagementService.confirmPayment(invoiceID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: completePayment
|
||||||
|
Description: Completes payment for a specific invoice using the given payment mode.
|
||||||
|
Parameters:
|
||||||
|
- invoiceID: std::string, ID of the invoice to be paid
|
||||||
|
- paymentMode: util::PaymentMode, mode of payment (e.g., ONLINE, OFFLINE)
|
||||||
|
Returns:
|
||||||
|
- void
|
||||||
|
*/
|
||||||
void Controller::completePayment(const std::string& invoiceID, util::PaymentMode paymentMode)
|
void Controller::completePayment(const std::string& invoiceID, util::PaymentMode paymentMode)
|
||||||
{
|
{
|
||||||
|
m_paymentManagementService.completePayment(invoiceID, paymentMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -8,19 +8,14 @@ Date:19-May-2026
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <string>
|
||||||
#include "AuthenticationManagementService.h"
|
#include "AuthenticationManagementService.h"
|
||||||
#include "Enums.h"
|
#include "Enums.h"
|
||||||
#include "InventoryManagementService.h"
|
#include "InventoryManagementService.h"
|
||||||
#include "Map.h"
|
#include "Map.h"
|
||||||
#include "PaymentManagementService.h"
|
#include "PaymentManagementService.h"
|
||||||
#include "PaymentManagementService.h"
|
|
||||||
#include "ServiceManagementService.h"
|
|
||||||
#include "ServiceManagementService.h"
|
|
||||||
#include "ServiceManagementService.h"
|
#include "ServiceManagementService.h"
|
||||||
#include "UserManagementService.h"
|
#include "UserManagementService.h"
|
||||||
#include "UserManagementService.h"
|
|
||||||
#include "UserManagementService.h"
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
class Service;
|
class Service;
|
||||||
class ComboPackage;
|
class ComboPackage;
|
||||||
@@ -69,6 +64,8 @@ public:
|
|||||||
void createComboPackage(const std::string& name, const util::Vector<std::string>& serviceIDs, double discountPercentage);
|
void createComboPackage(const std::string& name, const util::Vector<std::string>& serviceIDs, double discountPercentage);
|
||||||
void removeComboPackage(const std::string& comboPackageID);
|
void removeComboPackage(const std::string& comboPackageID);
|
||||||
util::Map<std::string, const Invoice*> getInvoicesByUser();
|
util::Map<std::string, const Invoice*> getInvoicesByUser();
|
||||||
|
util::Map<std::string, const Invoice*> getAllInvoices();
|
||||||
|
void confirmPayment(std::string invoiceID);
|
||||||
void completePayment(const std::string& invoiceID, util::PaymentMode paymentMode);
|
void completePayment(const std::string& invoiceID, util::PaymentMode paymentMode);
|
||||||
util::Vector<const Notification*> getNotifications();
|
util::Vector<const Notification*> getNotifications();
|
||||||
void deleteNotification(const std::string& notificationID);
|
void deleteNotification(const std::string& notificationID);
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
Place files here.
|
|
||||||
@@ -58,8 +58,8 @@ Invoice::Invoice(
|
|||||||
const std::string& bookingId,
|
const std::string& bookingId,
|
||||||
ServiceBooking* booking,
|
ServiceBooking* booking,
|
||||||
const util::Timestamp& invoiceDate,
|
const util::Timestamp& invoiceDate,
|
||||||
double laborCost, const util::Map<std::string,
|
double laborCost,
|
||||||
InventoryItem*>& parts,
|
const util::Map<std::string, InventoryItem*>& parts,
|
||||||
double partsCost,
|
double partsCost,
|
||||||
double discountPercentage,
|
double discountPercentage,
|
||||||
double totalAmount,
|
double totalAmount,
|
||||||
@@ -87,7 +87,6 @@ Invoice::Invoice(
|
|||||||
m_partIDs.push_back(partPointers[index]->getId());
|
m_partIDs.push_back(partPointers[index]->getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Invoice::Invoice(
|
Invoice::Invoice(
|
||||||
const std::string& id,
|
const std::string& id,
|
||||||
const std::string& bookingId,
|
const std::string& bookingId,
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ public:
|
|||||||
const std::string& bookingId,
|
const std::string& bookingId,
|
||||||
ServiceBooking* booking,
|
ServiceBooking* booking,
|
||||||
const util::Timestamp& invoiceDate,
|
const util::Timestamp& invoiceDate,
|
||||||
double laborCost, const util::Map<std::string,
|
double laborCost,
|
||||||
InventoryItem*>& parts,
|
const util::Map<std::string,InventoryItem*>& parts,
|
||||||
double partsCost,
|
double partsCost,
|
||||||
double discountPercentage,
|
double discountPercentage,
|
||||||
double totalAmount,
|
double totalAmount,
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ Date:19-May-2026
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "Timestamp.h"
|
|
||||||
#include "Enums.h"
|
#include "Enums.h"
|
||||||
|
#include "Timestamp.h"
|
||||||
|
|
||||||
class ServiceBooking;
|
class ServiceBooking;
|
||||||
class Service;
|
class Service;
|
||||||
|
|||||||
@@ -24,9 +24,10 @@ Parameters: None
|
|||||||
Returns: A new ServiceBooking object.
|
Returns: A new ServiceBooking object.
|
||||||
*/
|
*/
|
||||||
ServiceBooking::ServiceBooking()
|
ServiceBooking::ServiceBooking()
|
||||||
: m_id("SRV" + std::to_string(++m_uid)),
|
: m_id("SBK" + std::to_string(++m_uid)),
|
||||||
m_customer(nullptr),
|
m_customer(nullptr),
|
||||||
m_assignedTechnician(nullptr),
|
m_assignedTechnician(nullptr),
|
||||||
|
m_status(util::ServiceJobStatus::PENDING),
|
||||||
m_discountPercentage(0.0) {}
|
m_discountPercentage(0.0) {}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -56,7 +57,7 @@ ServiceBooking::ServiceBooking(
|
|||||||
const std::string& vehicleModel,
|
const std::string& vehicleModel,
|
||||||
double discountPercentage
|
double discountPercentage
|
||||||
)
|
)
|
||||||
: m_id("SRV" + std::to_string(++m_uid)),
|
: m_id("SBK" + std::to_string(++m_uid)),
|
||||||
m_status(status),
|
m_status(status),
|
||||||
m_services(services),
|
m_services(services),
|
||||||
m_customerId(customerId),
|
m_customerId(customerId),
|
||||||
|
|||||||
+6
-2
@@ -59,6 +59,10 @@ Returns:
|
|||||||
void InventoryManagementService::sendLowStockAlerts()
|
void InventoryManagementService::sendLowStockAlerts()
|
||||||
{
|
{
|
||||||
auto& inventoryItems = m_dataStore.getInventoryItems();
|
auto& inventoryItems = m_dataStore.getInventoryItems();
|
||||||
|
if (inventoryItems.isEmpty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
int inventoryItemsSize = inventoryItems.getSize();
|
int inventoryItemsSize = inventoryItems.getSize();
|
||||||
auto& usersMap = m_dataStore.getUsers();
|
auto& usersMap = m_dataStore.getUsers();
|
||||||
int usersMapSize = usersMap.getSize();
|
int usersMapSize = usersMap.getSize();
|
||||||
@@ -76,7 +80,7 @@ void InventoryManagementService::sendLowStockAlerts()
|
|||||||
{
|
{
|
||||||
throw std::runtime_error("The system has no admins present!");
|
throw std::runtime_error("The system has no admins present!");
|
||||||
}
|
}
|
||||||
for (int index = 0; index <= inventoryItemsSize; index++)
|
for (int index = 0; index < inventoryItemsSize; index++)
|
||||||
{
|
{
|
||||||
InventoryItem* inventoryItem = inventoryItems.getValueAt(index);
|
InventoryItem* inventoryItem = inventoryItems.getValueAt(index);
|
||||||
if (inventoryItem && inventoryItem->getQuantity() < config::threshold::INVENTORY_LOW_STOCK_THRESHOLD)
|
if (inventoryItem && inventoryItem->getQuantity() < config::threshold::INVENTORY_LOW_STOCK_THRESHOLD)
|
||||||
@@ -319,7 +323,7 @@ void InventoryManagementService::sendNotification(User* user, const std::string&
|
|||||||
Factory::getObject<Notification>(
|
Factory::getObject<Notification>(
|
||||||
user->getId(),
|
user->getId(),
|
||||||
user,
|
user,
|
||||||
"InventoryManagementService: " + title,
|
title,
|
||||||
message,
|
message,
|
||||||
util::Timestamp()
|
util::Timestamp()
|
||||||
);
|
);
|
||||||
|
|||||||
+181
-1
@@ -12,8 +12,11 @@ Date: 20-May-2026
|
|||||||
#include "Enums.h"
|
#include "Enums.h"
|
||||||
#include "Factory.h"
|
#include "Factory.h"
|
||||||
#include "FileManager.h"
|
#include "FileManager.h"
|
||||||
|
#include "InventoryItem.h"
|
||||||
#include "Invoice.h"
|
#include "Invoice.h"
|
||||||
|
#include "JobCard.h"
|
||||||
#include "PaymentManagementService.h"
|
#include "PaymentManagementService.h"
|
||||||
|
#include "Service.h"
|
||||||
#include "ServiceBooking.h"
|
#include "ServiceBooking.h"
|
||||||
#include "Timestamp.h"
|
#include "Timestamp.h"
|
||||||
#include "User.h"
|
#include "User.h"
|
||||||
@@ -83,7 +86,7 @@ void PaymentManagementService::sendNotification(User* user, const std::string& t
|
|||||||
Factory::getObject<Notification>(
|
Factory::getObject<Notification>(
|
||||||
user->getId(),
|
user->getId(),
|
||||||
user,
|
user,
|
||||||
"PaymentManagementService: " + title,
|
title,
|
||||||
message,
|
message,
|
||||||
util::Timestamp()
|
util::Timestamp()
|
||||||
);
|
);
|
||||||
@@ -253,3 +256,180 @@ void PaymentManagementService::saveObservers()
|
|||||||
{
|
{
|
||||||
util::saveObservers(config::file::PAYMENTMANAGEMENTOBSERVERS, this);
|
util::saveObservers(config::file::PAYMENTMANAGEMENTOBSERVERS, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: createInventoryItemsMap (static helper)
|
||||||
|
Description: Builds a map of inventory items required for a given service and adds them to the booking’s inventory map.
|
||||||
|
Parameters:
|
||||||
|
- completeInventoryItemMapOfBooking: util::Map<std::string, InventoryItem*>&, map to store inventory items for the booking
|
||||||
|
- currentService: const Service*, pointer to the current service
|
||||||
|
Returns:
|
||||||
|
- void
|
||||||
|
*/
|
||||||
|
static void createInventoryItemsMap(util::Map<std::string, InventoryItem*>& completeInventoryItemMapOfBooking, const Service* currentService)
|
||||||
|
{
|
||||||
|
auto& currentRequiredInventoryItems = currentService->getRequiredInventoryItems();
|
||||||
|
for (int iterator = 0; iterator < currentRequiredInventoryItems.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
auto& currentRequiredInventoryItem = currentRequiredInventoryItems.getValueAt(iterator);
|
||||||
|
completeInventoryItemMapOfBooking.insert(currentRequiredInventoryItem->getId(), currentRequiredInventoryItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: generateInvoice
|
||||||
|
Description: Generates an invoice for a completed service booking.
|
||||||
|
Validates that all job cards are completed, calculates labor and parts cost, applies discount,
|
||||||
|
and stores the invoice in the datastore.
|
||||||
|
Parameters:
|
||||||
|
- booking: ServiceBooking*, pointer to the service booking
|
||||||
|
Returns:
|
||||||
|
- void
|
||||||
|
Throws:
|
||||||
|
- std::runtime_error if booking is null or job cards are incomplete
|
||||||
|
*/
|
||||||
|
void PaymentManagementService::generateInvoice(ServiceBooking* booking)
|
||||||
|
{
|
||||||
|
if (!booking)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Invoice generation failed: booking is null.");
|
||||||
|
}
|
||||||
|
double totalLaborCost = 0, totalPartsCost = 0, totalServiceCost = 0;
|
||||||
|
double discountPercentage = booking->getDiscountPercentage();
|
||||||
|
std::string bookingID = booking->getId();
|
||||||
|
util::Map<std::string, Service*> servicesInTheBookedService = booking->getServices();
|
||||||
|
util::Map<std::string, InventoryItem*> completeInventoryItemMapOfBooking;
|
||||||
|
util::Map<std::string, JobCard*> currentJobCards = m_dataStore.getJobCards();
|
||||||
|
for (int iterator = 0; iterator < currentJobCards.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
JobCard* currentJobCard = currentJobCards.getValueAt(iterator);
|
||||||
|
util::ServiceJobStatus currentJobCardStatus = currentJobCard->getStatus();
|
||||||
|
if (currentJobCard->getBookingId() == bookingID && currentJobCardStatus != util::ServiceJobStatus::CANCELLED && currentJobCardStatus != util::ServiceJobStatus::COMPLETED)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Invoice generation failed: Not all job cards are completed for booking '" + bookingID + "'.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int iterator = 0; iterator < servicesInTheBookedService.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
Service* currentService = servicesInTheBookedService.getValueAt(iterator);
|
||||||
|
if (currentService)
|
||||||
|
{
|
||||||
|
createInventoryItemsMap(completeInventoryItemMapOfBooking, currentService);
|
||||||
|
totalLaborCost += currentService->getLaborCost();
|
||||||
|
totalPartsCost += util::calculatePartsCost(currentService);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
totalServiceCost = totalLaborCost + totalPartsCost;
|
||||||
|
totalServiceCost -= (totalServiceCost * (discountPercentage / 100));
|
||||||
|
Invoice* invoice = Factory::getObject<Invoice>(bookingID, booking, util::Timestamp(), totalLaborCost, completeInventoryItemMapOfBooking, totalPartsCost, discountPercentage, totalServiceCost, util::Timestamp(), util::PaymentMode::NOTSET, util::PaymentStatus::PENDING);
|
||||||
|
util::Map<std::string, Invoice*>& currentInvoices = m_dataStore.getInvoices();
|
||||||
|
currentInvoices.insert(invoice->getId(), invoice);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: getInvoices
|
||||||
|
Description: Retrieves all invoices associated with a specific customer.
|
||||||
|
Parameters:
|
||||||
|
- customerID: std::string, ID of the customer
|
||||||
|
Returns:
|
||||||
|
- util::Map<std::string, Invoice*> containing the customer’s invoices
|
||||||
|
*/
|
||||||
|
util::Map<std::string, Invoice*> PaymentManagementService::getInvoices(const std::string& customerID)
|
||||||
|
{
|
||||||
|
util::Map<std::string, Invoice*>& currentInvoices = m_dataStore.getInvoices();
|
||||||
|
util::Map<std::string, Invoice*> currentUserInvoices;
|
||||||
|
for (int iterator = 0; iterator < currentInvoices.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
Invoice* currentInvoice = currentInvoices.getValueAt(iterator);
|
||||||
|
if (currentInvoice->getBooking()->getCustomerId() == customerID)
|
||||||
|
{
|
||||||
|
currentUserInvoices.insert(currentInvoice->getId(), currentInvoice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return currentUserInvoices;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: completePayment
|
||||||
|
Description: Completes payment for a specific invoice. Updates payment method, date, and status,
|
||||||
|
then sends a notification to the customer.
|
||||||
|
Parameters:
|
||||||
|
- invoiceID: std::string, ID of the invoice
|
||||||
|
- paymentMode: util::PaymentMode, mode of payment (e.g., ONLINE, OFFLINE)
|
||||||
|
Returns:
|
||||||
|
- void
|
||||||
|
Throws:
|
||||||
|
- std::runtime_error if the invoice ID is invalid
|
||||||
|
*/
|
||||||
|
void PaymentManagementService::completePayment(const std::string& invoiceID, util::PaymentMode paymentMode)
|
||||||
|
{
|
||||||
|
auto& currentInvoices = m_dataStore.getInvoices();
|
||||||
|
int invoiceIndex = currentInvoices.find(invoiceID);
|
||||||
|
if (invoiceIndex != -1)
|
||||||
|
{
|
||||||
|
Invoice* invoice = currentInvoices.getValueAt(invoiceIndex);
|
||||||
|
if (invoice && invoice->getStatus() != util::PaymentStatus::PAID)
|
||||||
|
{
|
||||||
|
User* currentUser = invoice->getBooking()->getCustomer();
|
||||||
|
invoice->setPaymentMethod(paymentMode);
|
||||||
|
invoice->setPaymentDate(util::Timestamp());
|
||||||
|
invoice->setStatus(util::PaymentStatus::PAID);
|
||||||
|
std::string title, message;
|
||||||
|
title = "Payment successful";
|
||||||
|
message = "Payment successful for Invoice ID " + invoiceID;
|
||||||
|
sendNotification(currentUser, title, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Payment failed: invalid invoice ID.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: getAllInvoice
|
||||||
|
Description: Provides access to all invoices stored in the data store.
|
||||||
|
Parameters:
|
||||||
|
- none
|
||||||
|
Returns:
|
||||||
|
- util::Map<std::string, Invoice*>&: Map of invoice IDs to invoice objects
|
||||||
|
*/
|
||||||
|
util::Map<std::string, Invoice*>& PaymentManagementService::getAllInvoice()
|
||||||
|
{
|
||||||
|
return m_dataStore.getInvoices();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: confirmPayment
|
||||||
|
Description: Confirms payment for a specific invoice. Updates payment date and status,
|
||||||
|
then sends a notification to the customer.
|
||||||
|
Parameters:
|
||||||
|
- invoiceID: std::string, ID of the invoice to confirm
|
||||||
|
Returns:
|
||||||
|
- void
|
||||||
|
Throws:
|
||||||
|
- std::runtime_error if the invoice ID is invalid
|
||||||
|
*/
|
||||||
|
void PaymentManagementService::confirmPayment(std::string invoiceID)
|
||||||
|
{
|
||||||
|
std::string title, message;
|
||||||
|
auto& currentInvoices = m_dataStore.getInvoices();
|
||||||
|
int invoiceIndex = currentInvoices.find(invoiceID);
|
||||||
|
if (invoiceIndex != -1)
|
||||||
|
{
|
||||||
|
Invoice* invoice = currentInvoices.getValueAt(invoiceIndex);
|
||||||
|
if (invoice && invoice->getStatus() != util::PaymentStatus::COMPLETED)
|
||||||
|
{
|
||||||
|
User* currentUser = invoice->getBooking()->getCustomer();
|
||||||
|
invoice->setPaymentDate(util::Timestamp());
|
||||||
|
invoice->setStatus(util::PaymentStatus::COMPLETED);
|
||||||
|
title = "Payment Confirmed";
|
||||||
|
message = "Payment Confirmed for Invoice ID " + invoiceID;
|
||||||
|
sendNotification(currentUser, title, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Payment failed: invalid invoice ID.");
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
@@ -28,6 +28,8 @@ public:
|
|||||||
void generateInvoice(ServiceBooking* booking);
|
void generateInvoice(ServiceBooking* booking);
|
||||||
util::Map<std::string, Invoice*> getInvoices(const std::string& customerID);
|
util::Map<std::string, Invoice*> getInvoices(const std::string& customerID);
|
||||||
void completePayment(const std::string& invoiceID, util::PaymentMode paymentMode);
|
void completePayment(const std::string& invoiceID, util::PaymentMode paymentMode);
|
||||||
|
util::Map<std::string, Invoice*>& getAllInvoice();
|
||||||
|
void confirmPayment(std::string invoiceID);
|
||||||
void sendPaymentReminders();
|
void sendPaymentReminders();
|
||||||
void sendNotification(User* user, const std::string& title, const std::string& message) override;
|
void sendNotification(User* user, const std::string& title, const std::string& message) override;
|
||||||
void attach(User* user) override;
|
void attach(User* user) override;
|
||||||
|
|||||||
+507
-83
@@ -12,17 +12,19 @@ Date:19-May-2026
|
|||||||
#include "ComboPackage.h"
|
#include "ComboPackage.h"
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "DataStore.h"
|
#include "DataStore.h"
|
||||||
|
#include "Enums.h"
|
||||||
#include "Factory.h"
|
#include "Factory.h"
|
||||||
#include "FileManager.h"
|
#include "FileManager.h"
|
||||||
#include "InventoryItem.h"
|
#include "InventoryItem.h"
|
||||||
#include "JobCard.h"
|
#include "JobCard.h"
|
||||||
|
#include "NotificationManagementService.h"
|
||||||
|
#include "PaymentManagementService.h"
|
||||||
#include "Service.h"
|
#include "Service.h"
|
||||||
#include "ServiceBooking.h"
|
#include "ServiceBooking.h"
|
||||||
#include "ServiceBooking.h"
|
|
||||||
|
|
||||||
#include "ServiceManagementService.h"
|
#include "ServiceManagementService.h"
|
||||||
#include "Timestamp.h"
|
#include "Timestamp.h"
|
||||||
#include "User.h"
|
#include "User.h"
|
||||||
|
#include "UserManagementService.h"
|
||||||
#include "Utility.h"
|
#include "Utility.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -58,7 +60,7 @@ void ServiceManagementService::purchaseService(const util::Vector<std::string>&
|
|||||||
Service* service = servicesMap.getValueAt(serviceIndex);
|
Service* service = servicesMap.getValueAt(serviceIndex);
|
||||||
selectedServices[service->getId()] = service;
|
selectedServices[service->getId()] = service;
|
||||||
}
|
}
|
||||||
ServiceBooking* serviceBooking = Factory::getObject<ServiceBooking>(util::ServiceJobStatus::STARTED, selectedServices, authenticatedUser->getId(), authenticatedUser, vehicleNumber, vehicleBrand, vehicleModel, 0);
|
ServiceBooking* serviceBooking = Factory::getObject<ServiceBooking>(util::ServiceJobStatus::PENDING, selectedServices, authenticatedUser->getId(), authenticatedUser, vehicleNumber, vehicleBrand, vehicleModel, 0);
|
||||||
if (serviceBooking == nullptr)
|
if (serviceBooking == nullptr)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Failed to create service booking");
|
throw std::runtime_error("Failed to create service booking");
|
||||||
@@ -97,7 +99,7 @@ void ServiceManagementService::purchaseComboPackage(const std::string& comboPack
|
|||||||
}
|
}
|
||||||
const ComboPackage* comboPackage = comboPackagesMap[comboPackageID];
|
const ComboPackage* comboPackage = comboPackagesMap[comboPackageID];
|
||||||
util::Map<std::string, Service*> selectedServices = comboPackage->getServices();
|
util::Map<std::string, Service*> selectedServices = comboPackage->getServices();
|
||||||
ServiceBooking* serviceBooking = Factory::getObject<ServiceBooking>(util::ServiceJobStatus::STARTED, selectedServices, authenticatedUser->getId(), authenticatedUser, vehicleNumber, vehicleBrand, vehicleModel, comboPackage->getDiscountPercentage());
|
ServiceBooking* serviceBooking = Factory::getObject<ServiceBooking>(util::ServiceJobStatus::PENDING, selectedServices, authenticatedUser->getId(), authenticatedUser, vehicleNumber, vehicleBrand, vehicleModel, comboPackage->getDiscountPercentage());
|
||||||
if (serviceBooking == nullptr)
|
if (serviceBooking == nullptr)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Failed to create combo package service booking");
|
throw std::runtime_error("Failed to create combo package service booking");
|
||||||
@@ -172,7 +174,7 @@ void ServiceManagementService::sendNotification(User* user, const std::string& t
|
|||||||
Factory::getObject<Notification>(
|
Factory::getObject<Notification>(
|
||||||
user->getId(),
|
user->getId(),
|
||||||
user,
|
user,
|
||||||
"ServiceManagementService: " + title,
|
title,
|
||||||
message,
|
message,
|
||||||
util::Timestamp()
|
util::Timestamp()
|
||||||
);
|
);
|
||||||
@@ -505,6 +507,89 @@ void ServiceManagementService::saveObservers()
|
|||||||
util::saveObservers(config::file::SERVICEMANAGEMENTOBSERVERS, this);
|
util::saveObservers(config::file::SERVICEMANAGEMENTOBSERVERS, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: restoreInventory
|
||||||
|
Description: Restores inventory quantities for all required items in the services associated
|
||||||
|
with a given booking. Each item's quantity is incremented by a fixed value.
|
||||||
|
Parameter: ServiceBooking* booking - Pointer to the booking whose inventory items need to be restored
|
||||||
|
Return type: void
|
||||||
|
*/
|
||||||
|
static void restoreInventory(ServiceBooking* booking)
|
||||||
|
{
|
||||||
|
const int INCREMENT_VALUE = 1;
|
||||||
|
if (!booking)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto& services = booking->getServices();
|
||||||
|
for (int serviceIterator = 0; serviceIterator < services.getSize(); ++serviceIterator)
|
||||||
|
{
|
||||||
|
Service* service = services.getValueAt(serviceIterator);
|
||||||
|
if (!service)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto& items = service->getRequiredInventoryItems();
|
||||||
|
for (int InventoryIterator = 0; InventoryIterator < items.getSize(); ++InventoryIterator)
|
||||||
|
{
|
||||||
|
InventoryItem* item = items.getValueAt(InventoryIterator);
|
||||||
|
if (item)
|
||||||
|
{
|
||||||
|
item->setQuantity(item->getQuantity() + INCREMENT_VALUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: processBookingCancellation
|
||||||
|
Description: Cancels jobs and updates the status of a given booking. Sends notifications to the
|
||||||
|
specified user, resets technician assignment if needed, and restores inventory items.
|
||||||
|
Parameter: ServiceBooking* booking - Pointer to the booking being cancelled
|
||||||
|
util::ServiceJobStatus newServiceBookingStatus - New status to assign to the booking
|
||||||
|
const std::string& notificationTitle - Title of the booking cancellation notification
|
||||||
|
const std::string& notificationMessage - Message body of the booking cancellation notification
|
||||||
|
User* notifyUser - User to notify about the cancellation
|
||||||
|
util::ServiceJobStatus jobCardStatus - New status to assign to associated job cards
|
||||||
|
const std::string& jobNotificationTitle - Title of the job cancellation notification
|
||||||
|
const std::string& jobNotificationMessage - Message body of the job cancellation notification
|
||||||
|
util::Map<std::string, JobCard*>& jobs - Collection of job cards to update
|
||||||
|
ServiceManagementService& currentService - Reference to the service for sending notifications
|
||||||
|
Return type: void
|
||||||
|
*/
|
||||||
|
static void processBookingCancellation(ServiceBooking* booking,
|
||||||
|
util::ServiceJobStatus newServiceBookingStatus,
|
||||||
|
const std::string& notificationTitle,
|
||||||
|
const std::string& notificationMessage,
|
||||||
|
User* notifyUser,
|
||||||
|
util::ServiceJobStatus jobCardStatus,
|
||||||
|
const std::string& jobNotificationTitle,
|
||||||
|
const std::string& jobNotificationMessage,
|
||||||
|
util::Map<std::string, JobCard*>& jobs, ServiceManagementService& currentService)
|
||||||
|
{
|
||||||
|
if (!booking || !notifyUser)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int jobIterator = 0; jobIterator < jobs.getSize(); ++jobIterator)
|
||||||
|
{
|
||||||
|
JobCard* jobCard = jobs.getValueAt(jobIterator);
|
||||||
|
if (jobCard && jobCard->getBookingId() == booking->getId())
|
||||||
|
{
|
||||||
|
jobCard->setStatus(jobCardStatus);
|
||||||
|
currentService.sendNotification(notifyUser, jobNotificationTitle, jobNotificationMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
booking->setStatus(newServiceBookingStatus);
|
||||||
|
currentService.sendNotification(notifyUser, notificationTitle, notificationMessage);
|
||||||
|
if (newServiceBookingStatus == util::ServiceJobStatus::PENDING)
|
||||||
|
{
|
||||||
|
booking->setAssignedTechnician(nullptr);
|
||||||
|
booking->setAssignedTechnicianId("");
|
||||||
|
}
|
||||||
|
restoreInventory(booking);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Function: cancelCustomerServiceBookings
|
Function: cancelCustomerServiceBookings
|
||||||
Description: Cancels all service bookings associated with a given customer or technician.
|
Description: Cancels all service bookings associated with a given customer or technician.
|
||||||
@@ -513,69 +598,47 @@ Description: Cancels all service bookings associated with a given customer or te
|
|||||||
Parameter: const std::string& userID - ID of the customer or technician
|
Parameter: const std::string& userID - ID of the customer or technician
|
||||||
Return type: void
|
Return type: void
|
||||||
*/
|
*/
|
||||||
void ServiceManagementService::cancelCustomerServiceBookings(const std::string& userID)
|
void ServiceManagementService::cancelCustomerServiceBookings(const std::string& customerID)
|
||||||
{
|
{
|
||||||
const int INCREMENT_VALUE = 1;
|
|
||||||
auto& users = m_dataStore.getUsers();
|
auto& users = m_dataStore.getUsers();
|
||||||
int userIndex = users.find(userID);
|
int userIndex = users.find(customerID);
|
||||||
if (userIndex == -1)
|
if (userIndex == -1)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("User not found: " + userID);
|
throw std::runtime_error("User not found: " + customerID);
|
||||||
}
|
}
|
||||||
User* user = users.getValueAt(userIndex);
|
User* customer = users.getValueAt(userIndex);
|
||||||
if (user == nullptr)
|
if (!customer)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("User not found: " + userID);
|
throw std::runtime_error("User not found: " + customerID);
|
||||||
}
|
}
|
||||||
util::UserType type = user->getUserType();
|
auto& bookings = m_dataStore.getServiceBookings();
|
||||||
auto& bookings = DataStore::getInstance().getServiceBookings();
|
auto& jobs = m_dataStore.getJobCards();
|
||||||
for (int bookingIterator = 0; bookingIterator < bookings.getSize(); bookingIterator++)
|
for (int iteratorOne = 0; iteratorOne < bookings.getSize(); iteratorOne++)
|
||||||
{
|
{
|
||||||
ServiceBooking* booking = bookings.getValueAt(bookingIterator);
|
ServiceBooking* booking = bookings.getValueAt(iteratorOne);
|
||||||
if (booking != nullptr &&
|
if (!booking)
|
||||||
(booking->getCustomerId() == userID || booking->getAssignedTechnicianId() == userID))
|
|
||||||
{
|
{
|
||||||
if (booking->getStatus() == util::ServiceJobStatus::PENDING ||
|
continue;
|
||||||
booking->getStatus() == util::ServiceJobStatus::STARTED)
|
|
||||||
{
|
|
||||||
if (type == util::UserType::CUSTOMER)
|
|
||||||
{
|
|
||||||
booking->setStatus(util::ServiceJobStatus::CANCELLED);
|
|
||||||
booking->setCustomer(nullptr);
|
|
||||||
booking->setCustomerId("");
|
|
||||||
User* assignedTechnician = booking->getAssignedTechnician();
|
|
||||||
std::string title = "Customer Service Cancelled";
|
|
||||||
std::string message = "The customer has cancelled their service booking. Your assigned job card has been cancelled and the inventory has been restocked.";
|
|
||||||
sendNotification(assignedTechnician, title, message);
|
|
||||||
}
|
|
||||||
else if (type == util::UserType::TECHNICIAN)
|
|
||||||
{
|
|
||||||
booking->setStatus(util::ServiceJobStatus::PENDING);
|
|
||||||
std::string title = "Technician Unavailable";
|
|
||||||
std::string message = "Your assigned technician is no longer available. Your booking has been reset to pending, and we will reassign a new technician shortly.";
|
|
||||||
sendNotification(booking->getCustomer(), title, message);
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (booking->getCustomerId() != customerID)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (booking->getStatus() != util::ServiceJobStatus::PENDING && booking->getStatus() != util::ServiceJobStatus::STARTED)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
User* assignedTechnician = booking->getAssignedTechnician();
|
||||||
|
std::string titleToTechnician = "Customer Service Cancelled";
|
||||||
|
std::string messageToTechnician = "The customer has cancelled their service booking. Your assigned job card has been cancelled and the inventory has been restocked.";
|
||||||
|
std::string jobTitle = "Job Cancelled";
|
||||||
|
std::string jobMessage = "The job has been cancelled. Your job card has been cancelled and the inventory has been restocked.";
|
||||||
|
processBookingCancellation(booking,
|
||||||
|
util::ServiceJobStatus::CANCELLED,
|
||||||
|
titleToTechnician, messageToTechnician, assignedTechnician,
|
||||||
|
util::ServiceJobStatus::CANCELLED,
|
||||||
|
jobTitle, jobMessage, jobs, *this
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -588,34 +651,48 @@ Return type: void
|
|||||||
*/
|
*/
|
||||||
void ServiceManagementService::cancelTechnicianJobs(const std::string& technicianID)
|
void ServiceManagementService::cancelTechnicianJobs(const std::string& technicianID)
|
||||||
{
|
{
|
||||||
const int INCREMENT_VALUE = 1;
|
auto& users = m_dataStore.getUsers();
|
||||||
auto& jobs = m_dataStore.getJobCards();
|
int userIndex = users.find(technicianID);
|
||||||
for (int jobIterator = 0; jobIterator < jobs.getSize(); jobIterator++)
|
if (userIndex == -1)
|
||||||
{
|
{
|
||||||
JobCard* job = jobs.getValueAt(jobIterator);
|
throw std::runtime_error("User not found: " + technicianID);
|
||||||
if (job != nullptr && job->getTechnicianId() == technicianID)
|
}
|
||||||
|
User* technician = users.getValueAt(userIndex);
|
||||||
|
if (!technician)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("User not found: " + technicianID);
|
||||||
|
}
|
||||||
|
auto& bookings = m_dataStore.getServiceBookings();
|
||||||
|
auto& jobs = m_dataStore.getJobCards();
|
||||||
|
for (int iteratorOne = 0; iteratorOne < bookings.getSize(); iteratorOne++)
|
||||||
|
{
|
||||||
|
ServiceBooking* booking = bookings.getValueAt(iteratorOne);
|
||||||
|
if (!booking)
|
||||||
{
|
{
|
||||||
if (job->getStatus() == util::ServiceJobStatus::PENDING || job->getStatus() == util::ServiceJobStatus::STARTED)
|
continue;
|
||||||
{
|
|
||||||
job->setStatus(util::ServiceJobStatus::CANCELLED);
|
|
||||||
std::string title = "Job Cancelled";
|
|
||||||
std::string message = "The Job has cancelled. Your job card has been cancelled and the inventory has been restocked.";
|
|
||||||
sendNotification(job->getTechnician(), title, message);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
std::string technicianId = booking->getAssignedTechnicianId();
|
||||||
|
if (technicianId != technicianID)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (booking->getStatus() != util::ServiceJobStatus::PENDING && booking->getStatus() != util::ServiceJobStatus::STARTED)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
User* customer = booking->getCustomer();
|
||||||
|
if (!customer)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
std::string title = "Technician Unavailable";
|
||||||
|
std::string message = "Your assigned technician is no longer available. Your booking has been reset to pending and we will reassign a new technician shortly.";
|
||||||
|
processBookingCancellation(booking,
|
||||||
|
util::ServiceJobStatus::PENDING,
|
||||||
|
title, message, customer,
|
||||||
|
util::ServiceJobStatus::CANCELLED,
|
||||||
|
title, message, jobs, *this
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -725,3 +802,350 @@ void ServiceManagementService::removeComboPackage(const std::string& comboPackag
|
|||||||
throw std::runtime_error("Combo package with ID '" + comboPackageID + "' not found.");
|
throw std::runtime_error("Combo package with ID '" + comboPackageID + "' not found.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: getServiceBookings
|
||||||
|
Description: Retrieves all service bookings from the datastore.
|
||||||
|
Parameters:
|
||||||
|
- None
|
||||||
|
Returns:
|
||||||
|
- util::Map<std::string, ServiceBooking*> containing all service bookings
|
||||||
|
*/
|
||||||
|
util::Map<std::string, ServiceBooking*> ServiceManagementService::getServiceBookings()
|
||||||
|
{
|
||||||
|
return m_dataStore.getServiceBookings();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: getServiceBooking
|
||||||
|
Description: Retrieves a specific service booking by its ID.
|
||||||
|
Parameters:
|
||||||
|
- serviceID: std::string, ID of the service booking
|
||||||
|
Returns:
|
||||||
|
- ServiceBooking*: Pointer to the service booking, or nullptr if not found
|
||||||
|
*/
|
||||||
|
ServiceBooking* ServiceManagementService::getServiceBooking(const std::string& serviceID)
|
||||||
|
{
|
||||||
|
auto currentServiceBookings = getServiceBookings();
|
||||||
|
for (int iterator = 0; iterator < currentServiceBookings.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
if (currentServiceBookings.getValueAt(iterator)->getId() == serviceID)
|
||||||
|
{
|
||||||
|
return currentServiceBookings.getValueAt(iterator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: createJobCard
|
||||||
|
Description: Creates a job card for a given service booking, service, and technician.
|
||||||
|
Validates booking, service, technician, and inventory availability before creation.
|
||||||
|
Parameters:
|
||||||
|
- bookingID: std::string, ID of the service booking
|
||||||
|
- technicianID: std::string, ID of the technician
|
||||||
|
- serviceID: std::string, ID of the service
|
||||||
|
Returns:
|
||||||
|
- void
|
||||||
|
Throws:
|
||||||
|
- std::runtime_error if booking, service, technician, or inventory validation fails
|
||||||
|
*/
|
||||||
|
void ServiceManagementService::createJobCard(const std::string& bookingID, const std::string& technicianID, const std::string& serviceID)
|
||||||
|
{
|
||||||
|
UserManagementService m_userManagementService;
|
||||||
|
ServiceBooking* currentBooking = getServiceBooking(bookingID);
|
||||||
|
auto& currentJobCards = m_dataStore.getJobCards();
|
||||||
|
if (currentBooking == nullptr)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Service Booking not available");
|
||||||
|
}
|
||||||
|
auto& currentServices = currentBooking->getServices();
|
||||||
|
if (currentServices.find(serviceID) == -1)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Invalid service Id");
|
||||||
|
}
|
||||||
|
Service* currentService = currentServices.getValueAt(currentServices.find(serviceID));
|
||||||
|
User* selectedTechnician = m_userManagementService.getUser(technicianID);
|
||||||
|
if (selectedTechnician == nullptr)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Technician not available");
|
||||||
|
}
|
||||||
|
auto& inventoryItems = currentService->getRequiredInventoryItems();
|
||||||
|
for (int iterator = 0; iterator < inventoryItems.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
InventoryItem* currentInventoryItem = inventoryItems.getValueAt(iterator);
|
||||||
|
if (currentInventoryItem && currentInventoryItem->getQuantity() == 0)
|
||||||
|
{
|
||||||
|
std::string errorMessage = "Failed to create job card, " + currentInventoryItem->getPartName() + " is out of stock.";
|
||||||
|
throw std::runtime_error(errorMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int iterator = 0; iterator < inventoryItems.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
InventoryItem* currentInventoryItem = inventoryItems.getValueAt(iterator);
|
||||||
|
if (currentInventoryItem)
|
||||||
|
{
|
||||||
|
int currentStockQuantity = currentInventoryItem->getQuantity();
|
||||||
|
currentInventoryItem->setQuantity(currentStockQuantity - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currentBooking->setAssignedTechnician(selectedTechnician);
|
||||||
|
currentBooking->setAssignedTechnicianId(selectedTechnician->getId());
|
||||||
|
if (currentBooking->getStatus() == util::ServiceJobStatus::PENDING)
|
||||||
|
{
|
||||||
|
currentBooking->setStatus(util::ServiceJobStatus::STARTED);
|
||||||
|
}
|
||||||
|
std::string title = "Job card created";
|
||||||
|
std::string message = "Job card created for the service and you are assigned for that.";
|
||||||
|
JobCard* jobCard = Factory::getObject<JobCard>(bookingID, currentBooking, currentService, serviceID, technicianID, selectedTechnician, util::Timestamp(), util::ServiceJobStatus::STARTED, util::Timestamp());
|
||||||
|
if (jobCard)
|
||||||
|
{
|
||||||
|
currentJobCards.insert(jobCard->getId(), jobCard);
|
||||||
|
sendNotification(selectedTechnician, title, message);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Failed to create job card.");
|
||||||
|
}
|
||||||
|
title = "Technician assigned";
|
||||||
|
message = "A technician has been assigned to your Service Booking with ID " + bookingID;
|
||||||
|
sendNotification(currentBooking->getCustomer(), title, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: createService
|
||||||
|
Description: Creates a new service with associated inventory items and labor cost.
|
||||||
|
Validates inventory items before creation.
|
||||||
|
Parameters:
|
||||||
|
- name: std::string, name of the service
|
||||||
|
- inventoryItemIDs: util::Vector<std::string>, IDs of required inventory items
|
||||||
|
- laborCost: double, labor cost for the service
|
||||||
|
Returns:
|
||||||
|
- void
|
||||||
|
Throws:
|
||||||
|
- std::runtime_error if inventory items are not found or service creation fails
|
||||||
|
*/
|
||||||
|
void ServiceManagementService::createService(const std::string& name, const util::Vector<std::string>& inventoryItemIDs, double laborCost)
|
||||||
|
{
|
||||||
|
util::Map<std::string, InventoryItem*> currentServiceInventoryItems;
|
||||||
|
auto inventoryItems = m_dataStore.getInventoryItems();
|
||||||
|
for (int iteratorOne =0; iteratorOne < inventoryItemIDs.getSize(); iteratorOne++)
|
||||||
|
{
|
||||||
|
std::string currentItemID = inventoryItemIDs[iteratorOne];
|
||||||
|
bool itemFound = false;
|
||||||
|
for (int iteratorTwo = 0; iteratorTwo < inventoryItems.getSize(); iteratorTwo++)
|
||||||
|
{
|
||||||
|
InventoryItem* currentInventoryItem = inventoryItems.getValueAt(iteratorTwo);
|
||||||
|
if (currentInventoryItem && currentInventoryItem->getId() == currentItemID)
|
||||||
|
{
|
||||||
|
itemFound = true;
|
||||||
|
currentServiceInventoryItems.insert(currentInventoryItem->getId(), currentInventoryItem);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!itemFound)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Inventory item with ID '" + currentItemID + "' not found.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Service* newService = Factory::getObject<Service>(name, currentServiceInventoryItems, laborCost);
|
||||||
|
if (newService == nullptr)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Unable to create new service.");
|
||||||
|
}
|
||||||
|
util::Map<std::string, Service*>& currentServices = m_dataStore.getServices();
|
||||||
|
if (currentServices.find(newService->getId()) != -1)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Service with this ID Already exists.");
|
||||||
|
}
|
||||||
|
currentServices.insert(newService->getId(), newService);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: getServices
|
||||||
|
Description: Retrieves all services from the datastore.
|
||||||
|
Parameters:
|
||||||
|
- None
|
||||||
|
Returns:
|
||||||
|
- util::Map<std::string, Service*> containing all services
|
||||||
|
*/
|
||||||
|
util::Map<std::string, Service*> ServiceManagementService::getServices()
|
||||||
|
{
|
||||||
|
return m_dataStore.getServices();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: removeService
|
||||||
|
Description: Marks a service as inactive by its ID.
|
||||||
|
Parameters:
|
||||||
|
- serviceID: std::string, ID of the service
|
||||||
|
Returns:
|
||||||
|
- void
|
||||||
|
Throws:
|
||||||
|
- std::runtime_error if the service is not found
|
||||||
|
*/
|
||||||
|
void ServiceManagementService::removeService(const std::string& serviceID)
|
||||||
|
{
|
||||||
|
util::Map<std::string, Service*>& currentServices = m_dataStore.getServices();
|
||||||
|
util::Map<std::string, ComboPackage*>& currentComboPackages = m_dataStore.getComboPackages();
|
||||||
|
if (currentServices.find(serviceID) != -1)
|
||||||
|
{
|
||||||
|
currentServices.getValueAt(currentServices.find(serviceID))->setState(util::State::INACTIVE);
|
||||||
|
for (int iterator = 0; iterator < currentComboPackages.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
ComboPackage* currentComboPackage = currentComboPackages.getValueAt(iterator);
|
||||||
|
if (currentComboPackage && currentComboPackage->getState() == util::State::ACTIVE)
|
||||||
|
{
|
||||||
|
util::Map<std::string, Service*> currentServices = currentComboPackage->getServices();
|
||||||
|
for (int iterator = 0; iterator < currentServices.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
auto currentService = currentServices.getValueAt(iterator);
|
||||||
|
if (currentService->getId() == serviceID)
|
||||||
|
{
|
||||||
|
currentComboPackage->setState(util::State::INACTIVE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Service not found.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: getServiceBookings (overloaded)
|
||||||
|
Description: Retrieves all service bookings for a specific customer.
|
||||||
|
Parameters:
|
||||||
|
- customerID: std::string, ID of the customer
|
||||||
|
Returns:
|
||||||
|
- util::Map<std::string, ServiceBooking*> containing bookings for the customer
|
||||||
|
*/
|
||||||
|
util::Map<std::string, ServiceBooking*> ServiceManagementService::getServiceBookings(const std::string& customerID)
|
||||||
|
{
|
||||||
|
util::Map<std::string, ServiceBooking*> currentServiceBookings = getServiceBookings();
|
||||||
|
util::Map<std::string, ServiceBooking*> currentUserServiceBookings;
|
||||||
|
if (currentServiceBookings.getSize() != 0)
|
||||||
|
{
|
||||||
|
for (int iterator = 0; iterator < currentServiceBookings.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
auto currentServiceBooking = currentServiceBookings.getValueAt(iterator);
|
||||||
|
if (currentServiceBooking->getCustomerId() == customerID)
|
||||||
|
{
|
||||||
|
currentUserServiceBookings.insert(currentServiceBooking->getId(), currentServiceBooking);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return currentUserServiceBookings;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: getJobCards
|
||||||
|
Description: Retrieves all job cards assigned to a specific technician.
|
||||||
|
Parameters:
|
||||||
|
- technicianID: std::string, ID of the technician
|
||||||
|
Returns:
|
||||||
|
- util::Map<std::string, JobCard*> containing job cards assigned to the technician
|
||||||
|
*/
|
||||||
|
util::Map<std::string, JobCard*> ServiceManagementService::getJobCards(const std::string& technicianID)
|
||||||
|
{
|
||||||
|
util::Map<std::string, JobCard*> jobCards = m_dataStore.getJobCards();
|
||||||
|
util::Map<std::string, JobCard*> technicianJobCards;
|
||||||
|
for (int iterator = 0; iterator < jobCards.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
JobCard* currentJobCard = jobCards.getValueAt(iterator);
|
||||||
|
if (currentJobCard->getTechnicianId() == technicianID)
|
||||||
|
{
|
||||||
|
technicianJobCards.insert(currentJobCard->getId(), currentJobCard);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return technicianJobCards;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: hasCompletedAllJobs (static helper)
|
||||||
|
Description: Checks if all job cards for a given service booking are completed.
|
||||||
|
Parameters:
|
||||||
|
- bookingId: std::string, ID of the service booking
|
||||||
|
- currentAssignedJobs: util::Map<std::string, JobCard*>&, map of assigned job cards
|
||||||
|
Returns:
|
||||||
|
- bool: True if all job cards are completed, False otherwise
|
||||||
|
*/
|
||||||
|
static bool hasCompletedAllJobs(std::string bookingId, util::Map<std::string, JobCard*>& currentAssignedJobs)
|
||||||
|
{
|
||||||
|
for (int iterator = 0; iterator < currentAssignedJobs.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
JobCard* currentJob = currentAssignedJobs.getValueAt(iterator);
|
||||||
|
if (currentJob->getBookingId() == bookingId)
|
||||||
|
{
|
||||||
|
if (currentJob->getStatus() == util::ServiceJobStatus::STARTED)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: completeJob
|
||||||
|
Description: Marks a job card as completed for the authenticated technician.
|
||||||
|
If all job cards in the booking are completed, marks the booking as completed
|
||||||
|
and generates an invoice.
|
||||||
|
Parameters:
|
||||||
|
- jobID: std::string, ID of the job card
|
||||||
|
Returns:
|
||||||
|
- void
|
||||||
|
Throws:
|
||||||
|
- std::runtime_error if technician is not authenticated, job card not found, or job already completed
|
||||||
|
*/
|
||||||
|
void ServiceManagementService::completeJob(const std::string& jobID)
|
||||||
|
{
|
||||||
|
AuthenticationManagementService authenticationManagementService;
|
||||||
|
PaymentManagementService paymentManagementService;
|
||||||
|
bool jobStatusUpdated = false, serviceBookingCompleted;
|
||||||
|
JobCard* currentJob;
|
||||||
|
User* currentTechnician = authenticationManagementService.getAuthenticatedUser();
|
||||||
|
if (currentTechnician == nullptr)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Unable to fetch current technician.");
|
||||||
|
}
|
||||||
|
util::Map<std::string, JobCard*> currentAssignedJobs = getJobCards(currentTechnician->getId());
|
||||||
|
if (currentAssignedJobs.getSize() == 0)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("No job cards assigned to the technician.");
|
||||||
|
}
|
||||||
|
if (currentAssignedJobs.find(jobID) != -1)
|
||||||
|
{
|
||||||
|
currentJob = currentAssignedJobs.getValueAt(currentAssignedJobs.find(jobID));
|
||||||
|
if (currentJob == nullptr)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Unable to fetch current job.");
|
||||||
|
}
|
||||||
|
if (currentJob->getStatus() == util::ServiceJobStatus::STARTED)
|
||||||
|
{
|
||||||
|
currentJob->setStatus(util::ServiceJobStatus::COMPLETED);
|
||||||
|
jobStatusUpdated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Failed to complete the job, some error occurred or job already completed.");
|
||||||
|
}
|
||||||
|
if (!jobStatusUpdated)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Failed to complete the job, some error occurred or job already completed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
serviceBookingCompleted = hasCompletedAllJobs(currentJob->getBookingId(), currentAssignedJobs);
|
||||||
|
if (serviceBookingCompleted)
|
||||||
|
{
|
||||||
|
currentJob->getBooking()->setStatus(util::ServiceJobStatus::COMPLETED);
|
||||||
|
paymentManagementService.generateInvoice(currentJob->getBooking());
|
||||||
|
std::string title = "Service Booking completed. Invoice Generated.";
|
||||||
|
std::string message = "Services completed for the booking and invoice generated.";
|
||||||
|
sendNotification(currentJob->getBooking()->getCustomer(), title, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
@@ -32,6 +32,7 @@ public:
|
|||||||
void purchaseComboPackage(const std::string& comboPackageID, const std::string& vehicleNumber, const std::string& vehicleBrand, const std::string& vehicleModel);
|
void purchaseComboPackage(const std::string& comboPackageID, const std::string& vehicleNumber, const std::string& vehicleBrand, const std::string& vehicleModel);
|
||||||
util::Map<std::string, ServiceBooking*> getServiceBookings();
|
util::Map<std::string, ServiceBooking*> getServiceBookings();
|
||||||
util::Map<std::string, ServiceBooking*> getServiceBookings(const std::string& customerID);
|
util::Map<std::string, ServiceBooking*> getServiceBookings(const std::string& customerID);
|
||||||
|
ServiceBooking* getServiceBooking(const std::string& serviceID);
|
||||||
void createJobCard(const std::string& bookingID, const std::string& technicianID, const std::string& serviceID);
|
void createJobCard(const std::string& bookingID, const std::string& technicianID, const std::string& serviceID);
|
||||||
void createService(const std::string& name, const util::Vector<std::string>& inventoryItemIDs, double laborCost);
|
void createService(const std::string& name, const util::Vector<std::string>& inventoryItemIDs, double laborCost);
|
||||||
void removeService(const std::string& serviceID);
|
void removeService(const std::string& serviceID);
|
||||||
|
|||||||
+56
-10
@@ -6,6 +6,8 @@ Description: Implementation file containing the method definitions of the
|
|||||||
Author: Trenser
|
Author: Trenser
|
||||||
Date:19-May-2026
|
Date:19-May-2026
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "Enums.h"
|
#include "Enums.h"
|
||||||
#include "Factory.h"
|
#include "Factory.h"
|
||||||
@@ -17,8 +19,7 @@ Date:19-May-2026
|
|||||||
#include "User.h"
|
#include "User.h"
|
||||||
#include "UserManagementService.h"
|
#include "UserManagementService.h"
|
||||||
#include "Vector.h"
|
#include "Vector.h"
|
||||||
#include <stdexcept>
|
#include "Validator.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Function: ensureAdminExists
|
Function: ensureAdminExists
|
||||||
@@ -73,16 +74,18 @@ void UserManagementService::createUser(const std::string& username, const std::s
|
|||||||
PaymentManagementService paymentManagementService;
|
PaymentManagementService paymentManagementService;
|
||||||
ServiceManagementService serviceManagementService;
|
ServiceManagementService serviceManagementService;
|
||||||
auto& usersMap = m_dataStore.getUsers();
|
auto& usersMap = m_dataStore.getUsers();
|
||||||
int index = usersMap.findIf(
|
if (util::isUsernameDuplicate(username, usersMap))
|
||||||
[&](const std::string&, User* user)
|
|
||||||
{
|
|
||||||
return user->getUserName() == username;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
if (index != -1)
|
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Username already exists");
|
throw std::runtime_error("Username already exists");
|
||||||
}
|
}
|
||||||
|
if (util::isEmailDuplicate(email, usersMap))
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Email already exists");
|
||||||
|
}
|
||||||
|
if (util::isPhoneDuplicate(phone, usersMap))
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Phone already exists");
|
||||||
|
}
|
||||||
User* newUser = Factory::getObject<User>(username, password, name, phone, email, type);
|
User* newUser = Factory::getObject<User>(username, password, name, phone, email, type);
|
||||||
usersMap.insert(newUser->getId(), newUser);
|
usersMap.insert(newUser->getId(), newUser);
|
||||||
paymentManagementService.attach(newUser);
|
paymentManagementService.attach(newUser);
|
||||||
@@ -108,9 +111,23 @@ void UserManagementService::updateUserDetails(const std::string& userID, const s
|
|||||||
int index = usersMap.find(userID);
|
int index = usersMap.find(userID);
|
||||||
if (index == -1)
|
if (index == -1)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("User does not exist!");
|
throw std::runtime_error("User does not exist!\n");
|
||||||
}
|
}
|
||||||
User* user = usersMap.getValueAt(index);
|
User* user = usersMap.getValueAt(index);
|
||||||
|
if (email != user->getEmail())
|
||||||
|
{
|
||||||
|
if (util::isEmailDuplicate(email, usersMap))
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Email already exists!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (phone != user->getPhone())
|
||||||
|
{
|
||||||
|
if (util::isPhoneDuplicate(phone, usersMap))
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Phone number already exists!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
user->setEmail(email);
|
user->setEmail(email);
|
||||||
user->setPhone(phone);
|
user->setPhone(phone);
|
||||||
}
|
}
|
||||||
@@ -280,13 +297,42 @@ Return type: void
|
|||||||
*/
|
*/
|
||||||
void UserManagementService::removeUser(const std::string& userID)
|
void UserManagementService::removeUser(const std::string& userID)
|
||||||
{
|
{
|
||||||
|
InventoryManagementService inventoryManagementService;
|
||||||
|
PaymentManagementService paymentManagementService;
|
||||||
|
ServiceManagementService serviceManagementService;
|
||||||
int index = m_dataStore.getUsers().find(userID);
|
int index = m_dataStore.getUsers().find(userID);
|
||||||
if (index != -1)
|
if (index != -1)
|
||||||
{
|
{
|
||||||
User* user = m_dataStore.getUsers().getValueAt(index);
|
User* user = m_dataStore.getUsers().getValueAt(index);
|
||||||
if (user != nullptr)
|
if (user != nullptr)
|
||||||
{
|
{
|
||||||
|
if (user->getUserType() == util::UserType::CUSTOMER)
|
||||||
|
{
|
||||||
|
serviceManagementService.cancelCustomerServiceBookings(userID);
|
||||||
|
}
|
||||||
|
if (user->getUserType() == util::UserType::TECHNICIAN)
|
||||||
|
{
|
||||||
|
serviceManagementService.cancelTechnicianJobs(userID);
|
||||||
|
}
|
||||||
user->setState(util::State::INACTIVE);
|
user->setState(util::State::INACTIVE);
|
||||||
|
inventoryManagementService.detach(user);
|
||||||
|
paymentManagementService.detach(user);
|
||||||
|
serviceManagementService.detach(user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
util::Map<std::string, User*> UserManagementService::getUsers(util::UserType type)
|
||||||
|
{
|
||||||
|
util::Map<std::string, User*>& currentUsers = m_dataStore.getUsers();
|
||||||
|
util::Map<std::string, User*> filteredUsersMap;
|
||||||
|
for (int iterator = 0; iterator < currentUsers.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
User* currentUser = currentUsers.getValueAt(iterator);
|
||||||
|
if (currentUser && currentUser->getState() == util::State::ACTIVE && currentUser->getUserType() == type)
|
||||||
|
{
|
||||||
|
filteredUsersMap.insert(currentUser->getId(), currentUser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filteredUsersMap;
|
||||||
|
}
|
||||||
@@ -15,7 +15,7 @@ namespace config
|
|||||||
{
|
{
|
||||||
constexpr const char* DEFAULT_ADMIN_USERNAME = "admin";
|
constexpr const char* DEFAULT_ADMIN_USERNAME = "admin";
|
||||||
constexpr const char* DEFAULT_ADMIN_NAME = "admin";
|
constexpr const char* DEFAULT_ADMIN_NAME = "admin";
|
||||||
constexpr const char* DEFAULT_ADMIN_PASSWORD = "";
|
constexpr const char* DEFAULT_ADMIN_PASSWORD = "admin";
|
||||||
constexpr const char* DEFAULT_ADMIN_EMAIL = "admin@vss";
|
constexpr const char* DEFAULT_ADMIN_EMAIL = "admin@vss";
|
||||||
constexpr const char* DEFAULT_ADMIN_PHONE = "0000000000";
|
constexpr const char* DEFAULT_ADMIN_PHONE = "0000000000";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,13 +22,15 @@ namespace util
|
|||||||
enum class PaymentMode
|
enum class PaymentMode
|
||||||
{
|
{
|
||||||
ONLINE,
|
ONLINE,
|
||||||
OFFLINE
|
OFFLINE,
|
||||||
|
NOTSET
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class PaymentStatus
|
enum class PaymentStatus
|
||||||
{
|
{
|
||||||
PENDING,
|
PENDING,
|
||||||
COMPLETED
|
COMPLETED,
|
||||||
|
PAID
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class ServiceJobStatus
|
enum class ServiceJobStatus
|
||||||
@@ -110,6 +112,8 @@ namespace util
|
|||||||
return "ONLINE";
|
return "ONLINE";
|
||||||
case PaymentMode::OFFLINE:
|
case PaymentMode::OFFLINE:
|
||||||
return "OFFLINE";
|
return "OFFLINE";
|
||||||
|
case PaymentMode::NOTSET:
|
||||||
|
return "NOTSET";
|
||||||
}
|
}
|
||||||
throw std::invalid_argument("Invalid PaymentMode");
|
throw std::invalid_argument("Invalid PaymentMode");
|
||||||
}
|
}
|
||||||
@@ -134,6 +138,10 @@ namespace util
|
|||||||
{
|
{
|
||||||
return PaymentMode::OFFLINE;
|
return PaymentMode::OFFLINE;
|
||||||
}
|
}
|
||||||
|
if (value == "NOTSET")
|
||||||
|
{
|
||||||
|
return PaymentMode::NOTSET;
|
||||||
|
}
|
||||||
throw std::invalid_argument("Invalid PaymentMode string");
|
throw std::invalid_argument("Invalid PaymentMode string");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,6 +161,8 @@ namespace util
|
|||||||
return "PENDING";
|
return "PENDING";
|
||||||
case PaymentStatus::COMPLETED:
|
case PaymentStatus::COMPLETED:
|
||||||
return "COMPLETED";
|
return "COMPLETED";
|
||||||
|
case PaymentStatus::PAID:
|
||||||
|
return "PAID";
|
||||||
}
|
}
|
||||||
throw std::invalid_argument("Invalid PaymentStatus");
|
throw std::invalid_argument("Invalid PaymentStatus");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,10 +11,39 @@ Date: 22-May-2026
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <direct.h>
|
||||||
#include "Vector.h"
|
#include "Vector.h"
|
||||||
|
|
||||||
namespace util
|
namespace util
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
Function: ensureDirectoryExists
|
||||||
|
Description: Creates all missing directories present in the given file path.
|
||||||
|
Iteratively parses the path and creates each directory level
|
||||||
|
using _mkdir() before file operations are performed.
|
||||||
|
Parameters:
|
||||||
|
- filePath: const std::string&, relative or absolute file path
|
||||||
|
Returns:
|
||||||
|
- void
|
||||||
|
Throws:
|
||||||
|
- None (_mkdir failures are intentionally ignored if directory already exists)
|
||||||
|
*/
|
||||||
|
inline void ensureDirectoryExists(const std::string& filePath)
|
||||||
|
{
|
||||||
|
size_t position = 0;
|
||||||
|
|
||||||
|
while ((position = filePath.find('/', position)) != std::string::npos)
|
||||||
|
{
|
||||||
|
std::string directory = filePath.substr(0, position);
|
||||||
|
|
||||||
|
if (!directory.empty())
|
||||||
|
{
|
||||||
|
(void)_mkdir(directory.c_str());
|
||||||
|
}
|
||||||
|
position++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Function: loadRecords
|
Function: loadRecords
|
||||||
Description: Loads records from a given file path into a vector of strings.
|
Description: Loads records from a given file path into a vector of strings.
|
||||||
@@ -32,6 +61,7 @@ namespace util
|
|||||||
std::ifstream file(filePath);
|
std::ifstream file(filePath);
|
||||||
if (!file.is_open())
|
if (!file.is_open())
|
||||||
{
|
{
|
||||||
|
ensureDirectoryExists(filePath);
|
||||||
std::ofstream newFile(filePath);
|
std::ofstream newFile(filePath);
|
||||||
newFile.close();
|
newFile.close();
|
||||||
file.open(filePath);
|
file.open(filePath);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ Date: 22-May-2026
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include "Vector.h"
|
#include "Vector.h"
|
||||||
#include "Map.h"
|
#include "Map.h"
|
||||||
|
#include "FileHelper.h"
|
||||||
|
|
||||||
namespace util
|
namespace util
|
||||||
{
|
{
|
||||||
@@ -51,6 +52,7 @@ namespace util
|
|||||||
std::ifstream file(m_filePath);
|
std::ifstream file(m_filePath);
|
||||||
if (!file.is_open())
|
if (!file.is_open())
|
||||||
{
|
{
|
||||||
|
ensureDirectoryExists(m_filePath);
|
||||||
std::ofstream newFile(m_filePath);
|
std::ofstream newFile(m_filePath);
|
||||||
newFile.close();
|
newFile.close();
|
||||||
file.open(m_filePath);
|
file.open(m_filePath);
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ namespace util
|
|||||||
*/
|
*/
|
||||||
inline void pressEnter()
|
inline void pressEnter()
|
||||||
{
|
{
|
||||||
|
std::cout << std::endl;
|
||||||
system("pause");
|
system("pause");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -21,4 +21,28 @@ namespace util
|
|||||||
{
|
{
|
||||||
std::cout << "\x1B[2J\x1B[H" << std::flush;
|
std::cout << "\x1B[2J\x1B[H" << std::flush;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: truncateString
|
||||||
|
Description:
|
||||||
|
Truncates a string if its length exceeds the given maximum length.
|
||||||
|
The truncated string ends with "..." to indicate omitted characters.
|
||||||
|
Parameters:
|
||||||
|
- text: const std::string&, input string to truncate
|
||||||
|
- maxLength: size_t, maximum allowed length of the returned string
|
||||||
|
Returns:
|
||||||
|
- std::string: Original string if within limit, otherwise truncated string with "..."
|
||||||
|
*/
|
||||||
|
inline std::string truncateString(const std::string& text, size_t maxLength)
|
||||||
|
{
|
||||||
|
if (text.length() <= maxLength)
|
||||||
|
{
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
if (maxLength <= 3)
|
||||||
|
{
|
||||||
|
return std::string(maxLength, '.');
|
||||||
|
}
|
||||||
|
return text.substr(0, maxLength - 3) + "...";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,6 @@ Date:19-May-2026
|
|||||||
#include "DataStore.h"
|
#include "DataStore.h"
|
||||||
#include "FileHelper.h"
|
#include "FileHelper.h"
|
||||||
#include "InventoryItem.h"
|
#include "InventoryItem.h"
|
||||||
#include "InventoryItem.h"
|
|
||||||
#include "NotificationManagementService.h"
|
#include "NotificationManagementService.h"
|
||||||
#include "Service.h"
|
#include "Service.h"
|
||||||
|
|
||||||
|
|||||||
@@ -107,3 +107,69 @@ bool util::isPasswordValid(const std::string& password)
|
|||||||
|
|
||||||
return hasUpper && hasLower && hasDigit && hasSpecial;
|
return hasUpper && hasLower && hasDigit && hasSpecial;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function: isUsernameDuplicate
|
||||||
|
* Description: Checks if the given username already exists among active users.
|
||||||
|
* Parameters:
|
||||||
|
* username - string containing the username to validate
|
||||||
|
* usersMap - map of user objects keyed by identifier
|
||||||
|
* Returns:
|
||||||
|
* bool - true if the username is already in use by an active user, false otherwise
|
||||||
|
* Notes:
|
||||||
|
* - Only considers users with state util::State::ACTIVE
|
||||||
|
*/
|
||||||
|
bool util::isUsernameDuplicate(const std::string& username, const util::Map<std::string, User*>& usersMap)
|
||||||
|
{
|
||||||
|
int index = usersMap.findIf(
|
||||||
|
[&](const std::string&, User* user)
|
||||||
|
{
|
||||||
|
return (user->getUserName() == username && user->getState() == util::State::ACTIVE);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return index != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function: isPhoneDuplicate
|
||||||
|
* Description: Checks if the given phone number already exists among active users.
|
||||||
|
* Parameters:
|
||||||
|
* phone - string containing the phone number to validate
|
||||||
|
* usersMap - map of user objects keyed by identifier
|
||||||
|
* Returns:
|
||||||
|
* bool - true if the phone number is already in use by an active user, false otherwise
|
||||||
|
* Notes:
|
||||||
|
* - Only considers users with state util::State::ACTIVE
|
||||||
|
*/
|
||||||
|
bool util::isPhoneDuplicate(const std::string& phone, const util::Map<std::string, User*>& usersMap)
|
||||||
|
{
|
||||||
|
int index = usersMap.findIf(
|
||||||
|
[&](const std::string&, User* user)
|
||||||
|
{
|
||||||
|
return (user->getPhone() == phone && user->getState() == util::State::ACTIVE);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return index != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function: isEmailDuplicate
|
||||||
|
* Description: Checks if the given email address already exists among active users.
|
||||||
|
* Parameters:
|
||||||
|
* email - string containing the email address to validate
|
||||||
|
* usersMap - map of user objects keyed by identifier
|
||||||
|
* Returns:
|
||||||
|
* bool - true if the email address is already in use by an active user, false otherwise
|
||||||
|
* Notes:
|
||||||
|
* - Only considers users with state util::State::ACTIVE
|
||||||
|
*/
|
||||||
|
bool util::isEmailDuplicate(const std::string& email, const util::Map<std::string, User*>& usersMap)
|
||||||
|
{
|
||||||
|
int index = usersMap.findIf(
|
||||||
|
[&](const std::string&, User* user)
|
||||||
|
{
|
||||||
|
return (user->getEmail() == email && user->getState() == util::State::ACTIVE);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return index != -1;
|
||||||
|
}
|
||||||
@@ -9,10 +9,15 @@
|
|||||||
#include<string>
|
#include<string>
|
||||||
#include<algorithm>
|
#include<algorithm>
|
||||||
#include<cctype>
|
#include<cctype>
|
||||||
|
#include "Map.h"
|
||||||
|
#include "User.h"
|
||||||
|
|
||||||
namespace util
|
namespace util
|
||||||
{
|
{
|
||||||
bool isPhoneNumberValid(const std::string&);
|
bool isPhoneNumberValid(const std::string&);
|
||||||
bool isEmailValid(const std::string&);
|
bool isEmailValid(const std::string&);
|
||||||
bool isPasswordValid(const std::string&);
|
bool isPasswordValid(const std::string&);
|
||||||
|
bool isUsernameDuplicate(const std::string&, const util::Map<std::string, User*>&);
|
||||||
|
bool isPhoneDuplicate(const std::string&, const util::Map<std::string, User*>&);
|
||||||
|
bool isEmailDuplicate(const std::string&, const util::Map<std::string, User*>&);
|
||||||
}
|
}
|
||||||
@@ -11,13 +11,13 @@ Date: 19-May-2026
|
|||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "AdminMenu.h"
|
#include "AdminMenu.h"
|
||||||
#include "ComboPackage.h"
|
|
||||||
#include "Enums.h"
|
#include "Enums.h"
|
||||||
#include "InputHelper.h"
|
#include "InputHelper.h"
|
||||||
#include "InventoryItem.h"
|
#include "InventoryItem.h"
|
||||||
#include "MenuHelper.h"
|
#include "MenuHelper.h"
|
||||||
#include "OutputHelper.h"
|
#include "OutputHelper.h"
|
||||||
#include "Service.h"
|
#include "Service.h"
|
||||||
|
#include "ServiceBooking.h"
|
||||||
#include "User.h"
|
#include "User.h"
|
||||||
#include "Utility.h"
|
#include "Utility.h"
|
||||||
#include "Validator.h"
|
#include "Validator.h"
|
||||||
@@ -42,15 +42,19 @@ void AdminMenu::showMenu()
|
|||||||
<< "\n3. Remove Inventory Item"
|
<< "\n3. Remove Inventory Item"
|
||||||
<< "\n4. Check Stock Availability"
|
<< "\n4. Check Stock Availability"
|
||||||
<< "\n5. Assign Job to Technician"
|
<< "\n5. Assign Job to Technician"
|
||||||
<< "\n6. Add Technician"
|
<< "\n6. Display Users"
|
||||||
<< "\n7. Remove Customer/Technician"
|
<< "\n7. Add Technician"
|
||||||
<< "\n8. Create Service"
|
<< "\n8. Remove Customer/Technician"
|
||||||
<< "\n9. Remove Service"
|
<< "\n9. Display Services"
|
||||||
<< "\n10. Create Combo Package"
|
<< "\n10. Create Service"
|
||||||
<< "\n11. Remove Combo Package"
|
<< "\n11. Remove Service"
|
||||||
<< "\n12. View Notifications"
|
<< "\n12. Display Combo Packages"
|
||||||
<< "\n13. Change Password"
|
<< "\n13. Create Combo Package"
|
||||||
<< "\n14. Logout"
|
<< "\n14. Remove Combo Package"
|
||||||
|
<< "\n15. View Notifications"
|
||||||
|
<< "\n16. Change Password"
|
||||||
|
<< "\n17. Confirm Payment"
|
||||||
|
<< "\n18. Logout"
|
||||||
<< "\nEnter a choice: ";
|
<< "\nEnter a choice: ";
|
||||||
util::read(choice);
|
util::read(choice);
|
||||||
if (!handleOperation(choice))
|
if (!handleOperation(choice))
|
||||||
@@ -92,30 +96,42 @@ bool AdminMenu::handleOperation(int choice)
|
|||||||
assignJob();
|
assignJob();
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
addTechnician();
|
displayUsers();
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
removeUser();
|
addTechnician();
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
createService();
|
removeUser();
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 9:
|
||||||
removeService();
|
displayServices();
|
||||||
break;
|
break;
|
||||||
case 10:
|
case 10:
|
||||||
createComboPackages();
|
createService();
|
||||||
break;
|
break;
|
||||||
case 11:
|
case 11:
|
||||||
removeComboPackage();
|
removeService();
|
||||||
break;
|
break;
|
||||||
case 12:
|
case 12:
|
||||||
viewNotifications();
|
displayComboPackages();
|
||||||
break;
|
break;
|
||||||
case 13:
|
case 13:
|
||||||
changePassword();
|
createComboPackages();
|
||||||
break;
|
break;
|
||||||
case 14:
|
case 14:
|
||||||
|
removeComboPackage();
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
viewNotifications();
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
changePassword();
|
||||||
|
break;
|
||||||
|
case 17:
|
||||||
|
confirmPayment();
|
||||||
|
break;
|
||||||
|
case 18:
|
||||||
logout();
|
logout();
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
@@ -158,10 +174,33 @@ void AdminMenu::viewStockLevels()
|
|||||||
{
|
{
|
||||||
util::clear();
|
util::clear();
|
||||||
auto inventoryItems = m_controller.getInventoryItems();
|
auto inventoryItems = m_controller.getInventoryItems();
|
||||||
|
bool hasActiveItems = false;
|
||||||
|
std::cout << "View Stock Levels" << std::endl;
|
||||||
|
if (inventoryItems.isEmpty())
|
||||||
|
{
|
||||||
|
std::cout << "No items found in Inventory.\n";
|
||||||
|
util::pressEnter();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int index = 0; index < inventoryItems.getSize(); index++)
|
||||||
|
{
|
||||||
|
const InventoryItem* item = inventoryItems.getValueAt(index);
|
||||||
|
if (item->getState() == util::State::ACTIVE)
|
||||||
|
{
|
||||||
|
hasActiveItems = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!hasActiveItems)
|
||||||
|
{
|
||||||
|
std::cout << "No active Inventory Item found.\n";
|
||||||
|
util::pressEnter();
|
||||||
|
return;
|
||||||
|
}
|
||||||
std::cout << std::left << std::setw(15) << "Item ID"
|
std::cout << std::left << std::setw(15) << "Item ID"
|
||||||
<< std::setw(25) << "Part Name"
|
<< std::setw(25) << "Part Name"
|
||||||
<< std::setw(10) << "Quantity"
|
<< std::setw(15) << "Quantity"
|
||||||
<< std::setw(10) << "Price"
|
<< std::setw(15) << "Price"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
for (int iterator = 0; iterator < inventoryItems.getSize(); ++iterator)
|
for (int iterator = 0; iterator < inventoryItems.getSize(); ++iterator)
|
||||||
{
|
{
|
||||||
@@ -172,12 +211,14 @@ void AdminMenu::viewStockLevels()
|
|||||||
{
|
{
|
||||||
std::cout << std::left << std::setw(15) << item->getId()
|
std::cout << std::left << std::setw(15) << item->getId()
|
||||||
<< std::setw(25) << item->getPartName()
|
<< std::setw(25) << item->getPartName()
|
||||||
<< std::setw(10) << item->getQuantity()
|
<< std::setw(15) << item->getQuantity()
|
||||||
<< std::setw(10) << item->getPrice()
|
<< std::setw(15) << item->getPrice()
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
std::cout << "\n";
|
||||||
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -193,13 +234,15 @@ void AdminMenu::addInventoryItem()
|
|||||||
int choice, quantity;
|
int choice, quantity;
|
||||||
double price;
|
double price;
|
||||||
std::string partName;
|
std::string partName;
|
||||||
std::cout << "1. Add new item \n2. Add Quantity\nEnter your choice : ";
|
std::cout << "Add Inventory Item\n";
|
||||||
|
std::cout << "1. Add new item \n2. Restock Item\n\nEnter your choice : ";
|
||||||
util::read(choice);
|
util::read(choice);
|
||||||
switch (choice)
|
switch (choice)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
std::cout << "--------Enter Item Details----------\n";
|
util::clear();
|
||||||
|
std::cout << "Enter Item Details\n";
|
||||||
std::cout << "Part Name : ";
|
std::cout << "Part Name : ";
|
||||||
util::read(partName);
|
util::read(partName);
|
||||||
std::cout << "Quantity : ";
|
std::cout << "Quantity : ";
|
||||||
@@ -207,15 +250,21 @@ void AdminMenu::addInventoryItem()
|
|||||||
std::cout << "Price : ";
|
std::cout << "Price : ";
|
||||||
util::read(price);
|
util::read(price);
|
||||||
m_controller.addInventoryItem(partName, quantity, price);
|
m_controller.addInventoryItem(partName, quantity, price);
|
||||||
std::cout << "New Item " << partName << " added to the Inventory.\n";
|
std::cout << "\nNew Item " << partName << " added to the Inventory.\n\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
|
util::clear();
|
||||||
|
std::cout << "Select Item to Restock\n";
|
||||||
auto inventoryItems = m_controller.getInventoryItems();
|
auto inventoryItems = m_controller.getInventoryItems();
|
||||||
addQuantityToItem(inventoryItems, m_controller);
|
addQuantityToItem(inventoryItems, m_controller);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
std::cout << "\nEnter a valid choice.\n\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
@@ -230,6 +279,7 @@ Return type: void
|
|||||||
void AdminMenu::removeInventoryItem()
|
void AdminMenu::removeInventoryItem()
|
||||||
{
|
{
|
||||||
util::clear();
|
util::clear();
|
||||||
|
std::cout << "Remove Inventory Item\n";
|
||||||
auto inventoryItems = m_controller.getInventoryItems();
|
auto inventoryItems = m_controller.getInventoryItems();
|
||||||
auto activeItems = filterActiveItems(inventoryItems);
|
auto activeItems = filterActiveItems(inventoryItems);
|
||||||
int activeItemsSize = activeItems.getSize();
|
int activeItemsSize = activeItems.getSize();
|
||||||
@@ -273,8 +323,10 @@ void AdminMenu::checkStockAvailability()
|
|||||||
{
|
{
|
||||||
util::clear();
|
util::clear();
|
||||||
std::string itemId;
|
std::string itemId;
|
||||||
std::cout << "Enter the Item Id : ";
|
std::cout << "Check Stock Availability \n";
|
||||||
|
std::cout << "Enter the Item ID : ";
|
||||||
util::read(itemId);
|
util::read(itemId);
|
||||||
|
util::clear();
|
||||||
const InventoryItem* selectedItem = m_controller.getInventoryItem(itemId);
|
const InventoryItem* selectedItem = m_controller.getInventoryItem(itemId);
|
||||||
if (selectedItem != nullptr)
|
if (selectedItem != nullptr)
|
||||||
{
|
{
|
||||||
@@ -287,19 +339,213 @@ void AdminMenu::checkStockAvailability()
|
|||||||
std::cout << "Quantity : " << selectedItem->getQuantity() << "\n";
|
std::cout << "Quantity : " << selectedItem->getQuantity() << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Item not Found" << std::endl;
|
||||||
|
}
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: assignJob
|
||||||
|
Description: Allows the admin to assign pending service bookings to available technicians.
|
||||||
|
Creates job cards for selected services.
|
||||||
|
Parameters:
|
||||||
|
- None
|
||||||
|
Returns:
|
||||||
|
- void
|
||||||
|
*/
|
||||||
void AdminMenu::assignJob()
|
void AdminMenu::assignJob()
|
||||||
{
|
{
|
||||||
|
util::clear();
|
||||||
|
std::cout << "Assign Job to Technician\n";
|
||||||
|
std::string selectedService;
|
||||||
|
bool hasPendingService = false;
|
||||||
|
auto currentBookings = m_controller.getServiceBookings();
|
||||||
|
auto pendingServiceBookings = filterActiveServiceBookings(currentBookings);
|
||||||
|
auto availableTechnicians = m_controller.getUsers(util::UserType::TECHNICIAN);
|
||||||
|
int bookingsSize = pendingServiceBookings.getSize();
|
||||||
|
util::Map<int, const ServiceBooking*> serviceBookingsMap;
|
||||||
|
util::Map<int, const User*> currentAvailableTechniciansMap;
|
||||||
|
if (listServiceBookings(pendingServiceBookings, bookingsSize, serviceBookingsMap))
|
||||||
|
{
|
||||||
|
const ServiceBooking* selectedService = selectPendingServiceBookings(serviceBookingsMap);
|
||||||
|
if (selectedService)
|
||||||
|
{
|
||||||
|
if (availableTechnicians.getSize() != 0)
|
||||||
|
{
|
||||||
|
listAvailableTechnicians(availableTechnicians, availableTechnicians.getSize(), currentAvailableTechniciansMap);
|
||||||
|
const User* selectedTechnician = selectTechnician(currentAvailableTechniciansMap);
|
||||||
|
if (selectedTechnician)
|
||||||
|
{
|
||||||
|
auto& servicesInBooking = selectedService->getServices();
|
||||||
|
for (int iterator = 0; iterator < servicesInBooking.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
m_controller.createJobCard(selectedService->getId(), selectedTechnician->getId(), servicesInBooking.getValueAt(iterator)->getId());
|
||||||
|
}
|
||||||
|
std::cout << "Job card created for each service and technician successfully assigned.\n\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "No technicians are currently available.\n\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "No pending service bookings available.\n\n";
|
||||||
|
}
|
||||||
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: displayServices()
|
||||||
|
Description: Display all active services
|
||||||
|
Parameters:
|
||||||
|
- None
|
||||||
|
Returns:
|
||||||
|
- void
|
||||||
|
*/
|
||||||
|
void AdminMenu::displayServices()
|
||||||
|
{
|
||||||
|
util::clear();
|
||||||
|
std::cout << "List of all Services\n";
|
||||||
|
util::Map<std::string, const Service*> currentServices = m_controller.getServices();
|
||||||
|
util::Map<std::string, const Service*> currentActiveServices = filterActiveServices(currentServices);
|
||||||
|
displayAllServices(currentActiveServices);
|
||||||
|
util::pressEnter();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: createService
|
||||||
|
Description: Allows the admin to create a new service by selecting inventory items and specifying labor cost.
|
||||||
|
Parameters:
|
||||||
|
- None
|
||||||
|
Returns:
|
||||||
|
- void
|
||||||
|
*/
|
||||||
void AdminMenu::createService()
|
void AdminMenu::createService()
|
||||||
{
|
{
|
||||||
|
util::clear();
|
||||||
|
std::cout << "Create Service\n";
|
||||||
|
std::string serviceName;
|
||||||
|
double labourCost;
|
||||||
|
std::cout << "Enter the service name: ";
|
||||||
|
util::read(serviceName);
|
||||||
|
util::Map<std::string, const InventoryItem*> currentInventoryItems = m_controller.getInventoryItems();
|
||||||
|
util::Map<std::string, const InventoryItem*> activeInventoryItems = filterActiveItems(currentInventoryItems);
|
||||||
|
util::Vector<std::string> selectedInventoryItems;
|
||||||
|
selectInventoryItems(activeInventoryItems,selectedInventoryItems);
|
||||||
|
if (selectedInventoryItems.isEmpty())
|
||||||
|
{
|
||||||
|
util::pressEnter();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::cout << "\nEnter the labour cost: ";
|
||||||
|
util::read(labourCost);
|
||||||
|
m_controller.createService(serviceName, selectedInventoryItems, labourCost);
|
||||||
|
std::cout << "\nService created sucessfully.\n\n";
|
||||||
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: removeService
|
||||||
|
Description: Allows the admin to remove an existing service by selecting from available services.
|
||||||
|
Parameters:
|
||||||
|
- None
|
||||||
|
Returns:
|
||||||
|
- void
|
||||||
|
*/
|
||||||
void AdminMenu::removeService()
|
void AdminMenu::removeService()
|
||||||
{
|
{
|
||||||
|
util::clear();
|
||||||
|
std::cout << "Remove Service\n";
|
||||||
|
std::string selectedServiceID;
|
||||||
|
util::Map<std::string, const Service*> currentServices = m_controller.getServices();
|
||||||
|
util::Map<std::string, const Service*> currentActiveServices = filterActiveServices(currentServices);
|
||||||
|
selectedServiceID = selectServicesToRemove(currentActiveServices);
|
||||||
|
if (selectedServiceID != "")
|
||||||
|
{
|
||||||
|
m_controller.removeService(selectedServiceID);
|
||||||
|
std::cout << "Service removed successfully.\n\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Failed to remove service.\n\n";
|
||||||
|
}
|
||||||
|
util::pressEnter();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: displayUsers
|
||||||
|
Description: Displays all users.
|
||||||
|
Parameter: None
|
||||||
|
Return type: void
|
||||||
|
*/
|
||||||
|
void AdminMenu::displayUsers()
|
||||||
|
{
|
||||||
|
util::clear();
|
||||||
|
auto listOfUsers = m_controller.getUsers();
|
||||||
|
auto listOfActiveUsers = filterActiveUsers(listOfUsers);
|
||||||
|
int activeUserCount = listOfActiveUsers.getSize();
|
||||||
|
std::cout << "List of all Users\n";
|
||||||
|
if (activeUserCount < 1)
|
||||||
|
{
|
||||||
|
std::cout << "No Active users." << std::endl;
|
||||||
|
util::pressEnter();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
displayAllUsers(listOfActiveUsers);
|
||||||
|
util::pressEnter();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: confirmPayment
|
||||||
|
Description: Confirms payment for a selected invoice. Validates invoice status, updates payment date,
|
||||||
|
sets status to PAID, and sends a notification to the customer.
|
||||||
|
Parameters:
|
||||||
|
- invoiceID: std::string, ID of the invoice to confirm
|
||||||
|
Returns:
|
||||||
|
- void
|
||||||
|
*/
|
||||||
|
void AdminMenu::confirmPayment()
|
||||||
|
{
|
||||||
|
util::clear();
|
||||||
|
std::cout << "Confirm Payment\n";
|
||||||
|
auto invoiceList = m_controller.getAllInvoices();
|
||||||
|
if (invoiceList.isEmpty())
|
||||||
|
{
|
||||||
|
std::cout << "No pending invoices available for confirmation.";
|
||||||
|
util::pressEnter();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bool hasPaidInvoice = false;
|
||||||
|
for (int index = 0; index < invoiceList.getSize(); ++index)
|
||||||
|
{
|
||||||
|
const Invoice* invoice = invoiceList.getValueAt(index);
|
||||||
|
if (invoice && invoice->getStatus() == util::PaymentStatus::PAID)
|
||||||
|
{
|
||||||
|
hasPaidInvoice = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!hasPaidInvoice)
|
||||||
|
{
|
||||||
|
std::cout << "No pending invoices available for payment.\n";
|
||||||
|
util::pressEnter();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::string selectedID = selectInvoiceFromUserForPayment(invoiceList, util::PaymentStatus::PAID);
|
||||||
|
if (selectedID == "")
|
||||||
|
{
|
||||||
|
std::cout << "Payment failed.\n";
|
||||||
|
util::pressEnter();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_controller.confirmPayment(selectedID);
|
||||||
|
std::cout << "Payment Confirmed successfully.\n";
|
||||||
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -312,36 +558,37 @@ void AdminMenu::addTechnician()
|
|||||||
{
|
{
|
||||||
util::clear();
|
util::clear();
|
||||||
std::string username, name, password, email, phoneNumber;
|
std::string username, name, password, email, phoneNumber;
|
||||||
std::cout << std::left << std::setw(25) << "Enter Technician Username: ";
|
std::cout << "Add Technician\n";
|
||||||
|
std::cout << "Enter Technician Username: ";
|
||||||
util::read(username);
|
util::read(username);
|
||||||
std::cout << std::left << std::setw(25) << "Enter Technician Name: ";
|
std::cout << "Enter Technician Name: ";
|
||||||
util::read(name);
|
util::read(name);
|
||||||
std::cout << std::setw(25) << "Enter Technician Password: ";
|
std::cout << "Enter Technician Password: ";
|
||||||
util::read(password);
|
util::read(password);
|
||||||
if(!util::isPasswordValid(password))
|
if(!util::isPasswordValid(password))
|
||||||
{
|
{
|
||||||
std::cout << "Error: Password is invalid!";
|
std::cout << "\nError: Password is invalid!\n\n";
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::cout << std::setw(25) << "Enter Technician Email: ";
|
std::cout << "Enter Technician Email: ";
|
||||||
util::read(email);
|
util::read(email);
|
||||||
if(!util::isEmailValid(email))
|
if(!util::isEmailValid(email))
|
||||||
{
|
{
|
||||||
std::cout << "Error: Email is invalid!";
|
std::cout << "\nError: Email is invalid!\n\n";
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::cout << std::setw(25) << "Enter Technician Phone: ";
|
std::cout << "Enter Technician Phone: ";
|
||||||
util::read(phoneNumber);
|
util::read(phoneNumber);
|
||||||
if(!util::isPhoneNumberValid(phoneNumber))
|
if(!util::isPhoneNumberValid(phoneNumber))
|
||||||
{
|
{
|
||||||
std::cout << "Error: Phone Number is invalid!";
|
std::cout << "\nError: Phone Number is invalid!\n\n";
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_controller.createTechnician(username, name, password, email, phoneNumber);
|
m_controller.createTechnician(username, name, password, email, phoneNumber);
|
||||||
std::cout << "\nTechnician Added Successfully.\n";
|
std::cout << "\nTechnician Added Successfully.\n\n";
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -358,18 +605,19 @@ void AdminMenu::removeUser()
|
|||||||
auto listOfUsers = m_controller.getUsers();
|
auto listOfUsers = m_controller.getUsers();
|
||||||
auto listOfActiveUsers = filterActiveUsers(listOfUsers);
|
auto listOfActiveUsers = filterActiveUsers(listOfUsers);
|
||||||
int activeUserCount = listOfActiveUsers.getSize();
|
int activeUserCount = listOfActiveUsers.getSize();
|
||||||
|
std::cout << "Remove User \n";
|
||||||
if (activeUserCount < 1)
|
if (activeUserCount < 1)
|
||||||
{
|
{
|
||||||
std::cout << "No Active users." << std::endl;
|
std::cout << "No Active users." << std::endl;
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
displayAllActiveUsers(listOfActiveUsers, activeUserCount);
|
displayAllUsers(listOfActiveUsers);
|
||||||
std::cout << "Enter the index of the user to delete : ";
|
std::cout << "Enter the index of the user to delete : ";
|
||||||
util::read(indexChoice);
|
util::read(indexChoice);
|
||||||
if (indexChoice < 1 || indexChoice > activeUserCount)
|
if (indexChoice < 1 || indexChoice > activeUserCount)
|
||||||
{
|
{
|
||||||
std::cout << "Error Invaild index.\n" << std::endl;
|
std::cout << "Error invalid index.\n" << std::endl;
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -383,6 +631,24 @@ void AdminMenu::removeUser()
|
|||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: displayComboPackages()
|
||||||
|
Description: Display all active combo packages
|
||||||
|
Parameters:
|
||||||
|
- None
|
||||||
|
Returns:
|
||||||
|
- void
|
||||||
|
*/
|
||||||
|
void AdminMenu::displayComboPackages()
|
||||||
|
{
|
||||||
|
util::clear();
|
||||||
|
std::cout << "List of all Combo Packages\n";
|
||||||
|
util::Map<std::string, const ComboPackage*> currentComboPackages = m_controller.getComboPackages();
|
||||||
|
util::Map<std::string, const ComboPackage*> currentActiveComboPackages = filterComboPackages(currentComboPackages);
|
||||||
|
displayAllComboPackages(currentActiveComboPackages);
|
||||||
|
util::pressEnter();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Function: createComboPackages
|
Function: createComboPackages
|
||||||
Description: Creates a new combo package by selecting two active services and applying a discount.
|
Description: Creates a new combo package by selecting two active services and applying a discount.
|
||||||
@@ -392,7 +658,10 @@ Return type: void
|
|||||||
void AdminMenu::createComboPackages()
|
void AdminMenu::createComboPackages()
|
||||||
{
|
{
|
||||||
util::clear();
|
util::clear();
|
||||||
|
std::cout << "Create Combo Packages\n";
|
||||||
auto serviceList = m_controller.getServices();
|
auto serviceList = m_controller.getServices();
|
||||||
|
auto activeServices = filterActiveServices(serviceList);
|
||||||
|
int currentActiveServicesCount = activeServices.getSize();
|
||||||
const int NUMBER_OF_SERVICE_PER_PACKAGE = 2;
|
const int NUMBER_OF_SERVICE_PER_PACKAGE = 2;
|
||||||
util::Vector<std::string> selectedServiceID;
|
util::Vector<std::string> selectedServiceID;
|
||||||
for (int iterator = 0; iterator < NUMBER_OF_SERVICE_PER_PACKAGE; iterator++)
|
for (int iterator = 0; iterator < NUMBER_OF_SERVICE_PER_PACKAGE; iterator++)
|
||||||
@@ -400,10 +669,10 @@ void AdminMenu::createComboPackages()
|
|||||||
const Service* chosenService = nullptr;
|
const Service* chosenService = nullptr;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
chosenService = selectServiceFromServices(serviceList);
|
chosenService = selectServiceFromServices(activeServices);
|
||||||
if (chosenService == nullptr)
|
if (!chosenService)
|
||||||
{
|
{
|
||||||
std::cout << "Failed to create combo package!";
|
std::cout << "Failed to create combo package!\n\n";
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -418,13 +687,21 @@ void AdminMenu::createComboPackages()
|
|||||||
}
|
}
|
||||||
if (alreadyChosen)
|
if (alreadyChosen)
|
||||||
{
|
{
|
||||||
|
if (currentActiveServicesCount < 2)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
std::cout << "Service already selected. Please choose a different one." << std::endl;
|
std::cout << "Service already selected. Please choose a different one." << std::endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
selectedServiceID.push_back(chosenService->getId());
|
selectedServiceID.push_back(chosenService->getId());
|
||||||
util::clear();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (currentActiveServicesCount < 2)
|
||||||
|
{
|
||||||
|
std::cout << "All the available services selected\n\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
std::string packageName;
|
std::string packageName;
|
||||||
double discountPercentage;
|
double discountPercentage;
|
||||||
@@ -452,16 +729,17 @@ Return type: void
|
|||||||
void AdminMenu::removeComboPackage()
|
void AdminMenu::removeComboPackage()
|
||||||
{
|
{
|
||||||
util::clear();
|
util::clear();
|
||||||
|
std::cout << "Remove Combo Package\n";
|
||||||
util::Map<std::string, const ComboPackage*> currentComboPackages = m_controller.getComboPackages();
|
util::Map<std::string, const ComboPackage*> currentComboPackages = m_controller.getComboPackages();
|
||||||
std::string selectedComboPackageID = selectComboPackage(currentComboPackages);
|
std::string selectedComboPackageID = selectComboPackage(currentComboPackages);
|
||||||
if (selectedComboPackageID != "")
|
if (!selectedComboPackageID.empty())
|
||||||
{
|
{
|
||||||
m_controller.removeComboPackage(selectedComboPackageID);
|
m_controller.removeComboPackage(selectedComboPackageID);
|
||||||
std::cout << "Combo Package removed successfully.\n";
|
std::cout << "Combo Package removed successfully.\n\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "Combo package removal failed.\n";
|
std::cout << "Combo package removal failed.\n\n";
|
||||||
}
|
}
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,10 +24,14 @@ public:
|
|||||||
void removeInventoryItem();
|
void removeInventoryItem();
|
||||||
void checkStockAvailability();
|
void checkStockAvailability();
|
||||||
void assignJob();
|
void assignJob();
|
||||||
|
void displayServices();
|
||||||
void createService();
|
void createService();
|
||||||
void removeService();
|
void removeService();
|
||||||
|
void displayUsers();
|
||||||
|
void confirmPayment();
|
||||||
void addTechnician();
|
void addTechnician();
|
||||||
void removeUser();
|
void removeUser();
|
||||||
|
void displayComboPackages();
|
||||||
void createComboPackages();
|
void createComboPackages();
|
||||||
void removeComboPackage();
|
void removeComboPackage();
|
||||||
void viewNotifications();
|
void viewNotifications();
|
||||||
|
|||||||
@@ -6,15 +6,21 @@ Description: Implementation file containing the method definitions of the
|
|||||||
Author: Trenser
|
Author: Trenser
|
||||||
Date:19-May-2026
|
Date:19-May-2026
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include "ComboPackage.h"
|
#include "ComboPackage.h"
|
||||||
#include "CustomerMenu.h"
|
#include "CustomerMenu.h"
|
||||||
#include "InputHelper.h"
|
|
||||||
#include "InventoryItem.h"
|
|
||||||
#include "Map.h"
|
|
||||||
#include "MenuHelper.h"
|
#include "MenuHelper.h"
|
||||||
|
#include "Enums.h"
|
||||||
|
#include "InputHelper.h"
|
||||||
#include "OutputHelper.h"
|
#include "OutputHelper.h"
|
||||||
|
#include "InventoryItem.h"
|
||||||
|
#include "Invoice.h"
|
||||||
|
#include "Map.h"
|
||||||
#include "Service.h"
|
#include "Service.h"
|
||||||
|
#include "ServiceBooking.h"
|
||||||
|
#include "Timestamp.h"
|
||||||
|
#include "User.h"
|
||||||
#include "Validator.h"
|
#include "Validator.h"
|
||||||
#include "Vector.h"
|
#include "Vector.h"
|
||||||
|
|
||||||
@@ -138,11 +144,12 @@ void CustomerMenu::updateDetails()
|
|||||||
{
|
{
|
||||||
std::string email, phone;
|
std::string email, phone;
|
||||||
util::clear();
|
util::clear();
|
||||||
|
std::cout << "Update Details\n";
|
||||||
std::cout << "Enter new email: ";
|
std::cout << "Enter new email: ";
|
||||||
util::read(email);
|
util::read(email);
|
||||||
if (!util::isEmailValid(email))
|
if (!util::isEmailValid(email))
|
||||||
{
|
{
|
||||||
std::cout << "Error: Email is invalid!";
|
std::cout << "Error: Email is invalid!\n";
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -150,12 +157,12 @@ void CustomerMenu::updateDetails()
|
|||||||
util::read(phone);
|
util::read(phone);
|
||||||
if (!util::isPhoneNumberValid(phone))
|
if (!util::isPhoneNumberValid(phone))
|
||||||
{
|
{
|
||||||
std::cout << "Error: Phone number is invalid!";
|
std::cout << "Error: Phone number is invalid!\n";
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_controller.updateUserDetails(email, phone);
|
m_controller.updateUserDetails(email, phone);
|
||||||
std::cout << "Profile details updated successfully";
|
std::cout << "Profile details updated successfully\n";
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,9 +176,16 @@ Return type: void
|
|||||||
void CustomerMenu::selectService()
|
void CustomerMenu::selectService()
|
||||||
{
|
{
|
||||||
std::string vehicleNumber, vehicleBrand, vehicleModel;
|
std::string vehicleNumber, vehicleBrand, vehicleModel;
|
||||||
auto services = m_controller.getServices();
|
|
||||||
util::Vector<std::string> selectedServices;
|
|
||||||
util::clear();
|
util::clear();
|
||||||
|
std::cout << "Select a Service\n";
|
||||||
|
auto services = m_controller.getServices();
|
||||||
|
if (services.isEmpty())
|
||||||
|
{
|
||||||
|
std::cout << "No services available!";
|
||||||
|
util::pressEnter();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
util::Vector<std::string> selectedServices;
|
||||||
const Service* selectedService = selectServiceFromServices(services);
|
const Service* selectedService = selectServiceFromServices(services);
|
||||||
if (selectedService == nullptr)
|
if (selectedService == nullptr)
|
||||||
{
|
{
|
||||||
@@ -181,6 +195,7 @@ void CustomerMenu::selectService()
|
|||||||
}
|
}
|
||||||
selectedServices.push_back(selectedService->getId());
|
selectedServices.push_back(selectedService->getId());
|
||||||
util::clear();
|
util::clear();
|
||||||
|
std::cout << "Enter Vehicle Details\n";
|
||||||
std::cout << "Enter vehicle number: ";
|
std::cout << "Enter vehicle number: ";
|
||||||
util::read(vehicleNumber);
|
util::read(vehicleNumber);
|
||||||
std::cout << "Enter vehicle brand: ";
|
std::cout << "Enter vehicle brand: ";
|
||||||
@@ -202,16 +217,27 @@ Return type: void
|
|||||||
void CustomerMenu::selectComboPackage()
|
void CustomerMenu::selectComboPackage()
|
||||||
{
|
{
|
||||||
std::string vehicleNumber, vehicleBrand, vehicleModel;
|
std::string vehicleNumber, vehicleBrand, vehicleModel;
|
||||||
auto comboPackages = m_controller.getComboPackages();
|
|
||||||
util::clear();
|
util::clear();
|
||||||
const ComboPackage* selectedComboPackage = selectComboPackageFromPackages(comboPackages);
|
std::cout << "Select a Combo Package\n";
|
||||||
if (selectedComboPackage == nullptr)
|
auto comboPackages = m_controller.getComboPackages();
|
||||||
|
util::Map<std::string, const ComboPackage*> activeComboPackages = filterComboPackages(comboPackages);
|
||||||
|
if (activeComboPackages.isEmpty())
|
||||||
{
|
{
|
||||||
std::cout << "Failed to book combo package!";
|
std::cout << "No combo packages available!\n\n";
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const ComboPackage* selectedComboPackage = selectComboPackageFromPackages(activeComboPackages);
|
||||||
|
if (selectedComboPackage == nullptr)
|
||||||
|
{
|
||||||
|
std::cout << "Failed to book combo package!\n\n";
|
||||||
|
util::pressEnter();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::cout << "Combo Package selected\n";
|
||||||
|
util::pressEnter();
|
||||||
util::clear();
|
util::clear();
|
||||||
|
std::cout << "Enter the vehicle details\n";
|
||||||
std::cout << "Enter vehicle number: ";
|
std::cout << "Enter vehicle number: ";
|
||||||
util::read(vehicleNumber);
|
util::read(vehicleNumber);
|
||||||
std::cout << "Enter vehicle brand: ";
|
std::cout << "Enter vehicle brand: ";
|
||||||
@@ -219,20 +245,127 @@ void CustomerMenu::selectComboPackage()
|
|||||||
std::cout << "Enter vehicle model: ";
|
std::cout << "Enter vehicle model: ";
|
||||||
util::read(vehicleModel);
|
util::read(vehicleModel);
|
||||||
m_controller.purchaseComboPackage(selectedComboPackage->getId(), vehicleNumber, vehicleBrand, vehicleModel);
|
m_controller.purchaseComboPackage(selectedComboPackage->getId(), vehicleNumber, vehicleBrand, vehicleModel);
|
||||||
std::cout << "Combo Package has been booked successfully";
|
std::cout << "Combo Package has been booked successfully\n\n";
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: viewServiceHistory
|
||||||
|
Description: Displays the customer’s past service bookings in tabular format,
|
||||||
|
including booking ID, technician, vehicle details, discount percentage, and status.
|
||||||
|
Parameters:
|
||||||
|
- None
|
||||||
|
Returns:
|
||||||
|
- void
|
||||||
|
*/
|
||||||
void CustomerMenu::viewServiceHistory()
|
void CustomerMenu::viewServiceHistory()
|
||||||
{
|
{
|
||||||
|
util::clear();
|
||||||
|
bool hasServiceHistory = false;
|
||||||
|
const User* currentUser = m_controller.getAuthenticatedUser();
|
||||||
|
std::string currentUserID = currentUser->getId();
|
||||||
|
util::Map<std::string, const ServiceBooking*> serviceBookingsByCurrentUser = m_controller.getServiceBookingsByUser(currentUserID);
|
||||||
|
std::cout << "View Service History" << std::endl;
|
||||||
|
if (serviceBookingsByCurrentUser.getSize() != 0)
|
||||||
|
{
|
||||||
|
std::cout << std::left
|
||||||
|
<< std::setw(15) << "Booking ID"
|
||||||
|
<< std::setw(20) << "Technician"
|
||||||
|
<< std::setw(20) << "Vehicle Brand"
|
||||||
|
<< std::setw(20) << "Vehicle Number"
|
||||||
|
<< std::setw(20) << "Vehicle Model"
|
||||||
|
<< std::setw(20) << "Discount %"
|
||||||
|
<< std::setw(20) << "Status"
|
||||||
|
<< std::endl;
|
||||||
|
for (int iterator = 0; iterator < serviceBookingsByCurrentUser.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
const ServiceBooking* currentBooking = serviceBookingsByCurrentUser.getValueAt(iterator);
|
||||||
|
std::string technicianName = currentBooking->getAssignedTechnician() == nullptr
|
||||||
|
? "Not Assigned"
|
||||||
|
: currentBooking->getAssignedTechnician()->getName();
|
||||||
|
std::cout << std::left
|
||||||
|
<< std::setw(15) << currentBooking->getId()
|
||||||
|
<< std::setw(20) << technicianName
|
||||||
|
<< std::setw(20) << currentBooking->getVehicleBrand()
|
||||||
|
<< std::setw(20) << currentBooking->getVehicleNumber()
|
||||||
|
<< std::setw(20) << currentBooking->getVehicleModel()
|
||||||
|
<< std::setw(20) << currentBooking->getDiscountPercentage()
|
||||||
|
<< std::setw(20) << util::getServiceJobStatusString(currentBooking->getStatus())
|
||||||
|
<< std::endl;
|
||||||
|
hasServiceHistory = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!hasServiceHistory)
|
||||||
|
{
|
||||||
|
std::cout << "No history available." << std::endl;
|
||||||
|
}
|
||||||
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: completePayments
|
||||||
|
Description: Allows the customer to complete pending payments for invoices.
|
||||||
|
Validates invoice selection and payment mode before completing payment.
|
||||||
|
Parameters:
|
||||||
|
- None
|
||||||
|
Returns:
|
||||||
|
- void
|
||||||
|
*/
|
||||||
void CustomerMenu::completePayments()
|
void CustomerMenu::completePayments()
|
||||||
{
|
{
|
||||||
|
util::clear();
|
||||||
|
std::cout << "Complete Payments\n";
|
||||||
|
util::Map<std::string, const Invoice*> currentInvoices = m_controller.getInvoicesByUser();
|
||||||
|
if (currentInvoices.isEmpty())
|
||||||
|
{
|
||||||
|
std::cout << "No pending invoices available for payment.\n";
|
||||||
|
util::pressEnter();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bool hasPending = false;
|
||||||
|
for (int index = 0; index < currentInvoices.getSize(); ++index)
|
||||||
|
{
|
||||||
|
const Invoice* invoice = currentInvoices.getValueAt(index);
|
||||||
|
if (invoice && invoice->getStatus() == util::PaymentStatus::PENDING)
|
||||||
|
{
|
||||||
|
hasPending = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!hasPending)
|
||||||
|
{
|
||||||
|
std::cout << "No pending invoices available for payment.\n";
|
||||||
|
util::pressEnter();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::string selectedID = selectInvoiceFromUserForPayment(currentInvoices, util::PaymentStatus::PENDING);
|
||||||
|
if (selectedID == "")
|
||||||
|
{
|
||||||
|
std::cout << "Payment failed.\n";
|
||||||
|
util::pressEnter();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
util::PaymentMode paymentMode = selectPaymentMode();
|
||||||
|
m_controller.completePayment(selectedID, paymentMode);
|
||||||
|
std::cout << "Payment completed successfully.\n";
|
||||||
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: viewInvoices
|
||||||
|
Description: Displays invoices associated with the customer by calling displayInvoices.
|
||||||
|
Parameters:
|
||||||
|
- None
|
||||||
|
Returns:
|
||||||
|
- void
|
||||||
|
*/
|
||||||
void CustomerMenu::viewInvoices()
|
void CustomerMenu::viewInvoices()
|
||||||
{
|
{
|
||||||
|
util::clear();
|
||||||
|
std::cout << "View Invoices\n";
|
||||||
|
util::Map<std::string, const Invoice*> currentUserInvoices = m_controller.getInvoicesByUser();
|
||||||
|
displayInvoices(currentUserInvoices);
|
||||||
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
+54
-10
@@ -6,12 +6,15 @@ Description: Implementation file containing the method definitions of the
|
|||||||
Author: Trenser
|
Author: Trenser
|
||||||
Date:19-May-2026
|
Date:19-May-2026
|
||||||
*/
|
*/
|
||||||
#include "TechnicianMenu.h"
|
|
||||||
|
#include "Enums.h"
|
||||||
#include "InputHelper.h"
|
#include "InputHelper.h"
|
||||||
|
#include "JobCard.h"
|
||||||
|
#include "MenuHelper.h"
|
||||||
#include "OutputHelper.h"
|
#include "OutputHelper.h"
|
||||||
|
#include "Service.h"
|
||||||
|
#include "TechnicianMenu.h"
|
||||||
#include "Validator.h"
|
#include "Validator.h"
|
||||||
#include "MenuHelper.h"
|
|
||||||
#include "MenuHelper.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Function: showMenu
|
Function: showMenu
|
||||||
@@ -31,10 +34,11 @@ void TechnicianMenu::showMenu()
|
|||||||
int choice;
|
int choice;
|
||||||
util::clear();
|
util::clear();
|
||||||
std::cout << "Technician Menu"
|
std::cout << "Technician Menu"
|
||||||
<< "\n1. Mark Job as Completed"
|
<< "\n1. Display My Jobs"
|
||||||
<< "\n2. View Notifications"
|
<< "\n2. Mark Job as Completed"
|
||||||
<< "\n3. Change Password"
|
<< "\n3. View Notifications"
|
||||||
<< "\n4. Logout"
|
<< "\n4. Change Password"
|
||||||
|
<< "\n5. Logout"
|
||||||
<< "\nEnter a choice: ";
|
<< "\nEnter a choice: ";
|
||||||
util::read(choice);
|
util::read(choice);
|
||||||
if (!handleOperation(choice))
|
if (!handleOperation(choice))
|
||||||
@@ -61,15 +65,18 @@ bool TechnicianMenu::handleOperation(int choice)
|
|||||||
switch (choice)
|
switch (choice)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
completeJob();
|
displayJobs();
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
viewNotifications();
|
completeJob();
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
changePassword();
|
viewNotifications();
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
|
changePassword();
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
logout();
|
logout();
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
@@ -79,9 +86,46 @@ bool TechnicianMenu::handleOperation(int choice)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: displayJobs
|
||||||
|
Description: Displays all Jobs assigned to a Technician
|
||||||
|
Parameters:
|
||||||
|
- None
|
||||||
|
Returns:
|
||||||
|
- void
|
||||||
|
*/
|
||||||
|
void TechnicianMenu::displayJobs()
|
||||||
|
{
|
||||||
|
util::clear();
|
||||||
|
std::cout << "My Jobs\n";
|
||||||
|
util::Map<std::string, const JobCard*> assignedJobCards = m_controller.getJobCardsByUser();
|
||||||
|
util::Map<std::string, const JobCard*> startedJobCards = filterStartedJobCards(assignedJobCards);
|
||||||
|
displayAllJobs(startedJobCards);
|
||||||
|
util::pressEnter();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: completeJob
|
||||||
|
Description: Allows the technician to mark a selected job card as completed.
|
||||||
|
Validates selection and updates job status through the controller.
|
||||||
|
Parameters:
|
||||||
|
- None
|
||||||
|
Returns:
|
||||||
|
- void
|
||||||
|
*/
|
||||||
void TechnicianMenu::completeJob()
|
void TechnicianMenu::completeJob()
|
||||||
{
|
{
|
||||||
|
util::clear();
|
||||||
|
std::cout << "Complete Job\n";
|
||||||
|
util::Map<std::string, const JobCard*> assignedJobCards = m_controller.getJobCardsByUser();
|
||||||
|
util::Map<std::string, const JobCard*> startedJobCards = filterStartedJobCards(assignedJobCards);
|
||||||
|
std::string selectedJobID = selectJobCardToComplete(startedJobCards);
|
||||||
|
if (!selectedJobID.empty())
|
||||||
|
{
|
||||||
|
m_controller.completeJob(selectedJobID);
|
||||||
|
std::cout << "\nJob marked as completed.\n\n";
|
||||||
|
}
|
||||||
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ private:
|
|||||||
bool handleOperation(int choice);
|
bool handleOperation(int choice);
|
||||||
public:
|
public:
|
||||||
void showMenu();
|
void showMenu();
|
||||||
|
void displayJobs();
|
||||||
void completeJob();
|
void completeJob();
|
||||||
void viewNotifications();
|
void viewNotifications();
|
||||||
void logout();
|
void logout();
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ Author: Trenser
|
|||||||
Date:19-May-2026
|
Date:19-May-2026
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdexcept>
|
||||||
#include "Enums.h"
|
#include "Enums.h"
|
||||||
#include "InputHelper.h"
|
#include "InputHelper.h"
|
||||||
#include "OutputHelper.h"
|
#include "OutputHelper.h"
|
||||||
@@ -23,29 +25,44 @@ Return type: void
|
|||||||
*/
|
*/
|
||||||
void UserInterface::run()
|
void UserInterface::run()
|
||||||
{
|
{
|
||||||
m_controller.loadSystemData();
|
try
|
||||||
m_controller.runSystemChecks();
|
|
||||||
bool isMenuActive = true;
|
|
||||||
while (isMenuActive)
|
|
||||||
{
|
{
|
||||||
try
|
m_controller.loadSystemData();
|
||||||
|
m_controller.runSystemChecks();
|
||||||
|
bool isMenuActive = true;
|
||||||
|
while (isMenuActive)
|
||||||
{
|
{
|
||||||
int choice;
|
try
|
||||||
util::clear();
|
|
||||||
std::cout << "Vehicle Service System\n1. Login\n2. Register Customer\n3. Exit\nEnter your Choice: ";
|
|
||||||
util::read(choice);
|
|
||||||
if (!handleOperation(choice))
|
|
||||||
{
|
{
|
||||||
isMenuActive = false;
|
int choice;
|
||||||
|
util::clear();
|
||||||
|
std::cout << "Vehicle Service System\n1. Login\n2. Register Customer\n3. Exit\nEnter your Choice: ";
|
||||||
|
util::read(choice);
|
||||||
|
if (!handleOperation(choice))
|
||||||
|
{
|
||||||
|
isMenuActive = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (const std::exception& e)
|
||||||
|
{
|
||||||
|
std::cout << "Exception: " << e.what() << std::endl;
|
||||||
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
m_controller.saveSystemData();
|
||||||
{
|
}
|
||||||
std::cout << "Exception: " << e.what() << std::endl;
|
catch (const std::invalid_argument& exception)
|
||||||
util::pressEnter();
|
{
|
||||||
}
|
std::cout << "Exception: Invalid Argument: " << exception.what() << std::endl;
|
||||||
|
}
|
||||||
|
catch (const std::exception& exception)
|
||||||
|
{
|
||||||
|
std::cout << "Exception: " << exception.what() << std::endl;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
std::cout << "Unknown error occurred." << std::endl;
|
||||||
}
|
}
|
||||||
m_controller.saveSystemData();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -85,6 +102,7 @@ void UserInterface::login()
|
|||||||
{
|
{
|
||||||
std::string username, password;
|
std::string username, password;
|
||||||
util::clear();
|
util::clear();
|
||||||
|
std::cout << "Login\n";
|
||||||
std::cout << "Enter username: ";
|
std::cout << "Enter username: ";
|
||||||
util::read(username);
|
util::read(username);
|
||||||
std::cout << "Enter password: ";
|
std::cout << "Enter password: ";
|
||||||
@@ -92,7 +110,7 @@ void UserInterface::login()
|
|||||||
if (m_controller.login(username, password))
|
if (m_controller.login(username, password))
|
||||||
{
|
{
|
||||||
const User* authenticatedUser = m_controller.getAuthenticatedUser();
|
const User* authenticatedUser = m_controller.getAuthenticatedUser();
|
||||||
if (authenticatedUser != nullptr)
|
if (authenticatedUser && authenticatedUser->getState() != util::State::INACTIVE)
|
||||||
{
|
{
|
||||||
switch (authenticatedUser->getUserType())
|
switch (authenticatedUser->getUserType())
|
||||||
{
|
{
|
||||||
@@ -110,10 +128,16 @@ void UserInterface::login()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (authenticatedUser && authenticatedUser->getState() == util::State::INACTIVE)
|
||||||
|
{
|
||||||
|
std::cout << "\nError: Your account has been disabled. Please contact your Administrator.";
|
||||||
|
util::pressEnter();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "\nError: Invalid Username or Password";
|
std::cout << "\nError: Invalid Username or Password";
|
||||||
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,6 +153,7 @@ void UserInterface::registerCustomer()
|
|||||||
{
|
{
|
||||||
std::string username, name, email, phone, password;
|
std::string username, name, email, phone, password;
|
||||||
util::clear();
|
util::clear();
|
||||||
|
std::cout << "Register Customer\n";
|
||||||
std::cout << "Enter username: ";
|
std::cout << "Enter username: ";
|
||||||
util::read(username);
|
util::read(username);
|
||||||
std::cout << "Enter name: ";
|
std::cout << "Enter name: ";
|
||||||
|
|||||||
Reference in New Issue
Block a user