339 lines
13 KiB
PHP
339 lines
13 KiB
PHP
<?php
|
|
|
|
use App\Models\Orders;
|
|
use App\Models\Outlet;
|
|
use App\Models\Customer;
|
|
use App\Models\MenuItems;
|
|
use App\Models\OrderItems;
|
|
use App\Models\OrderTaxes;
|
|
use App\Libraries\Lalamove;
|
|
use App\Models\CustomerPoint;
|
|
use App\Models\CustomerVoucherList;
|
|
use App\Models\OrderPayments;
|
|
use App\Models\CustomerWallet;
|
|
use App\Models\OrderDeliveries;
|
|
use App\Models\OrderItemOptions;
|
|
use App\Libraries\Wato;
|
|
|
|
if (!function_exists('getOrderType')) {
|
|
|
|
function getOrderType($id)
|
|
{
|
|
$orders = new Orders();
|
|
|
|
$order = $orders
|
|
->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);
|
|
}
|
|
}
|
|
}
|