select('order_type') ->where('id', $id) ->where('deleted_at', null) ->first(); if (!$order) { return ''; } return $order['order_type'] ?? ''; } } if (!function_exists('getFullOrderDetail')) { function getFullOrderDetail($id) { $orders = new Orders(); $order_items = new OrderItems(); $order_item_options = new OrderItemOptions(); $order_payments = new OrderPayments(); $order_taxes = new OrderTaxes(); $order_detail = array(); $order = $orders->find($id); if (!$order) { return array(); } $order_detail = $order; $order_detail['items'] = $order_items->where('order_id', $order['id'])->findAll(); foreach ($order_detail['items'] as &$item) { $item['options'] = $order_item_options ->where('order_item_id', $item['id']) ->findAll(); } $order_detail['taxes'] = $order_taxes ->where('order_id', $order['id']) ->findAll(); $order_detail['payments'] = $order_payments ->where('order_id', $order['id']) ->orderBy('created_at', 'DESC') ->findAll(); // $order_detail['item'] = return $order_detail; } } if (!function_exists('completeOrder')) { function completeOrder($order_id) { $orders = new Orders(); $customers = new Customer(); $order_payments = new OrderPayments(); $customer_wallet = new CustomerWallet(); $customer_point_history = new CustomerPoint(); //get order and customer data $order = $orders->select('orders.*, customers.*, order_payments.*') ->join('customers', 'customers.id = orders.customer_id AND customers.deleted_at IS NULL') ->join('order_payments', 'order_payments.order_id = orders.id AND order_payments.deleted_at IS NULL') ->where('orders.id', $order_id) ->where('orders.deleted_at', null) ->first(); if (!$order) { return false; } //get payment method $order_so = $order['order_so']; $payment_method = $order['payment_method']; $customer_id = $order['customer_id']; $grand_total = $order['grand_total']; $outlet_id = $order['outlet_id']; $order_type = $order['order_type']; //get outlet data $outlets = new Outlet(); $outlet = $outlets->where('id', $outlet_id)->where('deleted_at', null)->first(); //update payment status $orders->update($order_id, ['payment_status' => 'paid']); switch ($payment_method) { case 'wallet': $wallet_balance = $order['customer_wallet'] - $grand_total; $customers->update($customer_id, ['customer_wallet' => $wallet_balance]); $order_payments->update($order_id, ['status' => 'completed', 'paid_at' => date('Y-m-d H:i:s')]); $customer_wallet_transaction = [ 'customer_id' => $customer_id, 'related_id' => $order_id, 'related_type' => 'order', 'action' => 'out', 'current' => $order['customer_wallet'], 'in' => 0, 'out' => $grand_total, 'balance' => $wallet_balance, 'remark' => $grand_total . ' deducted from wallet for order ' . $order_so, ]; $customer_wallet->insert($customer_wallet_transaction); break; default: //update order payments $order_payments->update($order_id, ['status' => 'completed', 'paid_at' => date('Y-m-d H:i:s')]); break; } //update point $customer_point = $order['customer_point'] + floor($grand_total); $customers->update($customer_id, ['customer_point' => $customer_point]); $customer_point_transaction = [ 'customer_id' => $customer_id, 'related_id' => $order_id, 'related_type' => 'order', 'action' => 'in', 'current' => $order['customer_point'], 'in' => floor($grand_total), 'out' => 0, 'balance' => $customer_point, 'remark' => floor($grand_total) . ' points earned from order ' . $order_so, ]; $customer_point_history->insert($customer_point_transaction); //get customer point history cumulative $customer_point_history_cumulative = $customer_point_history->where('customer_id', $customer_id)->where('deleted_at', null)->selectSum('in')->get()->getRow()->in ?? 0; //get membership tier setting and check for automatic upgrade $setting_membership_tier = new \App\Models\SettingMembershipTier(); $membership_tier_setting = $setting_membership_tier->where('deleted_at', null)->orderBy('min_points', 'ASC')->findAll(); // Get current customer membership tier $current_customer = $customers->where('id', $customer_id)->first(); $current_membership_tier = $current_customer['customer_tier_id'] ?? 0; $get_current_tier = $setting_membership_tier->where('id', $current_membership_tier)->first(); $current_tier_min_points = $get_current_tier['min_points'] ?? 0; // echo($customer_point_history_cumulative);exit; // Check if customer qualifies for higher membership tier $new_membership_tier = $current_membership_tier; foreach ($membership_tier_setting as $tier) { if ($customer_point_history_cumulative >= $tier['min_points'] && $tier['min_points'] > $current_tier_min_points) { // Customer qualifies for this tier // if($tier['id'] > $current_membership_tier){ $new_membership_tier = $tier['id']; log_message('info', 'Customer ' . $customer_id . ' upgraded from tier ' . $current_membership_tier . ' to tier ' . $new_membership_tier . ' (Points: ' . $customer_point_history_cumulative . ')'); // } } } // Update customer membership tier if upgraded if ($new_membership_tier != $current_membership_tier) { $customers->update($customer_id, [ 'customer_tier_id' => $new_membership_tier ]); log_message('info', 'Customer ' . $customer_id . ' membership tier updated to: ' . $new_membership_tier); } if ($order_type == 'delivery') { //need to check date & time as well // Check which delivery service was used based on quotation ID if ($order['lalamove_quot_id'] != null) { // Lalamove was used for quotation $lalamove = new Lalamove(); $lalamove_response = $lalamove->submitOrder($order_id); if (isset($lalamove_response['data']['orderId'])) { $order_delivery = new OrderDeliveries(); $order_delivery->insert([ 'order_id' => $order_id, 'provider_name' => 'Lalamove', 'status' => 'success', 'provider_order_id' => $lalamove_response['data']['orderId'], 'fee_amount' => $lalamove_response['data']['priceBreakdown']['total'], 'actual_fee_amount' => $lalamove_response['data']['priceBreakdown']['total'], 'transaction_id' => $lalamove_response['data']['quotationId'], 'tracking_link' => $lalamove_response['data']['shareLink'], 'created_at' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s'), ]); } else { return false; } } else if ($order['grab_quot_id'] != null) { // Grab was used for quotation $grab = new \App\Libraries\Grab(); $grab_response = $grab->submitOrder($order_id); if (isset($grab_response['deliveryID'])) { $order_delivery = new OrderDeliveries(); $order_delivery->insert([ 'order_id' => $order_id, 'provider_name' => 'Grab', 'status' => 'success', 'provider_order_id' => $grab_response['deliveryID'], 'fee_amount' => $order['delivery_fee'] ?? 0, 'actual_fee_amount' => $order['delivery_fee'] ?? 0, 'transaction_id' => $order['grab_quot_id'] ?? null, 'tracking_link' => $grab_response['trackingURL'] ?? null, 'created_at' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s'), ]); //update order status $orders->update($order_id, ['grab_quot_id' => $grab_response['deliveryID']]); } else { return false; } } else if ($order['delivery_fee'] > 0) { //manual delivery fee $order_delivery = new OrderDeliveries(); $order_delivery->insert([ 'order_id' => $order_id, 'provider_name' => 'Manual', 'status' => 'success', 'fee_amount' => $order['delivery_fee'] ?? 0, 'created_at' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s'), ]); } } // Get all items for this order $order_items = new OrderItems(); $menu_item = new MenuItems(); $customer_voucher_lists = new CustomerVoucherList(); $membershipTier = null; $hasMembershipItem = false; $orderItems = $order_items->where('order_id', $order_id)->findAll(); // Loop through items in order — assume $orderItems is already in "latest first" order foreach ($orderItems as $item) { $menuItem = $menu_item->where('id', $item['menu_item_id'])->first(); if ($menuItem && !empty($menuItem['membership_tier'])) { $membershipTier = (int) $menuItem['membership_tier']; $hasMembershipItem = true; break; // stop at first membership found — since list is latest first } } if ($hasMembershipItem) { // Update customer tier $customers->update($customer_id, [ 'customer_tier_id' => $membershipTier, 'customer_type' => 'VIP Customer' ]); // Give 3 vouchers for ($i = 0; $i < 3; $i++) { $voucherCode = strtoupper(uniqid('VCH')); $data = [ 'customer_id' => $customer_id, 'promo_setting_id' => '29', 'voucher_order_id' => $order_id, 'voucher_topup_id' => 0, 'voucher_code' => $voucherCode, 'voucher_expiry_date' => '2025-12-31', 'voucher_status' => 'active', ]; $customer_voucher_lists->insert($data); } } //send notification to customer $wato = new Wato(); $message = "🍽️ Your order has been placed successfully!\nOur outlet is now preparing your food.\nThank you for your patience."; $wato->pushNotification($order['phone'], $message); return true; //update order status // $orders->update($order_id, ['delivery_status' => 'pending']); } } if (!function_exists('calculateRoundingAmount')) { function calculateRoundingAmount($original_amount) { // Convert to float and format to 2 decimal places $original_amount = number_format_no_round((float)$original_amount); // echo($amount);exit; // Get the last digit (cents) $lastDigit = (int)substr($original_amount, -1); // Apply rounding rules if ($lastDigit <= 2) { // Round down to nearest 0 $amount = substr_replace($original_amount, '0', -1); } elseif ($lastDigit <= 7) { // Round to nearest 5 $amount = substr_replace($original_amount, '5', -1); } else { // Round up to next 10 cents $amount = number_format((float)$original_amount+0.1, 2, '.', ''); $amount = substr_replace($amount, '0', -1); } if ($lastDigit >= 6 && $lastDigit <= 9) { return number_format(((float)$amount - (float)$original_amount), 2); } else { return number_format(((float)$original_amount - (float)$amount), 2); } } }