Fix PR review comments and refactor menu helper logic
Changes: - Added missing include for MenuHelper.h in project and AdminMenu - Fixed typo in variable name inventoryIems to inventoryItems in Controller.cpp - Removed stray semicolon from include in Controller.h - Cleaned up duplicate comments in Controller.cpp description header - Minor formatting adjustments with blank lines after headers in multiple files - Updated ServiceManagementService notification message to remove informal wording - Refactored AdminMenu::changePassword to use changePasswordHelper - Added util::clear() call at start of viewStockLevels - Removed redundant helper functions from AdminMenu.cpp and moved to shared helpers - Fixed bug in removeInventoryItem to use activeItems instead of inventoryItems - Enhanced createComboPackages to enforce selection of two distinct services - General comment cleanup and formatting consistency across headers and implementation files
This commit is contained in:
+1
@@ -181,6 +181,7 @@
|
||||
<ClInclude Include="utilities\Vector.h" />
|
||||
<ClInclude Include="views\AdminMenu.h" />
|
||||
<ClInclude Include="views\CustomerMenu.h" />
|
||||
<ClInclude Include="views\MenuHelper.h" />
|
||||
<ClInclude Include="views\TechnicianMenu.h" />
|
||||
<ClInclude Include="views\UserInterface.h" />
|
||||
</ItemGroup>
|
||||
|
||||
+5
-7
@@ -2,13 +2,11 @@
|
||||
File: Controller.cpp
|
||||
Description: Implementation file containing the method definitions of the
|
||||
Controller class, which manages authentication, users, services,
|
||||
combo packages, and inventory operations.
|
||||
Implementation file containing the method definitions
|
||||
of the Controller class, which manages user authentication,
|
||||
inventory, services, bookings, and notifications.
|
||||
combo packages, bookings, notifications and inventory operations.
|
||||
Author: Trenser
|
||||
Date:19-May-2026
|
||||
*/
|
||||
|
||||
#include "Controller.h"
|
||||
#include "ComboPackage.h"
|
||||
#include "User.h"
|
||||
@@ -121,12 +119,12 @@ Return type: util::Map<std::string, const InventoryItem*>
|
||||
*/
|
||||
util::Map<std::string, const InventoryItem*> Controller::getInventoryItems()
|
||||
{
|
||||
auto inventoryIems = m_inventoryManagementService.getInventoryItems();
|
||||
auto inventoryItems = m_inventoryManagementService.getInventoryItems();
|
||||
util::Map<std::string, const InventoryItem*> readOnlyInventoryItems;
|
||||
int inventoryItemsMapSize = inventoryIems.getSize();
|
||||
int inventoryItemsMapSize = inventoryItems.getSize();
|
||||
for (int index = 0; index < inventoryItemsMapSize; index++)
|
||||
{
|
||||
readOnlyInventoryItems.insert(inventoryIems.getKeyAt(index), inventoryIems.getValueAt(index));
|
||||
readOnlyInventoryItems.insert(inventoryItems.getKeyAt(index), inventoryItems.getValueAt(index));
|
||||
}
|
||||
return readOnlyInventoryItems;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ Description: Header file declaring the Controller class, which manages
|
||||
Author: Trenser
|
||||
Date:19-May-2026
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "Map.h"
|
||||
@@ -13,7 +14,7 @@ Date:19-May-2026
|
||||
#include "UserManagementService.h"
|
||||
#include "ServiceManagementService.h"
|
||||
#include "AuthenticationManagementService.h"
|
||||
#include "InventoryManagementService.h";
|
||||
#include "InventoryManagementService.h"
|
||||
|
||||
class Service;
|
||||
class ComboPackage;
|
||||
|
||||
@@ -6,6 +6,7 @@ Description: Implementation file containing the method definitions of the
|
||||
Author: Trenser
|
||||
Date:19-May-2026
|
||||
*/
|
||||
|
||||
#include "JobCard.h"
|
||||
|
||||
int JobCard::m_uid = 0;
|
||||
|
||||
@@ -6,6 +6,7 @@ Description: Header file declaring the JobCard class, which represents
|
||||
Author: Trenser
|
||||
Date:19-May-2026
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "Timestamp.h"
|
||||
|
||||
@@ -6,6 +6,7 @@ Description: Implementation file containing the method definitions of the
|
||||
Author: Trenser
|
||||
Date:19-May-2026
|
||||
*/
|
||||
|
||||
#include "ServiceBooking.h"
|
||||
|
||||
int ServiceBooking::m_uid = 0;
|
||||
|
||||
@@ -6,6 +6,7 @@ Description: Header file declaring the ServiceBooking class, which represents
|
||||
Author: Trenser
|
||||
Date:19-May-2026
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "Map.h"
|
||||
|
||||
+1
@@ -6,6 +6,7 @@ Description: Implementation file containing the method definitions of the
|
||||
Author: Trenser
|
||||
Date:19-May-2026
|
||||
*/
|
||||
|
||||
#include "AuthenticationManagementService.h"
|
||||
#include "User.h"
|
||||
|
||||
|
||||
+1
@@ -6,6 +6,7 @@ Description: Header file declaring the AuthenticationManagementService class, wh
|
||||
Author: Trenser
|
||||
Date:19-May-2026
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "DataStore.h"
|
||||
|
||||
+1
@@ -6,6 +6,7 @@ Description: Implementation file containing the method definitions of the
|
||||
Author: Trenser
|
||||
Date:19-May-2026
|
||||
*/
|
||||
|
||||
#include "InventoryManagementService.h"
|
||||
#include "InventoryItem.h"
|
||||
#include "Factory.h"
|
||||
|
||||
+1
@@ -6,6 +6,7 @@ Description: Header file declaring the InventoryManagementService class,
|
||||
Author: Trenser
|
||||
Date:19-May-2026
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "Map.h"
|
||||
|
||||
+10
-3
@@ -6,6 +6,7 @@ Description: Implementation file containing the method definitions of the
|
||||
Author: Trenser
|
||||
Date:19-May-2026
|
||||
*/
|
||||
|
||||
#include "ServiceManagementService.h"
|
||||
#include "DataStore.h"
|
||||
#include "ServiceBooking.h"
|
||||
@@ -54,12 +55,16 @@ void ServiceManagementService::cancelCustomerServiceBookings(const std::string&
|
||||
booking->setCustomer(nullptr);
|
||||
booking->setCustomerId("");
|
||||
User* assignedTechnician = booking->getAssignedTechnician();
|
||||
sendNotification(assignedTechnician, "Customer Service Cancelled", "Uh?Oh. The customer has cancelled their service booking. Your assigned job card has been cancelled and the inventory has been restocked.");
|
||||
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);
|
||||
sendNotification(booking->getCustomer(), "Technician Unavailable", "Your assigned technician is no longer available. Your booking has been reset to pending, and we will reassign a new technician shortly.");
|
||||
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("");
|
||||
@@ -104,7 +109,9 @@ void ServiceManagementService::cancelTechnicianJobs(const std::string& technicia
|
||||
if (job->getStatus() == util::ServiceJobStatus::PENDING || job->getStatus() == util::ServiceJobStatus::STARTED)
|
||||
{
|
||||
job->setStatus(util::ServiceJobStatus::CANCELLED);
|
||||
sendNotification(job->getTechnician(), "Job Cancelled", "The Job has cancelled. Your job card has been cancelled and the inventory has been restocked.");
|
||||
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)
|
||||
{
|
||||
|
||||
+1
@@ -6,6 +6,7 @@ Description: Header file declaring the ServiceManagementService class, which man
|
||||
Author: Trenser
|
||||
Date:19-May-2026
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "Map.h"
|
||||
|
||||
+1
@@ -5,6 +5,7 @@ Description: Implementation file containing the method definitions of the
|
||||
Author: Trenser
|
||||
Date:19-May-2026
|
||||
*/
|
||||
|
||||
#include "UserManagementService.h"
|
||||
#include "User.h"
|
||||
|
||||
|
||||
+1
@@ -5,6 +5,7 @@ Description: Header file declaring the UserManagementService class, which manage
|
||||
Author: Trenser
|
||||
Date:19-May-2026
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "Map.h"
|
||||
|
||||
@@ -5,6 +5,7 @@ Description: Header file declaring utility functions used across the system,
|
||||
Author: Trenser
|
||||
Date:19-May-2026
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "Service.h"
|
||||
#include "InventoryItem.h"
|
||||
|
||||
@@ -6,6 +6,7 @@ Description: Implementation file containing the method definitions of the
|
||||
Author: Trenser
|
||||
Date:19-May-2026
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include "AdminMenu.h"
|
||||
@@ -18,6 +19,7 @@ Date:19-May-2026
|
||||
#include "Utility.h"
|
||||
#include "ComboPackage.h"
|
||||
#include "Enums.h"
|
||||
#include "MenuHelper.h"
|
||||
|
||||
/*
|
||||
Function: showMenu
|
||||
@@ -132,6 +134,7 @@ void AdminMenu::logout()
|
||||
{
|
||||
m_controller.logout();
|
||||
}
|
||||
|
||||
/*
|
||||
Function: changePassword
|
||||
Description: Allows the admin to change their password after validation.
|
||||
@@ -140,23 +143,7 @@ Return type: void
|
||||
*/
|
||||
void AdminMenu::changePassword()
|
||||
{
|
||||
std::string newPassword;
|
||||
while (true)
|
||||
{
|
||||
util::clear();
|
||||
std::cout << "Enter new password: ";
|
||||
util::read(newPassword);
|
||||
if (!util::isPasswordValid(newPassword))
|
||||
{
|
||||
std::cout << "Error: Password is not strong enough!\n";
|
||||
util::pressEnter();
|
||||
continue;
|
||||
}
|
||||
m_controller.changePassword(newPassword);
|
||||
std::cout << "Password changed successfully\n";
|
||||
util::pressEnter();
|
||||
break;
|
||||
}
|
||||
changePasswordHelper(m_controller);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -168,6 +155,7 @@ Return type: void
|
||||
*/
|
||||
void AdminMenu::viewStockLevels()
|
||||
{
|
||||
util::clear();
|
||||
auto inventoryItems = m_controller.getInventoryItems();
|
||||
std::cout << std::left << std::setw(15) << "Item ID"
|
||||
<< std::setw(25) << "Part Name"
|
||||
@@ -191,112 +179,6 @@ void AdminMenu::viewStockLevels()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Function: filterActiveItems
|
||||
Description: Filters out inactive inventory items and returns a map
|
||||
containing only active items.
|
||||
Parameter: const util::Map<std::string, const InventoryItem*>& inventoryItems -
|
||||
map of all inventory items
|
||||
Return type: util::Map<std::string, const InventoryItem*>
|
||||
*/
|
||||
static util::Map<std::string, const InventoryItem*>
|
||||
filterActiveItems(const util::Map<std::string, const InventoryItem*>& inventoryItems)
|
||||
{
|
||||
util::Map<std::string, const InventoryItem*> activeItems;
|
||||
int inventorySize = inventoryItems.getSize();
|
||||
for (int index = 0; index < inventorySize; index++)
|
||||
{
|
||||
const InventoryItem* item = inventoryItems.getValueAt(index);
|
||||
if (item != nullptr && item->getState() != util::State::INACTIVE)
|
||||
{
|
||||
activeItems.insert(item->getId(), item);
|
||||
}
|
||||
}
|
||||
return activeItems;
|
||||
}
|
||||
|
||||
/*
|
||||
Function: displayInventoryWithItems
|
||||
Description: Displays inventory items in a tabular format with index, ID,
|
||||
part name, quantity, and price.
|
||||
Parameter: util::Map<std::string, const InventoryItem*>& inventoryItems -
|
||||
map of inventory items to display
|
||||
Return type: void
|
||||
*/
|
||||
static void displayInventoryWithItems(util::Map<std::string, const InventoryItem*>& inventoryItems)
|
||||
{
|
||||
int inventorySize = inventoryItems.getSize();
|
||||
std::cout << std::left << std::setw(10) << "Index"
|
||||
<< std::setw(15) << "Item ID"
|
||||
<< std::setw(25) << "Part Name"
|
||||
<< std::setw(10) << "Quantity"
|
||||
<< std::setw(10) << "Price"
|
||||
<< std::endl;
|
||||
for (int iterator = 0; iterator < inventorySize; iterator++)
|
||||
{
|
||||
const InventoryItem* item = inventoryItems.getValueAt(iterator);
|
||||
if (item != nullptr)
|
||||
{
|
||||
std::cout << std::left << std::setw(10) << (iterator + 1)
|
||||
<< std::setw(15) << item->getId()
|
||||
<< std::setw(25) << item->getPartName()
|
||||
<< std::setw(10) << item->getQuantity()
|
||||
<< std::setw(10) << item->getPrice()
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Function: addQuantityToItem
|
||||
Description: Allows the admin to select an active inventory item and
|
||||
increase its stock quantity.
|
||||
Parameter: util::Map<std::string, const InventoryItem*>& inventoryItems -
|
||||
map of inventory items
|
||||
Controller& m_controller - controller instance to update stock
|
||||
Return type: void
|
||||
*/
|
||||
static void addQuantityToItem(util::Map<std::string, const InventoryItem*>& inventoryItems, Controller& m_controller)
|
||||
{
|
||||
int itemIndex;
|
||||
int quantity;
|
||||
auto activeItems = filterActiveItems(inventoryItems);
|
||||
int activeSize = activeItems.getSize();
|
||||
if (activeSize == 0)
|
||||
{
|
||||
std::cout << "No active items available in Inventory" << std::endl;
|
||||
return;
|
||||
}
|
||||
displayInventoryWithItems(activeItems);
|
||||
std::cout << "Enter the index of the item to update: ";
|
||||
util::read(itemIndex);
|
||||
if (itemIndex < 1 || itemIndex > activeSize)
|
||||
{
|
||||
std::cout << "Invalid index selected." << std::endl;
|
||||
return;
|
||||
}
|
||||
std::cout << "Enter quantity to add: ";
|
||||
util::read(quantity);
|
||||
if (quantity < 0)
|
||||
{
|
||||
std::cout << "The quantity should be Greater than 0." << std::endl;
|
||||
return;
|
||||
}
|
||||
const InventoryItem* selectedItem = activeItems.getValueAt(itemIndex - 1);
|
||||
if (selectedItem != nullptr)
|
||||
{
|
||||
std::string selectedItemId = selectedItem->getId();
|
||||
m_controller.addInventoryItemStock(selectedItemId, quantity);
|
||||
std::cout << "Updated " << selectedItem->getPartName()
|
||||
<< " stock. New quantity: " << selectedItem->getQuantity()
|
||||
<< std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Error: Selected item could not be found." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Function: addInventoryItem
|
||||
Description: Allows the admin to either add a new inventory item
|
||||
@@ -366,7 +248,7 @@ void AdminMenu::removeInventoryItem()
|
||||
util::pressEnter();
|
||||
return;
|
||||
}
|
||||
const InventoryItem* selectedItem = inventoryItems.getValueAt(itemIndex - 1);
|
||||
const InventoryItem* selectedItem = activeItems.getValueAt(itemIndex - 1);
|
||||
if (selectedItem != nullptr)
|
||||
{
|
||||
if(selectedItem->getState() != util::State::INACTIVE)
|
||||
@@ -462,62 +344,6 @@ void AdminMenu::addTechnician()
|
||||
util::pressEnter();
|
||||
}
|
||||
|
||||
/*
|
||||
Function: filterActiveUsers
|
||||
Description: Filters out inactive users and returns a map of active users.
|
||||
Parameter: const util::Map<std::string, const User*>& listOfUsers - all users
|
||||
Return type: util::Map<std::string, const User*>
|
||||
*/
|
||||
static util::Map<std::string, const User*>
|
||||
filterActiveUsers(const util::Map<std::string, const User*>& listOfUsers)
|
||||
{
|
||||
util::Map<std::string, const User*> activeUsers;
|
||||
int inventorySize = listOfUsers.getSize();
|
||||
for (int index = 0; index < inventorySize; index++)
|
||||
{
|
||||
const User* user = listOfUsers.getValueAt(index);
|
||||
if (user != nullptr && user->getState() != util::State::INACTIVE)
|
||||
{
|
||||
activeUsers.insert(user->getId(), user);
|
||||
}
|
||||
}
|
||||
return activeUsers;
|
||||
}
|
||||
|
||||
/*
|
||||
Function: displayAllActiveUsers
|
||||
Description: Displays all active users in a tabular format with index, ID, username, and type.
|
||||
Parameter: util::Map<std::string, const User*>& activeUsers - active users list
|
||||
int activeUserCount - number of active users
|
||||
Return type: void
|
||||
*/
|
||||
static void displayAllActiveUsers(util::Map<std::string, const User*>& activeUsers, int activeUserCount)
|
||||
{
|
||||
std::cout << std::left << std::setw(10) << "Index"
|
||||
<< std::setw(15) << "User ID"
|
||||
<< std::setw(25) << "Username"
|
||||
<< std::setw(25) << "User Type"
|
||||
<< std::endl;
|
||||
for (int iterator = 0; iterator < activeUserCount; iterator++)
|
||||
{
|
||||
const User* user = activeUsers.getValueAt(iterator);
|
||||
if (user != nullptr)
|
||||
{
|
||||
std::cout << std::left << std::setw(10) << (iterator + 1)
|
||||
<< std::setw(15) << user->getId()
|
||||
<< std::setw(25) << user->getUserName()
|
||||
<< std::setw(25) << util::getUserTypeString(user->getUserType())
|
||||
<< std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "No users found.\n";
|
||||
util::pressEnter();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Function: removeUser
|
||||
Description: Removes a selected active user (customer or technician) from the system.
|
||||
@@ -556,55 +382,6 @@ void AdminMenu::removeUser()
|
||||
util::pressEnter();
|
||||
}
|
||||
|
||||
/*
|
||||
Function: selectServiceFromServices
|
||||
Description: Displays active services and allows the admin to select one by index.
|
||||
Parameter: const util::Map<std::string, const Service*>& services - list of services
|
||||
Return type: const Service* - selected service
|
||||
*/
|
||||
static const Service* selectServiceFromServices(const util::Map<std::string, const Service*>& services)
|
||||
{
|
||||
util::Map<int, const Service*> activeServicesMap;
|
||||
int currentIndex = 1;
|
||||
int userInputIndex;
|
||||
std::cout << std::left
|
||||
<< std::setw(10) << "Index"
|
||||
<< std::setw(15) << "Service ID"
|
||||
<< std::setw(25) << "Service Name"
|
||||
<< std::setw(15) << "Estimated Cost"
|
||||
<< std::endl;
|
||||
for (int index = 0; index < services.getSize(); index++)
|
||||
{
|
||||
const Service* currentService = services.getValueAt(index);
|
||||
if (currentService->getState() != util::State::ACTIVE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
activeServicesMap.insert(currentIndex, currentService);
|
||||
double partsCost = calculatePartsCost(currentService);
|
||||
std::cout << std::left
|
||||
<< std::setw(10) << currentIndex
|
||||
<< std::setw(15) << currentService->getId()
|
||||
<< std::setw(25) << currentService->getName()
|
||||
<< std::setw(15) << (currentService->getLaborCost() + partsCost)
|
||||
<< std::endl;
|
||||
currentIndex++;
|
||||
}
|
||||
if (activeServicesMap.getSize() == 0)
|
||||
{
|
||||
std::cout << "No active services available." << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
std::cout << "Enter service index: ";
|
||||
util::read(userInputIndex);
|
||||
if (activeServicesMap.find(userInputIndex) == -1)
|
||||
{
|
||||
std::cout << "Invalid service index." << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
return activeServicesMap[userInputIndex];
|
||||
}
|
||||
|
||||
/*
|
||||
Function: createComboPackages
|
||||
Description: Creates a new combo package by selecting two active services and applying a discount.
|
||||
@@ -615,19 +392,38 @@ void AdminMenu::createComboPackages()
|
||||
{
|
||||
util::clear();
|
||||
auto serviceList = m_controller.getServices();
|
||||
const int numberOfServicesInPackage = 2;
|
||||
const int NUMBER_OF_SERVICE_PER_PACKAGE = 2;
|
||||
util::Vector<std::string> selectedServiceID;
|
||||
for (int iterator = 0; iterator < numberOfServicesInPackage; iterator++)
|
||||
for (int iterator = 0; iterator < NUMBER_OF_SERVICE_PER_PACKAGE; iterator++)
|
||||
{
|
||||
const Service* chosenService = selectServiceFromServices(serviceList);
|
||||
if (chosenService == nullptr)
|
||||
const Service* chosenService = nullptr;
|
||||
while (true)
|
||||
{
|
||||
std::cout << "Failed to create combo package!";
|
||||
util::pressEnter();
|
||||
return;
|
||||
chosenService = selectServiceFromServices(serviceList);
|
||||
if (chosenService == nullptr)
|
||||
{
|
||||
std::cout << "Failed to create combo package!";
|
||||
util::pressEnter();
|
||||
return;
|
||||
}
|
||||
bool alreadyChosen = false;
|
||||
for (int iteratorOne = 0; iteratorOne < selectedServiceID.getSize(); iteratorOne++)
|
||||
{
|
||||
if (selectedServiceID[iteratorOne] == chosenService->getId())
|
||||
{
|
||||
alreadyChosen = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (alreadyChosen)
|
||||
{
|
||||
std::cout << "Service already selected. Please choose a different one." << std::endl;
|
||||
continue;
|
||||
}
|
||||
selectedServiceID.push_back(chosenService->getId());
|
||||
util::clear();
|
||||
break;
|
||||
}
|
||||
selectedServiceID.push_back(chosenService->getId());
|
||||
util::clear();
|
||||
}
|
||||
std::string packageName;
|
||||
double discountPercentage;
|
||||
@@ -646,81 +442,6 @@ void AdminMenu::createComboPackages()
|
||||
util::pressEnter();
|
||||
}
|
||||
|
||||
/*
|
||||
Function: displayComboPackagesWithIndex
|
||||
Description: Displays combo packages with index, ID, name, and discount percentage.
|
||||
Parameter: util::Map<int, const ComboPackage*>& currentComboPackageIndexMap - combo packages map
|
||||
Return type: void
|
||||
*/
|
||||
static void displayComboPackagesWithIndex(util::Map<int, const ComboPackage*>& currentComboPackageIndexMap)
|
||||
{
|
||||
for (int iterator = 0; iterator < currentComboPackageIndexMap.getSize(); iterator++)
|
||||
{
|
||||
const ComboPackage* currentComboPackage = currentComboPackageIndexMap.getValueAt(iterator);
|
||||
if (currentComboPackage == nullptr)
|
||||
{
|
||||
throw std::runtime_error("Error accessing the combopackage.\n");
|
||||
}
|
||||
if (iterator == 0)
|
||||
{
|
||||
std::cout << std::left
|
||||
<< std::setw(8) << "Index"
|
||||
<< std::setw(10) << "ID"
|
||||
<< std::setw(20) << "Package Name"
|
||||
<< std::setw(15) << "Discount (%)"
|
||||
<< "\n";
|
||||
}
|
||||
std::cout << std::left
|
||||
<< std::setw(8) << currentComboPackageIndexMap.getKeyAt(iterator)
|
||||
<< std::setw(10) << currentComboPackage->getId()
|
||||
<< std::setw(20) << currentComboPackage->getPackageName()
|
||||
<< std::setw(15) << currentComboPackage->getDiscountPercentage()
|
||||
<< "\n";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Function: selectComboPackage
|
||||
Description: Allows the admin to select an active combo package by index.
|
||||
Parameter: util::Map<std::string, const ComboPackage*>& currentComboPackages - combo packages list
|
||||
Return type: std::string - ID of the selected combo package
|
||||
*/
|
||||
static std::string selectComboPackage(util::Map<std::string, const ComboPackage*>& currentComboPackages)
|
||||
{
|
||||
util::Map<int, const ComboPackage*> currentComboPackageIndexMap;
|
||||
if (currentComboPackages.getSize() == 0)
|
||||
{
|
||||
throw std::runtime_error("No combo packages are available.\n");
|
||||
}
|
||||
int currentIndex = 1, choice, selectedIndex;
|
||||
for (int iterator = 0; iterator < currentComboPackages.getSize(); iterator++)
|
||||
{
|
||||
if (currentComboPackages.getValueAt(iterator)->getState() == util::State::INACTIVE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
currentComboPackageIndexMap.insert(currentIndex++, currentComboPackages.getValueAt(iterator));
|
||||
}
|
||||
if (currentComboPackageIndexMap.getSize() == 0)
|
||||
{
|
||||
throw std::runtime_error("No combo packages currently active.");
|
||||
}
|
||||
displayComboPackagesWithIndex(currentComboPackageIndexMap);
|
||||
std::cout << "Enter your choice(Index): ";
|
||||
util::read(choice);
|
||||
selectedIndex = currentComboPackageIndexMap.find(choice);
|
||||
if (selectedIndex != -1)
|
||||
{
|
||||
std::string selectedComboPackageID = currentComboPackageIndexMap.getValueAt(selectedIndex)->getId();
|
||||
return selectedComboPackageID;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Enter a valid choice.\n";
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Function: removeComboPackage
|
||||
Description: Removes a selected combo package from the system.
|
||||
|
||||
@@ -6,6 +6,7 @@ Description: Header file declaring the AdminMenu class, which provides
|
||||
Author: Trenser
|
||||
Date:19-May-2026
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "Controller.h"
|
||||
|
||||
|
||||
@@ -0,0 +1,333 @@
|
||||
/*
|
||||
File: MenuHelper.h
|
||||
Description: Header file declaring the MenuHelper class, which provides
|
||||
utility functions for menu-driven operations such as
|
||||
notification selection and display.
|
||||
Author: Trenser
|
||||
Date: 21-May-2026
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <string>
|
||||
#include "Utility.h"
|
||||
#include "Controller.h"
|
||||
#include "ComboPackage.h"
|
||||
|
||||
/*
|
||||
Function: filterActiveItems
|
||||
Description: Filters out inactive inventory items and returns a map
|
||||
containing only active items.
|
||||
Parameter: const util::Map<std::string, const InventoryItem*>& inventoryItems -
|
||||
map of all inventory items
|
||||
Return type: util::Map<std::string, const InventoryItem*>
|
||||
*/
|
||||
inline util::Map<std::string, const InventoryItem*> filterActiveItems(const util::Map<std::string, const InventoryItem*>& inventoryItems)
|
||||
{
|
||||
util::Map<std::string, const InventoryItem*> activeItems;
|
||||
int inventorySize = inventoryItems.getSize();
|
||||
for (int index = 0; index < inventorySize; index++)
|
||||
{
|
||||
const InventoryItem* item = inventoryItems.getValueAt(index);
|
||||
if (item != nullptr && item->getState() != util::State::INACTIVE)
|
||||
{
|
||||
activeItems.insert(item->getId(), item);
|
||||
}
|
||||
}
|
||||
return activeItems;
|
||||
}
|
||||
|
||||
/*
|
||||
Function: displayInventoryWithItems
|
||||
Description: Displays inventory items in a tabular format with index, ID,
|
||||
part name, quantity, and price.
|
||||
Parameter: util::Map<std::string, const InventoryItem*>& inventoryItems -
|
||||
map of inventory items to display
|
||||
Return type: void
|
||||
*/
|
||||
inline void displayInventoryWithItems(util::Map<std::string, const InventoryItem*>& inventoryItems)
|
||||
{
|
||||
int inventorySize = inventoryItems.getSize();
|
||||
std::cout << std::left << std::setw(10) << "Index"
|
||||
<< std::setw(15) << "Item ID"
|
||||
<< std::setw(25) << "Part Name"
|
||||
<< std::setw(10) << "Quantity"
|
||||
<< std::setw(10) << "Price"
|
||||
<< std::endl;
|
||||
for (int iterator = 0; iterator < inventorySize; iterator++)
|
||||
{
|
||||
const InventoryItem* item = inventoryItems.getValueAt(iterator);
|
||||
if (item != nullptr)
|
||||
{
|
||||
std::cout << std::left << std::setw(10) << (iterator + 1)
|
||||
<< std::setw(15) << item->getId()
|
||||
<< std::setw(25) << item->getPartName()
|
||||
<< std::setw(10) << item->getQuantity()
|
||||
<< std::setw(10) << item->getPrice()
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Function: addQuantityToItem
|
||||
Description: Allows the admin to select an active inventory item and
|
||||
increase its stock quantity.
|
||||
Parameter: util::Map<std::string, const InventoryItem*>& inventoryItems -
|
||||
map of inventory items
|
||||
Controller& m_controller - controller instance to update stock
|
||||
Return type: void
|
||||
*/
|
||||
inline void addQuantityToItem(util::Map<std::string, const InventoryItem*>& inventoryItems, Controller& m_controller)
|
||||
{
|
||||
int itemIndex;
|
||||
int quantity;
|
||||
auto activeItems = filterActiveItems(inventoryItems);
|
||||
int activeSize = activeItems.getSize();
|
||||
if (activeSize == 0)
|
||||
{
|
||||
std::cout << "No active items available in Inventory" << std::endl;
|
||||
return;
|
||||
}
|
||||
displayInventoryWithItems(activeItems);
|
||||
std::cout << "Enter the index of the item to update: ";
|
||||
util::read(itemIndex);
|
||||
if (itemIndex < 1 || itemIndex > activeSize)
|
||||
{
|
||||
std::cout << "Invalid index selected." << std::endl;
|
||||
return;
|
||||
}
|
||||
std::cout << "Enter quantity to add: ";
|
||||
util::read(quantity);
|
||||
if (quantity < 0)
|
||||
{
|
||||
std::cout << "The quantity should be Greater than 0." << std::endl;
|
||||
return;
|
||||
}
|
||||
const InventoryItem* selectedItem = activeItems.getValueAt(itemIndex - 1);
|
||||
if (selectedItem != nullptr)
|
||||
{
|
||||
std::string selectedItemId = selectedItem->getId();
|
||||
m_controller.addInventoryItemStock(selectedItemId, quantity);
|
||||
std::cout << "Updated " << selectedItem->getPartName()
|
||||
<< " stock. New quantity: " << selectedItem->getQuantity()
|
||||
<< std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Error: Selected item could not be found." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Function: changePassword
|
||||
Description: Allows the admin to change their password after validation.
|
||||
Parameter: None
|
||||
Return type: void
|
||||
*/
|
||||
inline void changePasswordHelper(Controller& controller)
|
||||
{
|
||||
util::clear();
|
||||
std::string newPassword;
|
||||
while (true)
|
||||
{
|
||||
util::clear();
|
||||
std::cout << "Enter new password: ";
|
||||
util::read(newPassword);
|
||||
if (!util::isPasswordValid(newPassword))
|
||||
{
|
||||
std::cout << "Error: Password is not strong enough!\n";
|
||||
util::pressEnter();
|
||||
continue;
|
||||
}
|
||||
controller.changePassword(newPassword);
|
||||
std::cout << "Password changed successfully\n";
|
||||
util::pressEnter();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Function: filterActiveUsers
|
||||
Description: Filters out inactive users and returns a map of active users.
|
||||
Parameter: const util::Map<std::string, const User*>& listOfUsers - all users
|
||||
Return type: util::Map<std::string, const User*>
|
||||
*/
|
||||
inline util::Map<std::string, const User*> filterActiveUsers(const util::Map<std::string, const User*>& listOfUsers)
|
||||
{
|
||||
util::Map<std::string, const User*> activeUsers;
|
||||
int inventorySize = listOfUsers.getSize();
|
||||
for (int index = 0; index < inventorySize; index++)
|
||||
{
|
||||
const User* user = listOfUsers.getValueAt(index);
|
||||
if (user != nullptr && user->getState() != util::State::INACTIVE)
|
||||
{
|
||||
activeUsers.insert(user->getId(), user);
|
||||
}
|
||||
}
|
||||
return activeUsers;
|
||||
}
|
||||
|
||||
/*
|
||||
Function: displayAllActiveUsers
|
||||
Description: Displays all active users in a tabular format with index, ID, username, and type.
|
||||
Parameter: util::Map<std::string, const User*>& activeUsers - active users list
|
||||
int activeUserCount - number of active users
|
||||
Return type: void
|
||||
*/
|
||||
inline void displayAllActiveUsers(util::Map<std::string, const User*>& activeUsers, int activeUserCount)
|
||||
{
|
||||
std::cout << std::left << std::setw(10) << "Index"
|
||||
<< std::setw(15) << "User ID"
|
||||
<< std::setw(25) << "Username"
|
||||
<< std::setw(25) << "User Type"
|
||||
<< std::endl;
|
||||
for (int iterator = 0; iterator < activeUserCount; iterator++)
|
||||
{
|
||||
const User* user = activeUsers.getValueAt(iterator);
|
||||
if (user != nullptr)
|
||||
{
|
||||
std::cout << std::left << std::setw(10) << (iterator + 1)
|
||||
<< std::setw(15) << user->getId()
|
||||
<< std::setw(25) << user->getUserName()
|
||||
<< std::setw(25) << util::getUserTypeString(user->getUserType())
|
||||
<< std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "No users found.\n";
|
||||
util::pressEnter();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Function: selectServiceFromServices
|
||||
Description: Displays active services and allows the admin to select one by index.
|
||||
Parameter: const util::Map<std::string, const Service*>& services - list of services
|
||||
Return type: const Service* - selected service
|
||||
*/
|
||||
inline const Service* selectServiceFromServices(const util::Map<std::string, const Service*>& services)
|
||||
{
|
||||
util::Map<int, const Service*> activeServicesMap;
|
||||
int currentIndex = 1;
|
||||
int userInputIndex;
|
||||
std::cout << std::left
|
||||
<< std::setw(10) << "Index"
|
||||
<< std::setw(15) << "Service ID"
|
||||
<< std::setw(25) << "Service Name"
|
||||
<< std::setw(15) << "Estimated Cost"
|
||||
<< std::endl;
|
||||
for (int index = 0; index < services.getSize(); index++)
|
||||
{
|
||||
const Service* currentService = services.getValueAt(index);
|
||||
if (currentService == nullptr)
|
||||
{
|
||||
throw std::runtime_error("Warning: Encountered a null service\n");
|
||||
continue;
|
||||
}
|
||||
if (currentService->getState() != util::State::ACTIVE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
activeServicesMap.insert(currentIndex, currentService);
|
||||
double partsCost = calculatePartsCost(currentService);
|
||||
std::cout << std::left
|
||||
<< std::setw(10) << currentIndex
|
||||
<< std::setw(15) << currentService->getId()
|
||||
<< std::setw(25) << currentService->getName()
|
||||
<< std::setw(15) << (currentService->getLaborCost() + partsCost)
|
||||
<< std::endl;
|
||||
currentIndex++;
|
||||
}
|
||||
if (activeServicesMap.getSize() == 0)
|
||||
{
|
||||
std::cout << "No active services available." << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
std::cout << "Enter service index: ";
|
||||
util::read(userInputIndex);
|
||||
if (activeServicesMap.find(userInputIndex) == -1)
|
||||
{
|
||||
std::cout << "Invalid service index." << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
return activeServicesMap[userInputIndex];
|
||||
}
|
||||
|
||||
/*
|
||||
Function: displayComboPackagesWithIndex
|
||||
Description: Displays combo packages with index, ID, name, and discount percentage.
|
||||
Parameter: util::Map<int, const ComboPackage*>& currentComboPackageIndexMap - combo packages map
|
||||
Return type: void
|
||||
*/
|
||||
inline void displayComboPackagesWithIndex(util::Map<int, const ComboPackage*>& currentComboPackageIndexMap)
|
||||
{
|
||||
for (int iterator = 0; iterator < currentComboPackageIndexMap.getSize(); iterator++)
|
||||
{
|
||||
const ComboPackage* currentComboPackage = currentComboPackageIndexMap.getValueAt(iterator);
|
||||
if (currentComboPackage == nullptr)
|
||||
{
|
||||
throw std::runtime_error("Error accessing the combopackage.\n");
|
||||
}
|
||||
if (iterator == 0)
|
||||
{
|
||||
std::cout << std::left
|
||||
<< std::setw(8) << "Index"
|
||||
<< std::setw(10) << "ID"
|
||||
<< std::setw(20) << "Package Name"
|
||||
<< std::setw(15) << "Discount (%)"
|
||||
<< "\n";
|
||||
}
|
||||
std::cout << std::left
|
||||
<< std::setw(8) << currentComboPackageIndexMap.getKeyAt(iterator)
|
||||
<< std::setw(10) << currentComboPackage->getId()
|
||||
<< std::setw(20) << currentComboPackage->getPackageName()
|
||||
<< std::setw(15) << currentComboPackage->getDiscountPercentage()
|
||||
<< "\n";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Function: selectComboPackage
|
||||
Description: Allows the admin to select an active combo package by index.
|
||||
Parameter: util::Map<std::string, const ComboPackage*>& currentComboPackages - combo packages list
|
||||
Return type: std::string - ID of the selected combo package
|
||||
*/
|
||||
inline std::string selectComboPackage(util::Map<std::string, const ComboPackage*>& currentComboPackages)
|
||||
{
|
||||
util::Map<int, const ComboPackage*> currentComboPackageIndexMap;
|
||||
if (currentComboPackages.getSize() == 0)
|
||||
{
|
||||
throw std::runtime_error("No combo packages are available.\n");
|
||||
}
|
||||
int currentIndex = 1, choice, selectedIndex;
|
||||
for (int iterator = 0; iterator < currentComboPackages.getSize(); iterator++)
|
||||
{
|
||||
if (currentComboPackages.getValueAt(iterator)->getState() == util::State::INACTIVE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
currentComboPackageIndexMap.insert(currentIndex++, currentComboPackages.getValueAt(iterator));
|
||||
}
|
||||
if (currentComboPackageIndexMap.getSize() == 0)
|
||||
{
|
||||
throw std::runtime_error("No combo packages currently active.");
|
||||
}
|
||||
displayComboPackagesWithIndex(currentComboPackageIndexMap);
|
||||
std::cout << "Enter your choice(Index): ";
|
||||
util::read(choice);
|
||||
selectedIndex = currentComboPackageIndexMap.find(choice);
|
||||
if (selectedIndex != -1)
|
||||
{
|
||||
std::string selectedComboPackageID = currentComboPackageIndexMap.getValueAt(selectedIndex)->getId();
|
||||
return selectedComboPackageID;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Enter a valid choice.\n";
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ Date:19-May-2026
|
||||
#include "InputHelper.h"
|
||||
#include "OutputHelper.h"
|
||||
#include "Validator.h"
|
||||
#include "MenuHelper.h"
|
||||
|
||||
/*
|
||||
Function: showMenu
|
||||
@@ -100,23 +101,8 @@ Description: Allows the technician to change their password after validation.
|
||||
Parameter: None
|
||||
Return type: void
|
||||
*/
|
||||
|
||||
void TechnicianMenu::changePassword()
|
||||
{
|
||||
std::string newPassword;
|
||||
while (true)
|
||||
{
|
||||
util::clear();
|
||||
std::cout << "Enter new password: ";
|
||||
util::read(newPassword);
|
||||
if (!util::isPasswordValid(newPassword))
|
||||
{
|
||||
std::cout << "Error: Password is not strong enough!\n";
|
||||
util::pressEnter();
|
||||
continue;
|
||||
}
|
||||
m_controller.changePassword(newPassword);
|
||||
std::cout << "Password changed successfully\n";
|
||||
util::pressEnter();
|
||||
break;
|
||||
}
|
||||
changePasswordHelper(m_controller);
|
||||
}
|
||||
@@ -6,6 +6,7 @@ Description: Header file declaring the TechnicianMenu class, which provides
|
||||
Author: Trenser
|
||||
Date:19-May-2026
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "Controller.h"
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ Description: Implementation file containing the method definitions of the
|
||||
Author: Trenser
|
||||
Date:19-May-2026
|
||||
*/
|
||||
|
||||
#include "UserInterface.h"
|
||||
#include "InputHelper.h"
|
||||
#include "OutputHelper.h"
|
||||
|
||||
@@ -7,6 +7,7 @@ Description: Header file declaring the UserInterface class, which provides
|
||||
Author: Trenser
|
||||
Date:19-May-2026
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "Controller.h"
|
||||
#include "AdminMenu.h"
|
||||
|
||||
Reference in New Issue
Block a user