initial project
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
if (!function_exists('getColumnValues')) {
|
||||
|
||||
function getColumnValues($model, string $whereColumn, $whereValue, string $columnToExtract)
|
||||
{
|
||||
$data = $model->where($whereColumn, $whereValue)->findAll();
|
||||
if($data){
|
||||
return array_column($data, $columnToExtract);
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
if (!function_exists('send_api_request')) {
|
||||
/**
|
||||
* Send external API requests with cURL.
|
||||
*
|
||||
* @param string $method HTTP method: GET, POST, PUT, PATCH, DELETE
|
||||
* @param string $url Full URL to request
|
||||
* @param array $headers Optional headers (e.g., Authorization, Content-Type)
|
||||
* @param mixed $body Optional request body (array for form, JSON string for raw)
|
||||
* @param bool $as_json Decode response as JSON (default: true)
|
||||
* @return mixed Decoded JSON, raw string, or false on error
|
||||
*/
|
||||
function send_api_request($method, $url, $headers = [], $body = null, $as_json = true) {
|
||||
$curl = curl_init();
|
||||
|
||||
// Set HTTP method
|
||||
$method = strtoupper($method);
|
||||
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
|
||||
|
||||
// Attach body if needed
|
||||
if (in_array($method, ['POST', 'PUT', 'PATCH']) && $body !== null) {
|
||||
if (is_array($body)) {
|
||||
// Form-encoded
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($body));
|
||||
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
|
||||
} else {
|
||||
// Assume JSON string
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $body);
|
||||
$headers[] = 'Content-Type: application/json';
|
||||
}
|
||||
}
|
||||
|
||||
// Set cURL options
|
||||
curl_setopt_array($curl, [
|
||||
CURLOPT_URL => $url,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_ENCODING => '',
|
||||
CURLOPT_MAXREDIRS => 10,
|
||||
CURLOPT_TIMEOUT => 30,
|
||||
CURLOPT_FOLLOWLOCATION => true,
|
||||
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
||||
]);
|
||||
|
||||
if (!empty($headers)) {
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
|
||||
}
|
||||
|
||||
// Execute
|
||||
$response = curl_exec($curl);
|
||||
|
||||
$error = curl_error($curl);
|
||||
curl_close($curl);
|
||||
|
||||
if ($error) {
|
||||
print_r($error);
|
||||
exit;
|
||||
log_message('error', 'cURL Error: ' . $error);
|
||||
return false;
|
||||
}
|
||||
|
||||
return $as_json ? json_decode($response, true) : $response;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('json_encode_decode')) {
|
||||
function json_encode_decode($type, $data) {
|
||||
if ($type == 'encode'){
|
||||
return json_encode( $data, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_UNESCAPED_UNICODE ) ;
|
||||
}else{
|
||||
return json_decode( $data, true ) ;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if(!function_exists('number_format_no_round')){
|
||||
function number_format_no_round($number, $decimals = 2, $dec_point = '.', $thousands_sep = ',') {
|
||||
$factor = pow(10, $decimals);
|
||||
// Truncate instead of rounding
|
||||
$truncated = floor($number * $factor) / $factor;
|
||||
return number_format($truncated, $decimals, $dec_point, $thousands_sep);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
use Config\Services;
|
||||
|
||||
if (!function_exists('save_image_with_compression')) {
|
||||
/**
|
||||
* Save original image and a compressed (resized) version.
|
||||
*
|
||||
* @param \CodeIgniter\HTTP\Files\UploadedFile $uploadedFile
|
||||
* @param string $originalPath Folder for original image
|
||||
* @param string $compressedPath Folder for compressed image
|
||||
* @param int $compressedWidth Target width for compressed image
|
||||
* @param int $quality JPEG quality (0-100)
|
||||
* @return array ['original' => ..., 'compressed' => ...]
|
||||
*/
|
||||
function save_image_with_compression($uploadedFile, $originalPath, $compressedPath, $compressedWidth = 900, $quality = 80)
|
||||
{
|
||||
// Make sure directories exist
|
||||
if (!is_dir($originalPath)) mkdir($originalPath, 0755, true);
|
||||
if (!is_dir($compressedPath)) mkdir($compressedPath, 0755, true);
|
||||
|
||||
// Save original image
|
||||
$newName = $uploadedFile->getRandomName();
|
||||
$uploadedFile->move($originalPath, $newName);
|
||||
$originalImage = rtrim($originalPath, '/\\') . '/' . $newName;
|
||||
|
||||
// Resize and compress
|
||||
$imageService = Services::image('gd'); // or 'imagick' if enabled
|
||||
$imageService
|
||||
->withFile($originalImage)
|
||||
->resize($compressedWidth, 0, true) // keep aspect ratio
|
||||
->save(rtrim($compressedPath, '/\\') . '/' . $newName, $quality);
|
||||
|
||||
return [
|
||||
'original' => $originalImage,
|
||||
'compressed' => rtrim($compressedPath, '/\\') . '/' . $newName,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
<?php
|
||||
|
||||
use App\Models\MenuCategories;
|
||||
use App\Models\MenuImages;
|
||||
use App\Models\MenuItemCategories;
|
||||
use App\Models\MenuItemOptionsGroups;
|
||||
use App\Models\MenuItems;
|
||||
use App\Models\MenuItemTags;
|
||||
use App\Models\MenuItemVariations;
|
||||
use App\Models\OptionsGroups;
|
||||
use App\Models\RegularItemAvailability;
|
||||
use App\Models\SeasonalItemAvailability;
|
||||
use App\Models\Tags;
|
||||
use App\Models\VariationOptionsGroups;
|
||||
use App\Models\VariationTags;
|
||||
|
||||
if (!function_exists('getMenuImage')) {
|
||||
|
||||
function getMenuImage($id)
|
||||
{
|
||||
$menu_images = new MenuImages();
|
||||
$images_data = $menu_images->where('menu_item_id', $id)
|
||||
->where('deleted_at', NULL)
|
||||
->findAll();
|
||||
|
||||
$data = [];
|
||||
foreach ($images_data as $image) {
|
||||
$data[] = [
|
||||
'id' => $image['id'],
|
||||
'image_url' => getImagePath('menu_images', $image['image_url']),
|
||||
'order_index' => $image['order_index']
|
||||
];
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('getMenuCategory')) {
|
||||
|
||||
function getMenuCategory($id)
|
||||
{
|
||||
$menu_item_category = new MenuItemCategories();
|
||||
$category = new MenuCategories();
|
||||
$category_data = $menu_item_category->where('menu_item_id', $id)
|
||||
->where('deleted_at', NULL)
|
||||
->findAll();
|
||||
|
||||
$data = [];
|
||||
foreach ($category_data as $menu_category) {
|
||||
$category_detail = $category->withDeleted()->find($menu_category['category_id']);
|
||||
if ($category_detail) {
|
||||
$data[] = [
|
||||
'id' => $menu_category['category_id'],
|
||||
'title' => $category_detail['title']
|
||||
];
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('getImagePath')) {
|
||||
|
||||
function getImagePath($path, $name)
|
||||
{
|
||||
$full_path = '';
|
||||
if ($name) {
|
||||
$full_path = 'https://' . $_SERVER['SERVER_NAME'] . '/backend/uploads/' . $path . '/' . $name;
|
||||
}
|
||||
return $full_path;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('getVariationRelation')) {
|
||||
function getVariationRelation($menu_item_id)
|
||||
{
|
||||
$array = [];
|
||||
|
||||
$menu_varition = new MenuItemVariations();
|
||||
$variation_tag = new VariationTags();
|
||||
$variation_option_group = new VariationOptionsGroups();
|
||||
$tagModel = new Tags();
|
||||
$optionGroupModel = new OptionsGroups();
|
||||
|
||||
$menu_variation_data = $menu_varition
|
||||
->where('menu_item_id', $menu_item_id)
|
||||
->findAll();
|
||||
|
||||
foreach ($menu_variation_data as $menu_variation) {
|
||||
$variation_id = $menu_variation['id'];
|
||||
|
||||
$variation_tags = $variation_tag
|
||||
->where('variation_id', $variation_id)
|
||||
->findAll();
|
||||
|
||||
$tags = [];
|
||||
foreach ($variation_tags as $vt) {
|
||||
$tag = $tagModel->find($vt['tag_id']);
|
||||
if ($tag) {
|
||||
$tags[] = $tag;
|
||||
}
|
||||
}
|
||||
|
||||
$variation_option_groups = $variation_option_group
|
||||
->where('variation_id', $variation_id)
|
||||
->findAll();
|
||||
|
||||
$option_groups = [];
|
||||
foreach ($variation_option_groups as $vog) {
|
||||
$group = $optionGroupModel->find($vog['option_group_id']);
|
||||
if ($group) {
|
||||
$group['order_index'] = $vog['order_index'];
|
||||
$option_groups[] = $group;
|
||||
}
|
||||
}
|
||||
|
||||
// Sort $option_groups by 'order_index' ascending
|
||||
usort($option_groups, function ($a, $b) {
|
||||
return $a['order_index'] <=> $b['order_index'];
|
||||
});
|
||||
|
||||
$array[] = [
|
||||
'variation' => $menu_variation,
|
||||
'tags' => $tags,
|
||||
'option_groups' => $option_groups,
|
||||
];
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('getMenuTag')) {
|
||||
|
||||
function getMenuTag($id)
|
||||
{
|
||||
$menu_item_tag = new MenuItemTags();
|
||||
$tags = new Tags();
|
||||
$menu_item_tag_data = $menu_item_tag->where('menu_item_id', $id)
|
||||
->where('deleted_at', NULL)
|
||||
->findAll();
|
||||
|
||||
$data = [];
|
||||
foreach ($menu_item_tag_data as $menu_tag) {
|
||||
$tag = $tags->withDeleted()->find($menu_tag['tag_id']);
|
||||
$data[] = [
|
||||
'id' => $menu_tag['tag_id'],
|
||||
'title' => $tag['title'],
|
||||
'icon_url' => getImagePath('tags', $tag['icon_url'])
|
||||
];
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('getMenuOptionGroup')) {
|
||||
|
||||
function getMenuOptionGroup($id)
|
||||
{
|
||||
$menu_item_option_group = new MenuItemOptionsGroups();
|
||||
$option_groups = new OptionsGroups();
|
||||
$option_groups_data = $menu_item_option_group->where('menu_item_id', $id)
|
||||
->where('deleted_at', NULL)
|
||||
->orderBy('order_index', 'ASC')
|
||||
->findAll();
|
||||
|
||||
$data = [];
|
||||
foreach ($option_groups_data as $option_group) {
|
||||
$option_group_detail = $option_groups->withDeleted()->find($option_group['option_group_id']);
|
||||
$data[] = [
|
||||
'id' => $option_group['option_group_id'],
|
||||
'title' => $option_group_detail['title'],
|
||||
];
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('getAvailability')) {
|
||||
|
||||
function getAvailability($menu_item_id, $type)
|
||||
{
|
||||
$regular_item_availability = new RegularItemAvailability();
|
||||
$seasonal_item_availability = new SeasonalItemAvailability();
|
||||
|
||||
$data = [];
|
||||
|
||||
if ($type == 'seasonal') {
|
||||
$seasonal = $seasonal_item_availability->where('menu_item_id', $menu_item_id)->first();
|
||||
$data[] = $seasonal;
|
||||
} else {
|
||||
$regular = $regular_item_availability->where('menu_item_id', $menu_item_id)->findAll();
|
||||
$data[] = $regular;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,338 @@
|
||||
<?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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use App\Models\Outlet;
|
||||
|
||||
if (!function_exists('checkOperationDateAndTime')) {
|
||||
function checkOperationDateAndTime($outlet_id, $selected_date, $selected_time)
|
||||
{
|
||||
$outlet = new Outlet();
|
||||
$outlet_operating_hours = $outlet->getOperatingHoursWithDays($outlet_id);
|
||||
$operation_days = $outlet_operating_hours['operating_schedule']; //operation schedule and hours
|
||||
|
||||
$operation_date = $selected_date;
|
||||
$operation_time = $selected_time.':00';
|
||||
|
||||
$day_of_week = date('l', strtotime($operation_date));
|
||||
if(isset($operation_days[$day_of_week])){
|
||||
if(!$operation_days[$day_of_week]['is_operated']){
|
||||
return false;
|
||||
}
|
||||
|
||||
$operation_hours = $operation_days[$day_of_week]['operating_hours'];
|
||||
foreach($operation_hours as $operation_hour){
|
||||
if($operation_time >= $operation_hour['start_time'] && $operation_time <= $operation_hour['end_time']){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
if(!function_exists('revertPromoSetting')){
|
||||
function revertPromoSetting(array $promoSetting): array
|
||||
{
|
||||
$output = [
|
||||
'minimumSpend' => null,
|
||||
'minimumQuantity' => null,
|
||||
'everyQuantity' => null,
|
||||
'itemCategory1' => null,
|
||||
'itemCategoryID1' => [],
|
||||
'discountAmount' => null,
|
||||
'discountType' => null,
|
||||
'getNumber' => null,
|
||||
'itemCategory2' => null,
|
||||
'itemCategoryID2' => [],
|
||||
'promoType' => null,
|
||||
];
|
||||
|
||||
// --- MinimumSpend ---
|
||||
$min = $promoSetting['MinimumSpend'] ?? [];
|
||||
$type = $min['type'] ?? 'none';
|
||||
$amountType = $min['amount_type'] ?? '';
|
||||
$amount = $min['amount'] ?? 0;
|
||||
|
||||
if ($type !== 'none') {
|
||||
$output['itemCategory1'] = $type;
|
||||
$output['itemCategoryID1'] = $min['filter'] ?? [];
|
||||
|
||||
if ($amountType === 'amount') {
|
||||
$output['minimumSpend'] = $amount;
|
||||
} elseif ($amountType === 'quantity') {
|
||||
$output['minimumQuantity'] = $amount;
|
||||
} elseif ($amountType === 'every_quantity') {
|
||||
$output['everyQuantity'] = $amount;
|
||||
}
|
||||
}
|
||||
|
||||
// --- Promo ---
|
||||
$promo = $promoSetting['Promo'] ?? [];
|
||||
$promoType = $promo['promo_type'] ?? '';
|
||||
$output['promoType'] = $promoType;
|
||||
|
||||
$output['itemCategory2'] = $promo['filter_type'] ?? null;
|
||||
|
||||
if ($promoType === 'free_item') {
|
||||
$output['itemCategoryID2'] = $promo['free_item'] ?? [];
|
||||
$output['getNumber'] = $promo['amount'] ?? null;
|
||||
|
||||
} else {
|
||||
$output['itemCategoryID2'] = $promo['filter'] ?? [];
|
||||
$output['discountType'] = $promo['discount_type'] ?? null;
|
||||
|
||||
// Determine amount source
|
||||
if ($promo['discount_type'] === 'amount' || $promo['discount_type'] === 'percentage') {
|
||||
$output['discountAmount'] = $promo['amount'] ?? null;
|
||||
} else {
|
||||
$output['getNumber'] = $promo['amount'] ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
|
||||
if(!function_exists('calculatePromoPrice')){
|
||||
function calculatePromoPrice($price, $amount, $type){
|
||||
if ($price < 0 || $amount < 0) {
|
||||
return 0;
|
||||
}
|
||||
if($type == 'amount'){
|
||||
return $amount;
|
||||
} else if ($type == 'percentage'){
|
||||
return $price * $amount / 100;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
use App\Models\VoucherSchedule;
|
||||
use App\Models\VoucherSettings;
|
||||
|
||||
if (!function_exists('getVoucherSetting')) {
|
||||
|
||||
function getVoucherSetting($id)
|
||||
{
|
||||
$voucher_settings = new VoucherSettings();
|
||||
|
||||
$voucher = $voucher_settings
|
||||
->select('id, voucher_name')
|
||||
->where('id', $id)
|
||||
->where('deleted_at', null)
|
||||
->first();
|
||||
|
||||
if (!$voucher) {
|
||||
return []; // Or return null if preferred
|
||||
}
|
||||
|
||||
return [[
|
||||
'id' => $voucher['id'],
|
||||
'title' => $voucher['voucher_name']
|
||||
]];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user