1, 3 => 3, 4 => 6, 5 => 12, default => 0 }; return [ 'next_due_date' => $months ? Carbon::today()->addMonths($months)->timestamp : null, 'next_invoice' => $months ? Carbon::today()->addMonths($months)->timestamp : null, 'billing' => $months ?: 1 ]; } public function store(OrderRequest $request) { $request->validated(); $total = 0; $product_item = []; $relid_data = []; foreach ($request->product as $key => $item) { $product = null; //get product item by type product $relid_data[$key]['type'] = $item['type']; $product = match ((int) $item['type']) { 3 => $this->hostingRepository->find($item['product_id']), 4 => $this->vPSRepository->find($item['product_id']), default => null }; if (!$product) { throw new Exception("Sản phẩm không hợp lệ."); } $message = $product->name; $billing = 0; //Data product item with module auto create $relid_data[$key]['data'] = [ 'customer_id' => $request->customer_id, 'status' => 0, 'name' => $item['domain'] ]; //billing data $billingDetails = $this->calculateBillingDetails($item['billing']); $relid_data[$key]['data'] = array_merge($relid_data[$key]['data'], $billingDetails); //First pay for bill $price_select = $item['price_custom'] ? $item['price_custom'] : $product->price_sale ?? $product->price; $relid_data[$key]['data']['first_payment'] = $price_select * $billingDetails['billing']; //next_pay $relid_data[$key]['data']['next_payment'] = ($item['price_custom'] ?? $product->price) * $billingDetails['billing']; //invoice item $generalCode = Helper::generateUniqueCode(); $product_item[$key] = [ 'customer_id' => $request->customer_id, 'type_id' => $item['type'], 'product_id' => $item['product_id'], 'description' => $message, 'amount' => $price_select, 'billing' => $item['billing'], 'tax' => 1, 'due_date' => Carbon::today()->hour(23)->minute(59)->second(59)->timestamp, 'code' => $generalCode ]; $relid_data[$key]['code'] = $generalCode; if ($item['quantity'] > 1) { for ($i = 1; $i < $item['quantity']; $i++) { $newCode = Helper::generateUniqueCode(); $product_item[] = array_merge($product_item[$key], ['code' => $newCode]); $relid_data[] = array_merge($relid_data[$key], ['code' => $newCode]); } } if ($item['price_custom']) { $total += $item['quantity'] * $item['price_custom']; } else { $price = ($product->price_sale ? $product->price_sale : null) ?? $product->price; $total += $item['quantity'] * $price * $billingDetails['billing'];; } } $order_item = [ 'order_num' => Helper::generateUniqueCode(), 'customer_id' => $request->customer_id, 'date' => Carbon::today()->timestamp, 'invoice_id' => 0, 'discount_id' => $request->discount_id ?? 0, 'amount' => $total + ($total * (10 / 100)), 'payment_id' => $request->payment_id, 'user_id' => auth()->guard('admins')->user()->id, 'status' => $request->status, 'client_ip' => $request->getClientIp() ]; $invoice_data = [ 'date' => Carbon::today()->timestamp, 'due_date' => Carbon::today()->hour(23)->minute(59)->second(59)->timestamp, 'date_paid' => (int)$request->status === 1 ? Carbon::today()->timestamp : null, 'sub_total' => $total, 'tax' => $total * (10 / 100), 'total' => $total + ($total * (10 / 100)), 'payment_id' => $request->payment_id, 'customer_id' => $request->create_invoice ? $request->customer_id : 0, 'status' => $request->status ]; DB::beginTransaction(); try { $invoice = $this->invoiceRepository->create($invoice_data); $product_item = array_map(function ($array) use ($invoice) { $array['invoice_id'] = $invoice->id; return $array; }, $product_item); if ($request->create_invoice) { $order_item['invoice_id'] = $invoice->id; } $order = $this->orderRepository->create($order_item); //append order_id to relid data $relid_data = array_map(function ($array) use ($order) { $array['data']['order_id'] = $order->id; 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 = $this->moduleHostingRepository->create($item['data']); $relid[$code] = $relid_id->id; break; case 4: $item['data']['status'] = 2; $relid_id = $this->moduleVmwareRepository->create($item['data']); $relid[$code] = $relid_id->id; break; } } $product_item = array_filter(array_map(function ($array) use ($relid) { if (isset($relid[$array['code']])) { $array['relid'] = $relid[$array['code']]; unset($array['code']); return $array; } return null; }, $product_item)); $this->invoiceItemRepository->insert($product_item); $last_id = $this->invoiceItemRepository->filter(['limit' => count($product_item)], [], [], ['id'])->pluck('id')->toArray(); $order->orderItem()->sync($last_id); DB::commit(); } catch (Exception $error) { DB::rollBack(); return back()->withErrors($error->getMessage()); } return redirect()->route('administrator.pages.order.edit', ['id' => $order]); } public function create() { $title = 'Add new Order for Customer'; $customer = Customer::select('id', 'fullname')->where('status', 1)->get(); $payment = Payment::select('id', 'name')->where('status', 1)->get(); $discount = Discount::select('id', 'code', 'save', 'type')->where('status', 1)->get(); // $type = Type::select('id', 'name')->where('status', 1)->get(); return view('administrator.pages.order.add', compact('title', 'customer', 'payment', 'discount')); } public function edit(int $id = 0) { $order = $this->orderRepository->findWithRelationships($id, ['orderItem', 'user', 'customer.invoiceItem.type', 'payment', 'discount', 'invoice.invoiceItem']); if (!$order) { return redirect()->route('administrator.pages.order.index')->withErrors('Can\'t find a order by order id #' . $id); } $title = 'View Manage Order'; $order->orderItem->transform(function ($item) { $item->status = $this->invoiceItemRepository->findServiceStatus($item->relid, $item->type_id); return $item; }); return view('administrator.pages.order.edit', compact('title', 'order')); } public function update(int $id, UpdateOrderRequest $request) { $order = $this->orderRepository->findWithRelationships($id, ['invoice', 'orderItem']); if (!$order) { return redirect()->route('administrator.pages.order.index')->withErrors('Invalid request'); } $status = match ($request->action) { "accept" => 1, "cancel" => 2, default => 0 }; try { DB::beginTransaction(); $this->orderRepository->update($id, ['status' => $status]); if ($status === 1 && $request->module == 1) { $jobs = []; $addon = []; $product = 0; foreach ($order->orderItem as $key => $item) { switch ((int) $item->type_id) { case 1: $itemData = $this->addonRepository->find($item->relid); if ($itemData) { $price = match ((int) $item->billing) { 2 => $item->amount / 1, 3 => $item->amount / 3, 4 => $item->amount / 6, 5 => $item->amount / 12, default => 0 }; $addon[strtolower($itemData->name)] = (int) $price / $itemData->price; $product = $item->parent_id; } break; case 3: $hostingServer = $this->moduleHostingServerRepository->get_active(); if ($hostingServer) { $this->moduleHostingRepository->update($item->relid, ['module_server_id' => $hostingServer->first()->id]); $jobs[] = new CreateHostingJobs($item->relid); } break; case 4: $product = $this->moduleVmwareRepository->find($item->relid); if ($product && $product->os_id) { $os = $this->osRepository->findWithRelationships($product->os_id, ['osGroup']); if (! $os || ! $os->osGroup->isNotEmpty()) break; $ip_address = $this->ipAddressRepository->filter([ 'module_host_id' => $os->osGroup->module_host_id, 'status' => 0 ]); if (count($ip_address) > 0) { $this->moduleVmwareRepository->update($item->relid, [ 'module_ipaddress_id' => $ip_address->first()->id, ]); $this->ipAddressRepository->update($ip_address->first()->id, [ 'status' => 1 ]); $jobs[] = new CreateVMJobs($product->id); } } break; default: break; } } if (count($order->orderItem) === count($addon)) { dispatch(new UpgradeVirtualMachine($product, $addon, $order->id))->delay(now()->addSeconds(10)); } if (count($jobs)) { foreach ($jobs as $item) { dispatch($item)->delay(now()->addSeconds(10)); } } } DB::commit(); } catch (Exception $error) { DB::rollBack(); return back()->withErrors($error->getMessage()); } return back()->with('success', 'Order Set to ' . $request->action . ' success'); } public function destroy(Request $request) { $validator = Validator::make($request->all(), [ 'order' => 'numeric|required' ]); if ($validator->fails()) { return back()->withErrors('Can\'t find order'); } $order = Order::with('Invoice', 'Invoice.InvoiceItem')->find($request->order); if (!$order) { return back()->withErrors('Invalid request'); } if ($order->Invoice) { $order->Invoice->delete(); if ($order->Invoice->InvoiceItem->count()) { foreach ($order->Invoice->InvoiceItem->all() as $item) { $item->delete(); } } } $order->delete(); return back()->with('success', 'Delete Success'); } public function datatable(Request $request) { $query = $this->orderRepository->filter( $request->all(), ['payment', 'customer', 'invoice'], [], ['*'], true ); return DataTables::eloquent($query) ->addColumn('order_num', function ($d) { return view('administrator.pages.order.datatable.order_num', ['row' => $d])->render(); }) ->addColumn('date', function ($d) { return view('administrator.pages.order.datatable.date', ['row' => $d])->render(); }) ->addColumn('customer', function ($d) { return view('administrator.pages.order.datatable.customer', ['row' => $d])->render(); }) ->addColumn('payment', function ($d) { return view('administrator.pages.order.datatable.payment', ['row' => $d])->render(); }) ->addColumn('amount', function ($d) { return view('administrator.pages.order.datatable.amount', ['row' => $d])->render(); }) ->addColumn('invoice_status', function ($d) { return view('administrator.pages.order.datatable.invoice_status', ['row' => $d])->render(); }) ->addColumn('status', function ($d) { return view('administrator.pages.order.datatable.status', ['row' => $d])->render(); }) ->addColumn('action', function ($d) { return view('administrator.pages.order.datatable.action', ['row' => $d])->render(); }) ->rawColumns(['order_num', 'date', 'customer', 'payment', 'amount', 'invoice_status', 'status', 'action']) ->make(true); } }