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/teamdemo.sports-crowd.com/app/Services/ExperienceService.php
<?php

namespace App\Services;

use App\AcademyUser;
use App\Address;
use App\Core\Experience\Domain\ValueObjects\ExperiencePaymentStatusEnum;
use App\Core\Experience\Domain\ValueObjects\PlanSchemeEnum;
use App\Core\Payment\PaymentStatusEnum;
use App\Erp;
use App\ErpLog;
use App\ErpParameter;
use App\Http\Controllers\CollectionInvoiceController;
use App\Http\Controllers\Controller;
use App\Http\Controllers\ERPBaseController;
use App\Http\Controllers\NotificationsController;
use App\Http\Controllers\ServiceChargeController;
use App\Http\Controllers\UtilController;
use App\Mail\ExperienceConfirmed;
use App\Models\Experience\Experience;
use App\Models\Experience\ExperiencePayment;
use App\Models\Experience\ExperiencePlan;
use App\Models\Experience\ExperiencePlanPrice;
use App\Models\Experience\ExperienceUser;
use App\PaymentMethod;
use App\Services\AcademyService;
use Carbon\Carbon;
use DateInterval;
use DateTime;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Storage;
use stdClass;

class ExperienceService
{

    private $academyService;
    private $util;

    public function __construct()
    {
        $this->academyService = new AcademyService;
        $this->util = new UtilController();
    }

    public function get(Request $request)
    {
        if (!$request->has('show_in')) {
            $request->merge(['show_in' => ['all', 'app']]);
        }
        $experiences = $this->getExperienceQuery($request)->get();
        $availableExperiences = [];
        foreach ($experiences as $experience) {
            $experiencePayments = $this->experiencePaymentUser($experience->id);
            $experience->buy_amount = $experiencePayments ? $experiencePayments->buy_amount : 0;
            $experience->available = $experiencePayments ? $experiencePayments->available > 0 : true;
            $availableExperiences[] = $experience;
        }

        return $availableExperiences;
    }

