File: /var/www/vhost/disk-apps/qas.sports-crowd.com/app/Http/Controllers/Api/AcademyUserApiController.php
<?php
namespace App\Http\Controllers\Api;
use App\Module;
use App\Address;
use App\AcademyUser;
use App\AcademyState;
use App\AcademyDocument;
use App\AcademyDocumentUser;
use Illuminate\Http\Request;
use App\AcademyUsersDiscount;
use App\Models\AcademyReport;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use App\Http\Controllers\AcademyController;
use App\Http\Controllers\AcademyStateController;
use App\Http\Controllers\AcademyPurchaseController;
use App\Core\Academy\Application\AcademyUserService;
use App\Http\Controllers\AcademyParameterController;
class AcademyUserApiController extends Controller
{
private $academyController;
private $academyParameterController;
private $academyUserService;
private $academyPurchaseController;
public function __construct()
{
$this->academyController = new AcademyController;
$this->academyParameterController = new AcademyParameterController;
$this->academyUserService = new AcademyUserService();
$this->academyPurchaseController = new AcademyPurchaseController();
}
public function getAcademyUsersInfo($type_academy = 'children')
{
$academyUsers = AcademyUser::where('academy_users.user_id', Auth::user()->id)
->with('academy_state')
->with('student_document_type')
->with('academy_category')
->with('address')
->with('address.city')
->with('advisor_address')
->with('advisor_address.city')
->with('academy_location')
->withCount(['academy_purchases as pendingPayments' => function ($query) {
$query
->leftjoin('payment_transactions', 'payment_transactions.id', '=', 'academy_purchases.payment_transaction_id')
->where('payment_transactions.state', '!=', 'CONFIRMED')
->orWhereNull('payment_transactions.id');
},])
->where('type_academy', $type_academy)
->get();
foreach ($academyUsers as $user) {
if ($user->academy_category) {
$user->academy_location_id = $user->academy_category->academy_location_id;
} else {
$user->academy_location_id = null;
}
}
$enableRegistrationRenewal = $this->academyParameterController->getParametersValueByTypeAcademy('enable_registration_renewal', $type_academy);
foreach ($academyUsers as $academyUser) {
$reports = AcademyReport::where('academy_user_id', $academyUser->id)->count();
$academyUser->isReportValid = $reports > 0 ? true : false;
$discounts = AcademyUsersDiscount::where('academy_user_id', $academyUser->id)->pluck('academy_discount_id');
$academyUser->academy_discounts = $discounts;
$isRenewable = false;
if ($academyUser->academy_state->name == 'Matriculado' && $academyUser->pendingPayments == 0 && $enableRegistrationRenewal == 'true') {
$validateEnrollmentTagYear = $this->academyPurchaseController->validateEnrollmentTagYear($academyUser->user_id, date('Y'));
if (!$validateEnrollmentTagYear) {
$isRenewable = true;
}
}
$academyUser->isRenewable = $isRenewable;
}
return response()->json($academyUsers, 200);
}
public function createUserAcademy(Request $request)
{
$validation = $this->validateCreateAcademyUser($request);
if ($validation) {
return $validation;
}
$user = AcademyUser::where('id', $request['id'])->first();
$user_id = Auth::user()->id;
if (!isset($request["track1"])) {
$direction = $request["studentAddress"];
} else {
$direction = ($request['typeTrack'] . ' ' .
$request['track1'] . ' # ' .
$request['track2'] . ' - ' .
$request['track3']
);
}
if (!isset($request["advisorTrack1"])) {
$directionAdvisor = $request["advisorAddress"];
} else {
$directionAdvisor = ($request['advisorTypeTrack'] . ' ' .
$request['advisorTrack1'] . ' # ' .
$request['advisorTrack2'] . ' - ' .
$request['advisorTrack3']
);
}
$addressData = [
'direction' => $direction,
'user_id' => $user_id,
'active' => true,
'tag' => 'academy_users'
];
if (!isset($request["track1"])) {
$addressData['lat'] = $request['studentLatitude'];
$addressData['long'] = $request['studentLongitude'];
}
$address = null;
if ($addressData['lat'] && $addressData['long'] && $addressData['direction']) {
$address = Address::updateOrCreate(['user_id' => $user_id, 'tag' => 'academy_users'], $addressData);
}
$academy_user_data = [
'user_id' => $user_id,
'student_name' => $request['studentName'],
'student_last_name' => $request['studentLastName'],
'student_document_type_id' => $request['studentDocumentType'],
'identification' => $request['studentDocument'],
'school_name' => $request['school'],
'school_grade' => $request['school_grade'],
'birthdate' => $request['birthdate'],
'mail' => $request['email'],
'phone' => data_get($request, 'phone.nationalNumber', $request['phone'] ?? null),
'address_id' => $address ? $address->id : null,
'advisor_name' => $request['advisorName'],
'advisor_last_name' => $request['advisorLastName'],
'advisor_document_type_id' => $request['advisorDocumentType'],
'advisor_identification' => $request['advisorDocument'],
'advisor_ocupation' => $request['advisorOcupation'] ?? $request['ocupation'],
'advisor_relation' => $request['relation'],
'date' => $request['date'],
'age' => date_diff(new \DateTime(), date_create($request['birthdate']))->y,
'academy_schedule_id' => $request['academy_schedule_id'],
'active' => 0,
'ocupation' => $request['ocupation'],
'type_academy' => $request['type_academy'] ?? 'children',
//Campos de persona juridica
'type_person' => $request['typePerson'],
'advisor_nit' => $request['advisorNit'],
'advisor_business_name' => $request['advisorBusinessName'],
'advisor_property_name' => $request['advisorPropertyName'],
'advisor_isic_code' => $request['advisorIsicCode'],
'advisor_phone' => data_get($request, 'advisorPhone.nationalNumber', $request['advisorPhone'] ?? null),
'advisor_dial_code' => $request['advisorPhone']['dialCode'] ?? null,
'advisor_country_code' => $request['advisorPhone']['countryCode'] ?? null,
'advisor_mail' => $request['advisorMail'],
'advisor_cell_phone' => data_get($request, 'advisorCellPhone.nationalNumber', $request['advisorCellPhone'] ?? null),
'dial_code' => $request['phone']['dialCode'] ?? null,
'country_code' => $request['phone']['countryCode'] ?? null,
'advisor_cell_dial_code' => $request['advisorCellPhone']['dialCode'] ?? null,
'advisor_cell_country_code' => $request['advisorCellPhone']['countryCode'] ?? null,
];
if ($request['typePerson'] != "NATURAL_PERSON") {
$advisorAddressData = [
'direction' => $directionAdvisor,
'user_id' => $user_id,
'active' => true,
'tag' => 'advisor'
];
if (!isset($request["advisorTrack1"])) {
$advisorAddressData['lat'] = $request['advisorLatitude'];
$advisorAddressData['long'] = $request['advisorLongitude'];
}
$address_advisor = Address::updateOrCreate(['user_id' => $user_id, 'tag' => 'advisor'], $advisorAddressData);
}
$academy_user_data['advisor_address_id'] = $address_advisor->id ?? NULL;
$file = $request['photo'];
// Verifica si la entrada es una URL
if (filter_var($file, FILTER_VALIDATE_URL)) {
// Es una URL, no necesitas procesarla, simplemente asigna la URL a la propiedad 'photo'
$academy_user_data['photo'] = $file;
} else {
// Es un base64, procede con el procesamiento de la imagen
if ($file) {
$academy_user_data['photo'] = $this->savePhoto($file, $request['studentDocument']);
}
}
$academy_user = AcademyUser::updateOrCreate(['id' => $request['id']], $academy_user_data);
$this->academyUserService->generateCode($academy_user);
$academyStateRenovation = AcademyState::where('name', 'Renovacion Inscripcion')->first();
$academyStateRenovationId = $academyStateRenovation ? $academyStateRenovation->id : null;
if (!$user || $user->academy_state_id == $academyStateRenovationId) {
$academyState = new AcademyStateController();
$academyState->assignStateAcademy($academy_user);
}
$module = Module::where('route', 'academy')->first();
$this->registerLog(Auth::user()->id, 'Crear Alumno', json_encode($academy_user), "Create", $module->id);
return array('r' => true, 'data' => $academy_user, 'm' => 'Alumno registrado exitosamente!');
}
private function savePhoto($file, $identifier)
{
$extension = explode('/', mime_content_type($file))[1];
$filenametostore = 'foto_' . $identifier . '.' . $extension;
$directory = config('s3.academy') . '/academy_photos/';
list($baseType, $file) = explode(';', $file);
list(, $file) = explode(',', $file);
$file = base64_decode($file);
if (Storage::disk('s3')->exists($directory . $filenametostore)) {
Storage::disk('s3')->delete($directory . $filenametostore);
}
Storage::disk('s3')->put($directory . $filenametostore, $file, 'public');
return config('filesystems.disks.s3.url') . '/academy/academy_photos/' . $filenametostore;
}
public function completeUserAcademyData(Request $request)
{
// Certificado salud app
if (isset($request['file'])) {
$academyUserId = $request['id'];
$academyDocumentId = AcademyDocument::where('name', 'Certificado de salud APP')->pluck('id')->first();
$file = $request['file'];
$extension = explode('/', mime_content_type($file))[1];
$filenametostore = 'document' . base64_encode(random_bytes(4)) . '.' . $extension;
list($baseType, $file) = explode(';', $file);
list(, $file) = explode(',', $file);
$file = base64_decode($file);
if (Storage::disk('s3')->exists(config('s3.academy_documents') . $filenametostore)) {
Storage::disk('s3')->delete(config('s3.academy_documents') . $filenametostore);
}
Storage::disk('s3')->put(config('s3.academy_documents') . $filenametostore, fopen($request['file'], 'r+'), 'public');
$url = config('filesystems.disks.s3.url') . '/academy/academy_documents/' . $filenametostore;
$data = [
'academy_user_id' => $academyUserId,
'academy_document_id' => $academyDocumentId,
'link' => $url,
];
AcademyDocumentUser::updateOrCreate(
['academy_user_id' => $academyUserId, 'academy_document_id' => $academyDocumentId],
$data
);
}
$id = $request->input('id');
$academyUserPrevious = AcademyUser::find($id);
$previousAcademyUser = clone $academyUserPrevious;
$previousAcademyUser = json_encode($previousAcademyUser);
$data = $request->except(['academy_discounts', 'hasHealthDocument', 'file']);
$academyUser = AcademyUser::where('id', $id)->update($data);
$this->academyController->validateAcademyLocation($id);
AcademyUsersDiscount::where('academy_user_id', $id)->delete();
if ($request->input('academy_discounts')) {
$discount = new AcademyUsersDiscount();
$discount->academy_discount_id = $request->input('academy_discounts');
$discount->academy_user_id = $id;
$discount->save();
}
$academyState = AcademyState::find($academyUserPrevious->academy_state_id);
$uploadDocumentsButton = 'Botón cargar documentos';
if (!str_contains($academyState->app_components, $uploadDocumentsButton)) {
$academyStateController = new AcademyStateController;
$academyStateController->assignStateAcademy($id);
}
$logObj = array(
'previousAcademyUser' => json_decode($previousAcademyUser, true),
'newAcademyUser' => $academyUser
);
$module = Module::where('route', 'academy')->first();
$this->registerLog(Auth::user()->id, 'Completar Registro Alumno', json_encode($logObj), "Update", $module->id);
return array('r' => true, 'data' => $academyUser, 'm' => 'Alumno actualizado exitosamente!');
}
public function uploadUserAcademyDocument(Request $request)
{
$extension = $request->file('document')->getClientOriginalExtension();
$filenametostore = 'document' . Auth::user()->id . '_' . $request->input('documentId') . '.' . $extension;
if (Storage::disk('s3')->exists(config('s3.academy_documents') . $filenametostore)) {
Storage::disk('s3')->delete(config('s3.academy_documents') . $filenametostore);
}
Storage::disk('s3')->put(config('s3.academy_documents') . $filenametostore, fopen($request->file('document'), 'r+'), 'public');
$url = config('filesystems.disks.s3.url') . '/academy/academy_documents/' . $filenametostore;
$academyDocumentUser = new AcademyDocumentUser;
$academyDocumentUser->academy_user_id = $request->input('id');
$academyDocumentUser->academy_document_id = $request->input('documentId');
$academyDocumentUser->link = $url;
$academyDocumentUser->save();
return array('r' => true, 'data' => $academyDocumentUser, 'm' => __('messages.academy_document.document_uploaded_successfully'));
}
public function updateAcademyUserPhoto(Request $request)
{
$photoPath = $this->savePhoto($request['photo'], $request['academy_user']['identification']);
if ($photoPath) {
AcademyUser::where('id', $request['academy_user']['id'])->update(['photo' => $photoPath]);
return array('r' => true, 'data' => null, 'm' => 'Alumno actualizado exitosamente!');
}
}
public function getReportsAcademyUsers($academyUserId)
{
$reports = AcademyReport::where('academy_user_id', $academyUserId)->orderBy('created_at', 'DESC')->get();
return response()->json($reports, 200);
}
public function getAcademyUserById($id)
{
$academy_user = AcademyUser::where('id', $id)
->with('student_document_type')
->with('academy_category')
->with('address')
->with('academy_location')
->with('academy_schedule')
->with('advisor_address')
->with('advisor_address.city')
->first();
return $academy_user;
}
public function getAcademyUsersByFilters(Request $request)
{
$query = AcademyUser::select(
'academy_users.*',
DB::raw('IFNULL(academy_users.advisor_ocupation, "") as advisor_ocupation'),
DB::raw('IFNULL(academy_users.observations, "") as observations')
)
->where('active', true)
->whereHas('academy_schedule.academy_categories_schedules')
->whereHas('academy_schedule.academy_categories_schedules.academy_category')
->with('student_document_type')
->with('academy_schedule')
->with('academy_schedule.academy_categories_schedules')
->with('academy_schedule.academy_categories_schedules.academy_category')
->with('user')
->with('academy_state')
->with(['academy_attendance' => function ($query) use ($request) {
$query->whereDate('attendance_date', Carbon::parse($request['date']) ?? Carbon::now());
}]);
if ($request['id']) {
$query->where('id', $request['id']);
}
if ($request['scheduleId']) {
$query->where('academy_schedule_id', $request['scheduleId']);
}
// TEMPORAL, remover una vez se actualice el casteo del campo age en el APP
$results = $query->orderBy('payment_status', 'DESC')->get();
foreach ($results as $result) {
$result->age = (string) $result->age;
}
return $results;
}
public function patchRenewalUser(Request $request)
{
if (empty($request->userId)) {
return response()->json(['userId not provided'], 400);
}
$userId = $request->userId;
$academyUser = AcademyUser::find($userId);
if (!$academyUser) {
return response()->json(['User not found'], 404);
}
$academyStateRenewal = AcademyState::where('name', 'like', 'Renovacion de matricula')->first();
if (!$academyStateRenewal) {
return response()->json(['Academy state not found'], 404);
}
$previousAcademyUser = clone $academyUser;
$previousAcademyUser = json_encode($previousAcademyUser);
$academyUser->academy_state_id = $academyStateRenewal->id;
// Limpiar datos de academia
$academyUser->academy_place = null;
$academyUser->academy_location_id = null;
$academyUser->academy_category_id = null;
$academyUser->academy_schedule_id = null;
$academyUser->academy_period_id = null;
$academyUser->last_inscription_year = null;
$academyUser->update();
$logObj = array(
'previousAcademyUser' => json_decode($previousAcademyUser, true),
'newAcademyUser' => $academyUser
);
$module = Module::where('route', 'academy')->first();
$this->registerLog(Auth::user()->id, 'Renovar Matricula Alumno', json_encode($logObj), "Update", $module->id);
return response()->json($academyUser, 200);
}
public function validateGuardianInformation(Request $request)
{
if (!$request->academyUserId) {
return array('r' => false, 'm' => __('messages.guardian_information.academy_user_id_not_provided'));
}
if (!AcademyUser::where('id', $request->academyUserId)->first()->guardian_information) {
return array('r' => false, 'm' => __('messages.guardian_information.not_found'));
}
return array('r' => true, 'm' => __('messages.updated_successfully'));
}
public function updateGuardianInformation(Request $request)
{
try {
$guardianInformation = json_encode($request->except(['academyUserId']));
AcademyUser::where('id', $request->academyUserId)->update(['guardian_information' => $guardianInformation]);
return array('r' => true, 'm' => __('messages.updated_successfully'));
} catch (\Throwable $th) {
return array('r' => false, 'm' => $th->getMessage());
}
}
private function validateCreateAcademyUser(Request $request)
{
if (!$request['id']) {
$previousUser = AcademyUser::where('identification', $request['studentDocument'])->first();
if ($previousUser) {
return array(
'r' => false,
'data' => $previousUser,
'm' => trans('messages.academy_users.student_already_registered')
);
}
}
if (!$request['typePerson']) {
return array(
'r' => false,
'm' => 'Debes completar la información de responsable'
);
} else if ($request['typePerson'] == 'NATURAL_PERSON') {
if (!$request['advisorName']) {
return array(
'r' => false,
'm' => 'Debes completar el/los nombres de la persona responsable'
);
}
if (!$request['advisorLastName']) {
return array(
'r' => false,
'm' => 'Debes completar el/los apellidos de la persona responsable'
);
}
if (!$request['advisorDocumentType']) {
return array(
'r' => false,
'm' => 'Debes completar el tipo de documento de la persona responsable'
);
}
if (!$request['advisorDocument']) {
return array(
'r' => false,
'm' => 'Debes completar el documento de la persona responsable'
);
}
if ($request->has('advisorOcupation') && !$request['advisorOcupation']) {
return array(
'r' => false,
'm' => 'Debes completar la ocupación de la persona responsable'
);
}
if ($request->has('relation') && !$request['relation']) {
return array(
'r' => false,
'm' => 'Debes completar la relación de la persona responsable'
);
}
}
}
public function getAcademyUsersByCoach(Request $request)
{
$query = AcademyUser::select(
'academy_users.*',
DB::raw('IFNULL(GROUP_CONCAT(DISTINCT tags.name), "") AS segmentation'),
'academy_states.name AS academy_state_name',
'academy_states.color AS academy_state_color',
DB::raw('IFNULL(MAX(academy_attendances.attended), 0) AS attended'),
DB::raw('MAX(academy_attendances.comment) AS attendance_comment'),
DB::raw('IFNULL(MAX(academy_attendances.attendance_date), "' . Carbon::parse($date ?? now())->toDateString() . '") AS attendance_date')
)
->join('academy_schedules_coaches', 'academy_schedules_coaches.academy_schedule_id', '=', 'academy_users.academy_schedule_id')
->leftjoin('user_tags', 'user_tags.academy_user_id', '=', 'academy_users.id')
->leftjoin('tags', function ($join) {
$join->on('tags.id', '=', 'user_tags.tag_id')->where('tags.active', 1);
})
->join('academy_states', 'academy_states.id', '=', 'academy_users.academy_state_id')
->leftjoin('academy_attendances', function ($join) use ($request) {
$join->on('academy_attendances.academy_user_id', '=', 'academy_users.id')
->whereDate('academy_attendances.attendance_date', Carbon::parse($request['date']) ?? Carbon::now());
})
->where('academy_users.active', true)
->where('academy_schedules_coaches.user_id', Auth::id())
->groupBy('academy_users.id') // Necesario si usas GROUP_CONCAT
->orderBy('academy_users.student_name')
->orderBy('academy_users.student_last_name');
if ($request['scheduleId']) {
$query->where('academy_users.academy_schedule_id', $request['scheduleId']);
}
return $query->get();
}
}