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/demo.sports-crowd.com/app/Http/Controllers/ServiceChargeController.php
<?php

namespace App\Http\Controllers;

use App\AcademyCategory;
use App\Core\CorporateIdentity\Application\CorporateIdentityService;
use App\MatchEvent;
use App\Parameter;
use App\Tag;
use DataTables;
use App\ServiceCharge;
use App\ServiceChargeTag;
use App\TicketType;
use App\Zone;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;

class ServiceChargeController extends Controller
{
    private $services = [];
    private $paymentTypes = [];

    public function __construct()
    {
        $this->services[] = (object) [
            'name'  => 'Todos',
            'value' => 'all'
        ];
        $this->services[] = (object) [
            'name'  => 'Tienda',
            'value' => 'order'
        ];
        $this->services[] = (object) [
            'name'  => 'Boletería',
            'value' => 'ticket'
        ];
        $this->services[] = (object) [
            'name'  => 'Academia',
            'value' => 'academy'
        ];
        $this->services[] = (object) [
            'name'  => 'Experiencia',
            'value' => 'experience'
        ];

        $this->paymentTypes[] = (object) [
            'name'  => 'Todos',
            'value' => 'all'
        ];
        $this->paymentTypes[] = (object) [
            'name'  => 'Inscripción',
            'value' => 'enrollment'
        ];
        $this->paymentTypes[] = (object) [
            'name'  => 'Mensualidad',
            'value' => 'monthly'
        ];
    }

    public function index()
    {
        $active = Parameter::select('service_charge_enabled')->first()->service_charge_enabled;

        $corporateIdentity = CorporateIdentityService::get();
        return view('service_charges.list', compact('active', 'corporateIdentity'));
    }

    public function indexAdd()
    {
        $tags = Tag::select('id', 'name')->where('active', 1)->get();
        $services = $this->services;

        $data = $this->getCommonData();
        extract($data);

        return view('service_charges.create', compact(
            'tags',
            'services',
            'matchEvents',
            'tribunes',
            'ticketTypes',
            'paymentTypes',
            'categories'
        ));
    }

    public function indexEdit($id)
    {
        $object = ServiceCharge::findOrFail($id);
        $tags = Tag::select('id', 'name')->where('active', 1)->get();
        $assignedTags = ServiceChargeTag::where('service_charge_id', $id)->pluck('tag_id')->toArray();
        $services = $this->services;
        $assignedServices = explode(',', $object->services);
        $rules = json_decode($object->rules, false);
        $assignedMatchEvents = isset($rules->match_events) ? ($rules->match_events == '*' ? ['all'] : $rules->match_events) : [];
        $assignedZones = isset($rules->zones) ? ($rules->zones == '*' ? ['all'] : $rules->zones) : [];
        $assignedTicketTypes = isset($rules->ticket_types) ? ($rules->ticket_types == '*' ? ['all'] : $rules->ticket_types) : [];
        $assignedPaymentTypes = isset($rules->payment_types) ? ($rules->payment_types == '*' ? ['all'] : $rules->payment_types) : [];
        $assignedCategories = isset($rules->categories) ? ($rules->categories == '*' ? ['all'] : $rules->categories) : [];

        $data = $this->getCommonData();
        extract($data);

        return view('service_charges.edit', compact(
            'object',
            'assignedTags',
            'assignedServices',
            'assignedMatchEvents',
            'assignedZones',
            'assignedTicketTypes',
            'assignedPaymentTypes',
            'assignedCategories',
            'tags',
            'services',
            'matchEvents',
            'tribunes',
            'ticketTypes',
            'paymentTypes',
            'categories'
        ));
    }

