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 "ServiceBooking.h"
|
||||||
#include "ServiceManagementService.h"
|
#include "ServiceManagementService.h"
|
||||||
#include "Timestamp.h"
|
#include "Timestamp.h"
|
||||||
#include "Timestamp.h"
|
|
||||||
#include "User.h"
|
#include "User.h"
|
||||||
#include "UserManagementService.h"
|
#include "UserManagementService.h"
|
||||||
#include "Utility.h"
|
#include "Utility.h"
|
||||||
@@ -817,6 +816,10 @@ void ServiceManagementService::createJobCard(const std::string& bookingID, const
|
|||||||
}
|
}
|
||||||
currentBooking->setAssignedTechnician(selectedTechnician);
|
currentBooking->setAssignedTechnician(selectedTechnician);
|
||||||
currentBooking->setAssignedTechnicianId(selectedTechnician->getId());
|
currentBooking->setAssignedTechnicianId(selectedTechnician->getId());
|
||||||
|
if (currentBooking->getStatus() == util::ServiceJobStatus::PENDING)
|
||||||
|
{
|
||||||
|
currentBooking->setStatus(util::ServiceJobStatus::STARTED);
|
||||||
|
}
|
||||||
std::string title = "Job card created";
|
std::string title = "Job card created";
|
||||||
std::string message = "Job card created for the service and you are assigned for that.";
|
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());
|
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++)
|
for (int iterator = 0; iterator < currentUsers.getSize(); iterator++)
|
||||||
{
|
{
|
||||||
User* currentUser = currentUsers.getValueAt(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);
|
filteredUsersMap.insert(currentUser->getId(), currentUser);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -341,14 +341,16 @@ Returns:
|
|||||||
void AdminMenu::assignJob()
|
void AdminMenu::assignJob()
|
||||||
{
|
{
|
||||||
util::clear();
|
util::clear();
|
||||||
|
std::cout << "Assign Job to Technician\n";
|
||||||
std::string selectedService;
|
std::string selectedService;
|
||||||
bool hasPendingService = false;
|
bool hasPendingService = false;
|
||||||
auto currentBookings = m_controller.getServiceBookings();
|
auto currentBookings = m_controller.getServiceBookings();
|
||||||
|
auto pendingServiceBookings = filterActiveServiceBookings(currentBookings);
|
||||||
auto availableTechnicians = m_controller.getUsers(util::UserType::TECHNICIAN);
|
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 ServiceBooking*> serviceBookingsMap;
|
||||||
util::Map<int, const User*> currentAvailableTechniciansMap;
|
util::Map<int, const User*> currentAvailableTechniciansMap;
|
||||||
if (listServiceBookings(currentBookings, bookingsSize, serviceBookingsMap))
|
if (listServiceBookings(pendingServiceBookings, bookingsSize, serviceBookingsMap))
|
||||||
{
|
{
|
||||||
const ServiceBooking* selectedService = selectPendingServiceBookings(serviceBookingsMap);
|
const ServiceBooking* selectedService = selectPendingServiceBookings(serviceBookingsMap);
|
||||||
if (selectedService)
|
if (selectedService)
|
||||||
@@ -364,14 +366,19 @@ void AdminMenu::assignJob()
|
|||||||
{
|
{
|
||||||
m_controller.createJobCard(selectedService->getId(), selectedTechnician->getId(), servicesInBooking.getValueAt(iterator)->getId());
|
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
|
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();
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -358,6 +358,7 @@ Returns:
|
|||||||
void CustomerMenu::viewInvoices()
|
void CustomerMenu::viewInvoices()
|
||||||
{
|
{
|
||||||
util::clear();
|
util::clear();
|
||||||
|
std::cout << "View Invoices\n";
|
||||||
util::Map<std::string, const Invoice*> currentUserInvoices = m_controller.getInvoicesByUser();
|
util::Map<std::string, const Invoice*> currentUserInvoices = m_controller.getInvoicesByUser();
|
||||||
displayInvoices(currentUserInvoices);
|
displayInvoices(currentUserInvoices);
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
@@ -393,4 +394,4 @@ void CustomerMenu::configureNotifications()
|
|||||||
util::clear();
|
util::clear();
|
||||||
std::cout << "Notification preferences updated successfully.\n";
|
std::cout << "Notification preferences updated successfully.\n";
|
||||||
util::pressEnter();
|
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
|
Function: listServiceBookings
|
||||||
Description: Lists all pending service bookings and maps them to indices for selection.
|
Description: Lists all pending service bookings and maps them to indices for selection.
|
||||||
@@ -166,48 +188,46 @@ Returns:
|
|||||||
*/
|
*/
|
||||||
inline bool listServiceBookings(util::Map<std::string, const ServiceBooking*>& currentBookings, int& bookingsSize, util::Map<int, const ServiceBooking*>& serviceBookingsMap)
|
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;
|
int currentIndex = 1;
|
||||||
bool hasPendingService = false;
|
std::cout << "\nSelect Service Booking" << std::endl;
|
||||||
std::cout << std::left
|
std::cout << std::left
|
||||||
<< std::setw(10) << "Index"
|
<< std::setw(10) << "Index"
|
||||||
<< std::setw(10) << "ID"
|
<< std::setw(10) << "ID"
|
||||||
<< std::setw(12) << "Status"
|
<< std::setw(12) << "Status"
|
||||||
<< std::setw(12) << "CustID"
|
<< std::setw(12) << "CustID"
|
||||||
<< std::setw(20) << "Customer"
|
<< std::setw(20) << "Customer"
|
||||||
<< std::setw(15) << "VehicleNo"
|
<< std::setw(15) << "VehicleNo"
|
||||||
<< std::setw(15) << "Brand"
|
<< std::setw(15) << "Brand"
|
||||||
<< std::setw(15) << "Model"
|
<< std::setw(15) << "Model"
|
||||||
<< std::setw(20) << "Technician"
|
<< std::setw(20) << "Technician"
|
||||||
<< std::setw(15) << "TechnicianID"
|
<< std::setw(15) << "TechnicianID"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
for (int iterator = 0; iterator < bookingsSize; iterator++)
|
for (int iterator = 0; iterator < bookingsSize; iterator++)
|
||||||
{
|
{
|
||||||
const ServiceBooking* currentBooking = currentBookings.getValueAt(iterator);
|
const ServiceBooking* currentBooking = currentBookings.getValueAt(iterator);
|
||||||
if (currentBooking && currentBooking->getStatus() == util::ServiceJobStatus::PENDING)
|
if (currentBooking && currentBooking->getStatus() == util::ServiceJobStatus::PENDING)
|
||||||
{
|
{
|
||||||
hasPendingService = true;
|
const User* currentAssignedTechnician = currentBooking->getAssignedTechnician();
|
||||||
const User* currentAssignedTechnician = currentBooking->getAssignedTechnician();
|
std::cout << std::left
|
||||||
std::cout << std::left
|
<< std::setw(10) << currentIndex
|
||||||
<< std::setw(10) << currentIndex
|
<< std::setw(10) << currentBooking->getId()
|
||||||
<< std::setw(10) << currentBooking->getId()
|
<< std::setw(12) << util::getServiceJobStatusString(currentBooking->getStatus())
|
||||||
<< std::setw(12) << util::getServiceJobStatusString(currentBooking->getStatus())
|
<< std::setw(12) << currentBooking->getCustomerId()
|
||||||
<< std::setw(12) << currentBooking->getCustomerId()
|
<< std::setw(20) << currentBooking->getCustomer()->getName()
|
||||||
<< std::setw(20) << currentBooking->getCustomer()->getName()
|
<< std::setw(15) << currentBooking->getVehicleNumber()
|
||||||
<< std::setw(15) << currentBooking->getVehicleNumber()
|
<< std::setw(15) << currentBooking->getVehicleBrand()
|
||||||
<< std::setw(15) << currentBooking->getVehicleBrand()
|
<< std::setw(15) << currentBooking->getVehicleModel()
|
||||||
<< std::setw(15) << currentBooking->getVehicleModel()
|
<< std::setw(20) << ((currentAssignedTechnician == nullptr || currentAssignedTechnician->getName().empty()) ? "NULL" : currentAssignedTechnician->getName())
|
||||||
<< std::setw(20) << ((currentAssignedTechnician == nullptr || currentAssignedTechnician->getName().empty()) ? "Null" : currentAssignedTechnician->getName())
|
<< std::setw(15) << ((currentAssignedTechnician == nullptr || currentAssignedTechnician->getId().empty()) ? "NULL" : currentAssignedTechnician->getId())
|
||||||
<< std::setw(15) << ((currentAssignedTechnician == nullptr || currentAssignedTechnician->getId().empty()) ? "Null" : currentAssignedTechnician->getId())
|
<< std::endl;
|
||||||
<< std::endl;
|
serviceBookingsMap.insert(currentIndex++, currentBooking);
|
||||||
serviceBookingsMap.insert(currentIndex++, currentBooking);
|
}
|
||||||
}
|
}
|
||||||
}
|
return true;
|
||||||
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)
|
inline const ServiceBooking* selectPendingServiceBookings(util::Map<int, const ServiceBooking*>& serviceBookingsMap)
|
||||||
{
|
{
|
||||||
int userInputIndex;
|
int userInputIndex;
|
||||||
std::cout << "Enter a valid service index: ";
|
std::cout << "\nEnter a valid service index: ";
|
||||||
util::read(userInputIndex);
|
util::read(userInputIndex);
|
||||||
if (serviceBookingsMap.find(userInputIndex) != -1)
|
if (serviceBookingsMap.find(userInputIndex) != -1)
|
||||||
{
|
{
|
||||||
return serviceBookingsMap.getValueAt(userInputIndex);
|
return serviceBookingsMap.getValueAt(serviceBookingsMap.find(userInputIndex));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "Enter a valid index.";
|
std::cout << "Enter a valid index.\n\n";
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -248,6 +268,7 @@ inline void listAvailableTechnicians(util::Map<std::string, const User*> current
|
|||||||
{
|
{
|
||||||
bool hasTechnicians = false;
|
bool hasTechnicians = false;
|
||||||
int currentIndex = 1;
|
int currentIndex = 1;
|
||||||
|
std::cout << "\nSelect Technician\n";
|
||||||
std::cout << std::left
|
std::cout << std::left
|
||||||
<< std::setw(6) << "Index"
|
<< std::setw(6) << "Index"
|
||||||
<< std::setw(15) << "Technician ID"
|
<< std::setw(15) << "Technician ID"
|
||||||
@@ -270,7 +291,7 @@ inline void listAvailableTechnicians(util::Map<std::string, const User*> current
|
|||||||
}
|
}
|
||||||
if (!hasTechnicians)
|
if (!hasTechnicians)
|
||||||
{
|
{
|
||||||
std::cout << "No technicians currently available.";
|
std::cout << "No technicians currently available.\n\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,17 +304,18 @@ Returns:
|
|||||||
- const User*: Pointer to the selected technician, or nullptr if invalid
|
- const User*: Pointer to the selected technician, or nullptr if invalid
|
||||||
*/
|
*/
|
||||||
inline const User* selectTechnician(util::Map<int, const User*>& currentAvailableTechniciansMap)
|
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)
|
||||||
{
|
{
|
||||||
int userInputIndex;
|
return currentAvailableTechniciansMap.getValueAt(currentAvailableTechniciansMap.find(userInputIndex));
|
||||||
util::read(userInputIndex);
|
}
|
||||||
if (currentAvailableTechniciansMap.find(userInputIndex) != -1)
|
else
|
||||||
{
|
{
|
||||||
return currentAvailableTechniciansMap.getValueAt(userInputIndex);
|
std::cout << "Enter a valid index.\n\n";
|
||||||
}
|
return nullptr;
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cout << "Enter a valid index.";
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,57 +428,61 @@ Throws:
|
|||||||
*/
|
*/
|
||||||
inline void displayInvoices(util::Map<std::string, const Invoice*> currentUserInvoices)
|
inline void displayInvoices(util::Map<std::string, const Invoice*> currentUserInvoices)
|
||||||
{
|
{
|
||||||
if (currentUserInvoices.getSize() == 0)
|
if (currentUserInvoices.getSize() == 0)
|
||||||
{
|
{
|
||||||
std::cout << "No invoices found for this account." << std::endl;
|
std::cout << "No invoices found for this account." << std::endl << std::endl;
|
||||||
util::pressEnter();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int index = 0; index < currentUserInvoices.getSize(); index++)
|
for (int index = 0; index < currentUserInvoices.getSize(); index++)
|
||||||
{
|
|
||||||
const Invoice* currentInvoice = currentUserInvoices.getValueAt(index);
|
|
||||||
if (currentInvoice)
|
|
||||||
{
|
|
||||||
const User* currentTechnician = currentInvoice->getBooking()->getAssignedTechnician();
|
|
||||||
std::cout << "\nInvoice Details\n";
|
|
||||||
std::cout << "Booking ID: " << currentInvoice->getBookingId() << std::endl;
|
|
||||||
std::cout << "Vehicle Brand: " << currentInvoice->getBooking()->getVehicleBrand() << std::endl;
|
|
||||||
std::cout << "Vehicle Number: " << currentInvoice->getBooking()->getVehicleNumber() << std::endl;
|
|
||||||
std::cout << "Technician ID: " <<
|
|
||||||
((currentTechnician != nullptr && currentTechnician->getId() != "") ?
|
|
||||||
currentTechnician->getId() : "Null") << std::endl;
|
|
||||||
std::cout << "Technician Name: " <<
|
|
||||||
((currentTechnician != nullptr && currentTechnician->getName() != "") ?
|
|
||||||
currentTechnician->getName() : "Null") << std::endl;
|
|
||||||
std::cout << "Discount(%): " << currentInvoice->getDiscountPercentage() << std::endl;
|
|
||||||
std::cout << "Total Amount: " << currentInvoice->getTotalAmount() << std::endl;
|
|
||||||
std::cout << "Invoice Date: " << currentInvoice->getInvoiceDate().toString() << std::endl;
|
|
||||||
std::cout << "Payment Status: " << util::getPaymentStatusString(currentInvoice->getStatus()) << std::endl;
|
|
||||||
auto inventoryItemsInInvoice = currentInvoice->getParts();
|
|
||||||
std::cout << "\nItems Used:\n";
|
|
||||||
std::cout << std::left
|
|
||||||
<< std::setw(20) << "ItemName"
|
|
||||||
<< std::setw(10) << "Quantity"
|
|
||||||
<< std::setw(10) << "Price"
|
|
||||||
<< std::endl;
|
|
||||||
std::cout << std::string(40, '-') << std::endl;
|
|
||||||
for (int iterator = 0; iterator < inventoryItemsInInvoice.getSize(); iterator++)
|
|
||||||
{
|
|
||||||
InventoryItem* currentItem = inventoryItemsInInvoice.getValueAt(iterator);
|
|
||||||
std::cout << std::left
|
|
||||||
<< std::setw(20) << currentItem->getPartName()
|
|
||||||
<< std::setw(10) << currentItem->getQuantity()
|
|
||||||
<< std::setw(10) << currentItem->getPrice()
|
|
||||||
<< std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Null invoice encountered while displaying invoices.");
|
const Invoice* currentInvoice = currentUserInvoices.getValueAt(index);
|
||||||
util::pressEnter();
|
if (currentInvoice)
|
||||||
}
|
{
|
||||||
|
const User* currentTechnician = currentInvoice->getBooking()->getAssignedTechnician();
|
||||||
|
std::cout << "\nInvoice Details\n";
|
||||||
|
std::cout << "Booking ID: " << currentInvoice->getBookingId() << std::endl;
|
||||||
|
std::cout << "Vehicle Brand: " << currentInvoice->getBooking()->getVehicleBrand() << std::endl;
|
||||||
|
std::cout << "Vehicle Number: " << currentInvoice->getBooking()->getVehicleNumber() << std::endl;
|
||||||
|
std::cout << "Technician ID: " <<
|
||||||
|
((currentTechnician != nullptr && currentTechnician->getId() != "") ?
|
||||||
|
currentTechnician->getId() : "Null") << std::endl;
|
||||||
|
std::cout << "Technician Name: " <<
|
||||||
|
((currentTechnician != nullptr && currentTechnician->getName() != "") ?
|
||||||
|
currentTechnician->getName() : "Null") << std::endl;
|
||||||
|
std::cout << "Discount(%): " << currentInvoice->getDiscountPercentage() << std::endl;
|
||||||
|
std::cout << "Total Amount: " << currentInvoice->getTotalAmount() << std::endl;
|
||||||
|
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"
|
||||||
|
<< std::setw(10) << "Quantity"
|
||||||
|
<< std::setw(10) << "Price"
|
||||||
|
<< std::endl;
|
||||||
|
std::cout << std::string(40, '-') << std::endl;
|
||||||
|
for (int iterator = 0; iterator < inventoryItemsInInvoice.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
InventoryItem* currentItem = inventoryItemsInInvoice.getValueAt(iterator);
|
||||||
|
std::cout << std::left
|
||||||
|
<< std::setw(20) << currentItem->getPartName()
|
||||||
|
<< std::setw(10) << currentItem->getQuantity()
|
||||||
|
<< std::setw(10) << currentItem->getPrice()
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Null invoice encountered while displaying invoices.");
|
||||||
|
util::pressEnter();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user