    public function detail(Request $request)
    {
        $subQuery = '';
        if (Auth::check()) {
            $subQuery = ' - IFNULL((
                                SELECT SUM(ep.amount) / MAX(CASE 
                                                                WHEN ep_plan.entries_per_purchase = 0 
                                                                THEN 1 
                                                                ELSE ep_plan.entries_per_purchase 
                                                            END)
                                FROM experience_payments ep
                                JOIN experience_plan_prices epp ON epp.id = ep.experience_plan_price_id
                                JOIN experience_plans ep_plan ON ep_plan.id = epp.experience_plan_id
                                JOIN experience_users eu ON eu.id = ep.experience_user_id
                                WHERE ep.status != "EXPIRED"
                                AND epp.experience_plan_id = experience_plans.id
                                AND eu.user_id = ' . Auth::user()->id . '
                            ), 0)';
        }

        $buyLimitRaw = '
                        CAST(
                            GREATEST(
                                    experience_plans.buy_limit' . $subQuery . ', 
                                0) AS UNSIGNED
                        ) AS buy_limit
                    ';

        $query = Experience::select(
            'experiences.id',
            'experiences.name',
            'experiences.icon',
            'experiences.short_description',
            'experiences.image',
            'experiences.description',
            'experiences.apply_to',
            'experiences.includes',
            'experiences.when',
            'experiences.plan_scheme',
            'experiences.total_capacity',
            'experiences.available_slots',
            'experiences.buy_limit',
            'experiences.term_cons_url',
            'experiences.event_place',
            'experiences.start_datetime',
            'experiences.experience_type',
            'experiences.enable_raffle',
        )
            ->with([
                'plans' => function ($q) use ($buyLimitRaw) {
                    $q->select(
                        'experience_plans.id',
                        'experience_plans.name',
                        'experience_plans.description',
                        'experience_plans.type',
                        'experience_plans.experience_id',
                        'experience_plans.total_capacity',
                        'experience_plans.available_slots',
                        'experience_plans.entries_per_purchase',
                        'experience_plans.display_index',
                        DB::raw($buyLimitRaw),
                    )
                        ->join('experiences', 'experiences.id', '=', 'experience_plans.experience_id');
                },
                'plans.prices',
                'academy_plans',
                'academy_plans.prices'
            ])
            ->groupBy('experiences.id');

        $experience = $query->findorFail($request->id);

        if ($experience) {
            $experiencePayments = $this->experiencePaymentUser($experience->id);
            $experience->buy_amount = $experiencePayments ? $experiencePayments->buy_amount : 0;
        }

        return $experience;
    }

    public function payments(Request $request)
    {
        $userId = Auth::user()->id;
        $payments = ExperiencePayment::select(
            'experiences.id AS experience_id',
            'experience_payments.id',
            'experiences.name',
            'experiences.icon',
            'experiences.image',
            'experiences.available_slots',
            'experiences.active AS experience_active',
            DB::raw("CONCAT(experience_users.first_name, ' ', experience_users.last_name) AS student"),
            'experience_users.document AS document',
            'experience_plans.name AS plan',
            DB::raw('IFNULL(payment_transactions.payment_date, "") AS payment_date'),
            'experience_payments.amount',
            'experience_payments.subtotal',
            'experience_payments.service_charge',
            'experience_payments.total',
            'experience_payments.payment_due_date',
            'experience_payments.status',
            DB::raw('true AS enable_pay'),
            DB::raw('false AS enable_renew'),
            'experiences.start_datetime',
            'experience_payments.raffle',
            'experience_payments.updated_at',
        )->with(['experience_user', 'buyer', 'entrances'])
            ->leftjoin('payment_transactions', 'payment_transactions.id', '=', 'experience_payments.payment_transaction_id')
            ->join('experience_users', 'experience_users.id', '=', 'experience_payments.experience_user_id')
            ->join('experience_plan_prices', 'experience_plan_prices.id', '=', 'experience_payments.experience_plan_price_id')
            ->join('experience_plans', 'experience_plans.id', '=', 'experience_plan_prices.experience_plan_id')
            ->join('experiences', 'experiences.id', '=', 'experience_plans.experience_id')
            ->where('experience_users.experience_type', $request->type)
            ->where('experience_users.user_id', $userId)
            ->where('experience_payments.status', '!=', ExperiencePaymentStatusEnum::EXPIRED)
            ->groupBy('experience_payments.id')
            ->orderBy('experiences.active', 'DESC')
            ->orderBy('experience_payments.id', 'DESC')
            ->get();

        $validPayments = [];
        foreach ($payments as $payment) {
            $payment->confirmed = in_array($payment->status, [ExperiencePaymentStatusEnum::CONFIRMED, ExperiencePaymentStatusEnum::OVERSOLD]);
            $payment->active = $payment->status == ExperiencePaymentStatusEnum::CONFIRMED && $payment->experience_active;
            if (!$payment->confirmed) {
                $experiencePayments = $this->experiencePaymentUser($payment->experience_id);
                if ($payment->experience_active && $payment->available_slots && (!$experiencePayments || $experiencePayments->available)) {
                    $validPayments[] = $payment;
                }
            } else {
                $validPayments[] = $payment;
            }
        }
        return $validPayments;
    }

    public function enroll(Request $request)
    {
        $data = $this->getData($request);
        $validation = $this->validateData($data);
        if (!is_bool($validation)) {
            return $validation;
        }
        $experienceUser = $this->createExperienceUser($data);
        $payment = $this->createPayment($data, $experienceUser);
        if ($payment->status == ExperiencePaymentStatusEnum::CONFIRMED) {
            $this->confirmExperiencePayment($payment);
        }
        return response(array('r' => true, 'd' => $payment));
    }

    public function renew(Request $request)
    {
        $data = $this->getData($request);
        $experiencePaymentId = $data['experiencePaymentId'];
        $payment = $this->renewPayment($experiencePaymentId);
        return response(array('r' => true, 'd' => $payment));
    }

    public function students(Request $request)
    {
        $students = [];
        if ($request->type == 'academy') {
            $students = $this->academyStudents();
        } else {
            $students = ExperienceUser::select(
                'experience_users.first_name',
                'experience_users.last_name',
                'document_types.alias AS document_type',
                'document',
            )->join('document_types', 'document_types.id', '=', 'experience_users.document_type_id')
                ->where('user_id', Auth::user()->id)
                ->where('experience_type', $request->type)
                ->orderBy('name', 'ASC')
                ->get()->toArray();

            array_unshift($students, [
                'first_name' => Auth::user()->first_name,
                'last_name'  => Auth::user()->last_name,
                'document_type' => Auth::user()->documentType ? Auth::user()->documentType->alias : '',
                'document'   => Auth::user()->document
            ]);
            $students = collect($students)->unique('document')->values()->all();

            $students[] = [
                'first_name' => 'Nuevo',
                'document'   => 0
            ];
        }
        return $students;
    }

    public function guardians(Request $request)
    {
        $guardians = ExperienceUser::select(
            'guardian_name',
            'guardian_document',
            'guardian_email',
            'guardian_phone',
        )->where('user_id', Auth::user()->id)
            ->where('experience_type', $request->type)
            ->whereNotNull('guardian_document')
            ->groupBy([
                'guardian_name',
                'guardian_document',
                'guardian_email',
                'guardian_phone'
            ])
            ->orderBy('guardian_name', 'ASC')
            ->get();
        return $guardians;
    }

    public function finishPayment($paymentTransaction)
    {
        if ($paymentTransaction->state == PaymentStatusEnum::CONFIRMED) {
            $experiencePayment = ExperiencePayment::with(
                'experience_user',
                'payment_transaction',
                'experience_plan_price.plan.experience'
            )->where('payment_transaction_id', $paymentTransaction->id)->first();

            $experienceUser = $experiencePayment->experience_user;
            $user = $experienceUser->user;
            $this->confirmExperiencePayment($experiencePayment);

            $message = trans('experiences.messages.confirmation_payment', [
                'payment_transaction_reference' => $paymentTransaction->reference,
                'experience_description' => $experiencePayment->description,
                'experience_user_name' => ($experienceUser->first_name . ' ' . $experienceUser->last_name),
                'experience_user_document' => $experienceUser->document
            ]);

            $notificationsController = new NotificationsController;
            $notificationsController->createSystemNotification($message, $user->id);

            try {
                $invoice = new CollectionInvoiceController();
                $invoice->validateCreditCollectionInvoice($paymentTransaction->gateway_payments_id, $paymentTransaction->reference, $paymentTransaction->gateway_transaction_id, 'experience', $experiencePayment->total);
                // $pay = new LealPayController();
                // $pay->validateUserPointsAccumulation($order);
            } catch (\Throwable $th) {
                $data = [
                    'experiencePayment'     => $experiencePayment,
                    'message'               => $th->getMessage(),
                    'getFile'               => $th->getFile(),
                    'getLine'               => $th->getLine(),
                ];
                $util = new UtilController;
                $util->logFile(json_encode($data));
            }

            // Sincronizar pago al ERP
            // $this->syncERP($academyTournamentPayment);
        }
    }

    public function getUser($experiencePaymentId)
    {
        $experiencePayment = ExperiencePayment::find($experiencePaymentId);
        if (!$experiencePayment) {
            $user = new stdClass();
            $user->id = 0;
            $user->first_name = '';
            $user->last_name = '';
            $user->document = '';
            return $user;
        }
        return $this->mapUserData($experiencePayment);
    }

    private function experiencePaymentUser($experienceId)
    {
        if (!Auth::user()) {
            return null;
        }

        return ExperiencePayment::select(
            DB::raw('CAST(IF(MAX(experience_payments.status) = "CONFIRMED", SUM(experience_payments.amount), 0) AS UNSIGNED) AS buy_amount'),
            DB::raw('
                    CASE 
                        WHEN experiences.plan_scheme = ' . PlanSchemeEnum::AVAILABILITY_BY_EXPERIENCE . ' THEN 
                            IF(experiences.available_slots - IF(MAX(experience_payments.status) = "CONFIRMED", SUM(experience_payments.amount), 0) >= 0, true, false)
                        WHEN experiences.plan_scheme = ' . PlanSchemeEnum::AVAILABILITY_BY_PLAN . ' THEN 
                            IF(SUM(experience_plans.available_slots) - IF(MAX(experience_payments.status) = "CONFIRMED", SUM(experience_payments.amount), 0) >= 0, true, false)
                        ELSE false
                    END AS available
                ')
        )
            ->leftjoin('experience_plan_prices', 'experience_payments.experience_plan_price_id', '=', 'experience_plan_prices.id')
            ->leftjoin('experience_plans', 'experience_plan_prices.experience_plan_id', '=', 'experience_plans.id')
            ->leftjoin('experience_users', 'experience_payments.experience_user_id', '=', 'experience_users.id')
            ->leftjoin('experiences', 'experiences.id', '=', 'experience_plans.experience_id')
            ->where('experience_plans.experience_id', $experienceId)
            ->where('experience_users.user_id', Auth::user()->id)
            ->where('experience_payments.status', 'CONFIRMED')
            ->groupBy('experiences.id')
            ->first();
    }

    private function mapUserData($experiencePayment)
    {
        $user = new stdClass();
        $user->id = $experiencePayment->id;
        $user->first_name = $experiencePayment->experience_user->first_name;
        $user->last_name = $experiencePayment->experience_user->last_name;
        $user->document = $experiencePayment->experience_user->document;
        $user->email = $experiencePayment->experience_user->email;
        return $user;
    }

    public function confirmExperiencePayment($experiencePayment)
    {
        $this->handleRaffleForExperiencePayment($experiencePayment);
        if ($experiencePayment->status == ExperiencePaymentStatusEnum::EXPIRED) {
            $updated = Experience::where('id', $experiencePayment->experience_plan_price->plan->experience_id)
                ->where('available_slots', '>', 0)
                ->decrement('available_slots', $experiencePayment->amount);

            if (!$updated) {
                $experiencePayment->status = ExperiencePaymentStatusEnum::OVERSOLD;
                $experiencePayment->save();
            } else {
                $experiencePayment->status = ExperiencePaymentStatusEnum::CONFIRMED;
            }
        } else {
            $experiencePayment->status = ExperiencePaymentStatusEnum::CONFIRMED;
        }
        $experiencePayment->save();

        $sendEmail = $experiencePayment->experience_plan_price->plan->experience->send_email;
        if ($sendEmail && $experiencePayment->status == ExperiencePaymentStatusEnum::CONFIRMED) {
            Mail::send(new ExperienceConfirmed($experiencePayment->id));
        }

        $this->syncERP($experiencePayment);
    }

    private function validateData($data)
    {
        // Agregar validaciones de información y si ya existe el estudiante
        if (!isset($data['plan']) || ExperiencePlanPrice::find($data['plan']['plan_price_id']) == null) {
            return response(array('r' => false, 'm' => __('experiences.messages.no_experience_plan_selected')));
        }
        return true;
    }

    private function getData($request)
    {
        return $request->all();
    }

    private function createExperienceUser($data)
    {
        if (ExperienceUser::where('document', $data['document'])->where('user_id', '=', Auth::user()->id)->exists()) {
            return ExperienceUser::where('document', $data['document'])->where('user_id', '=', Auth::user()->id)->first();
        } else if (isset($data['experience_type']) && $data['experience_type'] == 'academy') {
            $data = $this->mapAcademyData($data);
        } else if (!isset($data['email'])) {
            $data = $this->mapExperienceUserData($data);
        }

        $experienceUser                         = new ExperienceUser;
        $experienceUser->first_name             = $data['first_name'] ? strtoupper($data['first_name']) : '';
        $experienceUser->last_name              = $data['last_name'] ? strtoupper($data['last_name']) : '';
        $experienceUser->birthdate              = $data['dob'] ?? $data['birthdate'] ?? null;
        $experienceUser->document_type_id       = $data['document_type_id'] ?? $data['document_type'];
        $experienceUser->document               = $data['document'];
        $experienceUser->email                  = $data['email'];
        $experienceUser->phone                  = is_array($data['phone']) ? $data['phone']['number'] : $data['phone'];
        $experienceUser->dial_code              = is_array($data['phone']) ? $data['phone']['dialCode'] : null;
        $experienceUser->country_code           = is_array($data['phone']) ? $data['phone']['countryCode'] : null;

        // Enviar almacenar el base64 de la imagen
        if (isset($data['fileIdentificationDocument']) && $data['fileIdentificationDocument']) {
            $experienceUser->identification_file    = $this->validateDataDocument($data['fileIdentificationDocument'], $data['document'] . '_identification_document');
        }
        if (isset($data['fileInsuranceDocument']) && $data['fileInsuranceDocument']) {
            $experienceUser->insurance_file         = $this->validateDataDocument($data['fileInsuranceDocument'], $data['document'] . '_insurance_document');
        }

        if ($this->isUnder18YearsOld($experienceUser->birthdate)) {
            if (isset($data['guardianFirstName']) && $data['guardianFirstName'])
                $experienceUser->guardian_first_name = strtoupper($data['guardianFirstName']);

            if (isset($data['guardianLastName']) && $data['guardianLastName'])
                $experienceUser->guardian_last_name = strtoupper($data['guardianLastName']);

            if (isset($data['guardianDocument']) && $data['guardianDocument'])
                $experienceUser->guardian_document = $data['guardianDocument'];

            if (isset($data['guardianEmail']) && $data['guardianEmail'])
                $experienceUser->guardian_email = $data['guardianEmail'];

            if (isset($data['guardianPhone']) && $data['guardianPhone']) {
                $experienceUser->guardian_phone = is_array($data['guardianPhone']) ? $data['guardianPhone']['number'] : $data['guardianPhone'];
                $experienceUser->guardian_dial_code = is_array($data['guardianPhone']) ? $data['guardianPhone']['dialCode'] : null;
                $experienceUser->guardian_country_code = is_array($data['guardianPhone']) ? $data['guardianPhone']['countryCode'] : null;
            }
        }

        $experienceUser->user_id = Auth::user()->id;
        $experienceUser->save();
        return $experienceUser;
    }

    private function createPayment($data, $experienceUser)
    {
        $experiencePlanPrice = ExperiencePlanPrice::find($data['plan']['plan_price_id']);
        if (!$this->experienceIsActive($experiencePlanPrice->plan->experience)) {
            throw new Exception(__('experiences.messages.experience_is_not_active'), 403);
        }

        $availableSlots = $this->experienceAvailableSlots($experiencePlanPrice->plan);
        if (!$availableSlots) {
            throw new Exception(__('experiences.messages.no_available_slots'), 403);
        }

        $amount = ($data['amount'] ?? 1);
        $entries = $this->calculatePurchaseEntries($experiencePlanPrice->plan, $amount);

        $userExperienceTotalPurchases = ExperiencePayment::join('experience_users', 'experience_payments.experience_user_id', '=', 'experience_users.id')
            ->where([
                ['experience_plan_price_id', $data['plan']['plan_price_id']],
                ['experience_users.user_id', $experienceUser->user_id],
                ['experience_payments.status', '!=', ExperiencePaymentStatusEnum::EXPIRED]
            ])->sum('amount');

        if (($userExperienceTotalPurchases + $entries) > ($experiencePlanPrice->plan->buy_limit * ($experiencePlanPrice->plan->entries_per_purchase > 0 ? $experiencePlanPrice->plan->entries_per_purchase : 1))) {
            throw new Exception(__('experiences.messages.no_slots_available_for_user'), 403);
        } else if ($availableSlots < $entries) {
            throw new Exception(__('experiences.messages.slots_exceeds_limit'), 403);
        }

        $this->decreaseAvailableSlots($experiencePlanPrice->plan, $entries);

        $controller = new ServiceChargeController;
        $serviceCharge = 0;
        $serviceChargeEnabled = $controller->validateServiceCharge();
        if ($serviceChargeEnabled) {
            $request = new Request([
                'services'      => 'experience',
            ]);
            $serviceCharge = $controller->calculateServiceCharge($request);
        }

        $price = floatval($data['plan']['price']);
        $price = $price * $amount;
        if ($serviceCharge && str_contains($serviceCharge . '', '%')) {
            $serviceCharge = (floatval(str_replace('%', '', $serviceCharge)) / 100) * $price;
        }
        $billingAddressId = $this->createBillingAddress($data);

        $payment = ExperiencePayment::create(
            [
                'payment_identifier'        => intval(Carbon::now()->getPreciseTimestamp(3)),
                'description'               => $experiencePlanPrice->description,
                'status'                    => $experiencePlanPrice->price > 0 ? 'PENDING' : 'CONFIRMED',
                'amount'                    => $entries,
                'price'                     => $price,
                'price_discount'            => 0,
                'discount'                  => 0,
                'subtotal'                  => $price,
                'service_charge'            => $serviceCharge,
                'total'                     => $price + $serviceCharge,
                'payment_due_date'          => $experiencePlanPrice->plan->experience->start_datetime ? Carbon::parse($experiencePlanPrice->plan->experience->start_datetime)->toDateString() : null,
                'experience_plan_price_id'  => $experiencePlanPrice->id,
                'experience_user_id'        => $experienceUser->id,
                'billing_first_name'        => $data['billing_first_name'] ?? null,
                'billing_last_name'         => $data['billing_last_name'] ?? null,
                'billing_document_type_id'  => $data['billing_document_type_id'] ?? null,
                'billing_document'          => $data['billing_document'] ?? null,
                'billing_email'             => $data['billing_email'] ?? null,
                'billing_phone'             => isset($data['billing_phone']) ? (is_array($data['billing_phone']) ? ($data['billing_phone']['number'] ?? null) : $data['billing_phone']) : null,
                'billing_dial_code'         => (isset($data['billing_phone']) && is_array($data['billing_phone'])) ? ($data['billing_phone']['dialCode'] ?? null) : null,
                'billing_country_code'      => (isset($data['billing_phone']) && is_array($data['billing_phone'])) ? ($data['billing_phone']['countryCode'] ?? null) : null,
                'billing_address'           => $billingAddressId ?? null,
                'term_cons'                 => $data['term_cons'] ?? true,
                'data_policy'               => $data['data_policy'] ?? true,
                'expires_at'                => Carbon::now()->addMinutes(30), // TODO: Configurar tiempo de expiración
                'sync_with_erp'             => false,
                'purchase_origin'           => $data['origin'] ?? 'app',
                'referral_code'             => $data['referral_code'] ?? null,
            ]
        );

        $payment->companions()->attach([$experienceUser->id => ['buyer' => true]]);
        return $payment;
    }

    private function calculatePurchaseEntries(ExperiencePlan $plan, $amount)
    {
        $experience = $plan->experience;
        if ($this->experiencePlanScheme($experience) == PlanSchemeEnum::AVAILABILITY_BY_EXPERIENCE) {
            return $plan->entries_per_purchase * $amount;
        } else {
            return $amount;
        }
    }

    private function experienceIsActive($experience)
    {
        return $experience->active;
    }

    public function experiencePlanScheme(Experience $experience)
    {
        return $experience->plan_scheme;
    }

    private function experienceAvailableSlots(ExperiencePlan $plan)
    {
        $experience = $plan->experience;
        if ($this->experiencePlanScheme($experience) == PlanSchemeEnum::AVAILABILITY_BY_EXPERIENCE) {
            return $experience->available_slots;
        } else {
            return $plan->available_slots;
        }
    }

    private function renewPayment($experiencePaymentId)
    {
        $experiencePayment = ExperiencePayment::find($experiencePaymentId);
        $data = $experiencePayment->toArray();

        $data['id']                         = null;
        $data['payment_identifier']         = intval(Carbon::now()->getPreciseTimestamp(3));
        $data['payment_due_date']           = null;
        $data['payment_transaction_id']     = null;
        $data['sync_with_erp']              = false;

        $newExperiencePayment = ExperiencePayment::create($data);
        return $newExperiencePayment;
    }

    private function isUnder18YearsOld($birthdate)
    {
        $birthdateFormat = new DateTime($birthdate);
        $now = new DateTime();
        $minimumDate = $now->sub(new DateInterval('P18Y'));
        return $birthdateFormat > $minimumDate;
    }

    private function validateDataDocument($fileBase64, $fileName)
    {
        if (!str_contains($fileBase64, 'data:image')) {
            return $fileBase64;
        }
        return $this->storeObjectToS3($fileBase64, $fileName);
    }

    private function storeObjectToS3($fileBase64, $fileName)
    {
        $streamResource = $this->storeBase64ResourceToStreamResource($fileBase64);
        $extension = $this->extensionFromBase64Resource($fileBase64);
        $filenameToStore = $fileName . '.' . $extension;

        Storage::disk('s3')->put(config('s3.default') . '/experience/' . $filenameToStore, $streamResource, 'public');
        $url = config('filesystems.disks.s3.url') . '/experience/' . $filenameToStore;

        return $url;
    }

    private function storeBase64ResourceToStreamResource($dataUrl)
    {
        $base64String = preg_replace('#^data:image/\w+;base64,#i', '', $dataUrl);
        $binaryData = base64_decode($base64String);
        $stream = fopen('php://memory', 'r+');
        fwrite($stream, $binaryData);
        rewind($stream);
        return $stream;
    }

    private function extensionFromBase64Resource($dataUrl)
    {
        preg_match('#^data:image/(\w+);base64,#i', $dataUrl, $matches);
        $extension = isset($matches[1]) ? $matches[1] : null;
        return $extension;
    }

    private function validateAcademyStudents()
    {
        return $this->academyService->validateAcademyStudents();
    }

    private function academyStudents()
    {
        return $this->academyService->academyStudents();
    }

    private function mapAcademyData($data)
    {
        return $this->academyService->mapAcademyData($data);
    }

    private function mapExperienceUserData($data)
    {
        $user = Auth::user();
        if ($user) {
            $data['first_name']     = $user->first_name;
            $data['last_name']      = $user->last_name;
            $data['dob']            = $user->userInfo->dob;
            $data['document_type_id']  = $user->document_type_id;
            $data['document']       = $user->document;
            $data['email']          = $user->email;
            $data['phone']          = $user->phone;

            $data['fileIdentificationDocument'] = 'pending';
            $data['fileInsuranceDocument']      = 'pending';

            $data['guardianFirstName']  = $user->first_name;
            $data['guardianLastName']   = $user->last_name;
            $data['guardianDocument']   = $user->document;
            $data['guardianEmail']      = $user->email;
            $data['guardianPhone']      = $user->phone;
        }
        return $data;
    }

    private function decreaseAvailableSlots(ExperiencePlan $plan, $amount)
    {
        $experience = $plan->experience;
        if ($this->experiencePlanScheme($experience) == PlanSchemeEnum::AVAILABILITY_BY_EXPERIENCE) {
            $updated = Experience::where('id', $experience->id)
                ->where('available_slots', '>=', $amount)
                ->decrement('available_slots', $amount);
        } else {
            $updated = ExperiencePlan::where('id', $plan->id)
                ->where('available_slots', '>=', $amount)
                ->decrement('available_slots', $amount);
        }

        if (!$updated) {
            throw new Exception("No hay cupos disponibles");
        }
    }

    private function createBillingAddress($data)
    {
        $billingAddressId = null;
        if (isset($data['address'])) {
            $address = Address::create([
                'direction' => $data['address']['address'],
                'user_id'   => Auth::user()->id,
                'active'    => true,
                'lat'       => $data['address']['lat'],
                'long'      => $data['address']['lng'],
            ]);
            $billingAddressId = $address->id;
        }
        return $billingAddressId;
    }


    public function experienceActive($experiencePaymentId)
    {
        $experience = $this->getExperienceByPaymentId($experiencePaymentId);
        return $experience ? true : false;
    }

    public function getExperienceByPaymentId($experiencePaymentId)
    {
        $experience = ExperiencePayment::select(
            'experiences.id',
            'experiences.name',
            'experience_plans.name as plan_name',
            'experience_payments.amount',
            'experience_payments.total'
        )
            ->join('experience_plan_prices', 'experience_plan_prices.id', '=', 'experience_payments.experience_plan_price_id')
            ->join('experience_plans', 'experience_plans.id', '=', 'experience_plan_prices.experience_plan_id')
            ->join('experiences', 'experiences.id', '=', 'experience_plans.experience_id')
            ->where('experience_payments.id', $experiencePaymentId)
            ->where('experiences.active', 1)
            ->groupBy('experiences.id', 'experience_plans.name', 'experience_payments.amount', 'experience_payments.total')
            ->first();
        return $experience;
    }

    public function getExperienceQuery($request)
    {
        $query = Experience::select(
            'experiences.id',
            'experiences.name',
            'experiences.icon',
            'experiences.short_description',
            'experiences.image',
            'experiences.apply_to',
            'experiences.includes',
            'experiences.when',
            'experiences.plan_scheme',
            'experiences.total_capacity',
            'experiences.available_slots',
            'experiences.buy_limit',
            'experiences.term_cons_url',
            'experiences.experience_type',
            'experiences.event_place',
            'experiences.is_sponsored',
            'experiences.start_datetime',
            'experiences.enable_raffle',
        )
            ->with('plans', 'plans.prices')
            ->with('academy_plans', 'academy_plans.prices')

            ->leftjoin('experience_tags', 'experiences.id', '=', 'experience_tags.experience_id')
            ->leftJoin('tags', function ($join) {
                $join->on('tags.id', '=', 'experience_tags.tag_id')
                    ->where('tags.active', 1);
            })
            ->leftjoin('user_tags', 'user_tags.tag_id', '=', 'experience_tags.tag_id')
            ->where(function ($q) {
                if (Auth::check()) {
                    $userId = Auth::user()->id;
                    $q->where('user_tags.user_id', $userId)
                        ->orWhereNull('experience_tags.tag_id')
                        ->orWhereNull('tags.id');
                } else {
                    $q->whereNull('experience_tags.tag_id')
                        ->orWhereNull('tags.id');
                }
            })

            ->where('experiences.active', 1)
            ->whereIn('show_in', $request->show_in)
            ->where(function ($query) {
                $query->whereHas('plans')->orwhereHas('academy_plans');
            })
            ->groupBy('experiences.id')
            ->orderBy('experiences.id', 'ASC');

        if ($request->type) {
            $query->where('experiences.experience_type', $request->type);
        }

        return $query;
    }

    public function saveCompanion($experienceId, $companion)
    {
        $experienceUser = ExperienceUser::updateOrCreate([
            'id' => $companion['id']
        ], [
            'first_name' => $companion['first_name'],
            'last_name' => $companion['last_name'],
            'document_type_id' => $companion['document_type_id'],
            'document' => $companion['document'],
            'email' => $companion['email'],
            'phone' => is_array($companion['phone']) ? $companion['phone']['number'] : $companion['phone'],
            'user_id' => Auth::user()->id,
            'dial_code' => is_array($companion['phone']) ? $companion['phone']['dialCode'] : null,
            'country_code' => is_array($companion['phone']) ? $companion['phone']['countryCode'] : null,
        ]);

        ExperiencePayment::find($experienceId)->companions()
            ->syncWithoutDetaching([$experienceUser->id => ['buyer' => false]]);
    }

    public function findExperiencePayment($paymentId)
    {
        return ExperiencePayment::find($paymentId);
    }

    public function findExperiencePlanPrice($planPriceId)
    {
        return ExperiencePlanPrice::find($planPriceId);
    }

    public function addCompanionsToExperiencePayment($payment, $data)
    {
        $groupedCompanions = [];

        // Agrupar datos por companionN_
        foreach ($data as $key => $value) {
            if (preg_match('/^companion(\d+)_(.+)$/', $key, $matches)) {
                $index = $matches[1];  // número de companion
                $field = $matches[2];  // nombre del campo (first_name, last_name, etc.)

                $groupedCompanions[$index][$field] = $value;
            }
        }

        $payment = $this->findExperiencePayment($payment->id);

        // Crear cada ExperienceUser y asociarlo al pago
        foreach ($groupedCompanions as $companionData) {
            $experienceUser = $this->createExperienceUser($companionData);
            $payment->companions()->attach($experienceUser->id, ['buyer' => false]);
        }
    }

    function handleRaffleForExperiencePayment($experiencePayment)
    {
        $experience = $experiencePayment->experience_plan_price->plan->experience;

        // Verificar si la rifa está habilitada
        if (!$experience->enable_raffle) {
            $experiencePayment->raffle = null;
            return;
        }

        $count = max((int) $experiencePayment->amount, 1);

        // Obtener los códigos existentes para esta experiencia (como enteros)
        $existingRaffles = DB::table('experience_payments')
            ->join('experience_plan_prices', 'experience_payments.experience_plan_price_id', '=', 'experience_plan_prices.id')
            ->join('experience_plans', 'experience_plan_prices.experience_plan_id', '=', 'experience_plans.id')
            ->where('experience_plans.experience_id', $experience->id)
            ->pluck('experience_payments.raffle')
            ->filter()
            ->flatMap(fn($r) => explode(',', $r))
            ->map(fn($r) => (int) trim($r))
            ->filter()
            ->unique()
            ->sort()
            ->values();

        $nextNumber = $existingRaffles->last() ? $existingRaffles->last() + 1 : 1;

        // Generar los nuevos códigos con formato 0001, 0002, etc.
        $newRaffles = collect(range($nextNumber, $nextNumber + $count - 1))
            ->map(fn($num) => str_pad($num, 4, '0', STR_PAD_LEFT))
            ->toArray();

        $experiencePayment->raffle = implode(',', $newRaffles);
    }

    public function syncERP($experiencePayment, $action = null)
    {
        try {
            $erps = Erp::select('id', 'class')->where('active', 1)->get();

            $erpSync = ErpParameter::where('key', 'experience_sync')->first();
            if (!$erpSync || $erpSync->value == 'false') {
                $this->saveERPLog($experiencePayment->id, 'Sinc ERP deshabilitada', 'syncERP');
                return;
            }

            if (!$this->validateSyncWithERPPayment($experiencePayment)) {
                return;
            }

            $erpService = new ErpService;
            foreach ($erps as $index => $erp) {
                $classPath = $erp->class;
                $ERPRepository = new $classPath($erp->id);

                $erpBaseController = new ERPBaseController;
                $erpReference = $experiencePayment->erp_reference ?? 'E' . $experiencePayment->id;

                if (
                    $experiencePayment->total < $erpBaseController->minPriceToSync($ERPRepository->erpId) ||
                    !$erpService->canSync($erpReference, $ERPRepository, 'experience_sync')
                ) {
                    return;
                }

                $previousBill = $ERPRepository->hasPreviousBill($erpReference);
                if ($previousBill['r']) {
                    $experiencePayment->erp_response = $previousBill['d'];
                    $experiencePayment->update();
                    $this->confirmSyncERP($experiencePayment);

                    if (isset($previousBill['saveLog']) && $previousBill['saveLog']) {
                        $this->saveERPLog($experiencePayment->id, json_encode($previousBill['error']), 'createOrder');
                    }

                    continue;
                }

                $experiencePayment->erp_reference = $ERPRepository->getNextReference($erpReference);
                $experiencePayment->update();
                $erpService->synchronizing($erpReference);

                switch ($action) {
                    case 'createOrder':
                        $this->createOrderERP($experiencePayment, $ERPRepository);
                        break;
                    case 'createRC':
                        $this->createRCERP($experiencePayment, $ERPRepository);
                        break;
                    case 'createBill':
                        $this->createBillERP($experiencePayment, $ERPRepository);
                        break;
                    default:
                        $this->createThirdClientERP($experiencePayment, $ERPRepository);
                        break;
                }
            }
        } catch (Exception $e) {
            $error = [
                'message'               => $e->getMessage(),
                'getFile'               => $e->getFile(),
                'getLine'               => $e->getLine(),
            ];
            $this->saveERPLog($experiencePayment->id, json_encode($error), 'syncERP');
        }
    }

    public function saveERPLog($data, $message, $action)
    {
        $transactionId = $data;
        ErpLog::updateOrCreate(
            [
                'origin'         => 'experience',
                'transaction_id' => $transactionId,
                'resolved'       => false
            ],
            [
                'origin'         => 'experience',
                'action'         => $action,
                'origin_class'   => get_class($this),
                'data'           => $data,
                'transaction_id' => $transactionId,
                'message'        => $message,
            ]
        );
    }

    private function validateSyncWithERPPayment($experiencePayment)
    {
        return !ExperiencePayment::whereKey($experiencePayment->id)->value('sync_with_erp');
    }

    public function confirmSyncERP($experiencePayment)
    {
        $experiencePayment->sync_with_erp = true;
        $experiencePayment->update();
    }


    private function createThirdClientERP($experiencePayment, $ERPRepository)
    {
        $experienceUser = $experiencePayment->experience_user;
        $experiencePayment->billing_address =  $academyUser->address_id ?? $ERPRepository->getDefaultAddress($experienceUser->user_id);
        $experiencePayment->update();

        $experienceType = $experiencePayment->experience_plan_price->plan->experience->experience_type;
        $isAcademyExperience = $experienceType == 'academy';

        $addressObj = Address::with('city')->find($experiencePayment->billing_address);
        $address   = $addressObj->direction . ' | ' . $addressObj->district;
        $shortAddress  = $addressObj->direction;
        $country    = $addressObj->city ? $addressObj->city->state->country->name : null;
        $province   = $addressObj->city ? $addressObj->city->state->name : null;
        $city       = $addressObj->city ? $addressObj->city->name : null;

        $juricalPerson = false;
        $thirdDocument = $experiencePayment->billing_document;

        $params = new \stdClass();
        $third  = new \stdClass();
        $client = new \stdClass();

        $third->document        = $thirdDocument;
        $third->firstName       = $experiencePayment->billing_first_name;
        $third->lastName        = $experiencePayment->billing_last_name;
        $third->contact         = $experiencePayment->billing_last_name . ' ' . $experiencePayment->billing_first_name;
        $third->phone           = $experiencePayment->billing_phone;
        $third->email           = $experiencePayment->billing_email;
        $third->documentType    = $ERPRepository->mapDocumentType($juricalPerson ? 'nit' : $experiencePayment->billing_document_type->alias);
        $third->birthDate       = Carbon::parse($experiencePayment->created_at)->format('Ymd');
        $third->typeThird       = 'NATURAL_PERSON';
        $third->gender          = '0';
        $third->socialReason        = $third->contact;
        $third->establishmentName   = $third->contact;
        $third->ciiu                = null;

        if ($isAcademyExperience) {
            $client->document       = $experienceUser->document;
            $client->contact        = $experienceUser->last_name . ' ' . $experienceUser->first_name;
            $client->phone          = $experienceUser->phone;
            $client->email          = $experienceUser->email;
        } else {
            $client = $third;
        }

        $params->third          = $third;
        $params->client         = $client;
        $params->address        = str_replace('#', 'N', $address);
        $params->shortAddress   = str_replace('#', 'N', $shortAddress);
        $params->country        = $country;
        $params->province       = $province;
        $params->city           = $city;
        $params->sucursal       = $isAcademyExperience ? $this->getSucursalForERP($experienceUser) : '001';
        $params->price_list     = '001';
        $params->typeClient     = $isAcademyExperience ? 'CACD' : 'CHED';
        $params->postal         = '';
        $params->hasTaxes       = '1';
        $params->createThirdPos = true;
        $params->idCriteria     = $isAcademyExperience ? '101' : '105';
        $params->criteria       = $isAcademyExperience ? '1012' : '1054';
        $params->currency       = 'COP';
        $params->latitude       = $addressObj ? $addressObj->lat : null;
        $params->longitude       = $addressObj ? $addressObj->long : null;

        $response = $ERPRepository->createThirdClient($params);
        if (!$response['r']) {
            $this->saveERPLog($experiencePayment->id, json_encode($response['d']), 'createThirdClient');
            return;
        }
        $this->createOrderERP($experiencePayment, $ERPRepository);
    }

    private function createOrderERP($experiencePayment, $ERPRepository)
    {
        $hasPreviousOrder = $ERPRepository->hasPreviousOrder(
            $experiencePayment->erp_reference,
            $experiencePayment->payment_transaction->reference,
            $experiencePayment->payment_transaction->gateway_transaction_id
        );

        if ($hasPreviousOrder) {
            $this->createRCERP($experiencePayment, $ERPRepository);
            return;
        }

        $experience = $experiencePayment->experience_plan_price->plan->experience;
        $serviceItemCode = $experience->experience_erp->service_item_code;
        $operationCenter = $experience->experience_erp->operation_center;
        if (!$serviceItemCode) {
            $this->saveERPLog(
                $experiencePayment->id,
                'La experiencia (' . $experience->name . ') no tiene código de servicio configurado',
                'createOrder'
            );
            return;
        }

        if (!$operationCenter) {
            $this->saveERPLog(
                $experiencePayment->id,
                'La experiencia (' . $experience->name . ') no tiene centro de operacion configurado',
                'createOrder'
            );
            return;
        }

        $addressObj = Address::with('city')->find($experiencePayment->billing_address);

        $experienceUser = $experiencePayment->experience_user;
        $experienceType = $experiencePayment->experience_plan_price->plan->experience->experience_type;
        $isAcademyExperience = $experienceType == 'academy';

        $third                  = new \stdClass();
        $third->firstName       = $experiencePayment->billing_first_name;
        $third->lastName        = $experiencePayment->billing_last_name;
        $third->contact         = $experiencePayment->billing_last_name . ' ' . $experiencePayment->billing_first_name;
        $third->phone           = $experiencePayment->billing_phone;
        $third->email           = $experiencePayment->billing_email;
        $third->documentType    = $ERPRepository->mapDocumentTypeOrder($experiencePayment->billing_document_type->alias);
        $third->document        = $experiencePayment->billing_document;

        $orderParams                    = new \stdClass();
        $orderParams->operationCenter   = $operationCenter;
        $orderParams->document          = $third->document;
        $orderParams->sucursal          = $isAcademyExperience ? $this->getSucursalForERP($experienceUser) : '001';
        $orderParams->costCenter        = $isAcademyExperience ? '3002' : '1201';
        $orderParams->date              = Carbon::now()->format('Ymd');
        $orderParams->customerType      = $isAcademyExperience ? 'CACD' : 'CHED';
        $orderParams->note              = $experiencePayment->payment_transaction->reference . ' - ' . $experience->name;
        $orderParams->reference         = $experiencePayment->erp_reference;
        $orderParams->numeroPedido      = $experiencePayment->id;
        $orderParams->third             = $third;
        $orderParams->transaction       = $experiencePayment->payment_transaction;
        $orderParams->address           = $addressObj;

        $itemParams                     = new \stdClass();
        $itemParams->operation_center   = $operationCenter;
        $itemParams->serviceCode        = $serviceItemCode;
        $itemParams->warehouse          = $isAcademyExperience ? 'AC017' : 'BDHED';
        $itemParams->cost_center        = $isAcademyExperience ? '3002' : '1201';
        $itemParams->date               = $orderParams->date;
        $itemParams->price_list         = '022';
        $itemParams->price              = $experiencePayment->total; //Pago total incluido descuentos
        $itemParams->fullPrice          = $experiencePayment->price + $experiencePayment->service_charge;
        $itemParams->discount           = 0;
        $itemParams->reason             = $isAcademyExperience ? '06' : '60';
        $itemParams->un                 = $isAcademyExperience ? '100' : '104';


        $discounts = [];
        if ($experiencePayment->discount > 0) {
            $controller = new Controller();
            $discount = array(
                'f430_id_co'                => $operationCenter,
                'f430_consec_docto'         => '1',
                'f431_nro_registro'         => '1',
                'f432_tasa'                 => $experiencePayment->discount,
                'f432_vlr_uni'              => 0,
            );
            array_push($discounts, $discount);
            $itemParams->discount += $controller->formatNumberForCurrency(($itemParams->price * $experiencePayment->discount) / 100);
        }

        if ($experiencePayment->price_discount > 0) {
            $discount = array(
                'f430_id_co'                => $operationCenter,
                'f430_consec_docto'         => '1',
                'f431_nro_registro'         => '1',
                'f432_tasa'                 => 0,
                'f432_vlr_uni'              => $experiencePayment->price_discount,
            );

            array_push($discounts, $discount);
            $itemParams->discount += $experiencePayment->price_discount;
        }

        $orderParams->discounts = $discounts;
        $orderParams->items = [$ERPRepository->generateOrderItem($itemParams)];

        $response = $ERPRepository->createOrder($orderParams);
        if (!$response['r']) {
            $this->saveERPLog($experiencePayment->id, json_encode($response['d']), 'createOrder');
            return;
        }

        $experiencePayment->erp_response = is_string($response['d']) ? $response['d'] : null;
        $experiencePayment->update();

        if (isset($response['saveLog']) && $response['saveLog']) {
            $this->saveERPLog(
                $experiencePayment->id,
                json_encode($response['error']),
                'createOrder'
            );
        }

        $this->createRCERP($experiencePayment, $ERPRepository);
    }

    private function createRCERP($experiencePayment, $ERPRepository)
    {
        $erpBaseController = new ERPBaseController;
        if (!$erpBaseController->syncRcEnabled($ERPRepository->erpId)) {
            $this->createBillERP($experiencePayment, $ERPRepository);
            return;
        }

        $response = $ERPRepository->getOrder($experiencePayment->erp_reference);
        if (!$response['r']) {
            $this->saveERPLog($experiencePayment->id, json_encode($response['d']), 'createRC');
            return;
        }
        foreach ($response['d']->detalle->Table as $index => $siesaOrder) {
            $response = $ERPRepository->getRC($experiencePayment->billing_document, $siesaOrder->CentroDeOperacion);
            if ($response['r']) {
                $previousRC = array_filter($response['d']->detalle->Table, function ($item) use ($experiencePayment) {
                    $fullPrice = $experiencePayment->price + $experiencePayment->service_charge;
                    return str_contains($item->Notas, $experiencePayment->payment_transaction->reference) && $item->TotalRecibo == $fullPrice;
                }, ARRAY_FILTER_USE_BOTH);

                if (count($previousRC)) {
                    $this->createBillERP($experiencePayment, $ERPRepository);
                    continue;
                }
            }

            $paymentTransaction = $experiencePayment->payment_transaction;
            $experienceUser = $experiencePayment->experience_user;
            $experienceType = $experiencePayment->experience_plan_price->plan->experience->experience_type;
            $isAcademyExperience = $experienceType == 'academy';
            $paymentMethod = PaymentMethod::select('code')->where('id', $paymentTransaction->payment_method_id)->first();

            $parameters = new \stdClass();
            $parameters->paymentDate = Carbon::parse($paymentTransaction->payment_date)->format('Ymd');
            $parameters->idThird = $experiencePayment->billing_document;
            $parameters->currency = 'COP';
            $parameters->siesaOrder = $siesaOrder;
            $parameters->fe =  $isAcademyExperience ? '1105' : '1104';
            $parameters->note = $paymentTransaction->reference;
            $parameters->assistant = $isAcademyExperience ? '28050502' : '28050507';
            $parameters->sucursal = $isAcademyExperience ? $this->getSucursalForERP($experienceUser) : '001';
            $parameters->paymetMethod = $paymentMethod ?  $paymentMethod->code : 'WOM';
            $parameters->UN = $isAcademyExperience ? '100' : '104';
            $parameters->price = $experiencePayment->total;

            $response = $ERPRepository->createRC($parameters);
            if (!$response['r']) {
                $this->saveERPLog($experiencePayment->id, json_encode($response['d']), 'createRC');
                return;
            }
            $this->createBillERP($experiencePayment, $ERPRepository);
        }
    }

    private function createBillERP($experiencePayment, $ERPRepository)
    {
        $erpBaseController = new ERPBaseController;
        if (!$erpBaseController->syncBillEnabled($ERPRepository->erpId)) {
            $this->confirmSyncERP($experiencePayment);
            return;
        }

        $response = $ERPRepository->getOrder($experiencePayment->erp_reference);
        if (!$response['r']) {
            $this->saveERPLog($experiencePayment->id, json_encode($response['d']), 'createBill');
            return;
        }

        $paymentTransaction = $experiencePayment->payment_transaction;
        foreach ($response['d']->detalle->Table as $index => $siesaOrder) {
            $parameters = new \stdClass();
            $parameters->siesaOrder     = $siesaOrder;
            $parameters->thirdDocument  = $experiencePayment->billing_document;
            $parameters->note           = $paymentTransaction->reference;
            $parameters->price          = $experiencePayment->total;
            $parameters->typeDocument   = 'FE1';

            $response = $ERPRepository->createBill($parameters);
            if (!$response['r']) {
                $this->saveERPLog($experiencePayment->id, json_encode($response['d']), 'createBill');
                return;
            }
        }
        $this->confirmSyncERP($experiencePayment);
    }

    public function retrySyncERP($data, $action)
    {
        $academyPurchase = ExperiencePayment::find($data);
        $this->syncERP($academyPurchase, $action);
    }

    public function getSucursalForERP($experienceUser)
    {
        $sucursal       = 2;
        $users          = AcademyUser::where('user_id', $experienceUser->user_id)->pluck('identification')->toArray();
        $sucursal       += array_search($experienceUser->document, $users);
        if ($sucursal == 5)
            $sucursal   += 1;

        return $this->util->completeLeadingZeros($sucursal, 3);
    }
}