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

namespace App\Http\Controllers\Api;

use App\User;
use App\Redemption;
use App\AcademyUser;
use Illuminate\Http\Request;
use App\Services\CarnetService;
use Illuminate\Support\Facades\DB;
use App\Services\ExperienceService;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\UtilController;
use App\Core\Membership\Application\MembershipService;
use App\Core\Redemption\Domain\ValueObjects\UserQRTypesEnum;

class RedemptionApiController extends Controller
{
    private $experienceService;
    private $carnetService;
    private $membershipService;
    private $utilController;


    public function __construct()
    {
        $this->experienceService = new ExperienceService();
        $this->carnetService = new CarnetService();
        $this->membershipService = new MembershipService();
        $this->utilController = new UtilController();
    }

    public function getHistory(Request $request)
    {
        $sectionId = $request['section_id'];
        $option = $request['option'];
        $typeUser = $request['qr_data']['t'] ?? null;
        $id = $request['qr_data']['u'];

        $redemptionsQuery = Redemption::select('options', DB::raw('count(*) as total'))
            ->where('section_id', $sectionId)->groupBy('options');

        if ($option) {
            $redemptionsQuery->where('options', $option);
        }

        switch ($typeUser) {
            case UserQRTypesEnum::EXPERIENCE:
                $redemptionsQuery->where('model_id', $id);
                $user = $this->experienceService->getUser($id);
                break;

            case UserQRTypesEnum::ACADEMY:
                $redemptionsQuery->where('academy_user_id', $id);
                $user = AcademyUser::select(
                    'id',
                    'student_name as first_name',
                    'student_last_name as last_name',
                    'identification as document'
                )->where('id', $id)->first();
                break;

            default:
                $redemptionsQuery->where('user_id', $id);
                $user = User::select('id', 'first_name', 'last_name', 'document')
                    ->where('id', $id)
                    ->first();
                break;
        }

        $redemptions = $redemptionsQuery->get();
        if (env('VALIDATE_SUBSCRIPTION_REDEMPTION') == 'true') {
            $subscribers = $this->validateUserSubscriptions($id, $sectionId);
            foreach ($redemptions as $key => $redemption) {
                $redemptions[$key]['total'] = $redemption->total . ' / ' . $subscribers;
            }
        }

        $data = array('user' => $user, 'redemptions' => $redemptions, 'typeUser' => $typeUser);
        return response()->json($data, 200);
    }

    public function redeem(Request $request)
    {
        $sectionId = $request['section_id'];
        $option = $request['option'];
        $typeUser = $request['qr_data']['t'] ?? null;
        $id = $request['qr_data']['u'];

        $data = array(
            'section_id' => $sectionId,
            'user_id' => $id,
            'options' => $option,
            'model' => $typeUser,
            'model_id' => $id
        );

        $message = '';
        if (env('VALIDATE_SUBSCRIPTION_REDEMPTION') == 'true') {
            $subscribers = $this->validateUserSubscriptions($id, $sectionId);
            if ($subscribers == 0) {
                return response(array(
                    "r" => false,
                    "type" => "error",
                    "title" => "Oops...",
                    "m" => 'El usuario no tiene abonos comprados',
                    "data" => null
                ));
            }
            $redemptions = $this->validateRedemptionNumber($id, $sectionId, $option);
            if ($redemptions >= $subscribers) {
                return response(array(
                    "r" => false,
                    "type" => "error",
                    "title" => "Oops...",
                    "m" => __('messages.redemptions.max_redemptions') . $redemptions . ' ingresos realizados / ' . $subscribers . ' abonos comprados',
                    "data" => null
                ));
            }
            $message = ', ' . ($redemptions + 1) . ' ingresos realizados / ' . $subscribers . ' abonos comprados';
        }

        switch ($typeUser) {
            case UserQRTypesEnum::EXPERIENCE:
                $data['academy_user_id'] = null;
                $data['user_id'] = null;
                break;

            case UserQRTypesEnum::ACADEMY:
                $data['academy_user_id'] = $id;
                $data['user_id'] = null;
                break;
        }
        $data['logged_user_id'] = Auth::user()->id;

        if ($model = Redemption::create($data)) {
            return response(array(
                "r" => true,
                "type" => "success",
                "title" => "",
                "m" => __('messages.created_successfully') . $message,
                "data" => $model->id
            ));
        } else {
            return response(array(
                "r" => false,
                "type" => "error",
                "title" => "Oops...",
                "m" => __('messages.error_creating'),
                "data" => null
            ));
        }
    }

