orders = new Orders(); $this->order_items = new OrderItems(); $this->order_item_options = new OrderItemOptions(); $this->order_taxes = new OrderTaxes(); $this->order_payments = new OrderPayments(); $this->order_deliveries = new OrderDeliveries(); $this->db = Config::connect(); $this->wato = new Wato(); $this->user = new User(); $this->menu_item_variations = new MenuItemVariations(); } public function orderList() { $user_id = $this->request->getVar('user_id'); $start_date = $this->request->getVar('start_date'); $end_date = $this->request->getVar('end_date'); $status = $this->request->getVar('status'); $outlet_id = $this->request->getVar('outlet_id'); $order_type = $this->request->getVar('order_type'); // Get the user information to check role and outlet $user = $this->user->find($user_id); if (!$user) { return $this->respond([ 'status' => 404, 'message' => 'User not found', 'data' => [] ]); } $orderQuery = $this->orders ->orderBy('created_at', 'DESC'); // If user is not admin, filter by their outlet_id if ($user['role'] !== 'admin') { $orderQuery->where('outlet_id', $user['outlet_id']); } else { // If admin and specific outlet_id is provided, use it if (!empty($outlet_id)) { $orderQuery->where('outlet_id', $outlet_id); } // Otherwise admin sees all orders (no outlet filter) } if (!empty($start_date)) { $orderQuery->where('created_at >=', $start_date . ' 00:00:00'); } if (!empty($end_date)) { $orderQuery->where('created_at <=', $end_date . ' 23:59:59'); } if (!empty($status)) { $orderQuery->where('status', $status); } if (!empty($outlet_id)) { $orderQuery->where('outlet_id', $outlet_id); } if (!empty($order_type)) { $orderQuery->where('order_type', $order_type); } $orders = $orderQuery->findAll(); if (empty($orders)) { return $this->respond([ 'status' => 200, 'message' => 'No orders found!', 'data' => [] ]); } foreach ($orders as &$order) { $order_id = $order['id']; // Fetch items + options $order['items'] = $this->order_items->where('order_id', $order_id)->findAll(); foreach ($order['items'] as &$item) { $item['options'] = $this->order_item_options ->where('order_item_id', $item['id']) ->findAll(); } // Fetch taxes $order['taxes'] = $this->order_taxes ->where('order_id', $order_id) ->findAll(); // Fetch payments $order['payments'] = $this->order_payments ->where('order_id', $order_id) ->orderBy('created_at', 'DESC') ->findAll(); // Fetch deliveries $order['deliveries'] = $this->order_deliveries ->where('order_id', $order_id) ->findAll(); } return $this->respond([ 'status' => 200, 'message' => 'Orders retrieved successfully', 'data' => $orders ]); } public function showOrder($order_id = null) { // Get order with customer + outlet info $order = $this->orders ->select(' orders.*, customers.id as customer_id, customers.name as customer_name, customers.email as customer_email, customers.phone as customer_phone, customers.profile_picture as customer_profile_pic, outlets.id as outlet_id, outlets.title as outlet_title, outlets.email as outlet_email, outlets.phone as outlet_phone, outlets.address as outlet_address, ') ->join('customers', 'customers.id = orders.customer_id', 'left') ->join('outlets', 'outlets.id = orders.outlet_id', 'left') // join outlets ->where('orders.id', $order_id) ->first(); if (!$order) { return $this->fail('Order not found', 400); } // Items + options + menu images $order['items'] = $this->order_items ->select('order_items.*, menu_images.image_url as menu_item_image') ->join('menu_images', 'menu_images.menu_item_id = order_items.menu_item_id', 'left') ->where('order_items.order_id', $order_id) ->groupBy('order_items.id') ->findAll(); foreach ($order['items'] as &$item) { $item['options'] = $this->order_item_options->where('order_item_id', $item['id'])->findAll(); $item['menu_item_image'] = getMenuImage($item['menu_item_id']); $item['variation_name'] = $this->menu_item_variations ->where('menu_item_id', $item['menu_item_id']) ->where('id', $item['variation_id']) ->first()['title'] ?? ''; } // Taxes $order['taxes'] = $this->order_taxes->where('order_id', $order_id)->findAll(); // Payments $order['payments'] = $this->order_payments ->where('order_id', $order_id) ->orderBy('created_at', 'DESC') ->findAll(); // Deliveries $order['deliveries'] = $this->order_deliveries->where('order_id', $order_id)->findAll(); return $this->respond([ 'status' => 200, 'message' => 'Order retrieved successfully', 'data' => $order ]); } public function updateOrderSchedule($order_id = null) { // Validate order_id if (empty($order_id)) { return $this->fail('Order ID is required', 400); } // Get the order $order = $this->orders->find($order_id); if (!$order) { return $this->fail('Order not found', 404); } // Check if order status is 'complete' if (isset($order['status']) && $order['status'] === 'complete') { return $this->fail('Cannot modify schedule for completed orders', 400); } // Get request data $selected_date = $this->request->getVar('selected_date'); $selected_time = $this->request->getVar('selected_time'); // Validate input if (empty($selected_date) || empty($selected_time)) { return $this->fail('Both selected_date and selected_time are required', 400); } // Prepare data to update $data = [ 'selected_date' => $selected_date, 'selected_time' => $selected_time, 'updated_at' => date('Y-m-d H:i:s') // Update timestamp ]; try { // Update the order $updated = $this->orders->update($order_id, $data); if (!$updated) { return $this->fail('Failed to update order schedule', 500); } // Get the updated order $updatedOrder = $this->orders->find($order_id); return $this->respond([ 'status' => 200, 'message' => 'Order schedule updated successfully', 'data' => $updatedOrder ]); } catch (\Exception $e) { return $this->fail('An error occurred while updating order schedule: ' . $e->getMessage(), 500); } } public function updateOrderStatus($order_id = null) { // Validate order_id if (empty($order_id)) { return $this->fail('Order ID is required', 400); } // Get the order $order = $this->orders->select('orders.*, customer_addresses.phone as recipient_phone') ->join('customer_addresses', 'customer_addresses.id = orders.customer_address_id AND customer_addresses.deleted_at IS NULL', 'left')->find($order_id); if (!$order) { return $this->fail('Order not found', 404); } // Get request data $status = $this->request->getVar('status'); // Validate input if (empty($status)) { return $this->fail('Status is required', 400); } // Define allowed status values $allowedStatuses = ['pending', 'picked_up', 'on_the_way', 'completed', 'ready_to_pickup']; if (!in_array($status, $allowedStatuses)) { return $this->fail('Invalid status value. Allowed values: ' . implode(', ', $allowedStatuses), 400); } // Prepare data to update $data = [ 'status' => $status, 'updated_at' => date('Y-m-d H:i:s') // Update timestamp ]; try { // Update the order $updated = $this->orders->update($order_id, $data); if ($order['status'] != $status) { //send notification to customer if status is changed $message = ''; switch ($status) { case 'ready_to_pickup': $message = "🍴 Your food is ready for pickup!\nPlease show your order number at the counter: \n**{{" . $order['order_so'] . "}}**"; break; case 'on_the_way': $message = "🚚 Your order [**" . $order['order_so'] . "**] is on the way!\nThe driver is delivering your food now.\nPlease get ready to receive it."; break; case 'completed': $message = "🎉 Your order [**" . $order['order_so'] . "**] has been completed.\nWe hope you enjoy your meal!\nThank you for ordering with us."; break; } if ($message) { $this->wato->pushNotification($order['recipient_phone'], $message); } } if (!$updated) { return $this->fail('Failed to update order status', 500); } // Get the updated order $updatedOrder = $this->orders->find($order_id); return $this->respond([ 'status' => 200, 'message' => 'Order status updated successfully', 'data' => $updatedOrder ]); } catch (\Exception $e) { return $this->fail('An error occurred while updating order status: ' . $e->getMessage(), 500); } } public function createOrderDelivery() { // Get request data $order_id = $this->request->getVar('order_id'); $fee_amount = $this->request->getVar('actual_fee_amount'); $tracking_link = $this->request->getVar('tracking_link'); // Optional fields that will be set to empty string if not provided $provider_name = $this->request->getVar('provider_name') ?? ''; $provider_order_id = $this->request->getVar('provider_order_id') ?? ''; $actual_fee_amount = $this->request->getVar('fee_amount') ?? ''; $transaction_id = $this->request->getVar('transaction_id') ?? ''; // Validate required fields if (empty($order_id) || empty($actual_fee_amount) || empty($tracking_link)) { return $this->fail('order_id, actual_fee_amount, and tracking_link are required', 400); } // Check if the order exists $order = $this->orders->find($order_id); if (!$order) { return $this->fail('Order not found', 404); } // Prepare data for insertion with empty strings for optional fields $data = [ 'order_id' => $order_id, 'provider_name' => $provider_name, 'status' => 'pending', // Default status 'provider_order_id' => $provider_order_id, 'fee_amount' => $fee_amount, 'actual_fee_amount' => $actual_fee_amount, 'transaction_id' => $transaction_id, 'tracking_link' => $tracking_link, 'created_at' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s') ]; try { // Insert the data $inserted = $this->order_deliveries->insert($data); if (!$inserted) { return $this->fail('Failed to create order delivery record', 500); } // Get the inserted ID $insertId = $this->db->insertID(); // Return success response with the created record return $this->respond([ 'status' => 201, 'message' => 'Order delivery record created successfully', 'data' => array_merge(['id' => $insertId], $data) ], 201); } catch (\Exception $e) { return $this->fail('An error occurred while creating order delivery: ' . $e->getMessage(), 500); } } public function updateOrderDelivery($id = null) { if (empty($id)) { return $this->fail('Delivery record ID is required', 400); } // Get request data - all fields optional except id $data = [ 'actual_fee_amount' => $this->request->getVar('actual_fee_amount') ?? '', 'tracking_link' => $this->request->getVar('tracking_link'), 'updated_at' => date('Y-m-d H:i:s') ]; // Remove fields that weren't provided in the request (except status which has a default) $data = array_filter($data, function ($value, $key) { return $value !== null || $key === 'status'; }, ARRAY_FILTER_USE_BOTH); if (empty($data)) { return $this->respond([ 'status' => 200, 'message' => 'No fields to update', 'data' => null ]); } try { $updated = $this->order_deliveries->update($id, $data); if (!$updated) { return $this->fail('Failed to update order delivery record', 500); } // Get the updated record $updatedData = $this->order_deliveries->find($id); // Convert NULL values to empty strings in the response $responseData = [ 'id' => $id, 'order_id' => $updatedData['order_id'], 'provider_name' => $updatedData['provider_name'] ?? '', 'status' => $updatedData['status'] ?? '', 'provider_order_id' => $updatedData['provider_order_id'] ?? '', 'fee_amount' => $updatedData['fee_amount'] ?? '', 'actual_fee_amount' => $updatedData['actual_fee_amount'], 'transaction_id' => $updatedData['transaction_id'] ?? '', 'tracking_link' => $updatedData['tracking_link'], 'created_at' => $updatedData['created_at'], 'updated_at' => $updatedData['updated_at'] ]; return $this->respond([ 'status' => 200, 'message' => 'Order delivery updated successfully', 'data' => $responseData ]); } catch (\Exception $e) { return $this->fail('An error occurred while updating order delivery: ' . $e->getMessage(), 500); } } public function getOrderDelivery($order_id = null) { // Validate order_id if (empty($order_id)) { return $this->fail('Order ID is required', 400); } try { // Get delivery record by order_id $delivery = $this->order_deliveries->where('order_id', $order_id)->get()->getRowArray(); if (!$delivery) { return $this->respond([ 'status' => 404, 'message' => 'No delivery record found for this order', 'data' => null ], 404); } // Format the response data with empty strings instead of NULL $responseData = [ 'id' => $delivery['id'], 'order_id' => $delivery['order_id'], 'provider_name' => $delivery['provider_name'] ?? '', 'status' => $delivery['status'] ?? '', 'provider_order_id' => $delivery['provider_order_id'] ?? '', 'fee_amount' => $delivery['fee_amount'] ?? '', 'actual_fee_amount' => $delivery['actual_fee_amount'], 'transaction_id' => $delivery['transaction_id'] ?? '', 'tracking_link' => $delivery['tracking_link'], 'created_at' => $delivery['created_at'], 'updated_at' => $delivery['updated_at'] ]; return $this->respond([ 'status' => 200, 'message' => 'Order delivery retrieved successfully', 'data' => $responseData ]); } catch (\Exception $e) { return $this->fail('An error occurred while fetching order delivery: ' . $e->getMessage(), 500); } } public function customerOrderList() { $start_date = $this->request->getVar('start_date'); $end_date = $this->request->getVar('end_date'); $status = $this->request->getVar('status'); $outlet_id = $this->request->getVar('outlet_id'); $order_type = $this->request->getVar('order_type'); $orderQuery = $this->orders ->orderBy('created_at', 'DESC'); if (!empty($start_date)) { $orderQuery->where('created_at >=', $start_date . ' 00:00:00'); } if (!empty($end_date)) { $orderQuery->where('created_at <=', $end_date . ' 23:59:59'); } if (!empty($status)) { $orderQuery->where('status', $status); } if (!empty($outlet_id)) { $orderQuery->where('outlet_id', $outlet_id); } if (!empty($order_type)) { $orderQuery->where('order_type', $order_type); } $orders = $orderQuery->findAll(); if (empty($orders)) { return $this->respond([ 'status' => 200, 'message' => 'No orders found!', 'data' => [] ]); } foreach ($orders as &$order) { $order_id = $order['id']; // Fetch items + options $order['items'] = $this->order_items->where('order_id', $order_id)->findAll(); foreach ($order['items'] as &$item) { $item['options'] = $this->order_item_options ->where('order_item_id', $item['id']) ->findAll(); } // Fetch taxes $order['taxes'] = $this->order_taxes ->where('order_id', $order_id) ->findAll(); // Fetch payments $order['payments'] = $this->order_payments ->where('order_id', $order_id) ->orderBy('created_at', 'DESC') ->findAll(); // Fetch deliveries $order['deliveries'] = $this->order_deliveries ->where('order_id', $order_id) ->findAll(); } return $this->respond([ 'status' => 200, 'message' => 'Orders retrieved successfully', 'data' => $orders ]); } }