Arreglo de la paginación y actualización de expediente
This commit is contained in:
parent
dd2b3211db
commit
9a4f70baa2
@ -15,7 +15,7 @@ class CatalogNameImgController extends VueController
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$names = CatalogNameImg::orderBy('name')->get();
|
||||
$names = CatalogNameImg::orderBy('id', 'ASC')->get();
|
||||
|
||||
return ApiResponse::OK->response([
|
||||
'names' => $names,
|
||||
|
||||
@ -16,57 +16,18 @@ class DeviceController extends Controller
|
||||
public function index(Request $request)
|
||||
{
|
||||
try {
|
||||
$query = Device::query();
|
||||
$devices = Device::query()->with('deviceModules.module', 'deviceModules.user');
|
||||
|
||||
if ($request->filled('serie')) {
|
||||
$query->where('serie', 'LIKE', '%' . $request->input('serie') . '%');
|
||||
$devices->where('serie', 'LIKE', '%' . $request->input('serie') . '%');
|
||||
}
|
||||
|
||||
if ($request->filled('brand')) {
|
||||
$query->where('brand', 'LIKE', '%' . $request->input('brand') . '%');
|
||||
$devices->where('brand', 'LIKE', '%' . $request->input('brand') . '%');
|
||||
}
|
||||
|
||||
$query->with('deviceModules.module', 'deviceModules.user');
|
||||
|
||||
$perPage = $request->input('per_page', 15);
|
||||
$devices = $query->paginate($perPage);
|
||||
|
||||
return ApiResponse::OK->response([
|
||||
'devices' => $devices->map(function ($device) {
|
||||
$module = $device->deviceModules->first()?->module;
|
||||
$authorizedUsers = $device->deviceModules
|
||||
->filter(fn($dm) => $dm->user !== null)
|
||||
->map(function ($deviceModule) {
|
||||
return [
|
||||
'id' => $deviceModule->user->id,
|
||||
'name' => $deviceModule->user->full_name,
|
||||
'email' => $deviceModule->user->email,
|
||||
];
|
||||
})
|
||||
->unique('id')
|
||||
->values();
|
||||
|
||||
return [
|
||||
'id' => $device->id,
|
||||
'brand' => $device->brand,
|
||||
'serie' => $device->serie,
|
||||
'mac_address' => $device->mac_address,
|
||||
'status' => $device->status ? 'activo' : 'inactivo',
|
||||
'module' => $module ? [
|
||||
'id' => $module->id,
|
||||
'name' => $module->name,
|
||||
] : null,
|
||||
'authorized_users' => $authorizedUsers,
|
||||
];
|
||||
}),
|
||||
'pagination' => [
|
||||
'total' => $devices->total(),
|
||||
'per_page' => $devices->perPage(),
|
||||
'current_page' => $devices->currentPage(),
|
||||
'last_page' => $devices->lastPage(),
|
||||
'from' => $devices->firstItem(),
|
||||
'to' => $devices->lastItem(),
|
||||
],
|
||||
'devices' => $devices->paginate(config('app.pagination')),
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
return ApiResponse::INTERNAL_ERROR->response([
|
||||
|
||||
@ -28,7 +28,7 @@ public function vehicleInscription(VehicleStoreRequest $request)
|
||||
try {
|
||||
$folio = $request->input('folio');
|
||||
$tagNumber = $request->input('tag_number');
|
||||
$vin = $request->input('vin');
|
||||
$niv = $request->input('niv');
|
||||
|
||||
// Buscar Tag y validar que NO tenga vehículo asignado
|
||||
$tag = Tag::where('folio', $folio)->where('tag_number', $tagNumber)->first();
|
||||
@ -128,19 +128,41 @@ public function vehicleInscription(VehicleStoreRequest $request)
|
||||
$uploadedFiles = [];
|
||||
if ($request->hasFile('files')) {
|
||||
$files = $request->file('files');
|
||||
$fileNames = $request->input('names', []);
|
||||
$nameIds = $request->input('name_id', []);
|
||||
|
||||
if (!empty($nameIds)) {
|
||||
$validIds = CatalogNameImg::whereIn('id', $nameIds)->pluck('id')->toArray();
|
||||
if (count($validIds) !== count($nameIds)) {
|
||||
DB::rollBack();
|
||||
return ApiResponse::INTERNAL_ERROR->response([
|
||||
'message' => 'Algunos IDs del catálogo de nombres no son válidos',
|
||||
'provided_id' => $nameIds,
|
||||
'valid_id' => $validIds,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($files as $index => $file) {
|
||||
$customName = $fileNames[$index] ?? "archivo_" . ($index + 1);
|
||||
$customName = str_replace(' ', '_', $customName);
|
||||
$catalogName = CatalogNameImg::firstOrCreate(['name' => $customName]);
|
||||
// Obtener el name_id del request o usar null como fallback
|
||||
$nameId = $nameIds[$index] ?? null;
|
||||
|
||||
if ($nameId === null) {
|
||||
DB::rollBack();
|
||||
return ApiResponse::INTERNAL_ERROR->response([
|
||||
'message' => "Falta el name_id para el archivo en el índice {$index}",
|
||||
'file_index' => $index,
|
||||
]);
|
||||
}
|
||||
|
||||
// Obtener el nombre del catálogo para el nombre del archivo
|
||||
$catalogName = CatalogNameImg::find($nameId);
|
||||
$extension = $file->getClientOriginalExtension();
|
||||
$fileName = $customName . '_' . date('dmY_His') . '.' . $extension;
|
||||
$fileName = $catalogName->name . '_' . date('dmY_His') . '.' . $extension;
|
||||
$path = $file->storeAs("records/{$record->folio}", $fileName, 'public');
|
||||
$md5 = md5_file($file->getRealPath());
|
||||
|
||||
$fileRecord = File::create([
|
||||
'name_id' => $catalogName->id,
|
||||
'name_id' => $nameId,
|
||||
'path' => $path,
|
||||
'md5' => $md5,
|
||||
'record_id' => $record->id,
|
||||
@ -156,7 +178,7 @@ public function vehicleInscription(VehicleStoreRequest $request)
|
||||
}
|
||||
|
||||
// Enviar a API Repuve Nacional
|
||||
$apiResponse = $this->sendToRepuveNacional($vin);
|
||||
$apiResponse = $this->sendToRepuveNacional($niv);
|
||||
|
||||
$apiResponse["repuve_response"]["folio_ci"] = $folio;
|
||||
$apiResponse["repuve_response"]["identificador_ci"] = $tagNumber;
|
||||
@ -215,6 +237,8 @@ public function vehicleInscription(VehicleStoreRequest $request)
|
||||
|
||||
DB::commit();
|
||||
|
||||
$record->load(['vehicle.owner', 'vehicle.tag', 'files', 'user']);
|
||||
|
||||
// Responder con éxito
|
||||
return ApiResponse::OK->response([
|
||||
'message' => 'Vehículo inscrito exitosamente',
|
||||
@ -228,22 +252,23 @@ public function vehicleInscription(VehicleStoreRequest $request)
|
||||
'created_at' => $record->created_at->toDateTimeString(),
|
||||
],
|
||||
'vehicle' => [
|
||||
'id' => $vehicle->id,
|
||||
'placa' => $vehicle->placa,
|
||||
'niv' => $vehicle->niv,
|
||||
'marca' => $vehicle->marca,
|
||||
'modelo' => $vehicle->modelo,
|
||||
'color' => $vehicle->color,
|
||||
'id' => $record->vehicle->id,
|
||||
'placa' => $record->vehicle->placa,
|
||||
'niv' => $record->vehicle->niv,
|
||||
'marca' => $record->vehicle->marca,
|
||||
'linea' => $record->vehicle->linea,
|
||||
'modelo' => $record->vehicle->modelo,
|
||||
'color' => $record->vehicle->color,
|
||||
],
|
||||
'owner' => [
|
||||
'id' => $owner->id,
|
||||
'full_name' => $owner->full_name,
|
||||
'rfc' => $owner->rfc,
|
||||
'id' => $record->vehicle->owner->id,
|
||||
'full_name' => $record->vehicle->owner->full_name,
|
||||
'rfc' => $record->vehicle->owner->rfc,
|
||||
],
|
||||
'tag' => [
|
||||
'id' => $tag->id,
|
||||
'folio' => $tag->folio,
|
||||
'status' => $tag->status,
|
||||
'id' => $record->vehicle->tag->id,
|
||||
'folio' => $record->vehicle->tag->folio,
|
||||
'status' => $record->vehicle->tag->status,
|
||||
],
|
||||
'files' => $uploadedFiles,
|
||||
'total_files' => count($uploadedFiles),
|
||||
@ -415,81 +440,38 @@ public function searchRecord(Request $request)
|
||||
'required_without_all' => 'Debe proporcionar al menos uno de los siguientes: folio, placa o vin.'
|
||||
]);
|
||||
|
||||
$query = Record::with(['vehicle.owner', 'vehicle.tag', 'files', 'user', 'error'])->orderBy('id', 'ASC');
|
||||
$records = Record::with([
|
||||
'vehicle:id,owner_id,placa,niv,marca,linea,modelo,color',
|
||||
'vehicle.owner:id,name,paternal,maternal,rfc',
|
||||
'vehicle.tag:id,vehicle_id,folio,tag_number,status',
|
||||
'files:id,record_id,name_id,path,md5',
|
||||
'files.catalogName:id,name',
|
||||
'user:id,name,email',
|
||||
'error:id,code,description'
|
||||
])->orderBy('id', 'ASC');
|
||||
|
||||
if ($request->filled('folio')) {
|
||||
$query->whereHas('vehicle.tag', function ($q) use ($request) {
|
||||
$records->whereHas('vehicle.tag', function ($q) use ($request) {
|
||||
$q->where('folio', 'LIKE', '%' . $request->input('folio') . '%');
|
||||
});
|
||||
} elseif ($request->filled('placa')) {
|
||||
$query->whereHas('vehicle', function ($q) use ($request) {
|
||||
$records->whereHas('vehicle', function ($q) use ($request) {
|
||||
$q->where('placa', 'LIKE', '%' . $request->input('placa') . '%');
|
||||
});
|
||||
} elseif ($request->filled('vin')) {
|
||||
$query->whereHas('vehicle', function ($q) use ($request) {
|
||||
$records->whereHas('vehicle', function ($q) use ($request) {
|
||||
$q->where('niv', 'LIKE', '%' . $request->input('vin') . '%');
|
||||
});
|
||||
}
|
||||
|
||||
$perPage = $request->input('per_page', 20);
|
||||
$records = $query->paginate($perPage);
|
||||
|
||||
if ($records->isEmpty()) {
|
||||
return ApiResponse::NOT_FOUND->response([
|
||||
'message' => 'No se encontraron expedientes con los criterios proporcionados.',
|
||||
'records' => [],
|
||||
'pagination' => [
|
||||
'current_page' => 1,
|
||||
'total_pages' => 0,
|
||||
'total_records' => 0,
|
||||
'per_page' => $perPage,
|
||||
],
|
||||
]);
|
||||
}
|
||||
return ApiResponse::OK->response([
|
||||
'message' => 'Expedientes encontrados exitosamente',
|
||||
'records' => $records->map(function ($record) {
|
||||
return [
|
||||
'id' => $record->id,
|
||||
'folio' => $record->folio,
|
||||
'created_at' => $record->created_at->toDateTimeString(),
|
||||
'vehicle' => [
|
||||
'id' => $record->vehicle->id,
|
||||
'placa' => $record->vehicle->placa,
|
||||
'niv' => $record->vehicle->niv,
|
||||
'marca' => $record->vehicle->marca,
|
||||
'modelo' => $record->vehicle->modelo,
|
||||
'color' => $record->vehicle->color,
|
||||
'clase_veh' => $record->vehicle->clase_veh,
|
||||
],
|
||||
'owner' => [
|
||||
'id' => $record->vehicle->owner->id,
|
||||
'full_name' => $record->vehicle->owner->full_name,
|
||||
'rfc' => $record->vehicle->owner->rfc,
|
||||
],
|
||||
'tag' => [
|
||||
'id' => $record->vehicle->tag ? $record->vehicle->tag->id : null,
|
||||
'folio' => $record->vehicle->tag ? $record->vehicle->tag->folio : null,
|
||||
'status' => $record->vehicle->tag ? $record->vehicle->tag->status : null,
|
||||
],
|
||||
'files' => $record->files->map(function ($file) {
|
||||
return [
|
||||
'id' => $file->id,
|
||||
'name' => $file->name,
|
||||
'path' => $file->path,
|
||||
'url' => $file->url,
|
||||
];
|
||||
}),
|
||||
];
|
||||
}),
|
||||
'pagination' => [
|
||||
'current_page' => $records->currentPage(),
|
||||
'total_pages' => $records->lastPage(),
|
||||
'total_records' => $records->total(),
|
||||
'per_page' => $records->perPage(),
|
||||
'from' => $records->firstItem(),
|
||||
'to' => $records->lastItem(),
|
||||
],
|
||||
'records' => $records->select([
|
||||
'id',
|
||||
'folio',
|
||||
'vehicle_id',
|
||||
'user_id',
|
||||
'created_at'
|
||||
])->paginate(config('app.pagination'))
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@ -21,65 +21,21 @@ class ModuleController extends Controller
|
||||
public function index(Request $request)
|
||||
{
|
||||
try {
|
||||
$query = Module::with(['responsible', 'municipality'])->withCount(['packages']);
|
||||
$modules = Module::with(['responsible:id,name,email', 'municipality:id,code,name'])->withCount(['packages']);
|
||||
|
||||
// Filtro por nombre
|
||||
if ($request->filled('name')) {
|
||||
$query->where('name', 'like', '%' . $request->input('name') . '%');
|
||||
$modules->where('name', 'like', '%' . $request->input('name') . '%');
|
||||
}
|
||||
|
||||
if ($request->filled('municipality')) {
|
||||
$query->whereHas('municipality', function ($q) use ($request) {
|
||||
$modules->whereHas('municipality', function ($q) use ($request) {
|
||||
$q->where('name', 'like', '%' . $request->input('municipality') . '%');
|
||||
});
|
||||
}
|
||||
|
||||
// Cargar relaciones para contar
|
||||
$query->withCount(['packages']);
|
||||
|
||||
// Ordenar
|
||||
$sortOrder = $request->input('sort_order', 'ASC');
|
||||
$query->orderBy('id', $sortOrder);
|
||||
|
||||
// Paginación
|
||||
$perPage = $request->input('per_page', 20);
|
||||
$modules = $query->paginate($perPage);
|
||||
|
||||
return ApiResponse::OK->response([
|
||||
'modules' => $modules->map(function ($module) {
|
||||
return [
|
||||
'id' => $module->id,
|
||||
'name' => $module->name,
|
||||
'responsible' => $module->responsible ? [
|
||||
'id' => $module->responsible->id,
|
||||
'name' => $module->responsible->full_name,
|
||||
'email' => $module->responsible->email,
|
||||
] : null,
|
||||
'municipality' => $module->municipality ? [
|
||||
'id' => $module->municipality->id,
|
||||
'code' => $module->municipality->code,
|
||||
'name' => $module->municipality->name,
|
||||
] : null,
|
||||
'address' => $module->address,
|
||||
'colony' => $module->colony,
|
||||
'cp' => $module->cp,
|
||||
'longitude' => $module->longitude,
|
||||
'latitude' => $module->latitude,
|
||||
'status' => $module->status,
|
||||
'status_text' => $module->status ? 'Activo' : 'Inactivo',
|
||||
'packages_count' => $module->packages_count ?? 0,
|
||||
'created_at' => $module->created_at->format('Y-m-d H:i:s'),
|
||||
'updated_at' => $module->updated_at->format('Y-m-d H:i:s'),
|
||||
];
|
||||
}),
|
||||
'pagination' => [
|
||||
'current_page' => $modules->currentPage(),
|
||||
'total_pages' => $modules->lastPage(),
|
||||
'per_page' => $modules->perPage(),
|
||||
'total' => $modules->total(),
|
||||
'from' => $modules->firstItem(),
|
||||
'to' => $modules->lastItem(),
|
||||
],
|
||||
'modules' => $modules->paginate(config('app.pagination')),
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
return ApiResponse::INTERNAL_ERROR->response([
|
||||
|
||||
@ -19,7 +19,7 @@ class MunicipalityController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$municipalities = Municipality::all();
|
||||
$municipalities = Municipality::orderBy('id', 'ASC')->get();
|
||||
|
||||
return ApiResponse::OK->response([
|
||||
'data' => $municipalities,
|
||||
|
||||
@ -9,8 +9,6 @@
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\Package;
|
||||
use App\Models\Tag;
|
||||
use Dompdf\FrameDecorator\Page;
|
||||
|
||||
class PackageController extends Controller
|
||||
{
|
||||
@ -18,49 +16,20 @@ class PackageController extends Controller
|
||||
public function index(Request $request)
|
||||
{
|
||||
try {
|
||||
$query = Package::query();
|
||||
$packages = Package::with([
|
||||
'module:id,name,responsible_id',
|
||||
'module.responsible:id,name,email'
|
||||
])->orderBy('id', 'ASC');
|
||||
|
||||
if ($request->filled('lote')) {
|
||||
$query->where('lot', 'LIKE', '%' . $request->lote . '%');
|
||||
$packages->where('lot', 'LIKE', '%' . $request->lote . '%');
|
||||
}
|
||||
|
||||
if ($request->filled('caja')) {
|
||||
$query->where('box_number', 'LIKE', '%' . $request->caja . '%');
|
||||
$packages->where('box_number', 'LIKE', '%' . $request->caja . '%');
|
||||
}
|
||||
|
||||
|
||||
$query->with('tags')->orderBy('id', 'ASC');
|
||||
$perPage = $request->input('per_page', 20);
|
||||
$packages = $query->paginate($perPage);
|
||||
|
||||
return ApiResponse::OK->response([
|
||||
'packages' => $packages->map(fn($item) => [
|
||||
'id' => $item->id,
|
||||
'lot' => $item->lot,
|
||||
'box_number' => $item->box_number,
|
||||
'starting_page' => $item->starting_page,
|
||||
'ending_page' => $item->ending_page,
|
||||
'module' => $item->module ? [
|
||||
'id' => $item->module->id,
|
||||
'name' => $item->module->name,
|
||||
] : null,
|
||||
'tags' => $item->tags->map(fn($tag) => [
|
||||
'id' => $tag->id,
|
||||
'folio' => $tag->folio,
|
||||
'vehicle_id' => $tag->vehicle_id,
|
||||
'status' => $tag->status ?? null,
|
||||
]),
|
||||
'tags_count' => $item->tags->count(),
|
||||
'created_at' => $item->created_at->format('Y-m-d H:i:s'),
|
||||
]),
|
||||
'pagination' => [
|
||||
'total' => $packages->total(),
|
||||
'per_page' => $packages->perPage(),
|
||||
'current_page' => $packages->currentPage(),
|
||||
'last_page' => $packages->lastPage(),
|
||||
'from' => $packages->firstItem(),
|
||||
'to' => $packages->lastItem(),
|
||||
],
|
||||
'packages' => $packages->paginate(config('app.pagination'))
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
return ApiResponse::INTERNAL_ERROR->response([
|
||||
|
||||
@ -187,82 +187,30 @@ public function errors(Request $request)
|
||||
'vin' => 'nullable|string',
|
||||
]);
|
||||
|
||||
$query = Record::with(['vehicle.owner', 'vehicle.tag', 'files', 'user', 'error'])
|
||||
$records = Record::with(['vehicle.owner', 'vehicle.tag', 'files', 'user', 'error'])
|
||||
->whereNotNull('api_response')
|
||||
->whereRaw("JSON_EXTRACT(api_response, '$.has_error') = true")
|
||||
->orderBy('error_occurred_at', 'DESC');
|
||||
->orderBy('id', 'ASC');
|
||||
|
||||
if ($request->filled('folio')) {
|
||||
$query->where('folio', 'LIKE', '%' . $request->input('folio') . '%');
|
||||
$records->where('folio', 'LIKE', '%' . $request->input('folio') . '%');
|
||||
}
|
||||
|
||||
if ($request->filled('placa')) {
|
||||
$query->whereHas('vehicle', function ($q) use ($request) {
|
||||
$records->whereHas('vehicle', function ($q) use ($request) {
|
||||
$q->where('placa', 'LIKE', '%' . $request->input('placa') . '%');
|
||||
});
|
||||
}
|
||||
|
||||
if ($request->filled('vin')) {
|
||||
$query->whereHas('vehicle', function ($q) use ($request) {
|
||||
$records->whereHas('vehicle', function ($q) use ($request) {
|
||||
$q->where('niv', 'LIKE', '%' . $request->input('vin') . '%');
|
||||
});
|
||||
}
|
||||
|
||||
$perPage = $request->input('per_page', 20);
|
||||
$records = $query->paginate($perPage);
|
||||
|
||||
if ($records->isEmpty()) {
|
||||
return ApiResponse::NOT_FOUND->response([
|
||||
'message' => 'No se encontraron expedientes con errores.',
|
||||
'records' => [],
|
||||
'pagination' => [
|
||||
'current_page' => 1,
|
||||
'total_pages' => 0,
|
||||
'total_records' => 0,
|
||||
'per_page' => $perPage,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
return ApiResponse::OK->response([
|
||||
'message' => 'Expedientes con errores encontrados exitosamente',
|
||||
'records' => $records->map(function ($record) {
|
||||
return [
|
||||
'id' => $record->id,
|
||||
'folio' => $record->folio,
|
||||
'created_at' => $record->created_at->toDateTimeString(),
|
||||
'error_occurred_at' => $record->error_occurred_at?->toDateTimeString(),
|
||||
|
||||
// Información del vehículo
|
||||
'vehicle' => [
|
||||
'id' => $record->vehicle->id,
|
||||
'placa' => $record->vehicle->placa,
|
||||
'niv' => $record->vehicle->niv,
|
||||
'marca' => $record->vehicle->marca,
|
||||
'modelo' => $record->vehicle->modelo,
|
||||
'color' => $record->vehicle->color,
|
||||
'clase_veh' => $record->vehicle->clase_veh,
|
||||
],
|
||||
|
||||
// Error del catálogo
|
||||
'error' => $record->error ? [
|
||||
'id' => $record->error->id,
|
||||
'code' => $record->error->code,
|
||||
'description' => $record->error->description,
|
||||
] : null,
|
||||
|
||||
// Respuesta completa de la API con el error
|
||||
'api_response' => $record->api_response,
|
||||
];
|
||||
}),
|
||||
'pagination' => [
|
||||
'current_page' => $records->currentPage(),
|
||||
'total_pages' => $records->lastPage(),
|
||||
'total_records' => $records->total(),
|
||||
'per_page' => $records->perPage(),
|
||||
'from' => $records->firstItem(),
|
||||
'to' => $records->lastItem(),
|
||||
],
|
||||
'records' => $records->paginate(config('app.pagination')),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,21 +11,11 @@ class TagsController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
try
|
||||
{
|
||||
$perPage = request()->input('per_page', 15);
|
||||
$tags = Tag::orderBy('id', 'ASC')->paginate($perPage);
|
||||
try {
|
||||
$tags = Tag::with('vehicle:id,placa,niv', 'package:id,lot,box_number')->orderBy('id', 'ASC');
|
||||
|
||||
return ApiResponse::OK->response([
|
||||
'data' => $tags->items(),
|
||||
'pagination' => [
|
||||
'total' => $tags->total(),
|
||||
'per_page' => $tags->perPage(),
|
||||
'current_page' => $tags->currentPage(),
|
||||
'last_page' => $tags->lastPage(),
|
||||
'from' => $tags->firstItem(),
|
||||
'to' => $tags->lastItem(),
|
||||
],
|
||||
'tag' => $tags->paginate(config('app.pagination')),
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
return ApiResponse::INTERNAL_ERROR->response([
|
||||
@ -64,13 +54,11 @@ public function destroy(Tag $tag)
|
||||
return ApiResponse::OK->response([
|
||||
'message' => 'Tag eliminado correctamente.',
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return ApiResponse::INTERNAL_ERROR->response([
|
||||
'message' => 'Error al eliminar el tag.',
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,11 +7,12 @@
|
||||
use App\Http\Requests\Repuve\VehicleUpdateRequest;
|
||||
use Notsoweb\ApiResponse\Enums\ApiResponse;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use App\Models\Record;
|
||||
use App\Models\File;
|
||||
use App\Models\Owner;
|
||||
use App\Models\Tag;
|
||||
use App\Models\Error;
|
||||
use App\Models\CatalogNameImg;
|
||||
use Exception;
|
||||
|
||||
class UpdateController extends Controller
|
||||
@ -21,33 +22,46 @@ public function vehicleData(Request $request)
|
||||
{
|
||||
try {
|
||||
$request->validate([
|
||||
'folio' => 'required','string','exists:records,folio',
|
||||
'tag_number' => 'required','string','exists:tags,tag_number',
|
||||
'vin' => 'required','string','exists:vehicles,vin'
|
||||
'folio' => 'required|string|exists:records,folio',
|
||||
'tag_number' => 'required|string|exists:tags,tag_number',
|
||||
'niv' => 'required|string|exists:vehicle,niv'
|
||||
]);
|
||||
|
||||
$folio = $request->input('folio');
|
||||
$tagNumber = $request->input('tag_number');
|
||||
$vin = $request->input('vin');
|
||||
$niv = $request->input('niv');
|
||||
|
||||
$isStolen = $this->checkIfStolen($vin);
|
||||
$isStolen = $this->checkIfStolen($folio);
|
||||
|
||||
if ($isStolen) {
|
||||
return ApiResponse::FORBIDDEN->response([
|
||||
'vin' => $vin,
|
||||
'stolen' => true,
|
||||
'message' => 'El vehículo reporta robo. No se puede continuar con la actualización.',
|
||||
]);
|
||||
}
|
||||
|
||||
$record = Record::with(['vehicle.owner', 'vehicle.tag', 'files', 'error'])
|
||||
->where('folio', $folio)
|
||||
$record = Record::with([
|
||||
'vehicle:id,owner_id,placa,niv,marca,linea,modelo,color',
|
||||
'vehicle.owner:id,name,paternal,maternal,rfc',
|
||||
'vehicle.tag:id,vehicle_id,folio,tag_number,status',
|
||||
'files:id,record_id,name_id,path,md5',
|
||||
'files.catalogName:id,name',
|
||||
'user:id,name,email',
|
||||
'error:id,code,description'
|
||||
])
|
||||
->select([
|
||||
'id',
|
||||
'folio',
|
||||
'vehicle_id',
|
||||
'user_id',
|
||||
'error_id',
|
||||
'created_at',
|
||||
'updated_at'
|
||||
])->where('folio', $folio)
|
||||
->first();
|
||||
|
||||
if (!$record) {
|
||||
return ApiResponse::BAD_REQUEST->response([
|
||||
return ApiResponse::NOT_FOUND->response([
|
||||
'message' => 'No se encontró el expediente',
|
||||
'folio' => $folio,
|
||||
]);
|
||||
}
|
||||
|
||||
@ -60,78 +74,15 @@ public function vehicleData(Request $request)
|
||||
]);
|
||||
}
|
||||
|
||||
if ($vehicle->numero_serie !== $vin) {
|
||||
if ($vehicle->niv !== $niv) {
|
||||
return ApiResponse::BAD_REQUEST->response([
|
||||
'message' => 'El VIN no coincide con el registrado en el expediente',
|
||||
'message' => 'El NIV no coincide con el registrado en el expediente',
|
||||
]);
|
||||
}
|
||||
|
||||
$owner = $vehicle->owner;
|
||||
|
||||
|
||||
return ApiResponse::OK->response([
|
||||
'message' => 'Datos del vehículo obtenidos exitosamente',
|
||||
'record' => [
|
||||
'id' => $record->id,
|
||||
'folio' => $record->folio,
|
||||
'created_at' => $record->created_at->toDateTimeString(),
|
||||
'updated_at' => $record->updated_at->toDateTimeString(),
|
||||
],
|
||||
'vehicle' => [
|
||||
'id' => $vehicle->id,
|
||||
'placa' => $vehicle->placa,
|
||||
'anio_placa' => $vehicle->anio_placa,
|
||||
'numero_serie' => $vehicle->numero_serie,
|
||||
'vigencia' => $vehicle->vigencia,
|
||||
'fecha_impresion' => $vehicle->fecha_impresion,
|
||||
'qr_hash' => $vehicle->qr_hash,
|
||||
'valido' => $vehicle->valido,
|
||||
'nombre' => $vehicle->nombre,
|
||||
'nombre2' => $vehicle->nombre2,
|
||||
'marca' => $vehicle->marca,
|
||||
'linea' => $vehicle->linea,
|
||||
'sublinea' => $vehicle->sublinea,
|
||||
'modelo' => $vehicle->modelo,
|
||||
'color' => $vehicle->color,
|
||||
'tipo' => $vehicle->tipo,
|
||||
'tipo_servicio' => $vehicle->tipo_servicio,
|
||||
'numero_motor' => $vehicle->numero_motor,
|
||||
'descripcion_origen' => $vehicle->descripcion_origen,
|
||||
'municipio' => $vehicle->municipio,
|
||||
'localidad' => $vehicle->localidad,
|
||||
'calle' => $vehicle->calle,
|
||||
'calle2' => $vehicle->calle2,
|
||||
'codigo_postal' => $vehicle->codigo_postal,
|
||||
'serie_folio' => $vehicle->serie_folio,
|
||||
'nrpv' => $vehicle->nrpv,
|
||||
],
|
||||
'owner' => [
|
||||
'id' => $owner->id,
|
||||
'name' => $owner->name,
|
||||
'paternal' => $owner->paternal,
|
||||
'maternal' => $owner->maternal,
|
||||
'full_name' => $owner->full_name,
|
||||
'rfc' => $owner->rfc,
|
||||
'curp' => $owner->curp,
|
||||
'address' => $owner->address,
|
||||
],
|
||||
'tag' => [
|
||||
'id' => $tag->id,
|
||||
'folio' => $tag->folio,
|
||||
'tag_number' => $tag->tag_number,
|
||||
'status' => $tag->status,
|
||||
'package_id' => $tag->package_id,
|
||||
],
|
||||
'existing_files' => $record->files->map(function ($file) {
|
||||
return [
|
||||
'id' => $file->id,
|
||||
'name' => $file->name,
|
||||
'path' => $file->path,
|
||||
'url' => $file->url,
|
||||
'created_at' => $file->created_at->toDateTimeString(),
|
||||
];
|
||||
}),
|
||||
'total_files' => $record->files->count(),
|
||||
'records' => $record,
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
return ApiResponse::BAD_REQUEST->response([
|
||||
@ -146,13 +97,13 @@ public function vehicleUpdate(VehicleUpdateRequest $request)
|
||||
try {
|
||||
$folio = $request->input('folio');
|
||||
$tagNumber = $request->input('tag_number');
|
||||
$vin = $request->input('vin');
|
||||
$niv = $request->input('niv');
|
||||
|
||||
$isStolen = $this->checkIfStolen($vin);
|
||||
$isStolen = $this->checkIfStolen($folio);
|
||||
|
||||
if ($isStolen) {
|
||||
return ApiResponse::FORBIDDEN->response([
|
||||
'vin' => $vin,
|
||||
'niv' => $niv,
|
||||
'stolen' => true,
|
||||
'message' => 'El vehículo reporta robo. No se puede continuar con la actualización.',
|
||||
]);
|
||||
@ -178,9 +129,9 @@ public function vehicleUpdate(VehicleUpdateRequest $request)
|
||||
]);
|
||||
}
|
||||
|
||||
if ($vehicle->numero_serie !== $vin) {
|
||||
if ($vehicle->niv !== $niv) {
|
||||
return ApiResponse::BAD_REQUEST->response([
|
||||
'message' => 'El VIN no coincide con el registrado en el expediente',
|
||||
'message' => 'El NIV no coincide con el registrado en el expediente',
|
||||
]);
|
||||
}
|
||||
|
||||
@ -200,36 +151,78 @@ public function vehicleUpdate(VehicleUpdateRequest $request)
|
||||
);
|
||||
|
||||
$uploadedFiles = [];
|
||||
|
||||
if ($request->hasFile('files')) {
|
||||
$files = $request->file('files');
|
||||
$fileNames = $request->input('names', []);
|
||||
$nameIds = $request->input('name_id', []);
|
||||
|
||||
if (!empty($nameIds)) {
|
||||
$validIds = CatalogNameImg::whereIn('id', $nameIds)->pluck('id')->toArray();
|
||||
if (count($validIds) !== count($nameIds)) {
|
||||
DB::rollBack();
|
||||
return ApiResponse::BAD_REQUEST->response([
|
||||
'message' => 'Algunos ids del catálogo de nombres no son válidos',
|
||||
'provided_id' => $nameIds,
|
||||
'valid_id' => $validIds,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($files as $indx => $file) {
|
||||
$customName = $fileNames[$indx] ?? "archivo_" . ($indx + 1);
|
||||
$customName = str_replace(' ', '_', $customName);
|
||||
$nameId = $nameIds[$indx] ?? null;
|
||||
|
||||
if ($nameId === null) {
|
||||
DB::rollBack();
|
||||
return ApiResponse::BAD_REQUEST->response([
|
||||
'message' => "Falta el name_id para el archivo",
|
||||
]);
|
||||
}
|
||||
|
||||
// Buscar si ya existe un archivo con este name_id para este record
|
||||
$existingFile = File::where('record_id', $record->id)
|
||||
->where('name_id', $nameId)
|
||||
->first();
|
||||
|
||||
if ($existingFile) {
|
||||
// Eliminar el archivo físico anterior
|
||||
Storage::disk('public')->delete($existingFile->path);
|
||||
|
||||
$replacedFiles[] = [
|
||||
'id' => $existingFile->id,
|
||||
'name_id' => $nameId,
|
||||
'old_path' => $existingFile->path,
|
||||
];
|
||||
|
||||
// Eliminar el registro de la BD
|
||||
$existingFile->delete();
|
||||
}
|
||||
|
||||
// Obtener el nombre del catálogo para el nombre del archivo
|
||||
$catalogName = CatalogNameImg::find($nameId);
|
||||
$extension = $file->getClientOriginalExtension();
|
||||
$fileName = $customName . '_' . time() . '.' . $extension;
|
||||
$path = $file->storeAs('records', $fileName, 'public');
|
||||
$fileName = $catalogName->name . '_' . date('dmY_His') . '.' . $extension;
|
||||
$path = $file->storeAs("records/{$record->folio}", $fileName, 'public');
|
||||
$md5 = md5_file($file->getRealPath());
|
||||
|
||||
$fileRecord = File::create([
|
||||
'record_id' => $record->id,
|
||||
'name' => $fileName,
|
||||
'name_id' => $nameId,
|
||||
'path' => $path,
|
||||
'md5' => $md5,
|
||||
'record_id' => $record->id,
|
||||
]);
|
||||
|
||||
$uploadedFiles[] = [
|
||||
'id' => $fileRecord->id,
|
||||
'name' => $fileRecord->name,
|
||||
'name' => $catalogName->name,
|
||||
'path' => $fileRecord->path,
|
||||
'url' => $fileRecord->url,
|
||||
'replaced' => $existingFile !== null,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
//Envio de datos
|
||||
$apiResponse = $this->sendToRepuveNacional($vin);
|
||||
$apiResponse = $this->sendToRepuveNacional($niv);
|
||||
$apiResponse["repuve_response"]["folio_ci"] = $record->folio;
|
||||
$apiResponse["repuve_response"]["identificador_ci"] = $tag->tag_number;
|
||||
|
||||
@ -288,7 +281,7 @@ public function vehicleUpdate(VehicleUpdateRequest $request)
|
||||
'vehicle' => [
|
||||
'id' => $vehicle->id,
|
||||
'placa' => $vehicle->placa,
|
||||
'numero_serie' => $vehicle->numero_serie,
|
||||
'niv' => $vehicle->niv,
|
||||
'marca' => $vehicle->marca,
|
||||
'modelo' => $vehicle->modelo,
|
||||
'color' => $vehicle->color,
|
||||
@ -303,8 +296,9 @@ public function vehicleUpdate(VehicleUpdateRequest $request)
|
||||
'tag_number' => $tag->tag_number,
|
||||
'status' => $tag->status,
|
||||
],
|
||||
'new_files' => $uploadedFiles,
|
||||
'total_files' => $record->files->count() + count($uploadedFiles),
|
||||
'uploaded_files' => $uploadedFiles,
|
||||
'replaced_count' => count($replacedFiles),
|
||||
'total_files' => File::where('record_id', $record->id)->count(),
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
return ApiResponse::INTERNAL_ERROR->response([
|
||||
@ -321,14 +315,14 @@ private function checkIfStolen(string $folio): bool
|
||||
return (bool) rand(0, 1);
|
||||
}
|
||||
|
||||
private function sendToRepuveNacional(string $vin): array
|
||||
private function sendToRepuveNacional(string $niv): array
|
||||
{
|
||||
// Enviar datos a API Repuve Nacional
|
||||
// Aquí se haría la llamada real a la API de Repuve Nacional
|
||||
// Por ahora simulamos con mock igual que InscriptionController
|
||||
|
||||
// Respuesta exitosa mockup REPUVE
|
||||
$mockResponse = "OK:SIN INFORMACION|OTROS|SIN INFORMACION|10/07/2023|CENTRO|$vin|WSA548B|HR16777934V|2023|BLANCO|ADVANCE|TABASCO|NISSAN|MARCH|PARTICULAR|AUTOMOVIL|ACTIVO|null||null|0|null|0|10337954|E2003412012BB0C130FAD04D|Sin observaciones
";
|
||||
$mockResponse = "OK:SIN INFORMACION|OTROS|SIN INFORMACION|10/07/2023|CENTRO|$niv|WSA548B|HR16777934V|2023|BLANCO|ADVANCE|TABASCO|NISSAN|MARCH|PARTICULAR|AUTOMOVIL|ACTIVO|null||null|0|null|0|10337954|E2003412012BB0C130FAD04D|Sin observaciones
";
|
||||
|
||||
// Parsear la cadena a JSON usando los campos oficiales
|
||||
$fields = [
|
||||
@ -370,7 +364,7 @@ private function sendToRepuveNacional(string $vin): array
|
||||
'error_code' => null,
|
||||
'error_message' => null,
|
||||
'timestamp' => now()->toDateTimeString(),
|
||||
'vin' => $vin,
|
||||
'niv' => $niv,
|
||||
'repuve_response' => $jsonResponse,
|
||||
];
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ public function rules(): array
|
||||
return [
|
||||
'folio' => ['required', 'string', 'max:50'],
|
||||
'tag_number' => ['required', 'string', 'exists:tags,tag_number'],
|
||||
'vin' => ['sometimes', 'string', 'max:30'],
|
||||
'niv' => ['sometimes', 'string', 'max:30'],
|
||||
'files' => ['nullable', 'array', 'min:1'],
|
||||
'files.*' => ['file', 'mimes:jpeg,png,jpg', 'max:10240'],
|
||||
'names' => ['nullable', 'array'],
|
||||
@ -30,8 +30,8 @@ public function messages(): array
|
||||
'folio.string' => 'El folio debe ser una cadena de texto',
|
||||
'tag_number.required' => 'El tag_number es requerido',
|
||||
'tag_number.exists' => 'El tag_number no existe en el sistema',
|
||||
'vin.required' => 'El VIN es requerido',
|
||||
'vin.string' => 'El VIN debe ser una cadena de texto',
|
||||
'niv.required' => 'El niv es requerido',
|
||||
'niv.string' => 'El niv debe ser una cadena de texto',
|
||||
'files.array' => 'Los archivos deben ser un array',
|
||||
'files.*.file' => 'Cada elemento debe ser un archivo válido',
|
||||
'files.*.mimes' => 'Los archivos deben ser de tipo: jpeg, png, jpg, pdf',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user