carts = new Carts(); $this->cart_items = new CartItems(); $this->cart_item_options = new CartItemOptions(); $this->menu_items = new MenuItems(); $this->menu_item_options_groups = new MenuItemOptionsGroups(); $this->option_groups = new OptionsGroups(); $this->options = new Options(); $this->menu_item_variations = new MenuItemVariations(); $this->variation_options_groups = new VariationOptionsGroups(); $this->outlet_menus = new OutletMenus(); $this->outlet = new Outlet(); $this->db = Config::connect(); $this->cart_service = service('cartService'); $this->calculate_service = service('calculateService'); $this->promo_service = service('promoService'); $this->voucher_service = service('voucherService'); } public function checkPwp($cart_id) { $cart = $this->carts->find($cart_id); if (!$cart) { return ['status' => 400, 'result' => 'Cart not found.']; } $cart_items = $this->cart_items ->where('cart_id', $cart_id) ->findAll(); if (empty($cart_items)) { return ['status' => 200, 'result' => []]; } $cart_item_ids = array_column($cart_items, 'menu_item_id'); $pwp_promos = $this->db->table('pwp') ->where('deleted_at', null) ->get() ->getResultArray(); $eligible_pwps = []; foreach ($pwp_promos as $promo) { $requiredIds = explode(',', $promo['selected_item']); $pwpIds = explode(',', $promo['pwp_item_id']); $hasQualifier = count(array_intersect($cart_item_ids, $requiredIds)) > 0; if ($hasQualifier) { foreach ($pwpIds as $pid) { $menu_item = $this->menu_items->find($pid); if (!$menu_item) continue; $eligible_pwps[] = [ 'pwp_id' => $promo['id'], 'pwp_item' => [ 'id' => $menu_item['id'], 'title' => $menu_item['title'], 'original_price' => $menu_item['price'], 'pwp_price' => $promo['amount'], ], 'requires' => $requiredIds, 'requirement' => [ 'type' => $promo['amount_type'], 'value' => $promo['order_index'] ] ]; } } } return ['status' => 200, 'result' => $eligible_pwps]; } public function getCartDetail() { // echo(123);exit; $validation = $this->validate([ 'customer_id' => 'required|numeric', 'outlet_id' => 'required|numeric', 'selected_date' => 'permit_empty|string', 'selected_time' => 'permit_empty|string', 'latitude' => 'permit_empty|string', 'longitude' => 'permit_empty|string', 'order_type' => 'permit_empty|string', 'address' => 'permit_empty|string', ]); if (!$validation) { return $this->failValidationErrors($this->validator->getErrors()); } $customer_id = $this->request->getVar('customer_id'); $outlet_id = $this->request->getVar('outlet_id'); $selected_date = $this->request->getVar('selected_date') ?? date('Y-m-d'); $selected_time = $this->request->getVar('selected_time') ?? date('H:i'); $latitude = $this->request->getVar('latitude'); $longitude = $this->request->getVar('longitude'); $order_type = strtolower(str_replace('-', '', $this->request->getVar('order_type'))); $address = $this->request->getVar('address'); $outlet = $this->outlet->where('id', $outlet_id)->first(); if (!$outlet) { return $this->respond(['status' => 405, 'message' => 'Outlet not found'], 400); } $outlet['serve_method'] = strtolower(str_replace('-', '', $outlet['serve_method'])); //check order type $serve_method = explode(',', $outlet['serve_method']); if ($outlet['status'] == 'inactive' || $outlet['deleted_at'] != null || !in_array($order_type, $serve_method)) { return $this->respond(['status' => 405, 'message' => 'Outlet not available for this order type'], 400); } $cart = $this->carts->where('customer_id', $customer_id) ->where('outlet_id', $outlet_id) ->where('status', 'active') ->where('deleted_at', null) ->orderBy('id', 'DESC') ->first(); if (!$cart) { return $this->respond("No active cart found for this customer.", 200); } $promo_or_voucher = null; if ($cart['promo_code_id'] > 0) { $check_promo = $this->promo_service->checkPromoAvailability($cart['promo_code_id'], $order_type, $customer_id); if (isset($check_promo['status']) && $check_promo['status'] == 400) { $this->calculate_service->resetVoucher($cart['id']); return $this->respond($check_promo); } $promo_or_voucher = 'promo'; } if ($cart['customer_voucher_list_id'] > 0) { $check_voucher = $this->voucher_service->checkVoucherAvailability($cart['customer_voucher_list_id'], $order_type, $customer_id); if (isset($check_voucher['status']) && $check_voucher['status'] == 400) { $this->calculate_service->resetVoucher($cart['id']); return $this->respond($check_voucher); } $promo_or_voucher = 'voucher'; } $cart_total_detail = $this->calculate_service->calculateCartTotals($cart['id'], $cart['outlet_id'], $selected_date, $selected_time, $latitude, $longitude, $order_type, $address, $promo_or_voucher); // print_r($cart_total_detail); // exit; if (isset($cart_total_detail['status']) && $cart_total_detail['status'] == 400) { $response = [ 'status' => 400, 'message' => $cart_total_detail['result'] ]; return $this->respond($response, 400); } $cart_total_detail = $cart_total_detail['data']; // $pwp_check = $this->checkPwp($cart['id']); // $eligible_pwps = ($pwp_check['status'] === 200) ? $pwp_check['result'] : []; unset($cart_total_detail['invalid_items']); return $this->respond([ 'status' => 200, 'message' => 'Cart retrieved successfully.', 'data' => $cart_total_detail, // 'eligible_pwps' => $eligible_pwps ]); } public function addCart() { $validation = $this->validate([ 'customer_id' => 'required|numeric', 'outlet_id' => 'required|numeric', 'menu_item_id' => 'required|numeric', 'quantity' => 'required|numeric', 'variation_id' => 'permit_empty|numeric', 'option' => 'permit_empty', 'is_free_item' => 'permit_empty', 'is_pwp' => 'permit_empty', ]); if (!$validation) { return $this->failValidationErrors($this->validator->getErrors()); } $customer_id = $this->request->getVar('customer_id'); $outlet_id = $this->request->getVar('outlet_id'); $menu_item_id = $this->request->getVar('menu_item_id'); $variation_id = $this->request->getVar('variation_id') ?? 0; $option_group = $this->request->getVar('option'); $quantity = $this->request->getVar('quantity'); $is_free_item_type = $this->request->getVar('is_free_item') == true ? 'free_item' : null; $is_pwp_type = $this->request->getVar('is_pwp') == true ? 'pwp' : null; $type = $is_free_item_type ?? $is_pwp_type; // print_r($this->request->getVar('is_free_item') == true ? 'free_item' : null);exit; // Check if existing cart $existing_cart = $this->carts ->where('customer_id', $customer_id) ->where('outlet_id', $outlet_id) ->where('status', 'active') ->first(); $addCart = $this->cart_service->addCartItem($customer_id, $outlet_id, $existing_cart, $menu_item_id, $variation_id, $option_group, $quantity, $type); return $this->respond($addCart); } public function updateCart() { $validation = $this->validate([ 'customer_id' => 'required|numeric', 'outlet_id' => 'required|numeric', 'action' => 'required|numeric', ]); if (!$validation) { return $this->failValidationErrors($this->validator->getErrors()); } $customer_id = $this->request->getVar('customer_id'); $outlet_id = $this->request->getVar('outlet_id'); $action = $this->request->getVar('action'); $cart_item_id = $this->request->getVar('cart_item_id'); $quantity = $this->request->getVar('quantity'); $variation_id = $this->request->getVar('variation_id'); $option_group = $this->request->getVar('option'); $cart = $this->carts->where('customer_id', $customer_id) ->where('outlet_id', $outlet_id) ->where('status', 'active') ->first(); if (!$cart) { return $this->fail('Cart not found', 400); } $this->db->transStart(); try { switch ($action) { case 1: // Update quantity $cart_item = $this->cart_items->find($cart_item_id); if (!$cart_item || $cart_item['cart_id'] != $cart['id']) { return $this->fail('Cart item not found', 400); } $data = [ 'unit_price' => $cart_item['unit_price'], 'quantity' => $quantity, 'line_subtotal' => $cart_item['unit_price'] * $quantity ]; $this->cart_items->update($cart_item['id'], $data); break; case 2: // Update Option $cart_item = $this->cart_items->find($cart_item_id); if (!$cart_item || $cart_item['cart_id'] != $cart['id']) { return $this->fail('Cart item not found', 400); } $menu_item_id = $cart_item['menu_item_id']; if (!isset($variation_id)) { return $this->fail('No variation found', 400); } $required_groups = $this->cart_service->getRequiredOptionGroups($menu_item_id, $variation_id); // Validate that required options are provided if (!empty($required_groups)) { if (empty($option_group)) { return $this->fail('Required options are missing', 400); } $provided_group_ids = array_map(function ($opt) { return $opt->group_id; }, $option_group); foreach ($required_groups as $group) { if (!in_array($group['id'], $provided_group_ids)) { return $this->fail('Required option group ' . $group['title'] . ' is missing', 400); } } } if ($variation_id == 0) { $menu_item = $this->menu_items->where('status', 'active')->find($menu_item_id); if (empty($menu_item)) { return $this->fail("Menu Item not found!", 400); } $basePrice = $menu_item['price']; $line_subtotal = $basePrice * $quantity; $update_cart_detail = [ 'variation_id' => 0, 'title' => $menu_item['title'], 'unit_price' => $basePrice, 'quantity' => $quantity, 'line_subtotal' => $line_subtotal, ]; $this->cart_items->update($cart_item['id'], $update_cart_detail); if (!empty($option_group)) { foreach ($option_group as $opt) { $option_group_id = $opt->group_id; $option_ids = $opt->option_ids; $existingGroupIds = getColumnValues($this->menu_item_options_groups, 'menu_item_id', $menu_item_id, 'option_group_id'); 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_groups['is_required'] == 1 && $option_num < 0) { return $this->fail('This option is required', 400); } if ($option_num >= $option_groups['min_quantity'] && $option_num <= $option_groups['max_quantity']) { $existing_cart_item_option = getColumnValues($this->cart_item_options, 'cart_item_id', $cart_item['id'], 'id'); $option_group_exist = []; foreach ($option_ids as $key => $value) { $option_selected = $this->options->where('option_group_id', $option_group_id)->find($value); if (empty($option_selected)) { return $this->fail('No option selected !', 400); } $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'] ]; $current_option_existing = $this->cart_item_options->where('cart_item_id', $cart_item['id']) ->where('option_id', $value) ->where('option_group_id', $option_group_id) ->first(); if ($current_option_existing) { $option_group_exist[] = $current_option_existing['id']; } else { $this->cart_item_options->insert($option_data); } } foreach ($existing_cart_item_option as $exist_option_id) { if (!in_array($exist_option_id, $option_group_exist)) { $this->cart_item_options->delete($exist_option_id); } } } else { return $this->fail('Please select correct quantity for option!', 400); } } } } } else { $existing_cart_item_option = getColumnValues($this->cart_item_options, 'cart_item_id', $cart_item['id'], 'id'); $this->cart_item_options->whereIn('id', $existing_cart_item_option)->delete(); } } else { $menu_item = $this->menu_items->where('status', 'active')->find($menu_item_id); if (empty($menu_item)) { return $this->fail("Menu Item not found!", 400); } $menu_variation = $this->menu_item_variations->where('menu_item_id', $menu_item_id)->first(); $basePrice = $menu_variation['price']; $line_subtotal = $basePrice * $quantity; $update_cart_detail = [ 'variation_id' => $variation_id, 'title' => $menu_item['title'], 'unit_price' => $basePrice, 'quantity' => $quantity, 'line_subtotal' => $line_subtotal, ]; $this->cart_items->update($cart_item['id'], $update_cart_detail); if (!empty($menu_variation)) { if ($variation_id > 0) { $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) { $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_groups['is_required'] == 1 && $option_num < 0) { return $this->fail('This option is required', 400); } if ($option_num >= $option_groups['min_quantity'] && $option_num <= $option_groups['max_quantity']) { $existing_cart_item_option = getColumnValues($this->cart_item_options, 'cart_item_id', $cart_item['id'], 'id'); $option_group_exist = []; foreach ($option_ids as $key => $value) { $option_selected = $this->options->where('option_group_id', $option_group_id)->find($value); if (empty($option_selected)) { return $this->fail('No option selected !', 400); } $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'] ]; $current_option_existing = $this->cart_item_options->where('cart_item_id', $cart_item['id']) ->where('option_id', $value) ->where('option_group_id', $option_group_id) ->first(); if ($current_option_existing) { $option_group_exist[] = $current_option_existing['id']; } else { $this->cart_item_options->insert($option_data); } } foreach ($existing_cart_item_option as $exist_option_id) { if (!in_array($exist_option_id, $option_group_exist)) { $this->cart_item_options->delete($exist_option_id); } } } else { return $this->fail('Please select correct quantity for option!', 400); } } } } } else { $existing_cart_item_options = $this->cart_item_options ->where('cart_item_id', $cart_item['id']) ->findAll(); if (!empty($existing_cart_item_options)) { $option_ids = array_column($existing_cart_item_options, 'id'); $this->cart_item_options->whereIn('id', $option_ids)->delete(); } } } else { return $this->fail('No variation found!', 400); } } } break; case 3: // Remove one item $cart_item = $this->cart_items->find($cart_item_id); // print_r(123123);exit; if (!$cart_item || $cart_item['cart_id'] != $cart['id']) { return $this->fail('Cart item not found', 400); } $this->cart_items->delete($cart_item['id']); $this->cart_item_options->where('cart_item_id', $cart_item['id'])->delete(); break; case 4: // Remove all items $all_cart_item = $this->cart_items->where('cart_id', $cart['id'])->findAll(); foreach ($all_cart_item as $item) { $this->cart_item_options->where('cart_item_id', $item['id'])->delete(); $this->cart_items->delete($item['id']); } break; default: return $this->fail('Invalid action', 400); break; } // $this->calculate_service->calculateCartTotals($cart['id'], $outlet_id); $this->db->transComplete(); return $this->respond([ 'status' => 200, 'message' => 'Cart updated successfully' ]); } catch (\Exception $e) { $this->db->transRollback(); return $this->fail($e->getMessage(), 400); } } public function deleteCart() { $validation = $this->validate([ 'customer_id' => 'required|numeric', 'outlet_id' => 'required|numeric', ]); if (!$validation) { return $this->failValidationErrors($this->validator->getErrors()); } $customer_id = $this->request->getVar('customer_id'); $outlet_id = $this->request->getVar('outlet_id'); $cart = $this->carts->where('customer_id', $customer_id) ->where('outlet_id', $outlet_id) ->where('status', 'active') ->first(); if ($cart) { $this->carts->update($cart['id'], ['status' => 'trash']); $this->carts->delete($cart['id']); $exist_cart_item = getColumnValues($this->cart_items, 'cart_id', $cart['id'], 'id'); $this->cart_items->where('cart_id', $cart['id'])->delete(); $this->cart_item_options->whereIn('cart_item_id', $exist_cart_item)->delete(); return $this->respond([ 'status' => 200, 'message' => 'Cart delete successfully' ]); } else { return $this->fail('Cart not found', 400); } } public function getCartItemsDetails($cart_item_id = null) { $cart_item = $this->cart_items->find($cart_item_id); if (!$cart_item) { return $this->fail('Cart item not found', 400); } $cart_item['variation'] = $this->menu_item_variations->find($cart_item['variation_id']); $cart_item['options'] = $this->cart_item_options ->select('cart_item_options.*, options_groups.title as option_group_title') ->join('options_groups', 'options_groups.id = cart_item_options.option_group_id', 'left') ->where('cart_item_id', $cart_item_id) ->findAll(); return $this->respond([ 'status' => 200, 'message' => 'Cart item details retrieved successfully', 'data' => $cart_item ]); } }