File: /var/www/vhost/disk-apps/teamdemo.sports-crowd.com/app/Http/Controllers/TicketsController.php
<?php
namespace App\Http\Controllers;
use App\Core\Ticket\Application\TicketService;
use App\Core\Ticket\Entities\TicketNotification;
use App\Core\Ticket\StageTypesEnum;
use App\Core\Ticket\TicketNotificationEnum;
use App\Core\Ticket\TicketStatusEnum;
use App\Core\Ticket\TicketTypesEnum;
use App\CorporateIdentity;
use Excel;
use DB;
use App\Door;
use App\Seat;
use App\Team;
use App\User;
use App\Zone;
use DateTime;
use Madzipper;
use App\Season;
use App\Ticket;
use App\Parameter;
use App\TicketLog;
use Carbon\Carbon;
use App\MatchEvent;
use App\TicketMain;
use App\TicketType;
use App\Tournament;
use App\PreSubscriber;
use App\TicketUserBlock;
use App\MatchEventZonePrice;
use Illuminate\Http\Request;
use App\TicketUserBlockBackup;
use App\Mail\NewSuscriptorMail;
use App\Mail\TicketPurchaseMail;
use App\Mail\TicketPurchaseEmailList;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Crypt;
use App\Http\Controllers\UserController;
use Illuminate\Support\Facades\Response;
use Illuminate\Database\Eloquent\Builder;
use App\Http\Controllers\PrintTicketController;
use App\Http\Controllers\Imports\CancelTicketsImport;
use App\Http\Controllers\Imports\CancelTicketsTemplate;
use App\Http\Controllers\Imports\MatchEventSeatsImport;
use App\Http\Controllers\Imports\MatchEventSeatsTemplate;
use App\Http\Controllers\Imports\MatchEventSpecialTextImport;
use App\Http\Controllers\Imports\MatchEventSpecialTextTemplate;
use App\Events\SmsNotificationEvent;
use App\Events\Ticket\NotificationTicketEvent;
use App\Events\Ticket\TicketBillingEvent;
use App\FlashTicketConfiguration;
use App\Http\Controllers\UtilController;
use App\MatchEventStage;
use DataTables;
use App\Http\Controllers\Exports\ListTickeLogsExport;
use App\Mail\TicketNotificationCancelled;
use App\Mail\TicketNotificationUnavailable;
use App\Mail\TicketPurchaseEmailListMultiple;
use App\Module;
use App\Services\TicketsService;
use App\Services\TicketParametersService;
class TicketsController extends Controller
{
private $util;
private $ticketsService;
private $ticketParametersService;
private $ticketService;
private $parameters;
public $responseCapacityZone;
public function __construct()
{
$this->parameters = Parameter::first();
$this->util = new UtilController;
$this->ticketsService = new TicketsService;
$this->ticketParametersService = new TicketParametersService;
$this->ticketService = new TicketService();
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index(Request $request)
{
$list_events = $this->getMatchEvents($request);
$events = [];
foreach ($list_events as $key => $event) {
// Se oculta un partido para el rol de gana
$str_event = preg_replace("/\s+/", ",", trim($this->parameters->hide_match));
$str_replace_event = str_replace('.', ',', trim($str_event));
$explode_event = explode(',', $str_replace_event);
$array_event_id_hide = array_filter($explode_event);
if (is_array($array_event_id_hide)) {
if (in_array(Auth::user()->rol->id, [$this->__EXTERNAL_OPERATOR_ROL]) && in_array($event->id, $array_event_id_hide)) {
continue;
}
}
if ($event->active) {
$events[] = $event;
}
}
if ($this->validateRolePermissions('ticketing', 'seller')) {
$types = TicketType::select('id', 'name')->where('active', true)->where('id', TicketTypesEnum::FREE_SALE)->get();
} else {
$types = TicketType::select('id', 'name')->where('active', true)->get();
}
$parameters = $this->parameters;
return view('tickets.list', compact('events', 'types', 'parameters'));
}
public function getMatchEvents(Request $request)
{
$matchEvents = MatchEvent::select(
'match_events.id',
'match_events.name',
'match_events.code',
'match_events.date_name',
'match_events.sales_type',
'match_events.event_start',
'match_events.stadium_to_play',
'match_events.active',
'event_start_sale',
'event_end_sale',
'season_id',
'team_id',
'match_events.zone_id',
)
->join('seasons', 'seasons.id', '=', 'match_events.season_id');
if ($request->user() && !in_array($request->user()->rol->id, [$this->__SUPERADMIN_ROL, $this->__ADMIN_ROL, $this->__TICKET_OFFICE_ROL, $this->__TICKET_OFFICE_ROL_INTERNAL])) {
$userId = $request->user()->id;
$matchEvents = $matchEvents
->leftJoin('match_event_tags', 'match_event_tags.match_event_id', '=', 'match_events.id')
->leftJoin('tags', function ($join) {
$join->on('tags.id', '=', 'match_event_tags.tag_id')
->where('tags.active', 1);
})
->leftJoin('user_tags', 'user_tags.tag_id', '=', 'match_event_tags.tag_id')
->where(function ($q) use ($userId) {
$q->where('user_tags.user_id', $userId)
->orWhereNull('match_event_tags.id')
->orWhereNull('tags.id');
});
} else {
$matchEvents = $matchEvents->where('match_events.sales_type', '=', 'seleccionada');
}
$matchEvents = $matchEvents->where('match_events.active', '=', true)
->where('seasons.active', '=', true)
->groupBy('match_events.id')->get();
$presuscription = $this->parameters->presuscription;
if ($presuscription && $request->user()) {
$totalSubscribers = PreSubscriber::where('email', $request->user()->email)->where('payment', false)->count();
$presuscription = $totalSubscribers > 0 ? 1 : 0;
}
$controller = new ServiceChargeController();
$newMatchEvents = [];
foreach ($matchEvents as $matchEvent) {
$stadium = Zone::select('id', 'img')->where('active', true)->where('id', $matchEvent->zone_id)->first();
if (!$stadium) {
continue;
}
$matchEvent->stadium = $stadium->img;
$seasonApp = Season::select('id', 'name', 'is_suscription')->where('active', true)->where('id', $matchEvent->season_id)->first();
if (!$seasonApp) {
continue;
}
$matchEvent->season_app = $seasonApp;
$teamApp = Team::select('id', 'name', 'display_name', 'logo')->where('active', true)->where('id', $matchEvent->team_id)->first();
if (!$teamApp) {
continue;
}
$matchEvent->team_app = $teamApp;
$matchEvent->sales = $matchEvent->sales_type == 'seleccionada' ? ('/select-tickets/' . $matchEvent->id) : ('/flash-tickets/' . $matchEvent->id);
$matchEvent->subscriberSales = $seasonApp->is_suscription ? ($presuscription > 0 ? ('/flash-tickets/' . $matchEvent->id . '/' . $presuscription) : '') : '';
$matchEventZonePrices = MatchEventZonePrice::where('match_event_id', $matchEvent->id)->count();
$matchEvent->invalidEvent = $matchEvent->sales_type == 'seleccionada' && ($matchEventZonePrices == 0 || $matchEvent->zone_id == null) ? 1 : 0;
$zone = Zone::find($matchEvent->zone_id);
$requestServiceCharge = new Request([
'services' => 'ticket',
'match_events' => $matchEvent->id,
'zones' => $zone ? [$zone->id, $zone->zone_id] : [],
'ticket_types' => TicketTypesEnum::FREE_SALE
]);
$serviceCharge = $controller->calculateServiceCharge($requestServiceCharge);
$matchEvent->service_charge = $serviceCharge;
$requestServiceChargeSubscriber = new Request([
'services' => 'ticket',
'match_events' => $matchEvent->id,
'zones' => $zone ? [$zone->id, $zone->zone_id] : [],
'ticket_types' => TicketTypesEnum::SUBSCRIBER
]);
$serviceChargeSubscriber = $controller->calculateServiceCharge($requestServiceChargeSubscriber);
$matchEvent->service_charge_subscriber = $serviceChargeSubscriber;
$newMatchEvents[] = $matchEvent;
}
return $newMatchEvents;
}
public function getTribunesParent($match_event_id = null)
{
$stadiumsZone = Zone::where('zones.active', 1)->whereNull('zone_id')->pluck('id');
$query = Zone::select('zones.id', 'zones.name', 'alias', 'is_main', 'is_saleable', 'zones.active')->where('zones.active', 1)->whereIn('zone_id', $stadiumsZone);
if ($match_event_id) {
$query = $query->with(['match_event_stage' => function ($q) use ($match_event_id) {
$q->where('match_event_id', $match_event_id)
->whereIn('stage_type_id', [StageTypesEnum::BLOCK_TRIBUNE, StageTypesEnum::EXCLUSIVE_TRIBUNE]);
}]);
}
$data = $query->get();
if (Auth::user()) {
$userId = Auth::user()->id;
foreach ($data as $zone) {
if (count($zone->match_event_stage)) {
foreach ($zone->match_event_stage as $key => $stage) {
if ($stage->stage_type_id == StageTypesEnum::EXCLUSIVE_TRIBUNE) {
$stageUser = DB::table('match_event_stages')
->leftJoin('match_event_stage_tags', 'match_event_stage_tags.match_event_stage_id', '=', 'match_event_stages.id')
->leftJoin('tags', function ($join) {
$join->on('tags.id', '=', 'match_event_stage_tags.tag_id')
->where('tags.active', 1);
})
->leftJoin('user_tags', 'user_tags.tag_id', '=', 'match_event_stage_tags.tag_id')
->where(function ($q) use ($userId) {
$q->where('user_tags.user_id', $userId)
->orWhereNull('match_event_stage_tags.id')
->orWhereNull('tags.id');
})
->where('match_event_stages.id', $stage->id)
->count();
if ($stageUser)
unset($zone->match_event_stage[$key]);
}
}
}
}
}
return $data;
}
public function loadStadiumZones(Request $request)
{
return $this->ticketsService->loadStadiumZones($request);
}
public function listTribunesParent($match_event_id)
{
try {
$tribunesParent = $this->getTribunesParent($match_event_id);
return response(array("r" => true, "type" => "success", "title" => "", "m" => "", "data" => $tribunesParent));
} catch (\Throwable $th) {
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "listTribunesParen", "m" => __('messages.error_global'), "data" => $th->getMessage()));
}
}
public function getTribunesByZone($parent_zone_id)
{
try {
$zones = Zone::where('zone_id', $parent_zone_id)->where('active', true)->get();
return response(array("r" => true, "type" => "success", "title" => "", "m" => "", "data" => $zones));
} catch (\Throwable $th) {
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "getTribunesByZone", "m" => __('messages.error_global'), "data" => $th->getMessage()));
}
}
public function getSeatByZone($zone_id)
{
try {
$seats = Seat::where('zone_id', $zone_id)->with('letter')->get();
return response(array("r" => true, "type" => "success", "title" => "", "m" => "", "data" => $seats));
} catch (\Throwable $th) {
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "getSeatByZone", "m" => __('messages.error_global'), "data" => $th->getMessage()));
}
}
public function getSeatFreeByZone($zone_id, $match_event_id)
{
try {
$matchEvent = MatchEvent::with('season')->where('id', $match_event_id)->first();
$parameters = Parameter::select('presuscription')->first();
$presubscriptionActive = $parameters->presuscription && $matchEvent->season->is_suscription;
$seats = Seat::with('letter')
->where('zone_id', $zone_id)
->whereNotIn('id', function ($query) use ($match_event_id) {
$query->select('seat_id')->from('ticket_user_blocks')->where('match_event_id', $match_event_id);
}) // Sin bloqueos
->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]);
}) // Que no este vendida
->whereNotIn('id', function ($query) use ($match_event_id) {
$query->select('seat_id')->from('match_event_stages')->where('match_event_id', $match_event_id)->where('stage_type_id', StageTypesEnum::BLOCK_SEAT);
}) // Que no este bloqueada para el evento
->when($presubscriptionActive, function ($query) {
$query->whereNotIn('id', function ($query) {
$query->select('seat_id')->from('pre_subscribers')->where(function ($query1) {
$query1->where('payment', 1)->orWhere('is_credit', 1);
});
});
}) // Que no este reservada para un abonado
->get();
return response(array("r" => true, "type" => "success", "title" => "", "m" => "", "data" => $seats));
} catch (\Throwable $th) {
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "getSeatFreeByZone", "m" => __('messages.error_global'), "data" => $th->getMessage()));
}
}
public function getParentZones($zone_id)
{
try {
$controller = new ZonesController;
$zoneChilds = $controller->getZonesChilds($zone_id)->toArray();
$zones = Zone::select('id', 'name', 'zone_id')->with('zone')->whereIn('id', $zoneChilds)->get();
return response(array("r" => true, "type" => "success", "title" => "", "m" => "", "data" => $zones));
} catch (\Throwable $th) {
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "getZones", "m" => __('messages.error_global'), "data" => $th->getMessage()));
}
}
public function getChildZones($zone_id)
{
try {
$controller = new ZonesController;
$zones = $controller->getChildZones($zone_id);
return response(array("r" => true, "type" => "success", "title" => "", "m" => "", "data" => $zones));
} catch (\Throwable $th) {
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "getZones", "m" => __('messages.error_global'), "data" => $th->getMessage()));
}
}
public function getSubZones($zone_id, $event_id)
{
try {
$zones = DB::table('zones as z')
->select(
'z.id',
'z.name',
'z.alias',
'z.active',
'z.is_saleable',
'z.zone_id',
'z.salable_capacity',
'z.total_capacity',
DB::raw('(z.salable_capacity - SUM(IF(t.id, 1, 0) + IF(tu.id, 1, 0) + IF(me.id, 1, 0))) AS available_seats')
)
->leftJoin('seats as s', 's.zone_id', '=', 'z.id')
->leftJoin('tickets as t', function ($join) use ($event_id) {
$join->on('t.seat_id', '=', 's.id')
->where('t.match_event_id', $event_id)
->whereIn('t.ticket_status_id', [TicketStatusEnum::PURCHASED, TicketStatusEnum::CREATED]);
})
->leftJoin('ticket_user_blocks as tu', function ($join) use ($event_id) {
$join->on('tu.seat_id', '=', 's.id')
->where('tu.match_event_id', $event_id);
})
->leftJoin('match_event_stages as me', function ($join) use ($event_id) {
$join->on('me.seat_id', '=', 's.id')
->where('me.match_event_id', $event_id);
})
->where('z.zone_id', $zone_id)
->where('z.active', true)
->groupBy('z.id')
->get();
return response(array("r" => true, "type" => "success", "title" => "", "m" => "", "data" => $zones));
} catch (\Throwable $th) {
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "getZones", "m" => __('messages.error_creating'), "data" => $th->getMessage()));
}
}
public function getSeatsCount($zone_id, $event_id)
{
try {
$count = 0;
// se valida la capacidad de la localidad no este superada
if (!$this->salableCapacityZone($zone_id, $event_id)) {
return 0;
}
$seats = Seat::select('seats.id', DB::raw('IF(t.id, 1, 0) AS ticket'), DB::raw('IF(tu.id, 1, 0) AS ticket_user_block'))
->where([['seats.zone_id', $zone_id], ['active', true]])
->leftJoin('tickets AS t', function ($join) use ($event_id) {
$join->on('seats.id', '=', 't.seat_id')->where('t.match_event_id', $event_id)
->whereIn('t.ticket_status_id', [TicketStatusEnum::PURCHASED, TicketStatusEnum::CREATED]);
})
->leftJoin('ticket_user_blocks AS tu', function ($join) use ($event_id) {
$join->on('seats.id', '=', 'tu.seat_id')->where('tu.match_event_id', $event_id);
})
->get();
foreach ($seats as $seat) {
if ($this->isAvailable($seat)) {
$count++;
}
}
return $count;
} catch (\Throwable $th) {
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "getSeats", "m" => __('messages.error_creating'), "data" => $th->getMessage()));
}
}
public function isAvailable($seat)
{
$flag = true;
if ($seat->ticket || $seat->ticket_user_block) {
$flag = false;
}
return $flag;
}
public function getSeats($zone_id, $event_id, $is_reassign = false)
{
try {
// se valida la capacidad de la localidad no este superada
if (!$this->salableCapacityZone($zone_id, $event_id, 0, null, $validateRules = false)) {
if ($is_reassign) {
$response = json_decode($this->responseCapacityZone->getContent());
return response(array("r" => true, "type" => "error", "title" => "", "m" => $response->m, "data" => []));
}
return $this->responseCapacityZone;
}
$parameters = Parameter::select('presuscription')->first();
$presubscriptionActive = $parameters->presuscription;
$event = MatchEvent::with('season')->where('id', $event_id)->first();
$user = Auth::user();
$seats = Seat::select(
'seats.id',
'seats.code',
'seats.letter_id',
'seats.zone_id',
DB::raw('IF(t.id, 1, 0) AS ticket'),
DB::raw('IF(tu.id, 1, 0) AS ticket_user_block'),
't.ticket_type_id',
'tu.is_social_distancing',
DB::raw('IF(presub.id, 1, 0) AS presubscription')
)
->with(['zone' => function ($q) {
$q->select('id', 'name', 'zone_id')->with(['zone' => function ($q) {
$q->select('id', 'name');
}]);
}])
->with(['letter' => function ($q) {
$q->select('id', 'name');
}])
->with(['match_event_stage' => function ($q) use ($event_id) {
$q->where('match_event_id', $event_id);
}])
->leftJoin('tickets AS t', function ($join) use ($event_id) {
$join->on('seats.id', '=', 't.seat_id')->where('t.match_event_id', $event_id)
->whereIn('t.ticket_status_id', [TicketStatusEnum::PURCHASED, TicketStatusEnum::CREATED]);
})
->leftJoin('ticket_user_blocks AS tu', function ($join) use ($event_id) {
$join->on('seats.id', '=', 'tu.seat_id')->where('tu.match_event_id', $event_id);
})
->leftJoin('pre_subscribers AS presub', function ($join) use ($presubscriptionActive, $user, $event) {
$join->on('seats.id', '=', 'presub.seat_id');
if (!$presubscriptionActive || !$event->season->is_suscription) {
$join->whereNull('presub.seat_id');
}
// TODO: Se comenta por el momento, para reestringir la compra de silla abonada desde boleta suelta.
// if ($user) {
// $join->where('presub.email', '!=', $user->email);
// }
})
->where('seats.zone_id', $zone_id)
->where('seats.active', 1)
->orderBy('seats.letter_id', 'desc')
->orderBy('seats.code', 'asc')
->get();
return response(array("r" => true, "type" => "success", "title" => "", "m" => "", "data" => $seats));
} catch (\Throwable $th) {
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "getSeats", "m" => __('messages.error_creating'), "data" => $th->getMessage()));
}
}
public function isPreabonado($document)
{
try {
if (!User::where([['document', $document], ['active', true]])->first()) {
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "isPreabonado", "m" => "Debes ingresar todos los datos en tu perfil.", "data" => null));
}
$listPreSubcriber = PreSubscriber::where('document', $document)->where('payment', false)->get();
if (count($listPreSubcriber) <= 0) {
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "isPreabonado", "m" => $this->parameters->presuscription_msj, "data" => null));
}
return response(array("r" => true, "type" => "success", "title" => "", "m" => "", "data" => $listPreSubcriber));
} catch (\Throwable $th) {
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "isPreabonado", "m" => __('messages.error_creating'), "data" => $th->getMessage()));
}
}
public function isPreabonadoByEmail(Request $request)
{
try {
$listPreSubcriber = PreSubscriber::where('email', $request->email)->get();
if (count($listPreSubcriber) <= 0) {
$message = $this->parameters->is_exclusive_subscriber_login ? $this->parameters->msj_exclusive_subscriber_login : null;
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "isPreabonadoByEmail", "m" => $message, "data" => null));
}
return response(array("r" => true, "type" => "success", "title" => "", "m" => "", "data" => null));
} catch (\Throwable $th) {
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "isPreabonadoByEmail", "m" => __('messages.error_creating'), "data" => $th->getMessage()));
}
}
public function isPreabonadoByDocSuscription(Request $request)
{
try {
$listPreSubcriber = PreSubscriber::where('document', $request->suscriptionDoc)->get();
if (count($listPreSubcriber) <= 0) {
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "isPreabonadoByEmail", "m" => $this->parameters->presuscription_msj, "data" => null));
}
foreach ($listPreSubcriber as $item) {
$item->email = $request->email;
$item->update();
}
return response(array("r" => true, "type" => "success", "title" => "", "m" => "", "data" => null));
} catch (\Throwable $th) {
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "isPreabonadoByEmail", "m" => __('messages.error_creating'), "data" => $th->getMessage()));
}
}
public function getSeatPrice($zone_id, $event_id)
{
try {
$matchEventPrice = MatchEventZonePrice::select('id', 'match_event_id', 'price', 'price_suscription', 'zone_id')
->where([['zone_id', $zone_id], ['match_event_id', $event_id]])->first();
if (!$matchEventPrice) {
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "validateSell", "m" => __('messages.error_validation_tickets.zone_no_saleable'), "data" => null));
}
$parameters = Parameter::select('presuscription')->first();
$presubscriptionActive = $parameters->presuscription;
if (!$presubscriptionActive) {
$matchEventPrice->price_suscription = 0;
$matchEventPrice->subscriberPrices = [];
} else {
$user = Auth::user();
$subscriberPrices = PreSubscriber::select('s.id AS seat_id', 'pre_subscribers.price AS price_suscription')
->join('seats as s', 's.id', '=', 'pre_subscribers.seat_id')
->join('zones as z', 'z.id', '=', 's.zone_id')
->where('z.id', $zone_id)
->where(function ($q) use ($user) {
if ($user) {
$q->where('pre_subscribers.email', $user->email);
}
})
->groupBy('s.id', 'pre_subscribers.price')
->get();
$matchEventPrice->subscriberPrices = $subscriberPrices;
}
$controller = new ServiceChargeController();
if ($matchEventPrice && $controller->validateServiceCharge()) {
$zone = Zone::select('zone_id')->where('id', $zone_id)->first();
$requestServiceCharge = new Request([
'services' => 'ticket',
'match_events' => $event_id,
'zones' => [$zone_id, $zone->zone_id],
'ticket_types' => TicketTypesEnum::FREE_SALE
]);
$serviceCharge = $controller->calculateServiceCharge($requestServiceCharge);
$matchEventPrice->service_charge = $serviceCharge;
$requestServiceChargeSubscriber = new Request([
'services' => 'ticket',
'match_events' => $event_id,
'zones' => [$zone_id, $zone->zone_id],
'ticket_types' => TicketTypesEnum::SUBSCRIBER
]);
$serviceChargeSubscriber = $controller->calculateServiceCharge($requestServiceChargeSubscriber);
$matchEventPrice->service_charge_subscriber = $serviceChargeSubscriber;
}
return response(array("r" => true, "type" => "success", "title" => "", "m" => "", "data" => $matchEventPrice));
} catch (\Throwable $th) {
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "getSeatPrice", "m" => __('messages.error_creating'), "data" => $th->getMessage()));
}
}
public function searchUser(Request $request, $document, $match_event_id = null, $ticket_type_id = null)
{
try {
$user = new UserController($request);
$search = $user->searchUser($document);
$isPreabonado = null;
if ($this->parameters->presuscription) {
$isPreabonado = $this->isPreabonado($document);
}
if ($match_event_id && $search) {
$tickets = Ticket::where('match_event_id', $match_event_id)
->where('user_id', $search->id)
->where('ticket_type_id', $ticket_type_id)
->count();
return response(array("r" => true, "type" => "success", "title" => "", "m" => "", "data" => $search, 'tickets' => $tickets, "isPreabonado" => $isPreabonado));
}
return response(array("r" => true, "type" => "success", "title" => "", "m" => "", "data" => $search, "isPreabonado" => $isPreabonado));
} catch (\Throwable $th) {
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "searchUser", "m" => __('messages.error_creating'), "data" => $th->getMessage()));
}
}
public function exchangeTicketsToUsers(Request $request, $document, $match_event_id = null, $ticket_type_id = null)
{
try {
$user = new UserController($request);
$search = $user->searchUser($document);
$isPreabonado = null;
if ($this->parameters->presuscription) {
$isPreabonado = $this->isPreabonado($document);
}
if ($search->document) {
$searchUser = User::where('document', '=', $search->document)->get();
return response(array("r" => true, "type" => "success", "title" => "", "m" => "", "data" => $searchUser, 'tickets' => $searchUser, "isPreabonado" => $isPreabonado));
}
return response(array("r" => true, "type" => "success", "title" => "", "m" => "", "data" => $searchUser, "isPreabonado" => $isPreabonado));
} catch (\Throwable $th) {
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "searchUser", "m" => __('messages.error_creating'), "data" => $th->getMessage()));
}
}
public function createBlockTicket($seat_id, $match_event_id, $user_id, $ticket_type_id, $ticket_main_id, $zone_id, $pin = false, $is_social_distancing = false, $price = false)
{
try {
// Se procesa el bloqueo
$minutesToBlock = $this->parameters->maximum_sale_blocking_time ?? 0;
$this->processBlockGeneralTicket($seat_id, $match_event_id, $user_id, $minutesToBlock, $ticket_type_id, $ticket_main_id, $zone_id, $is_social_distancing, $price);
// mensaje mostrando el tiempo limite que tiene para efectuar la compra
$messageBlockMinutes = Carbon::now()->addMinutes($minutesToBlock)->format('h:i:s A');
$message = __($this->parameters->msj_waiting_time_for_seat_blocking ?? 'messages.create_block', ['dateblock' => $messageBlockMinutes, 'time' => $minutesToBlock]);
if ($pin) {
$message = $message . "\n" . __('messages.create_block_2') . $pin;
} else {
$message = $message . __('messages.create_block_3');
}
return array("r" => true, "type" => "success", "title" => "", "origin" => "createBlockTicket", "m" => $message, "data" => null);
} catch (\Throwable $th) {
return array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "createBlockTicket", "m" => __('messages.error_global'), "data" => $th->getMessage());
}
}
public function getSeatBlockdistancing_x($index_init, $array_search)
{
// definimos el index de inicio de bloqueo a la izquierda y derecha deacuerdo al parametro de numero de sillas a bloquear
$init_block_left = $index_init - $this->parameters->social_distancing_number_seat_x;
$init_block_right = $index_init + $this->parameters->social_distancing_number_seat_x;
$list_block_distancing = [];
foreach ($array_search as $key2 => $id) {
if ($this->parameters->social_distancing_left) {
if ($key2 >= $init_block_left && $key2 < $index_init) {
$list_block_distancing[] = $id;
}
}
if ($this->parameters->social_distancing_right) {
if ($key2 > $index_init && $key2 <= $init_block_right) {
$list_block_distancing[] = $id;
}
}
}
return $list_block_distancing;
}
public function getSeatBlockdistancing_y($index_init, $array_search, $array_file_origin)
{
$number_differente = 0;
// definimos el index de inicio de bloqueo de arriba y abajo deacuerdo al parametro de numero de sillas a bloquear
if (count($array_file_origin) != count($array_search)) {
$number_differente = count($array_search) - count($array_file_origin);
}
if ($number_differente) {
$index_init = $index_init + ($number_differente / 2);
}
$init_block_left = $index_init - $this->parameters->social_distancing_number_seat_y;
$init_block_right = $index_init + $this->parameters->social_distancing_number_seat_y;
$list_block_distancing = [];
foreach ($array_search as $key2 => $id) {
if ($key2 == $index_init) {
$list_block_distancing[] = $id;
}
if ($key2 >= $init_block_left && $key2 < $index_init) {
$list_block_distancing[] = $id;
}
if ($key2 > $index_init && $key2 <= $init_block_right) {
$list_block_distancing[] = $id;
}
}
return $list_block_distancing;
}
public function getGroupSeatByLetter($zone_id, $letter_id)
{
$resp = [];
// $c = Seat::where([['zone_id',$zone_id],['letter_id', $letter_id]])->pluck('code')->toArray();
$c = Seat::where([['zone_id', $zone_id], ['letter_id', $letter_id]])->pluck('id')->toArray();
if ($c) {
$resp = $c;
}
return $resp;
}
public function searchNeighbour($seat_id, $zone_id)
{
$list_block_distancing = [];
$seat = Seat::where('id', $seat_id)->first();
if ($seat) {
$seats_group = Seat::where('zone_id', $zone_id)->distinct()->pluck('letter_id')->toArray();
$ids_x_group = $this->getGroupSeatByLetter($zone_id, $seat->letter_id);
// buscamos la fila vecina de arriba y la de abajo
$letter_id_top = 0;
$letter_id_bottom = 0;
foreach ($seats_group as $key => $letter) {
if ($letter == $seat->letter_id) {
if (isset($seats_group[$key + 1]) && $this->parameters->social_distancing_top) {
$letter_id_top = $seats_group[$key + 1];
}
if (isset($seats_group[$key - 1]) && $this->parameters->social_distancing_bottom) {
$letter_id_bottom = $seats_group[$key - 1];
}
}
}
// buscamos el index de la silla de la fila origen a comprar por el usuario
// $index_seat_buy = array_search($seat->code, $ids_x_group);
$index_seat_buy = array_search($seat->id, $ids_x_group);
// Consultamos la sillas a bloquear en el eje x basado en el index de la silla a comprar por el cliente
$list_block_distancing = array_merge($this->getSeatBlockdistancing_x($index_seat_buy, $ids_x_group), $list_block_distancing);
// Consultamos la sillas a bloquear en el eje y basado en el index de la silla a comprar por el cliente
if ($letter_id_top != 0 && $this->parameters->social_distancing_top) {
$ids_top_group = $this->getGroupSeatByLetter($zone_id, $letter_id_top);
$list_block_distancing = array_merge($this->getSeatBlockdistancing_y($index_seat_buy, $ids_top_group, $ids_x_group), $list_block_distancing);
}
if ($letter_id_bottom != 0 && $this->parameters->social_distancing_bottom) {
$ids_bottom_group = $this->getGroupSeatByLetter($zone_id, $letter_id_bottom);
$list_block_distancing = array_merge($this->getSeatBlockdistancing_y($index_seat_buy, $ids_bottom_group, $ids_x_group), $list_block_distancing);
}
}
return $list_block_distancing;
}
public function deleteBlock($seat_id, $match_event_id, $user_id)
{
try {
TicketUserBlock::where([['seat_id', $seat_id], ['match_event_id', $match_event_id], ['user_id', $user_id]])->delete();
} catch (\Throwable $th) {
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "deleteBlock", "m" => __('messages.error_global'), "data" => $th->getMessage()));
}
}
public function deleteBlockBackup($seat_id, $match_event_id, $user_id)
{
try {
TicketUserBlockBackup::where([['seat_id', $seat_id], ['match_event_id', $match_event_id], ['user_id', $user_id]])->delete();
} catch (\Throwable $th) {
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "deleteBlockBackup", "m" => __('messages.error_global'), "data" => $th->getMessage()));
}
}
private function createNewBlock($data)
{
TicketUserBlock::create($data);
}
private function processBlockGeneralTicket($seat_id, $match_event_id, $user_id, $minutesToBlock, $ticket_type_id, $ticket_main_id, $zone_id, $is_social_distancing, $custom_price)
{
$price = 0;
if ($custom_price) {
$price = $custom_price;
} else {
if (!$is_social_distancing && $ticket_type_id != TicketTypesEnum::COMPLIMENTARY) {
$zonePrice = MatchEventZonePrice::where([['zone_id', $zone_id], ['match_event_id', $match_event_id]])->first();
if ($zonePrice && $ticket_type_id != TicketTypesEnum::SUBSCRIBER) {
$price = $zonePrice->price;
} else if ($zonePrice && $ticket_type_id == TicketTypesEnum::SUBSCRIBER) {
$price = $zonePrice->price_suscription;
}
}
}
$data = [
'seat_id' => $seat_id,
'match_event_id' => $match_event_id,
'user_id' => $user_id,
'zone_id' => $zone_id,
'start_block' => Carbon::now(),
'end_block' => Carbon::now()->addMinutes($minutesToBlock),
'is_social_distancing' => $is_social_distancing,
'price' => $price,
'ticket_type_id' => $ticket_type_id,
'ticket_main_id' => $ticket_main_id,
];
$this->createNewBlock($data);
}
public function getEventsSubscription($seasonId = null, $matchEventId = null)
{
$listMatchEvents = [];
if (!$seasonId && !$matchEventId) {
$tournaments = Tournament::where('active', true)->get();
foreach ($tournaments as $tournament) {
$listSeasons = Season::where([['tournament_id', $tournament->id], ['is_suscription', true], ['active', true]])->orderBy('start', 'asc')->get();
foreach ($listSeasons as $season) {
$events = MatchEvent::where('season_id', $season->id)->where('event_start', '>', Carbon::now()->startOfDay())->with('team')->orderBy('event_start', 'asc')->get();
if ($events) {
$listMatchEvents[] = $events;
}
}
}
} else if ($seasonId && Season::find($seasonId)->is_suscription) {
$events = MatchEvent::where('season_id', $seasonId)->where('event_start', '>', Carbon::now()->startOfDay())->with('team')->orderBy('event_start', 'asc')->get();
if ($events) {
$listMatchEvents[] = $events;
}
} else if ($matchEventId) {
$matchEvent = MatchEvent::with('season')->find($matchEventId);
if ($matchEvent->season->is_suscription) {
$events = MatchEvent::where('season_id', $matchEvent->season_id)->where('event_start', '>', Carbon::now()->startOfDay())->with('team')->orderBy('event_start', 'asc')->get();
if ($events) {
$listMatchEvents[] = $events;
}
} else {
$events = MatchEvent::where('id', $matchEvent->id)->where('event_start', '>', Carbon::now()->startOfDay())->with('team')->orderBy('event_start', 'asc')->get();
if ($events) {
$listMatchEvents[] = $events;
}
}
}
$result = array_flatten($listMatchEvents);
return collect($result)->sortBy('event_start')->values();
}
// Genera Pin aleatorio gane.
public function generatepin($seat_id = 1)
{
$date = Carbon::now();
$date->addSeconds($seat_id);
return intval($date->getPreciseTimestamp(3));
}
public function createTicket(array $params)
{
$seat_id = $params['seat_id'];
$match_event_id = $params['match_event_id'];
$user_id = $params['user_id'];
$ticket_type_id = $params['ticket_type_id'];
$ticket_main_id = $params['ticket_main_id'];
$price = $params['price'];
$is_from_massive = $params['is_from_massive'] ?? false;
$special_text = $params['special_text'] ?? null;
$is_an_email_sent = $params['is_an_email_sent'] ?? false;
try {
$current_seat = Seat::select('code', 'zone_id', 'letter_id')->with('letter')->where('id', $seat_id)->first();
$zone = Zone::select('id', 'name', 'door_id', 'zone_id')->where('id', $current_seat->zone_id)->first();
$event = MatchEvent::select('code')->where('id', $match_event_id)->first();
$door_name = null;
if ($zone && $zone->door_id) {
$c_q = Door::select('name')->where('id', $zone->door_id)->first();
if ($c_q) {
$door_name = $c_q->name;
}
}
if (!$special_text) {
$stage = MatchEventStage::where([['match_event_id', $match_event_id], ['stage_type_id', StageTypesEnum::TICKET_LABEL]])->whereIn('zone_id', [$zone->id, $zone->zone_id])->first();
if ($stage) {
$special_text = $stage->special_text;
}
}
if (Ticket::where([['seat_id', $seat_id], ['match_event_id', $match_event_id], ['ticket_status_id', TicketStatusEnum::PURCHASED]])->first()) {
return;
}
$ticket = Ticket::create([
'code_ticket' => config('app.client') . $this->generatepin($seat_id),
'seat_id' => $seat_id,
'match_event_id' => $match_event_id,
'user_id' => $user_id,
'ticket_type_id' => $ticket_type_id,
'ticket_status_id' => 1,
'price' => $price,
'zone' => $zone->name,
'letter_seat' => $current_seat->letter->name,
'code_seat' => $current_seat->code,
'code_event' => $event->code,
'door' => $door_name,
'ticket_main_id' => $ticket_main_id,
'special_text' => $special_text,
'is_an_email_sent' => $is_an_email_sent
]);
if ($ticket && !$is_from_massive) {
if (Auth::user()) {
$this->registerLog(Auth::user()->id, 'Se creo boleta', json_encode($ticket), "Create", 'Boleteria');
} else {
$this->registerLog($user_id, 'Se creo boleta', json_encode($ticket), "Create", 'Boleteria');
}
$this->createLogTicket(TicketStatusEnum::PURCHASED, $ticket->id);
$message = __('messages.create_ticket');
return array("r" => true, "type" => "success", "title" => "", "origin" => "createTicket", "m" => $message, "data" => null);
}
if ($is_from_massive) {
if (Auth::user()) {
$this->registerLog(Auth::user()->id, 'Se creo boleta desde masivo', json_encode($ticket), "Create", 'Boleteria');
}
$this->createLogTicket(TicketStatusEnum::PURCHASED, $ticket->id);
return $ticket;
}
return array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "createTicket", "m" => __('messages.error_global'), "data" => null);
} catch (\Throwable $th) {
return array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "createTicket", "m" => __('messages.error_global'), "data" => $th->getMessage());
}
}
public function existsTicket($seat_id, $event_id, $user_id)
{
if ($this->parameters->is_social_distancing) {
return Ticket::where([['seat_id', $seat_id], ['match_event_id', $event_id], ['user_id', '=', $user_id]])->whereIn('ticket_status_id', [TicketStatusEnum::PURCHASED, TicketStatusEnum::CREATED])->exists();
} else {
return Ticket::where([['seat_id', $seat_id], ['match_event_id', $event_id]])->whereIn('ticket_status_id', [TicketStatusEnum::PURCHASED, TicketStatusEnum::CREATED])->exists();
}
}
public function existsBlock($seat_id, $event_id, $user_id)
{
if ($this->parameters->is_social_distancing) {
return TicketUserBlock::where([['seat_id', $seat_id], ['match_event_id', $event_id], ['is_social_distancing', false], ['user_id', '!=', $user_id]])->exists();
} else {
return TicketUserBlock::where([['seat_id', $seat_id], ['match_event_id', $event_id]])->exists();
}
}
public function infoSeat($seat_id)
{
return Seat::where('id', $seat_id)->with('letter')->first();
}
public function validateBlockDistancing($ticket_main_id)
{
$distancing = TicketUserBlock::where([['ticket_main_id', $ticket_main_id], ['is_social_distancing', true]])->get();
foreach ($distancing as $item) {
$item->end_block = null;
$item->update();
}
}
// Retorna la cantidad de sillas vendibles de una tribuna
// $currentTickets = el numero de boletas que se van a comprar en la transaccion actual
public function salableCapacityZone($zone_id, $event_id, $currentTickets = 0, $userId = null, $validateRules = true)
{
$zone = Zone::where('id', $zone_id)
->with(['match_event_stage' => function ($q) use ($event_id) {
$q->where('match_event_id', $event_id);
}])
->first();
$salable_capacity = $zone->salable_capacity;
$zoneActive = $zone->active;
if ($validateRules && $zone && count($zone->match_event_stage)) {
$stage = $zone->match_event_stage->last();
if ($stage->stage_type_id == StageTypesEnum::BLOCK_TRIBUNE) {
$zoneActive = $stage->active;
}
if ($stage->stage_type_id == StageTypesEnum::LIMIT_TRIBUNE_CAPACITY) {
$salable_capacity = $stage->salable_capacity;
}
if ($stage->stage_type_id == StageTypesEnum::EXCLUSIVE_TRIBUNE) {
$validExclusiveTribuneStage = false;
if (Auth::user() || $userId) {
$userId = Auth::user() ? Auth::user()->id : $userId;
$stageUser = DB::table('match_event_stages')
->leftJoin('match_event_stage_tags', 'match_event_stage_tags.match_event_stage_id', '=', 'match_event_stages.id')
->leftJoin('tags', function ($join) {
$join->on('tags.id', '=', 'match_event_stage_tags.tag_id')
->where('tags.active', 1);
})
->leftJoin('user_tags', 'user_tags.tag_id', '=', 'match_event_stage_tags.tag_id')
->where(function ($q) use ($userId) {
$q->where('user_tags.user_id', $userId)
->orWhereNull('match_event_stage_tags.id')
->orWhereNull('tags.id');
})
->where('match_event_stages.id', $stage->id)
->count();
if ($stageUser) {
$validExclusiveTribuneStage = true;
}
}
if (!$validExclusiveTribuneStage) {
$this->responseCapacityZone = response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "salableCapacityZone", "m" => __('messages.error_validation_10'), "data" => null));
return false;
}
}
}
if ($salable_capacity == 0 || !$zoneActive) {
$this->responseCapacityZone = response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "salableCapacityZone", "m" => __('messages.error_validation_10'), "data" => null));
return false;
}
$tickets = Ticket::where('match_event_id', $event_id)
->whereHas('seat', function (Builder $query) use ($zone_id) {
$query->where('zone_id', $zone_id)->whereIn('ticket_status_id', [TicketStatusEnum::PURCHASED, TicketStatusEnum::CREATED]);
})->count();
$blocks = TicketUserBlock::where('match_event_id', $event_id)
->whereHas('seat', function (Builder $query) use ($zone_id) {
$query->where('zone_id', $zone_id);
})->count();
if ($tickets + $blocks >= $salable_capacity) {
$this->responseCapacityZone = response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "salableCapacityZone", "m" => __('messages.error_validation_8'), "data" => null));
return false;
}
if ($currentTickets !== 0 && $currentTickets + $tickets + $blocks > $salable_capacity) {
$available = $salable_capacity - ($tickets + $blocks);
$this->responseCapacityZone = response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "salableCapacityZone", "m" => __('messages.error_validation_11', ['number' => $available]), "data" => null));
return false;
}
return true;
}
// Retorna la suma actual de bloqueos y tickets que tiene un usuario para un evento
public function getSumBlocksAndTicketsByUser($ticket_type_id, $user_id, $event_id)
{
$countTickets = Ticket::where([['ticket_type_id', $ticket_type_id], ['match_event_id', $event_id], ['user_id', $user_id]])->whereIn('ticket_status_id', [TicketStatusEnum::PURCHASED, TicketStatusEnum::CREATED])->count();
$countBlocks = TicketUserBlock::where([['ticket_type_id', $ticket_type_id], ['match_event_id', $event_id], ['user_id', $user_id], ['is_social_distancing', false]])->count();
return $countTickets + $countBlocks;
}
public function getSumTicketsByUserFlashConfiguration($match_event_id, $user_id)
{
$availableTickets = FlashTicketConfiguration::select('flash_ticket_configuration.zone_id', 'flash_ticket_configuration.id', DB::raw('flash_ticket_configuration.maximum_number_ballots - COUNT(ob1.id) AS available_tickets'))
->leftJoin(
DB::raw('(SELECT t.id, zones.zone_id FROM tickets t JOIN seats ON t.seat_id = seats.id JOIN zones ON zones.id = seats.zone_id WHERE t.user_id = ' . $user_id . ' AND t.match_event_id = ' . $match_event_id . ' AND ticket_status_id IN (' . TicketStatusEnum::PURCHASED . ', ' . TicketStatusEnum::CREATED . ') AND t.ticket_type_id != ' . TicketTypesEnum::COMPLIMENTARY . ') as ob1'),
function ($join) {
$join->on('ob1.zone_id', '=', 'flash_ticket_configuration.zone_id');
}
)
->where('flash_ticket_configuration.match_event_id', '=', $match_event_id)
->where('flash_ticket_configuration.active', 1)
->groupBy('flash_ticket_configuration.zone_id', 'flash_ticket_configuration.id', 'flash_ticket_configuration.maximum_number_ballots')
->get();
return $availableTickets;
}
public function validateSell($zone_id, $event_id, $seat_id, $user_id, $ticket_type_id, $ticket_main_id, $type_process, $price, $pin = false, $is_transaction = false)
{
if ($is_transaction) {
DB::beginTransaction();
}
try {
// se valida la capacidad de la localidad no este superada
if (!$this->salableCapacityZone($zone_id, $event_id, 0, $user_id)) {
return $this->responseCapacityZone;
}
// se consulta y valida si existe un ticket o un bloqueo para esa silla
$ticket_current = $this->existsTicket($seat_id, $event_id, $user_id);
$ticket_block = $this->existsBlock($seat_id, $event_id, $user_id);
if ($ticket_current) {
$seat = $this->infoSeat($seat_id);
$name_seat = "";
if ($seat) {
$name_seat = $seat->letter->name . $seat->code;
}
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "validateSell", "m" => __('messages.error_validation_3', ['seat' => $name_seat]), "data" => null));
}
if ($ticket_block) {
$seat = $this->infoSeat($seat_id);
$name_seat = "";
if ($seat) {
$name_seat = $seat->letter->name . $seat->code;
}
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "validateSell", "m" => __('messages.error_validation_4', ['seat' => $name_seat]), "data" => null));
}
// si esta activo la logica de compra con distanciamiento social
if ($this->parameters->is_social_distancing) {
// buscamos los vecinos de la silla origen, para validar si pueden ser bloqueadas
$list_block_distancing = $this->searchNeighbour($seat_id, $zone_id);
foreach ($list_block_distancing as $item) {
$current_block = $this->existsBlock($item, $event_id, $user_id);
$current_ticket = $this->existsTicket($item, $event_id, $user_id);
if ($current_block || $current_ticket) {
$seat = $this->infoSeat($seat_id);
$name_seat = "";
if ($seat) {
$name_seat = $seat->letter->name . $seat->code;
}
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "validateSell", "m" => __('messages.error_validation_9', ['seat' => $name_seat]), "data" => $item));
break;
}
}
}
if ($type_process == "ticket") {
$transaction = $this->createTicket(
[
'seat_id' => $seat_id,
'match_event_id' => $event_id,
'user_id' => $user_id,
'ticket_type_id' => $ticket_type_id,
'ticket_main_id' => $ticket_main_id,
'price' => $price
]
);
if ($this->parameters->is_social_distancing) {
$this->validateBlockDistancing($ticket_main_id);
}
if ($is_transaction) {
if ($transaction["r"]) {
DB::commit();
} else {
DB::rollback();
}
}
return response($transaction);
} else {
$transaction = $this->createBlockTicket($seat_id, $event_id, $user_id, $ticket_type_id, $ticket_main_id, $zone_id, $pin, false, $price);
if ($this->parameters->is_social_distancing) {
// se realiza el bloqueo de las sillas vecinas por distanciamiento
foreach ($list_block_distancing as $item) {
// se consulta si la silla vecina actual en el ciclo es una silla de las que se va a comprar, para no realizar el bloqueo
$is_buy_seat = TicketUserBlock::where([['seat_id', $item], ['user_id', $user_id], ['match_event_id', $event_id], ['is_social_distancing', false]])->first();
if (!$is_buy_seat) {
$this->createBlockTicket($item, $event_id, $user_id, $ticket_type_id, $ticket_main_id, $zone_id, $pin, true, $price);
}
}
// se elimina cualquier bloqueo de la silla a comprar si es del mismo usuario y tiene bloqueo por distanciamiento
$list_distancing = TicketUserBlock::where([
['seat_id', $seat_id],
['user_id', $user_id],
['match_event_id', $event_id],
['is_social_distancing', true]
])->get();
foreach ($list_distancing as $d_seat) {
$d_seat->delete();
}
}
if ($is_transaction) {
if ($transaction["r"]) {
DB::commit();
} else {
DB::rollback();
}
}
return response($transaction);
}
} catch (\Throwable $th) {
if ($is_transaction) {
DB::rollback();
}
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "validateSell", "m" => __('messages.error_global'), "data" => $th->getMessage()));
}
}
public function createBlock(Request $request, $origin)
{
DB::beginTransaction();
try {
// se valida la capacidad de la localidad no este superada
if (!$this->salableCapacityZone($request->input('tickets')[0]["seat"]["zone_id"], $request->input('tickets')[0]["match_event_id"], count($request->input('tickets')))) {
DB::rollback();
return $this->responseCapacityZone;
}
$userController = new UserController($request);
$user = $userController->searchUser($request->document, $request->email, $request->first_name, $request->last_name, $request->phone);
if (!$user) {
$current_user = $userController->createClient($request, $is_ticket = true, $validateByDocument = true);
if ($current_user["r"]) {
$user = $current_user["d"];
} else {
DB::rollback();
return response($current_user);
}
}
$user_id = $user->id;
$sumTicketsBlocks = $this->getSumBlocksAndTicketsByUser($request->input('ticket_type_id'), $user_id, $request->input('tickets')[0]["match_event_id"]) + count($request->input('tickets'));
$flashController = new FlashTicketController;
$matchEventsController = new MatchEventsController;
$maximum = !$matchEventsController->validateSaleByCapacity($request->input('tickets')[0]["match_event_id"]) ? $this->parameters->maximum_number_ballots : $flashController->getMaximumTicketsToBuy($request->input('tickets')[0]["match_event_id"]);
// Valida el numero maximo de boletas que puede comprar el usuario.
if ($request->input('ticket_type_id') == 1 && $sumTicketsBlocks > $maximum) {
DB::rollback();
$available = $maximum - ($sumTicketsBlocks - count($request->input('tickets')));
if ($available < 0) $available = 0;
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "createBlock", "m" => __('messages.error_validation_5', ['number' => $available]), "data" => null));
}
// Valida el numero máximo de abonos.
if ($request->input('ticket_type_id') == TicketTypesEnum::SUBSCRIBER && $sumTicketsBlocks > $this->parameters->maximum_number_suscription) {
DB::rollback();
$available = $this->parameters->maximum_number_suscription - ($sumTicketsBlocks - count($request->input('tickets')));
if ($available < 0) $available = 0;
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "createBlock", "m" => __('messages.error_validation_6', ['number' => $available]), "data" => null));
}
$pin = null;
$pin_tercero = null;
$pin_internal = null;
if ($origin == 'external') {
$pin_tercero = $this->generatepin();
$pin = $pin_tercero;
}
if ($origin == 'internal') {
$pin_internal = $this->generatepin();
$pin = $pin_internal;
}
$seller_id = null;
if (Auth::user()->rol_id != 4) {
$seller_id = Auth::user()->id;
}
$subtotal = $request->input('subtotal') ?? 0;
$serviceCharge = $request->input('serviceCharge') ?? 0;
$total = $request->input('amount') ?? $request->input('total') ?? 0;
$main = TicketMain::create([
'subtotal' => $subtotal,
'service_charge' => $serviceCharge,
'total' => $total,
'pin_internal' => $pin_internal,
'pin_tercero' => $pin_tercero,
'user_id_log' => $user_id,
'seller_user_id' => $seller_id,
'origin' => 'web',
]);
$log_tickets_main = "";
if ($request->input('ticket_type_id') != TicketTypesEnum::SUBSCRIBER) {
foreach ($request->input('tickets') as $ticket) {
$zone_id = $ticket["seat"]["zone_id"];
$event_id = $ticket["match_event_id"];
$seat_id = $ticket["seat"]["id"];
$log_tickets_main = $log_tickets_main . "zone: " . $zone_id . "event: " . $event_id . "seat: " . $seat_id . "\n";
// creamos los bloqueos
$data = $this->validateSell($zone_id, $event_id, $seat_id, $user_id, $ticket["ticket_type_id"], $main->id, $request->input('type_process'), 0, $pin);
$response = json_decode($data->getContent());
if (!$response->r) {
DB::rollback();
return $data;
break;
}
}
} else {
$log_tickets_main = 'Abonado, user_id: ' . $user_id;
$listEvents = $this->getEventsSubscription($request->input('season_id'), $request->input('match_event_id'));
if ($listEvents && count($listEvents) > 0) {
foreach ($request->input('tickets') as $ticket) {
foreach ($listEvents as $event) {
$zone_id = $ticket["seat"]["zone_id"];
$event_id = $event->id;
$seat_id = $ticket["seat"]["id"];
if (isset($ticket["dataTicket"]) && !$ticket["dataTicket"]["checkedCtrl"]) {
$user = $userController->searchUser($ticket["dataTicket"]["document"], $ticket["dataTicket"]["email_user"], $ticket["dataTicket"]["first_name"], $ticket["dataTicket"]["last_name"], $ticket["dataTicket"]["phone"], true);
if (!$user) {
$custom_request = new Request([
'first_name' => $ticket["dataTicket"]["first_name"],
'last_name' => $ticket["dataTicket"]["last_name"],
'phone' => $ticket["dataTicket"]["phone"],
'email' => $ticket["dataTicket"]["email_user"],
'password' => $ticket["dataTicket"]["phone"] + $ticket["dataTicket"]["document"],
'document' => $ticket["dataTicket"]["document"],
]);
$current_user = $userController->createClient($custom_request, $is_ticket = true, $validateByDocument = true);
if ($current_user["r"]) {
$user = $current_user["d"];
$user_id = $user->id;
} else {
DB::rollback();
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "validateUserByTicket", "m" => __('messages.error_global'), "data" => $current_user));
break;
}
}
$ticket["dataTicket"]["checkedCtrl"] = true;
}
// creamos los bloqueos
$data = $this->validateSell($zone_id, $event_id, $seat_id, $user_id, $ticket["ticket_type_id"], $main->id, $request->input('type_process'), 0, $pin);
$response = json_decode($data->getContent());
if (!$response->r) {
DB::rollback();
return $data;
break;
}
}
}
}
}
$main->comment_purchase_log = $log_tickets_main;
$main->update();
DB::commit();
return $data;
} catch (\Throwable $th) {
DB::rollback();
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "createBlock", "m" => __('messages.error_global'), "data" => $th->getMessage()));
}
}
public function getMatchEventsSuscription(Request $request)
{
try {
$list_match_events = $this->getEventsSubscription($request->input('season_id'), $request->input('match_event_id'));
$team_main = Team::where([['is_main', true], ['active', true]])->first();
return response(array("r" => true, "type" => "success", "title" => "", "m" => "", "data" => array('list_match_events' => $list_match_events, 'team_main' => $team_main)));
} catch (\Throwable $th) {
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "getMatchEventsSuscription", "m" => __('messages.error_global'), "data" => $th->getMessage()));
}
}
/*
@tickets Type TicketUserBlock listado de bloqueos.
@ticket_main_id Type int id de la cabecera de ticketes.
*/
public function generateTickets($tickets, $ticket_main_id, $isBackup = false)
{
DB::beginTransaction();
try {
// Validar reserva de abonos para fijar que ya estan pagos y tiene asociados los tiquetes
$parameters = Parameter::select('presuscription', 'web_presuscription')->first();
if ($parameters->presuscription || $parameters->web_presuscription) {
$seats = $tickets->where('ticket_type_id', TicketTypesEnum::SUBSCRIBER)->pluck('seat_id');
if (count($seats) > 0) {
try {
$user = User::where('id', $tickets[0]->user_id)->first();
PreSubscriber::where('payment', false)->where('email', $user->email)->whereIn('seat_id', $seats)->update(['payment' => true]);
Mail::to($user->email)->send(new NewSuscriptorMail($user->first_name . " " . $user->last_name));
} catch (\Exception $e) {
$error = [
'tickets' => $tickets,
'ticket_main_id' => $ticket_main_id,
'isBackup' => $isBackup,
'message' => $e->getMessage(),
'getFile' => $e->getFile(),
'getLine' => $e->getLine(),
];
$this->util->logFile(json_encode($error), 'sendListMail');
}
}
}
$data = response(array("r" => false, "type" => "", "title" => "", "m" => "No se ha podido generar las boletas.", "data" => ""));
foreach ($tickets as $key => $t) {
// eliminamos el bloqueo.
if (!$isBackup) {
$this->deleteBlock($t->seat_id, $t->match_event_id, $t->user_id);
} else {
$this->deleteBlockBackup($t->seat_id, $t->match_event_id, $t->user_id);
}
// Validamos la silla y creamos el ticket
$data = $this->validateSell($t->zone_id, $t->match_event_id, $t->seat_id, $t->user_id, $t->ticket_type_id, $ticket_main_id, 'ticket', $t->price);
$response = json_decode($data->getContent());
if (!$response->r) {
if ($isBackup) {
// Validar si hay alguna silla disponible, caso contrario hacer ROLLBACK
$dataOptional = $this->validateOptionalSeatForSell($t);
$responseOptional = json_decode($dataOptional->getContent());
if ($responseOptional->r) {
$data = $dataOptional;
continue;
}
DB::rollback();
return $data;
break;
}
DB::rollback();
return false;
break;
}
}
DB::commit();
$this->dispatchTicketProcesses(['ticketMainId' => $ticket_main_id]);
if ($isBackup) {
return $data;
}
return true;
} catch (\Throwable $th) {
DB::rollback();
return false;
}
}
public function createLogTicket($state_id, $ticket_id)
{
try {
$ticketLog = TicketLog::create(['ticket_id' => $ticket_id, 'ticket_status_id' => $state_id]);
if (Auth::user()) {
$this->registerLog(Auth::user()->id, 'Actualizó estado boleta', json_encode($ticketLog), "Update", 'Boleteria');
}
return response(array("r" => true, "type" => "success", "title" => "", "m" => "", "data" => null));
} catch (\Throwable $th) {
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "createLogTicket", "m" => __('messages.error_global'), "data" => $th->getMessage()));
}
}
public function changeStateTicket(Request $request)
{
try {
if ($request->state_id != 3 && $request->state_id != 4) {
return response(array("r" => false, "type" => "error", "title" => "Oops...", "m" => __('messages.state_invalid'), "data" => null));
}
$ticket = Ticket::where('id', $request->ticket_id)->with('seat')->first();
if ($ticket->update(['ticket_status_id' => $request->state_id])) {
$this->createLogTicket($request->state_id, $request->ticket_id);
}
return response(array("r" => true, "type" => "success", "title" => "Ok", "m" => __('messages.updated_successfully'), "data" => null));
} catch (\Throwable $th) {
return response(array("r" => false, "type" => "error", "title" => "Oops...", "m" => __('messages.error_global'), "data" => $th->getMessage()));
}
}
public function massiveStateChange(Request $request)
{
try {
if (!$request->hasFile('archivo') || !$request->file('archivo')->isValid()) {
return ['r' => false, 'm' => 'Archivo inválido o no recibido.'];
}
ini_set('memory_limit', '2048M');
$file = new CancelTicketsImport;
$file->request = $request;
Excel::import($file, $request->archivo);
return response(array("r" => true, 'd' => $file->answer, "m" => __('messages.match_event_tickets.title_24'), "data" => null));
} catch (\Exception $e) {
return response(array('r' => false, 'd' => null, 'm' => trans('messages.match_event_tickets.title_25') . $request->name_file . " " . $e->getMessage()));
}
}
/**
* Update the specified resource in storage.
*
*/
public function update(Request $request)
{
$user = User::find($request["user_id"]);
$user->first_name = $request["first_name"];
$user->last_name = $request["last_name"];
$user->document = $request["document"];
$user->phone = $request["phone"];
$user->email = $request["email"];
$user->update();
if ($user) {
return array('r' => true, 'd' => array('id' => $user->id), 'm' => trans('messages.updated_successfully'));
} else {
return array('r' => false, 'd' => null, 'm' => trans('messages.error_updating'));
}
}
public function updateTicket(Request $request)
{
$oldTicket = Ticket::find($request->id);
$updated = Ticket::where([
'id' => $request->id,
])->update($request->all());
sleep(1);
if ($updated) {
$data = [
'oldTicket' => $oldTicket,
'newTicket' => Ticket::find($request->id),
];
$this->registerLog(Auth::user()->id, 'Actualización de boleta', json_encode($data), "Update", 'Boleteria');
return array('r' => true, 'm' => trans('messages.updated_successfully'));
} else {
return array('r' => false, 'm' => trans('messages.error_updating'));
}
}
public function toUpdateUsersWithTickets(Request $request)
{
$updated = Ticket::where([
'match_event_id' => $request->event_id,
'user_id' => $request->oldUserId,
'code_ticket' => $request->code_ticket,
])->update(['user_id' => $request->newUserId]);
sleep(1);
if ($updated) {
$data = [
'oldUser' => User::find($request->oldUserId),
'newUser' => User::find($request->newUserId),
'ticket' => Ticket::where('code_ticket', $request->code_ticket)->first(),
];
$this->registerLog(Auth::user()->id, 'Cambio de usuario boleteria', json_encode($data), "Update", 'Boleteria');
return array('r' => true, 'm' => trans('messages.updated_successfully'));
} else {
return array('r' => false, 'm' => trans('messages.error_updating'));
}
}
public function sendSingleEmailTicket($userId, $code)
{
$user = User::find($userId);
try {
Mail::to($user->email)->send(new TicketPurchaseMail($user, $code));
$this->updateSentEmailIndicatorInTicket($code);
return array('r' => true, 'm' => 'Mail enviado');
} catch (\Exception $err) {
$log = array(
'error' => $err->getMessage(),
'user' => $user,
'code' => $code
);
$this->util->logFile(json_encode($log), 'sendSingleEmailTicket');
return array('r' => false, 'm' => 'Mail no enviado');
}
}
public function sendEmailMultipleTickets($userId, $ticketsToSendByMail, $ticketMainId, $matchEventId)
{
$user = User::find($userId);
try {
Mail::to($user->email)->send(new TicketPurchaseEmailList($ticketsToSendByMail, $ticketMainId, $matchEventId, $user));
$this->updateSentEmailIndicatorInTickets($ticketsToSendByMail);
return array('r' => true, 'm' => 'Mail enviado');
} catch (\Exception $err) {
$log = array(
'error' => $err->getMessage(),
'user' => $user,
'ticketsToSendByMail' => $ticketsToSendByMail,
'ticket_main' => $ticketMainId,
'match_event' => $matchEventId
);
$this->util->logFile(json_encode($log), 'sendEmailMultipleTickets');
return array('r' => false, 'm' => 'Mail no enviado');
}
}
public function sendEmailMultipleLinksTickets($userId, $ticketsToSendByMail, $ticketTypeId, $matchEventId)
{
$user = User::find($userId);
try {
Mail::to($user->email)->send(new TicketPurchaseEmailListMultiple($ticketsToSendByMail, $ticketTypeId, $matchEventId, $user));
$this->updateSentEmailIndicatorInTickets($ticketsToSendByMail);
return array('r' => true, 'm' => 'Mail enviado');
} catch (\Exception $err) {
$log = array(
'error' => $err->getMessage(),
'user' => $user,
'ticketsToSendByMail' => $ticketsToSendByMail,
'ticket_type' => $ticketTypeId,
'match_event' => $matchEventId
);
$this->util->logFile(json_encode($log), 'sendEmailMultipleLinksTickets');
return array('r' => false, 'm' => 'Mail no enviado');
}
}
private function updateSentEmailIndicatorInTicket($codeTicket)
{
$ticket = Ticket::where('code_ticket', $codeTicket)->first();
if (!$ticket || $ticket->is_an_email_sent == 1) {
return;
}
$ticket->is_an_email_sent = 1;
$ticket->update();
}
private function updateSentEmailIndicatorInTickets($tickets)
{
foreach ($tickets as $ticket) {
$this->updateSentEmailIndicatorInTicket($ticket->code_ticket);
}
}
public function updateTicketNotification($ticketMain, $ticketNotification)
{
if (!$ticketMain || !$ticketNotification) {
return;
}
$ticketMain->ticket_notification = $ticketNotification;
$ticketMain->update();
}
public function isCompletedTicketNotification($ticketMain)
{
return in_array($ticketMain->ticket_notification, [TicketNotificationEnum::COMPLETED, TicketNotificationEnum::NOTIFICATION_COMPLETED, TicketNotificationEnum::BILLING_COMPLETED]);
}
public function validateMails()
{
$ticketMains = DB::table('tickets as t')
->select(
'tm.id'
)
->join('ticket_mains as tm', 'tm.id', '=', 't.ticket_main_id')
->join('match_events as me', 'me.id', '=', 't.match_event_id')
->where(function ($query) {
$query->where('t.is_an_email_sent', 0)
->orWhere(function ($query1) {
$query1->where('tm.ticket_notification', '=', TicketNotificationEnum::PENDING)->whereNull('tm.cufe');
});
})
->whereIn('t.ticket_status_id', [TicketStatusEnum::PURCHASED, TicketStatusEnum::CREATED])
->where('me.event_end_sale', '>', DB::raw("CONVERT_TZ(NOW(), 'system', 'America/Bogota')"))
->where('t.created_at', '>', DB::raw("DATE_SUB(CONVERT_TZ(NOW(), 'system', 'America/Bogota'), INTERVAL 24 HOUR)"))
->groupBy('tm.id')
->get();
if (count($ticketMains) == 0) {
return array(
'r' => false,
'm' => 'No se encontraron transacciones pendientes de validacion de procesos.'
);
}
foreach ($ticketMains as $ticketMain) {
$this->dispatchTicketProcesses(['ticketMainId' => $ticketMain->id]);
}
return array(
'r' => true,
'm' => 'Se validaron ' . count($ticketMains) . ' transaciones pendientes de validacion de procesos.'
);
}
public function sendMassSmsNotifications($userId, $code)
{
try {
$dataUser = User::select('id', 'first_name', 'phone')->find($userId);
event(new SmsNotificationEvent($dataUser, $code));
return array('r' => true, 'm' => trans('SMS enviado'));
} catch (\Exception $e) {
return array('r' => false, 'm' => trans('SMS no enviado'));
}
}
public function getPin($url_key)
{
$corporateIdentity = CorporateIdentity::first();
return view("tickets.getPin", compact('url_key', 'corporateIdentity'));
}
public function getAttachmentFromPublic(Request $request)
{
$decrypted = "";
$url_key = $request->url_key;
$key = $request->key;
if (!$key) {
return array('Debes ingresar el pin enviado a tu correo');
}
try {
$decrypted = Crypt::decryptString($url_key);
} catch (\Exception $exx) {
return array('Error ' . $exx->getMessage());
}
if (!$decrypted) {
return array('Error de descifrado');
}
$decrypted = explode('|', $decrypted);
if ($decrypted[0] != $key) {
return array('Pin no válido. Revisa el pin enviado a tu correo');
}
if ($decrypted[3] == 'lista') {
$user_id = $decrypted[1];
$match_event_id = $decrypted[2];
$ticket_type_id = $decrypted[4];
$tickets = Ticket::select('tickets.*')
->where('user_id', $user_id)
->where('match_event_id', $match_event_id)
->where('ticket_type_id', $ticket_type_id)
->whereIn('ticket_status_id', [TicketStatusEnum::PURCHASED, TicketStatusEnum::CREATED])
->get();
return $this->downloadZipTickets($tickets, $user_id, $match_event_id);
}
if ($decrypted[3] == 'cortesia') {
$user_id = $decrypted[1];
$match_event_id = $decrypted[2];
$tickets = Ticket::select('tickets.*')
->where('user_id', $user_id)
->where('match_event_id', $match_event_id)
->where('ticket_type_id', TicketTypesEnum::COMPLIMENTARY)
->whereIn('ticket_status_id', [TicketStatusEnum::PURCHASED, TicketStatusEnum::CREATED])
->get();
return $this->downloadZipTickets($tickets, $user_id, $match_event_id);
}
if ($decrypted[3] == 'ticket') {
$code = $decrypted[2];
return $this->printTicket($code);
}
}
public function downloadTicketForUser(Request $request)
{
$decrypted = "";
$data = $request->data;
try {
$decrypted = Crypt::decryptString($data);
} catch (\Exception $exx) {
return array('Error de peticion, detalle: ' . $exx->getMessage());
}
if (!$decrypted) {
return array('Error de peticion, detalle: ' . 'Error de descifrado');
}
if (str_contains($decrypted, 'type=pdf')) {
if (str_contains($decrypted, 'codes=')) {
parse_str($decrypted, $params);
$codes = $params['codes'] ?? null;
if (!$codes) {
return array('No se encontraron tickets');
}
return $this->printTickets($codes);
} else {
parse_str($decrypted, $params);
$userId = $params['user_id'] ?? null;
$matchEventId = $params['match_event_id'] ?? null;
$ticketMainId = $params['ticket_main_id'] ?? null;
$tickets = Ticket::select('tickets.code_ticket')
->where('user_id', $userId)
->where('match_event_id', $matchEventId)
->where('ticket_main_id', $ticketMainId)
->whereIn('ticket_status_id', [TicketStatusEnum::PURCHASED, TicketStatusEnum::CREATED])
->pluck('code_ticket')
->toArray();
if (!count($tickets)) {
return array('No se encontraron tickets');
}
$codes = implode(',', $tickets);
return $this->printTickets($codes);
}
} else if (str_contains($decrypted, 'type=zip')) {
if (str_contains($decrypted, 'codes=')) {
parse_str($decrypted, $params);
$codes = $params['codes'] ?? null;
$tickets = Ticket::select('tickets.*')
->whereIn('code_ticket', explode(',', $codes))
->whereIn('ticket_status_id', [TicketStatusEnum::PURCHASED, TicketStatusEnum::CREATED])
->get();
if (!count($tickets)) {
return array('No se encontraron tickets');
}
return $this->downloadZipTickets($tickets, $tickets->first()->user_id, $tickets->first()->match_event_id);
} else {
parse_str($decrypted, $params);
$userId = $params['user_id'] ?? null;
$matchEventId = $params['match_event_id'] ?? null;
$ticketMainId = $params['ticket_main_id'] ?? null;
$tickets = Ticket::select('tickets.*')
->where('user_id', $userId)
->where('match_event_id', $matchEventId)
->where('ticket_main_id', $ticketMainId)
->whereIn('ticket_status_id', [TicketStatusEnum::PURCHASED, TicketStatusEnum::CREATED])
->get();
if (!count($tickets)) {
return array('No se encontraron tickets');
}
return $this->downloadZipTickets($tickets, $userId, $matchEventId);
}
} else if (str_contains($decrypted, ',')) {
return $this->printTickets($decrypted);
} else {
return $this->printTicket($decrypted);
}
}
public function printTicket($code, $type = "base64")
{
$printTicketController = new PrintTicketController;
return $printTicketController->printTicketForMassMail($code, $type);
}
public function printTickets($codes)
{
$printTicketController = new PrintTicketController;
return $printTicketController->printTickets($codes);
}
public function viewTicket($code)
{
return $this->printTicket($code);
}
public function viewTickets($tickets)
{
return $this->printTickets($tickets);
}
public function downloadZipTickets($tickets, $user_id, $match_event_id, $fileName = "")
{
if (!$fileName) {
$fileName = time();
}
if ($tickets) {
$pdfAttachment = [];
// Generar todos los PDF, uno por uno
foreach ($tickets as $t) {
$pdfAttachment[] = $this->printTicket($t->code_ticket, "file");
}
// Los comprimo y envío a descargar.
$zipFilename = "tickets-$user_id-$match_event_id-$fileName.zip";
Madzipper::make("tickets_tmp/$zipFilename")->add($pdfAttachment)->close();
$file = public_path() . "/tickets_tmp/$zipFilename";
$headers = array('Content-Type: application/zip');
return Response::download($file, "$zipFilename", $headers);
}
}
public function getPinMultiple($url_key)
{
$corporateIdentity = CorporateIdentity::first();
return view("tickets.getPinMultiple", compact('url_key', 'corporateIdentity'));
}
function countTicketsAndGetLinks(Request $request)
{
$decrypted = "";
$url_key = $request->url_key;
$key = $request->key;
if (!$key) {
return array('Debes ingresar el pin enviado a tu correo');
}
try {
$decrypted = Crypt::decryptString($url_key);
} catch (\Exception $exx) {
return array('Error ' . $exx->getMessage());
}
if (!$decrypted) {
return array('Error de descifrado');
}
$decrypted = explode('|', $decrypted);
if ($decrypted[0] != $key) {
return array('Pin no válido. Revisa el pin enviado a tu correo');
}
if ($decrypted[3] == 'multiple') {
$user_id = $decrypted[1];
$match_event_id = $decrypted[2];
$ticket_type_id = $decrypted[4];
$user = User::find($user_id);
$match = MatchEvent::find($match_event_id);
$ticket_type = TicketType::find($ticket_type_id);
if (!$user) {
return array('Error' => 'Revise datos usuario');
}
if (!$match) {
return array('Error' => 'Revise datos evento');
}
if (!$ticket_type) {
return array('Error' => 'Revise datos tipo ticket');
}
$total = Ticket::select('id', 'code_ticket', 'user_id')
->where('user_id', $user_id)
->where('match_event_id', $match_event_id)
->where('ticket_type_id', $ticket_type_id)
->whereIn('ticket_status_id', [TicketStatusEnum::PURCHASED, TicketStatusEnum::CREATED])
->count();
$limitPerPage = 100;
$pages = ceil($total / $limitPerPage);
$skip = 0;
$arrayLinks = array();
for ($i = 0; $i < $pages; $i++) {
$arrayLinks[] = "/download_ticket_for_user/links/$user_id/$match_event_id/$ticket_type_id/$limitPerPage/$skip";
$skip = $skip + $limitPerPage;
}
return view('tickets.links')
->with('total', $total)
->with('links', $arrayLinks)
->with('user', $user)
->with('match', $match)
->with('ticket_type', $ticket_type);
}
return array('Error');
}
function downloadLinks($user_id, $match_event_id, $ticket_type_id, $take, $skip)
{
$tickets = Ticket::select('id', 'code_ticket', 'user_id')
->where('user_id', $user_id)
->where('match_event_id', $match_event_id)
->where('ticket_type_id', $ticket_type_id)
->whereIn('ticket_status_id', [TicketStatusEnum::PURCHASED, TicketStatusEnum::CREATED])
->skip($skip)
->take($take)
->get();
return $this->downloadZipTickets($tickets, $user_id, $match_event_id, (($skip / 100) + 1));
}
function validateDownloadPanelTickets($email, $match_event_id, $from_date = null, $to_date = null, $type = null)
{
$user = User::select('id')->where('email', $email)->first();
if (!$user) {
$error_message = "No se ha encontrado usuario para este mail.";
return response()->json(['success' => false, 'message' => $error_message]);
}
if ($from_date && is_numeric($from_date)) {
$type = $from_date;
$from_date = null;
}
$tickets = DB::table('tickets')
->select(['tickets.id', 'tickets.code_ticket', 'tickets.user_id'])
->where('tickets.user_id', $user->id)
->where('tickets.match_event_id', $match_event_id)
->whereIn('tickets.ticket_status_id', [TicketStatusEnum::PURCHASED, TicketStatusEnum::CREATED])
->where(function ($query) use ($from_date, $to_date, $type) {
if ($from_date && $to_date) {
$query->whereBetween('tickets.created_at', [$from_date, $to_date]);
}
if ($type) {
$query->where('tickets.ticket_type_id', $type);
}
})
->count();
if ($tickets == 0) {
return response()->json(['success' => false, 'message' => 'No existen boletas a generar para el usuario']);
}
return response()->json(['success' => true, 'message' => 'Validación OK', 'data' => $tickets]);
}
function downloadPanelTickets($email, $match_event_id, $from_date = null, $to_date = null, $type = null)
{
$user = User::select('id')->where('email', $email)->first();
if ($from_date && is_numeric($from_date)) {
$type = $from_date;
$from_date = null;
}
$tickets = DB::table('tickets')
->select(['tickets.id', 'tickets.code_ticket', 'tickets.user_id'])
->where('tickets.user_id', $user->id)
->where('tickets.match_event_id', $match_event_id)
->whereIn('tickets.ticket_status_id', [TicketStatusEnum::PURCHASED, TicketStatusEnum::CREATED])
->where(function ($query) use ($from_date, $to_date, $type) {
if ($from_date && $to_date) {
$query->whereBetween('tickets.created_at', [$from_date, $to_date]);
}
if ($type) {
$query->where('tickets.ticket_type_id', $type);
}
})
->get();
$fecha = new DateTime();
return $this->downloadZipTickets($tickets, $user->id, $match_event_id, $fecha->getTimestamp());
}
public function massiveStateChangeTemplate()
{
return Excel::download(new CancelTicketsTemplate, trans('messages.match_event_tickets.title_22') . '.xlsx');
}
public function ticketTypeName($ticket)
{
if ($ticket->ticket_type_id != TicketTypesEnum::COMPLIMENTARY) {
return 'Boleta';
} else {
return 'Cortesia';
}
}
public function ticketSeatLocationFullText($ticket)
{
$seat = '';
if ($ticket) {
// Construir array con los partes del nombre
$parts = [
$ticket->seat->zone->zone->name,
$ticket->seat->zone->name,
$ticket->seat->letter->name . $ticket->seat->code
];
// Eliminar duplicados
$uniqueParts = [];
foreach ($parts as $part) {
if (!in_array($part, $uniqueParts)) {
$uniqueParts[] = $part;
}
}
// Unir con separador
$seat = implode(' - ', $uniqueParts);
}
return $seat;
}
public function validateOptionalSeatForSell($ticket)
{
$mainZone = null;
if ($ticket->seat && $ticket->seat->zone)
$mainZone = $ticket->seat->zone->zone_id;
$secondaryZone = $ticket->zone_id;
$zoneController = new ZonesController();
$zones = $zoneController->getAvailableZones($mainZone, $secondaryZone, $ticket->match_event_id);
foreach ($zones as $zone) {
$massiveFansController = new MassiveFansController();
$seats = $massiveFansController->getSeatsAvailableFromLocationAndEvent(
[
'zone_id' => $zone,
'quantity' => 1,
'match_event_id' => $ticket->match_event_id,
'validate_rules' => false
]
);
if (count($seats) > 0) {
$seat_id = $seats[0]->id;
$data = $this->validateSell($zone, $ticket->match_event_id, $seat_id, $ticket->user_id, $ticket->ticket_type_id, $ticket->ticket_main_id, 'ticket', $ticket->price);
$response = json_decode($data->getContent());
if ($response->r) {
return $data;
}
}
}
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "validateOptionalSeatForSell", "data" => $ticket));
}
public function getPendingMatchesTickets($ticket_id_origin, $tribune_id_final, $zone_id_final, $seat_id_final)
{
$userTicket = Ticket::with("match_event:id,season_id")->select("id", "user_id", "match_event_id", "seat_id", "ticket_type_id")->where('id', $ticket_id_origin)->first();
$pendingTickets = [];
if ($userTicket->ticket_type_id == TicketTypesEnum::SUBSCRIBER) {
$pendingTickets = Ticket::select("id", "code_ticket", "seat_id", "match_event_id", "door", "zone", "letter_seat", "code_seat")
->with("match_event:id,event_start,date_name,name")
->whereHas('match_event', function ($match_event) use ($userTicket) {
$match_event->where('event_start', '>=', Carbon::now());
$match_event->where('season_id', $userTicket->match_event->season_id);
})
->where('seat_id', $userTicket->seat_id)
->where('user_id', $userTicket->user_id)
->where('ticket_type_id', TicketTypesEnum::SUBSCRIBER)
->get();
} else {
$pendingTickets = Ticket::select("id", "code_ticket", "seat_id", "match_event_id", "door", "zone", "letter_seat", "code_seat")
->with("match_event:id,date_name,name")
->where('id', $userTicket->id)
->get();
}
return $pendingTickets;
}
public function postChangeSeat(Request $request)
{
$current_seat = Seat::select('code', 'zone_id', 'letter_id')->with('letter')->where('id', $request->seat_id_final)->first();
$name_seat = $current_seat->letter->name . $current_seat->code;
$zone = Zone::select('name', 'door_id')->where('id', $current_seat->zone_id)->first();
$door_name = null;
if ($zone && $zone->door_id) {
$c_q = Door::select('name')->where('id', $zone->door_id)->first();
if ($c_q) {
$door_name = $c_q->name;
}
}
$userTicket = Ticket::with("match_event:id,season_id")->select("id", "user_id", "match_event_id", "seat_id", "ticket_type_id")->where('id', $request->ticket_id_origin)->first();
// Abonados
if ($userTicket->ticket_type_id == TicketTypesEnum::SUBSCRIBER) {
$pendingTickets = Ticket::select("id", "code_ticket", "seat_id", "match_event_id", "door", "zone", "letter_seat", "code_seat")->with("match_event:id,event_start,date_name,name")
->whereHas('match_event', function ($match_event) use ($userTicket) {
$match_event->where('event_start', '>=', Carbon::now());
$match_event->where('season_id', $userTicket->match_event->season_id);
})
->where('seat_id', $userTicket->seat_id)
->where('user_id', $userTicket->user_id)
->where('ticket_type_id', TicketTypesEnum::SUBSCRIBER)
->get();
} else {
$pendingTickets = Ticket::select("id", "code_ticket", "seat_id", "match_event_id", "door", "zone", "letter_seat", "code_seat")
->where('id', $userTicket->id)
->get();
}
try {
DB::beginTransaction();
foreach ($pendingTickets as $p) {
$ticket_current = $this->existsTicket($request->seat_id_final, $p->match_event_id, $userTicket->user_id);
$ticket_block = $this->existsBlock($request->seat_id_final, $p->match_event_id, $userTicket->user_id);
if ($ticket_current) {
DB::rollback();
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "postChangeSeat", "m" => __('messages.error_validation_3', ['seat' => $name_seat]), "data" => null, 't' => $ticket_current));
}
if ($ticket_block) {
DB::rollback();
return response(array("r" => false, "type" => "error", "title" => "Oops...", "origin" => "postChangeSeat", "m" => __('messages.error_validation_4', ['seat' => $name_seat]), "data" => null, 't' => $ticket_block));
}
// Buscar ticket y actualizar.
$ticketToChange = Ticket::find($p->id);
$ticketToChange->seat_id = $request->seat_id_final;
$ticketToChange->zone = $zone->name;
$ticketToChange->letter_seat = $current_seat->letter->name;
$ticketToChange->code_seat = $current_seat->code;
$ticketToChange->door = $door_name;
$ticketToChange->update();
}
DB::commit();
} catch (\Exception $exx) {
DB::rollback();
return array('r' => false, 'm' => $exx->getMessage());
}
return array('r' => true, 'm' => 'Proceso exitoso');
}
public function getTotalByMatchCode($match_code)
{
$m = MatchEvent::select('id', 'name', 'event_start')->where('code', $match_code)->first();
if (!$m) {
return array('error' => 'El evento no existe');
}
$ticketsVendidos = Ticket::where('match_event_id', $m->id)
->where('ticket_status_id', [TicketStatusEnum::PURCHASED, TicketStatusEnum::CREATED])
->count();
$ticketsAnulados = Ticket::where('match_event_id', $m->id)
->where('ticket_status_id', TicketStatusEnum::CANCELLED)
->count();
return array(
'Evento' => $m->name,
'Hora inicio evento' => $m->event_start,
'Total vendidos - anulados' => $ticketsVendidos,
'Total anulados' => $ticketsAnulados,
'Total tickets vendidos + anulados' => ($ticketsVendidos + $ticketsAnulados)
);
}
public function exportMatchEventSeatsTemplate()
{
return Excel::download(new MatchEventSeatsTemplate, trans('messages.match_event_tickets.title_31') . '.xlsx');
}
public function importMatchEventSeats(Request $request)
{
try {
if (!$request->hasFile('archivo') || !$request->file('archivo')->isValid()) {
return ['r' => false, 'm' => 'Archivo inválido o no recibido.'];
}
ini_set('memory_limit', '2048M');
$file = new MatchEventSeatsImport($request->matchEventId);
$file->request = $request;
Excel::import($file, $request->archivo);
return array('r' => true, 'd' => $file->answer, 'm' => trans('messages.match_event_tickets.title_33') . ' ' . $file->edit['actualizados'] . ' actualizados.');
} catch (\Exception $e) {
return array('r' => false, 'd' => null, 'm' => trans('messages.match_event_tickets.title_34') . $request->name_file . " " . $e->getMessage());
}
}
public function exportMatchEventSpecialTextTemplate()
{
return Excel::download(new MatchEventSpecialTextTemplate, trans('messages.match_event_tickets.title_37') . '.xlsx');
}
public function importMatchEventSpecialText(Request $request)
{
try {
if (!$request->hasFile('archivo') || !$request->file('archivo')->isValid()) {
return ['r' => false, 'm' => 'Archivo inválido o no recibido.'];
}
ini_set('memory_limit', '2048M');
$file = new MatchEventSpecialTextImport($request->matchEventId);
$file->request = $request;
Excel::import($file, $request->archivo);
return array('r' => true, 'd' => $file->answer, 'm' => trans('messages.match_event_tickets.title_33') . ' ' . $file->edit['actualizados'] . ' actualizados.');
} catch (\Exception $e) {
return array('r' => false, 'd' => null, 'm' => trans('messages.match_event_tickets.title_34') . $request->name_file . " " . $e->getMessage());
}
}
public function getSeatFreeByZonesOrSeat($match_event_id, $zones, $seat = null)
{
$matchEvent = MatchEvent::with('season')->where('id', $match_event_id)->first();
$parameters = Parameter::select('presuscription')->first();
$presubscriptionActive = $parameters->presuscription && $matchEvent->season->is_suscription;
$freeSeat = null;
if ($seat) {
$freeSeat = Seat::with('letter')
->where('id', $seat)
->whereNotIn('id', function ($query) use ($match_event_id) {
$query->select('seat_id')->from('ticket_user_blocks')->where('match_event_id', $match_event_id);
}) // Sin bloqueos
->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]);
}) // Que no este vendida
->whereNotIn('id', function ($query) use ($match_event_id) {
$query->select('seat_id')->from('match_event_stages')->where('match_event_id', $match_event_id)->where('stage_type_id', StageTypesEnum::BLOCK_SEAT);
}) // Que no este bloqueada para el evento
->when($presubscriptionActive, function ($query) {
$query->whereNotIn('id', function ($query) {
$query->select('seat_id')->from('pre_subscribers')->where(function ($query1) {
$query1->where('payment', 1)->orWhere('is_credit', 1);
});
});
}) // Que no este reservada para un abonado
->first();
}
if (!$freeSeat) {
$freeSeat = Seat::with('letter')
->whereIn('zone_id', $zones)
->whereNotIn('id', function ($query) use ($match_event_id) {
$query->select('seat_id')->from('ticket_user_blocks')->where('match_event_id', $match_event_id);
}) // Sin bloqueos
->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]);
}) // Que no este vendida
->whereNotIn('id', function ($query) use ($match_event_id) {
$query->select('seat_id')->from('match_event_stages')->where('match_event_id', $match_event_id)->where('stage_type_id', StageTypesEnum::BLOCK_SEAT);
}) // Que no este bloqueada para el evento
->when($presubscriptionActive, function ($query) {
$query->whereNotIn('id', function ($query) {
$query->select('seat_id')->from('pre_subscribers')->where(function ($query1) {
$query1->where('payment', 1)->orWhere('is_credit', 1);
});
});
}) // Que no este reservada para un abonado
->first();
}
return $freeSeat;
}
public function changeFreeSeatToTicket($ticket, $freeSeat, $specialTicket = null)
{
$current_seat = Seat::select('code', 'zone_id', 'letter_id')->with('letter')->where('id', $freeSeat)->first();
$name_seat = $current_seat->letter->name . $current_seat->code;
$zone = Zone::select('name', 'door_id')->where('id', $current_seat->zone_id)->first();
$door_name = null;
if ($zone && $zone->door_id) {
$c_q = Door::select('name')->where('id', $zone->door_id)->first();
if ($c_q) {
$door_name = $c_q->name;
}
}
$userTicket = Ticket::with("match_event:id,season_id")->select("id", "user_id", "match_event_id", "seat_id", "ticket_type_id")->where('id', $ticket)->first();
$pendingTickets = array();
// Abonados
if ($userTicket->ticket_type_id == TicketTypesEnum::SUBSCRIBER) {
$pendingTickets = Ticket::select("id", "code_ticket", "seat_id", "match_event_id", "door", "zone", "letter_seat", "code_seat")->with("match_event:id,event_start,date_name,name")
->whereHas('match_event', function ($match_event) use ($userTicket) {
$match_event->where('event_start', '>=', Carbon::now());
$match_event->where('season_id', $userTicket->match_event->season_id);
})
->where('seat_id', $userTicket->seat_id)
->where('user_id', $userTicket->user_id)
->where('ticket_type_id', TicketTypesEnum::SUBSCRIBER)
->get();
} else if ($userTicket->ticket_type_id == TicketTypesEnum::FREE_SALE) {
$pendingTickets = Ticket::select("id", "code_ticket", "seat_id", "match_event_id", "door", "zone", "letter_seat", "code_seat")
->where('id', $userTicket->id)
->get();
}
if (count($pendingTickets) == 0) {
$pendingTickets[] = $userTicket;
}
try {
foreach ($pendingTickets as $p) {
$ticket_current = $this->existsTicket($freeSeat, $p->match_event_id, $userTicket->user_id);
$ticket_block = $this->existsBlock($freeSeat, $p->match_event_id, $userTicket->user_id);
if ($ticket_current) {
return array("r" => false, "m" => __('messages.error_validation_3', ['seat' => $name_seat]));
}
if ($ticket_block) {
return array("r" => false, "m" => __('messages.error_validation_4', ['seat' => $name_seat]));
}
// Buscar ticket y actualizar.
$ticketToChange = Ticket::find($p->id);
$ticketToChange->seat_id = $freeSeat;
$ticketToChange->zone = $zone->name;
$ticketToChange->letter_seat = $current_seat->letter->name;
$ticketToChange->code_seat = $current_seat->code;
$ticketToChange->door = $door_name;
if ($specialTicket != null)
$ticketToChange->special_text = $specialTicket;
$ticketToChange->update();
}
} catch (\Exception $exx) {
return array('r' => false, 'm' => $exx->getMessage());
}
return array('r' => true, 'm' => 'Proceso exitoso');
}
public function parameterViewTicket()
{
$parameters = $this->ticketParametersService->getParameterObject();
if (property_exists($parameters, 'qrcode_size')) {
$parameters->qrcode_size = round($parameters->qrcode_size / 37.7952755906, 1);
} else {
$parameters->qrcode_size = null;
}
return view('tickets.parameters', compact('parameters'));
}
public function saveParameters(Request $request)
{
return $this->ticketParametersService->saveParameters($request);
}
public function tableFilterTicketUserLogs($events = null, $types = null, $from_date = null, $to_date = null)
{
DB::statement("SET sql_mode = ''");
$obj = $obj = DB::table('ticket_user_logs')
->select(
'ticket_user_logs.id',
'ticket_user_logs.ticket_id',
'ticket_user_logs.previous_user_id AS previousUser',
'ticket_user_logs.new_user_id AS newUser',
'ticket_user_logs.payment_reference',
'ticket_user_logs.number_transfers',
'tickets.code_ticket AS codeTicket',
'previous_user.email AS previousUserEmail',
'new_user.email AS newUserEmail',
DB::raw('CONCAT(match_events.name, " - ",DATE_FORMAT(match_events.event_start, "%Y-%m-%d %h:%i %p")) AS event_'),
DB::raw('DATE_FORMAT(ticket_user_logs.created_at, "%Y-%m-%d %h:%i %p") AS date_'),
'ticket_types.name AS type'
)
->leftjoin('tickets', 'tickets.id', '=', 'ticket_user_logs.ticket_id')
->leftjoin('ticket_types', 'ticket_types.id', '=', 'tickets.ticket_type_id')
->leftjoin('users AS previous_user', 'previous_user.id', '=', 'ticket_user_logs.previous_user_id')
->leftjoin('users AS new_user', 'new_user.id', '=', 'ticket_user_logs.new_user_id')
->leftjoin('match_events', 'match_events.code', '=', 'tickets.code_event');
if ($events && $events != 'null') {
$obj->whereIn('match_events.id', explode(',', $events));
}
if ($types && $types != 'null') {
$obj->whereIn('tickets.ticket_type_id', explode(',', $types));
}
if ($from_date && $from_date != 'null') {
$obj->whereDate('ticket_user_logs.created_at', '>=', $from_date);
}
if ($to_date && $to_date != 'null') {
$obj->whereDate('ticket_user_logs.created_at', '<=', $to_date);
}
DB::statement("SET sql_mode = 'STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'");
\DB::enableQueryLog();
$dataTable = DataTables::of($obj)
->addColumn('actions', function ($obj) {
return '
<i class="fa fa-pencil iconMini" onClick="clickEdit(' . $obj->id . ')" data-id="' . $obj->id . '" data-toggle="tooltip" data-placement="bottom" style="cursor:pointer;"></i>
<i class="fa fa-trash iconMini" onClick="clickDelete(' . $obj->id . ')" data-id="' . $obj->id . '" data-toggle="tooltip" data-placement="bottom" style="cursor:pointer;"></i>
';
})
->rawColumns(['actions']);
$response = $dataTable->make(true);
$data = $response->getData();
$data = json_decode(json_encode($data), true);
$queries = \DB::getQueryLog();
$data['queries'] = $queries;
return $data;
}
public function listTicketUserLogs()
{
$events = MatchEvent::select('id', 'name', DB::raw('DATE_FORMAT(event_start, "%Y-%m-%d %h:%i %p") as event_start'), 'active')
->orderBy('name', 'ASC')
->get();
$types = TicketType::select('id', 'name')->where('active', true)->get();
return view('tickets.listTicketUserLog', compact('events', 'types'));
}
public function createTicketsMatchByQuery($matchEventReferenceId, $type = 2, $matchEventCopyId)
{
$matchEventId = $matchEventCopyId;
try {
if (in_array(Auth::user()->rol->id, [$this->__SUPERADMIN_ROL])) {
$tickets = DB::table('tickets as t')
->select('t.*')
->where('t.match_event_id', $matchEventReferenceId)
->where('t.ticket_type_id', $type)
->get();
$response = [];
foreach ($tickets as $ticket) {
$response[] = $this->createTicket(
[
'seat_id' => $ticket->seat_id,
'match_event_id' => $matchEventId,
'user_id' => $ticket->user_id,
'ticket_type_id' => $ticket->ticket_type_id,
'ticket_main_id' => $ticket->ticket_main_id,
'price' => $ticket->price
]
);
}
return 'Proceso ejecutado exitosamente: Total boletas generadas => ' . count($response);
}
return 'Proceso no ejecutado por permisos';
} catch (\Throwable $th) {
return $th->getMessage();
}
}
public function generateTicketsByReferenceOrTicketMain(Request $request, $reference = null, $ticketMainId = null)
{
if ($reference && $reference == 'null') {
$reference = null;
}
if (Auth::user()) {
$data = [
'reference' => $reference,
'ticketMainId' => $ticketMainId
];
$this->registerLog(Auth::user()->id, 'Crear boletas manualmente por referencia', json_encode($data), "Create", $this->getModule($request));
}
$ticketMain = TicketMain::with(['ticket_user_block_backups' => function ($q) {
$q->where('ticket_user_block_backups.is_social_distancing', false);
}])
->when($reference, function ($q) use ($reference) {
$q->where('payment_reference', $reference);
})
->when($ticketMainId, function ($q) use ($ticketMainId) {
$q->where('id', $ticketMainId);
})
->first();
if (!$ticketMain) {
return array('r' => false, 'm' => 'Proceso no ejecutado, debido a que no existe la reserva');
}
if (!$ticketMain->ticket_user_block_backups->isEmpty()) {
$statusGenerateTickets = $this->generateTickets($ticketMain->ticket_user_block_backups, $ticketMain->id, true);
$response = json_decode($statusGenerateTickets->getContent());
if ($response->r) {
$ticketMain->payment_state = "CONFIRMED";
$ticketMain->payment_comment = 'APPROVED';
$ticketMain->update();
return array('r' => true, 'm' => 'Proceso ejecutado exitosamente: ' . json_encode($response));
}
return array('r' => false, 'm' => 'Proceso no ejecutado, debido a: ' . json_encode($response));
}
return array('r' => false, 'm' => 'Proceso no ejecutado, debido a que no existen bloqueos de sillas');
}
public function getDetailNameZonesEvent($eventIdOrCode)
{
$data = DB::table('tickets as t')
->select(DB::raw('CONCAT(z1.name, IF(t.special_text IS NOT NULL, CONCAT("_", t.special_text), "")) AS tags'), DB::raw('COUNT(*) AS total'))
->join('seats as s', 's.id', '=', 't.seat_id')
->join('zones as z', 'z.id', '=', 's.zone_id')
->join('zones as z1', 'z1.id', '=', 'z.zone_id')
->where('t.ticket_status_id', TicketStatusEnum::PURCHASED)
->when($eventIdOrCode, function ($query) use ($eventIdOrCode) {
$query->where('t.code_event', $eventIdOrCode);
})
->groupBy('tags')
->orderBy('total', 'ASC')
->get();
$table = '<table>
<tr>
<th>Tribuna</th>
<th></th>
<th>Boletas</th>
</tr>';
$totalTickets = 0;
foreach ($data as $item) {
$table .= '<tr>' .
'<td>' . $item->tags . '</td>' .
'<td>' . '</td>' .
'<td>' . $item->total . '</td>' .
'</tr>';
$totalTickets += $item->total;
}
$table .= '<tr>
<th>Total</th>
<th></th>
<th>' . $totalTickets . '</th>
</tr>';
$table .= '</table>';
return $table;
}
public function getEventCapacity($eventIdOrCode)
{
$soldTickets = DB::table('tickets')
->select(
'zsub.name AS tribune',
DB::raw("z.name AS sector"),
'z.total_capacity AS total_capacity',
DB::raw('IF(MAX(mea.id), mea.salable_capacity, z.salable_capacity) AS capacity'),
DB::raw('COUNT(tickets.id) AS sold'),
DB::raw('(IF(MAX(mea.id), mea.salable_capacity, z.salable_capacity) - COUNT(tickets.id)) AS available')
)
->join('ticket_mains', 'tickets.ticket_main_id', '=', 'ticket_mains.id')
->join('match_events', 'tickets.match_event_id', '=', 'match_events.id')
->join('seats as s', 'tickets.seat_id', '=', 's.id')
->join('zones as z', 's.zone_id', '=', 'z.id')
->join('zones as zsub', 'z.zone_id', '=', 'zsub.id')
->leftJoin('match_event_stages as mea', function ($join) {
$join->on('mea.zone_id', '=', 'z.id')
->on('mea.match_event_id', '=', 'match_events.id')
->where('mea.stage_type_id', StageTypesEnum::LIMIT_TRIBUNE_CAPACITY);
})
->where(function ($query) use ($eventIdOrCode) {
$query->where('tickets.code_event', $eventIdOrCode)
->orWhere('tickets.match_event_id', $eventIdOrCode);
}) // Del evento
->where(function ($query) {
$query->where('tickets.ticket_status_id', TicketStatusEnum::PURCHASED) // Comprado
->orWhere('tickets.ticket_status_id', TicketStatusEnum::CREATED); // Ingresado
})
->groupBy([
'tribune',
'sector',
'z.total_capacity',
'z.salable_capacity',
'mea.salable_capacity'
])
->orderBy('tribune', 'ASC')
->orderBy('sector', 'ASC')
->get();
$table = '<table>
<tr>
<th>Tribuna</th>
<th>Sector</th>
<th>Capacidad Total</th>
<th>Capacidad Vendible</th>
<th>Boletas vendidas</th>
<th>Boletas disponibles</th>
</tr>';
$totalCapacity = 0;
$totalSold = 0;
$totalAvailable = 0;
foreach ($soldTickets as $item) {
$table .= '<tr>' .
'<td>' . $item->tribune . '</td>' .
'<td>' . $item->sector . '</td>' .
'<td>' . $item->total_capacity . '</td>' .
'<td>' . $item->capacity . '</td>' .
'<td>' . $item->sold . '</td>' .
'<td>' . $item->available . '</td>' .
'</tr>';
$totalCapacity += $item->capacity;
$totalSold += $item->sold;
$totalAvailable += $item->available;
}
$table .= '<tr>
<th>Total</th>
<th></th>
<th>' . $totalCapacity . '</th>
<th>' . $totalSold . '</th>
<th>' . $totalAvailable . '</th>
</tr>';
$table .= '</table>';
return $table;
}
public function validateExport(Request $request)
{
if ($request['query']) {
$results = $this->util->getGenericData($request["query"], $request["bindings"]);
if (count($results) > 0) {
$name = 'ReporteRepositorioDocumental' . time() . '.xlsx';
Excel::store(new ListTickeLogsExport($results), $name, 'public');
return response()->json(['success' => true, 'message' => 'Validación OK', 'data' => $name]);
}
}
return response()->json(['success' => false, 'message' => 'No existen datos a exportar']);
}
public function export($name)
{
return $this->util->export($name);
}
public function dispatchTicketProcesses(array $params)
{
$ticketMainId = $params['ticketMainId'];
$validateTicketNotifications = $params['validateTicketNotifications'] ?? true;
$ticketMain = $this->ticketService->find($ticketMainId);
if (!$ticketMain || ($validateTicketNotifications && $this->isCompletedTicketNotification($ticketMain))) {
return;
}
$params['ticketMain'] = $ticketMain;
$this->executeTicketProcesses($params);
}
// Ejecución de procesos alternos (facturación electronica o envio de correo)
public function executeTicketProcesses(array $params)
{
$ticketMain = $params['ticketMain'];
$enableElectronicInvoiceCreation = $params['enableElectronicInvoiceCreation'] ?? $this->ticketParametersService->validateElectronicInvoiceCreation();
$sendNotificationTickets = $this->ticketParametersService->validateSendingEmailTickets($ticketMain->origin);
$isValidatePurchaseType = $this->validatePurchaseType($ticketMain);
$isValidateStatusSendingTicketEmailsOnTickets = $this->validateStatusSendingTicketEmailsOnTickets($ticketMain);
if ($sendNotificationTickets && $isValidateStatusSendingTicketEmailsOnTickets) {
$this->notificationTickets($ticketMain->id);
} else if ($enableElectronicInvoiceCreation && !$ticketMain->cufe && $isValidatePurchaseType) {
$this->generateInvoice($ticketMain->id);
} else if ($sendNotificationTickets && $enableElectronicInvoiceCreation) {
$this->updateTicketNotification($ticketMain, TicketNotificationEnum::COMPLETED);
} else if ($sendNotificationTickets) {
$this->updateTicketNotification($ticketMain, TicketNotificationEnum::NOTIFICATION_COMPLETED);
} else if ($enableElectronicInvoiceCreation && $isValidatePurchaseType) {
$this->updateTicketNotification($ticketMain, TicketNotificationEnum::BILLING_COMPLETED);
} else {
$this->updateTicketNotification($ticketMain, TicketNotificationEnum::SKIP);
}
}
public function generateInvoice($ticketMainId)
{
try {
event(new TicketBillingEvent($ticketMainId));
} catch (\Exception $th) {
$data = [
'function' => 'generateInvoice',
'ticketMainId' => $ticketMainId,
'message' => $th->getMessage(),
'getFile' => $th->getFile(),
'getLine' => $th->getLine(),
];
$this->util->logFile(json_encode($data));
}
}
public function notificationTickets($ticketMainId, $validateSendingStatus = true, $userId = null)
{
try {
NotificationTicketEvent::dispatch($ticketMainId, $validateSendingStatus, $userId);
} catch (\Exception $th) {
$data = [
'function' => 'notificationTickets',
'ticketMainId' => $ticketMainId,
'message' => $th->getMessage(),
'getFile' => $th->getFile(),
'getLine' => $th->getLine(),
];
$this->util->logFile(json_encode($data));
}
}
public function ticketDoor($ticket)
{
return $ticket->door;
}
public function ticketDetailEvent($ticket)
{
return $ticket->match_event->name . ($ticket->match_event->stadium_to_play ? ' - Estadio ' . $ticket->match_event->stadium_to_play : '');
}
private function validatePurchaseType($ticketMain)
{
if ($this->ticketParametersService->enableElectronicComplimentaryBilling()) {
return true;
}
return Ticket::where('ticket_main_id', $ticketMain->id)->where('ticket_type_id', '!=', TicketTypesEnum::COMPLIMENTARY)->exists();
}
private function validateStatusSendingTicketEmailsOnTickets($ticketMain)
{
return Ticket::where('ticket_main_id', $ticketMain->id)->where('is_an_email_sent', 0)->exists();
}
public function subscribersTicketEvent($eventIdOrCode)
{
$data = DB::table('tickets as t')
->selectRaw('
COUNT(*) AS TOTAL,
CAST(SUM(IF(p.id IS NULL, 1, 0)) AS UNSIGNED) AS NUEVOS,
CAST(SUM(IF(p.id IS NULL, 0, 1)) AS UNSIGNED) AS ANTIGUOS
')
->leftJoin('pre_subscribers as p', 'p.seat_id', '=', 't.seat_id')
->where(function ($query) use ($eventIdOrCode) {
$query->where('t.code_event', $eventIdOrCode)
->orWhere('t.match_event_id', $eventIdOrCode);
}) // Del evento
->first();
return response()->json($data);
}
public function dataSubscribers(Request $request)
{
$eventCode = $request->input('eventCode', null);
if (!$eventCode) {
return response()->json('Codigo de evento no existe');
}
$matchEvent = MatchEvent::where('code', $eventCode)->first();
if (!$matchEvent) {
return response()->json('Evento no existe');
}
$count = $request->input('count', 1);
$date = $request->input('date', null);
$data = TicketMain::join('tickets as t', 't.ticket_main_id', '=', 'ticket_mains.id')
->selectRaw('COUNT(DISTINCT t.seat_id) AS subscribers, ROUND((SUM(t.price)*' . $count . '), 2) AS total')
->where('t.ticket_type_id', TicketTypesEnum::SUBSCRIBER)
->whereIn('t.ticket_status_id', [TicketStatusEnum::CREATED, TicketStatusEnum::PURCHASED])
->where('t.match_event_id', '=', $matchEvent->id)
->when($date, function ($query) use ($date) {
$query->where('t.created_at', '>=', $date);
})
->get();
if (!$data) {
return response()->json('No existen datos a mostrar');
}
$table = '<table>
<tr>
<th>Abonos</th>
<th></th>
<th>Total</th>
</tr>';
foreach ($data as $item) {
$table .= '<tr>' .
'<td>' . $item->subscribers . '</td>' .
'<td>' . '</td>' .
'<td>' . $this->formatCurrency($item->total) . '</td>' .
'</tr>';
}
$table .= '</table>';
return $table;
}
public function generateDynamicQr(Request $request)
{
return $this->ticketService->generateDynamicQr($request);
}
public function billingOnDemand(Request $request)
{
$email = $request->email;
$matchEventId = $request->matchEventId;
$type = $request->type;
$ticketMains = DB::table('tickets as t')
->select(
'tm.id'
)
->join('ticket_mains as tm', 'tm.id', '=', 't.ticket_main_id')
->join('users as u', 'u.id', '=', 'tm.user_id_log')
->whereNull('tm.cufe')
->whereIn('t.ticket_status_id', [TicketStatusEnum::PURCHASED, TicketStatusEnum::CREATED])
->where('t.match_event_id', $matchEventId)
->when($email, function ($query) use ($email) {
$query->where('u.email', $email);
})
->when($type, function ($query) use ($type) {
$query->where('t.ticket_type_id', $type);
})
->groupBy('tm.id')
->get();
if (count($ticketMains) == 0) {
return array(
'r' => false,
'm' => 'No se encontraron boletas a facturar a demanda.'
);
}
$data = array(
'email' => $email,
'matchEventId' => $matchEventId,
'type' => $type,
'ticketMains' => $ticketMains
);
$module = Module::where('route', 'ticket-office')->first();
$this->registerLog(Auth::user()->id, 'Facturación a demanda', json_encode($data), "Create", $module->id);
foreach ($ticketMains as $ticketMain) {
$this->dispatchTicketProcesses(['ticketMainId' => $ticketMain->id, 'validateTicketNotifications' => false, 'enableElectronicInvoiceCreation' => true]);
}
return array(
'r' => true,
'm' => 'Se validaron ' . count($ticketMains) . ' pagos a facturar a demanda.'
);
}
public function appNotificationTickets($ticketMainId, $userId)
{
$tickets = $this->ticketService->getTicketsByTicketMainIdAndUserId($ticketMainId, $userId);
if (!count($tickets)) {
return array(
'r' => false,
'm' => 'No se encontraron boletas a notificar.'
);
}
$tickets = $tickets->whereIn('ticket_status_id', [TicketStatusEnum::CREATED, TicketStatusEnum::PURCHASED]);
if (!count($tickets)) {
return array(
'r' => false,
'm' => 'No se encontraron boletas a notificar.'
);
}
$userPnsId = $tickets[0]->user->pns_id;
if (!$userPnsId) {
return array(
'r' => false,
'm' => 'No existe identificador de notificaciones para el usuario.'
);
}
$totalTickets = count($tickets);
$zoneTickets = $tickets[0]->zone;
$eventName = $tickets[0]->match_event->name;
$ticketType = $tickets[0]->ticket_type_id;
if ($ticketType == TicketTypesEnum::COMPLIMENTARY) {
$message = 'Tienes ' . $totalTickets . ' cortesías en proceso de aceptación: sector "' . $zoneTickets . '" para el partido "' . $eventName . '"';
} else {
$message = 'Tienes ' . $totalTickets . ' nuevas boletas: sector "' . $zoneTickets . '" para el partido "' . $eventName . '"';
}
$push = new PushNotificationController();
$push->sendToUser($message, $userPnsId, null, null, null, null, 'U');
}
public function notifyTicketCancellation($ticketMainId, $userId)
{
$tickets = $this->ticketService->getTicketsByTicketMainIdAndUserId($ticketMainId, $userId);
if (!count($tickets)) {
return array(
'r' => false,
'm' => 'No se encontraron boletas a notificar.'
);
}
$tickets = $tickets->where('ticket_status_id', TicketStatusEnum::CANCELLED);
if (!count($tickets)) {
return array(
'r' => false,
'm' => 'No se encontraron boletas a notificar.'
);
}
$totalTickets = count($tickets);
$ticketType = $tickets[0]->ticket_type_id == TicketTypesEnum::COMPLIMENTARY ? 'cortesías' : 'boletas';
$zoneTickets = $tickets[0]->zone;
$eventTickets = $tickets[0]->match_event->name;
Mail::to($tickets[0]->user->email)->send(new TicketNotificationCancelled(new TicketNotification($totalTickets, $ticketType, $zoneTickets, $eventTickets)));
}
public function appNotificationTicketCancellation($ticketMainId, $userId)
{
$tickets = $this->ticketService->getTicketsByTicketMainIdAndUserId($ticketMainId, $userId);
if (!count($tickets)) {
return array(
'r' => false,
'm' => 'No se encontraron boletas a notificar.'
);
}
$tickets = $tickets->where('ticket_status_id', TicketStatusEnum::CANCELLED);
if (!count($tickets)) {
return array(
'r' => false,
'm' => 'No se encontraron boletas a notificar.'
);
}
$userPnsId = $tickets[0]->user->pns_id;
if (!$userPnsId) {
return array(
'r' => false,
'm' => 'No existe identificador de notificaciones para el usuario.'
);
}
$totalTickets = count($tickets);
$zoneTickets = $tickets[0]->zone;
$eventName = $tickets[0]->match_event->name;
$ticketType = $tickets[0]->ticket_type_id;
if ($ticketType == TicketTypesEnum::COMPLIMENTARY) {
$message = 'Se han anulado ' . $totalTickets . ' cortesías, sector "' . $zoneTickets . '" para el partido "' . $eventName . '"';
} else {
$message = 'Se han anulado ' . $totalTickets . ' boletas: sector "' . $zoneTickets . '" para el partido "' . $eventName . '"';
}
$push = new PushNotificationController();
$push->sendToUser($message, $userPnsId, null, null, null, null, 'U');
}
public function notifyTicketUnavailable($ticketMainId, $userId)
{
$tickets = $this->ticketService->getTicketsByTicketMainIdAndUserId($ticketMainId, $userId);
if (!count($tickets)) {
return array(
'r' => false,
'm' => 'No se encontraron boletas a notificar.'
);
}
$tickets = $tickets->whereIn('ticket_status_id', [TicketStatusEnum::PURCHASED, TicketStatusEnum::CREATED]);
if (!count($tickets)) {
return array(
'r' => false,
'm' => 'No se encontraron boletas a notificar.'
);
}
$totalTickets = count($tickets);
$ticketType = $tickets[0]->ticket_type_id == TicketTypesEnum::COMPLIMENTARY ? 'cortesías' : 'boletas';
$zoneTickets = $tickets[0]->zone;
$eventTickets = $tickets[0]->match_event->name;
Mail::to($tickets[0]->user->email)->send(new TicketNotificationUnavailable(new TicketNotification($totalTickets, $ticketType, $zoneTickets, $eventTickets)));
}
public function appNotificationTicketUnavailable($ticketMainId, $userId)
{
$tickets = $this->ticketService->getTicketsByTicketMainIdAndUserId($ticketMainId, $userId);
if (!count($tickets)) {
return array(
'r' => false,
'm' => 'No se encontraron boletas a notificar.'
);
}
$tickets = $tickets->whereIn('ticket_status_id', [TicketStatusEnum::PURCHASED, TicketStatusEnum::CREATED]);
if (!count($tickets)) {
return array(
'r' => false,
'm' => 'No se encontraron boletas a notificar.'
);
}
$userPnsId = $tickets[0]->user->pns_id;
if (!$userPnsId) {
return array(
'r' => false,
'm' => 'No existe identificador de notificaciones para el usuario.'
);
}
$totalTickets = count($tickets);
$zoneTickets = $tickets[0]->zone;
$eventName = $tickets[0]->match_event->name;
$ticketType = $tickets[0]->ticket_type_id;
if ($ticketType == TicketTypesEnum::COMPLIMENTARY) {
$message = 'Tus ' . $totalTickets . ' cortesías, sector "' . $zoneTickets . '" para el partido "' . $eventName . '" ya no estan disponibles';
} else {
$message = 'Tus ' . $totalTickets . ' boletas, sector "' . $zoneTickets . '" para el partido "' . $eventName . '" ya no estan disponibles';
}
$push = new PushNotificationController();
$push->sendToUser($message, $userPnsId, null, null, null, null, 'U');
}
public function sendToBilling($matchEventId)
{
$ticketMains = DB::table('tickets as t')
->select(
'tm.id'
)
->join('ticket_mains as tm', 'tm.id', '=', 't.ticket_main_id')
->join('match_events as me', 'me.id', '=', 't.match_event_id')
->where('me.id', $matchEventId)
->where(function ($query) {
$query->whereNull('tm.cufe');
})
->whereIn('t.ticket_status_id', [TicketStatusEnum::PURCHASED, TicketStatusEnum::CREATED])
->groupBy('tm.id')
->get();
if (count($ticketMains) == 0) {
return array(
'r' => false,
'm' => 'No se encontraron transacciones pendientes de validacion de procesos.'
);
}
foreach ($ticketMains as $ticketMain) {
$this->dispatchTicketProcesses(['ticketMainId' => $ticketMain->id, 'validateTicketNotifications' => false, 'enableElectronicInvoiceCreation' => true]);
}
return array(
'r' => true,
'm' => 'Se validaron ' . count($ticketMains) . ' transaciones pendientes de validacion de procesos.'
);
}
}