Implement delivery assignment flow, restaurant order handling, and new controller helpers
- Add new Controller helper getDeliveryStatusString() - Add new Controller helper pickAssignmentFromDeliveryAssignments() - Implement controller listRestaurantOrders() - Implement controller markOrderReady() - Add order to restaurant when customer places order - Add m_assignments attribute to Controller - Implement controller listDeliveryAssignments() - Implement controller acceptDeliveryAssignments() - Implement controller confirmDeliveryAssignments()
This commit is contained in:
@@ -15,6 +15,9 @@ Date: 19-02-2026
|
||||
#include "Customer.h"
|
||||
#include "DeliveryPartner.h"
|
||||
#include "Restaurant.h"
|
||||
#include "MenuItem.h"
|
||||
#include "Order.h"
|
||||
#include "DeliveryAssignment.h"
|
||||
#include "inputHelper.h"
|
||||
#include "outputHelper.h"
|
||||
|
||||
@@ -161,6 +164,65 @@ static orders::iterator pickOrderFromOrders(orders& userOrders)
|
||||
return orderIterator;
|
||||
}
|
||||
|
||||
static std::string getDeliveryStatusString(const DeliveryStatus& deliveryStatus)
|
||||
{
|
||||
switch (deliveryStatus)
|
||||
{
|
||||
case DeliveryStatus::CREATED:
|
||||
return "Created";
|
||||
case DeliveryStatus::ACCEPTED:
|
||||
return "Accepted";
|
||||
case DeliveryStatus::DELIVERED:
|
||||
return "Delivered";
|
||||
default:
|
||||
return "Unkown";
|
||||
}
|
||||
}
|
||||
|
||||
static deliveryAssignments::iterator pickAssignmentFromDeliveryAssignments(deliveryAssignments& assignments, const users& allUsers)
|
||||
{
|
||||
util::clear();
|
||||
std::cout << "Pick a Delivery Assignment\n";
|
||||
int deliveryIndex = 1, deliveryChoiceIndex;
|
||||
if (assignments.empty())
|
||||
{
|
||||
std::cout << "No Delivery Assignments available at the moment!\n";
|
||||
return assignments.end();
|
||||
}
|
||||
std::cout << std::left << std::setw(8) << "Index"
|
||||
<< std::left << std::setw(5) << "ID"
|
||||
<< std::left << std::setw(12) << "Order ID"
|
||||
<< std::left << std::setw(22) << "Delivery Status"
|
||||
<< std::left << std::setw(30) << "Address"
|
||||
<< "\n";
|
||||
for (auto& assignment : assignments)
|
||||
{
|
||||
Order& order = assignment.second->getOrder();
|
||||
users::const_iterator customer = allUsers.find(order.getCustomerUsername());
|
||||
if (customer == allUsers.end())
|
||||
{
|
||||
throw std::runtime_error("Invalid state: Delivery Assignment has no associated Customer.");
|
||||
}
|
||||
std::cout << std::left << std::setw(8) << deliveryIndex
|
||||
<< std::left << std::setw(5) << assignment.second->getId()
|
||||
<< std::left << std::setw(12) << order.getId()
|
||||
<< std::left << std::setw(22) << getDeliveryStatusString(assignment.second->getStatus())
|
||||
<< std::left << std::setw(30) << customer->second->getAddress()
|
||||
<< "\n";
|
||||
deliveryIndex++;
|
||||
}
|
||||
std::cout << "\nSelect Index: ";
|
||||
util::readValue<int>(deliveryChoiceIndex);
|
||||
deliveryChoiceIndex--;
|
||||
if (deliveryChoiceIndex < 0 || deliveryChoiceIndex >= assignments.size())
|
||||
{
|
||||
return assignments.end();
|
||||
}
|
||||
deliveryAssignments::iterator assignmentIterator = assignments.begin();
|
||||
std::advance(assignmentIterator, deliveryChoiceIndex);
|
||||
return assignmentIterator;
|
||||
}
|
||||
|
||||
void FoodDeliveryController::run()
|
||||
{
|
||||
bool isMenuActive = true;
|
||||
@@ -393,12 +455,118 @@ void FoodDeliveryController::updateRestaurantStatus() const
|
||||
|
||||
void FoodDeliveryController::listRestaurantOrders() const
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
util::clear();
|
||||
if (!checkAccess(m_authenticatedUser, "RestaurantOwner"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
RestaurantOwner& restaurantOwner = *(std::dynamic_pointer_cast<RestaurantOwner>(m_authenticatedUser));
|
||||
restaurants::iterator restaurantIterator = pickRestaurantFromRestaurants(restaurantOwner.getRestaurants());
|
||||
if (restaurantIterator != restaurantOwner.getRestaurants().end())
|
||||
{
|
||||
orders& restaurantOrders = restaurantIterator->second->getOrders();
|
||||
if (restaurantOrders.empty())
|
||||
{
|
||||
std::cout << "Restaurant " << restaurantIterator->second->getName() << " has no orders!\n";
|
||||
return;
|
||||
}
|
||||
orders::iterator orderIterator = pickOrderFromOrders(restaurantOrders);
|
||||
if (orderIterator != restaurantOrders.end())
|
||||
{
|
||||
util::clear();
|
||||
items& orderItems = orderIterator->second->getItems();
|
||||
if (orderItems.empty())
|
||||
{
|
||||
throw std::runtime_error("Order has no items!");
|
||||
}
|
||||
std::cout << "Order " << orderIterator->second->getId() << "\n";
|
||||
std::cout << std::left << std::setw(25) << "Menu Item"
|
||||
<< std::left << std::setw(10) << "Price"
|
||||
<< std::left << std::setw(10) << "Quantity"
|
||||
<< std::left << std::setw(10) << "Total Cost"
|
||||
<< "\n";
|
||||
for (auto& item : orderItems)
|
||||
{
|
||||
MenuItem& menuItem = item->getMenuItem();
|
||||
std::cout << std::left << std::setw(25) << menuItem.getName()
|
||||
<< std::left << std::setw(10) << menuItem.getPrice()
|
||||
<< std::left << std::setw(10) << item->getQuantity()
|
||||
<< std::left << std::setw(10) << menuItem.getPrice() * item->getQuantity()
|
||||
<< "\n";
|
||||
}
|
||||
std::cout << "\nNet Cost : " << orderIterator->second->getTotal() << "\n";
|
||||
std::cout << "Status : " << getOrderStatusString(orderIterator->second->getStatus()) << "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Invalid Index. Cannot display Restaurant Orders\n";
|
||||
}
|
||||
}
|
||||
else if (!restaurantOwner.getRestaurants().empty())
|
||||
{
|
||||
std::cout << "Invalid Index. Cannot display Restaurant Orders\n";
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cout << "Exception: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void FoodDeliveryController::markOrderReady()
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
util::clear();
|
||||
if (!checkAccess(m_authenticatedUser, "RestaurantOwner"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
RestaurantOwner& restaurantOwner = *(std::dynamic_pointer_cast<RestaurantOwner>(m_authenticatedUser));
|
||||
restaurants::iterator restaurantIterator = pickRestaurantFromRestaurants(restaurantOwner.getRestaurants());
|
||||
if (restaurantIterator != restaurantOwner.getRestaurants().end())
|
||||
{
|
||||
orders& restaurantOrders = restaurantIterator->second->getOrders();
|
||||
if (restaurantOrders.empty())
|
||||
{
|
||||
std::cout << "Restaurant " << restaurantIterator->second->getName() << " has no orders!\n";
|
||||
return;
|
||||
}
|
||||
orders::iterator orderIterator = pickOrderFromOrders(restaurantOrders);
|
||||
if (orderIterator != restaurantOrders.end())
|
||||
{
|
||||
OrderStatus orderStatus = orderIterator->second->getStatus();
|
||||
if (orderStatus == OrderStatus::CREATED)
|
||||
{
|
||||
orderIterator->second->setStatus(OrderStatus::READYFORPICKUP);
|
||||
std::shared_ptr<DeliveryAssignment> deliveryAssignment = std::make_shared<DeliveryAssignment>(*orderIterator->second);
|
||||
m_assignments[deliveryAssignment->getId()] = deliveryAssignment;
|
||||
std::cout << "Order has been marked ready for pickup\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Cannot mark order ready for pickup. Order has already been cancelled, is in transit, or is already marked ready for pickup, or has been delivered!\n";
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Invalid Index. Cannot mark order ready for pickup!\n";
|
||||
}
|
||||
}
|
||||
else if (!restaurantOwner.getRestaurants().empty())
|
||||
{
|
||||
std::cout << "Invalid Index. Cannot mark order ready for pickup!\n";
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cout << "Exception: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void FoodDeliveryController::listMenuItems() const
|
||||
@@ -651,6 +819,7 @@ void FoodDeliveryController::placeOrder()
|
||||
if (order && !order->getItems().empty())
|
||||
{
|
||||
customer->addOrder(order);
|
||||
restaurantIterator->second->addOrder(order);
|
||||
std::cout << "Order with ID " << order->getId() << " has been placed successfully\n";
|
||||
}
|
||||
else
|
||||
@@ -718,17 +887,141 @@ void FoodDeliveryController::cancelOrder() const
|
||||
|
||||
void FoodDeliveryController::listDeliveryAssignments()
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
util::clear();
|
||||
if (!checkAccess(m_authenticatedUser, "DeliveryPartner"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto deliveryPartner = std::dynamic_pointer_cast<DeliveryPartner>(m_authenticatedUser);
|
||||
if (!deliveryPartner)
|
||||
{
|
||||
throw std::runtime_error("Cannot accept Delivery Assignment. Failed to verify access!");
|
||||
}
|
||||
deliveryAssignments& assignments = deliveryPartner->getAssignedDeliveries();
|
||||
if (assignments.empty())
|
||||
{
|
||||
std::cout << "You haven't accepted any Delivery Assignments!\n";
|
||||
return;
|
||||
}
|
||||
std::cout << std::left << std::setw(5) << "ID"
|
||||
<< std::left << std::setw(12) << "Order ID"
|
||||
<< std::left << std::setw(22) << "Delivery Status"
|
||||
<< std::left << std::setw(30) << "Address"
|
||||
<< "\n";
|
||||
for (auto& assignment : assignments)
|
||||
{
|
||||
Order& order = assignment.second->getOrder();
|
||||
users::const_iterator customer = m_users.find(order.getCustomerUsername());
|
||||
if (customer == m_users.end())
|
||||
{
|
||||
throw std::runtime_error("Invalid state: Delivery Assignment has no associated Customer.");
|
||||
}
|
||||
std::cout << std::left << std::setw(5) << assignment.second->getId()
|
||||
<< std::left << std::setw(12) << order.getId()
|
||||
<< std::left << std::setw(22) << getDeliveryStatusString(assignment.second->getStatus())
|
||||
<< std::left << std::setw(30) << customer->second->getAddress()
|
||||
<< "\n";
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cout << "Exception: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void FoodDeliveryController::acceptDeliveryAssignment()
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
util::clear();
|
||||
if (!checkAccess(m_authenticatedUser, "DeliveryPartner"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto deliveryPartner = std::dynamic_pointer_cast<DeliveryPartner>(m_authenticatedUser);
|
||||
if (!deliveryPartner)
|
||||
{
|
||||
throw std::runtime_error("Cannot accept Delivery Assignment. Failed to verify access!");
|
||||
}
|
||||
if (m_assignments.empty())
|
||||
{
|
||||
std::cout << "No Delivery Assignments available at the moment!\n";
|
||||
return;
|
||||
}
|
||||
deliveryAssignments::iterator assignmentIterator = pickAssignmentFromDeliveryAssignments(m_assignments, m_users);
|
||||
if (assignmentIterator != m_assignments.end())
|
||||
{
|
||||
DeliveryStatus deliveryStatus = assignmentIterator->second->getStatus();
|
||||
if (deliveryStatus == DeliveryStatus::CREATED)
|
||||
{
|
||||
assignmentIterator->second->setStatus(DeliveryStatus::ACCEPTED);
|
||||
assignmentIterator->second->getOrder().setStatus(OrderStatus::OUTFORDELIVERY);
|
||||
deliveryPartner->acceptDeliveryAssignment(assignmentIterator->second);
|
||||
std::cout << "Delivery Assignment " << assignmentIterator->second->getId() << " has been accepted successfully!\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Delivery Assignment " << assignmentIterator->second->getId() << " cannot be accepted as it is already accepted, or delivered!\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Invalid Index. Cannot accept Delivery Assignment!\n";
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cout << "Exception: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void FoodDeliveryController::confirmDeliveryAssignment()
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
util::clear();
|
||||
if (!checkAccess(m_authenticatedUser, "DeliveryPartner"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto deliveryPartner = std::dynamic_pointer_cast<DeliveryPartner>(m_authenticatedUser);
|
||||
if (!deliveryPartner)
|
||||
{
|
||||
throw std::runtime_error("Cannot confirm Delivery Assignment. Failed to verify access!");
|
||||
}
|
||||
deliveryAssignments& assignments = deliveryPartner->getAssignedDeliveries();
|
||||
if (assignments.empty())
|
||||
{
|
||||
std::cout << "You haven't accepted any Delivery Assignments!\n";
|
||||
return;
|
||||
}
|
||||
deliveryAssignments::iterator assignmentIterator = pickAssignmentFromDeliveryAssignments(assignments, m_users);
|
||||
if (assignmentIterator != assignments.end())
|
||||
{
|
||||
DeliveryStatus deliveryStatus = assignmentIterator->second->getStatus();
|
||||
if (deliveryStatus == DeliveryStatus::ACCEPTED)
|
||||
{
|
||||
assignmentIterator->second->setStatus(DeliveryStatus::DELIVERED);
|
||||
assignmentIterator->second->getOrder().setStatus(OrderStatus::DELIVERED);
|
||||
std::cout << "Delivery Assignment " << assignmentIterator->second->getId() << " has been completed successfully!\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Delivery Assignment " << assignmentIterator->second->getId() << " cannot be confirmed as it has not been accepted yet, or has already been delivered!\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Invalid Index. Cannot confirm Delivery Assignment!\n";
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cout << "Exception: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void FoodDeliveryController::viewProfile() const
|
||||
|
||||
@@ -14,12 +14,14 @@ class Restaurant;
|
||||
class MenuItem;
|
||||
class Item;
|
||||
class Order;
|
||||
class DeliveryAssignment;
|
||||
|
||||
using users = std::map<std::string, std::shared_ptr<User>>;
|
||||
using restaurants = std::map<int, std::shared_ptr<Restaurant>>;
|
||||
using menuItems = std::map<int, std::shared_ptr<MenuItem>>;
|
||||
using items = std::vector<std::shared_ptr<Item>>;
|
||||
using orders = std::map<int, std::shared_ptr<Order>>;
|
||||
using deliveryAssignments = std::map<int, std::shared_ptr<DeliveryAssignment>>;
|
||||
|
||||
class FoodDeliveryController
|
||||
{
|
||||
@@ -27,6 +29,7 @@ private:
|
||||
users m_users;
|
||||
restaurants m_restaurants;
|
||||
orders m_orders;
|
||||
deliveryAssignments m_assignments;
|
||||
std::shared_ptr<User> m_authenticatedUser;
|
||||
public:
|
||||
void run();
|
||||
|
||||
Reference in New Issue
Block a user