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; } }