HEX
Server: Apache/2.4.41 (Ubuntu)
System: Linux ip-172-31-42-149 5.15.0-1084-aws #91~20.04.1-Ubuntu SMP Fri May 2 07:00:04 UTC 2025 aarch64
User: ubuntu (1000)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: /var/www/vhost/disk-apps/qas.sports-crowd.com/app/Http/Controllers/Api/FlashTicketApiController.php
<?php

namespace App\Http\Controllers\Api;

use App\Core\Ticket\TicketStatusEnum;
use App\Http\Controllers\Controller;
use App\FlashTicketConfiguration;
use App\Http\Controllers\FlashTicketController;
use App\Seat;
use App\Ticket;
use App\TicketUserBlock;
use App\Zone;
use Illuminate\Http\Request;
use Illuminate\Database\Eloquent\Builder;
use App\Http\Controllers\MassiveFansController;
use App\Http\Controllers\ServiceChargeController;
use App\Http\Controllers\TicketsController;
use Illuminate\Support\Facades\Auth;

class FlashTicketApiController extends Controller
{

    public function validateUserTickets($ticketType, $matchEventId, $userId = null)
    {
        if (!$userId) {
            $userId = Auth::user()->id;
        }
        $tickets = new TicketsController();
        $sumTicketsBlocks = $tickets->getSumBlocksAndTicketsByUser($ticketType, $userId, $matchEventId);
        $controller = new FlashTicketController();
        $maximum = $controller->getMaximumTicketsToBuy($matchEventId);

        // Valida el numero maximo de boletas que puede comprar el usuario.
        if ($ticketType == 1 && $sumTicketsBlocks >= $maximum) {
            return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "validateUserTickets", "m" => __('messages.error_validation_16', ['number' => 0])));
        }
        return response(array("r" => true, "maximum" => $maximum, "purchased" => $sumTicketsBlocks));
    }

    public function getTribunesParent($matchEventId, Request $request)
    {
        $flashTicket = FlashTicketConfiguration::select('flash_ticket_configuration.id', 'price', 'special_price', 'maximum_number_ballots', 'image', 'show_image', 'description', 'match_event_id', 'zone_id', 'coupon', 'apply_coupon_type')
            ->with('zone')
            ->where([['active', 1], ['match_event_id', $matchEventId]])
            ->whereIn('show_in', ['all', 'app']);
        if (!$flashTicket->count()) {
            $flashTicket = FlashTicketConfiguration::select('flash_ticket_configuration.id', 'price', 'special_price', 'maximum_number_ballots', 'image', 'show_image', 'description', 'zone_id', 'coupon', 'apply_coupon_type')
                ->with('zone')
                ->where('active', 1)
                ->whereIn('show_in', ['all', 'app'])
                ->whereNull('match_event_id');
        }
        // Validacion de cupones
        $flashTicketCoupon = clone $flashTicket;
        $flashTicketCoupon = $flashTicketCoupon->leftjoin('flash_ticket_configuration_tags', 'flash_ticket_configuration_tags.flash_ticket_id', '=', 'flash_ticket_configuration.id')
            ->where('apply_coupon_type', '!=', 'tribune')
            ->whereNull('flash_ticket_configuration_tags.id');
        if (isset($request->availableCupon) && $request->availableCupon == 'true') {
            $couponCode = $request->cuponCode;
            $flashTicketCoupon = $flashTicketCoupon->orWhere(function ($q) use ($couponCode, $matchEventId) {
                $q->where([['active', 1], ['match_event_id', $matchEventId]])
                    ->whereIn('show_in', ['all', 'app'])->where('coupon', 'LIKE', '%' . $couponCode . '%');
            });
        }
        $flashTicketCoupon = $flashTicketCoupon->get();

        // Validacion de segmentación
        $userId = Auth::user()->id;
        $flashTicket->leftjoin('flash_ticket_configuration_tags', 'flash_ticket_configuration_tags.flash_ticket_id', '=', 'flash_ticket_configuration.id')
            ->leftjoin('user_tags', 'user_tags.tag_id', '=', 'flash_ticket_configuration_tags.tag_id')
            ->leftjoin('tags', function ($join) {
                $join->on('tags.id', '=', 'user_tags.tag_id')->where('tags.active', 1);
            })
            ->where(function ($q) use ($userId) {
                $q->where('user_tags.user_id', $userId)->orWhere(function ($q1) {
                    $q1->whereNull('flash_ticket_configuration_tags.id')->where('flash_ticket_configuration.apply_coupon_type', '!=', 'tribune');
                });
            });
        $flashTicket = $flashTicket->get();
        $flashTicket = $flashTicket->merge($flashTicketCoupon);
        $flashTicket = $flashTicket->unique('id');
        $flashTicket = $flashTicket->values()->all();

        $controller = new ServiceChargeController();
        foreach ($flashTicket as $item) {
            if ($controller->validateServiceCharge()) {
                $request = new Request([
                    'services'      => 'ticket',
                    'match_events'  => $matchEventId,
                    'zones'         => [$item->zone_id],
                ]);
                $serviceCharge = $controller->calculateServiceCharge($request);
                $item->service_charge = $serviceCharge;
            }
            $item->availabled = $this->getAvailabledTicketsToBuy($matchEventId, $item->zone_id, $item->maximum_number_ballots);
            $item->quantity = 0;
        }

        $validateCouponexits = FlashTicketConfiguration::select('flash_ticket_configuration.id')
            ->where([['active', 1], ['match_event_id', $matchEventId]])
            ->whereIn('show_in', ['all', 'app'])
            ->where('apply_coupon_type', '!=', 'none')
            ->where('coupon', '!=', null)
            ->count() > 0;

        return response()->json(['flashTicket' => $flashTicket, 'validateCouponexits' => $validateCouponexits], 200);
    }

    public function validateSeatsAvailableByCapacity(Request $request)
    {
        $response = array();
        $request = $request->all();
        foreach ($request as $zone) {
            $zone['seats'] = 0;
            $status = $this->validateChildZoneSeats(
                [
                    'zone' => $zone,
                    'zone_id' => $zone['zone_id'],
                    'quantity' => $zone['quantity'],
                    'match_event_id' => $zone['match_event_id'],
                    'salable_capacity' => $this->getMaximumSalableCapacityZones(array($zone['zone_id']), $zone['match_event_id'])
                ]
            );
            if ($status) {
                $response[] = $status;
            } else {
                $response[] = $zone;
            }
        }
        return response()->json($response, 200);
    }

    private function validateChildZoneSeats(array $params)
    {
        $zone = $params['zone'];
        $zoneId = $params['zone_id'];
        $quantity = $params['quantity'];
        $match_event_id = $params['match_event_id'];
        $salable_capacity = $params['salable_capacity'];

        $seatsZone = Seat::where('zone_id', $zoneId)->where('active', 1)->count();
        if ($seatsZone > 0) {
            if ($this->salableCapacityZone($match_event_id, array($zoneId), $quantity, $salable_capacity)) {
                $massiveFansController = new MassiveFansController();
                $seats = $massiveFansController->getSeatsAvailableFromLocationAndEvent(
                    [
                        'zone_id' => $zoneId,
                        'quantity' => $quantity,
                        'match_event_id' => $match_event_id
                    ]
                );
                if (count($seats) > 0 && count($seats) >= $quantity) {
                    $zone['seats'] = $seats;
                    return $zone;
                }
            } else {
                return $zone;
            }
        } else {
            $childZones = Zone::where('zone_id', $zoneId)->pluck('id');
            foreach ($childZones as $childZone) {
                $status = $this->validateChildZoneSeats(
                    [
                        'zone' => $zone,
                        'zone_id' => $childZone,
                        'quantity' => $quantity,
                        'match_event_id' => $match_event_id,
                        'salable_capacity' => $salable_capacity
                    ]
                );
                if ($status) {
                    return $status;
                    break;
                }
            }
        }
        return false;
    }

    private function getMaximumSalableCapacityZones($zones, $match_event_id)
    {
        $flashTicket = FlashTicketConfiguration::where('active', 1)
            ->whereIn('zone_id', $zones)
            ->when($match_event_id, function ($query) use ($match_event_id) {
                return $query->where('match_event_id', $match_event_id);
            })
            ->first();
        if (!$flashTicket) {
            $flashTicket = FlashTicketConfiguration::where('active', 1)
                ->whereIn('zone_id', $zones)
                ->first();
        }
        return $flashTicket ? $flashTicket->salable_capacity : 0;
    }

    private function salableCapacityZone($match_event_id, $zones, $quantity, $salable_capacity)
    {
        $tickets = Ticket::where('match_event_id', $match_event_id)
            ->whereHas('seat', function (Builder $query) use ($zones) {
                $query->whereIn('zone_id', $zones);
            })
            ->whereIn('ticket_status_id', [TicketStatusEnum::PURCHASED, TicketStatusEnum::CREATED])
            ->count();
        $blocks = TicketUserBlock::where('match_event_id', $match_event_id)
            ->whereHas('seat', function (Builder $query) use ($zones) {
                $query->whereIn('zone_id', $zones);
            })->count();

        if ($tickets + $blocks >= $salable_capacity) {
            return false;
        }
        if ($quantity !== 0 && $quantity + $tickets + $blocks > $salable_capacity) {
            return false;
        }
        return true;
    }

    private function getAvailabledTicketsToBuy($matchEventId, $zoneId, $maximum)
    {
        $zones = Zone::where('zone_id', $zoneId)->pluck('id');
        $zones = [$zoneId, ...$zones];
        $userId = Auth::user()->id;
        $tickets = Ticket::where('match_event_id', $matchEventId)->where('user_id', $userId)
            ->whereHas('seat', function (Builder $query) use ($zones) {
                $query->whereIn('zone_id', $zones);
            })
            ->whereIn('ticket_status_id', [TicketStatusEnum::PURCHASED, TicketStatusEnum::CREATED])
            ->count();
        $blocks = TicketUserBlock::where('match_event_id', $matchEventId)->where('user_id', $userId)
            ->whereHas('seat', function (Builder $query) use ($zones) {
                $query->whereIn('zone_id', $zones);
            })->count();

        $availabled = $maximum - ($tickets + $blocks);
        return $availabled;
    }

    public function validateACoupon($matchEventId, $coupon)
    {
        $flashTicket = FlashTicketConfiguration::where([['active', 1], ['match_event_id', $matchEventId]])
            ->where('coupon', 'LIKE', '%' . $coupon . '%')
            ->whereIn('show_in', ['all', 'app'])
            ->first();
        if (!$flashTicket) {
            return response()->json([
                'message' => 'El cupón no existe o no está activo',
                'status' => false
            ], 200);
        }

        return response()->json([
            'message' => 'El cupón es válido',
            'status' => true
        ], 200);
    }
}