    public function tableFilter()
    {
        $data = $this->getCommonData();
        extract($data);

        DB::statement("SET sql_mode = ''");
        $obj = ServiceCharge::select(
            'service_charges.id',
            'service_charges.price_type',
            'service_charges.price',
            'service_charges.services',
            'service_charges.rules',
            DB::raw('GROUP_CONCAT(DISTINCT(tags.name)) AS segmentation'),
            'service_charges.priority',
            'service_charges.active'
        )
            ->leftjoin('service_charge_tags', 'service_charges.id', '=', 'service_charge_tags.service_charge_id')
            ->leftjoin('tags', function ($join) {
                $join->on('tags.id', '=', 'service_charge_tags.tag_id')->where('tags.active', 1);
            })
            ->groupBy('service_charges.id')
            ->orderBy('service_charges.created_at', 'DESC');

        DB::statement("SET sql_mode = 'STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'");

        return DataTables::of($obj)
            ->addColumn('actions', function ($obj) {
                return '
                    <i class="fa fa-pencil iconMini" onClick="clickEdit(' . $obj->id . ')" data-id="' . $obj->id . '" title="Editar"></i>
                    <i class="fa fa-trash iconMini" onClick="clickDelete(' . $obj->id . ')" data-id="' . $obj->id . '" title="Eliminar"></i>
                ';
            })
            ->editColumn('services', function ($obj) {
                $services = [];
                if ($obj->services) {
                    foreach (explode(',', $obj->services) as $item) {
                        $object = collect($this->services)->where('value', $item)->first();
                        if ($object)
                            $services[] = $object->name;
                    }
                }
                return implode(',', $services);
            })
            ->editColumn('priority', function ($obj) {
                if ($obj->priority == 0) {
                    return 'NO';
                } else {
                    return 'SI';
                }
            })
            ->editColumn('rules', function ($obj) use ($matchEvents, $tribunes, $ticketTypes, $paymentTypes, $categories) {
                $response = '<ul>';
                if ($obj->rules) {
                    $rules = json_decode($obj->rules, false);

                    $assignedMatchEvents = isset($rules->match_events) ? ($rules->match_events == '*' ? ['all'] : $rules->match_events) : [];
                    if (count($assignedMatchEvents)) {
                        $matches = [];
                        foreach ($assignedMatchEvents as $matchEvent) {
                            $object = collect($matchEvents)->where('id', $matchEvent)->first();
                            if ($object)
                                $matches[] = ($object->name . ($object->event_start ? (' - ' . $object->event_start) : ''));
                        }
                        $response .= '<li>Partidos: ' . implode(',', $matches) . '</li>';
                    }

                    $assignedZones = isset($rules->zones) ? ($rules->zones == '*' ? ['all'] : $rules->zones) : [];
                    if (count($assignedZones)) {
                        $zones = [];
                        foreach ($assignedZones as $zone) {
                            $object = collect($tribunes)->where('id', $zone)->first();
                            if ($object)
                                $zones[] = ($object->name . ($object->zone ? (' (' . $object->zone->name . ')') : ''));
                        }
                        $response .= '<li>Tribunas: ' . implode(',', $zones) . '</li>';
                    }

                    $assignedTicketTypes = isset($rules->ticket_types) ? ($rules->ticket_types == '*' ? ['all'] : $rules->ticket_types) : [];
                    if (count($assignedTicketTypes)) {
                        $types = [];
                        foreach ($assignedTicketTypes as $ticketType) {
                            $object = collect($ticketTypes)->where('id', $ticketType)->first();
                            if ($object)
                                $types[] = $object->name;
                        }
                        $response .= '<li>Tipos: ' . implode(',', $types) . '</li>';
                    }

                    $assignedPaymentTypes = isset($rules->payment_types) ? ($rules->payment_types == '*' ? ['all'] : $rules->payment_types) : [];
                    if (count($assignedPaymentTypes)) {
                        $types = [];
                        foreach ($assignedPaymentTypes as $type) {
                            $object = collect($paymentTypes)->where('value', $type)->first();
                            if ($object)
                                $types[] = $object->name;
                        }
                        $response .= '<li>Tipo de pagos: ' . implode(',', $types) . '</li>';
                    }

                    $assignedCategories = isset($rules->categories) ? ($rules->categories == '*' ? ['all'] : $rules->categories) : [];
                    if (count($assignedCategories)) {
                        $responseCategories = [];
                        foreach ($assignedCategories as $category) {
                            $object = collect($categories)->where('id', $category)->first();
                            if ($object)
                                $responseCategories[] = $object->name;
                        }
                        $response .= '<li>Categorias: ' . implode(',', $responseCategories) . '</li>';
                    }
                }
                $response .= '</ul>';
                return $response;
            })
            ->editColumn('active', function ($obj) {
                if ($obj->active == 0) {
                    return '<div class="switch"><label><div class="checkbox checbox-switch switch-success"> <label> ' . __('messages.no') . ' <input type="checkbox" onChange="chk(' . $obj->id . ')" data-id="' . $obj->id . '" id="Checkactive' . $obj->id . '" name="Checkactivo" /> <span></span>' . __('messages.yes') . ' </label></div> </label> </div>';
                } else {
                    return '<div class="switch"><label> <div class="checkbox checbox-switch switch-success"> <label>   ' . __('messages.no') . ' <input type="checkbox" onChange="chk(' . $obj->id . ')" data-id="' . $obj->id . '" id="Checkactive' . $obj->id . '" name="Checkactivo" checked="" />
                        <span></span> ' . __('messages.yes') . ' </label> </div>  </label> </div>';
                }
            })
            ->rawColumns(['actions', 'active', 'rules'])
            ->make(true);
    }

