213 lines
8.3 KiB
PHP
213 lines
8.3 KiB
PHP
|
<?php
|
||
|
|
||
|
namespace Koneko\VuexyContacts\Services;
|
||
|
|
||
|
use Exception;
|
||
|
use Illuminate\Http\UploadedFile;
|
||
|
use Spatie\PdfToText\Pdf;
|
||
|
use Koneko\SatCatalogs\Models\{Estado,Localidad,Municipio,Colonia,RegimenFiscal};
|
||
|
|
||
|
class ConstanciaFiscalService
|
||
|
{
|
||
|
protected $data = [];
|
||
|
protected $actividades = [];
|
||
|
protected $regimenes = [];
|
||
|
|
||
|
/**
|
||
|
* Procesa el PDF de la Constancia de Situación Fiscal y extrae la información relevante.
|
||
|
*
|
||
|
* @param UploadedFile $file
|
||
|
* @return array
|
||
|
* @throws Exception
|
||
|
*/
|
||
|
public function extractData(UploadedFile $file): array
|
||
|
{
|
||
|
if ($file->getClientOriginalExtension() !== 'pdf') {
|
||
|
throw new Exception('El archivo debe ser un PDF.');
|
||
|
}
|
||
|
|
||
|
$text = Pdf::getText($file->getRealPath());
|
||
|
$text_array = array_values(array_filter(explode("\n", $text), 'trim')); // Limpia líneas vacías
|
||
|
|
||
|
// **Estructura base con NULL en todos los campos**
|
||
|
$this->data = array_fill_keys([
|
||
|
"rfc", "curp", "name", "last_name", "second_last_name", "nombre_comercial", "telefono",
|
||
|
"fecha_inicio_operaciones", "estatus_padron", "fecha_ultimo_cambio_estado",
|
||
|
"c_codigo_postal", "c_estado", "estado", "c_localidad", "localidad",
|
||
|
"c_municipio", "municipio", "c_colonia", "colonia",
|
||
|
"vialidad", "entre_calle", "num_ext", "num_int", "regimenes"
|
||
|
], null);
|
||
|
|
||
|
$this->data['regimenes'] = []; // Siempre inicializar como array
|
||
|
|
||
|
$this->procesarDatosInline($text_array);
|
||
|
|
||
|
$this->procesarRegimenes($text_array);
|
||
|
|
||
|
if (empty($this->data['rfc'])) {
|
||
|
throw new Exception('No se encontró RFC en el documento.');
|
||
|
}
|
||
|
|
||
|
return $this->data;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Procesa los datos generales hasta encontrar "Regímenes:".
|
||
|
*/
|
||
|
protected function procesarDatosInline(array $text_array)
|
||
|
{
|
||
|
foreach ($text_array as $index => $linea) {
|
||
|
$linea = trim($linea);
|
||
|
|
||
|
if ($linea === "Regímenes:") {
|
||
|
return; // Detener la iteración
|
||
|
}
|
||
|
|
||
|
// RFC, CURP, Nombre y Apellidos
|
||
|
if (str_contains($linea, "RFC:")) {
|
||
|
$this->data['rfc'] = trim($text_array[$index + 1]);
|
||
|
|
||
|
} elseif (str_contains($linea, "CURP:")) {
|
||
|
$this->data['curp'] = trim($text_array[$index + 1]);
|
||
|
|
||
|
} elseif (str_contains($linea, "Nombre (s):")) {
|
||
|
$this->data['name'] = trim($text_array[$index + 1]);
|
||
|
|
||
|
} elseif (str_contains($linea, "Primer Apellido:")) {
|
||
|
$this->data['last_name'] = trim($text_array[$index + 1]);
|
||
|
|
||
|
} elseif (str_contains($linea, "Segundo Apellido:")) {
|
||
|
$this->data['second_last_name'] = trim($text_array[$index + 1]);
|
||
|
}
|
||
|
|
||
|
// Fechas y estatus
|
||
|
elseif (str_contains($linea, "Fecha inicio de operaciones:")) {
|
||
|
$this->data['fecha_inicio_operaciones'] = trim($text_array[$index + 1]);
|
||
|
|
||
|
} elseif (str_contains($linea, "Estatus en el padrón:")) {
|
||
|
$this->data['estatus_padron'] = trim($text_array[$index + 1]);
|
||
|
|
||
|
} elseif (str_contains($linea, "Fecha de último cambio de estado:")) {
|
||
|
$this->data['fecha_ultimo_cambio_estado'] = trim($text_array[$index + 1]);
|
||
|
}
|
||
|
|
||
|
// Nombre Comercial
|
||
|
elseif (str_contains($linea, "Nombre Comercial:")) {
|
||
|
$this->data['nombre_comercial'] = trim($text_array[$index + 1]);
|
||
|
}
|
||
|
|
||
|
// **Teléfono (Dos Líneas)**
|
||
|
elseif (str_contains($linea, "Tel. Fijo Lada:")) {
|
||
|
$lada = trim(str_replace("Tel. Fijo Lada:", "", $linea));
|
||
|
|
||
|
if (isset($text_array[$index + 1]) && str_contains($text_array[$index + 1], "Número:")) {
|
||
|
$numero = trim(str_replace("Número:", "", $text_array[$index + 1]));
|
||
|
$this->data['telefono'] = $lada . " " . $numero;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// **Código Postal**
|
||
|
elseif (str_contains($linea, "Código Postal:")) {
|
||
|
$this->data['c_codigo_postal'] = trim(str_replace("Código Postal:", "", $linea));
|
||
|
}
|
||
|
|
||
|
// **Estado**
|
||
|
elseif (str_contains($linea, "Nombre de la Entidad Federativa:")) {
|
||
|
$estado_nombre = trim(str_replace("Nombre de la Entidad Federativa:", "", $linea));
|
||
|
$estado = Estado::where('nombre_del_estado', 'like', "%{$estado_nombre}%")->first();
|
||
|
|
||
|
$this->data['c_estado'] = $estado->c_estado ?? null;
|
||
|
$this->data['estado'] = $estado_nombre;
|
||
|
}
|
||
|
|
||
|
// **Municipio**
|
||
|
elseif (str_contains($linea, "Nombre del Municipio o Demarcación Territorial:")) {
|
||
|
$municipio_nombre = trim(str_replace("Nombre del Municipio o Demarcación Territorial:", "", $linea));
|
||
|
$municipio = Municipio::where('descripcion', 'like', "%{$municipio_nombre}%")->first();
|
||
|
|
||
|
$this->data['c_municipio'] = $municipio->c_municipio ?? null;
|
||
|
$this->data['municipio'] = $municipio_nombre;
|
||
|
}
|
||
|
|
||
|
// **Colonia**
|
||
|
elseif (str_contains($linea, "Nombre de la Colonia:")) {
|
||
|
$colonia_nombre = trim(str_replace("Nombre de la Colonia:", "", $linea));
|
||
|
$colonia = Colonia::where('nombre_del_asentamiento', 'like', "%{$colonia_nombre}%")->first();
|
||
|
|
||
|
$this->data['c_colonia'] = $colonia->c_colonia ?? null;
|
||
|
$this->data['colonia'] = $colonia_nombre;
|
||
|
}
|
||
|
|
||
|
// **Localidad** (Nueva implementación)
|
||
|
elseif (str_contains($linea, "Nombre de la Localidad:")) {
|
||
|
$localidad_nombre = trim(str_replace("Nombre de la Localidad:", "", $linea));
|
||
|
$localidad = Localidad::where('descripcion', 'like', "%{$localidad_nombre}%")->first();
|
||
|
|
||
|
$this->data['c_localidad'] = $localidad->c_localidad ?? null;
|
||
|
$this->data['localidad'] = $localidad_nombre;
|
||
|
}
|
||
|
|
||
|
// **Entre Calle**
|
||
|
elseif (str_contains($linea, "Entre Calle:")) {
|
||
|
$this->data['entre_calle'] = trim(str_replace("Entre Calle:", "", $linea));
|
||
|
}
|
||
|
|
||
|
// **Dirección**
|
||
|
elseif (str_contains($linea, "Nombre de Vialidad:")) {
|
||
|
$this->data['vialidad'] = trim(str_replace("Nombre de Vialidad:", "", $linea));
|
||
|
|
||
|
} elseif (str_contains($linea, "Número Exterior:")) {
|
||
|
$this->data['num_ext'] = trim(str_replace("Número Exterior:", "", $linea));
|
||
|
|
||
|
} elseif (str_contains($linea, "Número Interior:") && !str_contains($text_array[$index + 1], "Nombre de la Colonia:")) {
|
||
|
$this->data['num_int'] = trim(str_replace("Número Interior:", "", $linea));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Procesa los regímenes fiscales hasta encontrar "Obligaciones:".
|
||
|
*/
|
||
|
protected function procesarRegimenes(array $text_array)
|
||
|
{
|
||
|
$procesando = false;
|
||
|
|
||
|
foreach ($text_array as $index => $linea) {
|
||
|
if (trim($linea) === "Regímenes:") {
|
||
|
$procesando = true;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (trim($linea) === "Obligaciones:") {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if ($procesando) {
|
||
|
// **Filtrar líneas no relevantes**
|
||
|
if (in_array($linea, ["Régimen", "Fecha Inicio", "Fecha Fin", "Obligaciones:"])) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// **Si la línea es una fecha, asociarla al régimen anterior**
|
||
|
if (preg_match('/\d{2}\/\d{2}\/\d{4}/', $linea)) {
|
||
|
$ultimo_regimen = &$this->data['regimenes'][count($this->data['regimenes']) - 1];
|
||
|
if (isset($ultimo_regimen)) {
|
||
|
$ultimo_regimen['fecha_inicio'] = trim($linea);
|
||
|
}
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (!empty($linea)) {
|
||
|
$regimenFiscal = RegimenFiscal::where('descripcion', 'like', "%{$linea}%")->first();
|
||
|
$this->data['regimenes'][] = [
|
||
|
'regimen_fiscal' => trim($linea),
|
||
|
'c_regimen_fiscal' => $regimenFiscal->c_regimen_fiscal ?? null,
|
||
|
'fecha_inicio' => null,
|
||
|
];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|