Files
Sio-Back/app/Http/Controllers/Administrador/ClientesController.php
SIO Admin de656b70a2 feat: Actualizacion sistema SIO Backend
- Nuevo modulo de historial de cambios (ServicioHistorial)
- Observer para tracking automatico de cambios en servicios
- Correccion de variables auxiliar en ServiciosController
- Actualizacion de configuraciones y migraciones
- Endpoint para consultar historial de cambios

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 23:01:55 +00:00

468 lines
16 KiB
PHP
Executable File

<?php
namespace App\Http\Controllers\Administrador;
use App\Components\AdjustImage;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use const App\Http\Controllers\ATENCION_CLIENTES;
use App\Http\Requests\Administrador\ClientesDomiciliosRequest;
use App\Http\Requests\Administrador\ClientesRequest;
use App\Models\Cliente;
use App\Models\ClienteDatoFiscal;
use App\Models\ClienteDomicilio;
use App\Models\FacturaFormaPago;
use App\Models\FacturaMetodoPago;
use App\Models\FacturaTipoComprobante;
use App\Models\FacturaUsoCFDI;
use App\Models\Sucursal;
use App\Models\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Log;
class ClientesController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index(Request $request)
{
$user = Auth::user();
$deleted = $request->input('deleted');
$orderBy = $request->input('sortBy','users.nombre');
$order = $request->input('order','asc');
$queryBuilder = Cliente::select('clientes.*', 'users.nombre as asesor_nombre', 'users.apellido_paterno as asesor_apellido_paterno', 'users.apellido_materno as asesor_apellido_materno', 'sucursales.nombre as sucursal_nombre')
->join('users', 'users.id', '=', 'clientes.asesor_id')
->join('sucursales', 'sucursales.id', '=', 'clientes.sucursal_id')
->where('clientes.sucursal_id', $user->sucursal_id)
->orderBy($orderBy,$order);
if($query = $request->get('query',false)){
$queryBuilder->where(function($q) use ($query){
$q->where('clientes.denominacion','like','%' .$query.'%')
->orWhere('sucursales.nombre','like','%' .$query.'%');
});
}
if($deleted) {
$queryBuilder->onlyTrashed();
}
if($perPage = $request->input('perPage',false)){
$clientes = $queryBuilder->paginate($perPage);
}else{
$clientes = ['data'=>$queryBuilder->get()];
}
return response()->success($clientes);
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(ClientesRequest $request)
{
$data = $request->all();
DB::beginTransaction();
try {
$cliente = Cliente::create($data);
if($data['requiere_factura']){
$cliente->registroDatosFiscales()->create($data['datos_fiscales']);
}
DB::commit();
return response()->success($cliente);
} catch (\Exception $e) {
DB::rollBack();
Log::info($e->getMessage());
return response()->unprocessable('Error', ['Error al guardar el Cliente.']);
}
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
$cliente = Cliente::select('clientes.*', 'users.nombre as asesor_nombre', 'users.apellido_paterno as asesor_apellido_paterno', 'users.apellido_materno as asesor_apellido_materno', 'sucursales.nombre as sucursal_nombre')
->join('users', 'users.id', '=', 'clientes.asesor_id')
->join('sucursales', 'sucursales.id', '=', 'clientes.sucursal_id')
->where('clientes.id', $id)
->withTrashed()
->first();
$cliente->datos_fiscales = ClienteDatoFiscal::where('cliente_id', $id)->first();
return response()->success($cliente);
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(ClientesRequest $request, $id)
{
$data = $request->all();
DB::beginTransaction();
try {
$cliente = Cliente::where('id',$id)
->withTrashed()
->firstOrFail();
$cliente->update($data);
if($data['requiere_factura']){
$cliente->registroDatosFiscales()->update($data['datos_fiscales']);
}else{
$cliente->registroDatosFiscales()->delete();
}
DB::commit();
return response()->success($cliente);
} catch (\Exception $e) {
DB::rollBack();
Log::info($e->getMessage());
return response()->unprocessable('Error', ['Error al actualizar el Cliente.']);
}
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id, Request $request)
{
$deleted = $request->input('deleted');
if($deleted){
$cliente = Cliente::where('id',$id)
->onlyTrashed()
->first();
$cliente->restore();
}else{
$cliente = Cliente::findOrFail($id);
$cliente->delete();
}
return response()->success(['result' => 'ok']);
}
public function indexDomiciliosXCliente(Request $request, $id)
{
$orderBy = $request->input('sortBy','nombre_sucursal');
$order = $request->input('order','asc');
$queryBuilder = ClienteDomicilio::where('cliente_id', $id)
->orderBy($orderBy,$order);
if($query = $request->get('query',false)){
$queryBuilder->where(function($q) use ($query){
$q->where('nombre_sucursal','like','%' .$query.'%')
->orWhere('calle','like','%' .$query.'%')
->orWhere('entre_calles','like','%' .$query.'%')
->orWhere('num_ext','like','%' .$query.'%')
->orWhere('colonia','like','%' .$query.'%')
->orWhere('ciudad','like','%' .$query.'%')
->orWhere('cp','like','%' .$query.'%')
->orWhere('telefono','like','%' .$query.'%')
->orWhere('celular_responsable','like','%' .$query.'%');
});
}
$cliente = Cliente::where('id', $id)->first();
if($perPage = $request->input('perPage',false)){
$data = collect($queryBuilder->paginate($perPage))->put('cliente_denominacion', $cliente->denominacion)->all();
}else{
$data = ['data'=>$queryBuilder->get(), 'cliente_denominacion' => $cliente->denominacion];
}
return response()->success($data);
}
public function showDomicilioXCliente($cliente_id, $id)
{
$domicilio = ClienteDomicilio::where('cliente_id', $cliente_id)
->where('id', $id)
->firstOrFail();
return response()->success($domicilio);
}
public function updateDomicilioXCliente(ClientesDomiciliosRequest $request, $cliente_id, $id)
{
$data = $request->all();
$nombre_croquis_pdf = null;
$croquis_pdf = substr($request->input('nombre_croquis', false), strpos($request->input('nombre_croquis', false), ',') +1);
if ($croquis_pdf) {
$nombre_croquis_pdf = 'croquis_cliente_' . $cliente_id . '_domicilio_' . $id . '.pdf';
Storage::disk('public')->put('pdf_croquis/' . $nombre_croquis_pdf, base64_decode($croquis_pdf));
}
$validator = Validator::make($data, [
'nombre_sucursal' => [
Rule::unique('clientes_domicilios')->where(function ($query) use($cliente_id, $id) {
$query->where('cliente_id', $cliente_id)
->where('id', '<>',$id);
})
],
'numero_sucursal' => [
Rule::unique('clientes_domicilios')->where(function ($query) use($cliente_id, $id) {
$query->where('cliente_id', $cliente_id)
->where('id', '<>',$id);
})
]
]);
if($validator->fails()){
return response()->unprocessable('Parametros inválidos',$validator->errors()->all());
}
$domicilio = ClienteDomicilio::where('cliente_id', $cliente_id)
->where('id', $id)
->firstOrFail();
$data['nombre_croquis'] = $nombre_croquis_pdf;
$domicilio->update($data);
return response()->success($domicilio);
}
public function storeDomicilioXCliente(ClientesDomiciliosRequest $request, $cliente_id)
{
$data = $request->all();
$nombre_croquis_pdf = null;
$validator = Validator::make($data, [
'nombre_sucursal' => [
Rule::unique('clientes_domicilios')->where(function ($query) use($cliente_id) {
$query->where('cliente_id', $cliente_id);
})
],
'numero_sucursal' => [
Rule::unique('clientes_domicilios')->where(function ($query) use($cliente_id) {
$query->where('cliente_id', $cliente_id);
})
]
]);
if($validator->fails()){
return response()->unprocessable('Parametros inválidos',$validator->errors()->all());
}
$cliente = Cliente::where('id', $cliente_id)->firstOrFail();
//Se agregan valores por default de lat y lng
$lat = $request->input('lat', null);
$lng = $request->input('lng', null);
$data['lat'] = ($lat)? $lat : '24.772795';
$data['lng'] = ($lng)? $lng : '-107.4432';
$domicilio = $cliente->registroDomicilios()->create($data);
$croquis_pdf = substr($request->input('nombre_croquis', false), strpos($request->input('nombre_croquis', false), ',') +1);
if ($croquis_pdf) {
$nombre_croquis_pdf = 'croquis_cliente_' . $cliente_id .'_domicilio_' .$domicilio->id .'.pdf';
Storage::disk('public')->put('pdf_croquis/' . $nombre_croquis_pdf, base64_decode($croquis_pdf));
}
$domicilio->update([
'nombre_croquis' => $nombre_croquis_pdf
]);
return response()->success($domicilio);
}
public function destroyDomicilioXCliente($cliente_id, $id){
ClienteDomicilio::where('id', $id)
->where('cliente_id', $cliente_id)
->delete();
return response()->success(['result' => 'ok']);
}
public function asesores(Request $request){
$orderBy = $request->input('sortBy','nombre');
$order = $request->input('order','asc');
$queryBuilder = User::select('users.*', DB::raw("coalesce (roles.name, '') as role"), 'roles.id as role_id', 'tipos_empleados.nombre as tipo_empleado', 'tipos_empleados.id as tipo_empleado_id', 'sucursales.id as sucursal_id', 'sucursales.nombre as sucursal')
->orderBy($orderBy,$order)
->leftJoin('role_users', 'role_users.user_id', '=', 'users.id')
->leftJoin('roles', 'roles.id', '=', 'role_users.role_id')
->join('sucursales', 'sucursales.id', '=', 'users.sucursal_id')
->join('tipos_empleados', 'tipos_empleados.id', '=', 'users.tipo_empleado_id')
->where('users.tipo_empleado_id', ATENCION_CLIENTES);
if($query = $request->get('query',false)){
$queryBuilder->where(function($q) use ($query){
$q->where('users.email','like','%' .$query.'%')
->orWhere('users.nombre','like','%' .$query.'%')
->orWhere('users.apellido_paterno','like','%' .$query.'%')
->orWhere('users.apellido_materno','like','%' .$query.'%')
->orWhere('users.telefono','like','%' .$query.'%')
->orWhere('roles.name','like','%' .$query.'%');
});
}
if($perPage = $request->input('perPage',false)){
$data = $queryBuilder->paginate($perPage);
}else{
$data = ['data'=>$queryBuilder->get()];
}
return response()->success($data);
}
public function formasPago(Request $request){
$orderBy = $request->input('sortBy','descripcion');
$order = $request->input('order','asc');
$queryBuilder = FacturaFormaPago::orderBy($orderBy,$order);
if($query = $request->get('query',false)){
$queryBuilder->where(function($q) use ($query){
$q->where('descripcion','like','%' .$query.'%');
});
}
if($perPage = $request->input('perPage',false)){
$data = $queryBuilder->paginate($perPage);
}else{
$data = ['data'=>$queryBuilder->get()];
}
return response()->success($data);
}
public function metodosPago(Request $request){
$orderBy = $request->input('sortBy','descripcion');
$order = $request->input('order','asc');
$queryBuilder = FacturaMetodoPago::orderBy($orderBy,$order);
if($query = $request->get('query',false)){
$queryBuilder->where(function($q) use ($query){
$q->where('descripcion','like','%' .$query.'%');
});
}
if($perPage = $request->input('perPage',false)){
$data = $queryBuilder->paginate($perPage);
}else{
$data = ['data'=>$queryBuilder->get()];
}
return response()->success($data);
}
public function tipoComprobante(Request $request){
$orderBy = $request->input('sortBy','descripcion');
$order = $request->input('order','asc');
$queryBuilder = FacturaTipoComprobante::orderBy($orderBy,$order);
if($query = $request->get('query',false)){
$queryBuilder->where(function($q) use ($query){
$q->where('descripcion','like','%' .$query.'%');
});
}
if($perPage = $request->input('perPage',false)){
$data = $queryBuilder->paginate($perPage);
}else{
$data = ['data'=>$queryBuilder->get()];
}
return response()->success($data);
}
public function usoCFDI(Request $request){
$orderBy = $request->input('sortBy','descripcion');
$order = $request->input('order','asc');
$queryBuilder = FacturaUsoCFDI::orderBy($orderBy,$order);
if($query = $request->get('query',false)){
$queryBuilder->where(function($q) use ($query){
$q->where('descripcion','like','%' .$query.'%');
});
}
if($perPage = $request->input('perPage',false)){
$data = $queryBuilder->paginate($perPage);
}else{
$data = ['data'=>$queryBuilder->get()];
}
return response()->success($data);
}
public function sucursales(Request $request){
$orderBy = $request->input('sortBy','nombre');
$order = $request->input('order','asc');
$queryBuilder = Sucursal::orderBy($orderBy,$order);
if($query = $request->get('query',false)){
$queryBuilder->where(function($q) use ($query){
$q->where('nombre','like','%' .$query.'%');
});
}
if($perPage = $request->input('perPage',false)){
$data = $queryBuilder->paginate($perPage);
}else{
$data = ['data'=>$queryBuilder->get()];
}
return response()->success($data);
}
public function mostrarPDF($domicilio_id){
$domicilio = ClienteDomicilio::select('nombre_croquis')->where('id', $domicilio_id)->firstOrFail();
if($domicilio->nombre_croquis && Storage::disk('public')->exists("pdf_croquis/". $domicilio->nombre_croquis)) {
return response()->file(storage_path('app/public/pdf_croquis/' . $domicilio->nombre_croquis));
}else{
return response()->unprocessable('El domicilio del cliente no tiene asignado PDF. Favor de adjuntarlo.');
}
}
}