cart(customer()?->id); $title = "Giỏ hàng"; return view("frontend.cart.index", compact('cartItems', 'title')); } public function addCart(Request $request) { $userId = customer()?->id; $months = $request->input('months'); $productId = $request->product_id; $typeId = $request->type_id; if (!$userId) { return back()->with('error', 'Bạn cần đăng nhập để thêm sản phẩm vào giỏ hàng.'); } // Validate input data if (!$productId || !$typeId || !$months) { return back()->with('error', 'Dữ liệu không hợp lệ.'); } // Use updateOrCreate instead of delete + create for better performance try { CartModel::updateOrCreate( ['customer_id' => $userId], // Only one cart item per user [ 'product_id' => $productId, 'type_product' => $typeId, 'months' => $months, ] ); return redirect()->route('cart.index')->with('success', 'Sản phẩm đã được thêm vào giỏ hàng!'); } catch (\Exception $e) { Log::error('Cart add error: ' . $e->getMessage(), [ 'user_id' => $userId, 'product_id' => $productId, 'type_id' => $typeId ]); return back()->with('error', 'Có lỗi xảy ra khi thêm sản phẩm vào giỏ hàng.'); } } public function store(Request $request, Cart $cart) { $validator = null; $allOrderItem = []; if ($request->vps) { $validator = Validator::make( $request->all(), [ 'vps.*.os_id' => 'required', 'vps.*.os_version_id' => 'required', 'vps.*.time_buy' => 'required', 'vps.*.hostname' => 'required' ], [ 'vps.*.os_id' => [ 'required' => 'Vui lòng chọn hệ điều hành cần cài đặt!' ], 'vps.*.os_version_id' => [ 'required' => 'Vui lòng chọn version cần cài đặt!' ], 'vps.*.hostname' => [ 'required' => 'Vui lòng nhập hostname!' ] ] ); foreach ($request->vps as $_key => $_item) { $product = $cart->getItem(customer()?->id, $_key); if ($product) { $allOrderItem[] = [ 'data' => $_item, 'product' => $product ]; } } } if ($request->hosting) { $validator = Validator::make( $request->all(), [ 'hosting.*.time_buy' => 'required', 'hosting.*.domain' => 'required' ], [ 'hosting.*.domain' => [ 'required' => 'Vui lòng nhập tên miền để kích hoạt Hosting!' ], 'hosting.*.time_buy' => [ 'required' => 'Vui lòng chọn thời gian thanh toán!' ], ] ); $regexFilterDomain = '/(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]/m'; foreach ($request->hosting as $_key => $_item) { $filter = filter_var( $request->hosting[$_key]['domain'], FILTER_VALIDATE_REGEXP, [ 'options' => [ 'regexp' => $regexFilterDomain ] ] ); if ($filter === false) { return back()->with($request->except(['_token']))->withErrors("Tên miền không hợp lệ"); } } foreach ($request->hosting as $_key => $_item) { $product = $cart->getItem(customer()?->id, $_key); if ($product) { $allOrderItem[] = [ 'data' => $_item, 'product' => $product ]; } } } if ($validator && $validator->fails()) { return back()->with($request->except(['_token']))->withErrors($validator); } if (!count($allOrderItem)) { return back()->with($request->except('_token'))->withErrors("Yêu cầu không hợp lệ"); } $relid_data = []; foreach ($allOrderItem as $key => $item) { $relid_code = Helper::generateUniqueCode(); $product = null; $relid_data[$key]['code'] = $relid_code; $relid_data[$key]['data'] = [ 'customer_id' => customer()?->id, 'status' => 3 ]; switch ($item['product']['product_type']) { case 3: $product = Hosting::find($item['product']['product']); $relid_data[$key]['data']['name'] = $item['data']['domain']; $relid_data[$key]['type'] = 3; break; case 4: $product = VPS::find($item['product']['product']); $relid_data[$key]['data']['hostname'] = $item['data']['hostname']; $relid_data[$key]['data']['os_id'] = $item['data']['os_version_id']; $relid_data[$key]['type'] = 4; break; } $subMessage = ""; $billing = 0; switch ($item['data']['time_buy']) { case 1: $billing = 2; $subMessage = " ( " . Carbon::today()->format('d/m/Y') . " - " . Carbon::today()->addMonths(1)->format('d/m/Y') . " )"; $relid_data[$key]['data']['next_due_date'] = Carbon::today()->addMonths(1)->timestamp; $relid_data[$key]['data']['next_invoice'] = Carbon::today()->addMonths(1)->timestamp; break; case 3: $billing = 3; $subMessage = " ( " . Carbon::today()->format('d/m/Y') . " - " . Carbon::today()->addMonths(3)->format('d/m/Y') . " )"; $relid_data[$key]['data']['next_due_date'] = Carbon::today()->addMonths(3)->timestamp; $relid_data[$key]['data']['next_invoice'] = Carbon::today()->addMonths(3)->timestamp; break; case 6: $billing = 4; $subMessage = " ( " . Carbon::today()->format('d/m/Y') . " - " . Carbon::today()->addMonths(6)->format('d/m/Y') . " )"; $relid_data[$key]['data']['next_due_date'] = Carbon::today()->addMonths(6)->timestamp; $relid_data[$key]['data']['next_invoice'] = Carbon::today()->addMonths(6)->timestamp; break; case 12: $billing = 5; $subMessage = " ( " . Carbon::today()->format('d/m/Y') . " - " . Carbon::today()->addMonths(12)->format('d/m/Y') . " )"; $relid_data[$key]['data']['next_due_date'] = Carbon::today()->addMonths(12)->timestamp; $relid_data[$key]['data']['next_invoice'] = Carbon::today()->addMonths(12)->timestamp; break; } $totalAddon = 0; $message = $product->name; $product_item[] = [ 'customer_id' => customer()?->id, 'type_id' => $item['product']['product_type'], 'product_id' => $item['product']['product'], 'description' => $message . $subMessage, 'amount' => $item['product']['price'] * $item['data']['time_buy'], 'billing' => $billing, 'invoice_type' => 1, 'tax' => 1, 'parent_id' => 0, 'code' => $relid_code, 'due_date' => Carbon::today()->hour(23)->minute(59)->second(59)->timestamp, ]; if (isset($item['data']['addon'])) { foreach ($item['data']['addon'] as $_key => $_sub) { $productAddon = Addon::where('name', 'like', "%$_key%")->first(); $message = "Addon " . $productAddon->name; if ($_sub['value']) { $totalAddon += $_sub['price'] * $_sub['value'] * $item['data']['time_buy']; $product_item[$key]['addon'][] = [ 'customer_id' => customer()?->id, 'type_id' => $productAddon->type_id, 'product_id' => $productAddon->id, 'description' => $message . $subMessage, 'amount' => $_sub['price'] * $_sub['value'] * $item['data']['time_buy'], 'billing' => $billing, 'invoice_type' => 1, 'tax' => 1, 'due_date' => Carbon::today()->hour(23)->minute(59)->second(59)->timestamp, ]; } } } $relid_data[$key]['data']['first_payment'] = $item['product']['price'] * $item['data']['time_buy'] + $totalAddon; $relid_data[$key]['data']['next_payment'] = $item['product']['price'] * $item['data']['time_buy'] + $totalAddon; } $allOrderItemWithAddon = array_map(function ($item) { $codeCheckAddon = Helper::generateUniqueCode(); $item['addon_code'] = $codeCheckAddon; return $item; }, $product_item); $addonArray = []; foreach ($allOrderItemWithAddon as $item) { if (isset($item['addon'])) { foreach ($item['addon'] as $_Sub) { $_Sub['parent'] = $item['addon_code']; $addonArray[] = $_Sub; } } } $allOrderItemWithAddon = array_map(function ($item) { if (isset($item['addon'])) { unset($item['addon']); } return $item; }, array_merge($addonArray, $allOrderItemWithAddon)); $total = array_sum(array_map(function ($item) { return $item['amount']; }, $allOrderItemWithAddon)); $discount = 0; $discount_value = 0; if (session('coupon')) { $discount = session('coupon')['coupon_id']; switch (session('coupon')['coupon_type']) { case 1: $discount_value = (int) ((session('coupon')['coupon_value'] / 100) * $total); $total -= $discount_value; break; case 2: $discount_value = (int) session('coupon')['coupon_value']; $total -= $discount_value; break; } } try { DB::beginTransaction(); $invoice_data = [ 'date' => Carbon::today()->timestamp, 'due_date' => Carbon::today()->hour(23)->minute(59)->second(59)->timestamp, 'sub_total' => $total, 'tax' => $total * (10 / 100), 'total' => $total + ($total * (10 / 100)), 'payment_id' => 1, 'customer_id' => customer()?->id, 'status' => 0 ]; $invoice_id = Invoice::insertGetId($invoice_data); $allOrderItemWithAddon = array_map(function ($array) use ($invoice_id) { $array['invoice_id'] = $invoice_id; return $array; }, $allOrderItemWithAddon); $order_item = [ 'order_num' => Helper::generateUniqueCode(), 'customer_id' => customer()?->id, 'date' => Carbon::today()->timestamp, 'invoice_id' => $invoice_id, 'discount_id' => $discount, 'discount_value' => $discount_value, 'amount' => $total + ($total * (10 / 100)), 'payment_id' => 1, 'user_id' => 0, 'status' => 0, 'client_ip' => $request->getClientIp() ]; $order = Order::insertGetId($order_item); $relid_data = array_map(function ($array) use ($order) { $array['data']['order_id'] = $order; return $array; }, $relid_data); $relid = []; //insert + get id for item auto created by module foreach ($relid_data as $item) { $code = $item['code']; switch ($item['type']) { case 3: $relid_id = ModuleHosting::insertGetId($item['data']); $relid[$code] = $relid_id; break; case 4: $relid_id = ModuleVmware::insertGetId($item['data']); $relid[$code] = $relid_id; break; } } $allInvoiceItem = array_map(function ($array) use ($relid) { if (isset($array['code']) && array_key_exists($array['code'], $relid)) { $array['relid'] = $relid[$array['code']]; } else { $array['relid'] = 0; } unset($array['code']); return $array; }, $allOrderItemWithAddon); $productNoAddon = array_values(array_filter($allInvoiceItem, function ($item) { if (isset($item['addon_code'])) { return $item; } })); $productAddon = array_values(array_filter($allInvoiceItem, function ($item) { if (!isset($item['addon_code'])) { return $item; } })); $allProduct = []; foreach ($productNoAddon as $item) { foreach ($productAddon as $_sub) { if ($item['addon_code'] === $_sub['parent']) { $_Sub['parent_id'] = $item['relid']; $_sub['parent_id'] = $item['relid']; unset($_sub['parent']); $allProduct[] = $_sub; } } if (isset($item['addon_code'])) { unset($item['addon_code']); } $allProduct[] = $item; } InvoiceItem::insert($allProduct); $last_id = InvoiceItem::latest('id')->limit(count($allProduct))->select('id')->get()->toArray(); $Order__order_item = array_map(function ($array) use ($order) { return [ 'order_id' => $order, 'InvoiceItem_id' => $array['id'] ]; }, $last_id); DB::table('order__order_item')->insert($Order__order_item); Log::create([ 'agent' => $request->userAgent(), 'client_ip' => $request->getClientIp(), 'username' => "System", 'description' => customer()?->firstname . " created new Order with Order id: " . $order, 'customer_id' => customer()?->id ]); if (session('coupon')) { Discount::find(session('coupon')['coupon_id'])->increment('use', 1); } DB::commit(); } catch (Exception $exception) { DB::rollBack(); return back()->with($request->except(['_token']))->withErrors($exception->getMessage()); } session()->forget('cart'); session()->forget('coupon'); return redirect()->route('invoice.show', ['invoice_id' => $invoice_id])->with('sucess', 'Đặt hàng thành công'); } public function destroy(Request $request, Cart $cart) { $validator = Validator::make( $request->all(), [ 'cart_id' => 'required' ], [ 'cart_id' => [ 'required' => 'Yêu cầu không hợp lệ' ] ] ); if ($validator->fails()) { return back()->withErrors($validator); } $status = $cart->removeCartItem(customer()?->id, $request->cart_id); if ($status) { return back()->with('success', 'Xoá thông tin đơn hàng thành công'); } return back()->withErrors('Yêu cầu không hợp lệ'); } public function applyCoupon(Request $request) { $validator = Validator::make( $request->all(), [ 'promotion_code' => 'required' ], [ 'promotion_code' => [ 'required' => 'Mã giảm giá không được để trống' ] ] ); if ($validator->fails()) { return redirect() ->route('cart') ->with($request->except(['_token'])) ->withErrors($validator); } $Coupon = Discount::where('code', $request->promotion_code)->first(); if (!$Coupon) { return redirect() ->route('cart') ->with($request->except(['_token'])) ->withErrors("Mã giảm giá không hợp lệ"); } if ($Coupon->status === 0) { return redirect() ->route('cart') ->with($request->except(['_token'])) ->withErrors("Mã giảm giá không hợp lệ"); } if ($Coupon->end < Carbon::today()->timestamp) { return redirect() ->route('cart') ->with($request->except(['_token'])) ->withErrors("Mã giảm giá đã hết hạn sử dụng"); } if ($Coupon->start > Carbon::today()->timestamp) { return redirect() ->route('cart') ->with($request->except(['_token'])) ->withErrors("Mã giảm giá không hợp lệ"); } if ($Coupon->use === $Coupon->count) { return redirect() ->route('cart') ->with($request->except(['_token'])) ->withErrors("Mã giảm giá đã đạt giới hạn số lượng cho phép"); } $couponAdded = [ 'coupon_value' => $Coupon->discount, 'coupon_type' => $Coupon->type, 'coupon_code' => $Coupon->code, 'coupon_id' => $Coupon->id ]; session()->put('coupon', $couponAdded); return redirect() ->route('cart') ->with($request->except(['_token'])) ->with('success', 'Áp dụng mã giảm thành công!'); } public function addon(Request $request) { $validator = Validator::make($request->all(), [ 'product' => 'required|not__in:0' ], ['product.required' => 'Yêu cầu không hợp lệ']); if ($validator->fails()) { return response()->json(['error' => true, 'message' => $validator]); } $count = 0; $sumAddon = 0; $addOn = []; $billing = 0; if ($request->addon) { $i = 0; foreach ($request->addon as $key => $item) { if ($item['quantity'] != 0) { $product = Addon::where('name', 'like', "%$key%")->first(); $addOn[$i] = [ 'customer_id' => customer()?->id, 'type_id' => 1, 'due_date' => Carbon::today()->hour(23)->minute(59)->second(59)->timestamp, 'product_id' => $product->id, 'parent_id' => $request->product, 'relid' => 0, 'invoice_type' => "1", 'billing' => $request->billing, 'amount' => $item['price'] * $item['quantity'], 'tax' => 1, ]; $message = "Addon " . strtoupper($key); switch ($request->billing) { case 2: $billing = 1; $message .= " ( " . Carbon::today()->format('d/m/Y') . " - " . Carbon::today()->addMonths(1)->format('d/m/Y') . " )"; break; case 3: $billing = 3; $message .= " ( " . Carbon::today()->format('d/m/Y') . " - " . Carbon::today()->addMonths(3)->format('d/m/Y') . " )"; break; case 4: $billing = 6; $message .= " ( " . Carbon::today()->format('d/m/Y') . " - " . Carbon::today()->addMonths(6)->format('d/m/Y') . " )"; break; case 5: $billing = 12; $message .= " ( " . Carbon::today()->format('d/m/Y') . " - " . Carbon::today()->addMonths(12)->format('d/m/Y') . " )"; break; } $addOn[$i]['description'] = $message; } if ($item['quantity'] == 0) { ++$count; } $sumAddon += $item['price'] * $item['quantity']; $i++; } } $sumAddon *= $billing; if ($count === 3) { return response()->json(['error' => true, 'message' => 'Vui lòng chọn một addon để nâng cấp cấu hình!']); } $product = ModuleVmware::with('Order')->find($request->product); if (!$product) { return response()->json(['error' => true, 'message' => 'Yêu cầu không hợp lệ']); } $invoice_data = [ 'date' => Carbon::today()->timestamp, 'due_date' => Carbon::today()->hour(23)->minute(59)->second(59)->timestamp, 'sub_total' => $sumAddon, 'tax' => $sumAddon * (10 / 100), 'total' => $sumAddon + ($sumAddon * (10 / 100)), 'payment_id' => 1, 'customer_id' => customer()?->id, 'status' => 0 ]; try { DB::beginTransaction(); $invoice = Invoice::insertGetId($invoice_data); $order = [ 'order_num' => Helper::generateUniqueCode(), 'customer_id' => customer()?->id, 'date' => Carbon::today()->timestamp, 'invoice_id' => $invoice, 'discount_id' => 0, 'discount_value' => 0, 'amount' => $sumAddon + ($sumAddon * (10 / 100)), 'payment_id' => 1, 'user_id' => 0, 'status' => 0, 'client_ip' => $request->getClientIp() ]; $order_id = Order::insertGetId($order); $AddonItem = array_map(function ($item) use ($invoice) { $item['invoice_id'] = $invoice; return $item; }, $addOn); InvoiceItem::insert($AddonItem); $Order_item = InvoiceItem::select('id')->latest('id')->limit(count($AddonItem))->get(); foreach ($Order_item as $item) { DB::table('order__order_item')->insert([ 'InvoiceItem_id' => $item->id, 'order_id' => $order_id ]); } DB::commit(); } catch (Exception $exception) { DB::rollBack(); return response()->json(['error' => true, 'message' => $exception->getMessage()]); } return response()->json(['error' => false, 'message' => 'Order thành công. Vui lòng thanh toán để tiến hành nâng cấp!']); } }