Release inicial 1.0.0

This commit is contained in:
2025-03-10 18:25:41 -06:00
commit ba2845242d
83 changed files with 309608 additions and 0 deletions

View File

@ -0,0 +1,123 @@
<?php
namespace Koneko\SatCatalogs\Console\Commands;
use Illuminate\Console\Command;
use Koneko\SatCatalogs\Services\CsvGeneratorService;
class GenerateCsvFromXlsx extends Command
{
protected $signature = 'sat:generate-csv {xlsxFile} {--all} {sheetName?} {csvFile?} {--skipRows=7}';
protected $description = 'Genera archivos CSV optimizados a partir de un archivo XLSX y actualiza el archivo de versión.';
private $csvRecordsCount = [];
public function handle()
{
$xlsxFile = database_path("data/{$this->argument('xlsxFile')}");
if (!file_exists($xlsxFile)) {
$this->error("⚠️ El archivo XLSX no existe: {$xlsxFile}");
return;
}
if ($this->option('all')) {
$this->generateAllCsv($xlsxFile);
$this->updateVersionFile($xlsxFile);
return;
}
$sheetName = $this->argument('sheetName');
$csvFile = $this->argument('csvFile');
$skipRows = (int) $this->option('skipRows');
if (!$sheetName || !$csvFile) {
$this->error("⚠️ Debes proporcionar sheetName y csvFile o usar --all para procesar todos.");
return;
}
$this->generateCsv($xlsxFile, $sheetName, $csvFile, $skipRows);
}
private function generateAllCsv(string $xlsxFile)
{
$catalogs = [
'c_FormaPago' => 6,
'c_Moneda' => 5,
'c_CodigoPostal' => [['c_CodigoPostal_Parte_1', 'c_CodigoPostal_Parte_2'], 7],
'c_RegimenFiscal' => 6,
'c_Pais' => 5,
'c_UsoCFDI' => 6,
'c_ClaveProdServ' => 5,
'c_ClaveUnidad' => 6,
'c_Aduana' => 5,
'C_Colonia' => [['C_Colonia_1', 'C_Colonia_2', 'C_Colonia_3'], 5],
'c_Estado' => 5,
'C_Localidad' => 5,
'C_Municipio' => 5,
];
foreach ($catalogs as $csvFile => $sheetData) {
if (is_array($sheetData) && is_array($sheetData[0])) {
// Se trata de una combinación de hojas
[$sheets, $skipRows] = $sheetData;
$this->generateCsv($xlsxFile, $sheets, strtolower($csvFile), $skipRows);
} else {
// Proceso normal para una sola hoja
$this->generateCsv($xlsxFile, $csvFile, strtolower($csvFile), $sheetData);
}
}
echo "\n";
}
private function generateCsv(string $xlsxFile, string|array $sheetName, string $csvFile, int $skipRows)
{
echo "\n📌 Procesando hojas: " . (is_array($sheetName) ? implode(", ", $sheetName) : $sheetName) . "\n";
$csvPath = CsvGeneratorService::convertToCsv($xlsxFile, $sheetName, $csvFile, $skipRows);
if (isset($csvPath['error'])) {
$this->error("❌ Error en {$csvFile}: {$csvPath['error']}");
} else {
$rowCount = CsvGeneratorService::countCsvRows($csvPath);
$this->csvRecordsCount[$csvFile] = $rowCount;
$this->info("✅ CSV generado: {$csvPath} ({$rowCount} filas)");
}
// Liberar memoria forzadamente
gc_collect_cycles();
}
private function updateVersionFile(string $xlsxFile)
{
$versionFile = database_path('seeders/sat_cache/version.txt');
$versionContent = "📄 Versión de los Catálogos SAT\n";
$versionContent .= "-----------------------------------\n";
$versionContent .= "📌 Archivo XLSX: " . basename($xlsxFile) . "\n";
$versionContent .= "📅 Fecha de generación: " . now()->format('Y-m-d H:i:s') . "\n";
$versionContent .= "-----------------------------------\n";
$versionContent .= "📂 Archivos CSV generados:\n";
foreach ($this->csvRecordsCount as $csvFile => $rowCount) {
$versionContent .= " - {$csvFile}.csv ({$rowCount} filas)\n";
}
$versionContent .= "-----------------------------------\n";
$versionContent .= "🔗 Información del paquete:\n";
$versionContent .= " - Packagist: https://packagist.org/packages/koneko/laravel-sat-catalogs\n";
$versionContent .= " - Git Repo: https://git.koneko.mx/koneko/laravel-sat-catalogs\n";
file_put_contents($versionFile, $versionContent);
$this->info("✅ Archivo de versión actualizado: {$versionFile}");
}
}

View File

