File: /var/www/vhost/disk-apps/qas.sports-crowd.com/app/Http/Controllers/AcademyPurchaseController.php
<?php
namespace App\Http\Controllers;
use \Excel;
use App\Erp;
use App\Tag;
use App\User;
use Exception;
use App\ErpLog;
use App\Module;
use App\Address;
use App\UserTag;
use Carbon\Carbon;
use App\AcademyUser;
use App\ErpParameter;
use App\AcademyPeriod;
use App\PaymentMethod;
use App\AcademyCategory;
use App\AcademyLocation;
use App\AcademyLocationPeriod;
use App\AcademyParameter;
use App\AcademyPurchase;
use App\PaymentTransaction;
use App\Services\ErpService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
use App\Repositories\ERPLogRepository;
use App\Core\Payment\PaymentStatusEnum;
use App\Http\Controllers\UtilController;
use Yajra\DataTables\Facades\DataTables;
use App\Services\AcademyLocationsService;
use App\Repositories\PaymentTransactionRepository;
use App\Http\Controllers\Exports\AcademyPurchasesExport;
use App\Core\Payment\Application\PaymentTransactionService;
use App\Http\Controllers\Imports\AcademySchedulePaymentsImport;
use App\Http\Controllers\Imports\AcademySchedulePaymentsTemplate;
use App\Core\CorporateIdentity\Application\CorporateIdentityService;
class AcademyPurchaseController extends Controller implements PaymentTransactionRepository, ERPLogRepository
{
private $util;
public $messages = [];
private $academyParameterController;
public function __construct()
{
$this->util = new UtilController();
$this->academyParameterController = new AcademyParameterController;
}
public function index($type_academy = 'children')
{
$states = PaymentTransaction::groupBy('state')->orderBy('state', 'ASC')->pluck('state');
$states[] = 'Vacio';
$duePayments = array();
$duePayments[] = 'SI';
$duePayments[] = 'NO';
$academyLocationsService = new AcademyLocationsService;
if (!$academyLocationsService->validateAuthorizedLocations()) {
$authorizedLocations = $academyLocationsService->getAuthorizedLocations();
$franchises = AcademyLocation::select('id', 'name')->where('active', 1)->whereIn('id', $authorizedLocations)->orderBy('name', 'ASC')->get();
} else {
$franchises = AcademyLocation::select('id', 'name')->where('active', 1)->orderBy('name', 'ASC')->get();
}
// Obtener academy_location_id de las franquicias seleccionadas
$academyLocationIds = $franchises->pluck('id')->toArray();
// Obtener academy_period_id basado en academy_location_id
$academyPeriodIds = AcademyLocationPeriod::whereIn('academy_location_id', $academyLocationIds)
->pluck('academy_period_id')
->toArray();
// Verificar si hay academyPeriodIds válidos
if (!empty($academyPeriodIds)) {
// Si hay academyPeriodIds, se filtran por academyPeriodIds
$academyPeriods = AcademyPeriod::whereIn('id', $academyPeriodIds)->pluck('name')->toArray();
} else {
// Si no hay, se filtran todos
$academyPeriods = AcademyPeriod::pluck('name')->toArray();
}
// Inicializar el array de tipos con 'Inscripción'
$types = array_merge(['Inscripción'], $academyPeriods);
$corporateIdentity = CorporateIdentityService::get();
return view('academy.purchases.list', compact('states', 'types', 'duePayments', 'type_academy', 'franchises', 'corporateIdentity'));
}
public function tableFilter(Request $request)
{
$obj = $this->tableFilterQuery($request);
DB::enableQueryLog();
$dataTable = DataTables::of($obj);
$dataTable->filterColumn('coaches', function ($query, $keyword) {
$query->havingRaw("GROUP_CONCAT(DISTINCT(CONCAT_WS(' ', users1.first_name, users1.last_name, CONCAT('(',users1.email,')'))) LIKE ?", ['%' . $keyword . '%']);
});
$dataTable->filterColumn('hashed_reference', function ($query, $keyword) {
$query->whereRaw('MD5(payment_transactions.reference) LIKE ?', ['%' . $keyword . '%']);
});
$this->tableFilterCustomColumns($dataTable);
$response = $dataTable->make(true);
$data = $response->getData();
$data = json_decode(json_encode($data), true);
$queries = \DB::getQueryLog();
$data['queries'] = $queries;
return $data;
}
public function validateExport(Request $request)
{
if ($request['query']) {
ini_set('memory_limit', '2048M');
$results = $this->util->getGenericData($request["query"], $request["bindings"]);
if (count($results) > 0) {
$name = 'ReporteAcademiaPagos' . time() . '.xlsx';
Excel::store(new AcademyPurchasesExport($results), $name, 'public');
return response()->json(['success' => true, 'message' => 'Validación OK', 'data' => $name]);
}
}
return response()->json(['success' => false, 'message' => 'No existen datos a exportar']);
}
public function export($name)
{
return $this->util->export($name);
}
public function finishPayment($paymentTransaction)
{
if (!$paymentTransaction) {
return response()->json(['success' => false, 'message' => 'No se encontró la transacción de pago'], 200);
}
if ($paymentTransaction->state == 'CONFIRMED') {
$academyPurchase = AcademyPurchase::with('academy_user', 'academy_user.user', 'payment_transaction')
->where('payment_transaction_id', $paymentTransaction->id)
->first();
if (!$academyPurchase || !$academyPurchase->academy_user_id) {
return response()->json(['success' => false, 'message' => 'No se encontró el pago de la academia'], 200);
}
// Asignar estado academia
$academyState = new AcademyStateController();
$academyState->assignStateAcademy($academyPurchase->academy_user_id);
// Validar pago inscripción
if (isset($academyPurchase->enrollment_academy_price)) {
$request = new Request([
'id' => $academyPurchase->academy_user_id,
'state' => true
]);
// Ajustar cupos disponibles
$controller = new AcademyScheduleController();
$controller->adjustAvailableSlotsSchedules();
// Activar usuario
$academyController = new AcademyController;
$academyController->activate($request);
// Asociar etiqueta Inscrito_academia_XXXX
$this->createEnrollmentTag($academyPurchase, $academyPurchase->term);
// Validar periodo por defecto
$academyPeriodController = new AcademyPeriodController;
if ($academyDefaultPeriod = $academyPeriodController->validateDefaultPeriod($academyPurchase->academy_user_id)) {
$this->createPaymentSchedule(
$academyPurchase->academy_user_id,
$academyDefaultPeriod->id,
$academyPurchase->user_id,
null,
1
);
}
}
// Validar pago mensualidad
else {
$academyController = new AcademyController;
// Validar estado de pago
$academyController->validatePaymentStatus($academyPurchase->academy_user_id);
// Validar estado activo
$academyController->validateActive($academyPurchase->academy_user_id);
// Crear proximo pago
$purchase = $this->createNextPayment($academyPurchase);
// Validar estado al día de pagos y notificación de renovación
if (!$purchase) {
$academyController->notificateEmailRegistrationRenewal($academyPurchase->academy_user_id);
}
}
try {
$invoice = new CollectionInvoiceController();
$invoice->validateCreditCollectionInvoice($paymentTransaction->gateway_payments_id, $paymentTransaction->reference, $paymentTransaction->gateway_transaction_id, 'academy', $academyPurchase->price);
// $pay = new LealPayController();
// $pay->validateUserPointsAccumulation($order);
} catch (\Throwable $th) {
$data = [
'academyPurchase' => $academyPurchase,
'message' => $th->getMessage(),
'getFile' => $th->getFile(),
'getLine' => $th->getLine(),
];
$util = new UtilController;
$util->logFile(json_encode($data));
}
// Sincronizar pago al ERP
$this->syncERP($academyPurchase);
}
}
public function indexEditUserPayment($id)
{
$academy_payment = AcademyPurchase::where('id', $id)->with('user', 'academy_user', 'payment_transaction')->first();
$allPeriodsAcademy = AcademyPeriod::select('id', 'name')->where('active', true)->get();
$paymentMethods = PaymentMethod::select('id', 'name')->where('active', true)->get();
$type = 'purchases';
return view('academy.payments.edit', compact('academy_payment', 'allPeriodsAcademy', 'paymentMethods', 'type'));
}
public function indexPayUser($id)
{
$academy_payment = AcademyPurchase::where('id', $id)->with('user', 'academy_user', 'payment_transaction')->first();
$paymentMethods = PaymentMethod::select('id', 'name')->where('active', true)->get();
$type = 'purchases';
return view('academy.payments.pay', compact('academy_payment', 'paymentMethods', 'type'));
}
public function createEnrollmentPayment($academyUser, $discount, $paymentType, $confirmPayment = false)
{
$academyCategory = null;
if ($academyUser->academy_category_id) {
$academyCategory = AcademyCategory::where([['id', $academyUser->academy_category_id], ['active', 1]])->first();
}
if (!$academyCategory) {
return array('status' => false, 'message' => 'El alumno no contiene una categoría registrada o vigente al día de hoy');
}
$now = Carbon::now();
$startTerm = $this->academyParameterController->registrationStartDate($academyUser->type_academy);
$endTerm = $this->academyParameterController->registrationEndDate($academyUser->type_academy);
$years = [$startTerm->year, $endTerm->year];
$term = implode('-', array_unique($years));
$startTermString = $startTerm->toDateString();
$endTermString = $endTerm->toDateString();
$academyPurchase = AcademyPurchase::with('payment_transaction')
->where('academy_user_id', $academyUser->id)
->where('term_type', $paymentType)
->where(function ($query) use ($term, $startTermString, $endTermString) {
$query->where('term', $term)
->orWhere(function ($query) use ($startTermString, $endTermString) {
$query->where('start_term', $startTermString)->where('end_term', $endTermString);
});
})
->whereNull('deleted_at')
->first();
if ($academyPurchase && !$academyPurchase->payment_transaction) {
$academyPurchase->delete();
$academyPurchase = null;
}
if ($academyPurchase && $academyPurchase->payment_transaction && $academyPurchase->payment_transaction->state == 'CONFIRMED') {
return array('status' => true, 'academyPurchase' => $academyPurchase, 'message' => 'Ya existe un pago de inscripción vigente para este alumno');
}
if (!$discount) {
$studentDiscount = $this->validateStudentDiscounts($academyUser->id, 'enrollment');
if ($studentDiscount) {
$discount = $studentDiscount;
}
}
$serviceCharge = 0;
$controller = new ServiceChargeController;
if ($controller->validateServiceCharge()) {
$request = new Request([
'services' => 'academy',
'payment_types' => 'enrollment',
'categories' => [$academyCategory->id]
]);
$serviceCharge = $controller->calculateServiceCharge($request);
}
$paymentDueDate = $endTerm;
if ($daysPaymentDueDate = $this->academyParameterController->validateEnableCollectionAdvancePayments()) {
$paymentDueDate = Carbon::parse($startTerm)->addDays($daysPaymentDueDate - 1);
}
$subTotal = $this->formatNumberForCurrency($academyCategory->inscription_value * (1 - ($discount / 100)));
if ($serviceCharge && str_contains($serviceCharge . '', '%')) {
$serviceCharge = (floatval(str_replace('%', '', $serviceCharge)) / 100) * $subTotal;
}
$serviceCharge = !$subTotal ? 0 : $this->formatNumberForCurrency($serviceCharge);
$data = [
'enrollment_academy_price' => $academyCategory->inscription_value,
'subtotal' => $subTotal,
'service_charge' => $serviceCharge,
'price' => $subTotal + $serviceCharge,
'discount' => $discount,
'user_id' => $academyUser->user_id,
'academy_user_id' => $academyUser->id,
'state' => 0,
'active' => 1,
'term_type' => $paymentType,
'term' => $term,
'start_term' => $startTerm->toDateString(),
'end_term' => $endTerm->toDateString(),
'payment_activation' => $now,
'payment_due_date' => $paymentDueDate->toDateString(),
'payment_identifier' => intval($now->getPreciseTimestamp(3))
];
if ($academyPurchase) {
$academyPurchase->update($data);
return array('status' => true, 'academyPurchase' => $academyPurchase);
}
$academyPurchase = AcademyPurchase::updateOrCreate(
[
'academy_user_id' => $academyUser->id,
'term_type' => $paymentType,
'term' => $term
],
$data
);
$module = Module::where('route', 'academy')->first();
$this->registerLog(Auth::user() ? Auth::user()->id : 1, 'Crear Pago Inscripción', json_encode(AcademyPurchase::with('academy_user')->find($academyPurchase->id)), "Create", $module->id);
if ($discount == 100 || $confirmPayment) {
$controller = new AcademyController;
$status = $controller->changeSchedule($academyUser->id, $academyUser->academy_schedule_id);
$status = json_decode(json_encode($status), true);
if (!$status['original']['r']) {
return array('status' => false, 'message' => 'El pago no se puede confirmar porque no hay cupos disponibles en el horario registrado del alumno');
}
$paymentTransaction = $this->createPaymentTransaction($discount, $academyUser);
$academyPurchase->payment_transaction_id = $paymentTransaction->id;
$academyPurchase->update();
$this->finishPayment($paymentTransaction);
}
return array('status' => true, 'academyPurchase' => $academyPurchase);
}
public function createPaymentTransaction($discount, $academyUser)
{
$paymentTransaction = PaymentTransactionService::createPendingTransaction(
get_class($this),
null,
$academyUser->identification
);
$paymentTransaction->comment = 'Pago generado automáticamente por el sistema, ' . ($discount == 100 ? '100% descuento' : 'pago confirmado desde plantilla');
$paymentTransaction->payment_date = Carbon::now();
$paymentTransaction->state = PaymentStatusEnum::CONFIRMED;
$paymentTransaction->save();
return $paymentTransaction;
}
public function createPaymentSchedule(
$academyUserId,
$academyUserPeriodId,
$userId,
$initMonth,
$paymentsAmount = 1,
$discount = null,
$confirmPayment = false,
$message = null,
$schedule = null
) {
$academyUser = AcademyUser::where('id', $academyUserId)->first();
$academyCategory = null;
if ($academyUser->academy_category_id) {
$academyCategory = AcademyCategory::where([['id', $academyUser->academy_category_id], ['active', 1]])->first();
}
if (!$academyCategory) {
return;
}
$academyPeriod = AcademyPeriod::where('id', $academyUserPeriodId)
->first();
if (!$academyPeriod) {
return array('status' => false, 'message' => 'El periodo seleccionado no existe o se encuentra inactivo');
}
if ($academyPeriod) {
$academyUser->update(['academy_period_id' => $academyPeriod->id]);
}
$user = User::select('id', 'pns_id')->where('id', $academyUser->user_id)->first();
$start_term = Carbon::now();
$currentMonth = $start_term->month;
if (!$initMonth) {
// Obtener mes pendiente
$pendingMonths = $this->getPendingMonths($academyUser->id);
$initMonth = max($pendingMonths[0], $academyPeriod->init_month);
if (!($currentMonth == $academyPeriod->end_month || ($academyPeriod->init_month > $currentMonth && $academyPeriod->end_month <= 12) || $this->validateOldEnrolledUser($academyUser->id, $academyUser->type_academy))) {
if (($start_term->day > $this->validateMaximumPaymentDayMonth($academyUser->type_academy)) && $initMonth == $currentMonth) {
$initMonth += 1;
}
}
//se validan pagos anticipados del siguiente año
if (($currentMonth >= $academyPeriod->end_month && $currentMonth <= 12) || ($this->academyParameterController->validateRegistrationStartDate($start_term, $academyUser->type_academy))) {
$initMonth = $academyPeriod->init_month;
$start_term->addYear();
}
} else if ($this->academyParameterController->validateRegistrationStartDate($start_term, $academyUser->type_academy) && $this->validateEnrollmentTagNextYear($academyUser->user_id) && $initMonth < $academyPeriod->end_month) {
$start_term->addYear();
$currentMonth = $start_term->month;
}
//tratar de no generar un pago posterior al "mes fin de pago"
if (($currentMonth > $academyPeriod->end_month) && ($initMonth > $academyPeriod->end_month)) {
return;
}
$serviceCharge = 0;
$controller = new ServiceChargeController;
if ($controller->validateServiceCharge()) {
$request = new Request([
'services' => 'academy',
'payment_types' => 'monthly',
'categories' => [$academyCategory->id]
]);
$serviceCharge = $controller->calculateServiceCharge($request);
}
$start_term->day(1);
$start_term->month($initMonth);
$academyPurchaseSaved = null;
$registrationEndDate = $this->academyParameterController->registrationEndDate($academyUser->type_academy);
//Se obtiene la cantidad de meses disponibles
$pendingMonthsToCreateNextPayment = $registrationEndDate->month - $initMonth + 1;
$academyPeriodAux = null;
//Se valida si existe periodo que cumpla con la cantidad de meses disponibles
if ($academyPeriod->annual_installments > $pendingMonthsToCreateNextPayment) {
//Se obtiene el periodo que cumpla con la cantidad de meses disponibles
$academyPeriodAux = AcademyPeriod::where('active', true)
->where('init_month', '<=', $initMonth)
->where('end_month', '>=', $initMonth)
->where('annual_installments', '<=', $pendingMonthsToCreateNextPayment)
->orderBy('annual_installments', 'desc')
->first();
}
if ($academyPeriodAux) {
$academyPeriod = $academyPeriodAux;
}
//Cantidad de meses del periodo aceptado
$monthsAmount = $academyPeriod->annual_installments;
//Se validan descuentos
if (!$discount) {
$discount = $academyPeriod->discount;
$studentDiscount = $this->validateStudentDiscounts($academyUser->id, 'monthly');
if ($studentDiscount) {
$discount = $studentDiscount;
}
}
do {
$end_term = Carbon::parse($start_term)->addMonths($monthsAmount)->subDays(1);
$registrationEndDate = $this->academyParameterController->registrationEndDate($academyUser->type_academy);
if (Carbon::parse($start_term) > $registrationEndDate) {
return;
}
if ($end_term > $registrationEndDate) {
$end_term = $registrationEndDate;
}
$start_term_month = $start_term->locale('es')->monthName;
$end_term_month = Carbon::parse($end_term)->locale('es')->monthName;
if ($start_term->year == $end_term->year) {
if (!str_contains($academyPeriod->name, $start_term->year))
$term = $start_term->year . ', ' . (($start_term_month == $end_term_month) ? $start_term_month : ($start_term_month . ' - ' . $end_term_month));
else
$term = (($start_term_month == $end_term_month) ? $start_term_month : ($start_term_month . ' - ' . $end_term_month));
} else {
$term = $start_term_month . ', ' . $start_term->year . ' - ' . $end_term_month . ', ' . $end_term->year;
}
$startTermString = $start_term->toDateString();
$endTermString = $end_term->toDateString();
$previousPurchase = AcademyPurchase::with('payment_transaction')
->where('academy_user_id', $academyUserId)
->where('term_type', '!=', 'Inscripción')
->where('start_term', $startTermString)
->where('end_term', $endTermString)
->first();
if ($previousPurchase) {
if ($discount == 100 || $confirmPayment) {
if (!$previousPurchase->payment_transaction || $previousPurchase->payment_transaction->state != 'CONFIRMED') {
$paymentTransaction = $this->createPaymentTransaction($discount, $previousPurchase->academy_user);
$previousPurchase->payment_transaction_id = $paymentTransaction->id;
$previousPurchase->update();
$academyController = new AcademyController;
$academyController->validatePaymentStatus($previousPurchase->academy_user_id);
}
}
if ($paymentsAmount == 1)
// Retorna cuando encuentra que el pago que se esta tratando de generar ya existe
return $previousPurchase;
else {
$start_term = $end_term;
$paymentsAmount -= 1;
continue;
}
} else if ($start_term && $end_term) {
$paymentAvailable = $this->validatePaymentAvailableRegistrationPayment($academyUser, $start_term->toDateString(), $end_term->toDateString());
if (!$paymentAvailable) {
if ($paymentsAmount == 1)
return;
else {
$start_term = $end_term;
$paymentsAmount -= 1;
continue;
}
}
}
// TODO - Revisar este if porque con el manejo de los meses del siguiente año y fecha de fin inscripción, no se puede generar un pago posterior al mes de fin de pago.
// if (Carbon::parse($end_term)->subDays(1)->year > $start_term->year) {
// $academyPeriodNew = AcademyPeriod::select('id')
// ->where('annual_installments', '<=', 12 - $start_term->month + 1)
// ->orderBy('annual_installments', 'DESC')->first();
// $this->createPaymentSchedule(
// $academyUserId,
// $academyPeriodNew->id,
// $userId,
// $initMonth,
// $paymentsAmount,
// $discount,
// $confirmPayment,
// $message,
// $schedule
// );
// return;
// }
$monthly_academy_price = $academyCategory->monthly_payment * $monthsAmount;
$subTotal = $this->formatNumberForCurrency($monthly_academy_price * (1 - ($discount / 100)));
if ($serviceCharge && str_contains($serviceCharge . '', '%')) {
$serviceCharge = (floatval(str_replace('%', '', $serviceCharge)) / 100) * $subTotal;
}
$academyPurchase = new AcademyPurchase;
$academyPurchase->monthly_academy_price = $monthly_academy_price;
$academyPurchase->price_discount = 0;
$academyPurchase->discount = $discount;
$academyPurchase->subtotal = $subTotal;
$academyPurchase->service_charge = !$academyPurchase->subtotal ? 0 : $this->formatNumberForCurrency($serviceCharge);
$academyPurchase->price = $academyPurchase->subtotal + $academyPurchase->service_charge;
$academyPurchase->user_id = $academyUser->user_id;
$academyPurchase->academy_user_id = $academyUser->id;
$academyPurchase->active = 1;
$academyPurchase->term_type = $academyPeriod->name;
$academyPurchase->term = $term;
$academyPurchase->start_term = Carbon::parse($start_term)->toDateString();
$academyPurchase->end_term = Carbon::parse($end_term)->toDateString();
$academyPurchase->payment_activation = Carbon::now();
$paymentDueDate = $academyPurchase->end_term;
if ($daysPaymentDueDate = $this->academyParameterController->validateEnableCollectionAdvancePayments($academyUser->type_academy)) {
$paymentDueDate = Carbon::parse($start_term)->addDays($daysPaymentDueDate - 1)->toDateString();
}
$academyPurchase->payment_due_date = $paymentDueDate;
$academyPurchase->payment_identifier = intval(\Carbon\Carbon::now()->getPreciseTimestamp(3));
$academyPurchase->state = $academyPurchase->payment_due_date < $academyPurchase->payment_activation;
$academyPurchase->save();
$module = Module::where('route', 'academy')->first();
$this->registerLog(Auth::user() ? Auth::user()->id : 1, 'Crear Pago Mensualidad', json_encode(AcademyPurchase::with('academy_user')->find($academyPurchase->id)), "Create", $module->id);
if ($discount == 100 || $confirmPayment) {
$paymentTransaction = $this->createPaymentTransaction($discount, $academyPurchase->academy_user);
$academyPurchase->payment_transaction_id = $paymentTransaction->id;
$academyPurchase->update();
$academyController = new AcademyController;
$academyController->validatePaymentStatus($academyPurchase->academy_user_id);
if ($paymentsAmount == 1 && $discount == 100 && $initMonth < 12) {
$this->createPaymentSchedule(
$academyUserId,
$academyUserPeriodId,
$userId,
$initMonth + 1,
$paymentsAmount,
$discount,
$confirmPayment,
$message,
$schedule
);
}
if ($paymentsAmount == 1) {
// Retorna para evitar envio masivo de notificaciones
return $academyPurchase;
}
}
$start_term = $end_term->addDays(1);
if (!$academyPurchaseSaved)
$academyPurchaseSaved = $academyPurchase;
if ($user && $discount != 100) {
if (!$message) {
$message = 'Ya puedes realizar el pago "' . $academyPurchase->term . '" del alumno ' . $academyUser->student_name . ' ' . $academyUser->student_last_name . '.';
} else if (str_contains($message, 'notify')) {
$message = $this->academyParameterController->replaceWildcardsMessage($this->academyParameterController->getParametersMessage($message, true), $academyPurchase->term_type, $academyPurchase->term, $academyUser->student_name . ' ' . $academyUser->student_last_name, config('app.name'));
}
if ($user && $user->pns_id) {
$notificationsController = new NotificationsController;
$notificationsController->createSystemNotification($message, $user->id, $schedule);
}
}
$paymentsAmount -= 1;
} while ($start_term->year == Carbon::now()->year && $paymentsAmount > 0);
return $academyPurchaseSaved;
}
public function exportTemplate()
{
return Excel::download(new AcademySchedulePaymentsTemplate(), 'PlantillaProgramarPagos' . '_' . time() . '.xlsx');
}
public function import(Request $request)
{
try {
$file = new AcademySchedulePaymentsImport();
$file->request = $request;
Excel::import($file, $request->importSchedulePayments);
return array('r' => true, 'd' => $file->answer, 'm' => trans('messages.academy_payments.import_successfully') . ' ' . $file->edit['creados'] . ' creados');
} catch (Exception $e) {
$error = [
'function' => 'import',
'request' => $request->all(),
'message' => $e->getMessage(),
'getFile' => $e->getFile(),
'getLine' => $e->getLine(),
];
$util = new UtilController();
$util->logFile(json_encode($error));
return array('r' => false, 'm' => trans('messages.academy_payments.import_error') . "'" . $request->importSchedulePayments->getClientOriginalName() . "', el archivo no cumple con el formato requerido.");
}
}
public function modifyStudentPaymentSchedule($id)
{
$academy_payment = AcademyPurchase::where('academy_user_id', $id)->with('user', 'academy_user', 'payment_transaction')->get();
$student_info_change_payment_type = AcademyPurchase::where('academy_user_id', $id)->with('user', 'academy_user', 'payment_transaction')->first();
$validate_monthly_payment = false;
$paid_registration = false;
$payment_id = $student_info_change_payment_type->payment_transaction_id;
$cnt = 0;
foreach ($academy_payment as $payment) {
$cnt++;
$payment_transaction_id = $payment->payment_transaction_id;
$academyPurchaseId = $payment->id;
$payments_made = AcademyPurchase::where('id', $academyPurchaseId)->with('user', 'academy_user', 'payment_transaction')->first();
if (isset($payments_made)) {
$transacción_id = $payments_made->payment_transaction_id;
if (isset($transacción_id)) {
// Validamos el pago de la Inscripción
if ($payments_made->payment_transaction->state == 'CONFIRMED' && isset($payments_made->enrollment_academy_price)) {
$paid_registration = true;
}
} else {
if ($paid_registration == true) {
if (!isset($payments_made->academy_user->payment_status)) {
$validate_monthly_payment = true;
}
} else {
if ($paid_registration == false) {
return array('r' => false, 'd' => null, 'm' => trans('messages.academy_purchases.tag16'));
}
}
}
if ($paid_registration == true) {
// Validacion el payment_transaction_id no sea el mismo de la Inscripción
if (($payment_transaction_id == null || isset($payment_transaction_id)) && $payment_id != $payment_transaction_id) {
if (!isset($payments_made->academy_user->payment_status)) {
if (!isset($payments_made->payment_transaction->state) || $payments_made->payment_transaction->state == 'PENDING') {
$validate_monthly_payment = true;
} else {
$validate_monthly_payment = false;
$this->messages = [
'message' => trans('messages.academy_purchases.tag18'),
'state' => false,
];
break;
}
} else {
$validate_monthly_payment = false;
$this->messages = [
'message' => trans('messages.academy_purchases.tag18'),
'state' => false,
];
break;
}
}
}
}
}
if ($validate_monthly_payment == true) {
return array('r' => true, 'd' => $student_info_change_payment_type, 'm' => trans('messages.academy_purchases.tag17'));
} else {
return array('r' => false, 'd' => null, 'm' => trans('messages.academy_purchases.tag18'));
}
}
public function typePaymentModifiedAndAccepted(Request $request)
{
try {
$academy_user_id = $request['id'];
$userApp_id = $request['userApp_id'];
$periods_academy_new = $request['periods_academy_new'];
$if_remove_payments = false;
$academy_payment = AcademyPurchase::where('academy_user_id', $academy_user_id)->with('user', 'academy_user', 'payment_transaction')->get();
if ($academy_payment) {
foreach ($academy_payment as $payment) {
if (!$payment->enrollment_academy_price) {
$academyPurchaseId = $payment->id;
$remove_payment = AcademyPurchase::find($academyPurchaseId);
$remove_payment->delete();
$if_remove_payments = true;
}
}
}
if ($if_remove_payments == true) {
$this->createPaymentSchedule(
$academy_user_id,
$periods_academy_new,
$userApp_id,
null,
null
);
$dataId = AcademyPurchase::latest('id')->first();
}
return array('r' => true, 'd' => $dataId, 'm' => __('messages.academy_purchases.tag21'));
} catch (\Throwable $th) {
return array('r' => false, 'd' => null, 'm' => __('messages.academy_purchases.tag22'));
}
}
public function validatePayment($id)
{
$academyPurchase = AcademyPurchase::where('id', $id)->with('payment_transaction')->first();
$paymentTransactionController = new PaymentTransactionController();
$paymentTransactionController->validatePayment($academyPurchase->payment_transaction);
return array(
'r' => true,
'data' => null,
'm' => 'Se validó el pago en la pasarela de pagos'
);
}
public function delete(Request $request, $id)
{
try {
$payment = AcademyPurchase::with('user', 'academy_user', 'payment_transaction')->find($id);
if (AcademyPurchase::where('id', $id)->delete()) {
if ($payment->payment_transaction) {
$payment->payment_transaction->delete();
}
$this->registerLog(Auth::user()->id, 'Eliminar Pago Academia', json_encode($payment), "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 createNextPayment($academyPurchase, $message = null, $schedule = null)
{
$endTerm = Carbon::parse($academyPurchase->end_term);
$startTerm = $endTerm->month + 1;
if ($endTerm->year > Carbon::now()->year) {
$startTerm += 12;
}
$pendingMonths = $this->getPendingMonths($academyPurchase->academy_user_id, $startTerm);
if (!in_array($startTerm, $pendingMonths)) {
return false;
}
$academyUser = AcademyUser::select('id', 'user_id', 'academy_period_id')->where('id', $academyPurchase->academy_user_id)->first();
return $this->createPaymentSchedule(
$academyUser->id,
$academyUser->academy_period_id,
$academyUser->user_id,
$startTerm,
1,
null,
false,
$message,
$schedule
);
}
public function getPendingMonths($academyUserId, $initMonth = null)
{
$currentDate = Carbon::now();
$maximumPaymentDays = AcademyParameter::where('key', 'maximum_payment_day_month')->first()->value ?? 15;
$dataAcademyUser = AcademyUser::select('academy_users.type_academy', 'academy_periods.end_month')
->leftjoin('academy_periods', 'academy_users.academy_period_id', '=', 'academy_periods.id')
->where('academy_users.id', $academyUserId)
->first();
if ($this->academyParameterController->validateRegistrationStartDate($currentDate, $dataAcademyUser->type_academy)) {
$currentDate->startOfYear()->addYear();
}
if (!$initMonth) {
$month = $currentDate->month;
$initMonth = $currentDate->day > $maximumPaymentDays ? $month + 1 : $month;
}
$year = $currentDate->year;
$currentMonths = [];
$endMonth = $dataAcademyUser->end_month ?? 12;
if ($initMonth <= $endMonth) {
$availableMonths = range($initMonth, $endMonth);
} else {
$availableMonths = range($initMonth, $endMonth + 12);
}
$purchases = AcademyPurchase::select('academy_purchases.start_term', 'academy_purchases.end_term')
->where('academy_purchases.academy_user_id', $academyUserId)
->whereNull('academy_purchases.enrollment_academy_price')
->whereYear('academy_purchases.start_term', $year)
->join('payment_transactions', 'academy_purchases.payment_transaction_id', '=', 'payment_transactions.id')
->where('payment_transactions.state', 'CONFIRMED')
->get();
foreach ($purchases as $purchase) {
$startMonth = Carbon::parse($purchase->start_term)->month;
$endDate = Carbon::parse($purchase->end_term);
$currentMonths = array_merge($currentMonths, range($startMonth, $endDate->year > $year ? $endMonth : $endDate->month));
}
$months = array_diff($availableMonths, $currentMonths);
return count($months) > 0 ? array_slice($months, 0, 1) : [];
}
public function adjustPaymentsEnrolledStudents()
{
$academyUsers = AcademyUser::select('academy_users.*')->whereIn('academy_state_id', [6, 7])->get();
foreach ($academyUsers as $academyUser) {
$purchases = AcademyPurchase::where('academy_user_id', $academyUser->id)->whereNull('enrollment_academy_price')->get();
if (!count($purchases)) {
$this->createPaymentSchedule(
$academyUser->id,
$academyUser->academy_period_id,
$academyUser->user_id,
null,
1
);
} else {
$purchases = AcademyPurchase::select('academy_purchases.*')->where('academy_user_id', $academyUser->id)->whereNull('enrollment_academy_price')
->leftjoin('payment_transactions', 'payment_transactions.id', '=', 'academy_purchases.payment_transaction_id')
->where(function ($q) {
$q->whereNotIn('payment_transactions.state', ['PENDING', 'CONFIRMED'])->orWhereNull('payment_transactions.id');
})
->orderBy('start_term', 'ASC')
->get();
foreach ($purchases as $key => $purchase) {
if ($key > 0) {
$purchase->delete();
} else {
$purchase->update(['active' => true]);
}
}
}
}
return 'Proceso ejecutado, total alumnos revisados: ' . count($academyUsers);
}
public function validateStudentDiscounts($academyUserId, $type)
{
$controller = new AcademyDiscountController();
return $controller->validateStudentDiscounts($academyUserId, $type);
}
public function getPayment($id)
{
return AcademyPurchase::with(
'academy_user',
'academy_user.user',
'academy_user.academy_location',
'academy_user.academy_location.academy_location_erp',
'academy_user.academy_category',
'academy_user.academy_category.academy_category_erp',
'academy_user.academy_category.academy_location.academy_location_erp',
'payment_transaction',
'payment_transaction.payment_method',
'payment_transaction.gateway_payments'
)->find($id);
}
public function getSucursalForERP($id)
{
$sucursal = 2;
$payment = AcademyPurchase::find($id);
$users = AcademyUser::where('user_id', $payment->user_id)->pluck('id')->toArray();
$sucursal += array_search($payment->academy_user_id, $users);
if ($sucursal == 5)
$sucursal += 1;
return $this->util->completeLeadingZeros($sucursal, 3);
}
private function validateSyncWithERPPayment($academyPurchase)
{
return !AcademyPurchase::select('sync_with_erp')->where('id', $academyPurchase->id)->first()->sync_with_erp;
}
public function saveERPLog($data, $message, $action)
{
$transactionId = $data;
ErpLog::updateOrCreate(
[
'origin' => 'academy',
'transaction_id' => $transactionId,
'resolved' => false
],
[
'origin' => 'academy',
'action' => $action,
'origin_class' => get_class($this),
'data' => $data,
'transaction_id' => $transactionId,
'message' => $message,
]
);
}
public function retrySyncERP($data, $action)
{
$academyPurchase = AcademyPurchase::find($data);
$this->syncERP($academyPurchase, $action);
}
public function confirmSyncERP($academyPurchase)
{
$academyPurchase->sync_with_erp = true;
$academyPurchase->update();
}
public function syncERP($academyPurchase, $action = null)
{
try {
$erps = Erp::select('id', 'class')->where('active', true)->get();
$erpSync = ErpParameter::where('key', 'academy_sync')->first();
if (!$erpSync || $erpSync->value == 'false') {
$this->saveERPLog($academyPurchase->id, 'Sinc ERP deshabilitada', 'syncERP');
return;
}
if (!$this->validateSyncWithERPPayment($academyPurchase)) {
return;
}
$erpService = new ErpService;
foreach ($erps as $index => $erp) {
$classPath = $erp->class;
$ERPRepository = new $classPath($erp->id);
$erpBaseController = new ERPBaseController;
$erpReference = $academyPurchase->erp_reference ?? 'A' . $academyPurchase->id;
if (
$academyPurchase->price < $erpBaseController->minPriceToSync($ERPRepository->erpId) ||
!$erpService->canSync($erpReference, $ERPRepository, 'academy_sync')
) {
return;
}
$previousBill = $ERPRepository->hasPreviousBill($erpReference);
if ($previousBill['r']) {
$academyPurchase->erp_response = $previousBill['d'];
$academyPurchase->update();
$this->confirmSyncERP($academyPurchase);
if (isset($previousBill['saveLog']) && $previousBill['saveLog']) {
$this->saveERPLog(
$academyPurchase->id,
json_encode($previousBill['error']),
'createOrder'
);
}
continue;
}
$academyPurchase->erp_reference = $ERPRepository->getNextReference($erpReference);
$academyPurchase->update();
$erpService->synchronizing($erpReference);
switch ($action) {
case 'createOrder':
$this->createOrderERP($academyPurchase, $ERPRepository);
break;
case 'createRC':
$this->createRCERP($academyPurchase, $ERPRepository);
break;
case 'createBill':
$this->createBillERP($academyPurchase, $ERPRepository);
break;
default:
$this->createThirdClientERP($academyPurchase, $ERPRepository);
break;
}
}
} catch (Exception $e) {
$error = [
'message' => $e->getMessage(),
'getFile' => $e->getFile(),
'getLine' => $e->getLine(),
];
$this->saveERPLog($academyPurchase->id, json_encode($error), 'syncERP');
}
}
private function createThirdClientERP($academyPurchase, $ERPRepository)
{
$academyUser = AcademyUser::withTrashed()
->with('academy_schedule')
->with('advisor_document_type')
->where('id', $academyPurchase->academy_user_id)
->first();
$academyUser->address_id = $academyUser->address_id ?? $ERPRepository->getDefaultAddress($academyUser->user_id);
$academyUser->update();
$addressObj = Address::with('city')->find($academyUser->address_id);
$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 = $academyUser->type_person == 'JURIDICAL_PERSON';
$thirdDocument = $juricalPerson ? $academyUser->advisor_nit : $academyUser->advisor_identification;
$params = new \stdClass();
$third = new \stdClass();
$client = new \stdClass();
$third->document = $thirdDocument;
$third->firstName = $academyUser->advisor_name;
$third->lastName = $academyUser->advisor_last_name;
$third->contact = $academyUser->advisor_last_name . ' ' . $academyUser->advisor_name;
$third->phone = $academyUser->phone;
$third->email = $academyUser->mail;
$third->documentType = $ERPRepository->mapDocumentType($juricalPerson ? 'nit' : $academyUser->advisor_document_type->alias);
$third->birthDate = Carbon::parse($academyUser->created_at)->format('Ymd');
$third->typeThird = $academyUser->type_person;
$third->gender = '0';
$third->socialReason = $juricalPerson ? $academyUser->advisor_business_name : $third->contact;
$third->establishmentName = $juricalPerson ? $academyUser->advisor_property_name : $third->contact;
$third->ciiu = $juricalPerson ? $academyUser->advisor_isic_code : null;
$client->document = $academyUser->identification;
$client->contact = $academyUser->student_last_name . ' ' . $academyUser->student_name;
$client->phone = $academyUser->phone;
$client->email = $academyUser->mail;
$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 = $this->getSucursalForERP($academyPurchase->id);
$params->price_list = $academyUser->academy_schedule ? $academyUser->academy_schedule->academy_categories_schedules[0]->academy_category->academy_location->price_list : '';
$params->typeClient = 'CACD';
$params->postal = '';
$params->hasTaxes = '1';
$params->createThirdPos = true;
$params->idCriteria = '101';
$params->criteria = '1012';
$params->currency = 'COP';
$params->latitude = $addressObj ? $addressObj->lat : null;
$params->longitude = $addressObj ? $addressObj->long : null;
$response = $ERPRepository->createThirdClient($params);
if (!$response['r']) {
$this->saveERPLog($academyPurchase->id, json_encode($response['d']), 'createThirdClient');
return;
}
$this->createOrderERP($academyPurchase, $ERPRepository);
}
private function createOrderERP($academyPurchase, $ERPRepository)
{
$paymentDetail = $this->getPayment($academyPurchase->id);
$hasPreviousOrder = $ERPRepository->hasPreviousOrder(
$academyPurchase->erp_reference,
$paymentDetail->payment_transaction->reference,
$paymentDetail->payment_transaction->gateway_transaction_id
);
if ($hasPreviousOrder) {
$this->createRCERP($academyPurchase, $ERPRepository);
return;
}
$academyUser = $paymentDetail->academy_user;
if (!$academyUser->academy_category) {
$this->saveERPLog(
$academyPurchase->id,
'El deportista ' . $academyUser->student_name . ' ' . $academyUser->student_last_name . ' no tiene categoria asignada',
'createOrder'
);
return;
}
$academyCategoryErp = $paymentDetail->academy_user->academy_category->academy_category_erp;
$academyLocationErp = $paymentDetail->academy_user->academy_category->academy_location->academy_location_erp;
$paymentTransaction = $academyPurchase->payment_transaction;
if (!$academyCategoryErp) {
$this->saveERPLog(
$academyPurchase->id,
'La categería (' . $paymentDetail->academy_user->academy_category->name . ') no tiene código de servicio configurado',
'createOrder'
);
return;
}
$serviceCode = $paymentDetail->enrollment_academy_price ? $academyCategoryErp->registration_service_item_code : $academyCategoryErp->pension_service_item_code;
if ($paymentDetail->monthly_academy_price && $paymentDetail->academy_user->academy_period) {
$academyPeriod = $paymentDetail->academy_user->academy_period;
$academyPeriodErp = $academyPeriod->academy_period_erp;
if (count($academyPeriodErp)) {
if ($academyPeriod->annual_installments > 1) {
$serviceCode = $academyPeriodErp[0]->service_item_code;
} else {
if (Carbon::parse($paymentTransaction->payment_date) < Carbon::parse($academyPurchase->start_term)) {
$serviceCode = $academyPeriodErp[0]->service_item_code;
}
}
}
}
$academyUser = $paymentDetail->academy_user;
$juricalPerson = $academyUser->type_person == 'JURIDICAL_PERSON';
$addressObj = Address::with('city')->where('id', $academyUser->address_id)->first();
$operationCenter = $academyLocationErp->operation_center ?? null;
$costCenter = $academyCategoryErp->cost_center ?? null;
$third = new \stdClass();
$third->firstName = $academyUser->advisor_name;
$third->lastName = $academyUser->advisor_last_name;
$third->contact = $academyUser->advisor_last_name . ' ' . $academyUser->advisor_name;
$third->phone = $academyUser->phone;
$third->email = $academyUser->mail;
$third->documentType = $ERPRepository->mapDocumentTypeOrder($juricalPerson ? 'nit' : $academyUser->advisor_document_type->alias);
$third->document = $juricalPerson ? $academyUser->advisor_nit : $academyUser->advisor_identification;
$orderParams = new \stdClass();
$orderParams->operationCenter = $operationCenter;
$orderParams->document = $third->document;
$orderParams->sucursal = $this->getSucursalForERP($academyPurchase->id);
$orderParams->costCenter = $costCenter;
$orderParams->date = Carbon::now()->format('Ymd');
$orderParams->customerType = 'CACD';
$orderParams->note = $paymentDetail->payment_transaction->reference . ' - ' . $academyPurchase->term_type . ' - ' . $academyPurchase->term;
$orderParams->reference = $academyPurchase->erp_reference;
$orderParams->numeroPedido = $academyPurchase->id;
$orderParams->third = $third;
$orderParams->transaction = $paymentDetail->payment_transaction;
$orderParams->address = $addressObj;
$itemParams = new \stdClass();
$itemParams->operation_center = $operationCenter;
$itemParams->serviceCode = $serviceCode;
$itemParams->warehouse = 'AC' . $operationCenter;
$itemParams->cost_center = $costCenter;
$itemParams->date = $orderParams->date;
$itemParams->price_list = $academyLocationErp->price_list ?? null;
$itemParams->price = $paymentDetail->price; //Pago total incluido descuentos
$itemParams->fullPrice = $academyPurchase->monthly_academy_price ?? $academyPurchase->enrollment_academy_price;
$itemParams->discount = 0;
$discounts = [];
if ($paymentDetail->discount > 0 && $academyLocationErp) {
$discount = array(
'f430_id_co' => $academyLocationErp->operation_center,
'f430_consec_docto' => '1',
'f431_nro_registro' => '1',
'f432_tasa' => $paymentDetail->discount,
'f432_vlr_uni' => 0,
);
array_push($discounts, $discount);
$itemParams->discount += $this->formatNumberForCurrency(($itemParams->price * $paymentDetail->discount) / 100);
}
if ($paymentDetail->price_discount > 0 && $academyLocationErp) {
$discount = array(
'f430_id_co' => $academyLocationErp->operation_center,
'f430_consec_docto' => '1',
'f431_nro_registro' => '1',
'f432_tasa' => 0,
'f432_vlr_uni' => $paymentDetail->price_discount,
);
array_push($discounts, $discount);
$itemParams->discount += $paymentDetail->price_discount;
}
$orderParams->discounts = $discounts;
$orderParams->items = [$ERPRepository->generateOrderItem($itemParams)];
$response = $ERPRepository->createOrder($orderParams);
if (!$response['r']) {
$this->saveERPLog($academyPurchase->id, json_encode($response['d']), 'createOrder');
return;
}
$academyPurchase->erp_response = is_string($response['d']) ? $response['d'] : null;
$academyPurchase->update();
if (isset($response['saveLog']) && $response['saveLog']) {
$this->saveERPLog(
$academyPurchase->id,
json_encode($response['error']),
'createOrder'
);
}
$this->createRCERP($academyPurchase, $ERPRepository);
}
private function createRCERP($academyPurchase, $ERPRepository)
{
$erpBaseController = new ERPBaseController;
if (!$erpBaseController->syncRcEnabled($ERPRepository->erpId)) {
$this->createBillERP($academyPurchase, $ERPRepository);
return;
}
$paymentTransaction = $academyPurchase->payment_transaction;
$response = $ERPRepository->getOrder('A' . $academyPurchase->id);
if (!$response['r']) {
$this->saveERPLog($academyPurchase->id, json_encode($response['d']), 'createRC');
return;
}
$paymentMethod = PaymentMethod::select('code')->where('id', $paymentTransaction->payment_method_id)->first();
foreach ($response['d']->detalle->Table as $index => $siesaOrder) {
$paymentDetail = $this->getPayment($academyPurchase->id);
$academyUser = $paymentDetail->academy_user;
$response = $ERPRepository->getRC($academyUser->advisor_identification, $siesaOrder->CentroDeOperacion);
if ($response['r']) {
$previousRC = array_filter($response['d']->detalle->Table, function ($item) use ($paymentTransaction, $paymentDetail) {
return str_contains($item->Notas, $paymentTransaction->reference) && $item->TotalRecibo == $paymentDetail->price;
}, ARRAY_FILTER_USE_BOTH);
if (count($previousRC)) {
$this->createBillERP($academyPurchase, $ERPRepository);
continue;
}
}
$juricalPerson = $academyUser->type_person == 'JURIDICAL_PERSON';
$parameters = new \stdClass();
$parameters->paymentDate = Carbon::parse($paymentTransaction->payment_date)->format('Ymd');
$parameters->idThird = $juricalPerson ? $academyUser->advisor_nit : $academyUser->advisor_identification;
$parameters->currency = 'COP';
$parameters->siesaOrder = $siesaOrder;
$parameters->fe = '1105';
$parameters->note = $paymentTransaction->reference . ' - ' . $academyPurchase->term_type . ' - ' . $academyPurchase->term;
$parameters->assistant = '28050502';
$parameters->sucursal = $this->getSucursalForERP($academyPurchase->id);
$parameters->paymetMethod = $paymentMethod ? $paymentMethod->code : 'WAC';
$parameters->UN = '100';
$parameters->price = $paymentDetail->price;
$response = $ERPRepository->createRC($parameters);
if (!$response['r']) {
$this->saveERPLog($academyPurchase->id, json_encode($response['d']), 'createRC');
return;
}
$this->createBillERP($academyPurchase, $ERPRepository);
}
}
private function createBillERP($academyPurchase, $ERPRepository)
{
$erpBaseController = new ERPBaseController;
if (!$erpBaseController->syncBillEnabled($ERPRepository->erpId)) {
$this->confirmSyncERP($academyPurchase);
return;
}
$response = $ERPRepository->getOrder('A' . $academyPurchase->id);
if (!$response['r']) {
$this->saveERPLog($academyPurchase->id, json_encode($response['d']), 'createBill');
return;
}
$paymentTransaction = $academyPurchase->payment_transaction;
$paymentDetail = $this->getPayment($academyPurchase->id);
$academyUser = $paymentDetail->academy_user;
$juricalPerson = $academyUser->type_person == 'JURIDICAL_PERSON';
foreach ($response['d']->detalle->Table as $index => $siesaOrder) {
$parameters = new \stdClass();
$parameters->siesaOrder = $siesaOrder;
$parameters->thirdDocument = $juricalPerson ? $academyUser->advisor_nit : $academyUser->advisor_identification;
$parameters->note = $paymentTransaction->reference;
$parameters->price = $paymentDetail->price;
$parameters->typeDocument = 'FE1';
$response = $ERPRepository->createBill($parameters);
if (!$response['r']) {
$this->saveERPLog($academyPurchase->id, json_encode($response['d']), 'createBill');
return;
}
}
$this->confirmSyncERP($academyPurchase);
}
private function validatePaymentAvailableRegistrationPayment($academyUser, $start_term, $end_term)
{
return AcademyPurchase::join('payment_transactions', 'academy_purchases.payment_transaction_id', '=', 'payment_transactions.id')
->where('payment_transactions.state', 'CONFIRMED')
->where('academy_purchases.academy_user_id', $academyUser->id)
->whereNotNull('academy_purchases.enrollment_academy_price')
->whereDate('academy_purchases.start_term', '<=', $start_term)
->whereDate('academy_purchases.end_term', '>=', $end_term)
->first();
}
public function createEnrollmentTag($academyPurchase, $year)
{
$tag = $this->validateTag('Inscrito_academia_' . $year);
UserTag::updateOrCreate(
['tag_id' => $tag->id, 'user_id' => $academyPurchase->user_id, 'academy_user_id' => $academyPurchase->academy_user_id],
['tag_id' => $tag->id, 'user_id' => $academyPurchase->user_id, 'academy_user_id' => $academyPurchase->academy_user_id]
);
}
private function validateEnrollmentTagNextYear($userId)
{
$year = date('Y');
$year += 1;
$tag = $this->validateTag('Inscrito_academia_' . $year);
return UserTag::where([['user_id', $userId], ['tag_id', $tag->id]])->first();
}
public function validateEnrollmentTagYear($userId, $year)
{
$tag = $this->validateTag('Inscrito_academia_' . $year);
return UserTag::where([['user_id', $userId], ['tag_id', $tag->id]])->first();
}
private function validateTag($nameTag)
{
$tag = Tag::where('name', '=', $nameTag)->first();
if (!$tag) {
$tag = Tag::create(['name' => $nameTag, 'description' => $nameTag]);
}
return $tag;
}
public function validateStudentsWithoutRegistrationPaymentGenerated($academyUserId = null)
{
$date = Carbon::now();
$year = $date->year;
//Obtener alumnos sin pagos en el año actual
$users = AcademyUser::select('id')->where('academy_state_id', 5)
->whereNull('deleted_at')
->whereNotIn('id', function ($query) use ($year) {
$query->select('academy_user_id')
->from('academy_purchases')
->where('term', 'like', "{$year}%")
->where('term_type', 'Inscripción')
->whereNull('deleted_at');
})
->groupBy('id')
->get();
foreach ($users as $student) {
$academyUser = AcademyUser::find($student->id);
$this->createEnrollmentPayment(
$academyUser,
0,
'Inscripción'
);
}
}
private function validateOldEnrolledUser($academyUserId, $typeAcademy = 'children')
{
$oldEnrollmentUser = false;
if (
$this->academyParameterController->getParametersValueByTypeAcademy('enable_registration_renewal', $typeAcademy) == 'false' &&
$this->academyParameterController->getParametersValueByTypeAcademy('enable_first_month_renewal_payment_for_children', $typeAcademy) == 'true'
) {
$validOldEnrollmentUser = AcademyPurchase::select('academy_purchases.id')
->join('payment_transactions', 'payment_transactions.id', '=', 'academy_purchases.payment_transaction_id')
->where('academy_purchases.academy_user_id', $academyUserId)
->whereNull('academy_purchases.deleted_at')->whereNotNull('academy_purchases.enrollment_academy_price')->where('academy_purchases.term', Carbon::now()->subYear(1)->year)
->where('payment_transactions.state', 'CONFIRMED')
->first();
if ($validOldEnrollmentUser)
$oldEnrollmentUser = true;
}
return $oldEnrollmentUser;
}
private function validateMaximumPaymentDayMonth($typeAcademy = 'children')
{
$day = 15;
if ($academyParameter = $this->academyParameterController->getParametersValueByTypeAcademy('maximum_payment_day_month', $typeAcademy)) {
$day = $academyParameter;
}
return $day;
}
private function tableFilterQuery($request)
{
$states = $request->states;
$types = $request->types;
$duePayments = $request->duePayments;
$from_term = $request->from_term;
$to_term = $request->to_term;
$from_date = $request->from_date;
$to_date = $request->to_date;
$type_academy = $request->type_academy;
$franchises = $request->franchises;
DB::statement("SET sql_mode = ''");
$query = DB::table('academy_purchases')
->select(
'academy_purchases.id',
'academy_user.id AS academy_user.id',
'academy_user.student_name AS academy_user.student_name',
'academy_user.student_last_name AS academy_user.student_last_name',
'academy_user.identification AS academy_user.identification',
'academy_user.student_academy_code AS academy_user.student_academy_code',
'academy_state.name AS academy_state.name',
'academy_state.color AS academy_state.color',
'academy_locations.name AS locationName',
'academy_categories.name AS categoryName',
'academy_schedules.name AS scheduleName',
'appUser.first_name AS academy_user.user.first_name',
'appUser.last_name AS academy_user.user.last_name',
'appUser.email AS academy_user.user.email',
'academy_user.advisor_name AS academy_user.advisor_name',
'academy_user.advisor_last_name AS academy_user.advisor_last_name',
'academy_user.advisor_identification AS advisor_identification',
DB::raw('GROUP_CONCAT(DISTINCT(tags.name)) AS segmentation'),
DB::raw('IF(academy_purchases.state = 1, "SI", "NO") AS duePayment'),
'academy_purchases.term_type',
'academy_purchases.term',
'academy_purchases.start_term',
'academy_purchases.end_term',
'academy_purchases.payment_activation',
'academy_purchases.payment_due_date',
'academy_purchases.enrollment_academy_price',
'academy_purchases.monthly_academy_price',
'academy_purchases.price_discount',
'academy_purchases.discount',
'academy_purchases.subtotal',
'academy_purchases.service_charge',
'academy_purchases.price',
'payment_transactions.reference',
DB::raw('MD5(payment_transactions.reference) AS hashed_reference'),
'payment_transactions.gateway_transaction_id',
'payment_transactions.state',
'payment_transactions.comment',
'payment_methods.name AS payment_method',
'payment_transactions.support',
'academy_user.birthdate',
'document_types.name AS studentDocumentType',
DB::raw('IF(payment_transactions.state = "CONFIRMED",payment_transactions.payment_date,"") AS payment_date'),
'gateway_payments.name AS gateway_payments_name',
DB::raw("GROUP_CONCAT(DISTINCT(CONCAT_WS(' ', users1.first_name, users1.last_name, CONCAT('(',users1.email,')'))) ORDER BY users1.id ASC) AS coaches"),
'academy_purchases.sync_with_erp',
'academy_purchases.erp_response',
'academy_purchases.erp_reference'
)
->leftjoin('payment_transactions', 'academy_purchases.payment_transaction_id', '=', 'payment_transactions.id')
->leftjoin('payment_methods', 'payment_methods.id', '=', 'payment_transactions.payment_method_id')
->join('academy_users AS academy_user', function ($join) {
$join->on('academy_purchases.academy_user_id', '=', 'academy_user.id')
->whereNull('academy_user.deleted_at');
})
->join('document_types', 'document_types.id', '=', 'academy_user.student_document_type_id')
->leftjoin('academy_states AS academy_state', 'academy_state.id', '=', 'academy_user.academy_state_id')
->leftjoin('academy_categories', 'academy_categories.id', '=', 'academy_user.academy_category_id')
->leftjoin('academy_schedules', 'academy_schedules.id', '=', 'academy_user.academy_schedule_id')
->leftjoin('academy_schedules_coaches', 'academy_schedules_coaches.academy_schedule_id', '=', 'academy_schedules.id')
->leftjoin('users AS users1', 'users1.id', '=', 'academy_schedules_coaches.user_id')->whereNull('users1.deleted_at')
->leftjoin('academy_locations', 'academy_locations.id', '=', 'academy_categories.academy_location_id')
->leftjoin('users AS appUser', 'academy_user.user_id', '=', 'appUser.id')
->leftjoin('user_tags', 'appUser.id', '=', 'user_tags.user_id')
->leftjoin('tags', function ($join) {
$join->on('tags.id', '=', 'user_tags.tag_id')->where('tags.active', 1);
})
->leftjoin('gateway_payments', 'gateway_payments.id', '=', 'payment_transactions.gateway_payments_id')
->where([['academy_user.type_academy', $type_academy], ['academy_purchases.active', 1]])
->whereNull('academy_purchases.deleted_at')
->groupBy('academy_purchases.id');
//new filters
$academyLocationsService = new AcademyLocationsService;
if (!$academyLocationsService->validateAuthorizedLocations()) {
$authorizedLocations = $academyLocationsService->getAuthorizedLocations();
$query->whereIn('academy_locations.id', $authorizedLocations);
}
if ($request['categories'] || $request['locations']) {
$query->join('academy_categories_schedules as acs_filter', 'acs_filter.academy_schedule_id', '=', 'academy_schedules.id');
if ($request['locations']) {
$query->join('academy_categories as ac_filter_category', 'ac_filter_category.id', '=', 'acs_filter.academy_category_id')
->whereIn('ac_filter_category.academy_location_id', $request['locations'])
->whereIn('academy_categories.academy_location_id', $request['locations']);
}
if ($request['categories']) {
$query->whereIn('acs_filter.academy_category_id', $request['categories']);
// ->whereIn('academy_categories_schedules.academy_category_id', $request['categories']);
}
}
if ($request['schedules']) {
$query->join('academy_schedules_coaches as asc_filter', 'asc_filter.academy_schedule_id', '=', 'academy_schedules.id')
->whereIn('asc_filter.academy_schedule_id', $request['schedules']);
}
if ($request['coaches']) {
$query->join('academy_schedules_coaches as asc_main', 'asc_main.academy_schedule_id', '=', 'academy_schedules.id')
->whereIn('asc_main.user_id', $request['coaches']);
}
//end new filters
if ($states && $states != 'null') {
$options = $states;
$states = [];
$emptyOption = false;
$query->where(function ($q) use ($options, &$states, &$emptyOption) {
foreach ($options as $option) {
if ($option == 'Vacio') {
$q->whereNull('academy_purchases.payment_transaction_id');
$emptyOption = true;
} else {
$states[] = $option;
}
}
if (!empty($states)) {
if ($emptyOption) {
$q->orWhereIn('payment_transactions.state', $states);
} else {
$q->whereIn('payment_transactions.state', $states);
}
}
});
}
if ($types && $types != 'null') {
$query->whereIn('academy_purchases.term_type', $types);
}
if ($duePayments && $duePayments != 'null') {
$duePayments = str_replace('SI', 1, $duePayments);
$duePayments = str_replace('NO', 0, $duePayments);
$query->whereIn('academy_purchases.state', $duePayments);
}
if ($from_term && $from_term != 'null') {
$query->whereDate('academy_purchases.start_term', '>=', $from_term);
}
if ($to_term && $to_term != 'null') {
$query->whereDate('academy_purchases.end_term', '<=', $to_term);
}
if ($from_date && $from_date != 'null') {
$query->whereDate('payment_transactions.payment_date', '>=', $from_date);
}
if ($to_date && $to_date != 'null') {
$query->whereDate('payment_transactions.payment_date', '<=', $to_date);
}
DB::statement("SET sql_mode = 'STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'");
return $query;
}
private function tableFilterCustomColumns($dataTable)
{
$dataTable->addColumn('actions', function ($obj) {
if (
$this->validateRolePermissions('academy', 'administrator') ||
$this->validateRolePermissions('academy', 'supervisor')
) {
$actions = '<i class="fa fa-pencil iconMini" onClick="clickEditPayment(' . $obj->id . ')" data-id="' . $obj->id . '" title="Editar Pago"></i>';
$hideDeletePayment = $obj->state && $obj->state == 'CONFIRMED' && $obj->gateway_transaction_id && Auth::user()->rol_id != $this->__SUPERADMIN_ROL;
if (!$hideDeletePayment) {
$actions .= '<i class="fa fa-trash iconMini" onClick="clickDelete(' . $obj->id . ')" data-id="' . $obj->id . '" title="Eliminar"></i>';
}
if (!$obj->state || (!$obj->support && $obj->state != 'CONFIRMED')) {
$actions .= '<i class="fa fa-money iconMini" onClick="clickPay(' . $obj->id . ')" data-id="' . $obj->id . '" title="Cargar Pago"></i>';
}
if ($obj->state && $obj->support && $obj->state != 'CONFIRMED') {
$actions .= '<i class="fa fa-check iconMini" onClick="clickValidatePay(' . $obj->id . ')" data-id="' . $obj->id . '" title="Validar Pago"></i>';
}
if ($obj->state && $obj->state != 'CONFIRMED') {
$actions .= '<i class="fa fa-credit-card iconMini" onClick="clickValidatePaymentInGateway(' . $obj->id . ')" data-id="' . $obj->id . '" title="Validar en pasarela"></i>';
}
// if ($obj->state && $obj->state == 'CONFIRMED' && $obj->sync_with_erp) {
// $actions .= '<button type="button" class="btn btn-primary btn-xs" onClick="openCreditNote(' . $obj->id . ')"> <i class="fa fa-dollar"></i> ' . trans('messages.erp.credit_note') . '</button>';
// }
return $actions;
} else {
return '';
}
})
->addColumn('pending', function ($obj) {
return $obj->state && $obj->support && $obj->state != 'CONFIRMED';
})
->editColumn('state', function ($obj) {
return '<span class="label ' . ($obj->state == 'CONFIRMED' ? 'label-success' : 'label-danger') . '">' . $obj->state . '</span>';
})
->editColumn('payment_date', function ($obj) {
return $obj->payment_date ? Carbon::parse($obj->payment_date)->format('Y-m-d h:i:s A') : '';
})
->rawColumns(['actions', 'state', 'payment_date']);
}
}