Compare commits

..

2 Commits

7 changed files with 384 additions and 277 deletions

View File

@ -9,6 +9,7 @@
use App\Models\CatalogTagStatus;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
use Illuminate\Http\Request;
use Illuminate\Database\QueryException;
use App\Models\Package;
@ -20,14 +21,28 @@ class PackageController extends Controller
public function index(Request $request)
{
try {
$packages = Package::with([
Log::info('PackageController@index - Iniciando consulta de paquetes', [
'filters' => $request->all()
]);
// Si NO hay filtro de caja, no cargar las relaciones de tags para optimizar
$shouldLoadTags = $request->filled('caja') || $request->filled('box_number');
$packages = Package::query();
if ($shouldLoadTags) {
$packages->with([
'tags:id,folio,tag_number,package_id,status_id,vehicle_id,module_id',
'tags.status:id,code,name',
'tags.vehicle:id,placa,niv',
'tags.module:id,name',
'user:id,name,email'
])
->withCount('tags')
->orderBy('id', 'ASC');
]);
} else {
$packages->with('user:id,name,email');
}
$packages->withCount('tags')->orderBy('id', 'ASC');
if ($request->filled('lote') || $request->filled('lot')) {
$loteValue = $request->input('lote') ?? $request->input('lot');
@ -39,8 +54,14 @@ public function index(Request $request)
$packages->where('box_number', 'LIKE', '%' . trim($cajaValue) . '%');
}
Log::info('PackageController@index - Ejecutando paginación');
$paginatedPackages = $packages->paginate(config('app.pagination'));
Log::info('PackageController@index - Paginación completada', [
'total' => $paginatedPackages->total(),
'count' => $paginatedPackages->count()
]);
// Validación si no hay resultados
if ($paginatedPackages->isEmpty()) {
return ApiResponse::NOT_FOUND->response([
@ -68,20 +89,26 @@ public function index(Request $request)
] : null,
'estadisticas' => [
'total' => $package->tags->count(),
'available' => $package->tags->where('status.code', 'available')->count(),
'assigned' => $package->tags->where('status.code', 'assigned')->count(),
'cancelled' => $package->tags->where('status.code', 'cancelled')->count(),
'available' => $package->tags->filter(function($tag) {
return $tag->status && $tag->status->code === 'available';
})->count(),
'assigned' => $package->tags->filter(function($tag) {
return $tag->status && $tag->status->code === 'assigned';
})->count(),
'cancelled' => $package->tags->filter(function($tag) {
return $tag->status && $tag->status->code === 'cancelled';
})->count(),
],
'tags' => $package->tags->map(function ($tag) {
return [
'id' => $tag->id,
'folio' => $tag->folio,
'tag_number' => $tag->tag_number,
'status' => [
'status' => $tag->status ? [
'id' => $tag->status->id,
'code' => $tag->status->code,
'name' => $tag->status->name,
],
] : null,
'vehicle' => $tag->vehicle ? [
'id' => $tag->vehicle->id,
'placa' => $tag->vehicle->placa,
@ -97,10 +124,19 @@ public function index(Request $request)
});
}
Log::info('PackageController@index - Retornando respuesta exitosa');
return ApiResponse::OK->response([
'Paquetes' => $paginatedPackages,
]);
} catch (\Exception $e) {
Log::error('PackageController@index - Error capturado', [
'message' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'trace' => $e->getTraceAsString()
]);
return ApiResponse::INTERNAL_ERROR->response([
'message' => 'Error al obtener los paquetes',
'error' => $e->getMessage(),

View File

@ -845,7 +845,36 @@ public function updateData(VehicleUpdateRequest $request, $id)
// Procesar archivos
$uploadedFiles = [];
$replacedFiles = [];
$deletedFiles = [];
// Manejar eliminación de archivos
if ($request->has('delete_files')) {
$filesToDelete = $request->input('delete_files', []);
foreach ($filesToDelete as $fileId) {
$fileToDelete = File::where('id', $fileId)
->where('record_id', $record->id)
->first();
if ($fileToDelete) {
// Eliminar archivo físico
if (Storage::disk('public')->exists($fileToDelete->path)) {
Storage::disk('public')->delete($fileToDelete->path);
}
$deletedFiles[] = [
'id' => $fileToDelete->id,
'name_id' => $fileToDelete->name_id,
'name' => $fileToDelete->catalogName->name ?? 'Desconocido',
'path' => $fileToDelete->path,
];
$fileToDelete->delete();
}
}
}
// Manejar carga/reemplazo de archivos
if ($request->hasFile('files')) {
$files = $request->file('files');
$nameIds = $request->input('name_id', []);
@ -913,7 +942,7 @@ public function updateData(VehicleUpdateRequest $request, $id)
}
// Registrar el log de cambios si hubo actualizaciones
if ($hasVehicleChanges || $hasOwnerChanges || count($uploadedFiles) > 0) {
if ($hasVehicleChanges || $hasOwnerChanges || count($uploadedFiles) > 0 || count($deletedFiles) > 0) {
VehicleTagLog::create([
'vehicle_id' => $vehicle->id,
'tag_id' => $tag->id,
@ -923,7 +952,7 @@ public function updateData(VehicleUpdateRequest $request, $id)
}
// datos para REPUVE Nacional usando datos actuales de la BD
if ($hasVehicleChanges || $hasOwnerChanges || count($uploadedFiles) > 0) {
if ($hasVehicleChanges || $hasOwnerChanges || count($uploadedFiles) > 0 || count($deletedFiles) > 0) {
// Recargar el vehículo y propietario con los datos actualizados
$vehicle->refresh();
$owner->refresh();
@ -976,14 +1005,14 @@ public function updateData(VehicleUpdateRequest $request, $id)
$record->load(['vehicle.owner', 'vehicle.tag', 'files', 'error']);
$message = 'Expediente actualizado exitosamente';
if (!$hasVehicleChanges && !$hasOwnerChanges && empty($uploadedFiles)) {
if (!$hasVehicleChanges && !$hasOwnerChanges && empty($uploadedFiles) && empty($deletedFiles)) {
$message = 'No se detectaron cambios. Los datos ya estaban actualizados.';
} elseif (($hasVehicleChanges || $hasOwnerChanges) && !empty($uploadedFiles)) {
} elseif (($hasVehicleChanges || $hasOwnerChanges) && (!empty($uploadedFiles) || !empty($deletedFiles))) {
$message = 'Datos del vehículo/propietario y archivos actualizados exitosamente.';
} elseif (($hasVehicleChanges || $hasOwnerChanges) && empty($uploadedFiles)) {
$message = 'Datos del vehículo/propietario actualizados exitosamente. No se subieron archivos.';
} elseif (!$hasVehicleChanges && !$hasOwnerChanges && !empty($uploadedFiles)) {
$message = 'Archivos subidos exitosamente. No hubo cambios en los datos del vehículo/propietario.';
} elseif (($hasVehicleChanges || $hasOwnerChanges) && empty($uploadedFiles) && empty($deletedFiles)) {
$message = 'Datos del vehículo/propietario actualizados exitosamente. No se modificaron archivos.';
} elseif (!$hasVehicleChanges && !$hasOwnerChanges && (!empty($uploadedFiles) || !empty($deletedFiles))) {
$message = 'Archivos modificados exitosamente. No hubo cambios en los datos del vehículo/propietario.';
}
return ApiResponse::OK->response([
@ -993,9 +1022,11 @@ public function updateData(VehicleUpdateRequest $request, $id)
'vehicle_updated' => $hasVehicleChanges,
'owner_updated' => $hasOwnerChanges,
'files_uploaded' => count($uploadedFiles) > 0,
'files_deleted' => count($deletedFiles) > 0,
],
'record' => $record,
'uploaded_files' => $uploadedFiles,
'deleted_files' => $deletedFiles,
'replaced_count' => count($replacedFiles),
'total_files' => File::where('record_id', $record->id)->count(),
]);

View File

@ -12,17 +12,28 @@ class RepuveService
private string $baseUrl;
private string $roboEndpoint;
private string $inscripcionEndpoint;
private string $username;
private string $password;
private ?string $username = null;
private ?string $password = null;
private bool $credentialsLoaded = false;
public function __construct()
{
$this->baseUrl = config('services.repuve_federal.base_url');
$this->roboEndpoint = config('services.repuve_federal.robo_endpoint');
$this->inscripcionEndpoint = config('services.repuve_federal.inscripcion_endpoint');
}
/**
* Asegurar que las credenciales estén cargadas (lazy loading)
*/
private function asegurarCargaCredenciales(): void
{
if ($this->credentialsLoaded) {
return; // Ya están cargadas
}
// Cargar credenciales desde BD (encriptadas)
$this->loadCredentials();
$this->credentialsLoaded = true;
}
/**
@ -59,6 +70,8 @@ private function loadCredentials(): void
public function consultarPadron(string $niv)
{
$this->asegurarCargaCredenciales();
$url = $this->baseUrl . $this->roboEndpoint;
$arg2 = $niv . '|||||||';
@ -207,6 +220,7 @@ private function parseVehicleResponse(string $soapResponse, string $niv)
public function verificarRobo(?string $niv = null, ?string $placa = null): array
{
try {
$this->asegurarCargaCredenciales();
if (empty($niv) && empty($placa)) {
logger()->warning('REPUVE verificarRobo: No se proporcionó NIV ni PLACA');
@ -330,6 +344,8 @@ public function verificarRobo(?string $niv = null, ?string $placa = null): array
public function consultarVehiculo(?string $niv = null, ?string $placa = null)
{
try {
$this->asegurarCargaCredenciales();
$url = $this->baseUrl . '/jaxws-consultarpv/ConsultaRpv';
// Construir arg2: NIV||||||||
@ -426,9 +442,10 @@ public function consultarVehiculo(?string $niv = null, ?string $placa = null)
public function inscribirVehiculo(array $datos)
{
$this->asegurarCargaCredenciales();
$url = $this->baseUrl . $this->inscripcionEndpoint;
// DATOS HARDCODEADOS
$arg2 = implode('|', [
$datos['ent_fed'] ?? '', // 1. Entidad federativa
$datos['ofcexp'] ?? '', // 2. Oficina expedición

View File

@ -12,7 +12,7 @@
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 11pt;
font-size: 10.5pt;
margin: 0;
padding: 0;
}

View File

@ -23,56 +23,46 @@
margin: 0 auto;
}
.header {
width: 100%;
border-bottom: 1px solid #000;
padding-bottom: 10px;
margin-bottom: 15px;
}
/* NUEVO ENCABEZADO TIPO TABLA */
.header-table {
width: 100%;
border-collapse: collapse;
margin-bottom: 40px;
}
.header-left {
width: 40%;
/* Columna Izquierda: Logo y Texto */
.col-left {
width: 45%;
vertical-align: middle;
border-right: 1px solid #666;
/* LÍNEA VERTICAL SEPARADORA */
padding-right: 15px;
}
.header-center {
width: 20%;
vertical-align: middle;
}
.header-right {
width: 40%;
/* Columna Derecha: Fecha */
.col-right {
width: 55%;
vertical-align: bottom;
text-align: right;
vertical-align: middle;
font-size: 9pt;
padding-left: 15px;
padding-bottom: 30px;
}
.header-right strong {
font-size: 11pt;
display: block;
/* Estructura interna del Logo */
.logo-wrapper {
width: 100%;
}
.logo {
max-height: 50px;
.logo-img {
height: 80px;
width: auto;
vertical-align: middle;
margin-right: 10px;
}
.date-line {
text-align: right;
font-size: 10pt;
margin-bottom: 15px;
}
.date-blank {
display: inline-block;
border-bottom: 1px solid #000;
min-width: 50px;
text-align: center;
.date-text {
font-size: 11pt;
color: #000;
}
.title {
@ -159,36 +149,29 @@
<body>
<div class="container">
<!-- Header -->
<div class="header">
<table class="header-table">
<tr>
<td class="header-left">
<?php
<!-- Header Reemplazado -->
<table class="header-table">
<tr>
<td class="col-left">
<div class="logo-wrapper">
<?php
$imagePath = resource_path('images/logo-seguridad.png');
$imageData = base64_encode(file_get_contents($imagePath));
$imageSrc = 'data:image/png;base64,' . $imageData;
?>
<img src="{{ $imageSrc }}" alt="Logo" class="logo">
</td>
<td class="header-center"></td>
<td class="header-right">
<strong>SEGURIDAD</strong>
SECRETARÍA DE SEGURIDAD<br>Y PROTECCIÓN CIUDADANA
</td>
</tr>
</table>
</div>
<!-- Fecha -->
<div class="date-line">
{{ $fecha }} de {{ $mes }} del {{ $anio }}
</div>
<img src="{{ $imageSrc }}" alt="Logo" class="logo-img">
</div>
</td>
<td class="col-right">
<div class="date-text">
Villahermosa, Tabasco {{ \Carbon\Carbon::now()->locale('es')->isoFormat('D [de] MMMM [del] YYYY') }}
</div>
</td>
</tr>
</table>
<!-- Título -->
<div class="title">
Solicitud de Sustitución de Constancia de Inscripción
</div>
<div class="title">Solicitud de Sustitución de Constancia de Inscripción</div>
<!-- Destinatario -->
<div class="department">
@ -206,19 +189,19 @@
<!-- Datos del vehículo -->
<div class="data-row">
<span class="data-label">Marca: </span><span >{{ strtoupper($marca ?? '') }}</span>
<span class="data-label">Marca: </span><span>{{ strtoupper($marca ?? '') }}</span>
</div>
<div class="data-row">
<span class="data-label">Modelo: </span><span >{{ strtoupper($linea ?? '') }}</span>
<span class="data-label">Modelo: </span><span>{{ strtoupper($linea ?? '') }}</span>
</div>
<div class="data-row">
<span class="data-label">Año Modelo: </span><span >{{ $modelo ?? '' }}</span>
<span class="data-label">Año Modelo: </span><span>{{ $modelo ?? '' }}</span>
</div>
<div class="data-row">
<span class="data-label">Número de Identificación (NIV): </span><span>{{ strtoupper($niv ?? '') }}</span>
<span class="data-label">Número de Identificación (VIN): </span><span>{{ strtoupper($niv ?? '') }}</span>
</div>
<div class="data-row">
@ -226,11 +209,11 @@
</div>
<div class="data-row">
<span class="data-label">Placas: </span><span >{{ strtoupper($placa ?? '') }}</span>
<span class="data-label">Placas: </span><span>{{ strtoupper($placa ?? '') }}</span>
</div>
<div class="data-row">
<span class="data-label">Folio de Constancia de Inscripción: </span><span >{{ strtoupper($folio ?? '') }}</span>
<span class="data-label">Folio de Constancia de Inscripción: </span><span>{{ strtoupper($folio ?? '') }}</span>
</div>
<!-- Sección MOTIVO -->
@ -260,7 +243,7 @@
<!-- Teléfono -->
<div class="telefono-row">
<span class="telefono-label">Teléfono:</span><span>{{ $telefono ?? '' }}</span>
<span class="telefono-label">Teléfono: </span><span>{{ $telefono ?? '' }}</span>
</div>
</div>
</body>

View File

@ -145,7 +145,7 @@
.footer-registro {
text-align: center;
margin-top: 120px;
margin-top: 90px;
color: red;
font-weight: bold;
font-size: 9pt;
@ -287,10 +287,12 @@
<tr>
<td class="signature-cell">
<div class="signature-line"></div>
<p class="signature-role">{{ $record->vehicle->owner->full_name ?? '' }}</p>
<p class="signature-role">PROPIETARIO</p>
</td>
<td class="signature-cell">
<div class="signature-line"></div>
<p class="signature-role">{{ $record->user->full_name ?? '' }}</p>
<p class="signature-role">OPERADOR</p>
</td>
</tr>

View File

@ -1,310 +1,348 @@
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Hoja de Verificación Vehicular</title>
<style>
@page {
margin: 0.8cm;
margin: 0.5cm;
size: landscape;
}
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 8pt;
line-height: 1.0;
line-height: 1.1;
color: #000;
margin: 0;
padding: 0;
}
.container {
width: 100%;
margin: 0 auto;
position: relative;
}
/* Encabezado */
.header {
text-align: center;
margin-bottom: 6px;
margin-bottom: 110px;
position: relative;
height: 50px;
}
.header h1 {
font-size: 20pt;
font-size: 18pt;
font-weight: bold;
margin: 0;
padding: 2px 0;
padding-top: 5px;
text-transform: uppercase;
}
.signature-section {
/* Texto en esquina superior derecha */
.operator-box {
position: absolute;
right: 0;
top: 0;
width: 180px;
right: 10px;
top: 100px;
width: 220px;
text-align: center;
padding: 1px;
margin-bottom: 50px;
}
.signature-line {
border-top: 1px solid #000;
margin: 60px 10px 5px 10px;
.operator-line {
border-top: 2px solid #000;
margin: 0 auto 5px auto;
width: 180px;
}
.signature-text {
margin: 5px 0;
.operator-name {
margin: 0 0 2px 0;
font-weight: bold;
font-size: 9pt;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 150px;
}
table th {
background-color: #c00040;
color: white;
.operator-label {
margin: 0;
padding-top: 3px;
font-weight: bold;
padding: 4.5px 5px;
text-align: center;
border: 1px solid #000;
}
table td {
background-color: #f5deb3;
padding: 4px 5px;
border: 1px solid #000;
font-size: 8pt;
}
table td.white-bg {
background-color: #ffffff;
/* Tablas */
table {
width: 100%;
border-collapse: collapse;
margin-bottom: 0;
table-layout: fixed;
margin-top: 0; /* Sin margen superior extra */
}
table td.gray-bg {
background-color: #e0e0e0;
table.second-table {
margin-top: 0;
}
.section-original td:nth-child(1),
.section-original td:nth-child(2) {
background-color: #f5deb3;
}
.id-column {
width: 30px;
table th {
background-color: #98283e;
color: white;
font-weight: bold;
padding: 2px 3px;
text-align: center;
border: 1px solid #fff;
font-size: 8pt;
height: 10px;
}
table td {
padding: 2px 5px;
border: 1px solid #666;
vertical-align: middle;
font-size: 7pt;
height: 16px;
}
/* Estilos de Celdas */
.bg-label {
background-color: #e6d6ad;
font-weight: bold;
}
.desc-column {
width: 250px;
.bg-value {
background-color: #f7ebd9;
}
.obs-column {
min-width: 150px;
.bg-white {
background-color: #ffffff;
}
.correct-column{
width: 120px;
.bg-gray {
background-color: #d9d9d9;
}
/* Anchos de columnas - Primera tabla */
.col-label {
width: 12%;
}
.col-value {
width: 38%;
}
.col-correct {
width: 20%;
}
.col-new {
width: 30%;
}
/* Anchos de columnas - Segunda tabla */
.col-id {
width: 4%;
text-align: center;
}
.col-desc {
width: 28%;
}
.col-obs {
width: 32%;
}
</style>
</head>
<body>
<div class="container">
<!-- Header -->
<div class="header">
<h1>HOJA DE VERIFICACIÓN </h1>
</div>
<!-- Firma del operador -->
<div class="signature-section">
<div class="signature-line"></div>
<p class="signature-text">{{ $record->user->full_name }}</p>
<p class="signature-text">OPERADOR</p>
<h1>HOJA DE VERIFICACIÓN</h1>
</div>
<!-- Tabla de verificación -->
<div class="operator-box">
<div class="operator-line"></div>
<div class="operator-name">{{ $record->user->full_name ?? '' }}</div>
<div class="operator-label">OPERADOR</div>
</div>
<!-- Primera tabla: Datos del vehículo -->
<table>
<thead>
<tr>
<th colspan="2">ORIGINAL</th>
<th class="correct-column">CORRECTO</th>
<th>NUEVO</th>
<th colspan="2" class="col-label col-value">ORIGINAL</th>
<th class="col-correct">CORRECTO</th>
<th class="col-new">NUEVO</th>
</tr>
</thead>
<tbody>
<tr class="section-original">
<td class="id-column">COLOR</td>
<td>{{ strtoupper($record->vehicle->color) }}</td>
<td class="white-bg"></td>
<td class="gray-bg"></td>
<tr>
<td class="bg-label col-label">COLOR</td>
<td class="bg-value col-value">{{ isset($record->vehicle->color) ? strtoupper($record->vehicle->color) : '' }}</td>
<td class="bg-label col-correct"></td>
<td class="bg-gray col-new"></td>
</tr>
<tr class="section-original">
<td class="id-column">PLACA</td>
<td>{{ $record->vehicle->placa }}</td>
<td class="white-bg"></td>
<td class="gray-bg"></td>
<tr>
<td class="bg-label col-label">PLACA</td>
<td class="bg-value col-value">{{ $record->vehicle->placa ?? '' }}</td>
<td class="bg-label col-correct"></td>
<td class="bg-gray col-new"></td>
</tr>
<tr class="section-original">
<td class="id-column">VIN</td>
<td>{{ $record->vehicle->niv }}</td>
<td class="white-bg"></td>
<td class="gray-bg"></td>
<tr>
<td class="bg-label col-label">VIN</td>
<td class="bg-value col-value">{{ $record->vehicle->niv ?? '' }}</td>
<td class="bg-label col-correct"></td>
<td class="bg-gray col-new"></td>
</tr>
<tr class="section-original">
<td class="id-column">MARCA</td>
<td>{{ strtoupper($record->vehicle->marca) }}</td>
<td class="white-bg"></td>
<td class="gray-bg"></td>
<tr>
<td class="bg-label col-label">MARCA</td>
<td class="bg-value col-value">{{ isset($record->vehicle->marca) ? strtoupper($record->vehicle->marca) : '' }}</td>
<td class="bg-label col-correct"></td>
<td class="bg-gray col-new"></td>
</tr>
<tr class="section-original">
<td class="id-column">SUBMARCA</td>
<td>{{ strtoupper($record->vehicle->linea) }}</td>
<td class="white-bg"></td>
<td class="gray-bg"></td>
<tr>
<td class="bg-label col-label">SUBMARCA</td>
<td class="bg-value col-value">{{ isset($record->vehicle->linea) ? strtoupper($record->vehicle->linea) : '' }}</td>
<td class="bg-label col-correct"></td>
<td class="bg-gray col-new"></td>
</tr>
<tr class="section-original">
<td class="id-column">MODELO</td>
<td>{{ $record->vehicle->modelo }}</td>
<td class="white-bg"></td>
<td class="gray-bg"></td>
<tr>
<td class="bg-label col-label">MODELO</td>
<td class="bg-value col-value">{{ $record->vehicle->modelo ?? '' }}</td>
<td class="bg-label col-correct"></td>
<td class="bg-gray col-new"></td>
</tr>
<tr class="section-original">
<td class="id-column">TIPO</td>
<td>{{ strtoupper($record->vehicle->tipo_veh) }}</td>
<td class="white-bg"></td>
<td class="gray-bg"></td>
<tr>
<td class="bg-label col-label">TIPO</td>
<td class="bg-value col-value">{{ isset($record->vehicle->tipo_veh) ? strtoupper($record->vehicle->tipo_veh) : '' }}</td>
<td class="bg-label col-correct"></td>
<td class="bg-gray col-new"></td>
</tr>
<tr class="section-original">
<td class="id-column">MOTOR</td>
<td>{{ $record->vehicle->numero_motor ?? 'S/N' }}</td>
<td class="white-bg"></td>
<td class="gray-bg"></td>
<tr>
<td class="bg-label col-label">MOTOR</td>
<td class="bg-value col-value">{{ $record->vehicle->numero_motor ?? 'S/N' }}</td>
<td class="bg-label col-correct"></td>
<td class="bg-gray col-new"></td>
</tr>
</tbody>
</table>
<!-- Tabla de verificación de partes -->
<table style="margin-top: 15px;">
<!-- Segunda tabla: Puntos de verificación -->
<table class="second-table">
<thead>
<tr>
<th class="id-column">ID</th>
<th class="desc-column">DESCRIPCIÓN</th>
<th class="id-column">ID</th>
<th class="desc-column">DESCRIPCIÓN</th>
<th class="obs-column">OBSERVACIONES</th>
<th class="col-id">ID</th>
<th class="col-desc">DESCRIPCIÓN</th>
<th class="col-id">ID</th>
<th class="col-desc">DESCRIPCIÓN</th>
<th class="col-obs">OBSERVACIONES</th>
</tr>
</thead>
<tbody>
<tr>
<td class="id-column">1</td>
<td>PLACA VIN TABLERO IZQ</td>
<td class="id-column white-bg"></td>
<td class="white-bg"></td>
<td class="white-bg"></td>
<td class="col-id bg-label">1</td>
<td class="bg-label col-desc">PLACA VIN TABLERO IZQ</td>
<td class="col-id bg-gray"></td>
<td class="bg-gray col-desc"></td>
<td class="bg-gray col-obs"></td>
</tr>
<tr>
<td class="id-column">2</td>
<td>PARED DE FUEGO</td>
<td class="id-column white-bg"></td>
<td class="white-bg"></td>
<td class="white-bg"></td>
<td class="col-id bg-label">2</td>
<td class="bg-label col-desc">PARED DE FUEGO</td>
<td class="col-id bg-gray"></td>
<td class="bg-gray col-desc"></td>
<td class="bg-gray col-obs"></td>
</tr>
<tr>
<td class="id-column">3</td>
<td>BASE DE AMORTIGUADOR DERECHO</td>
<td class="id-column white-bg"></td>
<td class="white-bg"></td>
<td class="white-bg"></td>
<td class="col-id bg-label">3</td>
<td class="bg-label col-desc">BASE DE AMORTIGUADOR DERECHO</td>
<td class="col-id bg-gray"></td>
<td class="bg-gray col-desc"></td>
<td class="bg-gray col-obs"></td>
</tr>
<tr>
<td class="id-column">4</td>
<td>PISO ABAJO DEL ASIENTO DEL COPILOTO</td>
<td class="id-column white-bg"></td>
<td class="white-bg"></td>
<td class="white-bg"></td>
<td class="col-id bg-label">4</td>
<td class="bg-label col-desc">PISO ABAJO DEL ASIENTO COPILOTO</td>
<td class="col-id bg-gray"></td>
<td class="bg-gray col-desc"></td>
<td class="bg-gray col-obs"></td>
</tr>
<tr>
<td class="id-column">5</td>
<td>PISO DE CAJUELA</td>
<td class="id-column white-bg"></td>
<td class="white-bg"></td>
<td class="white-bg"></td>
<td class="col-id bg-label">5</td>
<td class="bg-label col-desc">PISO DE CAJUELA</td>
<td class="col-id bg-gray"></td>
<td class="bg-gray col-desc"></td>
<td class="bg-gray col-obs"></td>
</tr>
<tr>
<td class="id-column">6</td>
<td>ESTRIBO</td>
<td class="id-column white-bg"></td>
<td class="white-bg"></td>
<td class="white-bg"></td>
<td class="col-id bg-label">6</td>
<td class="bg-label col-desc">ESTRIBO</td>
<td class="col-id bg-gray"></td>
<td class="bg-gray col-desc"></td>
<td class="bg-gray col-obs"></td>
</tr>
<tr>
<td class="id-column">7</td>
<td>CHASIS DERECHO</td>
<td class="id-column white-bg"></td>
<td class="white-bg"></td>
<td class="white-bg"></td>
<td class="col-id bg-label">7</td>
<td class="bg-label col-desc">CHASIS DERECHO</td>
<td class="col-id bg-gray"></td>
<td class="bg-gray col-desc"></td>
<td class="bg-gray col-obs"></td>
</tr>
<tr>
<td class="id-column">8</td>
<td>CHASIS IZQUIERDO</td>
<td class="id-column white-bg"></td>
<td class="white-bg"></td>
<td class="white-bg"></td>
<td class="col-id bg-label">8</td>
<td class="bg-label col-desc">CHASIS IZQUIERDO</td>
<td class="col-id bg-gray"></td>
<td class="bg-gray col-desc"></td>
<td class="bg-gray col-obs"></td>
</tr>
<tr>
<td class="id-column">9</td>
<td>BAZTIDOR IZQUIERDO</td>
<td class="id-column white-bg"></td>
<td class="white-bg"></td>
<td class="white-bg"></td>
<td class="col-id bg-label">9</td>
<td class="bg-label col-desc">BASTIDOR IZQUIERDO</td>
<td class="col-id bg-gray"></td>
<td class="bg-gray col-desc"></td>
<td class="bg-gray col-obs"></td>
</tr>
<tr>
<td class="id-column">10</td>
<td>BAZTIDOR DERECHO</td>
<td class="id-column white-bg"></td>
<td class="white-bg"></td>
<td class="white-bg"></td>
<td class="col-id bg-label">10</td>
<td class="bg-label col-desc">BASTIDOR DERECHO</td>
<td class="col-id bg-gray"></td>
<td class="bg-gray col-desc"></td>
<td class="bg-gray col-obs"></td>
</tr>
<tr>
<td class="id-column">11</td>
<td>MARCO RADIADOR</td>
<td class="id-column white-bg"></td>
<td class="white-bg"></td>
<td class="white-bg"></td>
<td class="col-id bg-label">11</td>
<td class="bg-label col-desc">MARCO RADIADOR</td>
<td class="col-id bg-gray"></td>
<td class="bg-gray col-desc"></td>
<td class="bg-gray col-obs"></td>
</tr>
<tr>
<td class="id-column">12</td>
<td>PISO CARROCERIA</td>
<td class="id-column white-bg"></td>
<td class="white-bg"></td>
<td class="white-bg"></td>
<td class="col-id bg-label">12</td>
<td class="bg-label col-desc">PISO CARROCERÍA</td>
<td class="col-id bg-gray"></td>
<td class="bg-gray col-desc"></td>
<td class="bg-gray col-obs"></td>
</tr>
<tr>
<td class="id-column">13</td>
<td>TABLERO DE PARTE MEDIA</td>
<td class="id-column white-bg"></td>
<td class="white-bg"></td>
<td class="white-bg"></td>
<td class="col-id bg-label">13</td>
<td class="bg-label col-desc">TABLERO DE PARTE MEDIA</td>
<td class="col-id bg-gray"></td>
<td class="bg-gray col-desc"></td>
<td class="bg-gray col-obs"></td>
</tr>
<tr>
<td class="id-column">14</td>
<td>MOTOR</td>
<td class="id-column white-bg"></td>
<td class="white-bg"></td>
<td class="white-bg"></td>
<td class="col-id bg-label">14</td>
<td class="bg-label col-desc">MOTOR</td>
<td class="col-id bg-gray"></td>
<td class="bg-gray col-desc"></td>
<td class="bg-gray col-obs"></td>
</tr>
<tr>
<td class="id-column">15</td>
<td>TRANSMISION</td>
<td class="id-column white-bg"></td>
<td class="white-bg"></td>
<td class="white-bg"></td>
<td class="col-id bg-label">15</td>
<td class="bg-label col-desc">TRANSMISIÓN</td>
<td class="col-id bg-gray"></td>
<td class="bg-gray col-desc"></td>
<td class="bg-gray col-obs"></td>
</tr>
</tbody>
</table>
</div>
</body>
</html>