customerRepository->filter( $request->merge(['page' => $request->get('page') ?? 1])->all(), [], ['hosting', 'vps', 'domain'], ); $title = 'View All Customer'; return view('administrator.pages.customer.index', compact('customers', 'title')); } //Validate userid /** * Get customer Information */ public function getCustomerInfo(Request $request) { //Validate userid $userid = $this->validateUserid(); if (!$userid) { return redirect()->route('customer.index')->withErrors('No data found for this user'); } //find data after validate $customer = $this->customerRepository->findWithRelationships( $userid, [ 'mail', 'file' ], [ 'invoice' => [ 'invoices_status_count_1' => [ 'key' => 'status', 'condition' => '=', 'value' => 1 ], 'invoices_status_count_0' => [ 'key' => 'status', 'condition' => '=', 'value' => 0 ] ], 'hosting' => 'hosting_count', 'vps' => 'vps_count', 'domain' => 'domain_count', 'ticket' => 'ticket_count' ], [ 'invoice' => [ 'invoices_status_1' => [ 'key' => 'status', 'condition' => '=', 'value' => 1, 'sum' => 'total' ], 'invoices_status_0' => [ 'key' => 'status', 'condition' => '=', 'value' => 0, 'sum' => 'total' ] ] ] ); if (!$customer) { return redirect()->route('customer.index')->withErrors('No data found for this user'); } $title = "#" . $customer->id . " " . $customer->fullname; return view("administrator.pages.customer.info", compact('customer', 'title', 'userid')); } protected function validateUserid() { $validate = Validator::make(\request()->all(), [ 'userid' => 'numeric|required' ]); if ($validate->fails()) { return false; } return \request()->userid; } /** * Get customer Profile */ public function getCustomerProfile(Request $request) { //Validate userid $userid = $this->validateUserid(); if (!$userid) { return redirect()->route('customer.index')->withErrors('No data found for this user'); } //find data after validate $customer = $this->customerRepository->findWithRelationships($userid, ['snapshot']); if (!$customer) { return redirect()->route('customer.index')->withErrors('No data found for this user'); } $title = "#" . $customer->id . " " . $customer->fullname; return view("administrator.pages.customer.profile", compact('customer', 'title', 'userid')); } /** * Save profile update */ public function storeCustomerProfile(Request $request) { //Validate userid $userid = $this->validateUserid(); if (!$userid) { return redirect()->route('customer.index')->withErrors('No data found for this user'); } //validate data after validate userid $request->validate([ 'fullname' => 'required', 'email' => 'required' ]); //find user $customer = $this->customerRepository->findWithRelationships($userid, ['snapshot']); if (!$customer) { return redirect()->route('customer.index')->withErrors('No data found for this user'); } try { DB::beginTransaction(); $data = $request->except(['_token', 'userid', 'password', 'email_marketing', 'snapshot_limit']); $request->email_marketing === "on" ? $data['email_marketing'] = 1 : $data['email_marketing'] = 0; if (!empty($request->password)) { $data['password'] = password_hash($request->password, PASSWORD_BCRYPT); } $this->customerRepository->update($userid, $data); $customer->snapShot->limit = $request->snapshot_limit; $customer->snapShot->save(); DB::commit(); } catch (Exception $error) { DB::rollBack(); return back()->withErrors($error->getMessage()); } return back()->with('success', 'Updated successfully'); } /** * Get all product for customer */ public function getCustomerProduct(Request $request) { //Validate userid $userid = $this->validateUserid(); if (!$userid) { return redirect()->route('customer.index')->withErrors('No data found for this user'); } $customer = $this->customerRepository->find($userid); if (!$customer) { return redirect()->route('customer.index')->withErrors('Invalidated Request'); } // Lấy tất cả hosting và VPS của customer $hostingServices = $this->moduleHostingRepository->filter( ['customer_id' => $userid], ['server'] ); $vpsServices = $this->vmwareRepository->filter( ['customer_id' => $userid], ['ipaddress.host.datacenter.vCenter', 'os.osGroup'] ); // Kết hợp và format dữ liệu $allService = collect(); foreach ($hostingServices as $hosting) { $allService->push((object) [ 'product_id' => $hosting->id, 'product_type' => 3, 'name' => $hosting->name, 'description' => $hosting->name . ' (Hosting)' ]); } foreach ($vpsServices as $vps) { $allService->push((object) [ 'product_id' => $vps->id, 'product_type' => 4, 'name' => $vps->name, 'description' => $vps->name . ' (VPS)' ]); } // Lấy invoice_item cụ thể cho sản phẩm $invoice_item = $this->invoiceItemRepository->findBy( $userid, [ 'key' => 'customer_id', 'condition' => '=', 'value' => $userid ] ); $type = null; $product = null; $productName = ''; if ($invoice_item) { $product_id = $invoice_item->product_id ?? null; $product_module_id = $request->get('product') ?? $invoice_item->product_id ?? null; $type = $request->get('type') ?? $invoice_item->product_type ?? null; } else { $product_id = null; $product_module_id = $request->get('product'); $type = $request->get('type'); } switch ($type) { case 3: $product = $this->moduleHostingRepository->findWithRelationships( $product_module_id, [ 'order.payment', 'server' ] ); // Tìm template hosting dựa trên product_id $productName = $this->hostingRepository->find($product_id); break; case 4: $product = $this->vmwareRepository->findWithRelationships( $product_module_id, [ 'order.payment', 'ipaddress.host.datacenter.vCenter', 'os.osGroup' ] ); // Tìm template VPS dựa trên product_id $productName = $this->vPSRepositoryInterface->find($product_id); break; } $title = "#" . $customer->id . " " . $customer->fullname; return view( 'administrator.pages.customer.product', compact( 'title', 'userid', 'type', 'product', 'allService', 'productName', 'invoice_item' ) ); } public function storeCustomerProduct(Request $request) { if (!$request->product_type) { return back()->with($request->except(['_token', '_method']))->withErrors('Invalid Request'); } $product = null; $data = null; $rules = []; switch ($request->product_type) { case 3: $rules = [ 'product_id' => 'required', 'next_due_date' => 'required', 'next_payment' => 'required', 'status' => 'required' ]; $product = $this->moduleHostingRepository->find($request->product_id); $data = $this->handleHosting($request); break; case 4: $rules = [ 'product_id' => 'required', 'next_due_date' => 'required', 'next_payment' => 'required', 'status' => 'required' ]; $product = $this->vmwareRepository->find($request->product_id); $data = $this->handleVmware($request); break; } $validator = Validator::make($request->all(), $rules); if ($validator->fails()) { return back()->withErrors($validator->errors()->first()); } if (!$product) { return back()->withErrors('Product not found'); } try { DB::beginTransaction(); $product->update($data); $this->ipaddressRepository->updateBy(['ip' => $request->ip], ['status' => 1, 'vm_name' => $request->name]); DB::commit(); } catch (Exception $exception) { DB::rollBack(); return back()->with($request->except(['_token', '_method']))->withErrors($exception->getMessage()); } return back()->with('success', 'Update information successfully'); } protected function handleHosting($request) { return [ 'name' => $request->name, 'module_server_id' => $request->module_server_id, 'next_payment' => $request->next_payment, 'next_due_date' => Carbon::createFromFormat('d/m/Y', $request->next_due_date)->timestamp, 'next_invoice' => Carbon::createFromFormat('d/m/Y', $request->next_due_date)->timestamp, 'username' => $request->user, 'password' => $request->password ? SignRSA::EncryptFunc($request->password) : '', 'status' => $request->status ]; } protected function handleVmware($request) { return [ 'name' => $request->name, 'module_ipaddress_id' => $request->ip, 'port' => $request->port, 'user' => $request->user, 'password' => $request->password ? SignRSA::EncryptFunc($request->password) : '', 'hostname' => $request->hostname, 'vmware_id' => $request->vmware_id, 'os_id' => $request->os_version, 'next_payment' => $request->next_payment, 'next_due_date' => Carbon::createFromFormat('d/m/Y', $request->next_due_date)->timestamp, 'next_invoice' => Carbon::createFromFormat('d/m/Y', $request->next_due_date)->timestamp, 'status' => $request->status ]; } /** * Get Domain for customer */ public function getCustomerDomain(Request $request) { //Validate userid $userid = $this->validateUserid(); if (!$userid) { return redirect()->route('customer.index')->withErrors('No data found for this user'); } $customer = $this->customerRepository->find($userid); if (!$customer) { return redirect()->route('customer.index')->withErrors('Invalid Request'); } $domains = $this->moduleDomainRepository->filter( [ 'customer_id' => $userid, 'page' => $request->get('page') ?? 1 ], ['customer'] ); $title = "#" . $customer->id . " " . $customer->fullname; return view('administrator.pages.customer.domain', compact('userid', 'title', 'domains')); } /** * Get Invoice for customer */ public function getCustomerInvoice(Request $request) { //Validate userid $userid = $this->validateUserid(); if (!$userid) { return redirect()->route('customer.index')->withErrors('No data found for this user'); } $customer = $this->customerRepository->find($userid); if (!$customer) { return redirect()->route('customer.index')->withErrors('No data found for this user'); } $invoices = $this->invoiceRepository->filter( [ 'customer_id' => $userid, 'page' => $request->get('page') ?? 1 ], [ 'payment' ] ); $title = "#" . $customer->id . " " . $customer->fullname; return view('administrator.pages.customer.invoice', compact('userid', 'title', 'invoices')); } /** * Get Transactions for customer */ public function getCustomerTransactions(Request $request) { //Validate userid $userid = $this->validateUserid(); if (!$userid) { return redirect()->route('customer.index')->withErrors('No data found for this user'); } $customer = $this->customerRepository->find($userid); if (!$customer) { return redirect()->route('customer.index')->withErrors('No data found for this user'); } $transactions = $this->transactionRepository->filter( [ 'customer_id' => $userid, 'page' => $request->get('page') ?? 1 ] ); $title = "#" . $customer->id . " " . $customer->fullname; return view('administrator.pages.customer.transaction', compact('userid', 'title', 'transactions')); } /** * Get Mail for customer */ public function getCustomerEmail(Request $request) { $userid = $this->validateUserid(); if (!$userid) { return redirect()->route("customer.index")->withErrors("No data found for this user"); } $customer = $this->customerRepository->find($userid); if (!$customer) { return redirect()->route('customer.index')->withErrors('No data found for this user'); } $emails = $this->mailRepository->filter( [ 'customer_id' => $userid, 'page' => $request->get('page') ?? 1 ] ); $title = "#" . $customer->id . " " . $customer->fullname; if (isset($request->email_id)) { $template = $this->mailRepository->find($request->get('email_id')); if ($template) { // Blade emails.render đã bị xoá cùng toàn bộ view email — nội dung mail đã là // HTML hoàn chỉnh render từ tbl.template, trả thẳng ra là đủ. return response($template->message ?? '', 200, ['Content-Type' => 'text/html; charset=UTF-8']); } } return view('administrator.pages.customer.mail', compact('userid', 'title', 'emails')); } /** * Get Log for customer */ public function getCustomerLog(Request $request) { $userid = $this->validateUserid(); if (!$userid) { return redirect()->route("customer.index")->withErrors("No data found for this user"); } $customer = $this->customerRepository->find($userid); if (!$customer) { return redirect()->route('customer.index')->withErrors('Invalid Request'); } $logs = $this->logRepository->filter([ 'customer_id' => $userid, 'page' => $request->get('page') ?? 1 ], ['customer']); $title = "#" . $customer->id . " " . $customer->fullname; return view('administrator.pages.customer.log', compact('userid', 'title', 'logs')); } /** * Save new customer */ public function store(CreateCustomerRequest $request) { $request->validated(); $user = $this->customerRepository->findBy('email', $request->get('email')); if ($user) { return back()->withErrors("Email already exists on the system!"); } try { DB::beginTransaction(); $data = $request->all(); $data['password'] = password_hash($request->password, PASSWORD_BCRYPT); $request->email_marketing === "on" ? $data['email_marketing'] = 1 : $data['email_marketing'] = 0; $this->customerRepository->create($data); DB::commit(); } catch (Exception $error) { DB::rollBack(); return back()->withErrors($error->getMessage()); } return redirect()->route('customer.index')->with('success', 'New user added successfully'); } /** * add new customer */ public function create() { return view('administrator.pages.customer.add', ['title' => 'Thêm Customer']); } public function PasswordReset(Request $request) { $validator = Validator::make( $request->all(), [ 'userid' => 'required|numeric|not__in:0' ], [ 'userid' => [ 'required' => 'Invalid request' ] ] ); if ($validator->fails()) { return back()->withErrors($validator); } $password = Str::random(10); try { DB::beginTransaction(); $this->customerRepository->update( $request->get('userid'), [ 'password' => Hash::make($password) ] ); $data = [ 'company_name' => setting('company'), 'company_logo' => setting('logo'), 'password' => $password, ]; $jobs = new PasswordRecoverJob($data, $this->customerRepository->find($request->get('userid'))); dispatch($jobs)->delay(now()->addSeconds(10)); DB::commit(); } catch (Exception $exception) { DB::rollBack(); return back()->withErrors($exception->getMessage()); } return back()->with('success', "Change and Send new password to email successfully"); } public function addPay(Request $request) { $validator = Validator::make( $request->all(), [ 'userid' => 'required|numeric|not__in:0' ], [ 'userid' => [ 'required' => 'Invalid request' ] ] ); if ($validator->fails()) { return back()->withErrors($validator); } $userid = $request->userid; $customer = $this->customerRepository->find($userid); if (!$customer) { return redirect()->route('customer.index')->withErrors('No data found for this user'); } $title = "Add Pay for Customer"; return view('administrator.pages.customer.addPay', compact('title', 'userid')); } public function addPayStore(AddPayRequest $request) { $request->validated(); $customer = $this->customerRepository->find($request->get('userid')); if (!$customer) { return redirect()->route('customer.index')->withErrors('Invalid Request'); } try { DB::beginTransaction(); match ($request->action) { "+" => $this->customerRepository->update($request->get('userid'), [ 'credit' => (int) $customer->credit + (int) $request->get('amount'), 'total' => (int) $customer->total + (int) $request->get('amount'), ]), "-" => $this->customerRepository->update($request->get('userid'), [ 'credit' => (int) $customer->credit - (int) $request->get('amount'), 'total' => (int) $customer->total - (int) $request->get('amount'), ]), }; DB::commit(); } catch (Exception $exception) { DB::rollBack(); return back()->withErrors($exception->getMessage()); } return back()->with('success', 'Recharge for user successfully'); } public function LoginWithCustomer(Request $request) { $validator = Validator::make( $request->all(), [ 'userid' => 'required|numeric|not__in:0' ], [ 'userid' => [ 'required' => 'Invalid request' ] ] ); if ($validator->fails()) { return back()->withErrors($validator); } $customer = $this->customerRepository->find($request->get('userid')); if (!$customer) { return back()->withErrors('Invalid request'); } // TODO: impersonation feature needs redesign for JWT — session login does not work with JWT guard // This is a legacy Livewire admin feature; will be removed when portal-admin migration is complete Auth::guard('client')->login($customer); session()->put('admin_login_for_customer', true); return redirect()->route('home'); } public function LogoutWithCustomer() { Auth::guard('client')->logout(); return redirect()->route('customer.index'); } public function datatable(Request $request) { $query = $this->customerRepository->filter( $request->all(), [], ['hosting', 'vps', 'domain'], ['*'], true ); return DataTables::eloquent($query) ->addColumn('status', function ($d) { return view('administrator.pages.customer.datatable.status', ['row' => $d])->render(); }) ->addColumn( 'action', function ($d) { return view('administrator.pages.customer.datatable.action', ['row' => $d])->render(); } ) ->rawColumns(['status', 'action']) ->make(true); } public function edit(int $id = 0) { $customer = $this->customerRepository->find($id); if (!$customer) { return back()->withErrors('Invalid request.'); } $title = 'Edit Customer'; return view('administrator.pages.customer.edit', compact('title', 'customer')); } public function update(int $id = 0, CreateCustomerRequest $request) { $customer = $this->customerRepository->find($id); if (!$customer) { return back()->withErrors('Invalid request.'); } $request->validated(); try { DB::beginTransaction(); $data = $request->except(['_token', 'password']); if (!empty($request->password)) { $data['password'] = password_hash($request->password, PASSWORD_BCRYPT); } $this->customerRepository->update($id, $data); DB::commit(); } catch (Exception $error) { DB::rollBack(); return back()->withErrors($error->getMessage()); } return redirect()->route('customer.index')->with('success', 'Update customer successfully!'); } public function destroy(int $id = 0) { $customer = $this->customerRepository->find($id); if (!$customer) { return back()->withErrors('Invalid request.'); } DB::beginTransaction(); try { Invoice::where('customer_id', $id)->delete(); Order::where('customer_id', $id)->delete(); Transaction::where('customer_id', $id)->delete(); $customer->delete(); DB::commit(); } catch (Exception $error) { DB::rollBack(); return back()->withErrors($error->getMessage()); } return redirect()->route('customer.index')->with('success', 'Deleted customer successfully!'); } public function trash() { $title = 'Trash Customers'; return view('administrator.pages.customer.trash', compact('title')); } public function datatableTrash(Request $request) { $query = $this->customerRepository->onlyTrashed( [], ['hosting', 'vps', 'domain'] ); return DataTables::eloquent($query) ->addColumn('status', function ($d) { return view('administrator.pages.customer.datatable.status', ['row' => $d])->render(); }) ->addColumn( 'action', function ($d) { return view('administrator.pages.customer.datatable.action-trash', ['row' => $d])->render(); } ) ->rawColumns(['status', 'action']) ->make(true); } public function restore(int $id = 0) { $customer = $this->customerRepository->find($id); if (!$customer) { $customer = $this->customerRepository->onlyTrashed()->find($id); } if (!$customer) { return back()->withErrors('Invalid request.'); } DB::beginTransaction(); try { $customer->restore(); Invoice::withTrashed()->where('customer_id', $id)->restore(); Order::withTrashed()->where('customer_id', $id)->restore(); Transaction::withTrashed()->where('customer_id', $id)->restore(); DB::commit(); } catch (Exception $error) { DB::rollBack(); return back()->withErrors($error->getMessage()); } return back()->with('success', 'Restored customer successfully!'); } public function forceDelete(int $id = 0) { $customer = $this->customerRepository->onlyTrashed()->find($id); if (!$customer) { return back()->withErrors('Invalid request.'); } DB::beginTransaction(); try { Invoice::withTrashed()->where('customer_id', $id)->forceDelete(); Order::withTrashed()->where('customer_id', $id)->forceDelete(); Transaction::withTrashed()->where('customer_id', $id)->forceDelete(); $customer->forceDelete(); DB::commit(); } catch (Exception $error) { DB::rollBack(); return back()->withErrors($error->getMessage()); } return back()->with('success', 'Permanently deleted customer!'); } }