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']; } } ?>