diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp index e6a26e1..c19e440 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp @@ -2,6 +2,7 @@ #include "InventoryItem.h" #include "Service.h" #include "ServiceBooking.h" +#include "JobCard.h" bool Controller::login(const std::string& username, const std::string& password) { @@ -59,6 +60,8 @@ void Controller::purchaseComboPackage(const std::string& comboPackageID, const s util::Map Controller::getInventoryItems() { + util::Map dummyMap; + return dummyMap; } const InventoryItem* Controller::getInventoryItem(const std::string& inventoryItemID) @@ -129,11 +132,20 @@ void Controller::removeService(const std::string& serviceID) util::Map Controller::getJobCardsByUser() { - return util::Map(); + const User* currentUser = getAuthenticatedUser(); + auto jobCardsAssignedToTechnician = m_serviceManagementService.getJobCards(currentUser->getId()); + util::Map readOnlyJobCardMap; + for (int iterator = 0; iterator < jobCardsAssignedToTechnician.getSize(); iterator++) + { + JobCard* currentJobCard = jobCardsAssignedToTechnician.getValueAt(iterator); + readOnlyJobCardMap.insert(currentJobCard->getId(), currentJobCard); + } + return readOnlyJobCardMap; } void Controller::completeJob(const std::string& jobID) { + m_serviceManagementService.completeJob(jobID); } void Controller::removeUser(const std::string& userID) diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/JobCard.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/JobCard.cpp index 0229352..b9f1eee 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/JobCard.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/JobCard.cpp @@ -15,7 +15,9 @@ JobCard::JobCard(const std::string& bookingId, const std::string& serviceId, const std::string& technicianId, User* technician, - util::ServiceJobStatus status + const util::Timestamp& assignedDate, + util::ServiceJobStatus status, + const util::Timestamp& completionDate ) : m_id("JC" + std::to_string(++m_uid)), m_bookingId(bookingId), @@ -24,9 +26,9 @@ JobCard::JobCard(const std::string& bookingId, m_serviceId(serviceId), m_technicianId(technicianId), m_technician(technician), - m_assignedDate(util::Timestamp()), + m_assignedDate(assignedDate), m_status(status), - m_completionDate(util::Timestamp()) {} + m_completionDate(completionDate) {} const std::string& JobCard::getId() const { diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/JobCard.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/JobCard.h index c501e93..9bd78aa 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/JobCard.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/JobCard.h @@ -30,7 +30,9 @@ public: const std::string& serviceId, const std::string& technicianId, User* technician, - util::ServiceJobStatus status + const util::Timestamp& assignedDate, + util::ServiceJobStatus status, + const util::Timestamp& completionDate ); const std::string& getId() const; const std::string& getBookingId() const; diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp index 3a8a0a6..4f67c0d 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp @@ -7,6 +7,10 @@ #include "Service.h" #include "Enums.h" #include "InventoryItem.h" +#include "AuthenticationManagementService.h" +#include "PaymentManagementService.h" +#include "NotificationManagementService.h" +#include "User.h" util::Map ServiceManagementService::getServiceBookings() { @@ -65,14 +69,35 @@ void ServiceManagementService::createJobCard(const std::string& bookingID, const currentBooking->setAssignedTechnicianId(selectedTechnician->getId()); 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(bookingID, currentBooking, currentService, serviceID, technicianID, selectedTechnician, util::ServiceJobStatus::STARTED); + JobCard* jobCard = Factory::getObject(bookingID, currentBooking, currentService, serviceID, technicianID, selectedTechnician, util::Timestamp(), util::ServiceJobStatus::STARTED, util::Timestamp()); currentJobCards.insert(jobCard->getId(), jobCard); sendNotification(selectedTechnician,title, message); } void ServiceManagementService::createService(const std::string& name, const util::Vector& inventoryItemIDs, double laborCost) { - Service* newService = Factory::getObject(name, inventoryItemIDs, laborCost); + util::Map currentServiceInventoryItems; + auto inventoryItems = m_dataStore.getInventoryItems(); + for (int iteratorOne =0; iteratorOne < inventoryItemIDs.getSize(); iteratorOne++) + { + std::string currentItemID = inventoryItemIDs[iteratorOne]; + bool itemFound = false; + for (int iteratorTwo = 0; iteratorTwo < inventoryItems.getSize(); iteratorTwo++) + { + InventoryItem* currentInventoryItem = inventoryItems.getValueAt(iteratorTwo); + if (currentInventoryItem && currentInventoryItem->getId() == currentItemID) + { + itemFound = true; + currentServiceInventoryItems.insert(currentInventoryItem->getId(), currentInventoryItem); + break; + } + } + if (!itemFound) + { + throw std::runtime_error("Inventory item with ID '" + currentItemID + "' not found."); + } + } + Service* newService = Factory::getObject(name, currentServiceInventoryItems, laborCost); if (newService == nullptr) { throw std::runtime_error("Unable to create new service."); @@ -119,4 +144,84 @@ util::Map ServiceManagementService::getServiceBook } } return currentUserServiceBookings; +} + +util::Map ServiceManagementService::getJobCards(const std::string& technicianID) +{ + util::Map jobCards = m_dataStore.getJobCards(); + util::Map technicianJobCards; + for (int iterator = 0; iterator < jobCards.getSize(); iterator++) + { + JobCard* currentJobCard = jobCards.getValueAt(iterator); + if (currentJobCard->getTechnicianId() == technicianID) + { + technicianJobCards.insert(currentJobCard->getId(), currentJobCard); + } + } + return technicianJobCards; +} + +static bool hasAllJobCardsinServiceBookingCompleted(std::string bookingId, util::Map& currentAssignedJobs) +{ + for (int iterator = 0; iterator < currentAssignedJobs.getSize(); iterator++) + { + JobCard* currentJob = currentAssignedJobs.getValueAt(iterator); + if (currentJob->getBookingId() == bookingId) + { + if (currentJob->getStatus() == util::ServiceJobStatus::STARTED) + { + return false; + } + } + } + return true; +} + +void ServiceManagementService::completeJob(const std::string& jobID) +{ + AuthenticationManagementService authenticationManagementService; + PaymentManagementService paymentManagementService; + bool jobStatusUpdated = false, serviceBookingCompleted; + JobCard* currentJob; + User* currentTechnician = authenticationManagementService.getAuthenticatedUser(); + if (currentTechnician == nullptr) + { + throw std::runtime_error("Unable to fetch current technician."); + } + util::Map currentAssignedJobs = getJobCards(currentTechnician->getId()); + if (currentAssignedJobs.getSize() == 0) + { + throw std::runtime_error("No job cards assigned to the technician."); + } + if (currentAssignedJobs.find(jobID) != -1) + { + currentJob = currentAssignedJobs.getValueAt(currentAssignedJobs.find(jobID)); + if (currentJob == nullptr) + { + throw std::runtime_error("Unable to fetch current job."); + } + if (currentJob->getStatus() == util::ServiceJobStatus::STARTED) + { + currentJob->setStatus(util::ServiceJobStatus::COMPLETED); + jobStatusUpdated = true; + } + } + else + { + throw std::runtime_error("Failed to complete the job, some error occured or job already completed."); + } + if (!jobStatusUpdated) + { + throw std::runtime_error("Failed to complete the job, some error occured or job already completed."); + } + + serviceBookingCompleted = hasAllJobCardsinServiceBookingCompleted(currentJob->getBookingId(), currentAssignedJobs); + if (serviceBookingCompleted) + { + currentJob->getBooking()->setStatus(util::ServiceJobStatus::COMPLETED); + paymentManagementService.generateInvoice(currentJob->getBooking()); + std::string title = "Service Booking completed,Invoice Generated.\n"; + std::string message = "Services completed for the booking and invoice generated.\n"; + sendNotification(currentJob->getBooking()->getCustomer(), title, message); + } } \ No newline at end of file diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/TechnicianMenu.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/TechnicianMenu.cpp index d6c4d57..2b94fe3 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/TechnicianMenu.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/TechnicianMenu.cpp @@ -1,6 +1,10 @@ +#include #include "TechnicianMenu.h" #include "InputHelper.h" #include "OutputHelper.h" +#include "JobCard.h" +#include "Enums.h" +#include "Service.h" void TechnicianMenu::showMenu() { @@ -31,8 +35,68 @@ bool TechnicianMenu::handleOperation(int choice) return false; } +static std::string selectJobCardToComplete(util::Map& assignedJobCards, util::Map& incompleteJobCards) +{ + int currentIndex = 1; + int choice; + bool hasIncompleteJobCard = false; + std::cout << std::left + << std::setw(6) << "Index" + << std::setw(12) << "BookingID" + << std::setw(12) << "JobID" + << std::setw(20) << "ServiceName" + << std::setw(12) << "ServiceID" + << std::endl; + for (int iterator = 0; iterator < assignedJobCards.getSize(); iterator++) + { + const JobCard* currentJobCard = assignedJobCards.getValueAt(iterator); + if (currentJobCard && (currentJobCard->getStatus() == util::ServiceJobStatus::STARTED)) + { + std::cout << std::left << std::setw(6) << currentIndex + << std::setw(12) << currentJobCard->getBookingId() + << std::setw(12) << currentJobCard->getId() + << std::setw(20) << currentJobCard->getService()->getName() + << std::setw(12) << currentJobCard->getServiceId() + << std::endl; + hasIncompleteJobCard = true; + incompleteJobCards.insert(currentIndex++, currentJobCard); + } + } + if (!hasIncompleteJobCard) + { + std::cout << "No pending jobs are present.\n"; + return ""; + } + std::cout << "Select the Job Card to complete (Index): "; + util::read(choice); + int selectedJobCardIndex = incompleteJobCards.find(choice); + if (selectedJobCardIndex != -1) + { + const JobCard* selectedJobCard = incompleteJobCards.getValueAt(selectedJobCardIndex); + return selectedJobCard->getId(); + } + else + { + std::cout << "Invalid choice.\n"; + return ""; + } +} + void TechnicianMenu::completeJob() { + util::Map assignedJobCards = m_controller.getJobCardsByUser(); + util::Map incompleteJobCards; + std::cout << "Jobs to be completed.\n"; + std::string selectedJobID = selectJobCardToComplete(assignedJobCards, incompleteJobCards); + if (selectedJobID == "") + { + std::cout << "Failed to complete the job.\n"; + } + else + { + m_controller.completeJob(selectedJobID); + std::cout << "Job marked as completed.\n"; + } } void TechnicianMenu::viewNotifications()