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/MassiveFansController.php
<?php

namespace App\Http\Controllers;

use App\Core\Payment\PaymentStatusEnum;
use App\Core\Ticket\StageTypesEnum;
use App\Core\Ticket\TicketNotificationEnum;
use App\Core\Ticket\TicketOriginEnum;
use App\Core\Ticket\TicketStatusEnum;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use App\TicketType;
use App\MatchEvent;
use App\Seat;
use App\TicketMain;
use App\MatchEventZonePrice;
use App\Zone;
use App\Http\Controllers\Imports\FansImport;
use App\Http\Controllers\Exports\ReportFanst;
use App\Http\Controllers\TicketsController;
use App\MatchEventStage;
use App\Parameter;
use App\Ticket;
use Excel;
use DB;
use Exception;
use Illuminate\Support\Facades\Auth;
use stdClass;

class MassiveFansController extends Controller
{
    private $ticketsController;

    public function __construct()
    {
        $this->ticketsController = new TicketsController();
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $ticket_type    = TicketType::select('id', 'name')->where('active', true)->get();
        $match_event    = MatchEvent::select('id', 'name')->where('active', true)->get();
        $stadiumsZone   = Zone::where('active', 1)->whereNull('zone_id')->pluck('id');
        $mainZones      = Zone::select('id', 'name')->where('active', 1)->whereIn('zone_id', $stadiumsZone)->get();

        return view('massive_fans.fans')->with('ticket_type', $ticket_type)
            ->with('match_event', $match_event)
            ->with('main_zones', $mainZones);
    }

    public function vista($view)
    {
        return view($view);
    }

    public function export()
    {
        return Excel::download(new ReportFanst, trans('messages.fans.title_12') . '.xlsx');
    }

    public function import(Request $request)
    {
        try {
            $file = new FansImport;
            $file->request = $request;
            Excel::import($file, $request->importFans);
            return array('r' => true, 'd' => $file->answer, 'm' => trans('messages.screen_products_tag45') . ' ');
        } catch (\Exception $e) {
            return array('r' => false, 'm' => trans('messages.screen_products_tag46') . $request->name_file . "  \n" . $e->getMessage());
        }
    }

    public function ajaxGetSubzonesFromMainZone($zone_id, $match_event_id = null)
    {
        $zones = Zone::select('id', 'name')
            ->where('zone_id', $zone_id)
            ->where('is_saleable', true)
            ->where('salable_capacity', '>', 0);

        /*
        HABILITAR CUANDO SE ESTABLEZCA UN FLAG PARA VALIDAR REGLAS SEGUN WEB O MOVIL o AMBAS
        if ($match_event_id) {
            $rules = MatchEventStage::where('match_event_id', $match_event_id)->get();
            if (count($rules) > 0) {
                $zonesRules = array();
                foreach ($rules as $rule) {
                    // Bloqueo por zona
                    if ($rule->stage_type_id == StageTypesEnum::BLOCK_TRIBUNE) {
                        if ($rule->zone_id == $zone_id) {
                            return [];
                        }
                        $zonesRules[] = $rule->zone_id;
                    }
                }
                if (count($zonesRules) > 0) {
                    $zones->whereNotIn('id', $zonesRules);
                }
            }
        } 
        */

        return $zones->get();
    }

    public function ajaxGetPriceForZoneInMatch($zone_id, $match_event_id)
    {
        return MatchEventZonePrice::select('id', 'price', 'price_suscription')
            ->where('zone_id', $zone_id)
            ->where('match_event_id', $match_event_id)
            ->first();
    }

    public function importRandom(Request $request)
    {
        try {
            DB::beginTransaction();
            $request->validate([
                'quantity' => 'required|integer|min:1',
                'user_id' => 'required|exists:users,id',
                'zone_id' => 'required|exists:zones,id',
                'match_event_id' => 'required|exists:match_events,id',
                'ticket_type_id' => 'required|exists:ticket_types,id',
                'price' => 'required|numeric|min:0'
            ]);

            return $this->generateRamdomTickets(
                [
                    'quantity' => $request->quantity,
                    'user_id' => $request->user_id,
                    'zone_id' => $request->zone_id,
                    'match_event_id' => $request->match_event_id,
                    'ticket_type_id' => $request->ticket_type_id,
                    'price' => $request->price,
                    'validate_rules' => true,
                ]
            );
        } catch (Exception $e) {
            DB::rollback();
            return array('r' => false, 'd' => null, 'm' => 'No se pudo importar las boletas: ' . $e->getMessage());
        }
    }

