HEX
Server: LiteSpeed
System: Linux s1049.use1.mysecurecloudhost.com 4.18.0-477.27.2.lve.el8.x86_64 #1 SMP Wed Oct 11 12:32:56 UTC 2023 x86_64
User: xedaptot (3356)
PHP: 8.3.31
Disabled: NONE
Upload Files
File: /home/xedaptot/hi.naniguide.com/app/Http/Controllers/Admin/InvoiceController.php
<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Customer;
use App\Models\Subscription;
use App\Models\WebhookEvent;
use Illuminate\Http\Request;
use Stripe\StripeClient;

class InvoiceController extends Controller
{
    public function index(Request $request)
    {
        $search = trim((string) $request->get('q', ''));
        $status = trim((string) $request->get('status', ''));

        $mode = 'stripe';
        $invoices = collect();
        $stripePagination = null;
        $customersByStripeId = collect();
        $subscriptionsByStripeId = collect();
        $events = null;
        $stripeError = null;

        try {
            $stripe = app(StripeClient::class);

            $startingAfter = trim((string) $request->get('starting_after', ''));
            $endingBefore = trim((string) $request->get('ending_before', ''));

            if ($search !== '' && str_starts_with($search, 'in_')) {
                $invoice = $stripe->invoices->retrieve($search, []);
                $invoices = collect([$invoice])->map(fn ($i) => json_decode(json_encode($i), true));
                $stripePagination = [
                    'has_more' => false,
                    'next' => null,
                    'prev' => null,
                ];
            } else {
                $params = [
                    'limit' => 25,
                ];

                if ($status !== '') {
                    $params['status'] = $status;
                }

                if ($search !== '') {
                    if (str_starts_with($search, 'cus_')) {
                        $params['customer'] = $search;
                    } else {
                        $matchingStripeCustomerIds = Customer::query()
                            ->where(function ($q) use ($search) {
                                $q->where('email', 'like', '%' . $search . '%')
                                    ->orWhere('first_name', 'like', '%' . $search . '%')
                                    ->orWhere('last_name', 'like', '%' . $search . '%')
                                    ->orWhere('company_name', 'like', '%' . $search . '%');
                            })
                            ->whereNotNull('stripe_customer_id')
                            ->limit(200)
                            ->pluck('stripe_customer_id')
                            ->values()
                            ->all();

                        if (count($matchingStripeCustomerIds) === 1) {
                            $params['customer'] = $matchingStripeCustomerIds[0];
                        }
                    }
                }

                if ($startingAfter !== '') {
                    $params['starting_after'] = $startingAfter;
                } elseif ($endingBefore !== '') {
                    $params['ending_before'] = $endingBefore;
                }

                $result = $stripe->invoices->all($params);
                $invoices = collect($result->data ?? [])->map(fn ($i) => json_decode(json_encode($i), true));

                $firstId = (string) data_get($invoices->first(), 'id', '');
                $lastId = (string) data_get($invoices->last(), 'id', '');

                $stripePagination = [
                    'has_more' => (bool) ($result->has_more ?? false),
                    'next' => ($lastId !== '' && (bool) ($result->has_more ?? false)) ? $lastId : null,
                    'prev' => $firstId !== '' ? $firstId : null,
                ];
            }

            $stripeCustomerIds = $invoices
                ->map(fn (array $invoice) => data_get($invoice, 'customer'))
                ->filter()
                ->unique()
                ->values();

            $customersByStripeId = Customer::query()
                ->whereIn('stripe_customer_id', $stripeCustomerIds)
                ->get()
                ->keyBy('stripe_customer_id');

            $stripeSubscriptionIds = $invoices
                ->map(fn (array $invoice) => data_get($invoice, 'subscription'))
                ->filter()
                ->unique()
                ->values();

            $subscriptionsByStripeId = Subscription::query()
                ->whereIn('stripe_subscription_id', $stripeSubscriptionIds)
                ->get()
                ->keyBy('stripe_subscription_id');
        } catch (\Throwable $e) {
            $mode = 'events';
            $stripeError = $e->getMessage();
        }

        if ($mode === 'events') {
            $query = WebhookEvent::query()
                ->where('provider', 'stripe')
                ->where('type', 'like', 'invoice.%')
                ->orderByDesc('processed_at')
                ->orderByDesc('created_at');

            if ($status !== '') {
                $query->where('payload->status', $status);
            }

            if ($search !== '') {
                $matchingStripeCustomerIds = Customer::query()
                    ->where(function ($q) use ($search) {
                        $q->where('email', 'like', '%' . $search . '%')
                            ->orWhere('first_name', 'like', '%' . $search . '%')
                            ->orWhere('last_name', 'like', '%' . $search . '%')
                            ->orWhere('company_name', 'like', '%' . $search . '%');
                    })
                    ->whereNotNull('stripe_customer_id')
                    ->limit(200)
                    ->pluck('stripe_customer_id')
                    ->values()
                    ->all();

                $query->where(function ($q) use ($search, $matchingStripeCustomerIds) {
                    $q->where('payload->id', 'like', '%' . $search . '%')
                        ->orWhere('event_id', 'like', '%' . $search . '%');

                    if (count($matchingStripeCustomerIds) > 0) {
                        $q->orWhereIn('payload->customer', $matchingStripeCustomerIds);
                    }
                });
            }

            $events = $query->paginate(25)->withQueryString();

            $stripeCustomerIds = $events->getCollection()
                ->map(fn (WebhookEvent $event) => data_get($event->payload, 'customer'))
                ->filter()
                ->unique()
                ->values();

            $customersByStripeId = Customer::query()
                ->whereIn('stripe_customer_id', $stripeCustomerIds)
                ->get()
                ->keyBy('stripe_customer_id');

            $stripeSubscriptionIds = $events->getCollection()
                ->map(fn (WebhookEvent $event) => data_get($event->payload, 'subscription'))
                ->filter()
                ->unique()
                ->values();

            $subscriptionsByStripeId = Subscription::query()
                ->whereIn('stripe_subscription_id', $stripeSubscriptionIds)
                ->get()
                ->keyBy('stripe_subscription_id');
        }

        return view('admin.invoices.index', [
            'mode' => $mode,
            'invoices' => $invoices,
            'stripePagination' => $stripePagination,
            'stripeError' => $stripeError,
            'events' => $events,
            'customersByStripeId' => $customersByStripeId,
            'subscriptionsByStripeId' => $subscriptionsByStripeId,
            'search' => $search,
            'status' => $status,
        ]);
    }