    public function create(Request $request)
    {
        try {
            $tags = $request["tags"];
            $data = $request->except(['generalMultiselect', 'tags', 'matchEvents', 'zones', 'ticketTypes', 'paymentTypes', 'categories']);
            if ($request->input('services') && count($request->input('services'))) {
                $data['services'] = implode(',', $request->input('services'));
            }
            $rules = $this->mappingRules($request);
            $data['rules'] = $rules;
            if ($model = ServiceCharge::create($data)) {
                if ($tags != null) {
                    foreach ($tags as $tagId) {
                        ServiceChargeTag::create([
                            'tag_id' => $tagId,
                            'service_charge_id' => $model->id
                        ]);
                    }
                }

                $this->registerLog(Auth::user()->id, 'Crear configuración cobro servicios', json_encode($request->all()), "Create", $this->getModule($request));
                return response(array("r" => true, "type" => "success", "title" => "", "m" => __('messages.created_successfully'), "data" => $model->id));
            } else {
                return response(array("r" => false, "type" => "error", "title" => "Oops...", "m" => __('messages.error_creating'), "data" => null));
            }
        } catch (\Exception $e) {
            return response(
                array(
                    "r" => false,
                    "type" => "error",
                    "title" => "Oops...",
                    "m" => __($e->getMessage()),
                    "data" => null
                )
            );
        }
    }

    public function update(Request $request, $id)
    {
        try {
            $tags = $request["tags"];
            $data = $request->except(['generalMultiselect', 'tags', 'matchEvents', 'zones', 'ticketTypes', 'paymentTypes', 'categories']);
            if ($request->input('services') && count($request->input('services'))) {
                $data['services'] = implode(',', $request->input('services'));
            }
            $rules = $this->mappingRules($request);
            $data['rules'] = $rules;
            if (ServiceCharge::where('id', $id)->update($data)) {
                ServiceChargeTag::where('service_charge_id', $id)->delete();
                if ($tags != null) {
                    foreach ($tags as $tagId) {
                        ServiceChargeTag::create([
                            'tag_id' => $tagId,
                            'service_charge_id' => $id
                        ]);
                    }
                }

                $this->registerLog(Auth::user()->id, 'Editar configuración cobro servicios', json_encode($request->all()), "Update", $this->getModule($request));
                return response(array("r" => true, "type" => "success", "title" => "", "m" => __('messages.updated_successfully'), "data" => $id));
            } else {
                return response(array("r" => false, "type" => "error", "title" => "Oops...", "m" => __('messages.error_updating'), "data" => null));
            }
        } catch (\Exception $e) {
            return response(
                array(
                    "r" => false,
                    "type" => "error",
                    "title" => "Oops...",
                    "m" => __($e->getMessage()),
                    "data" => null
                )
            );
        }
    }