@ -0,0 +1,70 @@
<?php
namespace Koneko\SatCatalogs\Console\Commands;
use Illuminate\Console\Command;
use Koneko\SatCatalogs\Services\CsvDatabaseService;
class ImportCsvToDatabase extends Command
{
protected $signature = 'sat:import-csv {--update}';
protected $description = 'Importa todos los archivos CSV de los catálogos SAT a la base de datos';
private array $csvMappings = [
'c_formapago' => ['table' => 'sat_forma_pago', 'columns' => ['c_forma_pago', 'descripcion', 'fecha_inicio_vigencia', 'fecha_fin_vigencia']],
'c_moneda' => ['table' => 'sat_moneda', 'columns' => ['c_moneda', 'descripcion', 'decimales', 'porcentaje_variacion', 'fecha_inicio_vigencia', 'fecha_fin_vigencia']],
'c_codigopostal' => ['table' => 'sat_codigo_postal', 'columns' => ['c_codigo_postal', 'c_estado', 'c_municipio', 'c_localidad', 'estimulo_franja_fronteriza', 'fecha_inicio_vigencia', 'fecha_fin_vigencia']],
'c_pais' => ['table' => 'sat_pais', 'columns' => ['c_pais', 'descripcion', 'formato_de_codigo_postal', 'formato_de_registro_de_identidad_tributaria', 'validacion_del_registro_de_identidad_tributaria', 'agrupaciones']],
'c_estado' => ['table' => 'sat_estado', 'columns' => ['c_estado', 'c_pais', 'nombre_del_estado', 'fecha_inicio_vigencia', 'fecha_fin_vigencia']],
'c_municipio' => ['table' => 'sat_municipio', 'columns' => ['c_municipio', 'c_estado', 'descripcion', 'fecha_inicio_vigencia', 'fecha_fin_vigencia']],
'c_localidad' => ['table' => 'sat_localidad', 'columns' => ['c_localidad', 'c_estado', 'descripcion', 'fecha_inicio_vigencia', 'fecha_fin_vigencia']],
'c_colonia' => ['table' => 'sat_colonia', 'columns' => ['c_colonia', 'c_codigo_postal', 'nombre_del_asentamiento']],
'c_regimenfiscal' => ['table' => 'sat_regimen_fiscal', 'columns' => ['c_regimen_fiscal', 'descripcion', 'fisica', 'moral', 'fecha_inicio_vigencia', 'fecha_fin_vigencia']],
'c_usocfdi' => ['table' => 'sat_uso_cfdi', 'columns' => ['c_uso_cfdi', 'descripcion', 'aplica_para_tipo_persona_fisica', 'aplica_para_tipo_persona_moral', 'fecha_inicio_vigencia', 'fecha_fin_vigencia', 'regimen_fiscal_receptor']],
'c_claveprodserv' => ['table' => 'sat_clave_prod_serv', 'columns' => ['c_clave_prod_serv', 'descripcion', 'incluir_iva_trasladado', 'incluir_ieps_trasladado', 'complemento_que_debe_incluir', 'fecha_inicio_vigencia', 'fecha_fin_vigencia', 'estimulo_franja_fronteriza', 'palabras_similares']],
'c_claveunidad' => ['table' => 'sat_clave_unidad', 'columns' => ['c_clave_unidad', 'nombre', 'descripcion', 'nota', 'fecha_inicio_vigencia', 'fecha_fin_vigencia', 'simbolo']],
'c_aduana' => ['table' => 'sat_aduana', 'columns' => ['c_aduana', 'descripcion', 'fecha_inicio_vigencia', 'fecha_fin_vigencia']],
'c_banco' => ['table' => 'sat_banco', 'columns' => ['c_banco', 'descripcion', 'razon_social', 'rfc', 'status']],
'c_deduccion' => ['table' => 'sat_deduccion', 'columns' => ['c_deduccion', 'descripcion']],
'c_percepcion' => ['table' => 'sat_percepcion', 'columns' => ['c_percepcion', 'descripcion', 'gravado_exento']],
'c_regimen_contratacion' => ['table' => 'sat_regimen_contratacion', 'columns' => ['c_tipo_regimen', 'descripcion']],
];
public function handle()
{
$csvPath = database_path('seeders/sat_cache/');
$updateExisting = $this->option('update');
if (!is_dir($csvPath)) {
$this->error("⚠️ No se encontró la carpeta: {$csvPath}");
return;
}
$totalFiles = count($this->csvMappings);
$this->info("📌 Iniciando importación de {$totalFiles} archivos CSV...\n");
foreach ($this->csvMappings as $csvFile => $mapping) {
$fullPath = "{$csvPath}{$csvFile}.csv";
if (!file_exists($fullPath)) {
$this->warn("⚠️ Archivo CSV no encontrado: {$fullPath}");
continue;
}
$this->info("📂 Importando: {$csvFile}.csv → {$mapping['table']}");
$result = CsvDatabaseService::importCsvToTable($fullPath, $mapping['table'], $mapping['columns'], $updateExisting);
if (isset($result['error'])) {
$this->error("❌ Error en {$csvFile}: {$result['error']}");
} else {
$inserted = $result['inserted'] ?? 0;
$this->info("✅ Importación completa: {$csvFile} ({$inserted} insertados)\n");
}
}
$this->info("✅ Todos los archivos CSV han sido importados correctamente.");
}
}