    private function validateUserSubscriptions($userId, $sectionId)
    {
        $data = DB::table('tickets as t')
            ->selectRaw('COUNT(*) as subscribers')
            ->join('users as u', 'u.id', '=', 't.user_id')
            ->leftJoin(
                DB::raw('(SELECT me.id AS eventId, t.id AS tagId, ut.user_id AS userId
                            FROM match_events me
                            JOIN app_validation_section_tags avt ON avt.app_validation_section_id = ' . $sectionId . '
                            JOIN user_tags ut ON ut.tag_id = t.id
                            JOIN tags t ON t.id = ut.tag_id AND t.active = 1
                            WHERE me.name = t.name AND ut.user_id = ' . $userId . ') as ob1'),
                'ob1.userId',
                '=',
                'u.id'
            )
            ->whereColumn('t.match_event_id', 'ob1.eventId')
            ->where('t.ticket_status_id', 1)
            ->groupBy('u.id')
            ->first();
        return $data->subscribers ?? 0;
    }

    private function validateRedemptionNumber($userId, $sectionId, $options)
    {
        return Redemption::where([['user_id', $userId], ['section_id', $sectionId], ['options', $options]])
            ->count();
    }

    public function getUser($userId, $typeUser)
    {
        switch ($typeUser) {
            case UserQRTypesEnum::EXPERIENCE:
                $user = $this->experienceService->getUser($userId);
                return response()->json($user, 200);
                break;

            case UserQRTypesEnum::ACADEMY:
                $user = AcademyUser::select(
                    'id',
                    'student_name as first_name',
                    'student_last_name as last_name',
                    'identification as document'
                )->where('id', $userId)->first();
                break;

            default:
                $user = User::select('id', 'first_name', 'last_name', 'document')->where('id', $userId)->first();
                break;
        }

        return $user;
    }

    public function validateBenefit(Request $request)
    {
        $id = $request['qr_data']['u'];
        $typeUser = $request['qr_data']['t'] ?? null;
        $carnetId = $request['qr_data']['c'] ?? null;

        if ($typeUser && $typeUser == UserQRTypesEnum::EXPERIENCE) {
            if (!$this->experienceService->experienceActive($id)) {
                return $this->buildErrorResponse(__('messages.redemptions.experience_disabled'));
            }
            if (!$this->experienceService->getUser($id)) {
                return $this->buildErrorResponse(__('messages.redemptions.user_does_not_have_experience'));
            }

            $history = json_decode($this->getHistory($request)->getContent(), true);
            $redemptions = $history['redemptions'][0]['total'] ?? 0;
            $experience = $this->experienceService->getExperienceByPaymentId($id);

            if ($redemptions >= $experience->amount) {
                return $this->buildErrorResponse(
                    __('messages.redemptions.max_redemptions') . ': ' . $redemptions . '/' . $experience->amount
                );
            }
        }

        if ($carnetId) {
            if (!$this->carnetService->carnetActive($carnetId)) {
                return $this->buildErrorResponse(__('messages.redemptions.carnet_disabled'));
            }

            $segmentation = $this->carnetService->getSegmentationArray($carnetId);
            $isExperienceCanet = $this->membershipService->existBySegementation($segmentation);
            if ($isExperienceCanet && !$this->membershipService->memershipActiveBySegmentation($segmentation)) {
                return $this->buildErrorResponse(__('messages.redemptions.user_does_not_have_membership'));
            }
        }

        return response(array(
            "r" => true,
            "type" => "success",
            "available" => true,
            "message" => __('messages.redemptions.benefit_validated')
        ));
    }

    private function buildErrorResponse($message)
    {
        return response(array(
            "r" => false,
            "type" => "error",
            "m" => $message,
            "data" => null
        ));
    }

    public function getInfo(Request $request)
    {
        $info = [];
        $id = $request['u'];
        switch ($request['t']) {
            case UserQRTypesEnum::EXPERIENCE:
                $user = $this->experienceService->getUser($id);
                $experience = $this->experienceService->getExperienceByPaymentId($id);

                array_push($info, array(
                    "key" => __('messages.experience.experience'),
                    "value" => $experience->name
                ));

                array_push($info, array(
                    "key" => __('messages.experience.plan'),
                    "value" => $experience->plan_name
                ));

                array_push($info, array(
                    "key" => __('messages.productAttributes.title_5'),
                    "value" => $this->utilController->getCurrencyFormat($experience->total)
                ));

                array_push($info, array(
                    "key" => __('messages.screen_discounts_tag58'),
                    "value" => $experience->amount
                ));

                break;

            case UserQRTypesEnum::ACADEMY:
                $user = AcademyUser::select(
                    'id',
                    'student_name as first_name',
                    'student_last_name as last_name',
                    'identification as document'
                )->where('id', $id)->first();
                break;

            default:
                $user = User::select('id', 'first_name', 'last_name', 'document')
                    ->where('id', $id)
                    ->first();
                break;
        }

        array_push($info, array(
            "key" => __('messages.screen_changelogs_tag10'),
            "value" => $user->first_name . ' ' . $user->last_name,
        ));

        array_push($info, array(
            "key" => __('messages.screen_clients_tag13'),
            "value" => $user->document,
        ));

        return $info;
    }
}