    public function delete(Request $request, $id)
    {
        try {
            ServiceChargeTag::where('service_charge_id', $id)->delete();
            $service = ServiceCharge::find($id);
            if ($service && $service->delete()) {
                $this->registerLog(Auth::user()->id, 'Eliminar configuración cobro servicios', json_encode($service), "Delete", $this->getModule($request));
                return response(array("r" => true, "type" => "success", "title" => "", "m" => __('messages.deleted_successfully'), "data" => null));
            } else {
                return response(array("r" => false, "type" => "error", "title" => "Oops...", "m" => __('messages.error_removing'), "data" => null));
            }
        } catch (\Illuminate\Database\QueryException $e) {
            return response(array("r" => false, "type" => "error", "title" => "Oops...", "m" => __('messages.delete_relation_data'), "data" => null));
        }
    }

    public function activate(Request $request)
    {
        try {
            $id = $request['id'];
            $state = $request['state'];

            $service = ServiceCharge::find($id);
            $service->active = $state;
            $service->update();

            $this->registerLog(Auth::user()->id, 'Activar/Desactivar configuración cobro servicios', json_encode($service), "Update", $this->getModule($request));
            return array('r' => true, 'd' => null, 'm' => __('messages.updated_successfully'));
        } catch (\Throwable $th) {
            return array('r' => false, 'd' => null, 'm' => __('messages.error_updating'));
        }
    }

    public function activateApp(Request $request)
    {
        try {
            $state = $request['state'];
            $parameter = Parameter::first();
            $parameter->service_charge_enabled = $state;
            $parameter->update();
            Cache::forget('parameters');
            return array('r' => true, 'd' => null, 'm' => __('messages.updated_successfully'));
        } catch (\Throwable $th) {
            return array('r' => false, 'd' => null, 'm' => __('messages.error_updating'));
        }
    }

    public function validateServiceCharge()
    {
        $parameters = Parameter::first();
        return $parameters->service_charge_enabled;
    }

    public function calculateServiceCharge(Request $request)
    {
        $model = ServiceCharge::where('service_charges.active', 1);
        if ($request->all()) {
            $model->where(function ($query) use ($request) {
                $query->where('services', 'LIKE', '%all%')->orWhere('services', 'LIKE', '%' . $request->input('services') . '%');
            });
            $inputs = $request->except(['services']);
            foreach ($inputs as $key => $value) {
                $model->where(function ($query) use ($key, $value) {
                    if (is_array($value)) {
                        foreach ($value as $item) {
                            $query->orWhere('rules', 'LIKE', '%"' . $key . '": "*"%')
                                ->orWhere('rules', 'LIKE', '%[' . $item . ',%')   // al inicio del array
                                ->orWhere('rules', 'LIKE', '%,' . $item . ',%')   // en medio del array
                                ->orWhere('rules', 'LIKE', '%,' . $item . ']%')   // al final del array
                                ->orWhere('rules', 'LIKE', '%[' . $item . ']%');  // único valor
                        }
                    } else {
                        $query->orWhere('rules', 'LIKE', '%"' . $key . '": "*"%')
                            ->orWhere('rules', 'LIKE', '%[' . $value . ',%')
                            ->orWhere('rules', 'LIKE', '%,' . $value . ',%')
                            ->orWhere('rules', 'LIKE', '%,' . $value . ']%')
                            ->orWhere('rules', 'LIKE', '%[' . $value . ']%');
                    }
                });
            }
        }
        if (Auth::user()) {
            $userId = Auth::user()->id;
            $model->leftjoin('service_charge_tags', 'service_charges.id', '=', 'service_charge_tags.service_charge_id')
                ->leftJoin('tags', function ($join) {
                    $join->on('tags.id', '=', 'service_charge_tags.tag_id')
                        ->where('tags.active', 1);
                })
                ->leftjoin('user_tags', 'user_tags.tag_id', '=', 'service_charge_tags.tag_id')
                ->where(function ($q) use ($userId) {
                    $q->where('user_tags.user_id', $userId)
                        ->orWhereNull('tags.id');
                });
        }
        $data = $model->orderBy('priority', 'DESC')->first();
        if (!$data) {
            return 0;
        }

        if ($data->price_type == 'percent') {
            return $data->price . '%';
        } else {
            return $data->price;
        }
    }

