get('per_page', 15), 100); $query = $this->orderRepository->filter( $request->all(), ['payment', 'customer', 'invoice'], [], ['*'], true ); return response()->json([ 'error' => false, 'data' => [ 'items' => OrderResource::collection($query->get())->resolve(), 'total' => $query->count(), 'per_page' => $perPage, ], ]); } public function datatable(Request $request): JsonResponse { $query = $this->orderRepository->filter( $request->all(), ['payment', 'customer', 'invoice'], [], ['*'], true ); return DataTables::eloquent($query) ->addColumn('order_num', fn($d) => $d->order_num) ->addColumn('date', fn($d) => $d->date) ->addColumn('customer', fn($d) => $d->customer?->fullname) ->addColumn('payment', fn($d) => $d->payment?->name) ->addColumn('amount', fn($d) => $d->amount) ->addColumn('invoice_status', fn($d) => $d->invoice?->status) ->addColumn('status', fn($d) => $d->status) ->addColumn('action', fn($d) => $d->id) ->rawColumns(['order_num', 'date', 'customer', 'payment', 'amount', 'invoice_status', 'status', 'action']) ->make(true); } public function store(OrderRequest $request): JsonResponse { $request->validated(); $total = 0; $product_item = []; $relid_data = []; foreach ($request->product as $key => $item) { $product = null; $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) { return response()->json([ 'error' => true, 'message' => "Invalid product." ], 422); } $message = $product->name; $relid_data[$key]['data'] = [ 'customer_id' => $request->customer_id, 'status' => 0, 'name' => $item['domain'] ]; $billingDetails = $this->calculateBillingDetails($item['billing']); $relid_data[$key]['data'] = array_merge($relid_data[$key]['data'], $billingDetails); $price_select = $item['price_custom'] ?? $product->price_sale ?? $product->price; $relid_data[$key]['data']['first_payment'] = $price_select * $billingDetails['billing']; $relid_data[$key]['data']['next_payment'] = ($item['price_custom'] ?? $product->price) * $billingDetails['billing']; $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]); } } $total += $item['quantity'] * ($item['price_custom'] ?? ($product->price_sale ?? $product->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('admin')->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); $relid_data = array_map(function ($array) use ($order) { $array['data']['order_id'] = $order->id; return $array; }, $relid_data); $relid = []; 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(); return response()->json([ 'error' => false, 'message' => 'Order created successfully', 'data' => new OrderResource($order) ], 201); } catch (\Exception $e) { DB::rollBack(); return response()->json([ 'error' => true, 'message' => $e->getMessage() ], 500); } } public function show(int $id): JsonResponse { $order = $this->orderRepository->findWithRelationships( $id, ['orderItem', 'user', 'customer.invoiceItem.type', 'payment', 'discount', 'invoice.invoiceItem'] ); if (!$order) { return response()->json([ 'error' => true, 'message' => "Can't find order by ID #" . $id ], 404); } return response()->json([ 'error' => false, 'data' => new OrderResource($order) ]); } public function update(int $id, UpdateOrderRequest $request): JsonResponse { $order = $this->orderRepository->findWithRelationships($id, ['invoice', 'orderItem']); if (!$order) { return response()->json([ 'error' => true, 'message' => "Can't find order by ID #" . $id ], 404); } $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; } } if (count($order->orderItem) === count($addon)) { dispatch(new UpgradeVirtualMachine($product, $addon, $order->id))->delay(now()->addSeconds(10)); } foreach ($jobs as $item) { dispatch($item)->delay(now()->addSeconds(10)); } } DB::commit(); return response()->json([ 'error' => false, 'message' => 'Order updated successfully' ]); } catch (\Exception $e) { DB::rollBack(); return response()->json([ 'error' => true, 'message' => $e->getMessage() ], 500); } } public function destroy(int $id): JsonResponse { $order = Order::with('Invoice', 'Invoice.InvoiceItem')->find($id); if (!$order) { return response()->json([ 'error' => true, 'message' => "Can't find order by ID #" . $id ], 404); } try { DB::beginTransaction(); if ($order->Invoice) { $order->Invoice->delete(); if ($order->Invoice->InvoiceItem->count()) { foreach ($order->Invoice->InvoiceItem->all() as $item) { $item->delete(); } } } $order->delete(); DB::commit(); return response()->json([ 'error' => false, 'message' => 'Order deleted successfully' ]); } catch (\Exception $e) { DB::rollBack(); return response()->json([ 'error' => true, 'message' => $e->getMessage() ], 500); } } public function accept(int $id): JsonResponse { $order = $this->orderRepository->findWithRelationships($id, ['invoice', 'orderItem']); if (!$order) { return response()->json([ 'error' => true, 'message' => "Can't find order by ID #" . $id ], 404); } try { DB::beginTransaction(); $this->orderRepository->update($id, ['status' => 1]); DB::commit(); return response()->json([ 'error' => false, 'message' => 'Order accepted successfully' ]); } catch (\Exception $e) { DB::rollBack(); return response()->json([ 'error' => true, 'message' => $e->getMessage() ], 500); } } public function cancel(int $id): JsonResponse { $order = $this->orderRepository->find($id); if (!$order) { return response()->json([ 'error' => true, 'message' => "Can't find order by ID #" . $id ], 404); } try { DB::beginTransaction(); $this->orderRepository->update($id, ['status' => 2]); DB::commit(); return response()->json([ 'error' => false, 'message' => 'Order cancelled successfully' ]); } catch (\Exception $e) { DB::rollBack(); return response()->json([ 'error' => true, 'message' => $e->getMessage() ], 500); } } private function calculateBillingDetails($billing): array { $months = match ($billing) { 2 => 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 ]; } }