    public function generateRamdomTickets(array $params)
    {
        $quantity         = $params['quantity'] ?? 1;
        $user_id          = $params['user_id'] ?? null;
        $zone_id          = $params['zone_id'] ?? null;
        $match_event_id   = $params['match_event_id'] ?? null;
        $ticket_type_id   = $params['ticket_type_id'] ?? null;
        $price            = $params['price'] ?? 0;
        $ticket_main_id   = $params['ticket_main_id'] ?? null;
        $special_text     = $params['special_text'] ?? null;
        $sendEmail        = $params['send_email'] ?? true;
        $validateRules    = $params['validate_rules'] ?? false;

        $sellerUserId = Auth::user()->id;

        if ($ticket_main_id) {
            $ticket_main = TicketMain::where('id', $ticket_main_id)->first();
        } else {
            $ticket_main = new TicketMain;
            $ticket_main->origin = TicketOriginEnum::WEB;
            $ticket_main->subtotal = 0;
            $ticket_main->service_charge = 0;
            $ticket_main->total = 0;
            $ticket_main->payment_attempts = 0;
            $ticket_main->payment_state = PaymentStatusEnum::CONFIRMED;
            $ticket_main->pin = $this->gen_uid();
            $ticket_main->seller_user_id = $sellerUserId;
            $ticket_main->save();

            $ticket_main->payment_reference = strtoupper(hash("md5", (string) $ticket_main->id)) . '_' . $ticket_main->pin;
            $ticket_main->update();
        }

        $seats = $this->getSeatsAvailableFromLocationAndEvent(
            [
                'zone_id' => $zone_id,
                'quantity' => $quantity,
                'match_event_id' => $match_event_id,
                'validate_rules' => $validateRules
            ]
        );
        if (!count($seats)) {
            DB::rollback();
            return array('r' => false, 'd' => null, 'm' => 'No se ha encontrado la cantidad suficiente de sillas disponibles, revise el aforo vendible.');
        }

        $subtotalSumTickets = 0;
        $code_tickets_created = "";
        $createdTickets = [];

        foreach ($seats as $seat) {
            $subtotalSumTickets = $subtotalSumTickets + $price;
            $ticket = $this->ticketsController->createTicket(
                [
                    'seat_id' => $seat->id,
                    'match_event_id' => $match_event_id,
                    'user_id' => $user_id,
                    'ticket_type_id' => $ticket_type_id,
                    'ticket_main_id' => $ticket_main->id,
                    'price' => $price,
                    'is_from_massive' => true,
                    'special_text' => $special_text,
                    'is_an_email_sent' => !$sendEmail
                ]
            );
            if (!$ticket instanceof \Illuminate\Database\Eloquent\Model) {
                if (array_key_exists('r', $ticket)) {
                    if ($ticket['r'] == false) {
                        DB::rollback();
                        return array('r' => false, 'd' => $ticket['data'], 'm' => $ticket['m']);
                    }
                }
            }

            $code_tickets_created = $code_tickets_created . "-" . $ticket->code_ticket . "\n ";
            array_push($createdTickets, $ticket->code_ticket);
        }

        $ticket_main->user_id_log = $user_id;
        $ticket_main->ticket_notification = $sendEmail ? TicketNotificationEnum::PENDING : TicketNotificationEnum::SKIP;
        if ($ticket_main->subtotal != $subtotalSumTickets) {
            $ticket_main->subtotal = $subtotalSumTickets;
            $ticket_main->total = $ticket_main->subtotal + $ticket_main->service_charge;
        }
        $ticket_main->update();

        DB::commit();

        if ($ticket_main && $sellerUserId) {
            $this->registerLog($sellerUserId, 'Importacion boleteria masiva ', json_encode($ticket_main), "Create", 'Boletería masiva');
        }

        $this->ticketsController->dispatchTicketProcesses($ticket_main->id);

        return array('r' => true, 'd' => $createdTickets, 'm' => "Transacción #" . $ticket_main->id . " procesada. \nTickets Generados: \n " . $code_tickets_created);
    }

