<?php namespace App\Http\Controllers\Admin; use App\Helpers\Helper; use App\Http\Controllers\Controller; use App\Http\Controllers\Customer\PaymentController; use App\Library\Tool; use App\Models\Invoices; use App\Models\Keywords; use App\Models\PhoneNumbers; use App\Models\Senderid; use App\Models\Subscription; use App\Models\SubscriptionLog; use App\Models\SubscriptionTransaction; use App\Models\User; use App\Notifications\SubscriptionPurchase; use Carbon\Carbon; use Exception; use Illuminate\Auth\Access\AuthorizationException; use Illuminate\Contracts\Foundation\Application; use Illuminate\Contracts\View\Factory; use Illuminate\Contracts\View\View; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use JetBrains\PhpStorm\NoReturn; class InvoiceController extends Controller { /** * view invoices * * @return Application|Factory|View * @throws AuthorizationException */ public function index(): Factory|View|Application { $this->authorize('view invoices'); $breadcrumbs = [ ['link' => url(config('app.admin_path')."/dashboard"), 'name' => __('locale.menu.Dashboard')], ['link' => url(config('app.admin_path')."/dashboard"), 'name' => __('locale.menu.Reports')], ['name' => __('locale.menu.All Invoices')], ]; return view('admin.Invoices.index', compact('breadcrumbs')); } /** * @param Request $request * * @return void */ #[NoReturn] public function search(Request $request): void { $columns = [ 0 => 'responsive_id', 1 => 'uid', 2 => 'uid', 3 => 'created_at', 4 => 'id', 5 => 'type', 6 => 'description', 7 => 'amount', 8 => 'status', 9 => 'user_id', 10 => 'actions', ]; $totalData = Invoices::count(); $totalFiltered = $totalData; $limit = $request->input('length'); $start = $request->input('start'); $order = $columns[$request->input('order.0.column')]; $dir = $request->input('order.0.dir'); if (empty($request->input('search.value'))) { $invoices = Invoices::offset($start) ->limit($limit) ->orderBy($order, $dir) ->get(); } else { $search = $request->input('search.value'); $invoices = Invoices::whereLike(['uid', 'type', 'created_at', 'description', 'amount', 'status', 'user.first_name', 'user.last_name'], $search) ->offset($start) ->limit($limit) ->orderBy($order, $dir) ->get(); $totalFiltered = Invoices::whereLike(['uid', 'type', 'created_at', 'description', 'amount', 'status', 'user.first_name', 'user.last_name'], $search)->count(); } $data = []; if ( ! empty($invoices)) { foreach ($invoices as $invoice) { $show = route('admin.invoices.view', $invoice->uid); $customer_profile = route('admin.customers.show', $invoice->user->uid); $customer_name = $invoice->user->displayName(); $user_id = "<a href='$customer_profile' class='text-primary mr-1'>$customer_name</a>"; $invoice_number = "<a href='$show' class='text-primary fw-bold'>#$invoice->id</a>"; $nestedData['responsive_id'] = ''; $nestedData['uid'] = $invoice->uid; $nestedData['id'] = $invoice_number; $nestedData['user_id'] = $user_id; $nestedData['avatar'] = route('admin.customers.avatar', $invoice->user->uid); $nestedData['email'] = $invoice->user->email; $nestedData['created_at'] = Tool::customerDateTime($invoice->created_at); $nestedData['type'] = strtoupper($invoice->type); $nestedData['description'] = str_limit($invoice->description, 35); $nestedData['amount'] = Tool::format_price($invoice->amount, $invoice->currency->format); $nestedData['status'] = $invoice->getStatus(); $nestedData['get_status'] = $invoice->status; $nestedData['status_locale'] = __('locale.labels.approve'); $nestedData['edit'] = $show; $nestedData['delete'] = $invoice->uid; $data[] = $nestedData; } } $json_data = [ "draw" => intval($request->input('draw')), "recordsTotal" => intval($totalData), "recordsFiltered" => intval($totalFiltered), "data" => $data, ]; echo json_encode($json_data); exit(); } /** * view invoice * * @param Invoices $invoice * * @return Factory|View|Application */ public function view(Invoices $invoice): Factory|View|Application { $breadcrumbs = [ ['link' => url(config('app.admin_path')."/dashboard"), 'name' => __('locale.menu.Dashboard')], ['link' => url(config('app.admin_path')."/invoices"), 'name' => __('locale.menu.All Invoices')], ['name' => __('locale.labels.invoice')], ]; return view('admin.Invoices.view', compact('breadcrumbs', 'invoice')); } /** * print invoice * * @param Invoices $invoice * * @return Application|Factory|View */ public function print(Invoices $invoice): View|Factory|Application { $pageConfigs = ['pageHeader' => false]; return view('admin.Invoices.print', compact('invoice', 'pageConfigs')); } /** * @param Invoices $invoice * * @return JsonResponse * @throws Exception */ public function destroy(Invoices $invoice): JsonResponse { if (config('app.stage') == 'demo') { return response()->json([ 'status' => 'error', 'message' => 'Sorry! This option is not available in demo mode', ]); } if ( ! $invoice->delete()) { return response()->json([ 'status' => 'error', 'message' => __('locale.exceptions.something_went_wrong'), ]); } return response()->json([ 'status' => 'success', 'message' => 'Invoice was deleted successfully.', ]); } /** * batch actions * * @param Request $request * * @return JsonResponse */ public function batchAction(Request $request): JsonResponse { if (config('app.stage') == 'demo') { return response()->json([ 'status' => 'error', 'message' => 'Sorry! This option is not available in demo mode', ]); } $ids = $request->get('ids'); if (Invoices::whereIn('uid', $ids)->delete()) { return response()->json([ 'status' => 'success', 'message' => __('locale.subscription.invoices_deleted'), ]); } return response()->json([ 'status' => 'error', 'message' => __('locale.exceptions.something_went_wrong'), ]); } public function approve(Invoices $invoice) { $data = explode("|", $invoice->transaction_id); $paymentController = new PaymentController(); if (is_array($data) && count($data) == 2) { switch ($data[0]) { case 'top_up': $user = User::find($invoice->user_id); if ($user->sms_unit != '-1') { $user->sms_unit += $data['1']; $user->save(); } $subscription = $user->customer->activeSubscription(); $transaction = $subscription->addTransaction(SubscriptionTransaction::TYPE_SUBSCRIBE, [ 'status' => SubscriptionTransaction::STATUS_SUCCESS, 'title' => 'Add '.$data['1'].' sms units', 'amount' => $data['1'].' sms units', ]); $invoice->update([ 'status' => 'paid', 'transaction_id' => $transaction->uid, ]); return response()->json([ 'status' => 'success', 'message' => 'Invoice marked as paid', ]); case 'sender_id': $senderid = Senderid::findByUid($data[1]); $current = Carbon::now(); $senderid->validity_date = $current->add($senderid->frequency_unit, $senderid->frequency_amount); $senderid->status = 'active'; $senderid->save(); $paymentController->createNotification('senderid', $senderid->sender_id, User::find($senderid->user_id)->displayName()); $invoice->update([ 'status' => 'paid', 'transaction_id' => $senderid->uid, ]); return response()->json([ 'status' => 'success', 'message' => 'Invoice marked as paid', ]); case 'number': $number = PhoneNumbers::findByUid($data[1]); $current = Carbon::now(); $number->validity_date = $current->add($number->frequency_unit, $number->frequency_amount); $number->status = 'assigned'; $number->save(); $paymentController->createNotification('number', $number->number, User::find($number->user_id)->displayName()); $invoice->update([ 'status' => 'paid', 'transaction_id' => $number->uid, ]); return response()->json([ 'status' => 'success', 'message' => 'Invoice marked as paid', ]); case 'keyword': $keyword = Keywords::findByUid($data[1]); $current = Carbon::now(); $keyword->validity_date = $current->add($keyword->frequency_unit, $keyword->frequency_amount); $keyword->status = 'assigned'; $keyword->save(); $paymentController->createNotification('keyword', $keyword->keyword_name, User::find($keyword->user_id)->displayName()); $invoice->update([ 'status' => 'paid', 'transaction_id' => $keyword->uid, ]); case 'subscription': $subscription = Subscription::findByUid($data[1]); //set active subscription $subscription->setActive(); // add transaction $subscription->addTransaction(SubscriptionTransaction::TYPE_SUBSCRIBE, [ 'end_at' => $subscription->end_at, 'current_period_ends_at' => $subscription->current_period_ends_at, 'status' => SubscriptionTransaction::STATUS_SUCCESS, 'title' => trans('locale.subscription.subscribed_to_plan', ['plan' => $subscription->plan->getBillableName()]), 'amount' => $subscription->plan->getBillableFormattedPrice(), ]); // add log $subscription->addLog(SubscriptionLog::TYPE_ADMIN_APPROVED, [ 'plan' => $subscription->plan->getBillableName(), 'price' => $subscription->plan->getBillableFormattedPrice(), ]); sleep(1); // add log $subscription->addLog(SubscriptionLog::TYPE_SUBSCRIBED, [ 'plan' => $subscription->plan->getBillableName(), 'price' => $subscription->plan->getBillableFormattedPrice(), ]); $invoice->update([ 'status' => 'paid', 'transaction_id' => $subscription->uid, ]); $user = User::find($invoice->user_id); if ($user->sms_unit == null || $user->sms_unit == '-1' || $subscription->plan->getOption('sms_max') == '-1') { $user->sms_unit = $subscription->plan->getOption('sms_max'); } else { if ($subscription->plan->getOption('add_previous_balance') == 'yes') { $user->sms_unit += $subscription->plan->getOption('sms_max'); } else { $user->sms_unit = $subscription->plan->getOption('sms_max'); } } $user->save(); if (Helper::app_config('subscription_notification_email')) { $admin = User::find(1); $admin->notify(new SubscriptionPurchase(route('admin.invoices.view', $invoice->uid))); } if ($user->customer->getNotifications()['subscription'] == 'yes') { $user->notify(new SubscriptionPurchase(route('customer.invoices.view', $invoice->uid))); } return response()->json([ 'status' => 'success', 'message' => 'Invoice marked as paid', ]); default: return response()->json([ 'status' => 'error', 'message' => __('locale.exceptions.something_went_wrong'), ]); } } return response()->json(['status' => 'error', 'message' => __('locale.exceptions.something_went_wrong'),]); } }