Merged PR 1201: Fix invoice display issues and improve combo package handling

**Changes**:

- Removed inventory quantity from invoice item display.
- Added null checks when displaying combo packages.
- Added null checks when selecting combo packages.
- Replaced unnecessary object copies with references.
- Zero-initialized SerializedObserver.
- Initialized event handle array before use.

Fixes
#2115

Related work items: #2115
This commit is contained in:
2026-06-18 19:37:31 +05:30
3 changed files with 31 additions and 27 deletions
@@ -358,7 +358,7 @@ util::Map<std::string, TrackedRecord<ServiceBooking>>& DataStore::getServiceBook
{ {
throw std::runtime_error("Invalid service index."); throw std::runtime_error("Invalid service index.");
} }
auto currentService = services.getValueAt(serviceIndex); auto& currentService = services.getValueAt(serviceIndex);
servicesInBooking[currentServiceId] = currentService.data; servicesInBooking[currentServiceId] = currentService.data;
} }
serviceBooking->setServices(servicesInBooking); serviceBooking->setServices(servicesInBooking);
@@ -369,7 +369,7 @@ util::Map<std::string, TrackedRecord<ServiceBooking>>& DataStore::getServiceBook
{ {
throw std::runtime_error("Invalid user index."); throw std::runtime_error("Invalid user index.");
} }
auto customer = users.getValueAt(userIndex); auto& customer = users.getValueAt(userIndex);
serviceBooking->setCustomer(customer.data); serviceBooking->setCustomer(customer.data);
} }
if (!serviceBooking->getAssignedTechnicianId().empty()) if (!serviceBooking->getAssignedTechnicianId().empty())
@@ -379,7 +379,7 @@ util::Map<std::string, TrackedRecord<ServiceBooking>>& DataStore::getServiceBook
{ {
throw std::runtime_error("Invalid technician index."); throw std::runtime_error("Invalid technician index.");
} }
auto technician = users.getValueAt(technicianIndex); auto& technician = users.getValueAt(technicianIndex);
serviceBooking->setAssignedTechnician(technician.data); serviceBooking->setAssignedTechnician(technician.data);
} }
} }
@@ -423,7 +423,7 @@ util::Map<std::string, TrackedRecord<JobCard>>& DataStore::getJobCards()
{ {
throw std::runtime_error("Invalid service ID: " + serviceId); throw std::runtime_error("Invalid service ID: " + serviceId);
} }
auto trackedService = services.getValueAt(serviceIndex); auto& trackedService = services.getValueAt(serviceIndex);
jobCard->setService(trackedService.data); jobCard->setService(trackedService.data);
const std::string& technicianId = jobCard->getTechnicianId(); const std::string& technicianId = jobCard->getTechnicianId();
if (!technicianId.empty()) if (!technicianId.empty())
@@ -433,7 +433,7 @@ util::Map<std::string, TrackedRecord<JobCard>>& DataStore::getJobCards()
{ {
throw std::runtime_error("Invalid technician ID: " + technicianId); throw std::runtime_error("Invalid technician ID: " + technicianId);
} }
auto trackedTechnician = users.getValueAt(technicianIndex); auto& trackedTechnician = users.getValueAt(technicianIndex);
jobCard->setTechnician(trackedTechnician.data); jobCard->setTechnician(trackedTechnician.data);
} }
} }
@@ -691,7 +691,7 @@ void DataStore::saveObservers(MappingInfo& mapping, util::Map<std::string, User*
SharedMemory::setRecordCount(mapping, observerCount); SharedMemory::setRecordCount(mapping, observerCount);
for (size_t index = 0; index < observerCount; index++) for (size_t index = 0; index < observerCount; index++)
{ {
SerializedObserver serializedObserver; SerializedObserver serializedObserver{};
User* user = observers.getValueAt(static_cast<int>(index)); User* user = observers.getValueAt(static_cast<int>(index));
strcpy_s(serializedObserver.id, sizeof(serializedObserver.id), user->getId().c_str()); strcpy_s(serializedObserver.id, sizeof(serializedObserver.id), user->getId().c_str());
SerializedObserver* destination = static_cast<SerializedObserver*>(SharedMemory::getRecordAddress(mapping, index)); SerializedObserver* destination = static_cast<SerializedObserver*>(SharedMemory::getRecordAddress(mapping, index));
@@ -67,7 +67,7 @@ Return type: void
*/ */
void Menu::eventListenerLoop() void Menu::eventListenerLoop()
{ {
HANDLE handles[3]; HANDLE handles[3] = { NULL, NULL, NULL };
handles[0] = m_accountDisabledEvent; handles[0] = m_accountDisabledEvent;
handles[1] = m_notificationAvailableEvent; handles[1] = m_notificationAvailableEvent;
handles[2] = m_shutdownEvent; handles[2] = m_shutdownEvent;
@@ -588,7 +588,7 @@ inline void displayInvoices(util::Map<std::string, const Invoice*> currentUserIn
<< util::getPaymentStatusString(selectedInvoice->getStatus()) << std::endl; << util::getPaymentStatusString(selectedInvoice->getStatus()) << std::endl;
std::cout << std::left << std::setw(20) << "Payment Mode:" std::cout << std::left << std::setw(20) << "Payment Mode:"
<< util::getPaymentModeString(selectedInvoice->getPaymentMethod()) << std::endl; << util::getPaymentModeString(selectedInvoice->getPaymentMethod()) << std::endl;
auto inventoryItemsInInvoice = selectedInvoice->getParts(); auto& inventoryItemsInInvoice = selectedInvoice->getParts();
if (inventoryItemsInInvoice.isEmpty()) if (inventoryItemsInInvoice.isEmpty())
{ {
std::cout << "No inventory items used.\n\n"; std::cout << "No inventory items used.\n\n";
@@ -597,7 +597,6 @@ inline void displayInvoices(util::Map<std::string, const Invoice*> currentUserIn
std::cout << "\nItems Used:\n"; std::cout << "\nItems Used:\n";
std::cout << std::left std::cout << std::left
<< std::setw(20) << "ItemName" << std::setw(20) << "ItemName"
<< std::setw(10) << "Quantity"
<< std::setw(10) << "Price" << std::setw(10) << "Price"
<< std::endl; << std::endl;
std::cout << std::string(40, '-') << std::endl; std::cout << std::string(40, '-') << std::endl;
@@ -606,7 +605,6 @@ inline void displayInvoices(util::Map<std::string, const Invoice*> currentUserIn
InventoryItem* currentItem = inventoryItemsInInvoice.getValueAt(iterator); InventoryItem* currentItem = inventoryItemsInInvoice.getValueAt(iterator);
std::cout << std::left std::cout << std::left
<< std::setw(20) << currentItem->getPartName() << std::setw(20) << currentItem->getPartName()
<< std::setw(10) << currentItem->getQuantity()
<< std::setw(10) << currentItem->getPrice() << std::setw(10) << currentItem->getPrice()
<< std::endl; << std::endl;
} }
@@ -1146,15 +1144,18 @@ inline void displayAllComboPackages(util::Map<std::string, const ComboPackage*>
for (int index = 0; index < comboPackages.getSize(); index++) for (int index = 0; index < comboPackages.getSize(); index++)
{ {
const ComboPackage* currentComboPackage = comboPackages.getValueAt(index); const ComboPackage* currentComboPackage = comboPackages.getValueAt(index);
if (currentComboPackage && currentComboPackage->getState() != util::State::ACTIVE) if (currentComboPackage)
{ {
continue; if (currentComboPackage->getState() != util::State::ACTIVE)
{
continue;
}
std::cout << std::left
<< std::setw(15) << currentComboPackage->getId()
<< std::setw(35) << util::truncateString(currentComboPackage->getPackageName(), 30)
<< std::setw(15) << util::calculateComboServiceEstimatedCost(currentComboPackage)
<< std::endl;
} }
std::cout << std::left
<< std::setw(15) << currentComboPackage->getId()
<< std::setw(35) << util::truncateString(currentComboPackage->getPackageName(), 30)
<< std::setw(15) << util::calculateComboServiceEstimatedCost(currentComboPackage)
<< std::endl;
} }
} }
@@ -1180,18 +1181,21 @@ inline const ComboPackage* selectComboPackageFromPackages(const util::Map<std::s
for (int index = 0; index < comboPackages.getSize(); index++) for (int index = 0; index < comboPackages.getSize(); index++)
{ {
const ComboPackage* currentComboPackage = comboPackages.getValueAt(index); const ComboPackage* currentComboPackage = comboPackages.getValueAt(index);
if (currentComboPackage && currentComboPackage->getState() != util::State::ACTIVE) if (currentComboPackage)
{ {
continue; if (currentComboPackage->getState() != util::State::ACTIVE)
{
continue;
}
activeComboPackages.insert(currentIndex, currentComboPackage);
std::cout << std::left
<< std::setw(10) << currentIndex
<< std::setw(15) << currentComboPackage->getId()
<< std::setw(35) << util::truncateString(currentComboPackage->getPackageName(), 30)
<< std::setw(15) << util::calculateComboServiceEstimatedCost(currentComboPackage)
<< std::endl;
currentIndex++;
} }
activeComboPackages.insert(currentIndex, currentComboPackage);
std::cout << std::left
<< std::setw(10) << currentIndex
<< std::setw(15) << currentComboPackage->getId()
<< std::setw(35) << util::truncateString(currentComboPackage->getPackageName(), 30)
<< std::setw(15) << util::calculateComboServiceEstimatedCost(currentComboPackage)
<< std::endl;
currentIndex++;
} }
if (activeComboPackages.getSize() == 0) if (activeComboPackages.getSize() == 0)
{ {