    public function resendListEmailTickets(Request $request)
    {
        $userId = $request->user_id;
        $ticketTypeId = $request->ticket_type_id;
        $matchEventId = $request->match_event_id;
        $ticketMainId = $request->ticket_main_id;

        $tickets = Ticket::where('user_id', $userId)
            ->where('ticket_type_id', $ticketTypeId)
            ->where('ticket_main_id', $ticketMainId)
            ->get();

        $ticketsToSendByMail = new Collection();
        foreach ($tickets as $ticket) {
            $obj = new stdClass();
            $obj->user_id = $ticket->user_id;
            $obj->code_ticket = $ticket->code_ticket;
            $ticketsToSendByMail->push($obj);
        }

        return $this->ticketsController->sendEmailMultipleTickets($userId, $ticketsToSendByMail, $ticketMainId, $matchEventId);
    }

    public function getSeatsAvailableFromLocationAndEvent(array $params)
    {
        $zone_id = $params['zone_id'];
        $quantity = $params['quantity'];
        $match_event_id = $params['match_event_id'];
        $validateRules = $params['validate_rules'] ?? true;

        $rules = MatchEventStage::where('match_event_id', $match_event_id)->get();
        $ruleZone = MatchEventStage::where([['match_event_id', $match_event_id], ['zone_id', $zone_id], ['stage_type_id', StageTypesEnum::LIMIT_TRIBUNE_CAPACITY]])->first();

        $zone = Zone::where('id', $zone_id)->first();
        $matchEventsTickets = Ticket::where('match_event_id', $match_event_id)
            ->whereIn('ticket_status_id', [TicketStatusEnum::PURCHASED, TicketStatusEnum::CREATED])
            ->whereHas('seat', function ($query) use ($zone_id) {
                $query->where('zone_id', $zone_id);
            })
            ->count();

        // Se valida que no se supere la capacidad de boletas de la tribuna
        if ($matchEventsTickets + $quantity > ($ruleZone && $validateRules ? $ruleZone->salable_capacity : $zone->salable_capacity)) {
            return [];
        }

        $matchEvent = MatchEvent::with('season')->where('id', $match_event_id)->first();
        $parameters = Parameter::select('presuscription')->first();
        $presubscriptionActive = $parameters->presuscription && $matchEvent->season->is_suscription;

        $seats = Seat::select('id', 'code', 'zone_id', 'letter_id')
            ->where('zone_id', $zone_id)
            ->where('active', 1)
            ->whereNotIn('id', function ($query) use ($match_event_id) {
                $query->select('seat_id')->from('ticket_user_blocks')->where('match_event_id', $match_event_id);
            })
            ->whereNotIn('id', function ($query) use ($match_event_id) {
                $query->select('seat_id')->from('tickets')->where('match_event_id', $match_event_id)->whereIn('ticket_status_id', [TicketStatusEnum::PURCHASED, TicketStatusEnum::CREATED]);
            })
            ->when($presubscriptionActive, function ($query) {
                $query->whereNotIn('id', function ($query) {
                    $query->select('seat_id')->from('pre_subscribers');
                });
            }) // Que no este reservada para un abonado
            ->take($quantity);

        if ($validateRules && count($rules) > 0) {
            $seatsRules = array();
            $zonesRules = array();
            foreach ($rules as $rule) {
                // Bloqueo por silla
                if ($rule->stage_type_id == StageTypesEnum::BLOCK_SEAT) {
                    $seatsRules[] = $rule->seat_id;
                }
                // Bloqueo por zona
                if ($rule->stage_type_id == StageTypesEnum::BLOCK_TRIBUNE) {
                    $zonesRules[] = $rule->zone_id;
                }
            }
            if (count($seatsRules) > 0) {
                $seats->whereNotIn('id', $seatsRules);
            }
            if (count($zonesRules) > 0) {
                $seats->whereNotIn('zone_id', $zonesRules);
            }
        }
        return $seats->get();
    }
}