615 lines
18 KiB
C++
615 lines
18 KiB
C++
/*
|
|
File: AdminMenu.cpp
|
|
Description: Implementation file containing the method definitions of the
|
|
AdminMenu class, including menu handling, inventory operations,
|
|
and stock management functions.
|
|
Author: Trenser
|
|
Date:19-May-2026
|
|
*/
|
|
#include <iomanip>
|
|
#include "AdminMenu.h"
|
|
#include "InputHelper.h"
|
|
#include "OutputHelper.h"
|
|
#include "ServiceBooking.h"
|
|
#include "Enums.h"
|
|
#include "Service.h"
|
|
#include "InventoryItem.h"
|
|
|
|
/*
|
|
Function: showMenu
|
|
Description: Displays the admin menu and handles user input until the menu is exited.
|
|
Parameter: None
|
|
Return type: void
|
|
*/
|
|
void AdminMenu::showMenu()
|
|
{
|
|
bool isMenuActive = true;
|
|
while (isMenuActive)
|
|
{
|
|
try
|
|
{
|
|
int choice;
|
|
util::clear();
|
|
std::cout << "" << std::endl;
|
|
util::read(choice);
|
|
if (!handleOperation(choice))
|
|
{
|
|
isMenuActive = false;
|
|
}
|
|
}
|
|
catch (const std::exception& e)
|
|
{
|
|
std::cout << "Exception: " << e.what() << std::endl;
|
|
util::pressEnter();
|
|
}
|
|
}
|
|
}
|
|
|
|
bool AdminMenu::handleOperation(int choice)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
|
|
void AdminMenu::logout()
|
|
{
|
|
}
|
|
|
|
void AdminMenu::changePassword()
|
|
{
|
|
}
|
|
|
|
/*
|
|
Function: viewStockLevels
|
|
Description: Displays all active inventory items with their details
|
|
including ID, part name, quantity, and price.
|
|
Parameter: None
|
|
Return type: void
|
|
*/
|
|
void AdminMenu::viewStockLevels()
|
|
{
|
|
auto inventoryItems = m_controller.getInventoryItems();
|
|
std::cout << std::left << 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 < inventoryItems.getSize(); ++iterator)
|
|
{
|
|
const InventoryItem* item = inventoryItems.getValueAt(iterator);
|
|
if (item != nullptr)
|
|
{
|
|
if (item->getState() != util::State::INACTIVE)
|
|
{
|
|
std::cout << std::left << std::setw(15) << item->getId()
|
|
<< std::setw(25) << item->getPartName()
|
|
<< std::setw(10) << item->getQuantity()
|
|
<< std::setw(10) << item->getPrice()
|
|
<< std::endl;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
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
|
|
or increase the quantity of an existing item.
|
|
Parameter: None
|
|
Return type: void
|
|
*/
|
|
void AdminMenu::addInventoryItem()
|
|
{
|
|
util::clear();
|
|
int choice, quantity;
|
|
double price;
|
|
std::string partName;
|
|
std::cout << "1. Add new item \n2. Add Quantity\nEnter your choice : ";
|
|
util::read(choice);
|
|
switch (choice)
|
|
{
|
|
case 1:
|
|
{
|
|
std::cout << "--------Enter Item Details----------\n";
|
|
std::cout << "Part Name : ";
|
|
util::read(partName);
|
|
std::cout << "Quantity : ";
|
|
util::read(quantity);
|
|
std::cout << "Price : ";
|
|
util::read(price);
|
|
m_controller.addInventoryItem(partName, quantity, price);
|
|
std::cout << "New Item " << partName << " added to the Inventory.\n";
|
|
break;
|
|
}
|
|
case 2:
|
|
{
|
|
auto inventoryItems = m_controller.getInventoryItems();
|
|
addQuantityToItem(inventoryItems, m_controller);
|
|
break;
|
|
}
|
|
}
|
|
util::pressEnter();
|
|
}
|
|
|
|
/*
|
|
Function: removeInventoryItem
|
|
Description: Removes an active inventory item by marking it inactive
|
|
after user selection.
|
|
Parameter: None
|
|
Return type: void
|
|
*/
|
|
void AdminMenu::removeInventoryItem()
|
|
{
|
|
util::clear();
|
|
auto inventoryItems = m_controller.getInventoryItems();
|
|
auto activeItems = filterActiveItems(inventoryItems);
|
|
int activeItemsSize = activeItems.getSize();
|
|
if (activeItemsSize == 0)
|
|
{
|
|
std::cout << "No items available in Inventory." << std::endl;
|
|
util::pressEnter();
|
|
return;
|
|
}
|
|
displayInventoryWithItems(activeItems);
|
|
int itemIndex;
|
|
std::cout << "Enter the index of the item to remove: ";
|
|
util::read(itemIndex);
|
|
if (itemIndex < 1 || itemIndex > activeItemsSize)
|
|
{
|
|
std::cout << "Invalid index selected." << std::endl;
|
|
util::pressEnter();
|
|
return;
|
|
}
|
|
const InventoryItem* selectedItem = inventoryItems.getValueAt(itemIndex - 1);
|
|
if (selectedItem != nullptr)
|
|
{
|
|
if(selectedItem->getState() != util::State::INACTIVE)
|
|
{
|
|
std::string selectedItemId = selectedItem->getId();
|
|
m_controller.removeInventoryItem(selectedItemId);
|
|
std::cout << "Item " << selectedItem->getPartName() << " removed successfully." << std::endl;
|
|
}
|
|
}
|
|
util::pressEnter();
|
|
}
|
|
|
|
/*
|
|
Function: checkStockAvailability
|
|
Description: Checks if a specific inventory item is available
|
|
and displays its details if active.
|
|
Parameter: None
|
|
Return type: void
|
|
*/
|
|
void AdminMenu::checkStockAvailability()
|
|
{
|
|
util::clear();
|
|
std::string itemId;
|
|
std::cout << "Enter the Item Id : ";
|
|
util::read(itemId);
|
|
const InventoryItem* selectedItem = m_controller.getInventoryItem(itemId);
|
|
if (selectedItem != nullptr)
|
|
{
|
|
if (selectedItem->getState() != util::State::INACTIVE)
|
|
{
|
|
std::cout << "Item Details\n";
|
|
std::cout << "---------------------------------------------\n";
|
|
std::cout << "Item ID : " << selectedItem->getId() << "\n";
|
|
std::cout << "Part Name : " << selectedItem->getPartName() << "\n";
|
|
std::cout << "Quantity : " << selectedItem->getQuantity() << "\n";
|
|
}
|
|
}
|
|
util::pressEnter();
|
|
}
|
|
|
|
static bool listServiceBookings(util::Map<std::string, const ServiceBooking*>& currentBookings, int& bookingsSize, util::Map<int, const ServiceBooking*>& serviceBookingsMap)
|
|
{
|
|
int currentIndex = 1;
|
|
bool hasPendingService = false;
|
|
std::cout << std::left
|
|
<< std::setw(10) << "Index"
|
|
<< std::setw(10) << "ID"
|
|
<< std::setw(12) << "Status"
|
|
<< std::setw(12) << "CustID"
|
|
<< std::setw(20) << "Customer"
|
|
<< std::setw(15) << "VehicleNo"
|
|
<< std::setw(15) << "Brand"
|
|
<< std::setw(15) << "Model"
|
|
<< std::setw(20) << "Technician"
|
|
<< std::setw(15) << "TechID"
|
|
<< std::endl;
|
|
for (int iterator = 0; iterator < bookingsSize; iterator++)
|
|
{
|
|
const ServiceBooking* currentBooking = currentBookings.getValueAt(iterator);
|
|
if (currentBooking && currentBooking->getStatus() == util::ServiceJobStatus::PENDING)
|
|
{
|
|
hasPendingService = true;
|
|
std::cout << std::left
|
|
<< std::setw(10) << currentIndex
|
|
<< std::setw(10) << currentBooking->getId()
|
|
<< std::setw(12) << util::getServiceJobStatusString(currentBooking->getStatus())
|
|
<< std::setw(12) << currentBooking->getCustomerId()
|
|
<< std::setw(20) << currentBooking->getCustomer()->getName()
|
|
<< std::setw(15) << currentBooking->getVehicleNumber()
|
|
<< std::setw(15) << currentBooking->getVehicleBrand()
|
|
<< std::setw(15) << currentBooking->getVehicleModel()
|
|
<< std::setw(20) << (currentBooking->getAssignedTechnician() == nullptr ? "Null" : currentBooking->getAssignedTechnician()->getName())
|
|
<< std::setw(15) << (currentBooking->getAssignedTechnicianId().empty() ? "Null" : currentBooking->getAssignedTechnicianId())
|
|
<< std::endl;
|
|
serviceBookingsMap.insert(currentIndex++, currentBooking);
|
|
}
|
|
}
|
|
if (!hasPendingService)
|
|
{
|
|
std::cout << "No pending service available." << std::endl;
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static const ServiceBooking* selectPendingServiceBookings(util::Map<int, const ServiceBooking*>& serviceBookingsMap)
|
|
{
|
|
int userInputIndex;
|
|
std::cout << "Enter a valid service index: ";
|
|
util::read(userInputIndex);
|
|
if (serviceBookingsMap.find(userInputIndex) != -1)
|
|
{
|
|
return serviceBookingsMap.getValueAt(userInputIndex);
|
|
}
|
|
else
|
|
{
|
|
std::cout << "Enter a valid index.";
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
static void listAvailableTechnicians( util::Map<std::string, const User*> currentAvailableTechnicians, int numberOfTechnicians, util::Map<int, const User*>& currentAvailableTechniciansMap)
|
|
{
|
|
bool hasTechnicians = false;
|
|
int currentIndex = 1;
|
|
std::cout << std::left
|
|
<< std::setw(6) << "Index"
|
|
<< std::setw(15) << "Technician ID"
|
|
<< std::setw(20) << "Name"
|
|
<< std::endl;
|
|
for (int iterator = 0; iterator < numberOfTechnicians; iterator++)
|
|
{
|
|
const User* currentTechnician = currentAvailableTechnicians.getValueAt(iterator);
|
|
if (currentTechnician->getState() == util::State::INACTIVE)
|
|
{
|
|
continue;
|
|
}
|
|
hasTechnicians = true;
|
|
std::cout << std::left
|
|
<< std::setw(6) << currentIndex
|
|
<< std::setw(15) << currentTechnician->getId()
|
|
<< std::setw(20) << currentTechnician->getName()
|
|
<< std::endl;
|
|
currentAvailableTechniciansMap.insert(currentIndex++, currentTechnician);
|
|
}
|
|
if (!hasTechnicians)
|
|
{
|
|
std::cout << "No technicians currently available.";
|
|
}
|
|
}
|
|
|
|
static const User* selectTechnician(util::Map<int, const User*>& currentAvailableTechniciansMap)
|
|
{
|
|
int userInputIndex;
|
|
util::read(userInputIndex);
|
|
if (currentAvailableTechniciansMap.find(userInputIndex) != -1)
|
|
{
|
|
return currentAvailableTechniciansMap.getValueAt(userInputIndex);
|
|
}
|
|
else
|
|
{
|
|
std::cout << "Enter a valid index.";
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
void AdminMenu::assignJob()
|
|
{
|
|
util::clear();
|
|
std::string selectedService;
|
|
bool hasPendingService = false;
|
|
auto currentBookings = m_controller.getServiceBookings();
|
|
auto availableTechnicians = m_controller.getUsers(util::UserType::TECHNICIAN);
|
|
int bookingsSize = currentBookings.getSize();
|
|
util::Map<int, const ServiceBooking*> serviceBookingsMap;
|
|
util::Map<int, const User*> currentAvailableTechniciansMap;
|
|
if (listServiceBookings(currentBookings, 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());
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
std::cout << "No technicians are currently available.";
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
static void selectInventoryItems(util::Map<std::string, const InventoryItem*>& currentInventoryItems, util::Vector<std::string>& selectedInventoryItems)
|
|
{
|
|
bool doRun = true, hasInventoryItems = false;
|
|
util::Map<int, const InventoryItem*> currentInventoryMap;
|
|
int currentIndex = 1;
|
|
int choice;
|
|
if (currentInventoryItems.getSize() == 0)
|
|
{
|
|
std::cout << "Inventory empty.";
|
|
}
|
|
while (doRun)
|
|
{
|
|
bool hasInventoryItems = false;
|
|
int currentIndex = 1;
|
|
currentInventoryMap.clear();
|
|
std::cout << std::left
|
|
<< std::setw(6) << "Index"
|
|
<< std::setw(12) << "Item ID"
|
|
<< std::setw(20) << "Part Name"
|
|
<< std::setw(10) << "Price"
|
|
<< std::setw(10) << "Quantity"
|
|
<< std::endl;
|
|
for (int iterator = 0; iterator < currentInventoryItems.getSize(); iterator++)
|
|
{
|
|
const InventoryItem* currentInventoryItem = currentInventoryItems.getValueAt(iterator);
|
|
if (currentInventoryItem->getState() == util::State::INACTIVE)
|
|
{
|
|
continue;
|
|
}
|
|
std::cout << std::left
|
|
<< std::setw(6) << currentIndex
|
|
<< std::setw(12) << currentInventoryItem->getId()
|
|
<< std::setw(20) << currentInventoryItem->getPartName()
|
|
<< std::setw(10) << currentInventoryItem->getPrice()
|
|
<< std::setw(10) << currentInventoryItem->getQuantity()
|
|
<< std::endl;
|
|
|
|
hasInventoryItems = true;
|
|
currentInventoryMap.insert(currentIndex++, currentInventoryItem);
|
|
}
|
|
if (!hasInventoryItems)
|
|
{
|
|
std::cout << "No items present in the inventory." << std::endl;
|
|
doRun = false;
|
|
break;
|
|
}
|
|
std::cout << "Select the item (Index) or enter -1 to exit: ";
|
|
util::read(choice);
|
|
|
|
if (choice == -1)
|
|
{
|
|
doRun = false;
|
|
}
|
|
else if (currentInventoryMap.find(choice) != -1)
|
|
{
|
|
selectedInventoryItems.push_back(currentInventoryMap.getValueAt(choice)->getId());
|
|
std::cout << "Item added successfully." << std::endl;
|
|
}
|
|
else
|
|
{
|
|
std::cout << "Enter a valid integer." << std::endl;
|
|
}
|
|
}
|
|
}
|
|
|
|
void AdminMenu::createService()
|
|
{
|
|
util::clear();
|
|
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::Vector<std::string> selectedInventoryItems;
|
|
selectInventoryItems(currentInventoryItems,selectedInventoryItems);
|
|
std::cout << "Enter the labour cost: ";
|
|
util::read(labourCost);
|
|
m_controller.createService(serviceName, selectedInventoryItems, labourCost);
|
|
std::cout << "Service created sucessfully.\n";
|
|
}
|
|
|
|
static std::string selectServicesToRemove(util::Map<std::string, const Service*> currentServices)
|
|
{
|
|
util::Map<int, const Service*> currentServicesMap;
|
|
bool hasServices = false;
|
|
int currentIndex = 1, choice;
|
|
std::cout << std::left
|
|
<< std::setw(6) << "Index"
|
|
<< std::setw(12) << "Service ID"
|
|
<< std::setw(20) << "Name"
|
|
<< std::setw(10) << "Labor Cost"
|
|
<< std::endl;
|
|
for (int iterator = 0; iterator < currentServices.getSize(); iterator++)
|
|
{
|
|
const Service* currentService = currentServices.getValueAt(iterator);
|
|
if (currentService->getState() == util::State::INACTIVE)
|
|
{
|
|
continue;
|
|
}
|
|
std::cout << std::left
|
|
<< std::setw(6) << currentIndex
|
|
<< std::setw(12) << currentService->getId()
|
|
<< std::setw(20) << currentService->getName()
|
|
<< std::setw(10) << currentService->getLaborCost()
|
|
<< std::endl;
|
|
hasServices = true;
|
|
currentServicesMap.insert(currentIndex++, currentService);
|
|
}
|
|
if (!hasServices)
|
|
{
|
|
std::cout << "No services currently available." << std::endl;
|
|
return "";
|
|
}
|
|
std::cout << "Enter your choice: ";
|
|
util::read(choice);
|
|
if (currentServicesMap.find(choice) != -1)
|
|
{
|
|
return currentServicesMap.getValueAt(currentServicesMap.find(choice))->getId();
|
|
}
|
|
else
|
|
{
|
|
std::cout << "Invalid choice." << std::endl;
|
|
return "";
|
|
}
|
|
}
|
|
|
|
void AdminMenu::removeService()
|
|
{
|
|
util::clear();
|
|
std::string selectedServiceID;
|
|
util::Map<std::string, const Service*> currentServices = m_controller.getServices();
|
|
selectedServiceID = selectServicesToRemove(currentServices);
|
|
if (selectedServiceID != "")
|
|
{
|
|
m_controller.removeService(selectedServiceID);
|
|
std::cout << "Service removed sucessfully.";
|
|
}
|
|
else
|
|
{
|
|
std::cout << "Failed to remove service.";
|
|
}
|
|
}
|
|
|
|
void AdminMenu::addTechnician()
|
|
{
|
|
}
|
|
|
|
void AdminMenu::removeUser()
|
|
{
|
|
}
|
|
|
|
void AdminMenu::createComboPackages()
|
|
{
|
|
}
|
|
|
|
void AdminMenu::removeComboPackage()
|
|
{
|
|
}
|
|
|
|
void AdminMenu::viewNotifications()
|
|
{
|
|
}
|