From 1c84a87f11316032c93c002a2f1e97a44f25645a Mon Sep 17 00:00:00 2001 From: Jorge Luis caudillo esparza Date: Tue, 18 Aug 2026 17:20:44 -0700 Subject: [PATCH] Gis parte 2 --- SIG.Web/App_Code/Configuration/AppServices.cs | 9 + .../IFraccionamientoGisFileStore.cs | 1 + .../IFraccionamientoGisService.cs | 29 + .../FraccionamientoGisHandler.cs | 361 +++++++- .../FraccionamientoGisModels.cs | 37 + .../Bitacora/BitacoraRepository.cs | 15 +- .../Repositories/Database/RepositoryBase.cs | 116 ++- .../Documentos/ClienteDocumentoRepository.cs | 42 +- .../Facturacion/CfdiRepository.cs | 95 +- .../FraccionamientoRepository.cs | 85 +- .../General/GeneralCatalogRepository.cs | 60 +- .../Repositories/Menu/MenuRepository.cs | 45 +- .../Security/LoginAttemptRepository.cs | 65 +- .../Security/PermissionRepository.cs | 42 +- .../Security/UserAdministrationRepository.cs | 97 +- .../Repositories/Security/UserRepository.cs | 83 +- .../Security/UserSessionRepository.cs | 85 +- .../Tramites/TramiteCatalogRepository.cs | 126 +-- .../FraccionamientoGisFileStore.cs | 57 +- .../FraccionamientoGisService.cs | 439 ++++++++++ .../FraccionamientoDetalle.aspx | 86 +- .../FraccionamientoDetalle.aspx.cs | 168 ++-- .../FraccionamientoDetalle.aspx.designer.cs | 8 +- SIG.Web/Scripts/custom.js | 154 +++- SIG.Web/Scripts/fraccionamiento-gis.js | 826 +++++++++++++----- SIG.Web/Styles/fraccionamiento-gis.css | 150 +++- SIG.Web/proyecto.zip | Bin 1010632 -> 0 bytes 27 files changed, 2265 insertions(+), 1016 deletions(-) create mode 100644 SIG.Web/App_Code/Contracts/Fraccionamientos/IFraccionamientoGisService.cs create mode 100644 SIG.Web/App_Code/Services/Fraccionamientos/FraccionamientoGisService.cs delete mode 100644 SIG.Web/proyecto.zip diff --git a/SIG.Web/App_Code/Configuration/AppServices.cs b/SIG.Web/App_Code/Configuration/AppServices.cs index 677725e..7641dfc 100644 --- a/SIG.Web/App_Code/Configuration/AppServices.cs +++ b/SIG.Web/App_Code/Configuration/AppServices.cs @@ -46,6 +46,7 @@ namespace SIG.Web.AppCode.Configuration public static IGeneralCatalogRepository GeneralCatalogRepository { get; private set; } public static IClienteDocumentoService ClienteDocumentoService { get; private set; } public static IFraccionamientoService FraccionamientoService { get; private set; } + public static IFraccionamientoGisService FraccionamientoGisService { get; private set; } public static ITramiteCatalogService TramiteCatalogService { get; private set; } public static ICfdiTimbradoService CfdiTimbradoService { get; private set; } public static IPublicRegistrationService PublicRegistrationService { get; private set; } @@ -92,6 +93,14 @@ namespace SIG.Web.AppCode.Configuration FraccionamientoService = new FraccionamientoService( new FraccionamientoRepository(DbExecutor), BitacoraService); + + IFraccionamientoGisRepository gisRepository = + new FraccionamientoGisRepository(DbExecutor); + IFraccionamientoGisFileStore gisFileStore = + new FraccionamientoGisFileStore(); + FraccionamientoGisService = new FraccionamientoGisService( + gisRepository, + gisFileStore); TramiteCatalogService = new TramiteCatalogService( new TramiteCatalogRepository(DbExecutor), BitacoraService); diff --git a/SIG.Web/App_Code/Contracts/Fraccionamientos/IFraccionamientoGisFileStore.cs b/SIG.Web/App_Code/Contracts/Fraccionamientos/IFraccionamientoGisFileStore.cs index 0923212..b7b16cc 100644 --- a/SIG.Web/App_Code/Contracts/Fraccionamientos/IFraccionamientoGisFileStore.cs +++ b/SIG.Web/App_Code/Contracts/Fraccionamientos/IFraccionamientoGisFileStore.cs @@ -9,5 +9,6 @@ namespace SIG.Web.AppCode.Contracts.Fraccionamientos bool Exists(FraccionamientoGisContextModel context); void Save(FraccionamientoGisContextModel context, Stream source); Stream OpenRead(FraccionamientoGisContextModel context); + void Delete(FraccionamientoGisContextModel context); } } diff --git a/SIG.Web/App_Code/Contracts/Fraccionamientos/IFraccionamientoGisService.cs b/SIG.Web/App_Code/Contracts/Fraccionamientos/IFraccionamientoGisService.cs new file mode 100644 index 0000000..7c00f7c --- /dev/null +++ b/SIG.Web/App_Code/Contracts/Fraccionamientos/IFraccionamientoGisService.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using System.IO; +using SIG.Web.AppCode.Models.Common; +using SIG.Web.AppCode.Models.Fraccionamientos; + +namespace SIG.Web.AppCode.Contracts.Fraccionamientos +{ + public interface IFraccionamientoGisService + { + DbResult Get( + int stageId, + int executingUser, + string domainName); + + DbResult Save( + int stageId, + string originalFileName, + Stream content, + long contentLength, + IList links, + int executingUser, + string domainName); + + DbResult OpenFile( + int stageId, + int executingUser, + string domainName); + } +} diff --git a/SIG.Web/App_Code/Handlers/Fraccionamientos/FraccionamientoGisHandler.cs b/SIG.Web/App_Code/Handlers/Fraccionamientos/FraccionamientoGisHandler.cs index dc4e703..42e659f 100644 --- a/SIG.Web/App_Code/Handlers/Fraccionamientos/FraccionamientoGisHandler.cs +++ b/SIG.Web/App_Code/Handlers/Fraccionamientos/FraccionamientoGisHandler.cs @@ -1,78 +1,387 @@ using System; +using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Web; +using System.Web.Script.Serialization; using System.Web.SessionState; using SIG.Web.AppCode.Configuration; using SIG.Web.AppCode.Models.Common; -using SIG.Web.AppCode.Models.Documentos; +using SIG.Web.AppCode.Models.Fraccionamientos; +using SIG.Web.AppCode.Services.Errors; using SIG.Web.AppCode.Session; namespace SIG.Web.Pages.Fraccionamientos { public sealed class FraccionamientoGisHandler : IHttpHandler, IRequiresSessionState { + private static readonly JavaScriptSerializer Json = + new JavaScriptSerializer + { + MaxJsonLength = 4 * 1024 * 1024 + }; + public bool IsReusable { - get - { - return false; - } + get { return false; } } public void ProcessRequest(HttpContext context) { - if (!AppServices.UserContext.IsAuthenticated()) + try { - context.Response.StatusCode = 401; + UserSessionModel currentUser = GetCurrentUser(context); + if (currentUser == null) + { + WriteJson( + context, + 401, + new + { + success = false, + message = "Su sesión no está disponible. Inicie sesión nuevamente.", + codigo = string.Empty + }); + return; + } + + string method = (context.Request["metodo"] ?? string.Empty) + .Trim(); + + if (string.Equals( + context.Request.HttpMethod, + "POST", + StringComparison.OrdinalIgnoreCase)) + { + if (!string.Equals(method, "Save", StringComparison.OrdinalIgnoreCase)) + { + WriteJson( + context, + 405, + new + { + success = false, + message = "La operación GIS solicitada no es válida.", + codigo = string.Empty + }); + return; + } + + Save(context, currentUser); + return; + } + + int stageId; + if (!TryGetStageId(context, out stageId)) + { + WriteJson( + context, + 400, + new + { + success = false, + message = "Seleccione una etapa válida.", + codigo = string.Empty + }); + return; + } + + if (string.Equals(method, "Context", StringComparison.OrdinalIgnoreCase)) + { + GetContext(context, currentUser, stageId); + return; + } + + if (string.IsNullOrWhiteSpace(method) || + string.Equals(method, "File", StringComparison.OrdinalIgnoreCase)) + { + OpenFile(context, currentUser, stageId); + return; + } + + WriteJson( + context, + 405, + new + { + success = false, + message = "La operación GIS solicitada no es válida.", + codigo = string.Empty + }); + } + catch (Exception ex) + { + WriteUnexpectedError(context, ex); + } + } + + private static UserSessionModel GetCurrentUser(HttpContext context) + { + if (AppServices.UserContext == null || + !AppServices.UserContext.IsAuthenticated()) + { + return null; + } + + return AppServices.UserContext.GetCurrentUser(); + } + + private static void GetContext( + HttpContext context, + UserSessionModel currentUser, + int stageId) + { + DbResult result = + AppServices.FraccionamientoGisService.Get( + stageId, + currentUser.CveUsuario, + currentUser.NombreDominio); + + if (!result.Success || result.Data == null) + { + WriteResultFailure(context, result, 400); return; } + WriteJson( + context, + 200, + new + { + success = true, + message = string.Empty, + data = result.Data + }); + } + + private static void Save( + HttpContext context, + UserSessionModel currentUser) + { int stageId; - - if (!int.TryParse( - context.Request.QueryString["etapa"], - out stageId) || - stageId <= 0) + if (!TryGetStageId(context, out stageId)) { - context.Response.StatusCode = 400; + WriteJson( + context, + 400, + new + { + success = false, + message = "Seleccione una etapa válida.", + codigo = string.Empty + }); return; } - UserSessionModel currentUser = - AppServices.UserContext.GetCurrentUser(); + IList links; + string linksJson = context.Request.Form["vinculos"]; - if (currentUser == null) + try { - context.Response.StatusCode = 401; + links = string.IsNullOrWhiteSpace(linksJson) + ? new List() + : Json.Deserialize>( + linksJson); + } + catch (Exception) + { + WriteJson( + context, + 400, + new + { + success = false, + message = "Los vínculos GIS enviados no tienen un formato válido.", + codigo = string.Empty + }); return; } - DbResult result = - AppServices.ClienteDocumentoService.GetStageGis( + HttpPostedFile postedFile = context.Request.Files["archivo"]; + Stream content = postedFile != null + ? postedFile.InputStream + : null; + long contentLength = postedFile != null + ? postedFile.ContentLength + : 0L; + string originalFileName = postedFile != null + ? Path.GetFileName(postedFile.FileName) + : string.Empty; + + DbResult result = + AppServices.FraccionamientoGisService.Save( + stageId, + originalFileName, + content, + contentLength, + links, + currentUser.CveUsuario, + currentUser.NombreDominio); + + if (!result.Success) + { + WriteResultFailure(context, result, 400); + return; + } + + WriteJson( + context, + 200, + new + { + success = true, + message = "GIS y vínculos guardados correctamente.", + data = result.Data + }); + } + + private static void OpenFile( + HttpContext context, + UserSessionModel currentUser, + int stageId) + { + DbResult result = + AppServices.FraccionamientoGisService.OpenFile( stageId, currentUser.CveUsuario, currentUser.NombreDominio); if (!result.Success || result.Data == null || - string.IsNullOrWhiteSpace(result.Data.RutaFisica) || - !File.Exists(result.Data.RutaFisica)) + result.Data.Content == null) { - context.Response.StatusCode = 404; + WriteResultFailure(context, result, 404); return; } - ClienteDocumentoArchivoModel file = result.Data; + FraccionamientoGisFileModel file = result.Data; context.Response.Clear(); + context.Response.ClearHeaders(); + context.Response.TrySkipIisCustomErrors = true; context.Response.Cache.SetCacheability(HttpCacheability.NoCache); context.Response.Cache.SetNoStore(); - context.Response.ContentType = file.ContentType; + context.Response.ContentType = string.IsNullOrWhiteSpace(file.ContentType) + ? "application/octet-stream" + : file.ContentType; + + bool download = string.Equals( + context.Request.QueryString["download"], + "1", + StringComparison.Ordinal); + context.Response.AddHeader( "Content-Disposition", - "attachment; filename=\"" + file.NombreArchivo + "\""); - context.Response.TransmitFile(file.RutaFisica); + (download ? "attachment" : "inline") + + "; filename=\"" + + SanitizeHeaderFileName(file.NombreArchivo) + + "\""); + + using (file.Content) + { + file.Content.CopyTo(context.Response.OutputStream); + } + context.ApplicationInstance.CompleteRequest(); } + + private static bool TryGetStageId( + HttpContext context, + out int stageId) + { + string value = context.Request["CveFraccionamientoEtapa"]; + + if (string.IsNullOrWhiteSpace(value)) + { + value = context.Request.QueryString["etapa"]; + } + + return int.TryParse( + value, + NumberStyles.Integer, + CultureInfo.InvariantCulture, + out stageId) && + stageId > 0; + } + + private static void WriteResultFailure( + HttpContext context, + DbResult result, + int statusCode) + { + string message = result == null || + string.IsNullOrWhiteSpace(result.UserMessage) + ? "No fue posible completar la operación GIS." + : result.UserMessage; + + WriteJson( + context, + statusCode, + new + { + success = false, + message = message, + codigo = string.Empty + }); + } + + private static void WriteUnexpectedError( + HttpContext context, + Exception exception) + { + string cveUsuario; + string nombreUsuario; + int cveRol; + + SIGErrorManager.ObtenerUsuarioActual( + out cveUsuario, + out nombreUsuario, + out cveRol); + + string code = SIGErrorManager.Registrar( + exception, + context, + "FraccionamientoGisHandler", + cveUsuario, + nombreUsuario); + + WriteJson( + context, + 500, + new + { + success = false, + message = ErrorHandlerConfig.GetFriendlyMessage(exception), + codigo = code + }); + } + + private static void WriteJson( + HttpContext context, + int statusCode, + object value) + { + context.Response.Clear(); + context.Response.ClearHeaders(); + context.Response.StatusCode = statusCode; + context.Response.TrySkipIisCustomErrors = true; + context.Response.ContentType = "application/json; charset=utf-8"; + context.Response.Cache.SetCacheability(HttpCacheability.NoCache); + context.Response.Cache.SetNoStore(); + context.Response.Write(Json.Serialize(value)); + context.ApplicationInstance.CompleteRequest(); + } + + private static string SanitizeHeaderFileName(string fileName) + { + string safeName = string.IsNullOrWhiteSpace(fileName) + ? "archivo.gis" + : Path.GetFileName(fileName); + + return safeName + .Replace("\"", string.Empty) + .Replace("\r", string.Empty) + .Replace("\n", string.Empty); + } } } diff --git a/SIG.Web/App_Code/Models/Fraccionamientos/FraccionamientoGisModels.cs b/SIG.Web/App_Code/Models/Fraccionamientos/FraccionamientoGisModels.cs index 00f533e..534cd7b 100644 --- a/SIG.Web/App_Code/Models/Fraccionamientos/FraccionamientoGisModels.cs +++ b/SIG.Web/App_Code/Models/Fraccionamientos/FraccionamientoGisModels.cs @@ -1,3 +1,7 @@ +using System; +using System.Collections.Generic; +using System.IO; + namespace SIG.Web.AppCode.Models.Fraccionamientos { public sealed class FraccionamientoGisContextModel @@ -13,7 +17,40 @@ namespace SIG.Web.AppCode.Models.Fraccionamientos { public int CveFraccionamientoLote { get; set; } public string Nombre { get; set; } + public string Etapa { get; set; } + public string Numero { get; set; } + public string Tipo { get; set; } + public string Calle { get; set; } + public string Catastro { get; set; } + public decimal? MetrosCuadrados { get; set; } + public string Duplicador { get; set; } public string GISPoligonoClave { get; set; } public bool EsActivo { get; set; } } + + public sealed class FraccionamientoGisViewModel + { + public FraccionamientoGisContextModel Contexto { get; set; } + public List Lotes { get; set; } + public bool TieneArchivo { get; set; } + public string NombreArchivo { get; set; } + public DateTime? FechaArchivo { get; set; } + } + + public sealed class FraccionamientoGisSaveResultModel + { + public int CveFraccionamientoEtapa { get; set; } + public int VinculosGuardados { get; set; } + public bool ArchivoGuardado { get; set; } + public bool TieneArchivo { get; set; } + public string NombreArchivo { get; set; } + public DateTime? FechaArchivo { get; set; } + } + + public sealed class FraccionamientoGisFileModel + { + public string NombreArchivo { get; set; } + public string ContentType { get; set; } + public Stream Content { get; set; } + } } diff --git a/SIG.Web/App_Code/Repositories/Bitacora/BitacoraRepository.cs b/SIG.Web/App_Code/Repositories/Bitacora/BitacoraRepository.cs index 6e05115..a3611a6 100644 --- a/SIG.Web/App_Code/Repositories/Bitacora/BitacoraRepository.cs +++ b/SIG.Web/App_Code/Repositories/Bitacora/BitacoraRepository.cs @@ -13,21 +13,20 @@ using SIG.Web.AppCode.Utilities; namespace SIG.Web.AppCode.Repositories.Bitacora { - public sealed class BitacoraRepository : IBitacoraRepository + public sealed class BitacoraRepository + : RepositoryBase, IBitacoraRepository { private const string BitacoraDomain = "Bitacora"; - private readonly IDbExecutor _dbExecutor; - public BitacoraRepository(IDbExecutor dbExecutor) + : base(dbExecutor) { - _dbExecutor = dbExecutor; } public DbResult Agregar( BitacoraEventoModel evento, BitacoraContextoModel contexto) { - return _dbExecutor.Execute(BitacoraDomain, connection => + return ExecuteCustom(BitacoraDomain, connection => { using (IDbCommand command = connection.CreateCommand()) { @@ -121,7 +120,7 @@ namespace SIG.Web.AppCode.Repositories.Bitacora BitacoraFiltroModel filtro, int cveUsuarioEjecuta) { - return _dbExecutor.Execute(BitacoraDomain, connection => + return ExecuteCustom(BitacoraDomain, connection => { using (IDbCommand command = connection.CreateCommand()) { @@ -181,7 +180,7 @@ namespace SIG.Web.AppCode.Repositories.Bitacora int registrosOmitidos = checked( (consulta.Pagina - 1) * consulta.RegistrosPorPagina); - return _dbExecutor.Execute(BitacoraDomain, connection => + return ExecuteCustom(BitacoraDomain, connection => { using (IDbCommand command = connection.CreateCommand()) { @@ -275,7 +274,7 @@ namespace SIG.Web.AppCode.Repositories.Bitacora int registrosOmitidos = checked( (consulta.Pagina - 1) * consulta.RegistrosPorPagina); - return _dbExecutor.Execute(BitacoraDomain, connection => + return ExecuteCustom(BitacoraDomain, connection => { using (IDbCommand command = connection.CreateCommand()) { diff --git a/SIG.Web/App_Code/Repositories/Database/RepositoryBase.cs b/SIG.Web/App_Code/Repositories/Database/RepositoryBase.cs index 7535f42..7024fc1 100644 --- a/SIG.Web/App_Code/Repositories/Database/RepositoryBase.cs +++ b/SIG.Web/App_Code/Repositories/Database/RepositoryBase.cs @@ -21,13 +21,30 @@ namespace SIG.Web.AppCode.Repositories.Database _db = db; } - protected DbResult> QueryList( + protected DbResult ExecuteCustom( + string domain, + Func action) + { + if (action == null) + { + throw new ArgumentNullException("action"); + } + + return _db.Execute(domain, action); + } + + protected DbResult QueryReader( string procedure, int user, string domain, - Action parameters) - where T : class, new() + Action parameters, + Func readerMapper) { + if (readerMapper == null) + { + throw new ArgumentNullException("readerMapper"); + } + return _db.Execute(domain, connection => { using (IDbCommand command = connection.CreateCommand()) @@ -39,10 +56,11 @@ namespace SIG.Web.AppCode.Repositories.Database parameters(command); } - List value; + TResult value; + using (IDataReader reader = command.ExecuteReader()) { - value = reader.ToList(); + value = readerMapper(reader); } StoredProcedureCommand.EnsureSuccess(command); @@ -51,6 +69,21 @@ namespace SIG.Web.AppCode.Repositories.Database }); } + protected DbResult> QueryList( + string procedure, + int user, + string domain, + Action parameters) + where T : class, new() + { + return QueryReader( + procedure, + user, + domain, + parameters, + reader => reader.ToList()); + } + protected DbResult QueryOne( string procedure, int user, @@ -58,27 +91,12 @@ namespace SIG.Web.AppCode.Repositories.Database Action parameters) where T : class, new() { - return _db.Execute(domain, connection => - { - using (IDbCommand command = connection.CreateCommand()) - { - StoredProcedureCommand.Configure(command, procedure, user); - - if (parameters != null) - { - parameters(command); - } - - T value; - using (IDataReader reader = command.ExecuteReader()) - { - value = reader.ToObject(); - } - - StoredProcedureCommand.EnsureSuccess(command); - return value; - } - }); + return QueryReader( + procedure, + user, + domain, + parameters, + reader => reader.ToObject()); } protected DbResult QueryScalarId( @@ -86,6 +104,38 @@ namespace SIG.Web.AppCode.Repositories.Database int user, string domain, Action parameters) + { + return QueryReader( + procedure, + user, + domain, + parameters, + reader => reader.Read() + ? Convert.ToInt32(reader.GetValue(0)) + : 0); + } + + protected DbResult QueryScalarLong( + string procedure, + int user, + string domain, + Action parameters) + { + return QueryReader( + procedure, + user, + domain, + parameters, + reader => reader.Read() + ? Convert.ToInt64(reader.GetValue(0)) + : 0L); + } + + protected DbResult QueryScalarBool( + string procedure, + int user, + string domain, + Action parameters) { return _db.Execute(domain, connection => { @@ -98,16 +148,12 @@ namespace SIG.Web.AppCode.Repositories.Database parameters(command); } - int value; - using (IDataReader reader = command.ExecuteReader()) - { - value = reader.Read() - ? Convert.ToInt32(reader.GetValue(0)) - : 0; - } - + object value = command.ExecuteScalar(); StoredProcedureCommand.EnsureSuccess(command); - return value; + + return value != null && + value != DBNull.Value && + Convert.ToBoolean(value); } }); } diff --git a/SIG.Web/App_Code/Repositories/Documentos/ClienteDocumentoRepository.cs b/SIG.Web/App_Code/Repositories/Documentos/ClienteDocumentoRepository.cs index e85969f..48bc0a3 100644 --- a/SIG.Web/App_Code/Repositories/Documentos/ClienteDocumentoRepository.cs +++ b/SIG.Web/App_Code/Repositories/Documentos/ClienteDocumentoRepository.cs @@ -4,17 +4,15 @@ using SIG.Web.AppCode.Contracts.Documentos; using SIG.Web.AppCode.Models.Common; using SIG.Web.AppCode.Models.Documentos; using SIG.Web.AppCode.Repositories.Database; -using SIG.Web.AppCode.Utilities; namespace SIG.Web.AppCode.Repositories.Documentos { - public sealed class ClienteDocumentoRepository : IClienteDocumentoRepository + public sealed class ClienteDocumentoRepository + : RepositoryBase, IClienteDocumentoRepository { - private readonly IDbExecutor _db; - public ClienteDocumentoRepository(IDbExecutor db) + : base(db) { - _db = db; } public DbResult GetStageContext( @@ -22,31 +20,15 @@ namespace SIG.Web.AppCode.Repositories.Documentos int executingUser, string domainName) { - return _db.Execute(domainName, connection => - { - using (IDbCommand command = connection.CreateCommand()) - { - StoredProcedureCommand.Configure( - command, - "dbo.PA_Fraccionamientos_EtapaDocumentoGet", - executingUser); - StoredProcedureCommand.AddInput( - command, - "@CveFraccionamientoEtapa", - stageId, - DbType.Int32); - - ClienteDocumentoEtapaContextoModel value; - - using (IDataReader reader = command.ExecuteReader()) - { - value = reader.ToObject(); - } - - StoredProcedureCommand.EnsureSuccess(command); - return value; - } - }); + return QueryOne( + "dbo.PA_Fraccionamientos_EtapaDocumentoGet", + executingUser, + domainName, + command => StoredProcedureCommand.AddInput( + command, + "@CveFraccionamientoEtapa", + stageId, + DbType.Int32)); } } } diff --git a/SIG.Web/App_Code/Repositories/Facturacion/CfdiRepository.cs b/SIG.Web/App_Code/Repositories/Facturacion/CfdiRepository.cs index 011ec90..7340b79 100644 --- a/SIG.Web/App_Code/Repositories/Facturacion/CfdiRepository.cs +++ b/SIG.Web/App_Code/Repositories/Facturacion/CfdiRepository.cs @@ -11,13 +11,12 @@ using SIG.Web.AppCode.Utilities; namespace SIG.Web.AppCode.Repositories.Facturacion { - public sealed class CfdiRepository : ICfdiRepository + public sealed class CfdiRepository + : RepositoryBase, ICfdiRepository { - private readonly IDbExecutor _db; - public CfdiRepository(IDbExecutor db) + : base(db) { - _db = db; } public DbResult ObtenerEmisor( @@ -442,94 +441,6 @@ namespace SIG.Web.AppCode.Repositories.Facturacion }); } - private DbResult> QueryList( - string procedure, - int user, - string domain, - Action parameters) - where T : class, new() - { - return _db.Execute(domain, connection => - { - using (IDbCommand command = connection.CreateCommand()) - { - StoredProcedureCommand.Configure( - command, - procedure, - user); - parameters?.Invoke(command); - - List value; - using (IDataReader reader = command.ExecuteReader()) - { - value = reader.ToList(); - } - - StoredProcedureCommand.EnsureSuccess(command); - return value; - } - }); - } - - private DbResult QueryOne( - string procedure, - int user, - string domain, - Action parameters) - where T : class, new() - { - return _db.Execute(domain, connection => - { - using (IDbCommand command = connection.CreateCommand()) - { - StoredProcedureCommand.Configure( - command, - procedure, - user); - parameters?.Invoke(command); - - T value; - using (IDataReader reader = command.ExecuteReader()) - { - value = reader.ToObject(); - } - - StoredProcedureCommand.EnsureSuccess(command); - return value; - } - }); - } - - private DbResult QueryScalarLong( - string procedure, - int user, - string domain, - Action parameters) - { - return _db.Execute(domain, connection => - { - using (IDbCommand command = connection.CreateCommand()) - { - StoredProcedureCommand.Configure( - command, - procedure, - user); - parameters(command); - - long value; - using (IDataReader reader = command.ExecuteReader()) - { - value = reader.Read() - ? Convert.ToInt64(reader.GetValue(0)) - : 0L; - } - - StoredProcedureCommand.EnsureSuccess(command); - return value; - } - }); - } - private static void Add( IDbCommand command, string name, diff --git a/SIG.Web/App_Code/Repositories/Fraccionamientos/FraccionamientoRepository.cs b/SIG.Web/App_Code/Repositories/Fraccionamientos/FraccionamientoRepository.cs index 569cfb8..5279c7d 100644 --- a/SIG.Web/App_Code/Repositories/Fraccionamientos/FraccionamientoRepository.cs +++ b/SIG.Web/App_Code/Repositories/Fraccionamientos/FraccionamientoRepository.cs @@ -13,13 +13,12 @@ using SIG.Web.AppCode.Utilities; namespace SIG.Web.AppCode.Repositories.Fraccionamientos { - public sealed class FraccionamientoRepository : IFraccionamientoRepository + public sealed class FraccionamientoRepository + : RepositoryBase, IFraccionamientoRepository { - private readonly IDbExecutor _db; - public FraccionamientoRepository(IDbExecutor db) + : base(db) { - _db = db; } public DbResult> ListClients(int executingUser, string domainName) @@ -450,83 +449,5 @@ namespace SIG.Web.AppCode.Repositories.Fraccionamientos DbType.Int32); }); } - - private DbResult> QueryList( - string procedure, int user, string domain, Action parameters) - where T : class, new() - { - return _db.Execute(domain, connection => - { - using (IDbCommand command = connection.CreateCommand()) - { - StoredProcedureCommand.Configure(command, procedure, user); - if (parameters != null) parameters(command); - List value; - using (IDataReader reader = command.ExecuteReader()) - { - value = reader.ToList(); - } - StoredProcedureCommand.EnsureSuccess(command); - return value; - } - }); - } - - private DbResult QueryOne( - string procedure, int user, string domain, Action parameters) - where T : class, new() - { - return _db.Execute(domain, connection => - { - using (IDbCommand command = connection.CreateCommand()) - { - StoredProcedureCommand.Configure(command, procedure, user); - if (parameters != null) parameters(command); - T value; - using (IDataReader reader = command.ExecuteReader()) - { - value = reader.ToObject(); - } - StoredProcedureCommand.EnsureSuccess(command); - return value; - } - }); - } - - private DbResult QueryScalarId( - string procedure, int user, string domain, Action parameters) - { - return _db.Execute(domain, connection => - { - using (IDbCommand command = connection.CreateCommand()) - { - StoredProcedureCommand.Configure(command, procedure, user); - parameters(command); - int value; - using (IDataReader reader = command.ExecuteReader()) - { - value = reader.Read() ? Convert.ToInt32(reader.GetValue(0)) : 0; - } - StoredProcedureCommand.EnsureSuccess(command); - return value; - } - }); - } - - private DbResult Execute( - string procedure, int user, string domain, Action parameters) - { - return _db.Execute(domain, connection => - { - using (IDbCommand command = connection.CreateCommand()) - { - StoredProcedureCommand.Configure(command, procedure, user); - parameters(command); - command.ExecuteNonQuery(); - StoredProcedureCommand.EnsureSuccess(command); - return true; - } - }); - } } } diff --git a/SIG.Web/App_Code/Repositories/General/GeneralCatalogRepository.cs b/SIG.Web/App_Code/Repositories/General/GeneralCatalogRepository.cs index 258c659..0e93aed 100644 --- a/SIG.Web/App_Code/Repositories/General/GeneralCatalogRepository.cs +++ b/SIG.Web/App_Code/Repositories/General/GeneralCatalogRepository.cs @@ -9,61 +9,49 @@ using SIG.Web.AppCode.Utilities; namespace SIG.Web.AppCode.Repositories.General { - public sealed class GeneralCatalogRepository : IGeneralCatalogRepository + public sealed class GeneralCatalogRepository + : RepositoryBase, IGeneralCatalogRepository { - private readonly IDbExecutor _dbExecutor; - public GeneralCatalogRepository(IDbExecutor dbExecutor) + : base(dbExecutor) { - _dbExecutor = dbExecutor; } public DbResult> ListStates(string domainName) { - return _dbExecutor.Execute(domainName, connection => - { - using (IDbCommand command = connection.CreateCommand()) - { - StoredProcedureCommand.Configure(command, "dbo.PA_Gral_EstadoList", 0); - - List states; - using (IDataReader reader = command.ExecuteReader()) - { - states = reader.ToList(); - } - - StoredProcedureCommand.EnsureSuccess(command); - return states; - } - }); + return QueryList( + "dbo.PA_Gral_EstadoList", + 0, + domainName, + null); } public DbResult GetPostalCode( string postalCode, string domainName) { - return _dbExecutor.Execute(domainName, connection => - { - using (IDbCommand command = connection.CreateCommand()) + return QueryReader( + "dbo.PA_Gral_CodigoPostalGet", + 0, + domainName, + command => StoredProcedureCommand.AddInput( + command, + "@CP", + postalCode, + DbType.String), + reader => { - StoredProcedureCommand.Configure(command, "dbo.PA_Gral_CodigoPostalGet", 0); - StoredProcedureCommand.AddInput(command, "@CP", postalCode, DbType.String); + PostalCodeLookupModel value = + reader.ToObject(); - PostalCodeLookupModel value; - using (IDataReader reader = command.ExecuteReader()) + if (value != null && reader.NextResult()) { - value = reader.ToObject(); - - if (value != null && reader.NextResult()) - { - value.Colonias = reader.ToList(); - } + value.Colonias = + reader.ToList(); } - StoredProcedureCommand.EnsureSuccess(command); return value; - } - }); + }); } } } diff --git a/SIG.Web/App_Code/Repositories/Menu/MenuRepository.cs b/SIG.Web/App_Code/Repositories/Menu/MenuRepository.cs index 154212b..f74adea 100644 --- a/SIG.Web/App_Code/Repositories/Menu/MenuRepository.cs +++ b/SIG.Web/App_Code/Repositories/Menu/MenuRepository.cs @@ -5,50 +5,29 @@ using SIG.Web.AppCode.Contracts.Menu; using SIG.Web.AppCode.Models.Common; using SIG.Web.AppCode.Repositories.Database; using SIG.Web.AppCode.Session; -using SIG.Web.AppCode.Utilities; namespace SIG.Web.AppCode.Repositories.Menu { - public sealed class MenuRepository : IMenuRepository + public sealed class MenuRepository + : RepositoryBase, IMenuRepository { - private readonly IDbExecutor _dbExecutor; - public MenuRepository(IDbExecutor dbExecutor) + : base(dbExecutor) { - _dbExecutor = dbExecutor; } public DbResult> ListModules( UserSessionModel user) { - return _dbExecutor.Execute( + return QueryList( + "dbo.PA_Sis_MenuList", + user.CveUsuario, user.NombreDominio, - connection => - { - using (IDbCommand command = connection.CreateCommand()) - { - StoredProcedureCommand.Configure( - command, - "dbo.PA_Sis_MenuList", - user.CveUsuario); - - StoredProcedureCommand.AddInput( - command, - "@CveRol", - user.CveRol, - DbType.Int32); - - List items; - - using (IDataReader reader = command.ExecuteReader()) - { - items = reader.ToList(); - } - - StoredProcedureCommand.EnsureSuccess(command); - return items; - } - }); + command => StoredProcedureCommand.AddInput( + command, + "@CveRol", + user.CveRol, + DbType.Int32)); } } -} \ No newline at end of file +} diff --git a/SIG.Web/App_Code/Repositories/Security/LoginAttemptRepository.cs b/SIG.Web/App_Code/Repositories/Security/LoginAttemptRepository.cs index 85acd35..a87b6aa 100644 --- a/SIG.Web/App_Code/Repositories/Security/LoginAttemptRepository.cs +++ b/SIG.Web/App_Code/Repositories/Security/LoginAttemptRepository.cs @@ -6,13 +6,12 @@ using SIG.Web.AppCode.Repositories.Database; namespace SIG.Web.AppCode.Repositories.Security { - public sealed class LoginAttemptRepository : ILoginAttemptRepository + public sealed class LoginAttemptRepository + : RepositoryBase, ILoginAttemptRepository { - private readonly IDbExecutor _dbExecutor; - public LoginAttemptRepository(IDbExecutor dbExecutor) + : base(dbExecutor) { - _dbExecutor = dbExecutor; } public DbResult Save( @@ -24,24 +23,48 @@ namespace SIG.Web.AppCode.Repositories.Security string userAgent, string domainName) { - return _dbExecutor.Execute(domainName, connection => - { - using (IDbCommand command = connection.CreateCommand()) + return Execute( + "dbo.PA_Sis_IntentoInicioSesionAdd", + cveUser ?? 0, + domainName, + command => { - StoredProcedureCommand.Configure(command, "dbo.PA_Sis_IntentoInicioSesionAdd", cveUser ?? 0); - StoredProcedureCommand.AddInput(command, "@CveUsuario", cveUser.HasValue ? (object)cveUser.Value : null, DbType.Int32); - StoredProcedureCommand.AddInput(command, "@NombreUsuario", username, DbType.String); - StoredProcedureCommand.AddInput(command, "@Exitoso", wasSuccessful, DbType.Boolean); - StoredProcedureCommand.AddInput(command, "@MotivoFallo", failureReason, DbType.String); - StoredProcedureCommand.AddInput(command, "@DireccionIP", ipAddress, DbType.String); - StoredProcedureCommand.AddInput(command, "@AgenteUsuario", userAgent, DbType.String); - StoredProcedureCommand.AddInput(command, "@NombreDominio", domainName, DbType.String); - - command.ExecuteNonQuery(); - StoredProcedureCommand.EnsureSuccess(command); - return true; - } - }); + StoredProcedureCommand.AddInput( + command, + "@CveUsuario", + cveUser.HasValue ? (object)cveUser.Value : null, + DbType.Int32); + StoredProcedureCommand.AddInput( + command, + "@NombreUsuario", + username, + DbType.String); + StoredProcedureCommand.AddInput( + command, + "@Exitoso", + wasSuccessful, + DbType.Boolean); + StoredProcedureCommand.AddInput( + command, + "@MotivoFallo", + failureReason, + DbType.String); + StoredProcedureCommand.AddInput( + command, + "@DireccionIP", + ipAddress, + DbType.String); + StoredProcedureCommand.AddInput( + command, + "@AgenteUsuario", + userAgent, + DbType.String); + StoredProcedureCommand.AddInput( + command, + "@NombreDominio", + domainName, + DbType.String); + }); } } } diff --git a/SIG.Web/App_Code/Repositories/Security/PermissionRepository.cs b/SIG.Web/App_Code/Repositories/Security/PermissionRepository.cs index 4a8bb60..2bf7877 100644 --- a/SIG.Web/App_Code/Repositories/Security/PermissionRepository.cs +++ b/SIG.Web/App_Code/Repositories/Security/PermissionRepository.cs @@ -1,4 +1,3 @@ -using System; using System.Data; using SIG.Web.AppCode.Contracts.Database; using SIG.Web.AppCode.Contracts.Security; @@ -7,22 +6,22 @@ using SIG.Web.AppCode.Repositories.Database; namespace SIG.Web.AppCode.Repositories.Security { - public sealed class PermissionRepository : IPermissionRepository + public sealed class PermissionRepository + : RepositoryBase, IPermissionRepository { - private readonly IDbExecutor _dbExecutor; - public PermissionRepository(IDbExecutor dbExecutor) + : base(dbExecutor) { - _dbExecutor = dbExecutor; } public DbResult HasPermission( int cveUser, string permissionCode) { - return ExecuteCheck( + return QueryScalarBool( "dbo.PA_Sis_PermisoCheck", cveUser, + null, command => StoredProcedureCommand.AddInput( command, "@CodigoPermiso", @@ -34,40 +33,15 @@ namespace SIG.Web.AppCode.Repositories.Security int cveUser, string normalizedPageUrl) { - return ExecuteCheck( + return QueryScalarBool( "dbo.PA_Sis_PaginaAccessCheck", cveUser, + null, command => StoredProcedureCommand.AddInput( command, "@PaginaUrl", normalizedPageUrl, DbType.String)); } - - private DbResult ExecuteCheck( - string procedureName, - int cveUser, - Action addParameters) - { - return _dbExecutor.Execute(null, connection => - { - using (IDbCommand command = connection.CreateCommand()) - { - StoredProcedureCommand.Configure( - command, - procedureName, - cveUser); - - addParameters(command); - - object value = command.ExecuteScalar(); - StoredProcedureCommand.EnsureSuccess(command); - - return value != null && - value != DBNull.Value && - Convert.ToBoolean(value); - } - }); - } } -} \ No newline at end of file +} diff --git a/SIG.Web/App_Code/Repositories/Security/UserAdministrationRepository.cs b/SIG.Web/App_Code/Repositories/Security/UserAdministrationRepository.cs index b677738..ee24b1c 100644 --- a/SIG.Web/App_Code/Repositories/Security/UserAdministrationRepository.cs +++ b/SIG.Web/App_Code/Repositories/Security/UserAdministrationRepository.cs @@ -9,12 +9,12 @@ using SIG.Web.AppCode.Utilities; namespace SIG.Web.AppCode.Repositories.Security { - public sealed class UserAdministrationRepository : IUserAdministrationRepository + public sealed class UserAdministrationRepository + : RepositoryBase, IUserAdministrationRepository { - private readonly IDbExecutor _db; public UserAdministrationRepository(IDbExecutor db) + : base(db) { - _db = db; } public DbResult> ListUsers(string text, int executingUser, string domainName) @@ -44,11 +44,12 @@ namespace SIG.Web.AppCode.Repositories.Security public DbResult SaveUser(UserAdministrationModel user, string passwordHash, int executingUser, string domainName) { - return _db.Execute(domainName, connection => - { - using (IDbCommand command = connection.CreateCommand()) + return QueryScalarId( + "dbo.PA_Sis_UsuarioSave", + executingUser, + domainName, + command => { - StoredProcedureCommand.Configure(command, "dbo.PA_Sis_UsuarioSave", executingUser); StoredProcedureCommand.AddInput(command, "@CveUsuario", user.CveUsuario <= 0 ? (object)null : user.CveUsuario, DbType.Int32); StoredProcedureCommand.AddInput(command, "@NombreUsuario", user.NombreUsuario, DbType.String); StoredProcedureCommand.AddInput(command, "@CorreoElectronico", user.CorreoElectronico, DbType.String); @@ -56,15 +57,7 @@ namespace SIG.Web.AppCode.Repositories.Security StoredProcedureCommand.AddInput(command, "@HashContrasena", passwordHash, DbType.String); StoredProcedureCommand.AddInput(command, "@Activo", user.Activo, DbType.Boolean); StoredProcedureCommand.AddInput(command, "@DebeCambiarContrasena", user.DebeCambiarContrasena, DbType.Boolean); - int id; - using (IDataReader reader = command.ExecuteReader()) - { - id = reader.Read() ? reader.GetInt32(0) : 0; - } - StoredProcedureCommand.EnsureSuccess(command); - return id; - } - }); + }); } public DbResult DeleteUser(int userId, int executingUser, string domainName) @@ -182,77 +175,5 @@ namespace SIG.Web.AppCode.Repositories.Security tokenHash, DbType.StringFixedLength)); } - - private DbResult> QueryList( - string procedure, - int user, - string domain, - System.Action parameters) - where T : class, new() - { - return _db.Execute(domain, connection => - { - using (IDbCommand command = connection.CreateCommand()) - { - StoredProcedureCommand.Configure(command, procedure, user); - if (parameters != null) - { - parameters(command); - } - List value; - using (IDataReader reader = command.ExecuteReader()) - { - value = reader.ToList(); - } - StoredProcedureCommand.EnsureSuccess(command); - return value; - } - }); - } - - private DbResult QueryOne( - string procedure, - int user, - string domain, - System.Action parameters) - where T : class, new() - { - return _db.Execute(domain, connection => - { - using (IDbCommand command = connection.CreateCommand()) - { - StoredProcedureCommand.Configure(command, procedure, user); - if (parameters != null) - { - parameters(command); - } - T value; - using (IDataReader reader = command.ExecuteReader()) - { - value = reader.ToObject(); - } - StoredProcedureCommand.EnsureSuccess(command); - return value; - } - }); - } - - private DbResult Execute(string procedure, int user, string domain, System.Action parameters) - { - return _db.Execute(domain, connection => - { - using (IDbCommand command = connection.CreateCommand()) - { - StoredProcedureCommand.Configure(command, procedure, user); - if (parameters != null) - { - parameters(command); - } - command.ExecuteNonQuery(); - StoredProcedureCommand.EnsureSuccess(command); - return true; - } - }); - } } } diff --git a/SIG.Web/App_Code/Repositories/Security/UserRepository.cs b/SIG.Web/App_Code/Repositories/Security/UserRepository.cs index f29abd6..f3335ae 100644 --- a/SIG.Web/App_Code/Repositories/Security/UserRepository.cs +++ b/SIG.Web/App_Code/Repositories/Security/UserRepository.cs @@ -1,68 +1,69 @@ -using System; using System.Data; using SIG.Web.AppCode.Contracts.Database; using SIG.Web.AppCode.Contracts.Security; using SIG.Web.AppCode.Models.Common; using SIG.Web.AppCode.Models.Security; using SIG.Web.AppCode.Repositories.Database; -using SIG.Web.AppCode.Utilities; namespace SIG.Web.AppCode.Repositories.Security { - public sealed class UserRepository : IUserRepository + public sealed class UserRepository + : RepositoryBase, IUserRepository { - private readonly IDbExecutor _dbExecutor; - public UserRepository(IDbExecutor dbExecutor) + : base(dbExecutor) { - _dbExecutor = dbExecutor; } - public DbResult ObtenerPorNombreUsuario(string username, string domainName) + public DbResult ObtenerPorNombreUsuario( + string username, + string domainName) { - return _dbExecutor.Execute(domainName, connection => - { - using (IDbCommand command = connection.CreateCommand()) - { - StoredProcedureCommand.Configure(command, "dbo.PA_Sis_UsuarioGetByName", 0); - StoredProcedureCommand.AddInput(command, "@NombreUsuario", username, DbType.String); - - UserModel user; - - using (IDataReader reader = command.ExecuteReader()) - { - user = reader.ToObject(); - } - - StoredProcedureCommand.EnsureSuccess(command); - return user; - } - }); + return QueryOne( + "dbo.PA_Sis_UsuarioGetByName", + 0, + domainName, + command => StoredProcedureCommand.AddInput( + command, + "@NombreUsuario", + username, + DbType.String)); } - public DbResult RegisterSuccessfulLogin(int cveUser, string domainName) + public DbResult RegisterSuccessfulLogin( + int cveUser, + string domainName) { - return ExecuteUserUpdate("dbo.PA_Sis_UsuarioLoginSuccessUpdate", cveUser, domainName); + return ExecuteUserUpdate( + "dbo.PA_Sis_UsuarioLoginSuccessUpdate", + cveUser, + domainName); } - public DbResult RegisterFailedLogin(int cveUser, string domainName) + public DbResult RegisterFailedLogin( + int cveUser, + string domainName) { - return ExecuteUserUpdate("dbo.PA_Sis_UsuarioLoginFailedUpdate", cveUser, domainName); + return ExecuteUserUpdate( + "dbo.PA_Sis_UsuarioLoginFailedUpdate", + cveUser, + domainName); } - private DbResult ExecuteUserUpdate(string procedureName, int cveUser, string domainName) + private DbResult ExecuteUserUpdate( + string procedureName, + int cveUser, + string domainName) { - return _dbExecutor.Execute(domainName, connection => - { - using (IDbCommand command = connection.CreateCommand()) - { - StoredProcedureCommand.Configure(command, procedureName, cveUser); - StoredProcedureCommand.AddInput(command, "@CveUsuario", cveUser, DbType.Int32); - command.ExecuteNonQuery(); - StoredProcedureCommand.EnsureSuccess(command); - return true; - } - }); + return Execute( + procedureName, + cveUser, + domainName, + command => StoredProcedureCommand.AddInput( + command, + "@CveUsuario", + cveUser, + DbType.Int32)); } } } diff --git a/SIG.Web/App_Code/Repositories/Security/UserSessionRepository.cs b/SIG.Web/App_Code/Repositories/Security/UserSessionRepository.cs index 8f18009..ec79782 100644 --- a/SIG.Web/App_Code/Repositories/Security/UserSessionRepository.cs +++ b/SIG.Web/App_Code/Repositories/Security/UserSessionRepository.cs @@ -6,49 +6,68 @@ using SIG.Web.AppCode.Repositories.Database; namespace SIG.Web.AppCode.Repositories.Security { - public sealed class UserSessionRepository : IUserSessionRepository + public sealed class UserSessionRepository + : RepositoryBase, IUserSessionRepository { - private readonly IDbExecutor _dbExecutor; - public UserSessionRepository(IDbExecutor dbExecutor) + : base(dbExecutor) { - _dbExecutor = dbExecutor; } - public DbResult StartSession(int cveUser, string sessionToken, string ipAddress, string userAgent, string domainName) + public DbResult StartSession( + int cveUser, + string sessionToken, + string ipAddress, + string userAgent, + string domainName) { - return _dbExecutor.Execute(domainName, connection => - { - using (IDbCommand command = connection.CreateCommand()) + return Execute( + "dbo.PA_Sis_UsuarioSesionAdd", + cveUser, + domainName, + command => { - StoredProcedureCommand.Configure(command, "dbo.PA_Sis_UsuarioSesionAdd", cveUser); - StoredProcedureCommand.AddInput(command, "@CveUsuario", cveUser, DbType.Int32); - StoredProcedureCommand.AddInput(command, "@TokenSesion", sessionToken, DbType.String); - StoredProcedureCommand.AddInput(command, "@DireccionIP", ipAddress, DbType.String); - StoredProcedureCommand.AddInput(command, "@AgenteUsuario", userAgent, DbType.String); - StoredProcedureCommand.AddInput(command, "@NombreDominio", domainName, DbType.String); - - command.ExecuteNonQuery(); - StoredProcedureCommand.EnsureSuccess(command); - return true; - } - }); + StoredProcedureCommand.AddInput( + command, + "@CveUsuario", + cveUser, + DbType.Int32); + StoredProcedureCommand.AddInput( + command, + "@TokenSesion", + sessionToken, + DbType.String); + StoredProcedureCommand.AddInput( + command, + "@DireccionIP", + ipAddress, + DbType.String); + StoredProcedureCommand.AddInput( + command, + "@AgenteUsuario", + userAgent, + DbType.String); + StoredProcedureCommand.AddInput( + command, + "@NombreDominio", + domainName, + DbType.String); + }); } - public DbResult EndSession(string sessionToken, string domainName) + public DbResult EndSession( + string sessionToken, + string domainName) { - return _dbExecutor.Execute(domainName, connection => - { - using (IDbCommand command = connection.CreateCommand()) - { - StoredProcedureCommand.Configure(command, "dbo.PA_Sis_UsuarioSesionEnd", 0); - StoredProcedureCommand.AddInput(command, "@TokenSesion", sessionToken, DbType.String); - - command.ExecuteNonQuery(); - StoredProcedureCommand.EnsureSuccess(command); - return true; - } - }); + return Execute( + "dbo.PA_Sis_UsuarioSesionEnd", + 0, + domainName, + command => StoredProcedureCommand.AddInput( + command, + "@TokenSesion", + sessionToken, + DbType.String)); } } } diff --git a/SIG.Web/App_Code/Repositories/Tramites/TramiteCatalogRepository.cs b/SIG.Web/App_Code/Repositories/Tramites/TramiteCatalogRepository.cs index a8eb294..ecffccc 100644 --- a/SIG.Web/App_Code/Repositories/Tramites/TramiteCatalogRepository.cs +++ b/SIG.Web/App_Code/Repositories/Tramites/TramiteCatalogRepository.cs @@ -10,13 +10,12 @@ using SIG.Web.AppCode.Utilities; namespace SIG.Web.AppCode.Repositories.Tramites { - public sealed class TramiteCatalogRepository : ITramiteCatalogRepository + public sealed class TramiteCatalogRepository + : RepositoryBase, ITramiteCatalogRepository { - private readonly IDbExecutor _db; - public TramiteCatalogRepository(IDbExecutor db) + : base(db) { - _db = db; } public DbResult> ListEstatus(string texto, bool incluirInactivos, int usuario, string dominio) @@ -321,20 +320,17 @@ namespace SIG.Web.AppCode.Repositories.Tramites int usuario, string dominio) { - return _db.Execute(dominio, connection => - { - using (IDbCommand command = connection.CreateCommand()) + return Execute( + "dbo.PA_Tra_CatalogoOrdenMove", + usuario, + dominio, + command => { - StoredProcedureCommand.Configure(command, "dbo.PA_Tra_CatalogoOrdenMove", usuario); Add(command, "@Entidad", GetOrderEntityName(entity), DbType.String); Add(command, "@CveRegistro", id, DbType.Int32); Add(command, "@CveReferencia", referenceId, DbType.Int32); Add(command, "@ColocarDespues", placeAfter, DbType.Boolean); - command.ExecuteNonQuery(); - StoredProcedureCommand.EnsureSuccess(command); - return true; - } - }); + }); } private static string GetOrderEntityName(TramiteCatalogOrderEntity entity) @@ -356,89 +352,35 @@ namespace SIG.Web.AppCode.Repositories.Tramites } } - private DbResult> QueryList(string procedure, int user, string domain, Action parameters) - where T : class, new() + private DbResult Save( + string procedure, + int user, + string domain, + Action parameters) { - return _db.Execute(domain, connection => - { - using (IDbCommand command = connection.CreateCommand()) - { - StoredProcedureCommand.Configure(command, procedure, user); - if (parameters != null) - { - parameters(command); - } - - List value; - using (IDataReader reader = command.ExecuteReader()) - { - value = reader.ToList(); - } - - StoredProcedureCommand.EnsureSuccess(command); - return value; - } - }); + return QueryScalarId( + procedure, + user, + domain, + parameters); } - private DbResult QueryOne(string procedure, int user, string domain, Action parameters) - where T : class, new() + private DbResult Delete( + string procedure, + string parameterName, + int id, + int user, + string domain) { - return _db.Execute(domain, connection => - { - using (IDbCommand command = connection.CreateCommand()) - { - StoredProcedureCommand.Configure(command, procedure, user); - parameters(command); - - T value; - using (IDataReader reader = command.ExecuteReader()) - { - value = reader.ToObject(); - } - - StoredProcedureCommand.EnsureSuccess(command); - return value; - } - }); - } - - private DbResult Save(string procedure, int user, string domain, Action parameters) - { - return _db.Execute(domain, connection => - { - using (IDbCommand command = connection.CreateCommand()) - { - StoredProcedureCommand.Configure(command, procedure, user); - parameters(command); - - int value; - using (IDataReader reader = command.ExecuteReader()) - { - value = reader.Read() - ? Convert.ToInt32(reader.GetValue(0)) - : 0; - } - - StoredProcedureCommand.EnsureSuccess(command); - return value; - } - }); - } - - private DbResult Delete(string procedure, string parameterName, int id, int user, string domain) - { - return _db.Execute(domain, connection => - { - using (IDbCommand command = connection.CreateCommand()) - { - StoredProcedureCommand.Configure(command, procedure, user); - Add(command, parameterName, id, DbType.Int32); - command.ExecuteNonQuery(); - StoredProcedureCommand.EnsureSuccess(command); - return true; - } - }); + return Execute( + procedure, + user, + domain, + command => Add( + command, + parameterName, + id, + DbType.Int32)); } private static object NullableId(int value) diff --git a/SIG.Web/App_Code/Services/Fraccionamientos/FraccionamientoGisFileStore.cs b/SIG.Web/App_Code/Services/Fraccionamientos/FraccionamientoGisFileStore.cs index 1550c0f..209acf6 100644 --- a/SIG.Web/App_Code/Services/Fraccionamientos/FraccionamientoGisFileStore.cs +++ b/SIG.Web/App_Code/Services/Fraccionamientos/FraccionamientoGisFileStore.cs @@ -51,13 +51,48 @@ namespace SIG.Web.AppCode.Services.Fraccionamientos Directory.CreateDirectory(directory); } - using (FileStream destination = new FileStream( - path, - FileMode.Create, - FileAccess.Write, - FileShare.None)) + string temporaryPath = Path.Combine( + directory, + "." + Path.GetFileName(path) + "." + + Guid.NewGuid().ToString("N") + ".tmp"); + + try { - source.CopyTo(destination); + if (source.CanSeek) + { + source.Position = 0; + } + + using (FileStream destination = new FileStream( + temporaryPath, + FileMode.CreateNew, + FileAccess.Write, + FileShare.None)) + { + source.CopyTo(destination); + destination.Flush(); + } + + if (File.Exists(path)) + { + File.Replace( + temporaryPath, + path, + null); + } + else + { + File.Move( + temporaryPath, + path); + } + } + finally + { + if (File.Exists(temporaryPath)) + { + File.Delete(temporaryPath); + } } } @@ -70,6 +105,16 @@ namespace SIG.Web.AppCode.Services.Fraccionamientos FileShare.Read); } + public void Delete(FraccionamientoGisContextModel context) + { + string path = GetPhysicalPath(context); + + if (File.Exists(path)) + { + File.Delete(path); + } + } + private static void ValidateContext(FraccionamientoGisContextModel context) { if (context == null) diff --git a/SIG.Web/App_Code/Services/Fraccionamientos/FraccionamientoGisService.cs b/SIG.Web/App_Code/Services/Fraccionamientos/FraccionamientoGisService.cs new file mode 100644 index 0000000..334f385 --- /dev/null +++ b/SIG.Web/App_Code/Services/Fraccionamientos/FraccionamientoGisService.cs @@ -0,0 +1,439 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using SIG.Web.AppCode.Contracts.Fraccionamientos; +using SIG.Web.AppCode.Infrastructure.Transactions; +using SIG.Web.AppCode.Models.Common; +using SIG.Web.AppCode.Models.Fraccionamientos; +using SIG.Web.AppCode.Services.Logging; + +namespace SIG.Web.AppCode.Services.Fraccionamientos +{ + public sealed class FraccionamientoGisService : IFraccionamientoGisService + { + private const string GisExtension = ".gis"; + private const string GisContentType = "application/json"; + private const long MaxFileSize = 30L * 1024L * 1024L; + + private readonly IFraccionamientoGisRepository _repository; + private readonly IFraccionamientoGisFileStore _fileStore; + + public FraccionamientoGisService( + IFraccionamientoGisRepository repository, + IFraccionamientoGisFileStore fileStore) + { + if (repository == null) + { + throw new ArgumentNullException("repository"); + } + + if (fileStore == null) + { + throw new ArgumentNullException("fileStore"); + } + + _repository = repository; + _fileStore = fileStore; + } + + public DbResult Get( + int stageId, + int executingUser, + string domainName) + { + if (stageId <= 0) + { + return Fail( + "Seleccione una etapa válida."); + } + + DbResult contextResult = + _repository.GetContext( + stageId, + executingUser, + domainName); + + if (!contextResult.Success || contextResult.Data == null) + { + return CopyFailure( + contextResult, + "No fue posible obtener el contexto GIS de la etapa."); + } + + DbResult> linksResult = + _repository.ListLinks( + stageId, + executingUser, + domainName); + + if (!linksResult.Success) + { + return CopyFailure, FraccionamientoGisViewModel>( + linksResult, + "No fue posible obtener los lotes de la etapa."); + } + + try + { + bool hasFile = _fileStore.Exists(contextResult.Data); + + return DbResult.Ok( + new FraccionamientoGisViewModel + { + Contexto = contextResult.Data, + Lotes = linksResult.Data ?? + new List(), + TieneArchivo = hasFile, + NombreArchivo = hasFile + ? Path.GetFileName( + _fileStore.GetPhysicalPath(contextResult.Data)) + : string.Empty, + FechaArchivo = hasFile + ? (DateTime?)File.GetLastWriteTime( + _fileStore.GetPhysicalPath(contextResult.Data)) + : null + }); + } + catch (Exception ex) + { + const string userMessage = + "No fue posible consultar el archivo GIS; favor de contactar a Sistemas."; + + ExceptionLogger.Log( + ex, + "FraccionamientoGisService.Get", + userMessage); + + return DbResult.Fail( + userMessage, + ex.Message, + ex); + } + } + + public DbResult Save( + int stageId, + string originalFileName, + Stream content, + long contentLength, + IList links, + int executingUser, + string domainName) + { + if (stageId <= 0) + { + return Fail( + "Seleccione una etapa válida."); + } + + string validation = ValidateLinks(links); + if (!string.IsNullOrWhiteSpace(validation)) + { + return Fail(validation); + } + + bool hasUploadedFile = content != null && contentLength > 0; + + if (hasUploadedFile) + { + if (!string.Equals( + Path.GetExtension(originalFileName), + GisExtension, + StringComparison.OrdinalIgnoreCase)) + { + return Fail( + "El archivo seleccionado debe tener extensión .gis."); + } + + if (contentLength > MaxFileSize) + { + return Fail( + "El archivo GIS no puede exceder 30 MB."); + } + } + + DbResult contextResult = + _repository.GetContext( + stageId, + executingUser, + domainName); + + if (!contextResult.Success || contextResult.Data == null) + { + return CopyFailure( + contextResult, + "No fue posible obtener el contexto GIS de la etapa."); + } + + FraccionamientoGisContextModel gisContext = contextResult.Data; + bool hadFile; + + try + { + hadFile = _fileStore.Exists(gisContext); + } + catch (Exception ex) + { + return FileFailure( + ex, + "FraccionamientoGisService.Save.Exists"); + } + + if (!hasUploadedFile && !hadFile) + { + return Fail( + "Seleccione un archivo .gis antes de guardar."); + } + + byte[] previousFile = null; + + if (hasUploadedFile && hadFile) + { + try + { + using (Stream previous = _fileStore.OpenRead(gisContext)) + using (var backup = new MemoryStream()) + { + previous.CopyTo(backup); + previousFile = backup.ToArray(); + } + } + catch (Exception ex) + { + return FileFailure( + ex, + "FraccionamientoGisService.Save.Backup"); + } + } + + bool fileWasWritten = false; + + try + { + using (var transaction = new TransactionLogic()) + { + DbResult saveLinksResult = + _repository.SaveLinks( + stageId, + links, + executingUser, + domainName); + + if (!saveLinksResult.Success) + { + return DbResult.Fail( + saveLinksResult.UserMessage, + saveLinksResult.TechnicalMessage, + saveLinksResult.Exception); + } + + if (hasUploadedFile) + { + _fileStore.Save(gisContext, content); + fileWasWritten = true; + } + + transaction.Commit(); + } + + bool hasFile = _fileStore.Exists(gisContext); + + return DbResult.Ok( + new FraccionamientoGisSaveResultModel + { + CveFraccionamientoEtapa = stageId, + VinculosGuardados = links.Count, + ArchivoGuardado = hasUploadedFile, + TieneArchivo = hasFile, + NombreArchivo = hasFile + ? Path.GetFileName( + _fileStore.GetPhysicalPath(gisContext)) + : string.Empty + }); + } + catch (Exception ex) + { + if (fileWasWritten) + { + RestorePreviousFile( + gisContext, + hadFile, + previousFile); + } + + return FileFailure( + ex, + "FraccionamientoGisService.Save"); + } + } + + public DbResult OpenFile( + int stageId, + int executingUser, + string domainName) + { + if (stageId <= 0) + { + return Fail( + "Seleccione una etapa válida."); + } + + DbResult contextResult = + _repository.GetContext( + stageId, + executingUser, + domainName); + + if (!contextResult.Success || contextResult.Data == null) + { + return CopyFailure( + contextResult, + "No fue posible obtener el contexto GIS de la etapa."); + } + + try + { + if (!_fileStore.Exists(contextResult.Data)) + { + return Fail( + "No se encontró el archivo GIS de la etapa."); + } + + return DbResult.Ok( + new FraccionamientoGisFileModel + { + NombreArchivo = Path.GetFileName( + _fileStore.GetPhysicalPath(contextResult.Data)), + ContentType = GisContentType, + Content = _fileStore.OpenRead(contextResult.Data) + }); + } + catch (Exception ex) + { + return FileFailure( + ex, + "FraccionamientoGisService.OpenFile"); + } + } + + private void RestorePreviousFile( + FraccionamientoGisContextModel context, + bool hadFile, + byte[] previousFile) + { + try + { + if (hadFile && previousFile != null) + { + using (var backup = new MemoryStream(previousFile, false)) + { + _fileStore.Save(context, backup); + } + } + else + { + _fileStore.Delete(context); + } + } + catch (Exception restoreException) + { + ExceptionLogger.Log( + restoreException, + "FraccionamientoGisService.RestorePreviousFile", + "No fue posible restaurar el archivo GIS después de un error."); + } + } + + private static string ValidateLinks( + IList links) + { + if (links == null || links.Count == 0) + { + return "Debe vincular los polígonos del GIS con los lotes antes de guardar."; + } + + var lotIds = new HashSet(); + var polygonKeys = new HashSet(StringComparer.Ordinal); + + foreach (FraccionamientoGisLotLinkModel link in links) + { + if (link == null || link.CveFraccionamientoLote <= 0) + { + return "Existe un vínculo con un lote inválido."; + } + + string key = string.IsNullOrWhiteSpace(link.GISPoligonoClave) + ? null + : link.GISPoligonoClave.Trim(); + + if (key == null) + { + return "Existe al menos un polígono sin una clave GIS válida."; + } + + if (key.Length > 100) + { + return "Una clave de polígono GIS excede 100 caracteres."; + } + + if (!lotIds.Add(link.CveFraccionamientoLote)) + { + return "Un lote no puede vincularse con más de un polígono."; + } + + if (!polygonKeys.Add(key)) + { + return "Un polígono no puede vincularse con más de un lote."; + } + + link.GISPoligonoClave = key; + } + + return null; + } + + private static DbResult CopyFailure( + DbResult source, + string fallbackMessage) + { + if (source == null) + { + return Fail(fallbackMessage); + } + + return DbResult.Fail( + string.IsNullOrWhiteSpace(source.UserMessage) + ? fallbackMessage + : source.UserMessage, + source.TechnicalMessage, + source.Exception); + } + + private static DbResult FileFailure( + Exception ex, + string origin) + { + const string userMessage = + "No fue posible procesar el archivo GIS; favor de contactar a Sistemas."; + + ExceptionLogger.Log( + ex, + origin, + userMessage); + + return DbResult.Fail( + userMessage, + ex.Message, + ex); + } + + private static DbResult Fail(string message) + { + return DbResult.Fail( + message, + message, + null); + } + } +} diff --git a/SIG.Web/Pages/Fraccionamientos/FraccionamientoDetalle.aspx b/SIG.Web/Pages/Fraccionamientos/FraccionamientoDetalle.aspx index 7b69a95..ae96242 100644 --- a/SIG.Web/Pages/Fraccionamientos/FraccionamientoDetalle.aspx +++ b/SIG.Web/Pages/Fraccionamientos/FraccionamientoDetalle.aspx @@ -12,6 +12,9 @@ + @@ -949,10 +952,12 @@ - + @@ -1278,7 +1314,21 @@ +