    public function show(Request $request, string $invoice)
    {
        $mode = 'stripe';
        $invoiceId = $invoice;
        $invoiceData = null;
        $event = null;
        $stripeError = null;

        try {
            $stripe = app(StripeClient::class);
            $stripeInvoice = $stripe->invoices->retrieve($invoiceId, []);
            $invoiceData = json_decode(json_encode($stripeInvoice), true);
        } catch (\Throwable $e) {
            $mode = 'events';
            $stripeError = $e->getMessage();
        }

        if ($mode === 'events') {
            $event = WebhookEvent::query()
                ->where('provider', 'stripe')
                ->where('type', 'like', 'invoice.%')
                ->where('payload->id', $invoiceId)
                ->orderByDesc('processed_at')
                ->orderByDesc('created_at')
                ->first();

            if ($event) {
                $invoiceData = $event->payload;
            }
        }

        abort_unless(is_array($invoiceData), 404);

        $stripeCustomerId = data_get($invoiceData, 'customer');
        $stripeSubscriptionId = data_get($invoiceData, 'subscription');

        $customer = null;
        if (is_string($stripeCustomerId) && $stripeCustomerId !== '') {
            $customer = Customer::query()->where('stripe_customer_id', $stripeCustomerId)->first();
        }

        $subscription = null;
        if (is_string($stripeSubscriptionId) && $stripeSubscriptionId !== '') {
            $subscription = Subscription::query()->where('stripe_subscription_id', $stripeSubscriptionId)->first();
        }

        return view('admin.invoices.show', [
            'mode' => $mode,
            'invoiceId' => $invoiceId,
            'invoice' => $invoiceData,
            'event' => $event,
            'customer' => $customer,
            'subscription' => $subscription,
            'stripeError' => $stripeError,
        ]);
    }
}