Implement customer order controllers with related model/helper updates
- Implement Controller listCustomerOrders() - Implement Controller placeOrder() - Implement Controller cancelOrder() - Fix Item() constructor - Add static m_uid to Order to track unique ID - Add Order Status getter and setter - Rename pickMenuFromMenuItems() to pickItemFromMenu() - Add new controller helper pickOrderFromOrders() - Add new controller helper getOrderStatusString()
This commit is contained in:
@@ -65,7 +65,7 @@ static restaurants::iterator pickRestaurantFromRestaurants(restaurants& ownerRes
|
|||||||
return restaurantIterator;
|
return restaurantIterator;
|
||||||
}
|
}
|
||||||
|
|
||||||
static menuItems::iterator pickMenuFromMenuItems(menuItems& restaurantMenuItems)
|
static menuItems::iterator pickItemFromMenu(menuItems& restaurantMenuItems)
|
||||||
{
|
{
|
||||||
util::clear();
|
util::clear();
|
||||||
int menuItemIndex = 1, menuItemChoiceIndex;
|
int menuItemIndex = 1, menuItemChoiceIndex;
|
||||||
@@ -104,6 +104,63 @@ static menuItems::iterator pickMenuFromMenuItems(menuItems& restaurantMenuItems)
|
|||||||
return menuItemIterator;
|
return menuItemIterator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string getOrderStatusString(const OrderStatus& orderStatus)
|
||||||
|
{
|
||||||
|
switch (orderStatus)
|
||||||
|
{
|
||||||
|
case OrderStatus::CREATED:
|
||||||
|
return "Created";
|
||||||
|
case OrderStatus::READYFORPICKUP:
|
||||||
|
return "Ready For Pickup";
|
||||||
|
case OrderStatus::OUTFORDELIVERY:
|
||||||
|
return "Out for Delivery";
|
||||||
|
case OrderStatus::DELIVERED:
|
||||||
|
return "Delivered";
|
||||||
|
case OrderStatus::CANCELLED:
|
||||||
|
return "Cancelled";
|
||||||
|
default:
|
||||||
|
return "Unkown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static orders::iterator pickOrderFromOrders(orders& customerOrders)
|
||||||
|
{
|
||||||
|
util::clear();
|
||||||
|
std::cout << "Pick an order\n";
|
||||||
|
int orderIndex = 1, orderChoiceIndex;
|
||||||
|
if (customerOrders.empty())
|
||||||
|
{
|
||||||
|
std::cout << "You have not placed any orders!\n";
|
||||||
|
return customerOrders.end();
|
||||||
|
}
|
||||||
|
std::cout << std::left << std::setw(8) << "Index"
|
||||||
|
<< std::left << std::setw(5) << "ID"
|
||||||
|
<< std::left << std::setw(15) << "Item Count"
|
||||||
|
<< std::left << std::setw(15) << "Total Amount"
|
||||||
|
<< std::left << std::setw(15) << "Status"
|
||||||
|
<< "\n";
|
||||||
|
for (auto& order : customerOrders)
|
||||||
|
{
|
||||||
|
std::cout << std::left << std::setw(8) << orderIndex
|
||||||
|
<< std::left << std::setw(5) << order.second->getId()
|
||||||
|
<< std::left << std::setw(15) << order.second->getItems().size()
|
||||||
|
<< std::left << std::setw(15) << order.second->getTotal()
|
||||||
|
<< std::left << std::setw(15) << getOrderStatusString(order.second->getStatus())
|
||||||
|
<< "\n";
|
||||||
|
orderIndex++;
|
||||||
|
}
|
||||||
|
std::cout << "\nSelect Index: ";
|
||||||
|
util::readValue<int>(orderChoiceIndex);
|
||||||
|
orderChoiceIndex--;
|
||||||
|
if (orderChoiceIndex < 0 || orderChoiceIndex >= customerOrders.size())
|
||||||
|
{
|
||||||
|
return customerOrders.end();
|
||||||
|
}
|
||||||
|
orders::iterator orderIterator = customerOrders.begin();
|
||||||
|
std::advance(orderIterator, orderChoiceIndex);
|
||||||
|
return orderIterator;
|
||||||
|
}
|
||||||
|
|
||||||
void FoodDeliveryController::run()
|
void FoodDeliveryController::run()
|
||||||
{
|
{
|
||||||
bool isMenuActive = true;
|
bool isMenuActive = true;
|
||||||
@@ -441,7 +498,7 @@ void FoodDeliveryController::removeMenuItem() const
|
|||||||
if (restaurantIterator != restaurantOwner.getRestaurants().end())
|
if (restaurantIterator != restaurantOwner.getRestaurants().end())
|
||||||
{
|
{
|
||||||
menuItems& restaurantMenuItems = restaurantIterator->second->getMenuItems();
|
menuItems& restaurantMenuItems = restaurantIterator->second->getMenuItems();
|
||||||
menuItems::iterator menuItemIterator = pickMenuFromMenuItems(restaurantMenuItems);
|
menuItems::iterator menuItemIterator = pickItemFromMenu(restaurantMenuItems);
|
||||||
if (menuItemIterator != restaurantMenuItems.end())
|
if (menuItemIterator != restaurantMenuItems.end())
|
||||||
{
|
{
|
||||||
restaurantMenuItems.erase(menuItemIterator);
|
restaurantMenuItems.erase(menuItemIterator);
|
||||||
@@ -464,19 +521,200 @@ void FoodDeliveryController::removeMenuItem() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FoodDeliveryController::listCustomerOrders()
|
void FoodDeliveryController::listCustomerOrders() const
|
||||||
{
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
util::clear();
|
||||||
|
if (!checkAccess(m_authenticatedUser, "Customer"))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto customer = std::dynamic_pointer_cast<Customer>(m_authenticatedUser);
|
||||||
|
if (!customer)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Cannot place order. Failed to verify access!");
|
||||||
|
}
|
||||||
|
orders customerOrders = customer->getOrders();
|
||||||
|
if (customerOrders.empty())
|
||||||
|
{
|
||||||
|
std::cout << "You have not placed any orders!\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
orders::iterator orderIterator = pickOrderFromOrders(customerOrders);
|
||||||
|
if (orderIterator != customerOrders.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 << "Net Cost : " << orderIterator->second->getTotal() << "\n";
|
||||||
|
std::cout << "Status : " << getOrderStatusString(orderIterator->second->getStatus()) << "\n";
|
||||||
|
}
|
||||||
|
else if (!customerOrders.empty())
|
||||||
|
{
|
||||||
|
std::cout << "Invalid Index. Cannot display order!\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (const std::exception& e)
|
||||||
|
{
|
||||||
|
std::cout << "Exception: " << e.what() << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FoodDeliveryController::placeOrder()
|
void FoodDeliveryController::placeOrder()
|
||||||
{
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
util::clear();
|
||||||
|
if (!checkAccess(m_authenticatedUser, "Customer"))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto customer = std::dynamic_pointer_cast<Customer>(m_authenticatedUser);
|
||||||
|
if (!customer)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Cannot place order. Failed to verify access!");
|
||||||
|
}
|
||||||
|
restaurants::iterator restaurantIterator = pickRestaurantFromRestaurants(m_restaurants);
|
||||||
|
if (restaurantIterator != m_restaurants.end())
|
||||||
|
{
|
||||||
|
bool isMenuActive = true;
|
||||||
|
menuItems& restaurantMenuItems = restaurantIterator->second->getMenuItems();
|
||||||
|
if (!restaurantIterator->second->getStatus())
|
||||||
|
{
|
||||||
|
std::cout << "Restaurant is closed. Check again later!\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (restaurantMenuItems.empty())
|
||||||
|
{
|
||||||
|
std::cout << "Operation cancelled. Restaurant has no Menu Items!\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::cout << "Creating order\n";
|
||||||
|
std::shared_ptr<Order> order;
|
||||||
|
while (isMenuActive)
|
||||||
|
{
|
||||||
|
menuItems::iterator menuItemIterator = pickItemFromMenu(restaurantMenuItems);
|
||||||
|
if (menuItemIterator != restaurantMenuItems.end())
|
||||||
|
{
|
||||||
|
int quantity;
|
||||||
|
char choice;
|
||||||
|
std::cout << "Enter quantity: ";
|
||||||
|
util::readValue<int>(quantity);
|
||||||
|
if (quantity > 0)
|
||||||
|
{
|
||||||
|
if (!order)
|
||||||
|
{
|
||||||
|
order = std::make_shared<Order>();
|
||||||
|
}
|
||||||
|
order->addItem(Item(*(menuItemIterator->second), quantity));
|
||||||
|
std::cout << menuItemIterator->second->getName() << " with quantity " << quantity << " has been added to your Order\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Quantity cannot be zero!\n";
|
||||||
|
}
|
||||||
|
std::cout << "Do you want to add more items (Y/N)?: ";
|
||||||
|
util::readValue<char>(choice);
|
||||||
|
if (choice != 'Y' && choice != 'y')
|
||||||
|
{
|
||||||
|
isMenuActive = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!restaurantMenuItems.empty())
|
||||||
|
{
|
||||||
|
std::cout << "Invalid Index. Cannot place order!\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (order && !order->getItems().empty())
|
||||||
|
{
|
||||||
|
customer->addOrder(order);
|
||||||
|
std::cout << "Order with ID " << order->getId() << " has been placed successfully\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Operation cancelled. Cannot place order with zero items!\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!m_restaurants.empty())
|
||||||
|
{
|
||||||
|
std::cout << "Invalid Index. Cannot place order!\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (const std::exception& e)
|
||||||
|
{
|
||||||
|
std::cout << "Exception: " << e.what() << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FoodDeliveryController::cancelOrder()
|
void FoodDeliveryController::cancelOrder() const
|
||||||
{
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
util::clear();
|
||||||
|
if (!checkAccess(m_authenticatedUser, "Customer"))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto customer = std::dynamic_pointer_cast<Customer>(m_authenticatedUser);
|
||||||
|
if (!customer)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Cannot place order. Failed to verify access!");
|
||||||
|
}
|
||||||
|
orders customerOrders = customer->getOrders();
|
||||||
|
if (customerOrders.empty())
|
||||||
|
{
|
||||||
|
std::cout << "You have not placed any orders!\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
orders::iterator orderIterator = pickOrderFromOrders(customerOrders);
|
||||||
|
if (orderIterator != customerOrders.end())
|
||||||
|
{
|
||||||
|
OrderStatus orderStatus = orderIterator->second->getStatus();
|
||||||
|
if (orderStatus != OrderStatus::CANCELLED && orderStatus != OrderStatus::DELIVERED) {
|
||||||
|
orderIterator->second->setStatus(OrderStatus::CANCELLED);
|
||||||
|
std::cout << "Order " << orderIterator->second->getId() << " has been cancelled successfully!\n";
|
||||||
|
}
|
||||||
|
else if (orderStatus == OrderStatus::DELIVERED)
|
||||||
|
{
|
||||||
|
std::cout << "Cannot cancel Order " << orderIterator->second->getId() << " as it has already been delivered!\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Order " << orderIterator->second->getId() << " has already been cancelled!\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!customerOrders.empty())
|
||||||
|
{
|
||||||
|
std::cout << "Invalid Index. Cannot cancel order!\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (const std::exception& e)
|
||||||
|
{
|
||||||
|
std::cout << "Exception: " << e.what() << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FoodDeliveryController::listDeliveryAssignments()
|
void FoodDeliveryController::listDeliveryAssignments()
|
||||||
|
|||||||
@@ -6,21 +6,27 @@ Date: 18-02-2026
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
class User;
|
class User;
|
||||||
class Restaurant;
|
class Restaurant;
|
||||||
class MenuItem;
|
class MenuItem;
|
||||||
|
class Item;
|
||||||
|
class Order;
|
||||||
|
|
||||||
using users = std::map<std::string, std::shared_ptr<User>>;
|
using users = std::map<std::string, std::shared_ptr<User>>;
|
||||||
using restaurants = std::map<int, std::shared_ptr<Restaurant>>;
|
using restaurants = std::map<int, std::shared_ptr<Restaurant>>;
|
||||||
using menuItems = std::map<int, std::shared_ptr<MenuItem>>;
|
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>>;
|
||||||
|
|
||||||
class FoodDeliveryController
|
class FoodDeliveryController
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
users m_users;
|
users m_users;
|
||||||
restaurants m_restaurants;
|
restaurants m_restaurants;
|
||||||
|
orders m_orders;
|
||||||
std::shared_ptr<User> m_authenticatedUser;
|
std::shared_ptr<User> m_authenticatedUser;
|
||||||
public:
|
public:
|
||||||
void run();
|
void run();
|
||||||
@@ -34,9 +40,9 @@ public:
|
|||||||
void listMenuItems() const;
|
void listMenuItems() const;
|
||||||
void addMenuItem() const;
|
void addMenuItem() const;
|
||||||
void removeMenuItem() const;
|
void removeMenuItem() const;
|
||||||
void listCustomerOrders();
|
void listCustomerOrders() const;
|
||||||
void placeOrder();
|
void placeOrder();
|
||||||
void cancelOrder();
|
void cancelOrder() const;
|
||||||
void listDeliveryAssignments();
|
void listDeliveryAssignments();
|
||||||
void acceptDeliveryAssignment();
|
void acceptDeliveryAssignment();
|
||||||
void confirmDeliveryAssignment();
|
void confirmDeliveryAssignment();
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ private:
|
|||||||
int m_quantity;
|
int m_quantity;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Item(MenuItem& item)
|
Item(MenuItem& item, int quantity)
|
||||||
: m_item(item), m_quantity(0)
|
: m_item(item), m_quantity(quantity)
|
||||||
{}
|
{}
|
||||||
int getQuantity() const;
|
int getQuantity() const;
|
||||||
MenuItem& getMenuItem();
|
MenuItem& getMenuItem();
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#include "Order.h"
|
#include "Order.h"
|
||||||
|
|
||||||
|
int Order::m_uid = 0;
|
||||||
|
|
||||||
int Order::getId() const
|
int Order::getId() const
|
||||||
{
|
{
|
||||||
return m_id;
|
return m_id;
|
||||||
@@ -20,7 +22,17 @@ double Order::getTotal() const
|
|||||||
double total = 0;
|
double total = 0;
|
||||||
for (auto& itemPointer : m_items)
|
for (auto& itemPointer : m_items)
|
||||||
{
|
{
|
||||||
total += itemPointer->getMenuItem().getPrice();
|
total += itemPointer->getMenuItem().getPrice() * itemPointer->getQuantity();
|
||||||
}
|
}
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OrderStatus Order::getStatus() const
|
||||||
|
{
|
||||||
|
return m_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Order::setStatus(const OrderStatus& orderStatus)
|
||||||
|
{
|
||||||
|
m_status = orderStatus;
|
||||||
|
}
|
||||||
|
|||||||
@@ -22,18 +22,14 @@ enum class OrderStatus
|
|||||||
class Order
|
class Order
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
static int m_uid;
|
||||||
int m_id;
|
int m_id;
|
||||||
items m_items;
|
items m_items;
|
||||||
double m_totalAmount;
|
double m_totalAmount;
|
||||||
OrderStatus m_status;
|
OrderStatus m_status;
|
||||||
public:
|
public:
|
||||||
Order():
|
Order():
|
||||||
m_id(0),
|
m_id(++m_uid),
|
||||||
m_totalAmount(0),
|
|
||||||
m_status(OrderStatus::CREATED)
|
|
||||||
{}
|
|
||||||
Order(int id):
|
|
||||||
m_id(id),
|
|
||||||
m_totalAmount(0),
|
m_totalAmount(0),
|
||||||
m_status(OrderStatus::CREATED)
|
m_status(OrderStatus::CREATED)
|
||||||
{}
|
{}
|
||||||
@@ -41,5 +37,7 @@ public:
|
|||||||
void addItem(const Item&);
|
void addItem(const Item&);
|
||||||
items& getItems();
|
items& getItems();
|
||||||
double getTotal() const;
|
double getTotal() const;
|
||||||
|
OrderStatus getStatus() const;
|
||||||
|
void setStatus(const OrderStatus&);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user