8162a2fe3d
<UserStory> SER005: Update Service Status </UserStory>
<Changes>
1. Integrated Controller with ServiceManagementService to support job completion workflow.
2. Implemented ServiceManagementService::completeJob with validation for technician assignment, job existence, and status transition.
3. Enhanced TechnicianMenu with job selection helper to display assigned jobs, allow index-based selection, and handle invalid choices.
4. Updated TechnicianMenu::completeJob to mark job as completed via Controller and provide user feedback.
5. Added logic to check if all jobs in a booking are completed, triggering invoice generation and customer notification.
</Changes>
<Test>
Acceptance Criteria:
1. Status updates are visible to customers immediately after technician marks job as completed.
Precondition:
1. Technician is logged into the system.
2. At least one active job card is assigned to the technician.
3. Datastore contains valid service bookings linked to jobs.
Steps:
1. Navigate to Technician menu and choose "Complete Job".
- Verify that the system lists active jobs with index-based selection.
2. Select a job card by index.
- Verify that the job status changes from STARTED to COMPLETED.
3. Check customer view.
- Verify that the updated status is reflected in the customer’s booking history.
4. If all jobs in the booking are completed:
- Verify that an invoice is generated and a notification is sent to the customer.
</Test>
<Review>
Sreeja Reghukumar, please review
</Review>
89 lines
3.0 KiB
C++
89 lines
3.0 KiB
C++
#include "ServiceManagementService.h"
|
|
#include "AuthenticationManagementService.h"
|
|
#include "PaymentManagementService.h"
|
|
#include "NotificationManagementService.h"
|
|
#include "JobCard.h"
|
|
#include "User.h"
|
|
#include "Enums.h"
|
|
#include "ServiceBooking.h"
|
|
#include "Service.h"
|
|
|
|
util::Map<std::string, JobCard*> ServiceManagementService::getJobCards(const std::string& technicianID)
|
|
{
|
|
util::Map<std::string, JobCard*> jobCards = m_dataStore.getJobCards();
|
|
util::Map<std::string, JobCard*> 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<std::string, JobCard*>& 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<std::string, JobCard*> 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);
|
|
}
|
|
} |