Files
Jobhero_back/app/Http/Controllers/PaymentController.php
Carlos b34622b289 Fix búsqueda en tiempo real, paginación, OneSignal, bancos/categorías y vistas auth
- ajaxcrud.js: fix race condition en búsqueda, abort de requests en vuelo
- Layout: mover @yield('js') después de app.js para corregir orden de carga
- Paginación: useBootstrapFour() + eliminar wrappers <ul> duplicados en 17 vistas
- OneSignal: migrar de UserTag iChamba_ID a ExternalId en controladores
- API: agregar endpoint GET /api/banks y campos rfc/bank/bank_account/fee en hero()
- Seeders: BanksSeeder (239 bancos) y CategoriesSeeder (100 categorías)
- Auth views: corregir padding/scroll en register, login, password reset

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 21:21:44 -06:00

420 lines
15 KiB
PHP
Executable File

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Pagination\LengthAwarePaginator;
use Carbon\Carbon;
use App\Models\User;
use App\Models\Suppliers;
use App\Models\Payments;
use App\Models\FinishedContracts;
use App\Models\Cards;
use Openpay;
use Exception;
use OpenpayApiError;
use OpenpayApiAuthError;
use OpenpayApiRequestError;
use OpenpayApiConnectionError;
use OpenpayApiTransactionError;
class PaymentController extends Controller
{
//
public function index(Request $request)
{
$dateFrom = $request->has('date_from') ? strip_tags($request->get('date_from')) : $request->session()->get('pay_date_from', '');
$dateTo = $request->has('date_to') ? strip_tags($request->get('date_to')) : $request->session()->get('pay_date_to', '');
if ($request->has('date_from')) $request->session()->put('pay_date_from', $dateFrom);
if ($request->has('date_to')) $request->session()->put('pay_date_to', $dateTo);
$contracts = FinishedContracts::with(['suppliers.user', 'suppliers.banks'])
->where('status_id', 3)
->where('paid', false)
->where('transaction_id', '!=', 'NO APPLY')
->when($dateFrom, fn($q) => $q->whereDate('appointment', '>=', $dateFrom))
->when($dateTo, fn($q) => $q->whereDate('appointment', '<=', $dateTo))
->get();
$field = in_array($request->input('field'), ['company_name', 'email', 'rfc_curp', 'clabe', 'bank', 'contract_count', 'total_amount', 'total_revenue', 'total_iva', 'total_isr', 'total_fee'])
? $request->input('field')
: 'total_amount';
$sort = $request->input('sort', 'desc') === 'asc' ? 'asc' : 'desc';
$grouped = $contracts->groupBy('supplier_id')->map(function ($group) {
$first = $group->first();
return (object) [
'suppliers' => $first->suppliers,
'contract_count' => $group->count(),
'total_amount' => $group->sum('amount'),
'total_revenue' => $group->sum('revenue'),
'total_iva' => $group->sum('IVA'),
'total_isr' => $group->sum('ISR'),
'total_fee' => $group->sum('ichamba_fee'),
];
})->values();
$sortCallbacks = [
'company_name' => fn($r) => optional($r->suppliers)->company_name,
'email' => fn($r) => optional(optional($r->suppliers)->user)->email,
'rfc_curp' => fn($r) => optional($r->suppliers)->RFC ?: optional($r->suppliers)->CURP,
'clabe' => fn($r) => optional($r->suppliers)->clabe,
'bank' => fn($r) => optional(optional($r->suppliers)->banks)->name,
'contract_count' => fn($r) => $r->contract_count,
'total_amount' => fn($r) => $r->total_amount,
'total_revenue' => fn($r) => $r->total_revenue,
'total_iva' => fn($r) => $r->total_iva,
'total_isr' => fn($r) => $r->total_isr,
'total_fee' => fn($r) => $r->total_fee,
];
$grouped = $sort === 'asc'
? $grouped->sortBy($sortCallbacks[$field])->values()
: $grouped->sortByDesc($sortCallbacks[$field])->values();
$perPage = 15;
$page = $request->input('page', 1);
$payments = new LengthAwarePaginator(
$grouped->slice(($page - 1) * $perPage, $perPage)->values(),
$grouped->count(),
$perPage,
$page,
['path' => $request->url(), 'query' => $request->query()]
);
if ($request->ajax()) {
return view('payments.index', compact('payments', 'dateFrom', 'dateTo'));
} else {
return view('payments.ajax', compact('payments', 'dateFrom', 'dateTo'));
}
}
public function cardsindex(Request $request)
{
//
$request->session()->put('search', $request
->has('search') ? strip_tags($request->get('search')) : ($request->session()
->has('search') ? strip_tags($request->session()->get('search')) : ''));
$request->session()->put('field', $request
->has('field') ? strip_tags($request->get('field')) : ($request->session()
->has('field') ? strip_tags($request->session()->get('field')) : 'id'));
$request->session()->put('sort', $request
->has('sort') ? strip_tags($request->get('sort')) : ($request->session()
->has('sort') ? strip_tags($request->session()->get('sort')) : 'asc'));
//$headers = $request->get('header') != '' ? $request->get('header') : -1;
$cards= new Cards();
$cards = $cards->where('id', 'LIKE', '%' . strip_tags($request->session()->get('search')) . '%')
->orwhere('token', 'LIKE', '%' . strip_tags($request->session()->get('search')) . '%')
->orderBy(strip_tags($request->session()->get('field')), strip_tags($request->session()->get('sort')))
->paginate(10);
if ($request->ajax()) {
return view('cards.index', compact('cards'));
} else {
return view('cards.ajax', compact('cards'));
}
}
public function destroy($id)
{
$credit_card = Cards::where('id', $id)->first();
$user = User::where('id', $credit_card->user_id)->first();
Openpay::setProductionMode(true);
try {
$openpay = Openpay::getInstance(config('app.openpay_id'), config('app.openpay_apikey'));
$customer = $openpay->customers->get($user->openpay_id);
$card = $customer->cards->get($credit_card->token);
$card->delete();
} catch (OpenpayApiTransactionError $e) {
return response()->json([
'type' => 'error',
'message' => 'Error en la transacción'
]);
} catch (OpenpayApiRequestError $e) {
return response()->json([
'type' => 'error',
'message' => 'Error en los datos requeridos'
]);
} catch (OpenpayApiConnectionError $e) {
return response()->json([
'type' => 'error',
'message' => 'Error al conectarse a Openpay: ' . $e->getMessage()
]);
} catch (OpenpayApiAuthError $e) {
return response()->json([
'type' => 'error',
'message' => 'Error al conectarse a Openpay: ' . $e->getMessage()
]);
} catch (OpenpayApiError $e) {
return response()->json([
'type' => 'error',
'message' => 'Error al conectarse a Openpay: ' . $e->getMessage()
]);
} catch (Exception $e) {
return response()->json([
'type' => 'error',
'message' => 'Error: ' . $e->getMessage()
]);
}
Cards::destroy($id);
return redirect('cards');
}
public function addcard(Request $request)
{
$rules = [
'token' => 'required|string|regex:/(^[A-Za-z0-9 ]+$)+/',
'device_id' => 'required|string|regex:/(^[A-Za-z0-9 ]+$)+/',
];
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
return redirect()->back()->withInput($request->all())->withErrors($validator);
}
$user = $request->user();
Openpay::setProductionMode(true);
if ($user->openpay_id == null) {
try {
$openpay = Openpay::getInstance(config('app.openpay_id'), config('app.openpay_apikey'));
$customerData = array(
'external_id' => $user->id,
'name' => $user->name,
'email' => $user->email,
);
$customer = $openpay->customers->add($customerData);
} catch (OpenpayApiTransactionError $e) {
return response()->json([
'type' => 'error',
'message' => 'No se pudo procesar la transacción'
]);
} catch (OpenpayApiRequestError $e) {
return response()->json([
'type' => 'error',
'message' => 'No se pudo procesar la operación'
]);
} catch (OpenpayApiConnectionError $e) {
return response()->json([
'type' => 'error',
'message' => 'Error al conectarse a Openpay: ' . $e->getMessage()
]);
} catch (OpenpayApiAuthError $e) {
return response()->json([
'type' => 'error',
'message' => 'Error al conectarse a Openpay: ' . $e->getMessage()
]);
} catch (OpenpayApiError $e) {
return response()->json([
'type' => 'error',
'message' => 'Error al conectarse a Openpay: ' . $e->getMessage()
]);
} catch (Exception $e) {
return response()->json([
'type' => 'error',
'message' => 'Error: ' . $e->getMessage()
]);
}
$user->openpay_id = $customer->id;
$user->save();
}
$cardDataRequest = array(
'token_id' => $request->token,
'device_session_id' => $request->device_id
);
try {
$openpay = Openpay::getInstance(config('app.openpay_id'), config('app.openpay_apikey'));
$customer = $openpay->customers->get($user->openpay_id);
$card = $customer->cards->add($cardDataRequest);
} catch (OpenpayApiTransactionError $e) {
return response()->json([
'type' => 'error',
'message' => 'No se pudo procesar la transacción'
]);
} catch (OpenpayApiRequestError $e) {
return response()->json([
'type' => 'error',
'message' => 'No se pudo procesar la operación'
]);
} catch (OpenpayApiConnectionError $e) {
return response()->json([
'type' => 'error',
'message' => 'Error al conectarse a Openpay: ' . $e->getMessage()
]);
} catch (OpenpayApiAuthError $e) {
return response()->json([
'type' => 'error',
'message' => 'Error al conectarse a Openpay: ' . $e->getMessage()
]);
} catch (OpenpayApiError $e) {
return response()->json([
'type' => 'error',
'message' => 'Error al conectarse a Openpay: ' . $e->getMessage()
]);
} catch (Exception $e) {
return response()->json([
'type' => 'error',
'message' => 'Error: ' . $e->getMessage()
]);
}
$card = new Cards();
$card->user_id = $user->id;
$card->token = $request->token;
$card->save();
return response()->json([
'message' => 'Tarjeta guardada exitosamente'
]);
}
public function deletecard(Request $request)
{
$rules = [
'card_id' => 'required|numeric',
];
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
return redirect()->back()->withInput($request->all())->withErrors($validator);
}
$user = $request->user();
$credit_card = Cards::where('id', $request->card_id)->first();
Openpay::setProductionMode(true);
if ($credit_card->user_id == $user->id) {
try {
$openpay = Openpay::getInstance(config('app.openpay_id'), config('app.openpay_apikey'));
$customer = $openpay->customers->get($user->openpay_id);
$card = $customer->cards->get($credit_card->token);
$card->delete();
} catch (OpenpayApiTransactionError $e) {
return response()->json([
'type' => 'error',
'message' => 'No se pudo procesar la transacción'
]);
} catch (OpenpayApiRequestError $e) {
return response()->json([
'type' => 'error',
'message' => 'No se pudo procesar la operación'
]);
} catch (OpenpayApiConnectionError $e) {
return response()->json([
'type' => 'error',
'message' => 'Error al conectarse a Openpay: ' . $e->getMessage()
]);
} catch (OpenpayApiAuthError $e) {
return response()->json([
'type' => 'error',
'message' => 'Error al conectarse a Openpay: ' . $e->getMessage()
]);
} catch (OpenpayApiError $e) {
return response()->json([
'type' => 'error',
'message' => 'Error al conectarse a Openpay: ' . $e->getMessage()
]);
} catch (Exception $e) {
return response()->json([
'type' => 'error',
'message' => 'Error: ' . $e->getMessage()
]);
}
Cards::destroy($request->card_id);
return response()->json([
'message' => 'Tarjeta eliminada exitosamente'
]);
}
}
public function getcards(Request $request)
{
$user = $request->user();
Openpay::setProductionMode(true);
if ($user->openpay_id) {
try {
$openpay = Openpay::getInstance(config('app.openpay_id'), config('app.openpay_apikey'));
$customer = $openpay->customers->get($user->openpay_id);
} catch (OpenpayApiTransactionError $e) {
return response()->json([
'type' => 'error',
'message' => 'No se pudo procesar la transacción'
]);
} catch (OpenpayApiRequestError $e) {
return response()->json([
'type' => 'error',
'message' => 'No se pudo procesar la operación'
]);
} catch (OpenpayApiConnectionError $e) {
return response()->json([
'type' => 'error',
'message' => 'Error al conectarse a Openpay: ' . $e->getMessage()
]);
} catch (OpenpayApiAuthError $e) {
return response()->json([
'type' => 'error',
'message' => 'Error al conectarse a Openpay: ' . $e->getMessage()
]);
} catch (OpenpayApiError $e) {
return response()->json([
'type' => 'error',
'message' => 'Error al conectarse a Openpay: ' . $e->getMessage()
]);
} catch (Exception $e) {
return response()->json([
'type' => 'error',
'message' => 'Error: ' . $e->getMessage()
]);
}
$cards = Cards::where('user_id', $user->id)->get();
$cardsinfo = array();
foreach ($cards as $credit_card) {
$card = $customer->cards->get($credit_card->token);
$cardinfo = array(
'id' => $credit_card->id,
'brand' => $card->brand,
'card_number' => $card->card_number,
);
$cardsinfo[] = $cardinfo;
}
return response()->json($cardsinfo);
}
}
}