Merge branch 'feature-payment-management' into feature-1553-1598

This commit is contained in:
Jissin Mathew
2026-05-25 12:11:20 +05:30
11 changed files with 395 additions and 16 deletions
@@ -1 +1,135 @@
#include "PaymentManagementService.h"
#include "ServiceBooking.h"
#include "Service.h"
#include "InventoryItem.h"
#include "Utility.h"
#include "Factory.h"
#include "Timestamp.h"
#include "Invoice.h"
#include "JobCard.h"
#include "Enums.h"
/*
Function: createInventoryItemsMap (static helper)
Description: Builds a map of inventory items required for a given service and adds them to the bookings inventory map.
Parameters:
- completeInventoryItemMapOfBooking: util::Map<std::string, InventoryItem*>&, map to store inventory items for the booking
- currentService: const Service*, pointer to the current service
Returns:
- void
*/
static void createInventoryItemsMap(util::Map<std::string, InventoryItem*>& completeInventoryItemMapOfBooking, const Service* currentService)
{
auto& currentRequiredInventoryItems = currentService->getRequiredInventoryItems();
for (int iterator = 0; iterator < currentRequiredInventoryItems.getSize(); iterator++)
{
auto& currentRequiredInventoryItem = currentRequiredInventoryItems.getValueAt(iterator);
completeInventoryItemMapOfBooking.insert(currentRequiredInventoryItem->getId(), currentRequiredInventoryItem);
}
}
/*
Function: generateInvoice
Description: Generates an invoice for a completed service booking.
Validates that all job cards are completed, calculates labor and parts cost, applies discount,
and stores the invoice in the datastore.
Parameters:
- booking: ServiceBooking*, pointer to the service booking
Returns:
- void
Throws:
- std::runtime_error if booking is null or job cards are incomplete
*/
void PaymentManagementService::generateInvoice(ServiceBooking* booking)
{
if (!booking)
{
throw std::runtime_error("Invoice generation failed: booking is null.");
}
double totalLabourCost = 0, totalPartsCost = 0, totalServiceCost = 0;
double discountPercentage = booking->getDiscountPercentage();
std::string bookingID = booking->getId();
util::Map<std::string, Service*> servicesInTheBookedService = booking->getServices();
util::Map<std::string, InventoryItem*> completeInventoryItemMapOfBooking;
util::Map<std::string, JobCard*> currentJobCards = m_dataStore.getJobCards();
for (int iterator = 0; iterator < currentJobCards.getSize(); iterator++)
{
JobCard* currentJobCard = currentJobCards.getValueAt(iterator);
if (currentJobCard->getBookingId() == bookingID && currentJobCard->getStatus() != util::ServiceJobStatus::COMPLETED)
{
throw std::runtime_error("Invoice generation failed: not all job cards are completed for booking '" + bookingID + "'.");
}
}
for (int iterator = 0; iterator < servicesInTheBookedService.getSize(); iterator++)
{
Service* currentService = servicesInTheBookedService.getValueAt(iterator);
if (currentService)
{
createInventoryItemsMap(completeInventoryItemMapOfBooking, currentService);
totalLabourCost += currentService->getLaborCost();
totalPartsCost += calculatePartsCost(currentService);
}
}
totalServiceCost = totalLabourCost + totalPartsCost;
totalServiceCost -= (totalServiceCost * (discountPercentage / 100));
Invoice* invoice = Factory::getObject<Invoice>(bookingID, booking, util::Timestamp(), totalLabourCost, completeInventoryItemMapOfBooking, totalPartsCost, discountPercentage, totalServiceCost, util::Timestamp(), util::PaymentMode::NOTSET, util::PaymentStatus::PENDING);
util::Map<std::string, Invoice*>& currentInvoices = m_dataStore.getInvoices();
currentInvoices.insert(invoice->getId(), invoice);
}
/*
Function: getInvoices
Description: Retrieves all invoices associated with a specific customer.
Parameters:
- customerID: std::string, ID of the customer
Returns:
- util::Map<std::string, Invoice*> containing the customers invoices
*/
util::Map<std::string, Invoice*> PaymentManagementService::getInvoices(const std::string& customerID)
{
util::Map<std::string, Invoice*>& currentInvoices = m_dataStore.getInvoices();
util::Map<std::string, Invoice*> currentUserInvoices;
for (int iterator = 0; iterator < currentInvoices.getSize(); iterator++)
{
Invoice* currentInvoice = currentInvoices.getValueAt(iterator);
if (currentInvoice->getBooking()->getCustomerId() == customerID)
{
currentUserInvoices.insert(currentInvoice->getId(), currentInvoice);
}
}
return currentUserInvoices;
}
/*
Function: completePayment
Description: Completes payment for a specific invoice. Updates payment method, date, and status,
then sends a notification to the customer.
Parameters:
- invoiceID: std::string, ID of the invoice
- paymentMode: util::PaymentMode, mode of payment (e.g., ONLINE, OFFLINE)
Returns:
- void
Throws:
- std::runtime_error if the invoice ID is invalid
*/
void PaymentManagementService::completePayment(const std::string& invoiceID, util::PaymentMode paymentMode)
{
auto& currentInvoices = m_dataStore.getInvoices();
int invoiceIndex = currentInvoices.find(invoiceID);
if (invoiceIndex != -1)
{
Invoice* invoice = currentInvoices.getValueAt(invoiceIndex);
User* currentUser = invoice->getBooking()->getCustomer();
invoice->setPaymentMethod(paymentMode);
invoice->setPaymentDate(util::Timestamp());
invoice->setStatus(util::PaymentStatus::COMPLETED);
std::string title, message;
title = "Payment successful";
message = "Payment successful for invoice ID " + invoiceID;
sendNotification(currentUser, title, message);
}
else
{
throw std::runtime_error("Payment failed: invalid invoice ID.");
}
}