initial project

This commit is contained in:
2025-11-06 13:41:06 +08:00
commit 1b08727cb2
209 changed files with 31602 additions and 0 deletions
+689
View File
@@ -0,0 +1,689 @@
<?
namespace App\Services;
use App\Models\CartItems;
use App\Models\MenuItemVariations;
use App\Models\DeliverySettingModel;
use App\Models\CartItemOptions;
use App\Models\Carts;
use App\Models\Customer;
use App\Models\CustomerVoucherList;
use App\Models\MenuItems;
use App\Models\MenuImages;
use App\Models\OutletMenus;
use App\Models\OutletTax;
use App\Models\StoreDiscount;
use App\Models\SettingTax;
use App\Models\Outlet;
use App\Services\PromoService;
use App\Models\PromoCode;
use App\Libraries\Lalamove;
use App\Models\PwpModel;
use Exception;
use CodeIgniter\Database\Config;
helper('general');
class CalculateService
{
private $cart_items;
private $variations;
private $options;
private $carts;
private $menu_items;
private $menu_images;
private $outlet_menus;
private $outlet_tax;
private $setting_tax;
private $cart_item_options;
private $customer_voucher_list;
private $promo_service;
private $promo_codes;
private $pwp;
private $outlet;
private $store_discount;
private $customer;
private $setting_delivery_fee;
public function __construct(PromoService $promoService)
{
$this->cart_items = new CartItems();
$this->variations = new MenuItemVariations();
$this->options = new CartItemOptions();
$this->carts = new Carts();
$this->menu_items = new MenuItems();
$this->menu_images = new MenuImages();
$this->outlet_menus = new OutletMenus();
$this->outlet_tax = new OutletTax();
$this->setting_tax = new SettingTax();
$this->cart_item_options = new CartItemOptions();
$this->promo_service = $promoService;
$this->promo_codes = new PromoCode();
$this->customer_voucher_list = new CustomerVoucherList();
$this->outlet = new Outlet();
$this->store_discount = new StoreDiscount();
$this->customer = new Customer();
$this->pwp = new PwpModel();
$this->setting_delivery_fee = new DeliverySettingModel();
helper('order_helper');
}
private function getOriginalItemPrice($menu_item_id)
{
$menu_item = $this->menu_items->find($menu_item_id);
return $menu_item ? $menu_item['price'] : 0;
}
private function checkItemPwpDiscount($cart_id)
{
$cart = $this->carts->find($cart_id);
$cart_items = $this->cart_items->where('cart_id', $cart_id)->findAll();
// print_r($cart_items);exit;
$pwp_promos = $this->pwp->where('deleted_at', null)->orderBy('order_index', 'ASC')->findAll();
$total_qualify = 0;
foreach ($pwp_promos as $promo) {
if($promo['mode'] == 'selected_item'){
$requiredIds = explode(',', $promo['pwp_item_id']);
foreach($cart_items as $item){
if(in_array($item['menu_item_id'], $requiredIds)){
// echo(123);exit;
if($promo['amount_type'] == 'amount'){
$total_qualify+=($item['quantity'] * $item['unit_price']);
}else{
$total_qualify+=$item['quantity'];
}
}
}
}else{
if($promo['amount_type'] == 'amount'){
$total_qualify+= $cart['grand_total'];
}else{
$total_qualify+= $cart['item_count'];
}
}
// echo($total_qualify);exit;
if($total_qualify >= $promo['amount']){
return [
'has_discount' => true,
'pwp_item' => explode(',', $promo['selected_item']),
];
}
}
return ['has_discount' => false];
}
public function calculateCartTotals($cart_id, $outlet_id, $selected_date = null, $selected_time = null, $latitude = null, $longitude = null, $order_type = null, $address = null, $promo_or_voucher = null)
{
$cart = $this->carts->find($cart_id);
if ($selected_date == null && $selected_time == null) {
$selected_date = $cart['selected_date'];
$selected_time = $cart['selected_time'];
}
if ($order_type == null) {
$order_type = $cart['order_type'];
}
if ($address == null) {
$address = $cart['address'];
}
if ($latitude == null && $longitude == null) {
$latitude = $cart['latitude'];
$longitude = $cart['longitude'];
}
$cart_items = $this->cart_items->where('cart_id', $cart_id)->findAll();
$customer_id = $cart['customer_id'];
$customer = $this->customer->where('id', $customer_id)->first();
$customer_tier = $customer['customer_tier_id'] ?? 0;
$subtotal = $subtotal_without_options = 0;
$total_discount = $promo_discount_amount = 0;
$total_tax = 0;
$invalid_items = [];
$promo_code_id = $cart['promo_code_id'];
$free_item_list = [];
$promo_code = '';
$voucher_code = '';
$packaging_charge = 0;
$array_discount = [];
$store_discount = $this->store_discount->where("FIND_IN_SET($outlet_id, outlet_list)")->where("FIND_IN_SET($customer_tier, tier_id_list)")->findAll();
// print_r($cart_items);exit;
foreach ($cart_items as $item) {
$is_valid = true;
if ($outlet_id) {
$menu_available = $this->outlet_menus->where([
'menu_item_id' => $item['menu_item_id'],
'outlet_id' => $outlet_id
])->first();
if (!$menu_available) {
$is_valid = false;
$invalid_items[] = $item['id'];
$this->options->where('cart_item_id', $item['id'])->delete();
continue;
}
}
$unit_price = $item['unit_price'];
$title = $item['title'];
$variation_price = 0;
$packaging_price = 0;
if (!empty($item['variation_id']) && $item['variation_id'] > 0) {
$menu_item = $this->menu_items->find($item['menu_item_id']);
$variation = $this->variations->find($item['variation_id']);
if ($variation) {
$unit_price = $variation['price'];
$packaging_price = $menu_item['packaging_price'] ?? 0;
$packaging_charge = $packaging_price * $item['quantity'];
}
} else {
$menu_item = $this->menu_items->find($item['menu_item_id']);
if ($menu_item) {
$unit_price = $item['is_pwp'] == true ? $menu_item['pwp_price'] : $menu_item['price'];
$title = $menu_item['title'];
$packaging_price = $menu_item['packaging_price'] ?? 0;
$packaging_charge = $packaging_price * $item['quantity'];
}
}
if(is_array($store_discount)){
foreach($store_discount as $discount){
$menu_item_list = explode(',', $discount['menu_item_list']);
if(in_array($item['menu_item_id'], $menu_item_list)){
if($discount['discount_type'] == 'percentage'){
$total_discount += ($unit_price * $item['quantity']) * ($discount['discount_value'] / 100);
if(!array_key_exists($discount['id'], $array_discount)){
$array_discount[$discount['id']] = [
'discount_name' => $discount['discount_name'],
'discount_type' => $discount['discount_type'],
'discount_value' => $discount['discount_value'],
'discount_amount' => number_format_no_round(($unit_price * $item['quantity']) * ($discount['discount_value'] / 100))
];
}else{
$array_discount[$discount['id']]['discount_amount'] += number_format_no_round(($unit_price * $item['quantity']) * ($discount['discount_value'] / 100));
}
}else{
if(!array_key_exists($discount['id'], $array_discount)){
$total_discount = $discount['discount_value'];
$array_discount[$discount['id']] = [
'discount_name' => $discount['discount_name'],
'discount_type' => $discount['discount_type'],
'discount_value' => $discount['discount_value'],
'discount_amount' => number_format_no_round(($unit_price * $item['quantity']) * ($discount['discount_value'] / 100))
];
}
}
}
}
}
$item_subtotal = ($unit_price) * $item['quantity'];
$item_subtotal_without_options = $item_subtotal;
$options = $this->options->where('cart_item_id', $item['id'])->findAll();
$options_total = array_sum(array_column($options, 'price_adjustment'));
$item_subtotal += $options_total;
if (($item['unit_price'] != $unit_price || $item['title'] != $title) && (($item['is_free_item'] == false || $item['is_free_item'] == '1') && $item['is_pwp'] == false)) {
$this->cart_items->update($item['id'], [
'unit_price' => $unit_price,
'title' => $title,
'line_subtotal' => $item_subtotal
]);
}
if ($item['is_free_item'] == true || $item['is_free_item'] == '1') {
$item_subtotal = 0;
}
if($item['is_pwp'] == true && ($item['unit_price'] != $unit_price || $item['title'] != $title)){
// $item_subtotal = $item['pwp_price'] * $item['quantity'];
$this->cart_items->update($item['id'], [
'unit_price' => $unit_price,
'title' => $item['title'],
'line_subtotal' => $item_subtotal
]);
}
if ($is_valid && $item['is_free_item'] != true && $item['is_free_item'] != '1') {
$subtotal += $item_subtotal;
$subtotal_without_options += $item_subtotal_without_options;
}
}
if($subtotal < $total_discount){
$total_discount = $subtotal;
}
if (!empty($invalid_items)) {
$this->cart_items->whereIn('id', $invalid_items)->delete();
$cart_items = $this->cart_items->where('cart_id', $cart_id)->findAll();
}
// Get cart items with options (after potential deletions)
$final_cart_items = $this->cart_items
->where('cart_id', $cart_id)
->where('deleted_at', null)
->findAll();
foreach ($final_cart_items as &$item) {
$item['variation'] = $this->variations->find($item['variation_id']);
$item['options'] = $this->options
->where('cart_item_id', $item['id'])
->where('deleted_at', null)
->findAll();
if ($item['variation_id'] > 0) {
$item['image'] = $item['variation']['images'];
} else {
$image = $this->menu_images->where('menu_item_id', $item['menu_item_id'])->orderBy('order_index', 'ASC')->first();
if ($image) {
$item['image'] = 'https://icom.ipsgroup.com.my/backend/uploads/menu_images/'.$image['image_url'];
} else {
$item['image'] = null;
}
}
}
//check store discount
// $store_discount = $this->store_discount->where("FIND_IN_SET($outlet_id, outlet_list)")->where("FIND_IN_SET($order_type, order_type)")->findAll();
// print_r($final_cart_items);exit;
$quotation_id = null;
$delivery_fee = 0;
$delivery_service = null;
if ($order_type == 'delivery' && $latitude && $longitude && $address) {
$outlet_data = $this->outlet->where('id', $outlet_id)->first();
$delivery_options = explode(',', $outlet_data['delivery_options'] ?? '');
// Lalamove
if (in_array('Lalamove', $delivery_options)) {
try {
$lalamove = new Lalamove();
$delivery_response = $lalamove->requestQuotation(
$selected_date,
$selected_time,
$subtotal,
$outlet_id,
$latitude,
$longitude,
$address
);
if (isset($delivery_response['data'])) {
$quotation_id = $delivery_response['data']['quotationId'];
$delivery_fee = $delivery_response['data']['priceBreakdown']['total'];
$delivery_service = 'Lalamove';
}
} catch (Exception $e) {
log_message('error', 'Lalamove quotation failed: ' . $e->getMessage());
}
}
// Grab
if (!$quotation_id && in_array('Grab Express', $delivery_options)) {
try {
$grab = new \App\Libraries\Grab();
$delivery_response = $grab->requestQuotation(
$selected_date,
$selected_time,
$subtotal,
$outlet_id,
$latitude,
$longitude,
$address
);
if (!empty($delivery_response['quotes'])) {
$quotation_id = time();
$delivery_fee = $delivery_response['quotes'][0]['amount'] ?? 0;
$delivery_service = 'Grab';
}
} catch (Exception $e) {
log_message('error', 'Grab quotation failed: ' . $e->getMessage());
}
}
// Manual fallback
if (!$quotation_id) {
$distance = $this->calculateDistance($outlet_id, $latitude, $longitude);
$delivery_fee = $this->calculateDeliveryFee($distance);
}
}
if ($cart['promo_code_id'] > 0 || $cart['customer_voucher_list_id'] > 0) {
$promo_setting_id = 0;
//check promo
if ($cart['promo_code_id'] > 0) {
$promo_data = $this->promo_codes->find($cart['promo_code_id']);
$promo_code = $promo_data['code'];
$promo_setting_id = $promo_data['promo_setting_id'];
} else if ($cart['customer_voucher_list_id'] > 0) {
$voucher_data = $this->customer_voucher_list->where('id', $cart['customer_voucher_list_id'])->first();
$voucher_code = $voucher_data['voucher_code'];
$promo_setting_id = $voucher_data['promo_setting_id'];
}
// print_r($final_cart_items);exit;
$promo = $this->promo_service->checkPromoLogic($promo_setting_id, $final_cart_items, number_format($subtotal_without_options, 2), $cart['customer_id'], $outlet_id, $order_type, $delivery_fee);
if (isset($promo['status']) && $promo['status'] == 400) {
//remove from cart
$result = $this->resetVoucher($cart_id);
// print_r($promo);
// exit;
return $promo;
}
if (isset($promo['status']) && $promo['status'] == 200) {
// print_r($promo);exit;
if ($promo['delivery_fee'] > 0) {
$promo_discount_amount += $promo['delivery_fee'];
}
if ($promo['promo_discount_total'] > 0) {
$promo_discount_amount += $promo['promo_discount_total'];
}
$free_item_list = $promo['free_item_list'];
}
}
$tax_detail = [];
$grand_total = $subtotal + $packaging_charge - $total_discount - $promo_discount_amount;
if($grand_total < 0){
$grand_total = 0;
}
$tax_array = $this->setting_tax->where("FIND_IN_SET($outlet_id, outlet_id)")->where("FIND_IN_SET('" . $order_type . "', order_type)")->findAll();
foreach ($tax_array as $tax) {
$add_tax = $grand_total * ($tax['tax_rate'] / 100);
$total_tax += $add_tax;
$tax_detail[] = [
'tax_type' => $tax['tax_type'],
'tax_rate' => $tax['tax_rate'],
'tax_amount' => number_format_no_round($add_tax)
];
}
//add tax
// echo $total_tax;exit;
$grand_total += $total_tax;
$grand_total = number_format_no_round($grand_total);
// echo($grand_total);exit;
$rounding_amount = calculateRoundingAmount($grand_total);
// echo $rounding_amount;exit;
$grand_total = $grand_total + $rounding_amount;
// echo $grand_total;exit;
//calculate rounding amount
//call delivery service api if delivery
// print_r($final_cart_items);exit;
// Update cart totals in database
$this->carts->update($cart_id, [
'item_count' => count($cart_items),
'subtotal_amount' => number_format($subtotal, 2),
'discount_amount' => number_format($total_discount, 2),
'tax_amount' => number_format($total_tax, 2),
'grand_total' => number_format($grand_total, 2),
'rounding_amount' => number_format($rounding_amount, 2),
'promo_discount_amount' => $promo_or_voucher == 'promo' ? number_format($promo_discount_amount, 2) : 0.00,
'voucher_discount_amount' => $promo_or_voucher == 'voucher' ? number_format($promo_discount_amount, 2) : 0.00,
'delivery_fee' => number_format($delivery_fee, 2),
'selected_date' => $selected_date,
'selected_time' => $selected_time,
'latitude' => $latitude,
'longitude' => $longitude,
'order_type' => $order_type,
'address' => $address,
'lalamove_quot_id' => $delivery_service === 'Lalamove' ? $quotation_id : null,
'grab_quot_id' => $delivery_service === 'Grab' ? $quotation_id : null
]);
// print_r($final_cart_items);exit;
//check pwp
$pwp_menu = [];
$pwp_discount = $this->checkItemPwpDiscount($cart_id);
// print_r($final_cart_items);exit;
if($pwp_discount['has_discount']){
$pwp_items = $pwp_discount['pwp_item'];
foreach($pwp_items as $pwp_item){
$pwp_menu_item = $this->menu_items->where('id', $pwp_item)->first();
if(isset($pwp_menu_item['pwp_price'])){
if($pwp_menu_item['pwp_price'] > 0){
$pwp_menu[] = $pwp_menu_item;
}
}
}
}
// print_r($pwp_menu);exit;
// Return the complete structure
return [
'status' => 200,
'message' => 'Cart retrieved successfully.',
'data' => [
'id' => $cart['id'],
'customer_id' => $cart['customer_id'],
'outlet_id' => $cart['outlet_id'],
'status' => $cart['status'],
'order_summary' => [
'item_count' => count($final_cart_items),
'subtotal_amount' => number_format($subtotal, 2),
'discount_amount' => number_format($total_discount, 2),
'tax_amount' => number_format($total_tax, 2),
'delivery_fee' => number_format($delivery_fee, 2),
'packaging_charge' => number_format($packaging_charge, 2),
// 'packaging_charge' => "123",
'grand_total' => number_format($grand_total, 2),
'store_discount' => $array_discount,
'store_discount_amount' => number_format($total_discount, 2),
'grand_total_without_rounding' => number_format($grand_total - $rounding_amount, 2),
'rounding_amount' => number_format($rounding_amount, 2),
'promo_code_id' => $promo_code_id ?? 0,
'promo_discount_amount' => $promo_or_voucher == 'promo' ? number_format($promo_discount_amount, 2) : 0.00,
'promo_code' => $promo_code,
'customer_voucher_list_id' => $cart['customer_voucher_list_id'],
'voucher_discount_amount' => $promo_or_voucher == 'voucher' ? number_format($promo_discount_amount, 2) : 0.00,
'voucher_code' => $voucher_code,
'selected_date' => $selected_date,
'selected_time' => $selected_time,
'latitude' => $latitude,
'longitude' => $longitude,
'order_type' => $order_type,
'address' => $address
],
'tax_detail' => $tax_detail,
'invalid_items' => $invalid_items,
'items' => $final_cart_items,
'free_item_list' => $free_item_list,
'pwp_menu' => $pwp_menu
]
];
}
public function resetVoucher($cart_id)
{
// Reset promo and voucher fields
$this->carts->update($cart_id, [
'promo_code_id' => 0,
'promo_discount_amount' => 0,
'customer_voucher_list_id' => 0,
'voucher_discount_amount' => 0
]);
// Get free items from cart
$freeItems = $this->cart_items
->select('id')
->where('cart_id', $cart_id)
->where('is_free_item', 1)
->findAll();
if (!empty($freeItems)) {
// Collect all item IDs
$itemIds = array_column($freeItems, 'id');
// Delete all related item options in one query
$this->cart_item_options->whereIn('cart_item_id', $itemIds)->delete();
// Delete all free items in one query
$this->cart_items->whereIn('id', $itemIds)->delete();
}
}
/**
* Calculate distance from outlet to customer using Google Distance Matrix API
* @param int $outlet_id
* @param float $latitude
* @param float $longitude
* @return float Distance in kilometers
*/
public function calculateDistance($outlet_id, $latitude, $longitude)
{
try {
// Validate input parameters
if (empty($outlet_id) || !is_numeric($outlet_id)) {
log_message('error', 'CalculateService: Invalid outlet ID provided: ' . $outlet_id);
return 0;
}
if (!is_numeric($latitude) || !is_numeric($longitude)) {
log_message('error', 'CalculateService: Invalid coordinates provided - lat: ' . $latitude . ', lng: ' . $longitude);
return 0;
}
// Validate coordinate ranges
if ($latitude < -90 || $latitude > 90 || $longitude < -180 || $longitude > 180) {
log_message('error', 'CalculateService: Coordinates out of valid range - lat: ' . $latitude . ', lng: ' . $longitude);
return 0;
}
// Get outlet coordinates
$outlet = $this->outlet->find($outlet_id);
if (!$outlet || !isset($outlet['latitude']) || !isset($outlet['longitude'])) {
log_message('error', 'CalculateService: Outlet not found or missing coordinates for outlet ID: ' . $outlet_id);
return 0;
}
$outlet_lat = $outlet['latitude'];
$outlet_lng = $outlet['longitude'];
// Check if we have valid outlet coordinates
if (!is_numeric($outlet_lat) || !is_numeric($outlet_lng)) {
log_message('error', 'CalculateService: Invalid outlet coordinates - lat: ' . $outlet_lat . ', lng: ' . $outlet_lng);
return 0;
}
// Check if Google API key is configured
if (empty(GOOGLE_DISTANCE_MATRIX_API_KEY) || GOOGLE_DISTANCE_MATRIX_API_KEY === 'YOUR_GOOGLE_API_KEY_HERE') {
log_message('error', 'CalculateService: Google Distance Matrix API key not configured');
return 0;
}
// Google Distance Matrix API endpoint
$api_url = 'https://maps.googleapis.com/maps/api/distancematrix/json';
// Build the request URL
$params = [
'origins' => $outlet_lat . ',' . $outlet_lng,
'destinations' => $latitude . ',' . $longitude,
'mode' => 'driving',
'units' => 'metric',
'key' => GOOGLE_DISTANCE_MATRIX_API_KEY
];
$url = $api_url . '?' . http_build_query($params);
log_message('info', 'CalculateService: Requesting distance from Google API - Outlet: ' . $outlet_id . ', Customer: ' . $latitude . ',' . $longitude);
// Make the API request using the helper function
$response = send_api_request('GET', $url, [], null, true);
if ($response === false) {
log_message('error', 'CalculateService: Failed to get response from Google Distance Matrix API');
return 0;
}
$data = $response;
// Check for API errors
if ($data['status'] !== 'OK') {
$error_message = $data['error_message'] ?? $data['status'] ?? 'Unknown error';
log_message('error', 'CalculateService: Google Distance Matrix API error: ' . $error_message);
// Log additional error details if available
if (isset($data['error_message'])) {
log_message('error', 'CalculateService: Google API Error Message: ' . $data['error_message']);
}
if (isset($data['status'])) {
log_message('error', 'CalculateService: Google API Status: ' . $data['status']);
}
return 0;
}
// Extract distance from response
if (isset($data['rows'][0]['elements'][0]['distance']['value'])) {
$distance_meters = $data['rows'][0]['elements'][0]['distance']['value'];
$distance_km = $distance_meters / 1000;
log_message('info', 'CalculateService: Distance calculated successfully - Outlet: ' . $outlet_id . ', Distance: ' . $distance_km . ' km');
return round($distance_km, 2);
} else {
// Check if the route is not found
if (isset($data['rows'][0]['elements'][0]['status']) && $data['rows'][0]['elements'][0]['status'] === 'NOT_FOUND') {
log_message('warning', 'CalculateService: Route not found between outlet and customer location');
} else {
log_message('warning', 'CalculateService: No distance data in Google API response');
}
return 0;
}
} catch (Exception $e) {
log_message('error', 'CalculateService: Exception in calculateDistance: ' . $e->getMessage());
log_message('error', 'CalculateService: Stack trace: ' . $e->getTraceAsString());
return 0;
}
}
/**
* Calculate delivery fee based on distance
* @param float $distance Distance in kilometers
* @return float Delivery fee in RM
*/
public function calculateDeliveryFee($distance)
{
// Validate input
if (!is_numeric($distance) || $distance < 0) {
log_message('warning', 'CalculateService: Invalid distance provided for fee calculation: ' . $distance);
return 0;
}
if ($distance == 0) {
return 0;
}
// Delivery fee structure based on distance
$fee = 0;
//get setting delivery fee
$setting_delivery_fee = $this->setting_delivery_fee->findAll();
foreach($setting_delivery_fee as $setting){
if($distance >= $setting['start_km'] && $distance <= $setting['end_km']){
$fee = $setting['price_per_km'];
}
}
// Ensure fee is a valid number and round to 2 decimal places
$fee = round($fee, 2);
log_message('info', 'CalculateService: Delivery fee calculated - Distance: ' . $distance . ' km, Fee: RM ' . $fee);
return $fee;
}
}
+426
View File
@@ -0,0 +1,426 @@
<?
namespace App\Services;
use App\Models\CartItems;
use App\Models\MenuItemVariations;
use App\Models\CartItemOptions;
use App\Models\Carts;
use App\Models\MenuItems;
use App\Models\OutletMenus;
use App\Models\OutletTax;
use App\Models\SettingTax;
use CodeIgniter\Database\Config;
use App\Models\MenuItemOptionsGroups;
use App\Models\OptionsGroups;
use App\Models\VariationOptionsGroups;
use App\Services\PromoService;
use App\Models\Options;
class CartService
{
private $db;
private $cart_items;
private $variations;
private $options;
private $carts;
private $menu_items;
private $outlet_menus;
private $outlet_tax;
private $setting_tax;
private $cart_item_options;
private $menu_item_options_groups;
private $option_groups;
private $menu_item_variations;
private $variation_options_groups;
private $promo_service;
public function __construct()
{
$this->cart_items = new CartItems();
$this->variations = new MenuItemVariations();
$this->options = new Options();
$this->carts = new Carts();
$this->menu_items = new MenuItems();
$this->outlet_menus = new OutletMenus();
$this->outlet_tax = new OutletTax();
$this->setting_tax = new SettingTax();
$this->cart_item_options = new CartItemOptions();
$this->menu_item_options_groups = new MenuItemOptionsGroups();
$this->option_groups = new OptionsGroups();
$this->menu_item_variations = new MenuItemVariations();
$this->variation_options_groups = new VariationOptionsGroups();
$this->db = Config::connect();
}
public function addCartItem($customer_id, $outlet_id, $existing_cart, $menu_item_id, $variation_id, $option_group, $quantity, $type = null) {
// If no cart, create one
if (!$existing_cart) {
$cartData = [
'customer_id' => $customer_id,
'outlet_id' => $outlet_id,
'status' => 'active',
'item_count' => 0,
'subtotal_amount' => 0,
'discount_amount' => 0,
'tax_amount' => 0,
'grand_total' => 0,
'promo_code_id' => 0,
'promo_discount_amount' => 0,
'customer_voucher_list_id' => 0,
'voucher_discount_amount' => 0,
'created_at' => date('Y-m-d H:i:s'),
];
$cartId = $this->carts->insert($cartData);
if (!$cartId) {
return ['status' => 400, 'message' => "Failed to create cart."];
}
$existing_cart = $this->carts->find($cartId);
}
$cart = $existing_cart;
$this->db->transStart();
try {
//check outlet menu
$menuAvailable = $this->outlet_menus->where([
'menu_item_id' => $menu_item_id,
'outlet_id' => $outlet_id
])->first();
if (!$menuAvailable) {
return ['status' => 400, 'message' => 'This menu is not available for this outlet!'];
}
$menu_variation = $this->menu_item_variations->where('menu_item_id', $menu_item_id)->findAll();
if(($variation_id == 0 || $variation_id == null) && !empty($menu_variation)){ //make variation required
return ['status' => 400, 'message' => 'Please select a variation!'];
}
$required_groups = $this->getRequiredOptionGroups($menu_item_id, $variation_id);
// Validate that required options are provided
if (!empty($required_groups)) {
if (empty($option_group)) {
return ['status' => 400, 'message' => 'Required options are missing'];
}
$provided_group_ids = array_map(function ($opt) {
if (!is_object($opt)) {
$opt = (object) $opt;
}
return $opt->group_id;
}, $option_group);
foreach ($required_groups as $group) {
if (!in_array($group['id'], $provided_group_ids)) {
return ['status' => 400, 'message' => 'Required option group ' . $group['title'] . ' is missing'];
}
}
}
//Check if the new item is same with old item then update quantity
$options_match = false;
$existing_cart_item = $this->cart_items
->where('cart_id', $cart['id'])
->where('menu_item_id', $menu_item_id)
->where('variation_id', $variation_id)
->first();
if($type != 'free_item'){
if ($existing_cart_item) {
if(($type == 'pwp' && $existing_cart_item['is_pwp'] == true) || $type != 'pwp'){
// Check if options match
$options_match = true;
if (!empty($option_group)) {
// Get existing options for this cart item
$existing_options = $this->cart_item_options
->where('cart_item_id', $existing_cart_item['id'])
->findAll();
// Convert existing options to comparable format
$existing_option_ids = [];
foreach ($existing_options as $opt) {
if (!isset($existing_option_ids[$opt['option_group_id']])) {
$existing_option_ids[$opt['option_group_id']] = [];
}
$existing_option_ids[$opt['option_group_id']][] = $opt['option_id'];
}
// Convert new options to comparable format
$new_option_ids = [];
foreach ($option_group as $opt) {
if (!is_object($opt)) {
$opt = (object) $opt;
}
$new_option_ids[$opt->group_id] = $opt->option_ids;
}
// Compare options
if ($existing_option_ids != $new_option_ids) {
$options_match = false;
}
} else {
// If no options in request but existing item has options
$has_existing_options = $this->cart_item_options
->where('cart_item_id', $existing_cart_item['id'])
->countAllResults() > 0;
if ($has_existing_options) {
$options_match = false;
}
}
if ($options_match) {
// Update quantity of existing item
$new_quantity = $existing_cart_item['quantity'] + $quantity;
$new_line_subtotal = $existing_cart_item['unit_price'] * $new_quantity;
$this->cart_items->update($existing_cart_item['id'], [
'quantity' => $new_quantity,
'line_subtotal' => $new_line_subtotal
]);
}
}
}
}
// echo($variation_id);exit;
if (!$options_match) {
if ($variation_id == 0) {
$menu_item = $this->menu_items->where('status', 'active')->find($menu_item_id);
if (empty($menu_item)) {
return ['status' => 400, 'message' => "Menu Item not found!"];
}
$basePrice = $menu_item['price'];
$order_index = $this->cart_items->withDeleted()->where('cart_id', $cart['id'])->countAllResults();
// Insert cart item
$line_subtotal = $basePrice * $quantity;
$add_cart_detail = [
'cart_id' => $cart['id'],
'menu_item_id' => $menu_item_id,
'variation_id' => 0,
'title' => $menu_item['title'],
'unit_price' => $basePrice,
'quantity' => $quantity,
'line_subtotal' => $line_subtotal,
'order_index' => $order_index,
];
if($type == 'free_item'){
$add_cart_detail = [
'cart_id' => $cart['id'],
'menu_item_id' => $menu_item_id,
'variation_id' => 0,
'title' => $menu_item['title'],
'unit_price' => 0,
'quantity' => $quantity,
'line_subtotal' => 0,
'order_index' => $order_index,
'is_free_item' => 1
];
}
if($type == 'pwp'){
$add_cart_detail = [
'cart_id' => $cart['id'],
'menu_item_id' => $menu_item_id,
'variation_id' => 0,
'title' => $menu_item['title'],
'unit_price' => $menu_item['pwp_price'],
'quantity' => $quantity,
'line_subtotal' => $menu_item['pwp_price'] * $quantity,
'order_index' => $order_index,
'is_pwp' => true
];
}
// print_r($add_cart_detail);exit;
$cart_item_id = $this->cart_items->insert($add_cart_detail);
$existingGroupIds = getColumnValues($this->menu_item_options_groups, 'menu_item_id', $menu_item_id, 'option_group_id');
if (!empty($option_group)) {
foreach ($option_group as $opt) {
if (!is_object($opt)) {
$opt = (object) $opt;
}
$option_group_id = $opt->group_id;
$option_ids = $opt->option_ids;
if (in_array($option_group_id, $existingGroupIds)) {
$option_groups = $this->option_groups->find($option_group_id);
$option_num = count($option_ids);
if (!empty($option_groups)) {
if ($option_num >= $option_groups['min_quantity'] && $option_num <= $option_groups['max_quantity']) {
foreach ($option_ids as $key => $value) {
$option_selected = $this->options->where('option_group_id', $option_group_id)->find($value);
if (empty($option_selected)) {
return ['status' => 400, 'message' => 'No option selected !'];
}
$option_data = [
'cart_item_id' => $cart_item_id,
'option_id' => $value,
'option_group_id' => $option_group_id,
'option_title' => $option_selected['title'],
'price_adjustment' => $option_selected['price_adjustment']
];
$this->cart_item_options->insert($option_data);
}
} else {
return ['status' => 400, 'message' => 'Please select correct quantity for option!'];
}
}
}
}
}
} else {
$menu_item = $this->menu_items->where('status', 'active')->find($menu_item_id);
if (empty($menu_item)) {
return ['status' => 400, 'message' => "Menu Item not found!"];
}
$menu_variation = $this->menu_item_variations->withDeleted()->find($variation_id);
if (empty($menu_variation)) {
return ['status' => 400, 'message' => "Menu Variation not found!"];
}
$item_price = $menu_variation['price'];
$order_index = $this->cart_items->withDeleted()->where('cart_id', $cart['id'])->countAllResults();
$line_subtotal = $item_price * $quantity;
$add_cart_detail = [
'cart_id' => $cart['id'],
'menu_item_id' => $menu_item_id,
'variation_id' => $variation_id,
'title' => $menu_item['title'],
'unit_price' => $item_price,
'quantity' => $quantity,
'line_subtotal' => $line_subtotal,
'order_index' => $order_index,
];
if($type == 'free_item'){
$add_cart_detail = [
'cart_id' => $cart['id'],
'menu_item_id' => $menu_item_id,
'variation_id' => $variation_id,
'title' => $menu_item['title'],
'unit_price' => 0,
'quantity' => $quantity,
'line_subtotal' => 0,
'order_index' => $order_index,
'is_free_item' => 1
];
}
if($type == 'pwp'){
$add_cart_detail = [
'cart_id' => $cart['id'],
'menu_item_id' => $menu_item_id,
'variation_id' => $variation_id,
'title' => $menu_item['title'],
'unit_price' => $menu_item['pwp_price'],
'quantity' => $quantity,
'line_subtotal' => $menu_item['pwp_price'] * $quantity,
'order_index' => $order_index,
'is_pwp' => true
];
}
$cart_item_id = $this->cart_items->insert($add_cart_detail);
if ($menu_variation) {
$existing_variation_option_group = getColumnValues($this->variation_options_groups, 'variation_id', $variation_id, 'option_group_id');
if (!empty($option_group)) {
foreach ($option_group as $opt) {
if (!is_object($opt)) {
$opt = (object) $opt;
}
$option_group_id = $opt->group_id;
$option_ids = $opt->option_ids;
if (in_array($option_group_id, $existing_variation_option_group)) {
$option_groups = $this->option_groups->find($option_group_id);
$option_num = count($option_ids);
if (!empty($option_groups)) {
if ($option_num >= $option_groups['min_quantity'] && $option_num <= $option_groups['max_quantity']) {
foreach ($option_ids as $key => $value) {
$option_selected = $this->options->where('option_group_id', $option_group_id)->where('id', $value)->first();
if (empty($option_selected)) {
return ['status' => 400, 'message' => 'No option selected !'];
}
$option_data = [
'cart_item_id' => $cart_item_id,
'option_id' => $value,
'option_group_id' => $option_group_id,
'option_title' => $option_selected['title'],
'price_adjustment' => $option_selected['price_adjustment']
];
$this->cart_item_options->insert($option_data);
}
} else {
return ['status' => 400, 'message' => 'Please select correct quantity for option!'];
}
}
}
}
}
} else {
return ['status' => 400, 'message' => 'No variation found!'];
}
}
}
// $total = $this->calculateCartTotals($cart['id'], $cart['outlet_id']);
$this->db->transComplete();
return [
'status' => 200,
'message' => 'Item added to cart successfully.',
'data' => ['cart_id' => $cart['id']]
];
} catch (\Exception $e) {
$this->db->transRollback();
return ['status' => 400, 'message' => "Something went wrong: " . $e];
}
}
public function getRequiredOptionGroups($menu_item_id, $variation_id)
{
if ($variation_id == 0) {
$existingGroupIds = getColumnValues($this->menu_item_options_groups, 'menu_item_id', $menu_item_id, 'option_group_id');
} else {
$existingGroupIds = getColumnValues($this->variation_options_groups, 'variation_id', $variation_id, 'option_group_id');
}
if(!empty($existingGroupIds)){
$data = $this->option_groups
->whereIn('id', $existingGroupIds)
->where('is_required', 1)
->findAll();
} else {
$data = [];
}
return $data;
}
}
+452
View File
@@ -0,0 +1,452 @@
<?php
namespace App\Services;
use App\Models\PromoSetting;
use App\Models\PromoCode;
use App\Models\PromoRedemptionRecord;
use App\Models\MenuItems;
use App\Models\MenuItemCategories;
use App\Models\Carts;
helper('promo');
class PromoService
{
private $promoSetting;
private $promoCode;
private $promoRedemptionRecord;
private $menuItem;
private $menuItemCategories;
private $carts;
private $cart_service;
public function __construct()
{
$this->promoSetting = new PromoSetting();
$this->promoCode = new PromoCode();
$this->promoRedemptionRecord = new PromoRedemptionRecord();
$this->menuItem = new MenuItems();
$this->carts = new Carts();
$this->menuItemCategories = new MenuItemCategories();
$this->cart_service = service('cartService');
}
public function checkPromoAvailability($promo_code_id, $order_type, $customer_id){
$promo_code = $this->promoCode->where('deleted_at', null)->find($promo_code_id);
if (empty($promo_code)) {
return ['status' => 400, 'result' => 'Promotion does not exist.'];
}
//Filter by date and time
$current_date = date('Y-m-d');
$current_time = date('H:i');
if ($current_date < $promo_code['start_date'] || $current_date > $promo_code['end_date']) {
return ['status' => 400, 'result' => 'Promotion already expired.'];
}
// Check day/time validity
$validity = json_decode($promo_code['customize_validity'], true);
$dayMap = [
'mon' => 'mon',
'tue' => 'tue',
'wed' => 'wed',
'thu' => 'thurs',
'fri' => 'fri',
'sat' => 'sat',
'sun' => 'sun'
];
$current_day_key = $dayMap[strtolower(date('D'))];
if (isset($validity[$current_day_key]) && $validity[$current_day_key]['enabled']) {
$startTime = $validity[$current_day_key]['startTime'];
$endTime = $validity[$current_day_key]['endTime'];
if ($current_time < $startTime || $current_time > $endTime) {
return ['status' => 400, 'result' => 'Promo code not valid at this time.'];
}
} else {
return ['status' => 400, 'result' => 'Promo Code not valid on this day.'];
}
//Check how many left for the promotion
$promotionAlreadyRedeem = $this->promoRedemptionRecord->where('promo_codes_id', $promo_code['id'])->countAllResults();
if($promotionAlreadyRedeem >= $promo_code['total_redemption_limit'] && $promo_code['total_redemption_limit'] != 0){
return ['status' => 400, 'result' => 'Promo Code already fully redeemed.'];
}
//Check how many left for the customer / customer can redeem multiple or one times
$customerAlreadyRedeem = $this->promoRedemptionRecord ->where('promo_codes_id', $promo_code['id'])->where('customer_id', $customer_id)->countAllResults();
if($promo_code['usage_limit_type'] == 'one' && $customerAlreadyRedeem > 0){
return ['status' => 400, 'result' => 'Promo Code only can be redeemed once.'];
}
if($promo_code['usage_limit_type'] == 'multiple' && $customerAlreadyRedeem >= $promo_code['usage_limit'] && $promo_code['usage_limit'] != 0){
return ['status' => 400, 'result' => 'Promo Code only can be redeemed '. $promo_code['usage_limit'] .' times.'];
}
//Check if the promotion is valid for the order type
//order type = delivery, pick-up, dine-in, reservation
$allowed_order_types = ['delivery', 'pickup', 'dinein', 'reservation'];
if (!in_array($order_type, $allowed_order_types)) {
return ['status' => 400, 'result' => 'Invalid order type.'];
}
$promo_code['promo_order_type'] = explode(',', $promo_code['promo_order_type']);
// print_r($order_type);exit;
if (!in_array($order_type, $promo_code['promo_order_type']) && !in_array("all", $promo_code['promo_order_type'])) {
return ['status' => 400, 'result' => 'Promo Code only valid for ' . $order_type . ' order.'];
}
}
// public function checkPromoLogic($promo_setting_id, $cart_items, $subtotal, $customer_id, $outlet_id, $order_type = 'pickup', $delivery_fee = 0){
public function checkPromoLogic($promo_setting_id, $cart_items, $subtotal, $customer_id, $outlet_id, $order_type, $delivery_fee) {
//Check if it has minimum spend requirement
$promoSetting = $this->promoSetting->where('status', 'active')->find($promo_setting_id);
if(empty($promoSetting)){
return ['status' => 400, 'result' => 'Promo Code does not exist.'];
}
$promoSettingData = json_decode($promoSetting['promo_setting'], true);
$minimumSpend = $promoSettingData['MinimumSpend'];
$promo = $promoSettingData['Promo'];
if ($minimumSpend['type'] !== 'none') {
//minimum spend of subtotal amount (excluded options price)
if($minimumSpend['type'] == 'total' && $minimumSpend['amount_type'] == 'amount'){
if ($subtotal < $minimumSpend['amount']) {
return ['status' => 400, 'result' => 'Minimum spend requirement not met.'];
}
}
//minimum quantity in item / category
if(($minimumSpend['type'] == 'item' || $minimumSpend['type'] == 'category') && $minimumSpend['amount_type'] == 'quantity'){
$minimumQuantity = 0;
if($minimumSpend['type'] == 'item'){
foreach($cart_items as $item){
if(in_array($item['menu_item_id'], $minimumSpend['filter'])){
$minimumQuantity += $item['quantity'];
}
}
} else if ($minimumSpend['type'] == 'category') {
foreach($cart_items as $item){
$category_ids = getMenuCategory($item['menu_item_id']);
foreach($category_ids as $category_id){
if(in_array($category_id['id'], $minimumSpend['filter'])){
$minimumQuantity += $item['quantity'];
break;
}
}
}
}
if($minimumQuantity < $minimumSpend['amount']){
return ['status' => 400, 'result' => 'Minimum quantity requirement for this promo code is not met.'];
}
}
//minmum every item / category have certain quantity
if (($minimumSpend['type'] == 'item' || $minimumSpend['type'] == 'category') &&$minimumSpend['amount_type'] == 'every_quantity') {
$everyQuantity = (int)$minimumSpend['amount'];
$validItems = [];
if ($minimumSpend['type'] == 'item') {
// Build a map of menu_item_id to quantity
foreach ($cart_items as $item) {
if (in_array($item['menu_item_id'], $minimumSpend['filter'])) {
$validItems[$item['menu_item_id']] = ($validItems[$item['menu_item_id']] ?? 0) + $item['quantity'];
}
}
// Check all required filters are present
foreach ($minimumSpend['filter'] as $requiredId) {
if (!isset($validItems[$requiredId])) {
return ['status' => 400, 'result' => 'Required item(s) is not found in cart.'];
}
if ((int)$validItems[$requiredId] < $everyQuantity) {
return ['status' => 400, 'result' => 'Every quantity requirement for this promo code is not met.'];
}
}
}
if ($minimumSpend['type'] == 'category') {
foreach ($cart_items as $item) {
$category_ids = getMenuCategory($item['menu_item_id']);
foreach ($category_ids as $cat) {
$cat_id = $cat['id'];
if (in_array($cat_id, $minimumSpend['filter'])) {
if (!isset($validItems[$cat_id])) {
$validItems[$cat_id] = $item['quantity'];
}else{
$validItems[$cat_id] += $item['quantity'];
}
break;
}
}
}
foreach ($minimumSpend['filter'] as $requiredCatId) {
if (!isset($validItems[$requiredCatId])) {
return ['status' => 400, 'result' => 'Required category item(s) is not found in cart.'];
}
if ((int)$validItems[$requiredCatId] < $everyQuantity) {
return ['status' => 400, 'result' => 'Every quantity requirement for this promo code is not met.'];
}
}
}
}
if (($minimumSpend['type'] == 'item' || $minimumSpend['type'] == 'category') && $minimumSpend['amount_type'] == 'amount') {
$eligibleSubtotal = 0.0;
// print_r($minimumSpend);
// print_r($cart_items);
// exit;
foreach ($cart_items as $item) {
if ($minimumSpend['type'] === 'item') {
if (in_array($item['menu_item_id'], $minimumSpend['filter'])) {
$eligibleSubtotal += (float)$item['line_subtotal'];
}
} else {
$category_ids = getMenuCategory($item['menu_item_id']);
foreach ($category_ids as $cat) {
if (in_array($cat['id'], haystack: $minimumSpend['filter'])) {
$eligibleSubtotal += (float)$item['line_subtotal'];
break;
}
}
}
}
// print_r($eligibleSubtotal);exit;
if ($eligibleSubtotal < (float)$minimumSpend['amount']) {
return ['status' => 400, 'result' => 'Minimum spend on eligible items not met.'];
}
}
}
$afterPromo = [];
$promo_discount_total = 0;
$afterPromo['promo_discount_total'] = 0;
$afterPromo['delivery_fee'] = 0;
$afterPromo['free_item_list'] = [];
//Discount
if ($promo['promo_type'] == 'discount') {
$promoPrice = 0;
$total = 0;
// $capped_at = $promo['capped_at'] ?? 0;
// All
if ($promo['filter_type'] == 'total') {
$promoPrice = calculatePromoPrice($subtotal, $promo['amount'], $promo['discount_type']);
$total = $subtotal;
}
// Item
if ($promo['filter_type'] == 'item') {
// $total = 0;
foreach ($cart_items as $item) {
if (in_array($item['menu_item_id'], $promo['filter'])) {
$total += $item['line_subtotal'];
}
}
switch($promo['discount_type']){
case 'amount':
$promoPrice = $promo['amount'];
break;
case 'percentage':
$promoPrice = calculatePromoPrice($total, $promo['amount'], $promo['discount_type']);
break;
}
}
// Category
if ($promo['filter_type'] == 'category') {
foreach ($cart_items as $item) {
$category_ids = getMenuCategory($item['menu_item_id']);
foreach ($category_ids as $category_id) {
if (in_array($category_id['id'], $promo['filter'])) {
$total += $item['line_subtotal'];
}
}
}
switch($promo['discount_type']){
case 'amount':
$promoPrice = $promo['amount'];
break;
case 'percentage':
$promoPrice = calculatePromoPrice($total, $promo['amount'], $promo['discount_type']);
break;
}
}
// if($promo['discount_type'] == 'percentage'){
// if($promoPrice > $capped_at){
// $promoPrice = $capped_at;
// }
// }
if($promoPrice > $total){
$promoPrice = $total;
}
$afterPromo['promo_discount_total'] = $promoPrice;
}
//Next Item
if ($promo['promo_type'] == 'next_item') {
if (count($cart_items) < 2) {
return ['status' => 400, 'result' => 'At least two items are required for this promo code.'];
}
$eligibleItems = [];
if ($promo['filter_type'] == 'item') {
foreach ($cart_items as $item) {
if (in_array($item['menu_item_id'], $promo['filter'])) {
$eligibleItems[] = $item;
}
}
if (count($eligibleItems) < 2) {
return ['status' => 400, 'result' => 'Two eligible items required for this promo code.'];
}
$lowestItem = $eligibleItems[0];
foreach ($eligibleItems as $item) {
if ((float)$item['unit_price'] < (float)$lowestItem['unit_price']) {
$lowestItem = $item;
}
}
$afterPromo['promo_discount_total'] = calculatePromoPrice($lowestItem['unit_price'], $promo['amount'], $promo['discount_type']);
}
if ($promo['filter_type'] == 'category') {
foreach ($cart_items as $item) {
$category_ids = getMenuCategory($item['menu_item_id']);
$category_ids_flat = array_column($category_ids, 'id');
$intersect = array_intersect($category_ids_flat, $promo['filter']);
if (!empty($intersect)) {
$eligibleItems[] = $item;
}
}
if (count($eligibleItems) < 2) {
return ['status' => 400, 'result' => 'Two eligible category items required for this promo code.'];
}
$lowestItem = $eligibleItems[0];
foreach ($eligibleItems as $item) {
if ((float)$item['unit_price'] < (float)$lowestItem['unit_price']) {
$lowestItem = $item;
}
}
$afterPromo['promo_discount_total'] = calculatePromoPrice($lowestItem['unit_price'], $promo['amount'], $promo['discount_type']);
}
}
// print_r($order_type);
// print_r($delivery_fee);
// print_r($promo);
// exit;
//Delivery Fee
if($delivery_fee > 0 && $order_type == 'delivery') {
if($promo['promo_type'] == 'delivery'){
if($promo['filter_type'] == 'total'){
$afterPromo['delivery_fee'] = calculatePromoPrice($delivery_fee, $promo['amount'], $promo['discount_type']);
}
}
}
//Free Item
if($promo['promo_type'] == 'free_item'){
$free_items = [];
$isIncluded = true;
if($promo['filter_type'] == 'item'){
foreach($promo['free_item'] as $free_item_id){
$menu_item = $this->menuItem
->select('menu_items.id, menu_items.title, menu_images.image_url, menu_images.image_url_compressed')
->join('menu_images', 'menu_images.menu_item_id = menu_items.id', 'left')
->where('menu_items.status', 'active')
->find($free_item_id);
if($menu_item){
$free_items[] = [
'id' => $menu_item['id'],
'title' => $menu_item['title'],
'image_url' => getMenuImage($menu_item['id']),
// 'image_url_compressed' => getMenuImage($menu_item['id'])
];
}
}
}
if($promo['filter_type'] == 'category'){
foreach($promo['free_item'] as $free_item_id){
$menu_items = $this->menuItemCategories
->select('menu_items.id, menu_items.title, menu_item_categories.category_id')
->join('menu_items', 'menu_items.id = menu_item_categories.menu_item_id')
->where('menu_item_categories.category_id', $free_item_id)
->where('menu_items.status', 'active')
->findAll();
if($menu_items){
foreach($menu_items as $item){
$menu_item = $this->menuItem
->select('menu_items.id, menu_items.title, menu_images.image_url, menu_images.image_url_compressed')
->join('menu_images', 'menu_images.menu_item_id = menu_items.id', 'left')
->where('menu_items.status', 'active')
->find($item['id']);
if($menu_item){
$free_items[$item['category_id']][] = [
'id' => $menu_item['id'],
'category_id' => $item['category_id'],
'title' => $menu_item['title'],
'image_url' => getMenuImage($menu_item['id']),
// 'image_url_compressed' => getMenuImage($menu_item['id'])
];
}
}
}
}
}
$afterPromo['free_item_list'] = $free_items;
}
$afterPromo['status'] = 200;
return $afterPromo;
}
public function checkPromoCode($promo_code){
if(empty($promo_code)){
return ['status' => 400, 'result' => 'Promo code is empty.'];
}
$promo_code_id = $this->promoCode->where('code', $promo_code)->orderBy('id', 'desc')->limit(1)->first();
if(empty($promo_code_id)){
return ['status' => 400, 'result' => 'Promo code not found.'];
}
return $promo_code_id['id'];
}
}
?>
+35
View File
@@ -0,0 +1,35 @@
<?
namespace App\Services;
use App\Models\CustomerVoucherList;
class VoucherService
{
private $customer_voucher_list;
public function __construct()
{
$this->customer_voucher_list = new CustomerVoucherList();
}
public function checkVoucherAvailability($customer_voucher_list_id, $order_type, $customer_id)
{
$customer_voucher = $this->customer_voucher_list->where('id', $customer_voucher_list_id)->where('customer_id', $customer_id)->first();
if(empty($customer_voucher)){
return ['status' => 400, 'result' => 'Customer voucher not found.'];
}
$current_date = date('Y-m-d');
if($current_date > $customer_voucher['voucher_expiry_date']){
return ['status' => 400, 'result' => 'Voucher already expired.'];
}
if($customer_voucher['voucher_status'] != 'active'){
return ['status' => 400, 'result' => 'Voucher already ' . $customer_voucher['voucher_status'] . '.'];
}
}
}
?>