diff --git a/Contracts/ArchivoElectronico/IArchivoElectronicoRepository.cs b/Contracts/ArchivoElectronico/IArchivoElectronicoRepository.cs new file mode 100644 index 0000000..1f7c6dd --- /dev/null +++ b/Contracts/ArchivoElectronico/IArchivoElectronicoRepository.cs @@ -0,0 +1,9 @@ +using CORRESPONSALBackend.DTO.ArchivoElectronico; +using GEMCO.Backend.Models.Reportes; + +namespace CORRESPONSALBackend.Contracts.ArchivoElectronico{ + public interface IArchivoElectronicoRepository + { + public Task> getRptPedimentoPagadosAEO(DTOAEPeriodo dTOData); + } +} \ No newline at end of file diff --git a/Contracts/ArchivoElectronico/IArchivoElectronicoService.cs b/Contracts/ArchivoElectronico/IArchivoElectronicoService.cs new file mode 100644 index 0000000..751c86e --- /dev/null +++ b/Contracts/ArchivoElectronico/IArchivoElectronicoService.cs @@ -0,0 +1,5 @@ +namespace CORRESPONSALBackend.Contracts.ArchivoElectronico{ + public interface IArchivoElectronicoService{ + + } +} \ No newline at end of file diff --git a/Contracts/Utils/IFileManagerRepository.cs b/Contracts/Utils/IFileManagerRepository.cs index 236cd1c..8068a2f 100644 --- a/Contracts/Utils/IFileManagerRepository.cs +++ b/Contracts/Utils/IFileManagerRepository.cs @@ -12,5 +12,6 @@ namespace CORRESPONSALBackend.Contracts.Utils public Task UpdateFileNameById(long id, string newFileName); public Task> GetFilesByProcessId(int process); public Task UpdateFileProcessById(long fileId, int process); + public Task> GetTraficoFiles(int idTrafico); } } \ No newline at end of file diff --git a/Controllers/AuthController.cs b/Controllers/AuthController.cs index 09a4c72..bb77c8b 100644 --- a/Controllers/AuthController.cs +++ b/Controllers/AuthController.cs @@ -133,10 +133,10 @@ namespace CORRESPONSALBackend.Controllers { DTOPINData PINData = await _usuariosRepo.CreatePIN(IdUser); string htmlContent = $@" - + - - + +
Estimado usuario, mediante este correo se le notifica que esta en proceso de cambiar su contraseña
Estimado usuario, mediante este correo se le notifica que está en proceso de cambiar su contraseña.
Se ha generado un PIN para poder cambiar su contraseña. PIN : {PINData.PIN}
El PIN tiene un tiempo de vida de 10 minutos, a partir de su generacion, despues de ese tiempo caduca
Si usted no es quien ha activando este mecanismo, favor de ponerse en contacto con personal de ZINC
El PIN tiene un tiempo de vida de 10 minutos, a partir de su generación.
Si usted NO es quien ha activando este mecanismo, favor de ponerse en contacto con personal de GEMCO.
"; if (PINData.PIN > 0) { diff --git a/Controllers/FileManagerController.cs b/Controllers/FileManagerController.cs index de0c4e6..77713b1 100644 --- a/Controllers/FileManagerController.cs +++ b/Controllers/FileManagerController.cs @@ -430,5 +430,16 @@ namespace CORRESPONSALBackend.Controllers return BadRequest(ex.Message); } } + + [HttpGet("FileListByReferencia")] + public async Task GeFileListByReferencia([FromQuery] string referencia){ + try{ + var trafico = await _traficosRepository.GetByReferencia(referencia); + var fileList = await _Repo.GetTraficoFiles(trafico.id); + return Ok(fileList); + }catch(Exception ex){ + return BadRequest(ex.Message); + } + } } } \ No newline at end of file diff --git a/Controllers/Utils/ArchivoElectronicoController.cs b/Controllers/Utils/ArchivoElectronicoController.cs new file mode 100644 index 0000000..41c05e0 --- /dev/null +++ b/Controllers/Utils/ArchivoElectronicoController.cs @@ -0,0 +1,93 @@ +using CORRESPONSALBackend.Contracts.ArchivoElectronico; +using CORRESPONSALBackend.Contracts.Corresponsalias; +using CORRESPONSALBackend.Contracts.Utils; +using CORRESPONSALBackend.DTO.ArchivoElectronico; +using CORRESPONSALBackend.Models.Utils; +using CORRESPONSALBackend.Repository.Utils; +using GEMCO.Backend.Models.Reportes; +using Microsoft.AspNetCore.Mvc; + +namespace CORRESPONSALBackend.Controllers.Utils{ + [Route("api/[controller]")] + [ApiController] + public class ArchivoElectronicoController : ControllerBase { + + private readonly IArchivoElectronicoRepository _AERepo; + private readonly IConfiguration _config; + private readonly IFilePaths4ProcessRepository _RepoRelativePath; + private readonly string RootPathCorresponsales; + private readonly ICorresponsaliasTraficosRepository _traficosRepository; + private readonly IFileManagerRepository _fileManagerRepo; + public ArchivoElectronicoController(IArchivoElectronicoRepository AERepo, IConfiguration config, + ICorresponsaliasTraficosRepository traficosRepository, IFilePaths4ProcessRepository RepoRelativePath, + IFileManagerRepository fileManagerRepo){ + _AERepo = AERepo; + _traficosRepository = traficosRepository; + _config = config; + _RepoRelativePath = RepoRelativePath; + _fileManagerRepo = fileManagerRepo; + RootPathCorresponsales = _config.GetValue("AllFiles"); + } + + [HttpGet] + [Route("RptArchivoElectronicoOficial")] + public async Task> GetReporteArchivElectronicoOficial([FromQuery] DTOAEPeriodo DTOData) + { + List data = await _AERepo.getRptPedimentoPagadosAEO(DTOData); + return data; + } + + [HttpPost] + [Route("DownloadZippedArchivosOficiales")] + public async Task DownloadZippedArchivosOficiales([FromBody] DTOAEPeriodoSeleccion data){ + try{ + //Se obtiene la ruta donde se alojará temporalmente el zip + FilePaths4Process tempFilesRelativePath = await _RepoRelativePath.getPaths4ProcessById(45); // Path: Corresponsales\Zips\Facturacion\Entregas\ + var tempFilesPath = RootPathCorresponsales + tempFilesRelativePath.Path;// Path: C:data\Corresponsales\Zips\Clientes\ArchivosElectronicos + string tempFolderName = "ReporteArchivosElectronicos";//Nombre del folder Temporal + string tempFolderPath= tempFilesPath + $"{tempFolderName}\\";//ruta del folder temporal Path: C:data\Corresponsales\Zips\Clientes\ArchivosElectronicos\ReporteArchivosElectronicos + string zipFileName = $"{tempFolderName}.zip";//Nombre del zip final + var zipFilePath = tempFilesPath + zipFileName;//Ruta del zip final Path: C:data\Corresponsales\Zips\Clientes\ArchivosElectronicos\ReporteArchivosElectronicos.zip + + if(System.IO.File.Exists(zipFilePath)){//Si ya existe un zip de una descarga anterior lo borra + System.IO.File.Delete(zipFilePath); + } + + if(System.IO.Directory.Exists(tempFolderPath)){//Si ya existe la carpeta temporal de una descarga anterior la borra + System.IO.Directory.Delete(tempFolderPath, true); + } + + System.IO.Directory.CreateDirectory(tempFolderPath);//Se crea el folder temporal donde se pondran los archivos oficiales + foreach(var referencia in data.Referencias){ + var trafico = await _traficosRepository.GetByReferencia(referencia); + string folderAE = tempFolderPath + $"{referencia}\\";//Se obtiene el nombre de la subcarpeta del AE de cada referencia + if(System.IO.Directory.Exists(folderAE)){//Si existe la carpeta se borra + System.IO.Directory.Delete(folderAE); + } + System.IO.Directory.CreateDirectory(folderAE);//Se crea la carpeta + //Obtener la lista de archivos de la referencia actual. + var filesLog = await _fileManagerRepo.GetTraficoFiles(trafico.id); + var filteredFilesLog = filesLog.Where(x => new List(){2,10,11,12,13,14,15,19,17,18,37,38,39,41}.Contains(x.Proceso)); + foreach(var fileLog in filteredFilesLog){ + FilePaths4Process fileRelativePath = await _RepoRelativePath.getPaths4ProcessById(fileLog.Proceso);//Se obtiene la ruta relativa donde debe estar alojado el archivo + var filePath = RootPathCorresponsales + fileRelativePath.Path + fileLog!.NombreArchivo;//Ahora se obtiene la ruta completa del archivo. + if(System.IO.File.Exists(filePath)){ + var bytes = await System.IO.File.ReadAllBytesAsync(filePath); + var originalFileStream = new MemoryStream(bytes); + using(var tempFileStream = System.IO.File.Create(folderAE + fileLog.NombreArchivo)){ + await originalFileStream.CopyToAsync(tempFileStream); + } + } + } + } + System.IO.Compression.ZipFile.CreateFromDirectory(tempFolderPath, zipFilePath);//Se comprime la carpeta con los archivos electronicos de las referencias + Directory.Delete(tempFolderPath, true);//Se borra el folder temporal + var zipBytes = await System.IO.File.ReadAllBytesAsync(zipFilePath); + var zipStream = new MemoryStream(zipBytes); + return File(zipStream, "application/zip", zipFileName); + }catch(Exception ex){ + return BadRequest(ex.Message); + } + } + } +} \ No newline at end of file diff --git a/Models/Reportes/RptPedimentosPagadosAEO.cs b/Models/Reportes/RptPedimentosPagadosAEO.cs new file mode 100644 index 0000000..f538fb6 --- /dev/null +++ b/Models/Reportes/RptPedimentosPagadosAEO.cs @@ -0,0 +1,11 @@ +namespace GEMCO.Backend.Models.Reportes +{ + public class RptPedimentosPagadosAEO + { + public string Referencia { set; get; } = null!; + public int Aduana { get; set; } = 0; + public int Patente { get; set; } = 0; + public int Pedimento { get; set; } = 0; + public string FechaPago { set; get; } = null!; + } +} diff --git a/Program.cs b/Program.cs index 1304b84..c33a083 100644 --- a/Program.cs +++ b/Program.cs @@ -52,6 +52,8 @@ using CORRESPONSALBackend.Repository.Reportes.CuentasCerradas; using CORRESPONSALBackend.Services.Reportes.CuentasCerradas; using CORRESPONSALBackend.Contracts.Reportes; using CORRESPONSALBackend.Services.Reportes; +using CORRESPONSALBackend.Contracts.ArchivoElectronico; +using CORRESPONSALBackend.Services; var builder = WebApplication.CreateBuilder(args); @@ -92,6 +94,9 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); //Clientes builder.Services.AddScoped(); @@ -112,7 +117,6 @@ builder.Services.AddScoped( builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); -builder.Services.AddScoped(); //Utilerias builder.Services.AddScoped(); diff --git a/Repository/ArchivoElectronicoRepository.cs b/Repository/ArchivoElectronicoRepository.cs new file mode 100644 index 0000000..fdd84d4 --- /dev/null +++ b/Repository/ArchivoElectronicoRepository.cs @@ -0,0 +1,31 @@ +using System.Data; +using CORRESPONSALBackend.Context; +using CORRESPONSALBackend.Contracts.ArchivoElectronico; +using CORRESPONSALBackend.DTO.ArchivoElectronico; +using Dapper; +using GEMCO.Backend.Models.Reportes; + +namespace CORRESPONSALBackend.Repository{ + public class ArchivoElectronicoRepository : IArchivoElectronicoRepository + { + private readonly DapperContext _context; + public ArchivoElectronicoRepository(DapperContext context) { _context = context; } + public async Task> getRptPedimentoPagadosAEO(DTOAEPeriodo data) + { + var query = "getRptArchivoElectronicoOficial"; + using (var connection = _context.CreateConnection()) + { + var entrada = await connection.QueryAsync(query, + new + { + @Anio = data.Anio, + @Mes = data.Mes, + @NoCliente = data.NoCliente, + @TipoOperacion = data.TipoOperacion + }, + commandType: CommandType.StoredProcedure); + return entrada.ToList(); + } + } + } +} \ No newline at end of file diff --git a/Repository/Utils/FileManagerRepository.cs b/Repository/Utils/FileManagerRepository.cs index 4248a94..9a7b861 100644 --- a/Repository/Utils/FileManagerRepository.cs +++ b/Repository/Utils/FileManagerRepository.cs @@ -122,5 +122,16 @@ namespace CORRESPONSALBackend.Repository.Utils commandType: CommandType.StoredProcedure); return entrada.FirstOrDefault(); } + + public async Task> GetTraficoFiles(int idTrafico){ + string query = "[Utils.FileManager.GetTraficoFiles]"; + using var connection = _context.CreateConnection(); + var entrada = await connection.QueryAsync(query, new + { + @idtrafico = idTrafico + }, + commandType: CommandType.StoredProcedure); + return entrada.ToList(); + } } } \ No newline at end of file diff --git a/Services/ArchivoElectronicoService.cs b/Services/ArchivoElectronicoService.cs new file mode 100644 index 0000000..bc4cafb --- /dev/null +++ b/Services/ArchivoElectronicoService.cs @@ -0,0 +1,7 @@ +using CORRESPONSALBackend.Contracts.ArchivoElectronico; + +namespace CORRESPONSALBackend.Services{ + public class ArchivoElectronicoService : IArchivoElectronicoService{ + + } +} \ No newline at end of file