diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp index b92c3aa..cac0fab 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp @@ -1,5 +1,9 @@ #include #include "Controller.h" +#include "InventoryItem.h" +#include "Service.h" +#include "ServiceBooking.h" +#include "JobCard.h" #include "Enums.h" #include "User.h" @@ -44,7 +48,13 @@ void Controller::updateUserDetails(const std::string& email, const std::string& util::Map Controller::getServices() { - return util::Map(); + util::Map currentServices = m_serviceManagementService.getServices(); + util::Map readOnlyServices; + for (int iterator = 0; iterator < currentServices.getSize(); iterator++) + { + readOnlyServices.insert(currentServices.getValueAt(iterator)->getId(), currentServices.getValueAt(iterator)); + } + return readOnlyServices; } util::Map Controller::getComboPackages() @@ -64,7 +74,8 @@ void Controller::purchaseComboPackage(const std::string& comboPackageID, const s util::Map Controller::getInventoryItems() { - return util::Map(); + util::Map dummyMap; + return dummyMap; } const InventoryItem* Controller::getInventoryItem(const std::string& inventoryItemID) @@ -82,12 +93,24 @@ void Controller::removeInventoryItem(const std::string& inventoryItemID) util::Map Controller::getServiceBookings() { - return util::Map(); + auto serviceBookings = m_serviceManagementService.getServiceBookings(); + util::Map readOnlyServiceBookings; + for (int iterator = 0; iterator < serviceBookings.getSize(); iterator++) + { + readOnlyServiceBookings.insert(serviceBookings.getKeyAt(iterator), serviceBookings.getValueAt(iterator)); + } + return readOnlyServiceBookings; } util::Map Controller::getServiceBookingsByUser(const std::string userID) { - return util::Map(); + util::Map readOnlyServiceBookingsByUserMap; + util::Map currentServiceBookingsByUser = m_serviceManagementService.getServiceBookings(userID); + for (int iterator = 0; iterator < currentServiceBookingsByUser.getSize(); iterator++) + { + readOnlyServiceBookingsByUserMap.insert(currentServiceBookingsByUser.getValueAt(iterator)->getId(), currentServiceBookingsByUser.getValueAt(iterator)); + } + return readOnlyServiceBookingsByUserMap; } util::Map Controller::getUsers() @@ -97,28 +120,46 @@ util::Map Controller::getUsers() util::Map Controller::getUsers(util::UserType userType) { - return util::Map(); + auto userMap = m_userManagementService.getUsers(userType); + util::Map readOnlyUserMap; + for (int iterator = 0; iterator < userMap.getSize(); iterator++) + { + readOnlyUserMap.insert(userMap.getKeyAt(iterator), userMap.getValueAt(iterator)); + } + return readOnlyUserMap; } void Controller::createJobCard(const std::string& bookingID, const std::string& technicianID, const std::string& serviceID) { + m_serviceManagementService.createJobCard(bookingID, technicianID, serviceID); } void Controller::createService(const std::string& name, const util::Vector& inventoryItemIDs, double laborCost) { + m_serviceManagementService.createService(name, inventoryItemIDs, laborCost); } void Controller::removeService(const std::string& serviceID) { + m_serviceManagementService.removeService(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/controllers/Controller.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.h index dddbb94..40a59db 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.h @@ -5,6 +5,7 @@ #include "AuthenticationManagementService.h" #include "UserManagementService.h" #include "ServiceManagementService.h" +#include "InventoryManagementService.h" class Service; class ComboPackage; diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/JobCard.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/JobCard.cpp index 04e9195..b9f1eee 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/JobCard.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/JobCard.cpp @@ -7,7 +7,7 @@ JobCard::JobCard() m_booking(nullptr), m_service(nullptr), m_technician(nullptr), - m_status(ServiceJobStatus()) {} + m_status(util::ServiceJobStatus()) {} JobCard::JobCard(const std::string& bookingId, ServiceBooking* booking, @@ -16,7 +16,7 @@ JobCard::JobCard(const std::string& bookingId, const std::string& technicianId, User* technician, const util::Timestamp& assignedDate, - ServiceJobStatus status, + util::ServiceJobStatus status, const util::Timestamp& completionDate ) : m_id("JC" + std::to_string(++m_uid)), @@ -70,7 +70,7 @@ const util::Timestamp& JobCard::getAssignedDate() const return m_assignedDate; } -ServiceJobStatus JobCard::getStatus() const +util::ServiceJobStatus JobCard::getStatus() const { return m_status; } @@ -120,7 +120,7 @@ void JobCard::setAssignedDate(const util::Timestamp& assignedDate) m_assignedDate = assignedDate; } -void JobCard::setStatus(ServiceJobStatus status) +void JobCard::setStatus(util::ServiceJobStatus status) { m_status = status; } diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/JobCard.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/JobCard.h index 15a8a5d..9bd78aa 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/JobCard.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/JobCard.h @@ -1,13 +1,12 @@ #pragma once #include #include "Timestamp.h" +#include "Enums.h" class ServiceBooking; class Service; class User; -enum class ServiceJobStatus : int; - class JobCard { private: @@ -20,7 +19,7 @@ private: std::string m_technicianId; User* m_technician; util::Timestamp m_assignedDate; - ServiceJobStatus m_status; + util::ServiceJobStatus m_status; util::Timestamp m_completionDate; public: @@ -32,7 +31,7 @@ public: const std::string& technicianId, User* technician, const util::Timestamp& assignedDate, - ServiceJobStatus status, + util::ServiceJobStatus status, const util::Timestamp& completionDate ); const std::string& getId() const; @@ -43,7 +42,7 @@ public: const std::string& getTechnicianId() const; User* getTechnician() const; const util::Timestamp& getAssignedDate() const; - ServiceJobStatus getStatus() const; + util::ServiceJobStatus getStatus() const; const util::Timestamp& getCompletionDate() const; void setId(const std::string& id); void setBookingId(const std::string& bookingId); @@ -53,6 +52,6 @@ public: void setTechnicianId(const std::string& technicianId); void setTechnician(User* technician); void setAssignedDate(const util::Timestamp& assignedDate); - void setStatus(ServiceJobStatus status); + void setStatus(util::ServiceJobStatus status); void setCompletionDate(const util::Timestamp& completionDate); }; \ No newline at end of file diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ServiceBooking.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ServiceBooking.cpp index 51fc6ff..b67bead 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ServiceBooking.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ServiceBooking.cpp @@ -17,6 +17,8 @@ ServiceBooking::ServiceBooking( const std::string& vehicleNumber, const std::string& vehicleBrand, const std::string& vehicleModel, + const std::string& assignedTechnicianId, + const User* assignedTechnician, double discountPercentage ) : m_id("SRV" + std::to_string(++m_uid)), diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ServiceBooking.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ServiceBooking.h index 84a8aac..612ac86 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ServiceBooking.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ServiceBooking.h @@ -32,6 +32,8 @@ public: const std::string& vehicleNumber, const std::string& vehicleBrand, const std::string& vehicleModel, + const std::string& assignedTechnicianId, + const User* assignedTechnician, double discountPercentage ); const std::string& getId() const; @@ -43,7 +45,7 @@ public: const std::string& getVehicleBrand() const; const std::string& getVehicleModel() const; const std::string& getAssignedTechnicianId() const; - User* getAssignedTechnician() const; + const User* getAssignedTechnician() const; double getDiscountPercentage() const; void setId(const std::string& id); void setStatus(const util::ServiceJobStatus& status); diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp index 3c787b3..52a0a20 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp @@ -5,6 +5,232 @@ #include "ServiceBooking.h" #include "ComboPackage.h" #include "Factory.h" +#include "UserManagementService.h" +#include "ServiceBooking.h" +#include "Factory.h" +#include "JobCard.h" +#include "Timestamp.h" +#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() +{ + return m_dataStore.getServiceBookings(); +} + +ServiceBooking* ServiceManagementService::getServiceBooking(const std::string& serviceID) +{ + auto currentServiceBookings = getServiceBookings(); + for (int iterator = 0; iterator < currentServiceBookings.getSize(); iterator++) + { + if (currentServiceBookings.getValueAt(iterator)->getId() == serviceID) + { + return currentServiceBookings.getValueAt(iterator); + } + } + return nullptr; +} + +void ServiceManagementService::createJobCard(const std::string& bookingID, const std::string& technicianID, const std::string& serviceID) +{ + UserManagementService m_userManagementService; + ServiceBooking* currentBooking = getServiceBooking(bookingID); + auto& currentJobCards = m_dataStore.getJobCards(); + if (currentBooking == nullptr) + { + throw std::runtime_error("Service Booking not available"); + } + auto& currentServices = currentBooking->getServices(); + if (currentServices.find(serviceID) == -1) + { + throw std::runtime_error("Invalid service Id"); + } + Service* currentService = currentServices.getValueAt(currentServices.find(serviceID)); + User* selectedTechnician = m_userManagementService.getUser(technicianID); + if (selectedTechnician == nullptr) + { + throw std::runtime_error("Technician not available"); + } + auto& inventoryItems = currentService->getRequiredInventoryItems(); + for (int iterator = 0; iterator < inventoryItems.getSize(); iterator++) + { + InventoryItem* currentInventoryItem = inventoryItems.getValueAt(iterator); + if (currentInventoryItem->getQuantity() == 0) + { + std::string errorMessage = "Failed to create job card, " + currentInventoryItem->getPartName() + " is out of stock."; + throw std::runtime_error(errorMessage); + } + else + { + int currentStockQuantity = currentInventoryItem->getQuantity(); + currentInventoryItem->setQuantity(currentStockQuantity - 1); + } + } + currentBooking->setAssignedTechnician(selectedTechnician); + 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::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) +{ + 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."); + } + util::Map& currentServices = m_dataStore.getServices(); + if (currentServices.find(newService->getId()) != -1) + { + throw std::runtime_error("Service with this ID Already exists."); + } + currentServices.insert(newService->getId(), newService); +} + +util::Map ServiceManagementService::getServices() +{ + return m_dataStore.getServices(); +} + +void ServiceManagementService::removeService(const std::string& serviceID) +{ + util::Map currentServices = getServices(); + if (currentServices.find(serviceID) != -1) + { + currentServices.getValueAt(currentServices.find(serviceID))->setState(util::State::INACTIVE); + } + else + { + throw std::runtime_error("Service not found."); + } +} + +util::Map ServiceManagementService::getServiceBookings(const std::string& customerID) +{ + util::Map currentServiceBookings = getServiceBookings(); + util::Map currentUserServiceBookings; + if (currentServiceBookings.getSize() != 0) + { + for (int iterator = 0; iterator < currentServiceBookings.getSize(); iterator++) + { + auto currentServiceBooking = currentServiceBookings.getValueAt(iterator); + if (currentServiceBooking->getCustomerId() == customerID) + { + currentUserServiceBookings.insert(currentServiceBooking->getId(), currentServiceBooking); + } + } + } + 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); + } +} void ServiceManagementService::purchaseService(const util::Vector& serviceIDs, const std::string& vehicleNumber, const std::string& vehicleBrand, const std::string& vehicleModel) { diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.h index 85e05ed..ab5723e 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.h @@ -22,6 +22,7 @@ public: void purchaseComboPackage(const std::string& comboPackageID, const std::string& vehicleNumber, const std::string& vehicleBrand, const std::string& vehicleModel); util::Map getServiceBookings(); util::Map getServiceBookings(const std::string& customerID); + ServiceBooking* getServiceBooking(const std::string& serviceID); void createJobCard(const std::string& bookingID, const std::string& technicianID, const std::string& serviceID); void createService(const std::string& name, const util::Vector& inventoryItemIDs, double laborCost); void removeService(const std::string& serviceID); diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp index 395e12f..de4de04 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp @@ -72,3 +72,32 @@ void UserManagementService::updateUserDetails(const std::string& userID, const s user->setEmail(email); user->setPhone(phone); } + +util::Map UserManagementService::getUsers(util::UserType type) +{ + util::Map& currentUsers = m_dataStore.getUsers(); + util::Map filteredUsersMap; + for (int iterator = 0; iterator < currentUsers.getSize(); iterator++) + { + User* currentUser = currentUsers.getValueAt(iterator); + if (currentUser->getUserType() == type) + { + filteredUsersMap.insert(currentUser->getId(), currentUser); + } + } + return filteredUsersMap; +} + +User* UserManagementService::getUser(const std::string& userID) +{ + util::Map& currentUsers = m_dataStore.getUsers(); + for (int iterator = 0; iterator < currentUsers.getSize(); iterator++) + { + User* currentUser = currentUsers.getValueAt(iterator); + if (currentUser->getId() == userID) + { + return currentUser; + } + } + return nullptr; +} diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Enums.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Enums.h index 24bbdcd..5353467 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Enums.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Enums.h @@ -24,6 +24,7 @@ namespace util enum class ServiceJobStatus { + PENDING, STARTED, COMPLETED }; @@ -125,6 +126,8 @@ namespace util return "STARTED"; case ServiceJobStatus::COMPLETED: return "COMPLETED"; + case ServiceJobStatus::PENDING: + return "STARTED"; } throw std::invalid_argument("Invalid ServiceJobStatus"); } diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/AdminMenu.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/AdminMenu.cpp index 0432f3c..dd9b1fa 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/AdminMenu.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/AdminMenu.cpp @@ -1,6 +1,12 @@ +#include #include "AdminMenu.h" +#include "Service.h" #include "InputHelper.h" #include "OutputHelper.h" +#include "ServiceBooking.h" +#include "Enums.h" +#include "Service.h" +#include "InventoryItem.h" void AdminMenu::showMenu() { @@ -56,16 +62,290 @@ void AdminMenu::checkStockAvailability() { } +static bool listServiceBookings(util::Map& currentBookings, int& bookingsSize, util::Map& serviceBookingsMap) +{ + int currentIndex = 1; + bool hasPendingService = false; + std::cout << std::left + << std::setw(10) << "Index" + << std::setw(10) << "ID" + << std::setw(12) << "Status" + << std::setw(12) << "CustID" + << std::setw(20) << "Customer" + << std::setw(15) << "VehicleNo" + << std::setw(15) << "Brand" + << std::setw(15) << "Model" + << std::setw(20) << "Technician" + << std::setw(15) << "TechID" + << std::endl; + for (int iterator = 0; iterator < bookingsSize; iterator++) + { + const ServiceBooking* currentBooking = currentBookings.getValueAt(iterator); + if (currentBooking && currentBooking->getStatus() == util::ServiceJobStatus::PENDING) + { + hasPendingService = true; + std::cout << std::left + << std::setw(10) << currentIndex + << std::setw(10) << currentBooking->getId() + << std::setw(12) << util::getServiceJobStatusString(currentBooking->getStatus()) + << std::setw(12) << currentBooking->getCustomerId() + << std::setw(20) << currentBooking->getCustomer()->getName() + << std::setw(15) << currentBooking->getVehicleNumber() + << std::setw(15) << currentBooking->getVehicleBrand() + << std::setw(15) << currentBooking->getVehicleModel() + << std::setw(20) << (currentBooking->getAssignedTechnician() == nullptr ? "Null" : currentBooking->getAssignedTechnician()->getName()) + << std::setw(15) << (currentBooking->getAssignedTechnicianId().empty() ? "Null" : currentBooking->getAssignedTechnicianId()) + << std::endl; + serviceBookingsMap.insert(currentIndex++, currentBooking); + } + } + if (!hasPendingService) + { + std::cout << "No pending service available." << std::endl; + return false; + } + return true; +} + +static const ServiceBooking* selectPendingServiceBookings(util::Map& serviceBookingsMap) +{ + int userInputIndex; + std::cout << "Enter a valid service index: "; + util::read(userInputIndex); + if (serviceBookingsMap.find(userInputIndex) != -1) + { + return serviceBookingsMap.getValueAt(userInputIndex); + } + else + { + std::cout << "Enter a valid index."; + return nullptr; + } +} + +static void listAvailableTechnicians( util::Map currentAvailableTechnicians, int numberOfTechnicians, util::Map& currentAvailableTechniciansMap) +{ + bool hasTechnicians = false; + int currentIndex = 1; + std::cout << std::left + << std::setw(6) << "Index" + << std::setw(15) << "Technician ID" + << std::setw(20) << "Name" + << std::endl; + for (int iterator = 0; iterator < numberOfTechnicians; iterator++) + { + const User* currentTechnician = currentAvailableTechnicians.getValueAt(iterator); + if (currentTechnician->getState() == util::State::INACTIVE) + { + continue; + } + hasTechnicians = true; + std::cout << std::left + << std::setw(6) << currentIndex + << std::setw(15) << currentTechnician->getId() + << std::setw(20) << currentTechnician->getName() + << std::endl; + currentAvailableTechniciansMap.insert(currentIndex++, currentTechnician); + } + if (!hasTechnicians) + { + std::cout << "No technicians currently available."; + } +} + +static const User* selectTechnician(util::Map& currentAvailableTechniciansMap) +{ + int userInputIndex; + util::read(userInputIndex); + if (currentAvailableTechniciansMap.find(userInputIndex) != -1) + { + return currentAvailableTechniciansMap.getValueAt(userInputIndex); + } + else + { + std::cout << "Enter a valid index."; + return nullptr; + } +} + void AdminMenu::assignJob() { + util::clear(); + std::string selectedService; + bool hasPendingService = false; + auto currentBookings = m_controller.getServiceBookings(); + auto availableTechnicians = m_controller.getUsers(util::UserType::TECHNICIAN); + int bookingsSize = currentBookings.getSize(); + util::Map serviceBookingsMap; + util::Map currentAvailableTechniciansMap; + if (listServiceBookings(currentBookings, bookingsSize, serviceBookingsMap)) + { + const ServiceBooking* selectedService = selectPendingServiceBookings(serviceBookingsMap); + if (selectedService) + { + if (availableTechnicians.getSize() != 0) + { + listAvailableTechnicians(availableTechnicians, availableTechnicians.getSize(), currentAvailableTechniciansMap); + const User* selectedTechnician = selectTechnician(currentAvailableTechniciansMap); + if (selectedTechnician) + { + auto& servicesInBooking = selectedService->getServices(); + for (int iterator = 0; iterator < servicesInBooking.getSize(); iterator++) + { + m_controller.createJobCard(selectedService->getId(), selectedTechnician->getId(), servicesInBooking.getValueAt(iterator)->getId()); + } + } + } + else + { + std::cout << "No technicians are currently available."; + } + } + } + +} + +static void selectInventoryItems(util::Map& currentInventoryItems, util::Vector& selectedInventoryItems) +{ + bool doRun = true, hasInventoryItems = false; + util::Map currentInventoryMap; + int currentIndex = 1; + int choice; + if (currentInventoryItems.getSize() == 0) + { + std::cout << "Inventory empty."; + } + while (doRun) + { + bool hasInventoryItems = false; + int currentIndex = 1; + currentInventoryMap.clear(); + std::cout << std::left + << std::setw(6) << "Index" + << std::setw(12) << "Item ID" + << std::setw(20) << "Part Name" + << std::setw(10) << "Price" + << std::setw(10) << "Quantity" + << std::endl; + for (int iterator = 0; iterator < currentInventoryItems.getSize(); iterator++) + { + const InventoryItem* currentInventoryItem = currentInventoryItems.getValueAt(iterator); + if (currentInventoryItem->getState() == util::State::INACTIVE) + { + continue; + } + std::cout << std::left + << std::setw(6) << currentIndex + << std::setw(12) << currentInventoryItem->getId() + << std::setw(20) << currentInventoryItem->getPartName() + << std::setw(10) << currentInventoryItem->getPrice() + << std::setw(10) << currentInventoryItem->getQuantity() + << std::endl; + + hasInventoryItems = true; + currentInventoryMap.insert(currentIndex++, currentInventoryItem); + } + if (!hasInventoryItems) + { + std::cout << "No items present in the inventory." << std::endl; + doRun = false; + break; + } + std::cout << "Select the item (Index) or enter -1 to exit: "; + util::read(choice); + + if (choice == -1) + { + doRun = false; + } + else if (currentInventoryMap.find(choice) != -1) + { + selectedInventoryItems.push_back(currentInventoryMap.getValueAt(choice)->getId()); + std::cout << "Item added successfully." << std::endl; + } + else + { + std::cout << "Enter a valid integer." << std::endl; + } + } } void AdminMenu::createService() { + util::clear(); + std::string serviceName; + double labourCost; + std::cout << "Enter the service name: "; + util::read(serviceName); + util::Map currentInventoryItems = m_controller.getInventoryItems(); + util::Vector selectedInventoryItems; + selectInventoryItems(currentInventoryItems,selectedInventoryItems); + std::cout << "Enter the labour cost: "; + util::read(labourCost); + m_controller.createService(serviceName, selectedInventoryItems, labourCost); + std::cout << "Service created sucessfully.\n"; +} + +static std::string selectServicesToRemove(util::Map currentServices) +{ + util::Map currentServicesMap; + bool hasServices = false; + int currentIndex = 1, choice; + std::cout << std::left + << std::setw(6) << "Index" + << std::setw(12) << "Service ID" + << std::setw(20) << "Name" + << std::setw(10) << "Labor Cost" + << std::endl; + for (int iterator = 0; iterator < currentServices.getSize(); iterator++) + { + const Service* currentService = currentServices.getValueAt(iterator); + if (currentService->getState() == util::State::INACTIVE) + { + continue; + } + std::cout << std::left + << std::setw(6) << currentIndex + << std::setw(12) << currentService->getId() + << std::setw(20) << currentService->getName() + << std::setw(10) << currentService->getLaborCost() + << std::endl; + hasServices = true; + currentServicesMap.insert(currentIndex++, currentService); + } + if (!hasServices) + { + std::cout << "No services currently available." << std::endl; + return ""; + } + std::cout << "Enter your choice: "; + util::read(choice); + if (currentServicesMap.find(choice) != -1) + { + return currentServicesMap.getValueAt(currentServicesMap.find(choice))->getId(); + } + else + { + std::cout << "Invalid choice." << std::endl; + return ""; + } } void AdminMenu::removeService() { + util::clear(); + std::string selectedServiceID; + util::Map currentServices = m_controller.getServices(); + selectedServiceID = selectServicesToRemove(currentServices); + if (selectedServiceID != "") + { + m_controller.removeService(selectedServiceID); + std::cout << "Service removed sucessfully."; + } + else + { + std::cout << "Failed to remove service."; + } } void AdminMenu::addTechnician() diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.cpp index 0a97c6a..7151737 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.cpp @@ -1,15 +1,18 @@ #include #include "CustomerMenu.h" -#include "Service.h" -#include "InventoryItem.h" #include "ComboPackage.h" -#include "Service.h" +#include "Enums.h" #include "InputHelper.h" +#include "InventoryItem.h" +#include "Map.h" #include "OutputHelper.h" +#include "Service.h" +#include "Service.h" +#include "ServiceBooking.h" +#include "User.h" +#include "Utility.h" #include "Validator.h" #include "Vector.h" -#include "Utility.h" -#include "Map.h" void CustomerMenu::showMenu() { @@ -270,6 +273,44 @@ void CustomerMenu::selectComboPackage() void CustomerMenu::viewServiceHistory() { + util::clear(); + bool hasServiceHistory = false; + const User* currentUser = m_controller.getAuthenticatedUser(); + std::string currentUserID = currentUser->getId(); + util::Map serviceBookingsByCurrentUser = m_controller.getServiceBookingsByUser(currentUserID); + if (serviceBookingsByCurrentUser.getSize() != 0) + { + std::cout << std::left + << std::setw(12) << "Booking ID" + << std::setw(20) << "Technician" + << std::setw(15) << "Vehicle Brand" + << std::setw(15) << "Vehicle Number" + << std::setw(15) << "Vehicle Model" + << std::setw(10) << "Discount %" + << std::setw(12) << "Status" + << std::endl; + for (int iterator = 0; iterator < serviceBookingsByCurrentUser.getSize(); iterator++) + { + const ServiceBooking* currentBooking = serviceBookingsByCurrentUser.getValueAt(iterator); + std::string technicianName = currentBooking->getAssignedTechnician() == nullptr + ? "Not Assigned" + : currentBooking->getAssignedTechnician()->getName(); + std::cout << std::left + << std::setw(12) << currentBooking->getId() + << std::setw(20) << technicianName + << std::setw(15) << currentBooking->getVehicleBrand() + << std::setw(15) << currentBooking->getVehicleNumber() + << std::setw(15) << currentBooking->getVehicleModel() + << std::setw(10) << currentBooking->getDiscountPercentage() + << std::setw(12) << util::getServiceJobStatusString(currentBooking->getStatus()) + << std::endl; + hasServiceHistory = true; + } + } + if (!hasServiceHistory) + { + std::cout << "No history available." << std::endl; + } } void CustomerMenu::completePayments() 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()