Fix Assign Job to Technician issues and View invoices issues
- Assign Job to Technician: - Added heading for clearer user guidance. - Filtered only pending service bookings for assignment. - Improved technician listing and selection with clearer prompts. - Ensured booking status transitions correctly from PENDING to STARTED when job cards are created. - Enhanced feedback messages for technician availability and job card creation. - View Invoices: - Added heading "View Invoices" for better UI consistency. - Updated displayInvoices to take map by reference for efficiency. - Improved formatting of invoice details with consistent spacing and line breaks. - Added handling for empty invoice parts list (shows "No inventory items used"). - Enhanced error messages when encountering null invoices. Fixes #1745 Fixes #1752
This commit is contained in:
+4
-1
@@ -23,7 +23,6 @@ Date:19-May-2026
|
||||
#include "ServiceBooking.h"
|
||||
#include "ServiceManagementService.h"
|
||||
#include "Timestamp.h"
|
||||
#include "Timestamp.h"
|
||||
#include "User.h"
|
||||
#include "UserManagementService.h"
|
||||
#include "Utility.h"
|
||||
@@ -817,6 +816,10 @@ void ServiceManagementService::createJobCard(const std::string& bookingID, const
|
||||
}
|
||||
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());
|
||||
|
||||
+1
-1
@@ -315,7 +315,7 @@ util::Map<std::string, User*> UserManagementService::getUsers(util::UserType typ
|
||||
for (int iterator = 0; iterator < currentUsers.getSize(); iterator++)
|
||||
{
|
||||
User* currentUser = currentUsers.getValueAt(iterator);
|
||||
if (currentUser->getUserType() == type)
|
||||
if (currentUser && currentUser->getState() == util::State::ACTIVE && currentUser->getUserType() == type)
|
||||
{
|
||||
filteredUsersMap.insert(currentUser->getId(), currentUser);
|
||||
}
|
||||
|
||||
@@ -341,14 +341,16 @@ Returns:
|
||||
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 = currentBookings.getSize();
|
||||
int bookingsSize = pendingServiceBookings.getSize();
|
||||
util::Map<int, const ServiceBooking*> serviceBookingsMap;
|
||||
util::Map<int, const User*> currentAvailableTechniciansMap;
|
||||
if (listServiceBookings(currentBookings, bookingsSize, serviceBookingsMap))
|
||||
if (listServiceBookings(pendingServiceBookings, bookingsSize, serviceBookingsMap))
|
||||
{
|
||||
const ServiceBooking* selectedService = selectPendingServiceBookings(serviceBookingsMap);
|
||||
if (selectedService)
|
||||
@@ -364,14 +366,19 @@ void AdminMenu::assignJob()
|
||||
{
|
||||
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.";
|
||||
std::cout << "No technicians are currently available.\n\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "No pending service bookings available.\n\n";
|
||||
}
|
||||
util::pressEnter();
|
||||
}
|
||||
|
||||
|
||||
@@ -358,6 +358,7 @@ Returns:
|
||||
void CustomerMenu::viewInvoices()
|
||||
{
|
||||
util::clear();
|
||||
std::cout << "View Invoices\n";
|
||||
util::Map<std::string, const Invoice*> currentUserInvoices = m_controller.getInvoicesByUser();
|
||||
displayInvoices(currentUserInvoices);
|
||||
util::pressEnter();
|
||||
|
||||
@@ -154,6 +154,28 @@ inline void selectInventoryItems(util::Map<std::string, const InventoryItem*>& c
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Function: filterActiveServiceBookings
|
||||
Description: Filters the given service bookings and returns only bookings with PENDING status.
|
||||
Parameters:
|
||||
- currentBookings: util::Map<std::string, const ServiceBooking*>, collection of current service bookings
|
||||
Returns:
|
||||
- util::Map<std::string, const ServiceBooking*>: map containing only active (PENDING) service bookings
|
||||
*/
|
||||
inline util::Map<std::string, const ServiceBooking*> filterActiveServiceBookings(util::Map<std::string, const ServiceBooking*> currentBookings)
|
||||
{
|
||||
util::Map<std::string, const ServiceBooking*> activeServcieBookings;
|
||||
for (int iterator = 0; iterator < currentBookings.getSize(); iterator++)
|
||||
{
|
||||
const ServiceBooking* currentServiceBooking = currentBookings.getValueAt(iterator);
|
||||
if (currentServiceBooking && currentServiceBooking->getStatus() == util::ServiceJobStatus::PENDING)
|
||||
{
|
||||
activeServcieBookings.insert(currentServiceBooking->getId(), currentServiceBooking);
|
||||
}
|
||||
}
|
||||
return activeServcieBookings;
|
||||
}
|
||||
|
||||
/*
|
||||
Function: listServiceBookings
|
||||
Description: Lists all pending service bookings and maps them to indices for selection.
|
||||
@@ -166,8 +188,12 @@ Returns:
|
||||
*/
|
||||
inline bool listServiceBookings(util::Map<std::string, const ServiceBooking*>& currentBookings, int& bookingsSize, util::Map<int, const ServiceBooking*>& serviceBookingsMap)
|
||||
{
|
||||
if (currentBookings.getSize() == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
int currentIndex = 1;
|
||||
bool hasPendingService = false;
|
||||
std::cout << "\nSelect Service Booking" << std::endl;
|
||||
std::cout << std::left
|
||||
<< std::setw(10) << "Index"
|
||||
<< std::setw(10) << "ID"
|
||||
@@ -185,7 +211,6 @@ inline bool listServiceBookings(util::Map<std::string, const ServiceBooking*>& c
|
||||
const ServiceBooking* currentBooking = currentBookings.getValueAt(iterator);
|
||||
if (currentBooking && currentBooking->getStatus() == util::ServiceJobStatus::PENDING)
|
||||
{
|
||||
hasPendingService = true;
|
||||
const User* currentAssignedTechnician = currentBooking->getAssignedTechnician();
|
||||
std::cout << std::left
|
||||
<< std::setw(10) << currentIndex
|
||||
@@ -196,16 +221,11 @@ inline bool listServiceBookings(util::Map<std::string, const ServiceBooking*>& c
|
||||
<< std::setw(15) << currentBooking->getVehicleNumber()
|
||||
<< std::setw(15) << currentBooking->getVehicleBrand()
|
||||
<< std::setw(15) << currentBooking->getVehicleModel()
|
||||
<< std::setw(20) << ((currentAssignedTechnician == nullptr || currentAssignedTechnician->getName().empty()) ? "Null" : currentAssignedTechnician->getName())
|
||||
<< std::setw(15) << ((currentAssignedTechnician == nullptr || currentAssignedTechnician->getId().empty()) ? "Null" : currentAssignedTechnician->getId())
|
||||
<< std::setw(20) << ((currentAssignedTechnician == nullptr || currentAssignedTechnician->getName().empty()) ? "NULL" : currentAssignedTechnician->getName())
|
||||
<< std::setw(15) << ((currentAssignedTechnician == nullptr || currentAssignedTechnician->getId().empty()) ? "NULL" : currentAssignedTechnician->getId())
|
||||
<< std::endl;
|
||||
serviceBookingsMap.insert(currentIndex++, currentBooking);
|
||||
}
|
||||
}
|
||||
if (!hasPendingService)
|
||||
{
|
||||
std::cout << "No pending service available." << std::endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -221,15 +241,15 @@ Returns:
|
||||
inline const ServiceBooking* selectPendingServiceBookings(util::Map<int, const ServiceBooking*>& serviceBookingsMap)
|
||||
{
|
||||
int userInputIndex;
|
||||
std::cout << "Enter a valid service index: ";
|
||||
std::cout << "\nEnter a valid service index: ";
|
||||
util::read(userInputIndex);
|
||||
if (serviceBookingsMap.find(userInputIndex) != -1)
|
||||
{
|
||||
return serviceBookingsMap.getValueAt(userInputIndex);
|
||||
return serviceBookingsMap.getValueAt(serviceBookingsMap.find(userInputIndex));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Enter a valid index.";
|
||||
std::cout << "Enter a valid index.\n\n";
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@@ -248,6 +268,7 @@ inline void listAvailableTechnicians(util::Map<std::string, const User*> current
|
||||
{
|
||||
bool hasTechnicians = false;
|
||||
int currentIndex = 1;
|
||||
std::cout << "\nSelect Technician\n";
|
||||
std::cout << std::left
|
||||
<< std::setw(6) << "Index"
|
||||
<< std::setw(15) << "Technician ID"
|
||||
@@ -270,7 +291,7 @@ inline void listAvailableTechnicians(util::Map<std::string, const User*> current
|
||||
}
|
||||
if (!hasTechnicians)
|
||||
{
|
||||
std::cout << "No technicians currently available.";
|
||||
std::cout << "No technicians currently available.\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,16 +304,17 @@ Returns:
|
||||
- const User*: Pointer to the selected technician, or nullptr if invalid
|
||||
*/
|
||||
inline const User* selectTechnician(util::Map<int, const User*>& currentAvailableTechniciansMap)
|
||||
{
|
||||
{
|
||||
int userInputIndex;
|
||||
std::cout << "\nEnter valid technician index: ";
|
||||
util::read(userInputIndex);
|
||||
if (currentAvailableTechniciansMap.find(userInputIndex) != -1)
|
||||
{
|
||||
return currentAvailableTechniciansMap.getValueAt(userInputIndex);
|
||||
return currentAvailableTechniciansMap.getValueAt(currentAvailableTechniciansMap.find(userInputIndex));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Enter a valid index.";
|
||||
std::cout << "Enter a valid index.\n\n";
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@@ -408,8 +430,7 @@ inline void displayInvoices(util::Map<std::string, const Invoice*> currentUserIn
|
||||
{
|
||||
if (currentUserInvoices.getSize() == 0)
|
||||
{
|
||||
std::cout << "No invoices found for this account." << std::endl;
|
||||
util::pressEnter();
|
||||
std::cout << "No invoices found for this account." << std::endl << std::endl;
|
||||
return;
|
||||
}
|
||||
else
|
||||
@@ -435,6 +456,11 @@ inline void displayInvoices(util::Map<std::string, const Invoice*> currentUserIn
|
||||
std::cout << "Invoice Date: " << currentInvoice->getInvoiceDate().toString() << std::endl;
|
||||
std::cout << "Payment Status: " << util::getPaymentStatusString(currentInvoice->getStatus()) << std::endl;
|
||||
auto inventoryItemsInInvoice = currentInvoice->getParts();
|
||||
if (inventoryItemsInInvoice.isEmpty())
|
||||
{
|
||||
std::cout << "No inventory items used.\n\n";
|
||||
continue;
|
||||
}
|
||||
std::cout << "\nItems Used:\n";
|
||||
std::cout << std::left
|
||||
<< std::setw(20) << "ItemName"
|
||||
@@ -451,7 +477,7 @@ inline void displayInvoices(util::Map<std::string, const Invoice*> currentUserIn
|
||||
<< std::setw(10) << currentItem->getPrice()
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("Null invoice encountered while displaying invoices.");
|
||||
|
||||
Reference in New Issue
Block a user