    private function mappingRules(Request $request)
    {
        $rules = '{ ';
        if ($request->input('matchEvents') && count($request->input('matchEvents'))) {
            $matchEvents = implode(',', $request->input('matchEvents'));
            if (str_contains($matchEvents, 'all'))
                $rules .= '"match_events": ' . '"*", ';
            else
                $rules .= '"match_events": ' . '[' . $matchEvents . '], ';
        }
        if ($request->input('zones') && count($request->input('zones'))) {
            $zones = implode(',', $request->input('zones'));
            if (str_contains($zones, 'all'))
                $rules .= '"zones": ' . '"*", ';
            else
                $rules .= '"zones": ' . '[' . $zones . '], ';
        }
        if ($request->input('ticketTypes') && count($request->input('ticketTypes'))) {
            $ticketTypes = implode(',', $request->input('ticketTypes'));
            if (str_contains($ticketTypes, 'all'))
                $rules .= '"ticket_types": ' . '"*", ';
            else
                $rules .= '"ticket_types": ' . '[' . $ticketTypes . '], ';
        }
        if ($request->input('paymentTypes') && count($request->input('paymentTypes'))) {
            $paymentTypes = implode(',', $request->input('paymentTypes'));
            if (str_contains($paymentTypes, 'all'))
                $rules .= '"payment_types": ' . '"*", ';
            else
                $rules .= '"payment_types": ' . '[' . $paymentTypes . '], ';
        }
        if ($request->input('categories') && count($request->input('categories'))) {
            $categories = implode(',', $request->input('categories'));
            if (str_contains($categories, 'all'))
                $rules .= '"categories": ' . '"*", ';
            else
                $rules .= '"categories": ' . '[' . $categories . '], ';
        }
        if (strlen($rules) > 2)
            $rules = substr($rules, 0, -2);
        $rules .= ' }';
        return $rules;
    }

    private function getCommonData()
    {
        // Opciones de reglas
        // Boletería
        $matchEvents = MatchEvent::select('id', 'name', 'event_start')->orderBy('created_at', 'DESC')->get();                                   // Partidos
        $matchEvents->prepend((object) [
            'id'            => 'all',
            'name'          => 'Todos',
            'event_start'   => ''
        ]);
        $tribunes = Zone::select('id', 'name', 'zone_id')->with('zone')->whereNotNull('zone_id')->orderBy('salable_capacity', 'DESC')->get();   // Zonas vendibles
        $tribunes->prepend((object) [
            'id'            => 'all',
            'name'          => 'Todas',
            'zone'   => ''
        ]);
        $ticketTypes = TicketType::select('id', 'name')->where('active', 1)->get();
        $ticketTypes->prepend((object) [
            'id'            => 'all',
            'name'          => 'Todas',
            'zone'          => ''
        ]);

        // Academia
        $paymentTypes = $this->paymentTypes;
        $categories = AcademyCategory::select('id', 'name', 'academy_location_id')->with('academy_location')->orderBy('name', 'DESC')->get();   // Categorias
        $categories->prepend((object) [
            'id'                => 'all',
            'name'              => 'Todas',
            'academy_location'  => ''
        ]);

        return compact('matchEvents', 'tribunes', 'ticketTypes', 'paymentTypes', 'categories');
    }
}