Ajustes Lotes
This commit is contained in:
@@ -1,43 +0,0 @@
|
||||
CAMBIO REQUERIDO EN Pages/Desarrolladores/DesarrolladorDetalle.aspx
|
||||
|
||||
El ZIP fuente SIG.Web(3).zip no contiene la carpeta Pages, por lo que no es seguro
|
||||
inventar ni sobrescribir DesarrolladorDetalle.aspx.
|
||||
|
||||
El botón "Ver etapa" debe dejar de abrir el panel lateral y navegar a:
|
||||
|
||||
~/Pages/Fraccionamientos/EtapaDetalle.aspx?etapa={CveFraccionamientoEtapa}
|
||||
|
||||
Si actualmente es un LinkButton, reemplazar sólo esa acción por un HyperLink.
|
||||
|
||||
Ejemplo dentro del ItemTemplate:
|
||||
|
||||
<asp:HyperLink
|
||||
ID="BtnVerEtapa"
|
||||
runat="server"
|
||||
CssClass="btn btn-circle btn-sm default sig-accion-icono"
|
||||
ToolTip="Ver etapa"
|
||||
aria-label="Ver etapa"
|
||||
NavigateUrl='<%# ResolveUrl("~/Pages/Fraccionamientos/EtapaDetalle.aspx?etapa=" +
|
||||
Convert.ToInt32(Eval("CveFraccionamientoEtapa")).ToString(
|
||||
System.Globalization.CultureInfo.InvariantCulture)) %>'>
|
||||
<i class="fa fa-eye" aria-hidden="true"></i>
|
||||
</asp:HyperLink>
|
||||
|
||||
Si la URL se arma en code-behind, usar:
|
||||
|
||||
private string UrlDetalleEtapa(int cveFraccionamientoEtapa)
|
||||
{
|
||||
return ResolveUrl("~/Pages/Fraccionamientos/EtapaDetalle.aspx?etapa=" +
|
||||
cveFraccionamientoEtapa.ToString(
|
||||
System.Globalization.CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
y asignar esa URL al HyperLink de Ver etapa.
|
||||
|
||||
Quitar del botón Ver etapa:
|
||||
- CommandName usado sólo para abrir el panel.
|
||||
- data-sig-panel-abrir.
|
||||
- OnClientClick que abra el panel.
|
||||
- cualquier llamada a SIGPanelLateral.abrir(...) asociada exclusivamente a Ver etapa.
|
||||
|
||||
No eliminar el UserControl DetalleEtapa.ascx: la nueva página lo reutiliza.
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using SIG.Web.AppCode.Contracts.Clientes;
|
||||
using SIG.Web.AppCode.Contracts.Convenios;
|
||||
@@ -18,6 +18,7 @@ using SIG.Web.AppCode.Contracts.Security;
|
||||
using SIG.Web.AppCode.Contracts.Tramites;
|
||||
using SIG.Web.AppCode.Contracts.Ventas;
|
||||
using SIG.Web.AppCode.Notifications.Contracts;
|
||||
using SIG.Web.AppCode.Notifications.Repositories;
|
||||
using SIG.Web.AppCode.Notifications.Services;
|
||||
using SIG.Web.AppCode.Repositories.Bitacora;
|
||||
using SIG.Web.AppCode.Repositories.Database;
|
||||
@@ -65,6 +66,7 @@ namespace SIG.Web.AppCode.Configuration
|
||||
public static IClienteDocumentoService ClienteDocumentoService { get; private set; }
|
||||
public static ITramiteDocumentoService TramiteDocumentoService { get; private set; }
|
||||
public static IServicioFraccionamiento ServicioFraccionamiento { get; private set; }
|
||||
public static IServicioLotesEtapa ServicioLotesEtapa { get; private set; }
|
||||
public static IServicioGisFraccionamiento ServicioGisFraccionamiento { get; private set; }
|
||||
public static ITramiteCatalogService TramiteCatalogService { get; private set; }
|
||||
public static ITramiteSolicitudService TramiteSolicitudService { get; private set; }
|
||||
@@ -80,6 +82,8 @@ namespace SIG.Web.AppCode.Configuration
|
||||
public static IPermissionService PermissionService { get; private set; }
|
||||
public static IMenuProvider MenuProvider { get; private set; }
|
||||
public static INotificationCenter NotificationCenter { get; private set; }
|
||||
public static INotificacionService NotificacionService { get; private set; }
|
||||
public static INotificacionConfiguracionService NotificacionConfiguracionService { get; private set; }
|
||||
public static IBuscadorCatalogoDataProvider SearchProvider { get; private set; }
|
||||
|
||||
public static void Configure()
|
||||
@@ -139,6 +143,14 @@ namespace SIG.Web.AppCode.Configuration
|
||||
|
||||
ITramiteSolicitudRepository tramiteSolicitudRepository =
|
||||
new TramiteSolicitudRepository(DbExecutor);
|
||||
INotificacionRepository notificacionRepository =
|
||||
new NotificacionRepository(DbExecutor);
|
||||
NotificacionService = new NotificacionService(
|
||||
notificacionRepository,
|
||||
new SmtpEmailSender());
|
||||
NotificacionConfiguracionService = new NotificacionConfiguracionService(
|
||||
notificacionRepository,
|
||||
NotificacionService);
|
||||
ITramiteDocumentoRepository tramiteDocumentoRepository =
|
||||
new TramiteDocumentoRepository(DbExecutor);
|
||||
ITramiteDocumentoFileStore tramiteDocumentoFileStore =
|
||||
@@ -148,7 +160,8 @@ namespace SIG.Web.AppCode.Configuration
|
||||
tramiteDocumentoFileStore,
|
||||
BitacoraService,
|
||||
UserContext,
|
||||
tramiteSolicitudRepository);
|
||||
tramiteSolicitudRepository,
|
||||
NotificacionConfiguracionService);
|
||||
|
||||
IRepositorioFraccionamiento repositorioFraccionamiento =
|
||||
new RepositorioFraccionamiento(DbExecutor);
|
||||
@@ -158,6 +171,12 @@ namespace SIG.Web.AppCode.Configuration
|
||||
tramiteSolicitudRepository,
|
||||
BitacoraService);
|
||||
|
||||
IRepositorioLotesEtapa repositorioLotesEtapa =
|
||||
new RepositorioLotesEtapa(DbExecutor);
|
||||
ServicioLotesEtapa = new ServicioLotesEtapa(
|
||||
repositorioLotesEtapa,
|
||||
BitacoraService);
|
||||
|
||||
IRepositorioGisFraccionamiento repositorioGis =
|
||||
new RepositorioGisFraccionamiento(DbExecutor);
|
||||
IAlmacenArchivosGisFraccionamiento almacenArchivosGis =
|
||||
@@ -183,7 +202,8 @@ namespace SIG.Web.AppCode.Configuration
|
||||
repositorioFraccionamiento,
|
||||
BitacoraService,
|
||||
TramiteDocumentoService,
|
||||
UserContext);
|
||||
UserContext,
|
||||
NotificacionConfiguracionService);
|
||||
var clienteProfact = new ClienteTimbradoPacProfact(
|
||||
new ProveedorCredencialPacConfiguracion());
|
||||
ServicioTimbradoCfdi = new ServicioTimbradoCfdi(
|
||||
|
||||
@@ -59,7 +59,9 @@ namespace SIG.Web.AppCode.Configuration
|
||||
"~/Scripts/SigPdfDrawer.js",
|
||||
"~/Scripts/PanelLateral.js",
|
||||
"~/Scripts/DocumentosEtapa.js",
|
||||
"~/Scripts/DocumentosEtapaCargaMasiva.js",
|
||||
"~/Scripts/SigVisualizadorArchivo.js",
|
||||
"~/Scripts/DocumentosEtapaNavegacion.js",
|
||||
"~/Scripts/Visitas.js",
|
||||
"~/Scripts/PagosConvenios.js",
|
||||
"~/Scripts/custom.js",
|
||||
@@ -67,7 +69,8 @@ namespace SIG.Web.AppCode.Configuration
|
||||
"~/Scripts/filtrosig.js",
|
||||
"~/Scripts/scrollsig.js",
|
||||
"~/Scripts/sig-grid-agrupado.js",
|
||||
"~/Scripts/Convenios.js"
|
||||
"~/Scripts/Convenios.js",
|
||||
"~/Scripts/LotesEtapa.js"
|
||||
));
|
||||
bundles.Add(new ScriptBundle("~/bundles/WebFormsJs").Include(
|
||||
"~/Scripts/WebForms/WebForms.js",
|
||||
@@ -129,12 +132,15 @@ namespace SIG.Web.AppCode.Configuration
|
||||
"~/Styles/SigVisualizadorArchivo.css",
|
||||
"~/Styles/DetalleEtapa.css",
|
||||
"~/Styles/DocumentosEtapa.css",
|
||||
"~/Styles/DocumentosEtapaCargaMasiva.css",
|
||||
"~/Styles/DocumentosEtapaNavegacion.css",
|
||||
"~/Styles/Archivos.css",
|
||||
"~/Styles/Estilos.css",
|
||||
"~/Styles/filtrosig.css",
|
||||
"~/Styles/scrollsig.css",
|
||||
"~/Styles/sig-grid-agrupado.css",
|
||||
"~/Styles/Convenios.css",
|
||||
"~/Styles/LotesEtapa.css",
|
||||
"~/Metronic/assets/global/plugins/bootstrap-switch/css/bootstrap-switch.min.css",
|
||||
"~/Metronic/assets/global/plugins/bootstrap-toastr/toastr.min.css",
|
||||
"~/Metronic/assets/layouts/layout3/css/jquery.datetimepicker.css",
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace SIG.Web.AppCode.Contracts.Clientes
|
||||
int cveUsuarioEjecuta,
|
||||
string nombreDominio);
|
||||
|
||||
DbResult<int> GuardarFraccionamientoConEtapa(
|
||||
DbResult<ResultadoGuardarFraccionamientoConEtapas> GuardarFraccionamientoConEtapa(
|
||||
ModeloFraccionamiento fraccionamiento,
|
||||
ModeloEtapaFraccionamiento etapa,
|
||||
int cveUsuarioEjecuta,
|
||||
|
||||
@@ -10,6 +10,8 @@ namespace SIG.Web.AppCode.Contracts.Convenios
|
||||
DbResult<ConvenioDetalleCompleto> Obtener(int cveConvenio, int usuario, string dominio);
|
||||
DbResult<List<ConvenioConceptoCatalogo>> ListarConceptos(int usuario, string dominio);
|
||||
DbResult<int> Agregar(SolicitudAltaConvenio solicitud, int usuario, string dominio);
|
||||
DbResult<ConvenioLotesConvenio> ObtenerLotesConvenio(int cveConvenio, int usuario, string dominio);
|
||||
DbResult<bool> GuardarLotesConvenio(int cveConvenio, int lotesConvenio, int usuario, string dominio);
|
||||
DbResult<bool> Eliminar(int cveConvenio, int usuario, string dominio);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,6 +85,13 @@ namespace SIG.Web.AppCode.Contracts.Documentos
|
||||
int cveUsuarioEjecuta,
|
||||
string nombreDominio);
|
||||
|
||||
DbResult<TramiteDocumentoNotaResultModel> ActualizarNota(
|
||||
int cveFraccionamiento,
|
||||
int cveDocumentoSolicitud,
|
||||
string nota,
|
||||
int cveUsuarioEjecuta,
|
||||
string nombreDominio);
|
||||
|
||||
DbResult<TramiteDocumentoReviewResultModel> Review(
|
||||
int developmentId,
|
||||
int documentRequestId,
|
||||
|
||||
@@ -85,6 +85,13 @@ namespace SIG.Web.AppCode.Contracts.Documentos
|
||||
int cveUsuarioEjecuta,
|
||||
string nombreDominio);
|
||||
|
||||
DbResult<TramiteDocumentoNotaResultModel> ActualizarNota(
|
||||
int cveFraccionamiento,
|
||||
int cveDocumentoSolicitud,
|
||||
string nota,
|
||||
int cveUsuarioEjecuta,
|
||||
string nombreDominio);
|
||||
|
||||
DbResult<TramiteDocumentoReviewResultModel> Review(
|
||||
int developmentId,
|
||||
int documentRequestId,
|
||||
|
||||
57
SIG.Web/App_Code/Contracts/Fraccionamientos/ILotesEtapa.cs
Normal file
57
SIG.Web/App_Code/Contracts/Fraccionamientos/ILotesEtapa.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using SIG.Web.AppCode.Models.Common;
|
||||
using SIG.Web.AppCode.Models.Fraccionamientos;
|
||||
|
||||
namespace SIG.Web.AppCode.Contracts.Fraccionamientos
|
||||
{
|
||||
public interface IRepositorioLotesEtapa
|
||||
{
|
||||
DbResult<ModeloLoteFraccionamiento> Obtener(
|
||||
int cveFraccionamiento, int cveLote,
|
||||
int cveUsuarioEjecuta, string nombreDominio);
|
||||
|
||||
DbResult<int> CambiarAprobacion(
|
||||
int cveFraccionamiento, int cveLote, bool aprobado,
|
||||
int cveUsuarioEjecuta, string nombreDominio);
|
||||
|
||||
DbResult<int> CambiarBloqueo(
|
||||
int cveFraccionamiento, int cveLote, bool bloqueado,
|
||||
int cveUsuarioEjecuta, string nombreDominio);
|
||||
|
||||
DbResult<int> ActualizarInfraestructura(
|
||||
int cveFraccionamiento, int cveLote,
|
||||
decimal avanceAgua, decimal avanceDrenaje,
|
||||
int cveUsuarioEjecuta, string nombreDominio);
|
||||
|
||||
DbResult<int> CambiarAutorizacionAgua(
|
||||
int cveFraccionamiento, int cveLote, bool autorizado,
|
||||
int cveUsuarioEjecuta, string nombreDominio);
|
||||
|
||||
DbResult<int> CambiarAutorizacionDrenaje(
|
||||
int cveFraccionamiento, int cveLote, bool autorizado,
|
||||
int cveUsuarioEjecuta, string nombreDominio);
|
||||
}
|
||||
|
||||
public interface IServicioLotesEtapa
|
||||
{
|
||||
DbResult<bool> CambiarAprobacion(
|
||||
int cveFraccionamiento, int cveLote, bool aprobado,
|
||||
int cveUsuarioEjecuta, string nombreDominio);
|
||||
|
||||
DbResult<bool> CambiarBloqueo(
|
||||
int cveFraccionamiento, int cveLote, bool bloqueado,
|
||||
int cveUsuarioEjecuta, string nombreDominio);
|
||||
|
||||
DbResult<bool> ActualizarInfraestructura(
|
||||
int cveFraccionamiento, int cveLote,
|
||||
decimal avanceAgua, decimal avanceDrenaje,
|
||||
int cveUsuarioEjecuta, string nombreDominio);
|
||||
|
||||
DbResult<bool> CambiarAutorizacionAgua(
|
||||
int cveFraccionamiento, int cveLote, bool autorizado,
|
||||
int cveUsuarioEjecuta, string nombreDominio);
|
||||
|
||||
DbResult<bool> CambiarAutorizacionDrenaje(
|
||||
int cveFraccionamiento, int cveLote, bool autorizado,
|
||||
int cveUsuarioEjecuta, string nombreDominio);
|
||||
}
|
||||
}
|
||||
@@ -14,89 +14,33 @@ namespace SIG.Web.AppCode.Contracts.Fraccionamientos
|
||||
DbResult<int> VincularLoteTipoViviendaEtapa(int cveEtapa, int cveRegistro, int cveLote, int cveUsuarioEjecuta, string nombreDominio);
|
||||
DbResult<bool> DesvincularLoteTipoViviendaEtapa(int cveEtapa, int cveVinculo, int cveUsuarioEjecuta, string nombreDominio);
|
||||
|
||||
DbResult<List<ModeloFilaDesarrollos>> ListarDesarrollos(
|
||||
int cveCliente, int cveUsuarioEjecuta, string nombreDominio);
|
||||
DbResult<List<ModeloFilaDesarrollos>> ListarDesarrollos( int cveCliente, int cveUsuarioEjecuta, string nombreDominio);
|
||||
|
||||
DbResult<List<OpcionClienteFraccionamiento>> ListarClientes(int cveUsuarioEjecuta, string nombreDominio);
|
||||
DbResult<List<OpcionEstatusFraccionamiento>> ListarEstatus(int cveUsuarioEjecuta, string nombreDominio);
|
||||
DbResult<List<ModeloFraccionamiento>> Listar(string texto, int? cveCliente, bool incluirInactivo, int cveUsuarioEjecuta, string nombreDominio);
|
||||
DbResult<ModeloFraccionamiento> Obtener(int cveFraccionamiento, int cveUsuarioEjecuta, string nombreDominio);
|
||||
DbResult<List<ModeloAvisoDetalleFraccionamiento>> ObtenerAvisosDetalle(
|
||||
int cveFraccionamiento,
|
||||
int cveUsuarioEjecuta,
|
||||
string nombreDominio);
|
||||
DbResult<int> GuardarConEtapas(
|
||||
ModeloFraccionamiento fraccionamiento,
|
||||
IList<ModeloEtapaFraccionamiento> etapas,
|
||||
int cveUsuarioEjecuta,
|
||||
string nombreDominio);
|
||||
DbResult<List<ModeloAvisoDetalleFraccionamiento>> ObtenerAvisosDetalle( int cveFraccionamiento, int cveUsuarioEjecuta, string nombreDominio);
|
||||
DbResult<ResultadoGuardarFraccionamientoConEtapas> GuardarConEtapas(
|
||||
ModeloFraccionamiento fraccionamiento, IList<ModeloEtapaFraccionamiento> etapas, int cveUsuarioEjecuta, string nombreDominio);
|
||||
DbResult<int> Guardar(ModeloFraccionamiento fraccionamiento, int cveUsuarioEjecuta, string nombreDominio);
|
||||
DbResult<bool> Eliminar(int cveFraccionamiento, int cveUsuarioEjecuta, string nombreDominio);
|
||||
DbResult<List<ModeloEtapaFraccionamiento>> ListarEtapas(int cveFraccionamiento, int cveUsuarioEjecuta, string nombreDominio);
|
||||
DbResult<ModeloEtapaFraccionamiento> ObtenerEtapa(
|
||||
int cveFraccionamientoEtapa,
|
||||
int cveUsuarioEjecuta,
|
||||
string nombreDominio);
|
||||
DbResult<ResultadoAvanceEtapaFraccionamiento> ActualizarAvanceEtapa(
|
||||
int cveFraccionamientoEtapa,
|
||||
decimal avance,
|
||||
int cveUsuarioEjecuta,
|
||||
string nombreDominio);
|
||||
DbResult<ModeloCondicionesEtapaFraccionamiento> ObtenerCondicionesEtapa(
|
||||
int cveFraccionamientoEtapa,
|
||||
int cveUsuarioEjecuta,
|
||||
string nombreDominio);
|
||||
DbResult<ModeloCondicionesEtapaFraccionamiento> GuardarCondicionesEtapa(
|
||||
ModeloCondicionesEtapaFraccionamiento condiciones,
|
||||
int cveUsuarioEjecuta,
|
||||
string nombreDominio);
|
||||
DbResult<ModeloGisEtapaFraccionamiento> ObtenerGisEtapa(
|
||||
int cveFraccionamientoEtapa,
|
||||
int cveUsuarioEjecuta,
|
||||
string nombreDominio);
|
||||
DbResult<ModeloGisEtapaFraccionamiento> GuardarGisEtapa(
|
||||
int cveFraccionamientoEtapa,
|
||||
int cveUsuarioEjecuta,
|
||||
string nombreDominio);
|
||||
DbResult<ModeloEtapaFraccionamiento> ObtenerEtapa( int cveFraccionamientoEtapa, int cveUsuarioEjecuta, string nombreDominio);
|
||||
DbResult<ResultadoAvanceEtapaFraccionamiento> ActualizarAvanceEtapa( int cveFraccionamientoEtapa, decimal avance, int cveUsuarioEjecuta, string nombreDominio);
|
||||
DbResult<ModeloCondicionesEtapaFraccionamiento> ObtenerCondicionesEtapa( int cveFraccionamientoEtapa, int cveUsuarioEjecuta, string nombreDominio);
|
||||
DbResult<ModeloCondicionesEtapaFraccionamiento> GuardarCondicionesEtapa( ModeloCondicionesEtapaFraccionamiento condiciones, int cveUsuarioEjecuta, string nombreDominio);
|
||||
DbResult<ModeloGisEtapaFraccionamiento> ObtenerGisEtapa( int cveFraccionamientoEtapa, int cveUsuarioEjecuta, string nombreDominio);
|
||||
DbResult<ModeloGisEtapaFraccionamiento> GuardarGisEtapa( int cveFraccionamientoEtapa, int cveUsuarioEjecuta, string nombreDominio);
|
||||
DbResult<List<ModeloTramiteEtapaFraccionamiento>> ListarTramitesEtapa(int cveFraccionamiento, int cveUsuarioEjecuta, string nombreDominio);
|
||||
DbResult<int> GuardarEtapa(ModeloEtapaFraccionamiento etapa, int cveUsuarioEjecuta, string nombreDominio);
|
||||
DbResult<bool> MoverOrdenEtapa(
|
||||
int cveFraccionamientoEtapa,
|
||||
int cveFraccionamientoEtapaReferencia,
|
||||
bool colocarDespues,
|
||||
int cveUsuarioEjecuta,
|
||||
string nombreDominio);
|
||||
DbResult<bool> MoverOrdenEtapa( int cveFraccionamientoEtapa, int cveFraccionamientoEtapaReferencia, bool colocarDespues, int cveUsuarioEjecuta, string nombreDominio);
|
||||
DbResult<bool> EliminarEtapa(int cveFraccionamientoEtapa, int cveUsuarioEjecuta, string nombreDominio);
|
||||
DbResult<List<ModeloLoteFraccionamiento>> ListarLotes(
|
||||
int cveFraccionamiento,
|
||||
int? cveFraccionamientoEtapa,
|
||||
int cveUsuarioEjecuta,
|
||||
string nombreDominio);
|
||||
DbResult<ModeloLoteFraccionamiento> ObtenerLote(
|
||||
int cveFraccionamiento,
|
||||
int cveFraccionamientoLote,
|
||||
int cveUsuarioEjecuta,
|
||||
string nombreDominio);
|
||||
DbResult<int> GuardarLote(
|
||||
int cveFraccionamiento,
|
||||
ModeloLoteFraccionamiento lote,
|
||||
int cveUsuarioEjecuta,
|
||||
string nombreDominio);
|
||||
DbResult<int> GuardarLotes(
|
||||
int cveFraccionamiento,
|
||||
int cveFraccionamientoEtapa,
|
||||
IList<ModeloLoteFraccionamiento> lotes,
|
||||
int cveUsuarioEjecuta,
|
||||
string nombreDominio);
|
||||
DbResult<bool> EliminarLote(
|
||||
int cveFraccionamiento,
|
||||
int cveFraccionamientoLote,
|
||||
int cveUsuarioEjecuta,
|
||||
string nombreDominio);
|
||||
DbResult<int> LimpiarLotesEtapa(
|
||||
int cveFraccionamiento,
|
||||
int cveFraccionamientoEtapa,
|
||||
int cveUsuarioEjecuta,
|
||||
string nombreDominio);
|
||||
DbResult<List<ModeloLoteFraccionamiento>> ListarLotes(int cveFraccionamiento,int? cveFraccionamientoEtapa,int cveUsuarioEjecuta,string nombreDominio);
|
||||
DbResult<ModeloLoteFraccionamiento> ObtenerLote(int cveFraccionamiento,int cveFraccionamientoLote, int cveUsuarioEjecuta, string nombreDominio);
|
||||
DbResult<int> GuardarLote( int cveFraccionamiento, ModeloLoteFraccionamiento lote, int cveUsuarioEjecuta, string nombreDominio);
|
||||
DbResult<int> GuardarLotes( int cveFraccionamiento, int cveFraccionamientoEtapa, IList<ModeloLoteFraccionamiento> lotes, int cveUsuarioEjecuta, string nombreDominio);
|
||||
DbResult<bool> EliminarLote( int cveFraccionamiento, int cveFraccionamientoLote, int cveUsuarioEjecuta, string nombreDominio);
|
||||
DbResult<int> LimpiarLotesEtapa( int cveFraccionamiento, int cveFraccionamientoEtapa, int cveUsuarioEjecuta, string nombreDominio);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,5 +5,6 @@ namespace SIG.Web.AppCode.Contracts.Security
|
||||
bool IsConfigured { get; }
|
||||
void SendVerification(string recipient, string verificationUrl);
|
||||
void EnviarContrasena(string destinatario, string nombreUsuario, string contrasena);
|
||||
void Send(string recipient, string subject, string htmlBody);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,44 +86,80 @@ namespace SIG.Web.Pages.Fraccionamientos
|
||||
nombreArchivo,
|
||||
tipoContenido))
|
||||
{
|
||||
SigVisualizadorArchivoOfficeResultado conversion;
|
||||
string error;
|
||||
|
||||
using (file.Content)
|
||||
using (var contenidoOffice = new MemoryStream())
|
||||
{
|
||||
if (!SigVisualizadorArchivoOfficeConverter.IntentarConvertir(
|
||||
file.Content,
|
||||
file.Content.CopyTo(contenidoOffice);
|
||||
contenidoOffice.Position = 0;
|
||||
|
||||
if (SigVisualizadorArchivoVistaPreviaExcel.EsCompatible(nombreArchivo))
|
||||
{
|
||||
byte[] vistaPreviaExcel;
|
||||
string errorExcel;
|
||||
|
||||
if (SigVisualizadorArchivoVistaPreviaExcel.IntentarGenerarHtml(
|
||||
contenidoOffice,
|
||||
nombreArchivo,
|
||||
out vistaPreviaExcel,
|
||||
out errorExcel))
|
||||
{
|
||||
PrepareResponse(
|
||||
context,
|
||||
"text/html; charset=utf-8",
|
||||
false,
|
||||
Path.GetFileNameWithoutExtension(nombreArchivo) + ".html");
|
||||
context.Response.OutputStream.Write(
|
||||
vistaPreviaExcel,
|
||||
0,
|
||||
vistaPreviaExcel.Length);
|
||||
context.ApplicationInstance.CompleteRequest();
|
||||
return;
|
||||
}
|
||||
|
||||
contenidoOffice.Position = 0;
|
||||
}
|
||||
|
||||
SigVisualizadorArchivoOfficeResultado conversion;
|
||||
string errorConversion;
|
||||
|
||||
if (SigVisualizadorArchivoOfficeConverter.IntentarConvertir(
|
||||
contenidoOffice,
|
||||
nombreArchivo,
|
||||
out conversion,
|
||||
out error))
|
||||
out errorConversion))
|
||||
{
|
||||
RespondError(
|
||||
context,
|
||||
415,
|
||||
string.IsNullOrWhiteSpace(error)
|
||||
? "No fue posible generar la vista previa del archivo de Office."
|
||||
: error);
|
||||
using (conversion)
|
||||
using (var contenidoPdf = new FileStream(
|
||||
conversion.RutaPdf,
|
||||
FileMode.Open,
|
||||
FileAccess.Read,
|
||||
FileShare.Read))
|
||||
{
|
||||
PrepareResponse(
|
||||
context,
|
||||
"application/pdf",
|
||||
false,
|
||||
Path.GetFileNameWithoutExtension(nombreArchivo) + ".pdf");
|
||||
contenidoPdf.CopyTo(context.Response.OutputStream);
|
||||
}
|
||||
|
||||
context.ApplicationInstance.CompleteRequest();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
using (conversion)
|
||||
using (var contenidoPdf = new FileStream(
|
||||
conversion.RutaPdf,
|
||||
FileMode.Open,
|
||||
FileAccess.Read,
|
||||
FileShare.Read))
|
||||
{
|
||||
PrepareResponse(
|
||||
RespondError(
|
||||
context,
|
||||
"application/pdf",
|
||||
false,
|
||||
Path.GetFileNameWithoutExtension(nombreArchivo) + ".pdf");
|
||||
contenidoPdf.CopyTo(context.Response.OutputStream);
|
||||
415,
|
||||
string.IsNullOrWhiteSpace(errorConversion)
|
||||
? "No fue posible generar la vista previa del archivo de Office."
|
||||
: errorConversion);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
context.ApplicationInstance.CompleteRequest();
|
||||
return;
|
||||
if (visualizar && EsArchivoGis(nombreArchivo))
|
||||
{
|
||||
tipoContenido = "application/geo+json; charset=utf-8";
|
||||
}
|
||||
|
||||
PrepareResponse(
|
||||
@@ -169,6 +205,9 @@ namespace SIG.Web.Pages.Fraccionamientos
|
||||
context.Response.StatusCode = statusCode;
|
||||
context.Response.TrySkipIisCustomErrors = true;
|
||||
context.Response.ContentType = "text/plain; charset=utf-8";
|
||||
context.Response.AddHeader(
|
||||
"X-SIG-Visualizador-Mensaje",
|
||||
HttpUtility.UrlEncode(message ?? string.Empty));
|
||||
context.Response.Write(message);
|
||||
context.ApplicationInstance.CompleteRequest();
|
||||
}
|
||||
@@ -193,6 +232,13 @@ namespace SIG.Web.Pages.Fraccionamientos
|
||||
result > 0;
|
||||
}
|
||||
|
||||
private static bool EsArchivoGis(string nombreArchivo)
|
||||
{
|
||||
string extension = Path.GetExtension(nombreArchivo ?? string.Empty);
|
||||
return string.Equals(extension, ".gis", StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(extension, ".geojson", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
private static string SanitizeFileName(string fileName)
|
||||
{
|
||||
string value = Path.GetFileName(
|
||||
|
||||
@@ -0,0 +1,538 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
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.Session;
|
||||
using SIG.Web.AppCode.Services.Logging;
|
||||
|
||||
namespace SIG.Web.Pages.Fraccionamientos
|
||||
{
|
||||
/// <summary>
|
||||
/// Descarga en un ZIP todos los archivos visibles para el usuario en el
|
||||
/// contexto actual del control DocumentosEtapa.
|
||||
///
|
||||
/// El escritor ZIP incluido aquí usa el método STORE (sin compresión) para
|
||||
/// no agregar dependencias nuevas al proyecto. El resultado sigue siendo
|
||||
/// un archivo .zip estándar.
|
||||
/// </summary>
|
||||
public sealed class TramiteDocumentosZipHandler
|
||||
: IHttpHandler, IRequiresSessionState
|
||||
{
|
||||
public bool IsReusable
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public void ProcessRequest(HttpContext context)
|
||||
{
|
||||
UserSessionModel usuario = ObtenerUsuario();
|
||||
if (usuario == null)
|
||||
{
|
||||
ResponderError(context, 401, "Su sesión no está disponible. Inicie sesión nuevamente.");
|
||||
return;
|
||||
}
|
||||
|
||||
int cveFraccionamiento;
|
||||
if (!LeerEntero(context.Request.QueryString["fraccionamiento"], out cveFraccionamiento) ||
|
||||
cveFraccionamiento <= 0)
|
||||
{
|
||||
ResponderError(context, 400, "El fraccionamiento solicitado no es válido.");
|
||||
return;
|
||||
}
|
||||
|
||||
int? cveEtapa;
|
||||
int? cveTipoTramite;
|
||||
if (!LeerEnteroOpcional(context.Request.QueryString["etapa"], out cveEtapa) ||
|
||||
!LeerEnteroOpcional(context.Request.QueryString["tramite"], out cveTipoTramite))
|
||||
{
|
||||
ResponderError(context, 400, "Los filtros de descarga no son válidos.");
|
||||
return;
|
||||
}
|
||||
|
||||
DbResult<List<TramiteDocumentoSolicitudModel>> consulta =
|
||||
AppServices.TramiteDocumentoService.ListForDevelopment(
|
||||
cveFraccionamiento,
|
||||
cveEtapa,
|
||||
cveTipoTramite,
|
||||
usuario.CveUsuario,
|
||||
usuario.NombreDominio);
|
||||
|
||||
if (!consulta.Success)
|
||||
{
|
||||
ResponderError(context, 400, consulta.UserMessage ?? "No fue posible consultar los documentos.");
|
||||
return;
|
||||
}
|
||||
|
||||
List<TramiteDocumentoSolicitudModel> documentos =
|
||||
(consulta.Data ?? new List<TramiteDocumentoSolicitudModel>())
|
||||
.Where(documento => documento.TieneArchivo && documento.CveDocumentoSolicitud > 0)
|
||||
.GroupBy(documento => documento.CveDocumentoSolicitud)
|
||||
.Select(grupo => grupo.First())
|
||||
.ToList();
|
||||
|
||||
if (documentos.Count == 0)
|
||||
{
|
||||
ResponderError(context, 404, "No hay archivos cargados para descargar.");
|
||||
return;
|
||||
}
|
||||
|
||||
string rutaTemporal = Path.Combine(
|
||||
Path.GetTempPath(),
|
||||
"SIG-Documentos-" + Guid.NewGuid().ToString("N") + ".zip");
|
||||
|
||||
try
|
||||
{
|
||||
List<string> errores;
|
||||
int agregados = CrearZip(
|
||||
rutaTemporal,
|
||||
documentos,
|
||||
cveFraccionamiento,
|
||||
usuario,
|
||||
out errores);
|
||||
|
||||
if (agregados == 0)
|
||||
{
|
||||
ResponderError(
|
||||
context,
|
||||
404,
|
||||
errores.Count > 0
|
||||
? string.Join(" ", errores)
|
||||
: "No fue posible abrir los archivos solicitados.");
|
||||
return;
|
||||
}
|
||||
|
||||
string nombreZip = "Documentos-Fraccionamiento-" +
|
||||
cveFraccionamiento.ToString(CultureInfo.InvariantCulture);
|
||||
if (cveEtapa.HasValue)
|
||||
{
|
||||
nombreZip += "-Etapa-" + cveEtapa.Value.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
nombreZip += ".zip";
|
||||
|
||||
context.Response.Clear();
|
||||
context.Response.ClearHeaders();
|
||||
context.Response.TrySkipIisCustomErrors = true;
|
||||
context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
|
||||
context.Response.Cache.SetNoStore();
|
||||
context.Response.ContentType = "application/zip";
|
||||
context.Response.AddHeader(
|
||||
"Content-Disposition",
|
||||
"attachment; filename=\"" + nombreZip + "\"");
|
||||
|
||||
var informacion = new FileInfo(rutaTemporal);
|
||||
context.Response.AddHeader(
|
||||
"Content-Length",
|
||||
informacion.Length.ToString(CultureInfo.InvariantCulture));
|
||||
|
||||
using (var archivoZip = new FileStream(
|
||||
rutaTemporal,
|
||||
FileMode.Open,
|
||||
FileAccess.Read,
|
||||
FileShare.Read))
|
||||
{
|
||||
archivoZip.CopyTo(context.Response.OutputStream);
|
||||
}
|
||||
|
||||
context.ApplicationInstance.CompleteRequest();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
const string mensaje =
|
||||
"No fue posible generar la descarga de documentos; favor de contactar a Sistemas.";
|
||||
ExceptionLogger.Log(
|
||||
ex,
|
||||
"TramiteDocumentosZipHandler.ProcessRequest",
|
||||
mensaje);
|
||||
ResponderError(context, 500, mensaje);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
if (File.Exists(rutaTemporal))
|
||||
{
|
||||
File.Delete(rutaTemporal);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// La limpieza del temporal no debe invalidar la descarga.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static int CrearZip(
|
||||
string rutaZip,
|
||||
IList<TramiteDocumentoSolicitudModel> documentos,
|
||||
int cveFraccionamiento,
|
||||
UserSessionModel usuario,
|
||||
out List<string> errores)
|
||||
{
|
||||
errores = new List<string>();
|
||||
int agregados = 0;
|
||||
var nombres = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
using (var salida = new FileStream(
|
||||
rutaZip,
|
||||
FileMode.CreateNew,
|
||||
FileAccess.ReadWrite,
|
||||
FileShare.None))
|
||||
using (var zip = new ZipStoreWriter(salida))
|
||||
{
|
||||
foreach (TramiteDocumentoSolicitudModel documento in documentos)
|
||||
{
|
||||
DbResult<TramiteDocumentoFileModel> resultado =
|
||||
AppServices.TramiteDocumentoService.Open(
|
||||
cveFraccionamiento,
|
||||
documento.CveDocumentoSolicitud,
|
||||
usuario.CveUsuario,
|
||||
usuario.NombreDominio);
|
||||
|
||||
if (!resultado.Success || resultado.Data == null || resultado.Data.Content == null)
|
||||
{
|
||||
errores.Add(
|
||||
(documento.TipoDocumento ?? "Documento") + ": " +
|
||||
(resultado.UserMessage ?? "No fue posible abrir el archivo."));
|
||||
continue;
|
||||
}
|
||||
|
||||
TramiteDocumentoFileModel archivo = resultado.Data;
|
||||
string nombreEntrada = NombreUnico(
|
||||
LimpiarNombreArchivo(archivo.NombreArchivo, documento.CveDocumentoSolicitud),
|
||||
nombres);
|
||||
|
||||
using (archivo.Content)
|
||||
{
|
||||
zip.AddEntry(nombreEntrada, archivo.Content, DateTime.Now);
|
||||
}
|
||||
|
||||
agregados++;
|
||||
}
|
||||
|
||||
if (agregados > 0 && errores.Count > 0)
|
||||
{
|
||||
byte[] contenidoError = Encoding.UTF8.GetBytes(
|
||||
"Algunos archivos no pudieron agregarse a la descarga:\r\n\r\n" +
|
||||
string.Join("\r\n", errores.Select(error => "- " + error)));
|
||||
using (var memoria = new MemoryStream(contenidoError))
|
||||
{
|
||||
zip.AddEntry("_ERRORES.txt", memoria, DateTime.Now);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return agregados;
|
||||
}
|
||||
|
||||
private static string LimpiarNombreArchivo(string nombre, int clave)
|
||||
{
|
||||
string limpio = Path.GetFileName(nombre ?? string.Empty);
|
||||
if (string.IsNullOrWhiteSpace(limpio))
|
||||
{
|
||||
limpio = "Documento-" + clave.ToString(CultureInfo.InvariantCulture) + ".bin";
|
||||
}
|
||||
|
||||
foreach (char caracter in Path.GetInvalidFileNameChars())
|
||||
{
|
||||
limpio = limpio.Replace(caracter, '_');
|
||||
}
|
||||
|
||||
return limpio;
|
||||
}
|
||||
|
||||
private static string NombreUnico(string nombre, HashSet<string> usados)
|
||||
{
|
||||
if (usados.Add(nombre))
|
||||
{
|
||||
return nombre;
|
||||
}
|
||||
|
||||
string extension = Path.GetExtension(nombre);
|
||||
string baseNombre = Path.GetFileNameWithoutExtension(nombre);
|
||||
int consecutivo = 2;
|
||||
|
||||
while (true)
|
||||
{
|
||||
string candidato = baseNombre + " (" +
|
||||
consecutivo.ToString(CultureInfo.InvariantCulture) + ")" + extension;
|
||||
if (usados.Add(candidato))
|
||||
{
|
||||
return candidato;
|
||||
}
|
||||
consecutivo++;
|
||||
}
|
||||
}
|
||||
|
||||
private static UserSessionModel ObtenerUsuario()
|
||||
{
|
||||
return AppServices.UserContext != null && AppServices.UserContext.IsAuthenticated()
|
||||
? AppServices.UserContext.GetCurrentUser()
|
||||
: null;
|
||||
}
|
||||
|
||||
private static bool LeerEntero(string valor, out int resultado)
|
||||
{
|
||||
return int.TryParse(
|
||||
valor,
|
||||
NumberStyles.Integer,
|
||||
CultureInfo.InvariantCulture,
|
||||
out resultado);
|
||||
}
|
||||
|
||||
private static bool LeerEnteroOpcional(string valor, out int? resultado)
|
||||
{
|
||||
resultado = null;
|
||||
if (string.IsNullOrWhiteSpace(valor))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int entero;
|
||||
if (!LeerEntero(valor, out entero) || entero <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
resultado = entero;
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void ResponderError(HttpContext context, int statusCode, string mensaje)
|
||||
{
|
||||
context.Response.Clear();
|
||||
context.Response.StatusCode = statusCode;
|
||||
context.Response.TrySkipIisCustomErrors = true;
|
||||
context.Response.ContentType = "text/plain; charset=utf-8";
|
||||
context.Response.Write(mensaje ?? "No fue posible completar la descarga.");
|
||||
context.ApplicationInstance.CompleteRequest();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Escritor ZIP mínimo, método STORE (sin compresión), UTF-8 y data descriptor.
|
||||
/// Evita agregar una dependencia adicional únicamente para esta descarga.
|
||||
/// </summary>
|
||||
private sealed class ZipStoreWriter : IDisposable
|
||||
{
|
||||
private const uint FirmaLocal = 0x04034b50;
|
||||
private const uint FirmaDescriptor = 0x08074b50;
|
||||
private const uint FirmaCentral = 0x02014b50;
|
||||
private const uint FirmaFin = 0x06054b50;
|
||||
private const ushort Version = 20;
|
||||
private const ushort Flags = 0x0808; // UTF-8 + data descriptor.
|
||||
private const ushort MetodoStore = 0;
|
||||
|
||||
private readonly Stream _salida;
|
||||
private readonly BinaryWriter _writer;
|
||||
private readonly List<EntradaZip> _entradas = new List<EntradaZip>();
|
||||
private bool _cerrado;
|
||||
|
||||
public ZipStoreWriter(Stream salida)
|
||||
{
|
||||
_salida = salida ?? throw new ArgumentNullException("salida");
|
||||
if (!salida.CanWrite || !salida.CanSeek)
|
||||
{
|
||||
throw new ArgumentException("El stream ZIP debe permitir escritura y posicionamiento.", "salida");
|
||||
}
|
||||
|
||||
_writer = new BinaryWriter(salida, Encoding.UTF8, true);
|
||||
}
|
||||
|
||||
public void AddEntry(string nombre, Stream contenido, DateTime fecha)
|
||||
{
|
||||
if (_cerrado)
|
||||
{
|
||||
throw new ObjectDisposedException("ZipStoreWriter");
|
||||
}
|
||||
if (contenido == null)
|
||||
{
|
||||
throw new ArgumentNullException("contenido");
|
||||
}
|
||||
|
||||
byte[] nombreBytes = Encoding.UTF8.GetBytes(nombre ?? "archivo.bin");
|
||||
if (nombreBytes.Length > ushort.MaxValue)
|
||||
{
|
||||
throw new InvalidOperationException("El nombre del archivo es demasiado largo para el ZIP.");
|
||||
}
|
||||
|
||||
long offsetLocalLong = _salida.Position;
|
||||
if (offsetLocalLong > uint.MaxValue)
|
||||
{
|
||||
throw new InvalidOperationException("La descarga excede el tamaño ZIP soportado.");
|
||||
}
|
||||
|
||||
ushort horaDos;
|
||||
ushort fechaDos;
|
||||
ConvertirFechaDos(fecha, out horaDos, out fechaDos);
|
||||
|
||||
_writer.Write(FirmaLocal);
|
||||
_writer.Write(Version);
|
||||
_writer.Write(Flags);
|
||||
_writer.Write(MetodoStore);
|
||||
_writer.Write(horaDos);
|
||||
_writer.Write(fechaDos);
|
||||
_writer.Write((uint)0);
|
||||
_writer.Write((uint)0);
|
||||
_writer.Write((uint)0);
|
||||
_writer.Write((ushort)nombreBytes.Length);
|
||||
_writer.Write((ushort)0);
|
||||
_writer.Write(nombreBytes);
|
||||
|
||||
var crc = new Crc32();
|
||||
long longitud = 0;
|
||||
byte[] buffer = new byte[81920];
|
||||
int leidos;
|
||||
while ((leidos = contenido.Read(buffer, 0, buffer.Length)) > 0)
|
||||
{
|
||||
_salida.Write(buffer, 0, leidos);
|
||||
crc.Update(buffer, 0, leidos);
|
||||
longitud += leidos;
|
||||
|
||||
if (longitud > uint.MaxValue)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Uno de los archivos excede el tamaño ZIP soportado.");
|
||||
}
|
||||
}
|
||||
|
||||
uint tamano = (uint)longitud;
|
||||
uint valorCrc = crc.Value;
|
||||
|
||||
_writer.Write(FirmaDescriptor);
|
||||
_writer.Write(valorCrc);
|
||||
_writer.Write(tamano);
|
||||
_writer.Write(tamano);
|
||||
|
||||
_entradas.Add(new EntradaZip
|
||||
{
|
||||
Nombre = nombreBytes,
|
||||
Crc = valorCrc,
|
||||
Tamano = tamano,
|
||||
OffsetLocal = (uint)offsetLocalLong,
|
||||
HoraDos = horaDos,
|
||||
FechaDos = fechaDos
|
||||
});
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_cerrado)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_cerrado = true;
|
||||
EscribirDirectorioCentral();
|
||||
_writer.Flush();
|
||||
_writer.Dispose();
|
||||
}
|
||||
|
||||
private void EscribirDirectorioCentral()
|
||||
{
|
||||
if (_entradas.Count > ushort.MaxValue)
|
||||
{
|
||||
throw new InvalidOperationException("La descarga contiene demasiados archivos.");
|
||||
}
|
||||
|
||||
long inicioCentralLong = _salida.Position;
|
||||
if (inicioCentralLong > uint.MaxValue)
|
||||
{
|
||||
throw new InvalidOperationException("La descarga excede el tamaño ZIP soportado.");
|
||||
}
|
||||
|
||||
foreach (EntradaZip entrada in _entradas)
|
||||
{
|
||||
_writer.Write(FirmaCentral);
|
||||
_writer.Write(Version);
|
||||
_writer.Write(Version);
|
||||
_writer.Write(Flags);
|
||||
_writer.Write(MetodoStore);
|
||||
_writer.Write(entrada.HoraDos);
|
||||
_writer.Write(entrada.FechaDos);
|
||||
_writer.Write(entrada.Crc);
|
||||
_writer.Write(entrada.Tamano);
|
||||
_writer.Write(entrada.Tamano);
|
||||
_writer.Write((ushort)entrada.Nombre.Length);
|
||||
_writer.Write((ushort)0);
|
||||
_writer.Write((ushort)0);
|
||||
_writer.Write((ushort)0);
|
||||
_writer.Write((ushort)0);
|
||||
_writer.Write((uint)0);
|
||||
_writer.Write(entrada.OffsetLocal);
|
||||
_writer.Write(entrada.Nombre);
|
||||
}
|
||||
|
||||
long finCentralLong = _salida.Position;
|
||||
long tamanoCentralLong = finCentralLong - inicioCentralLong;
|
||||
if (tamanoCentralLong > uint.MaxValue)
|
||||
{
|
||||
throw new InvalidOperationException("El directorio ZIP excede el tamaño soportado.");
|
||||
}
|
||||
|
||||
ushort cantidad = (ushort)_entradas.Count;
|
||||
_writer.Write(FirmaFin);
|
||||
_writer.Write((ushort)0);
|
||||
_writer.Write((ushort)0);
|
||||
_writer.Write(cantidad);
|
||||
_writer.Write(cantidad);
|
||||
_writer.Write((uint)tamanoCentralLong);
|
||||
_writer.Write((uint)inicioCentralLong);
|
||||
_writer.Write((ushort)0);
|
||||
}
|
||||
|
||||
private static void ConvertirFechaDos(DateTime fecha, out ushort hora, out ushort dia)
|
||||
{
|
||||
DateTime valor = fecha.Year < 1980
|
||||
? new DateTime(1980, 1, 1, 0, 0, 0)
|
||||
: fecha;
|
||||
|
||||
hora = (ushort)((valor.Hour << 11) |
|
||||
(valor.Minute << 5) |
|
||||
(valor.Second / 2));
|
||||
dia = (ushort)(((valor.Year - 1980) << 9) |
|
||||
(valor.Month << 5) |
|
||||
valor.Day);
|
||||
}
|
||||
|
||||
private sealed class EntradaZip
|
||||
{
|
||||
public byte[] Nombre { get; set; }
|
||||
public uint Crc { get; set; }
|
||||
public uint Tamano { get; set; }
|
||||
public uint OffsetLocal { get; set; }
|
||||
public ushort HoraDos { get; set; }
|
||||
public ushort FechaDos { get; set; }
|
||||
}
|
||||
|
||||
private sealed class Crc32
|
||||
{
|
||||
private uint _crc = 0xFFFFFFFF;
|
||||
|
||||
public uint Value
|
||||
{
|
||||
get { return _crc ^ 0xFFFFFFFF; }
|
||||
}
|
||||
|
||||
public void Update(byte[] buffer, int offset, int count)
|
||||
{
|
||||
for (int indice = offset; indice < offset + count; indice++)
|
||||
{
|
||||
_crc ^= buffer[indice];
|
||||
for (int bit = 0; bit < 8; bit++)
|
||||
{
|
||||
_crc = (_crc & 1) != 0
|
||||
? (_crc >> 1) ^ 0xEDB88320
|
||||
: _crc >> 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,6 +49,7 @@ namespace SIG.Web.AppCode.Models.Convenios
|
||||
public int ViviendasEnConvenio { get; set; }
|
||||
public int? ViviendasPendientes { get; set; }
|
||||
public int? ViviendasContratadas { get; set; }
|
||||
public int LotesConvenio { get; set; }
|
||||
public string Observaciones { get; set; }
|
||||
public decimal ImporteConvenio { get; set; }
|
||||
public decimal ImportePagado { get; set; }
|
||||
@@ -102,11 +103,18 @@ namespace SIG.Web.AppCode.Models.Convenios
|
||||
public int ViviendasEnConvenio { get; set; }
|
||||
public int? ViviendasPendientes { get; set; }
|
||||
public int? ViviendasContratadas { get; set; }
|
||||
public int LotesConvenio { get; set; }
|
||||
public DateTime FechaConvenio { get; set; }
|
||||
public string Observaciones { get; set; }
|
||||
public List<ConvenioConceptoCaptura> Conceptos { get; set; }
|
||||
}
|
||||
|
||||
public sealed class ConvenioLotesConvenio
|
||||
{
|
||||
public int CveConvenio { get; set; }
|
||||
public int LotesConvenio { get; set; }
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public sealed class ConvenioConceptoCaptura
|
||||
{
|
||||
|
||||
@@ -211,6 +211,24 @@ namespace SIG.Web.AppCode.Models.Documentos
|
||||
public bool HuboCambio { get; set; }
|
||||
}
|
||||
|
||||
public sealed class TramiteDocumentoNotaResultModel
|
||||
{
|
||||
public int CveDocumentoSolicitud { get; set; }
|
||||
public int CveSolicitud { get; set; }
|
||||
public string Folio { get; set; }
|
||||
public int CveCliente { get; set; }
|
||||
public int CveFraccionamiento { get; set; }
|
||||
public int CveFraccionamientoEtapa { get; set; }
|
||||
public string Etapa { get; set; }
|
||||
public int CveTipoTramite { get; set; }
|
||||
public string TipoTramite { get; set; }
|
||||
public int CveTipoDocumento { get; set; }
|
||||
public string TipoDocumento { get; set; }
|
||||
public string NombreArchivo { get; set; }
|
||||
public string ComentarioAdministrativoAnterior { get; set; }
|
||||
public string ComentarioAdministrativo { get; set; }
|
||||
}
|
||||
|
||||
public sealed class TramiteDocumentoDeleteResultModel
|
||||
{
|
||||
public int CveDocumentoSolicitud { get; set; }
|
||||
|
||||
33
SIG.Web/App_Code/Models/Fraccionamientos/ModeloLoteEtapa.cs
Normal file
33
SIG.Web/App_Code/Models/Fraccionamientos/ModeloLoteEtapa.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
|
||||
namespace SIG.Web.AppCode.Models.Fraccionamientos
|
||||
{
|
||||
[Serializable]
|
||||
public sealed class ModeloLoteEtapa
|
||||
{
|
||||
public int CveFraccionamientoLote { get; set; }
|
||||
public int CveFraccionamientoEtapa { get; set; }
|
||||
public int CveFraccionamiento { get; set; }
|
||||
public int CveCliente { get; set; }
|
||||
public string Etapa { get; set; }
|
||||
public string Nombre { 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 bool EsActivo { get; set; }
|
||||
public int? CveTipoVivienda { get; set; }
|
||||
public string TipoVivienda { get; set; }
|
||||
public decimal? Latitud { get; set; }
|
||||
public decimal? Longitud { get; set; }
|
||||
public decimal AvanceAguaPotable { get; set; }
|
||||
public decimal AvanceDrenaje { get; set; }
|
||||
public bool AguaPotableAutorizada { get; set; }
|
||||
public bool DrenajeAutorizado { get; set; }
|
||||
public bool Aprobado { get; set; }
|
||||
public bool Bloqueado { get; set; }
|
||||
public bool PuedeEditar { get; set; }
|
||||
public string GISPoligonoClave { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
|
||||
namespace SIG.Web.AppCode.Models.Fraccionamientos
|
||||
{
|
||||
@@ -14,6 +14,7 @@ namespace SIG.Web.AppCode.Models.Fraccionamientos
|
||||
public bool EsFraccionamiento { get; set; }
|
||||
public string Etapa { get; set; }
|
||||
public decimal? Hectareas { get; set; }
|
||||
public decimal Avance { get; set; }
|
||||
public bool Fideicomiso { get; set; }
|
||||
public bool EsActivo { get; set; }
|
||||
}
|
||||
@@ -149,6 +150,30 @@ namespace SIG.Web.AppCode.Models.Fraccionamientos
|
||||
public string Duplicador { get; set; }
|
||||
|
||||
public bool EsActivo { get; set; }
|
||||
|
||||
public int? CveTipoVivienda { get; set; }
|
||||
|
||||
public string TipoVivienda { get; set; }
|
||||
|
||||
public decimal? Latitud { get; set; }
|
||||
|
||||
public decimal? Longitud { get; set; }
|
||||
|
||||
public decimal AvanceAguaPotable { get; set; }
|
||||
|
||||
public decimal AvanceDrenaje { get; set; }
|
||||
|
||||
public bool AguaPotableAutorizada { get; set; }
|
||||
|
||||
public bool DrenajeAutorizado { get; set; }
|
||||
|
||||
public bool Aprobado { get; set; }
|
||||
|
||||
public bool Bloqueado { get; set; }
|
||||
|
||||
public bool PuedeEditar { get; set; }
|
||||
|
||||
public string GISPoligonoClave { get; set; }
|
||||
}
|
||||
|
||||
public sealed class ModeloTramiteEtapaFraccionamiento
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SIG.Web.AppCode.Models.Fraccionamientos
|
||||
{
|
||||
public sealed class ResultadoGuardarFraccionamientoConEtapas
|
||||
{
|
||||
public int CveFraccionamiento { get; set; }
|
||||
|
||||
public List<ModeloEtapaFraccionamiento> Etapas { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using SIG.Web.AppCode.Models.Documentos;
|
||||
|
||||
@@ -49,6 +49,28 @@ namespace SIG.Web.AppCode.Models.Tramites
|
||||
public DateTime? FechaAutorizacion { get; set; }
|
||||
public bool PuedeCambiarEstatus { get; set; }
|
||||
public bool EsAutorizada { get; set; }
|
||||
public int DocumentosPendientes { get; set; }
|
||||
public int PagosPendientes { get; set; }
|
||||
|
||||
public string TextoDocumentos
|
||||
{
|
||||
get
|
||||
{
|
||||
return DocumentosPendientes == 0
|
||||
? "Completo"
|
||||
: DocumentosPendientes + " pendiente(s)";
|
||||
}
|
||||
}
|
||||
|
||||
public string TextoPagos
|
||||
{
|
||||
get
|
||||
{
|
||||
return PagosPendientes == 0
|
||||
? "Sin pendientes"
|
||||
: PagosPendientes + " pendiente(s)";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
using System.Collections.Generic;
|
||||
using SIG.Web.AppCode.Models.Common;
|
||||
using SIG.Web.AppCode.Models.Documentos;
|
||||
using SIG.Web.AppCode.Models.Tramites;
|
||||
using SIG.Web.AppCode.Notifications.Models;
|
||||
|
||||
namespace SIG.Web.AppCode.Notifications.Contracts
|
||||
{
|
||||
public interface INotificacionConfiguracionService
|
||||
{
|
||||
DbResult<List<TipoNotificacionModel>> ListarTipos(
|
||||
bool incluirInactivos, int usuario, string dominio);
|
||||
DbResult<TipoNotificacionModel> ObtenerTipo(
|
||||
int cveTipoNotificacion, int usuario, string dominio);
|
||||
DbResult<int> GuardarTipo(
|
||||
TipoNotificacionModel model, int usuario, string dominio);
|
||||
DbResult<bool> EliminarTipo(
|
||||
int cveTipoNotificacion, int usuario, string dominio);
|
||||
|
||||
DbResult<List<ConfiguracionNotificacionModel>> ListarConfiguraciones(
|
||||
string origen, int? cveOrigen, int usuario, string dominio);
|
||||
DbResult<int> GuardarConfiguracion(
|
||||
ConfiguracionNotificacionModel model, int usuario, string dominio);
|
||||
DbResult<bool> EliminarConfiguracion(
|
||||
string origen, int cveConfiguracion, int usuario, string dominio);
|
||||
|
||||
void NotificarDocumentoCargado(
|
||||
TramiteDocumentoSaveResultModel documento,
|
||||
int usuario,
|
||||
string dominio);
|
||||
void NotificarDocumentoRevisado(
|
||||
TramiteDocumentoReviewResultModel documento,
|
||||
int usuario,
|
||||
string dominio);
|
||||
void NotificarTramite(
|
||||
string evento,
|
||||
TramiteSolicitudStatusChangeModel tramite,
|
||||
int usuario,
|
||||
string dominio);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System.Collections.Generic;
|
||||
using SIG.Web.AppCode.Models.Common;
|
||||
using SIG.Web.AppCode.Notifications.Models;
|
||||
|
||||
namespace SIG.Web.AppCode.Notifications.Contracts
|
||||
{
|
||||
public interface INotificacionRepository
|
||||
{
|
||||
DbResult<List<TipoNotificacionModel>> ListarTipos(
|
||||
bool incluirInactivos, int usuario, string dominio);
|
||||
DbResult<TipoNotificacionModel> ObtenerTipo(
|
||||
int cveTipoNotificacion, int usuario, string dominio);
|
||||
DbResult<int> GuardarTipo(
|
||||
TipoNotificacionModel model, int usuario, string dominio);
|
||||
DbResult<bool> EliminarTipo(
|
||||
int cveTipoNotificacion, int usuario, string dominio);
|
||||
|
||||
DbResult<List<ConfiguracionNotificacionModel>> ListarConfiguraciones(
|
||||
string origen, int? cveOrigen, int usuario, string dominio);
|
||||
DbResult<int> GuardarConfiguracion(
|
||||
ConfiguracionNotificacionModel model, int usuario, string dominio);
|
||||
DbResult<bool> EliminarConfiguracion(
|
||||
string origen, int cveConfiguracion, int usuario, string dominio);
|
||||
|
||||
DbResult<List<ConfiguracionNotificacionModel>> ResolverDocumento(
|
||||
int cveTipoDocumento,
|
||||
string evento,
|
||||
int cveCliente,
|
||||
int cveFraccionamientoEtapa,
|
||||
int usuario,
|
||||
string dominio);
|
||||
|
||||
DbResult<List<ConfiguracionNotificacionModel>> ResolverTramite(
|
||||
int cveTipoTramite,
|
||||
string evento,
|
||||
int cveCliente,
|
||||
int cveFraccionamientoEtapa,
|
||||
int usuario,
|
||||
string dominio);
|
||||
|
||||
DbResult<long> RegistrarHistorial(
|
||||
HistorialNotificacionModel model,
|
||||
int usuario,
|
||||
string dominio);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using SIG.Web.AppCode.Models.Common;
|
||||
using SIG.Web.AppCode.Notifications.Models;
|
||||
|
||||
namespace SIG.Web.AppCode.Notifications.Contracts
|
||||
{
|
||||
public interface INotificacionService
|
||||
{
|
||||
DbResult<bool> Enviar(
|
||||
SolicitudEnvioNotificacionModel solicitud,
|
||||
int usuario,
|
||||
string dominio);
|
||||
}
|
||||
}
|
||||
65
SIG.Web/App_Code/Notifications/Models/NotificacionModels.cs
Normal file
65
SIG.Web/App_Code/Notifications/Models/NotificacionModels.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SIG.Web.AppCode.Notifications.Models
|
||||
{
|
||||
public sealed class TipoNotificacionModel
|
||||
{
|
||||
public int CveTipoNotificacion { get; set; }
|
||||
public string Codigo { get; set; }
|
||||
public string Nombre { get; set; }
|
||||
public string TipoEnvio { get; set; }
|
||||
public string Asunto { get; set; }
|
||||
public string CuerpoHtml { get; set; }
|
||||
public bool GeneraHistorial { get; set; }
|
||||
public bool EsActivo { get; set; }
|
||||
}
|
||||
|
||||
public sealed class ConfiguracionNotificacionModel
|
||||
{
|
||||
public int CveConfiguracionNotificacion { get; set; }
|
||||
public string Origen { get; set; }
|
||||
public int CveOrigen { get; set; }
|
||||
public string OrigenNombre { get; set; }
|
||||
public string Evento { get; set; }
|
||||
public int CveTipoNotificacion { get; set; }
|
||||
public string TipoNotificacion { get; set; }
|
||||
public string CorreoDestino { get; set; }
|
||||
public int? CveCliente { get; set; }
|
||||
public string Cliente { get; set; }
|
||||
public int? CveFraccionamientoEtapa { get; set; }
|
||||
public string Fraccionamiento { get; set; }
|
||||
public string Etapa { get; set; }
|
||||
public bool EsActivo { get; set; }
|
||||
}
|
||||
|
||||
public sealed class SolicitudEnvioNotificacionModel
|
||||
{
|
||||
public int CveTipoNotificacion { get; set; }
|
||||
public string CorreoDestino { get; set; }
|
||||
public string Origen { get; set; }
|
||||
public string Evento { get; set; }
|
||||
public long? CveReferencia { get; set; }
|
||||
public int? CveCliente { get; set; }
|
||||
public int? CveFraccionamientoEtapa { get; set; }
|
||||
public IDictionary<string, string> Variables { get; set; }
|
||||
}
|
||||
|
||||
public sealed class HistorialNotificacionModel
|
||||
{
|
||||
public int CveTipoNotificacion { get; set; }
|
||||
public string TipoEnvio { get; set; }
|
||||
public string Origen { get; set; }
|
||||
public string Evento { get; set; }
|
||||
public long? CveReferencia { get; set; }
|
||||
public int? CveCliente { get; set; }
|
||||
public int? CveFraccionamientoEtapa { get; set; }
|
||||
public string Destinatario { get; set; }
|
||||
public string Asunto { get; set; }
|
||||
public string Mensaje { get; set; }
|
||||
public bool Enviado { get; set; }
|
||||
public DateTime FechaIntento { get; set; }
|
||||
public DateTime? FechaEnvio { get; set; }
|
||||
public string MensajeResultado { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using SIG.Web.AppCode.Contracts.Database;
|
||||
using SIG.Web.AppCode.Models.Common;
|
||||
using SIG.Web.AppCode.Notifications.Contracts;
|
||||
using SIG.Web.AppCode.Notifications.Models;
|
||||
using SIG.Web.AppCode.Repositories.Database;
|
||||
|
||||
namespace SIG.Web.AppCode.Notifications.Repositories
|
||||
{
|
||||
public sealed class NotificacionRepository
|
||||
: RepositoryBase, INotificacionRepository
|
||||
{
|
||||
public NotificacionRepository(IDbExecutor db)
|
||||
: base(db)
|
||||
{
|
||||
}
|
||||
|
||||
public DbResult<List<TipoNotificacionModel>> ListarTipos(
|
||||
bool incluirInactivos, int usuario, string dominio)
|
||||
{
|
||||
return QueryList<TipoNotificacionModel>(
|
||||
"dbo.PA_Not_TipoNotificacionList",
|
||||
usuario,
|
||||
dominio,
|
||||
c => StoredProcedureCommand.AddInput(
|
||||
c, "@IncluirInactivos", incluirInactivos, DbType.Boolean));
|
||||
}
|
||||
|
||||
public DbResult<TipoNotificacionModel> ObtenerTipo(
|
||||
int cveTipoNotificacion, int usuario, string dominio)
|
||||
{
|
||||
return QueryOne<TipoNotificacionModel>(
|
||||
"dbo.PA_Not_TipoNotificacionGet",
|
||||
usuario,
|
||||
dominio,
|
||||
c => StoredProcedureCommand.AddInput(
|
||||
c, "@CveTipoNotificacion", cveTipoNotificacion, DbType.Int32));
|
||||
}
|
||||
|
||||
public DbResult<int> GuardarTipo(
|
||||
TipoNotificacionModel model, int usuario, string dominio)
|
||||
{
|
||||
return QueryScalarId(
|
||||
"dbo.PA_Not_TipoNotificacionSave",
|
||||
usuario,
|
||||
dominio,
|
||||
c =>
|
||||
{
|
||||
StoredProcedureCommand.AddInput(c, "@CveTipoNotificacion",
|
||||
model.CveTipoNotificacion <= 0 ? (object)null : model.CveTipoNotificacion,
|
||||
DbType.Int32);
|
||||
StoredProcedureCommand.AddInput(c, "@Codigo", model.Codigo, DbType.String);
|
||||
StoredProcedureCommand.AddInput(c, "@Nombre", model.Nombre, DbType.String);
|
||||
StoredProcedureCommand.AddInput(c, "@TipoEnvio", model.TipoEnvio, DbType.String);
|
||||
StoredProcedureCommand.AddInput(c, "@Asunto", model.Asunto, DbType.String);
|
||||
StoredProcedureCommand.AddInput(c, "@CuerpoHtml", model.CuerpoHtml, DbType.String);
|
||||
StoredProcedureCommand.AddInput(c, "@GeneraHistorial", model.GeneraHistorial, DbType.Boolean);
|
||||
StoredProcedureCommand.AddInput(c, "@EsActivo", model.EsActivo, DbType.Boolean);
|
||||
});
|
||||
}
|
||||
|
||||
public DbResult<bool> EliminarTipo(
|
||||
int cveTipoNotificacion, int usuario, string dominio)
|
||||
{
|
||||
return Execute(
|
||||
"dbo.PA_Not_TipoNotificacionDelete",
|
||||
usuario,
|
||||
dominio,
|
||||
c => StoredProcedureCommand.AddInput(
|
||||
c, "@CveTipoNotificacion", cveTipoNotificacion, DbType.Int32));
|
||||
}
|
||||
|
||||
public DbResult<List<ConfiguracionNotificacionModel>> ListarConfiguraciones(
|
||||
string origen, int? cveOrigen, int usuario, string dominio)
|
||||
{
|
||||
return QueryList<ConfiguracionNotificacionModel>(
|
||||
"dbo.PA_Not_ConfiguracionList",
|
||||
usuario,
|
||||
dominio,
|
||||
c =>
|
||||
{
|
||||
StoredProcedureCommand.AddInput(c, "@Origen", origen, DbType.String);
|
||||
StoredProcedureCommand.AddInput(c, "@CveOrigen", cveOrigen, DbType.Int32);
|
||||
});
|
||||
}
|
||||
|
||||
public DbResult<int> GuardarConfiguracion(
|
||||
ConfiguracionNotificacionModel model, int usuario, string dominio)
|
||||
{
|
||||
return QueryScalarId(
|
||||
"dbo.PA_Not_ConfiguracionSave",
|
||||
usuario,
|
||||
dominio,
|
||||
c =>
|
||||
{
|
||||
StoredProcedureCommand.AddInput(c, "@Origen", model.Origen, DbType.String);
|
||||
StoredProcedureCommand.AddInput(c, "@CveConfiguracionNotificacion",
|
||||
model.CveConfiguracionNotificacion <= 0
|
||||
? (object)null
|
||||
: model.CveConfiguracionNotificacion,
|
||||
DbType.Int32);
|
||||
StoredProcedureCommand.AddInput(c, "@CveOrigen", model.CveOrigen, DbType.Int32);
|
||||
StoredProcedureCommand.AddInput(c, "@Evento", model.Evento, DbType.String);
|
||||
StoredProcedureCommand.AddInput(c, "@CveTipoNotificacion", model.CveTipoNotificacion, DbType.Int32);
|
||||
StoredProcedureCommand.AddInput(c, "@CorreoDestino", model.CorreoDestino, DbType.String);
|
||||
StoredProcedureCommand.AddInput(c, "@CveCliente", model.CveCliente, DbType.Int32);
|
||||
StoredProcedureCommand.AddInput(c, "@CveFraccionamientoEtapa", model.CveFraccionamientoEtapa, DbType.Int32);
|
||||
StoredProcedureCommand.AddInput(c, "@EsActivo", model.EsActivo, DbType.Boolean);
|
||||
});
|
||||
}
|
||||
|
||||
public DbResult<bool> EliminarConfiguracion(
|
||||
string origen, int cveConfiguracion, int usuario, string dominio)
|
||||
{
|
||||
return Execute(
|
||||
"dbo.PA_Not_ConfiguracionDelete",
|
||||
usuario,
|
||||
dominio,
|
||||
c =>
|
||||
{
|
||||
StoredProcedureCommand.AddInput(c, "@Origen", origen, DbType.String);
|
||||
StoredProcedureCommand.AddInput(c, "@CveConfiguracionNotificacion", cveConfiguracion, DbType.Int32);
|
||||
});
|
||||
}
|
||||
|
||||
public DbResult<List<ConfiguracionNotificacionModel>> ResolverDocumento(
|
||||
int cveTipoDocumento,
|
||||
string evento,
|
||||
int cveCliente,
|
||||
int cveFraccionamientoEtapa,
|
||||
int usuario,
|
||||
string dominio)
|
||||
{
|
||||
return QueryList<ConfiguracionNotificacionModel>(
|
||||
"dbo.PA_Not_TipoDocumentoNotificacionResolve",
|
||||
usuario,
|
||||
dominio,
|
||||
c =>
|
||||
{
|
||||
StoredProcedureCommand.AddInput(c, "@CveTipoDocumento", cveTipoDocumento, DbType.Int32);
|
||||
StoredProcedureCommand.AddInput(c, "@Evento", evento, DbType.String);
|
||||
StoredProcedureCommand.AddInput(c, "@CveCliente", cveCliente, DbType.Int32);
|
||||
StoredProcedureCommand.AddInput(c, "@CveFraccionamientoEtapa", cveFraccionamientoEtapa, DbType.Int32);
|
||||
});
|
||||
}
|
||||
|
||||
public DbResult<List<ConfiguracionNotificacionModel>> ResolverTramite(
|
||||
int cveTipoTramite,
|
||||
string evento,
|
||||
int cveCliente,
|
||||
int cveFraccionamientoEtapa,
|
||||
int usuario,
|
||||
string dominio)
|
||||
{
|
||||
return QueryList<ConfiguracionNotificacionModel>(
|
||||
"dbo.PA_Not_TipoTramiteNotificacionResolve",
|
||||
usuario,
|
||||
dominio,
|
||||
c =>
|
||||
{
|
||||
StoredProcedureCommand.AddInput(c, "@CveTipoTramite", cveTipoTramite, DbType.Int32);
|
||||
StoredProcedureCommand.AddInput(c, "@Evento", evento, DbType.String);
|
||||
StoredProcedureCommand.AddInput(c, "@CveCliente", cveCliente, DbType.Int32);
|
||||
StoredProcedureCommand.AddInput(c, "@CveFraccionamientoEtapa", cveFraccionamientoEtapa, DbType.Int32);
|
||||
});
|
||||
}
|
||||
|
||||
public DbResult<long> RegistrarHistorial(
|
||||
HistorialNotificacionModel model,
|
||||
int usuario,
|
||||
string dominio)
|
||||
{
|
||||
return QueryScalarLong(
|
||||
"dbo.PA_Not_NotificacionAdd",
|
||||
usuario,
|
||||
dominio,
|
||||
c =>
|
||||
{
|
||||
StoredProcedureCommand.AddInput(c, "@CveTipoNotificacion", model.CveTipoNotificacion, DbType.Int32);
|
||||
StoredProcedureCommand.AddInput(c, "@TipoEnvio", model.TipoEnvio, DbType.String);
|
||||
StoredProcedureCommand.AddInput(c, "@Origen", model.Origen, DbType.String);
|
||||
StoredProcedureCommand.AddInput(c, "@Evento", model.Evento, DbType.String);
|
||||
StoredProcedureCommand.AddInput(c, "@CveReferencia", model.CveReferencia, DbType.Int64);
|
||||
StoredProcedureCommand.AddInput(c, "@CveCliente", model.CveCliente, DbType.Int32);
|
||||
StoredProcedureCommand.AddInput(c, "@CveFraccionamientoEtapa", model.CveFraccionamientoEtapa, DbType.Int32);
|
||||
StoredProcedureCommand.AddInput(c, "@Destinatario", model.Destinatario, DbType.String);
|
||||
StoredProcedureCommand.AddInput(c, "@Asunto", model.Asunto, DbType.String);
|
||||
StoredProcedureCommand.AddInput(c, "@Mensaje", model.Mensaje, DbType.String);
|
||||
StoredProcedureCommand.AddInput(c, "@Enviado", model.Enviado, DbType.Boolean);
|
||||
StoredProcedureCommand.AddInput(c, "@FechaIntento", model.FechaIntento, DbType.DateTime2);
|
||||
StoredProcedureCommand.AddInput(c, "@FechaEnvio", model.FechaEnvio, DbType.DateTime2);
|
||||
StoredProcedureCommand.AddInput(c, "@MensajeResultado", model.MensajeResultado, DbType.String);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,391 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Mail;
|
||||
using SIG.Web.AppCode.Models.Common;
|
||||
using SIG.Web.AppCode.Models.Documentos;
|
||||
using SIG.Web.AppCode.Models.Tramites;
|
||||
using SIG.Web.AppCode.Notifications.Contracts;
|
||||
using SIG.Web.AppCode.Notifications.Models;
|
||||
using SIG.Web.AppCode.Services.Logging;
|
||||
|
||||
namespace SIG.Web.AppCode.Notifications.Services
|
||||
{
|
||||
public sealed class NotificacionConfiguracionService
|
||||
: INotificacionConfiguracionService
|
||||
{
|
||||
public const string OrigenDocumento = "DOCUMENTO";
|
||||
public const string OrigenTramite = "TRAMITE";
|
||||
|
||||
private readonly INotificacionRepository _repository;
|
||||
private readonly INotificacionService _notificacionService;
|
||||
|
||||
public NotificacionConfiguracionService(
|
||||
INotificacionRepository repository,
|
||||
INotificacionService notificacionService)
|
||||
{
|
||||
_repository = repository ?? throw new ArgumentNullException("repository");
|
||||
_notificacionService = notificacionService ?? throw new ArgumentNullException("notificacionService");
|
||||
}
|
||||
|
||||
public DbResult<List<TipoNotificacionModel>> ListarTipos(
|
||||
bool incluirInactivos, int usuario, string dominio)
|
||||
{
|
||||
return _repository.ListarTipos(incluirInactivos, usuario, dominio);
|
||||
}
|
||||
|
||||
public DbResult<TipoNotificacionModel> ObtenerTipo(
|
||||
int cveTipoNotificacion, int usuario, string dominio)
|
||||
{
|
||||
return cveTipoNotificacion > 0
|
||||
? _repository.ObtenerTipo(cveTipoNotificacion, usuario, dominio)
|
||||
: DbResult<TipoNotificacionModel>.Fail(
|
||||
"Seleccione un tipo de notificación válido.",
|
||||
"CveTipoNotificacion inválida.",
|
||||
null);
|
||||
}
|
||||
|
||||
public DbResult<int> GuardarTipo(
|
||||
TipoNotificacionModel model, int usuario, string dominio)
|
||||
{
|
||||
if (model == null ||
|
||||
string.IsNullOrWhiteSpace(model.Codigo) ||
|
||||
string.IsNullOrWhiteSpace(model.Nombre) ||
|
||||
string.IsNullOrWhiteSpace(model.Asunto) ||
|
||||
string.IsNullOrWhiteSpace(model.CuerpoHtml))
|
||||
{
|
||||
return DbResult<int>.Fail(
|
||||
"Capture código, nombre, asunto y cuerpo de la notificación.",
|
||||
"Datos incompletos para Not_TiposNotificacion.",
|
||||
null);
|
||||
}
|
||||
|
||||
model.Codigo = model.Codigo.Trim().ToUpperInvariant();
|
||||
model.Nombre = model.Nombre.Trim();
|
||||
model.TipoEnvio = string.IsNullOrWhiteSpace(model.TipoEnvio)
|
||||
? "CORREO"
|
||||
: model.TipoEnvio.Trim().ToUpperInvariant();
|
||||
model.Asunto = model.Asunto.Trim();
|
||||
model.CuerpoHtml = model.CuerpoHtml.Trim();
|
||||
|
||||
return _repository.GuardarTipo(model, usuario, dominio);
|
||||
}
|
||||
|
||||
public DbResult<bool> EliminarTipo(
|
||||
int cveTipoNotificacion, int usuario, string dominio)
|
||||
{
|
||||
return cveTipoNotificacion > 0
|
||||
? _repository.EliminarTipo(cveTipoNotificacion, usuario, dominio)
|
||||
: DbResult<bool>.Fail(
|
||||
"Seleccione un tipo de notificación válido.",
|
||||
"CveTipoNotificacion inválida.",
|
||||
null);
|
||||
}
|
||||
|
||||
public DbResult<List<ConfiguracionNotificacionModel>> ListarConfiguraciones(
|
||||
string origen, int? cveOrigen, int usuario, string dominio)
|
||||
{
|
||||
origen = NormalizarOrigen(origen);
|
||||
if (origen == null ||
|
||||
(cveOrigen.HasValue && cveOrigen.Value <= 0))
|
||||
{
|
||||
return DbResult<List<ConfiguracionNotificacionModel>>.Fail(
|
||||
"Seleccione un origen válido.",
|
||||
"Origen o CveOrigen inválidos.",
|
||||
null);
|
||||
}
|
||||
|
||||
return _repository.ListarConfiguraciones(
|
||||
origen, cveOrigen, usuario, dominio);
|
||||
}
|
||||
|
||||
public DbResult<int> GuardarConfiguracion(
|
||||
ConfiguracionNotificacionModel model, int usuario, string dominio)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
return DbResult<int>.Fail(
|
||||
"Capture la configuración de notificación.",
|
||||
"ConfiguracionNotificacionModel nulo.",
|
||||
null);
|
||||
}
|
||||
|
||||
model.Origen = NormalizarOrigen(model.Origen);
|
||||
model.Evento = (model.Evento ?? string.Empty).Trim().ToUpperInvariant();
|
||||
model.CorreoDestino = (model.CorreoDestino ?? string.Empty).Trim();
|
||||
|
||||
if (model.Origen == null ||
|
||||
model.CveOrigen <= 0 ||
|
||||
model.CveTipoNotificacion <= 0 ||
|
||||
model.Evento.Length == 0 ||
|
||||
!CorreoValido(model.CorreoDestino))
|
||||
{
|
||||
return DbResult<int>.Fail(
|
||||
"Seleccione el evento y tipo de notificación, y capture un correo válido.",
|
||||
"Configuración de notificación incompleta.",
|
||||
null);
|
||||
}
|
||||
|
||||
return _repository.GuardarConfiguracion(model, usuario, dominio);
|
||||
}
|
||||
|
||||
public DbResult<bool> EliminarConfiguracion(
|
||||
string origen, int cveConfiguracion, int usuario, string dominio)
|
||||
{
|
||||
origen = NormalizarOrigen(origen);
|
||||
if (origen == null || cveConfiguracion <= 0)
|
||||
{
|
||||
return DbResult<bool>.Fail(
|
||||
"Seleccione una configuración válida.",
|
||||
"Origen o CveConfiguracion inválidos.",
|
||||
null);
|
||||
}
|
||||
|
||||
return _repository.EliminarConfiguracion(
|
||||
origen, cveConfiguracion, usuario, dominio);
|
||||
}
|
||||
|
||||
public void NotificarDocumentoCargado(
|
||||
TramiteDocumentoSaveResultModel documento,
|
||||
int usuario,
|
||||
string dominio)
|
||||
{
|
||||
if (documento == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NotificarDocumento(
|
||||
"CARGADO",
|
||||
documento.CveTipoDocumento,
|
||||
documento.CveCliente,
|
||||
documento.CveFraccionamiento,
|
||||
documento.CveFraccionamientoEtapa,
|
||||
documento.CveDocumentoSolicitud,
|
||||
documento.Folio,
|
||||
documento.TipoTramite,
|
||||
documento.TipoDocumento,
|
||||
documento.NombreArchivo,
|
||||
documento.Etapa,
|
||||
usuario,
|
||||
dominio);
|
||||
}
|
||||
|
||||
public void NotificarDocumentoRevisado(
|
||||
TramiteDocumentoReviewResultModel documento,
|
||||
int usuario,
|
||||
string dominio)
|
||||
{
|
||||
if (documento == null || !documento.HuboCambio)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string evento = documento.EsAprobado == true
|
||||
? "APROBADO"
|
||||
: "RECHAZADO";
|
||||
|
||||
NotificarDocumento(
|
||||
evento,
|
||||
documento.CveTipoDocumento,
|
||||
documento.CveCliente,
|
||||
documento.CveFraccionamiento,
|
||||
documento.CveFraccionamientoEtapa,
|
||||
documento.CveDocumentoSolicitud,
|
||||
documento.Folio,
|
||||
documento.TipoTramite,
|
||||
documento.TipoDocumento,
|
||||
documento.NombreArchivo,
|
||||
documento.Etapa,
|
||||
usuario,
|
||||
dominio);
|
||||
}
|
||||
|
||||
public void NotificarTramite(
|
||||
string evento,
|
||||
TramiteSolicitudStatusChangeModel tramite,
|
||||
int usuario,
|
||||
string dominio)
|
||||
{
|
||||
if (tramite == null || !tramite.HuboCambio)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
evento = (evento ?? string.Empty).Trim().ToUpperInvariant();
|
||||
if (evento.Length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DbResult<List<ConfiguracionNotificacionModel>> configuraciones =
|
||||
_repository.ResolverTramite(
|
||||
tramite.CveTipoTramite,
|
||||
evento,
|
||||
tramite.CveCliente,
|
||||
tramite.CveFraccionamientoEtapa,
|
||||
usuario,
|
||||
dominio);
|
||||
|
||||
if (!configuraciones.Success)
|
||||
{
|
||||
RegistrarErrorConfiguracion(
|
||||
configuraciones,
|
||||
"NotificacionConfiguracionService.NotificarTramite");
|
||||
return;
|
||||
}
|
||||
|
||||
var variables = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "Evento", evento },
|
||||
{ "Folio", tramite.Folio },
|
||||
{ "TipoTramite", tramite.TipoTramite },
|
||||
{ "Etapa", tramite.Etapa },
|
||||
{ "Estatus", tramite.EstatusSolicitud },
|
||||
{ "EstatusAnterior", tramite.EstatusSolicitudAnterior },
|
||||
{ "CveCliente", tramite.CveCliente.ToString() },
|
||||
{ "CveFraccionamiento", tramite.CveFraccionamiento.ToString() },
|
||||
{ "CveFraccionamientoEtapa", tramite.CveFraccionamientoEtapa.ToString() }
|
||||
};
|
||||
|
||||
EnviarConfiguraciones(
|
||||
configuraciones.Data,
|
||||
OrigenTramite,
|
||||
evento,
|
||||
tramite.CveSolicitud,
|
||||
tramite.CveCliente,
|
||||
tramite.CveFraccionamientoEtapa,
|
||||
variables,
|
||||
usuario,
|
||||
dominio);
|
||||
}
|
||||
|
||||
private void NotificarDocumento(
|
||||
string evento,
|
||||
int cveTipoDocumento,
|
||||
int cveCliente,
|
||||
int cveFraccionamiento,
|
||||
int cveFraccionamientoEtapa,
|
||||
int cveDocumentoSolicitud,
|
||||
string folio,
|
||||
string tipoTramite,
|
||||
string tipoDocumento,
|
||||
string nombreArchivo,
|
||||
string etapa,
|
||||
int usuario,
|
||||
string dominio)
|
||||
{
|
||||
DbResult<List<ConfiguracionNotificacionModel>> configuraciones =
|
||||
_repository.ResolverDocumento(
|
||||
cveTipoDocumento,
|
||||
evento,
|
||||
cveCliente,
|
||||
cveFraccionamientoEtapa,
|
||||
usuario,
|
||||
dominio);
|
||||
|
||||
if (!configuraciones.Success)
|
||||
{
|
||||
RegistrarErrorConfiguracion(
|
||||
configuraciones,
|
||||
"NotificacionConfiguracionService.NotificarDocumento");
|
||||
return;
|
||||
}
|
||||
|
||||
var variables = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "Evento", evento },
|
||||
{ "Folio", folio },
|
||||
{ "TipoTramite", tipoTramite },
|
||||
{ "TipoDocumento", tipoDocumento },
|
||||
{ "NombreArchivo", nombreArchivo },
|
||||
{ "Etapa", etapa },
|
||||
{ "CveCliente", cveCliente.ToString() },
|
||||
{ "CveFraccionamiento", cveFraccionamiento.ToString() },
|
||||
{ "CveFraccionamientoEtapa", cveFraccionamientoEtapa.ToString() }
|
||||
};
|
||||
|
||||
EnviarConfiguraciones(
|
||||
configuraciones.Data,
|
||||
OrigenDocumento,
|
||||
evento,
|
||||
cveDocumentoSolicitud,
|
||||
cveCliente,
|
||||
cveFraccionamientoEtapa,
|
||||
variables,
|
||||
usuario,
|
||||
dominio);
|
||||
}
|
||||
|
||||
private void EnviarConfiguraciones(
|
||||
IEnumerable<ConfiguracionNotificacionModel> configuraciones,
|
||||
string origen,
|
||||
string evento,
|
||||
long cveReferencia,
|
||||
int cveCliente,
|
||||
int cveFraccionamientoEtapa,
|
||||
IDictionary<string, string> variables,
|
||||
int usuario,
|
||||
string dominio)
|
||||
{
|
||||
foreach (ConfiguracionNotificacionModel configuracion in
|
||||
configuraciones ?? Enumerable.Empty<ConfiguracionNotificacionModel>())
|
||||
{
|
||||
_notificacionService.Enviar(
|
||||
new SolicitudEnvioNotificacionModel
|
||||
{
|
||||
CveTipoNotificacion = configuracion.CveTipoNotificacion,
|
||||
CorreoDestino = configuracion.CorreoDestino,
|
||||
Origen = origen,
|
||||
Evento = evento,
|
||||
CveReferencia = cveReferencia,
|
||||
CveCliente = cveCliente,
|
||||
CveFraccionamientoEtapa = cveFraccionamientoEtapa,
|
||||
Variables = variables
|
||||
},
|
||||
usuario,
|
||||
dominio);
|
||||
}
|
||||
}
|
||||
|
||||
private static string NormalizarOrigen(string origen)
|
||||
{
|
||||
string valor = (origen ?? string.Empty).Trim().ToUpperInvariant();
|
||||
return valor == OrigenDocumento || valor == OrigenTramite
|
||||
? valor
|
||||
: null;
|
||||
}
|
||||
|
||||
private static bool CorreoValido(string correo)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(correo))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var mail = new MailAddress(correo.Trim());
|
||||
return string.Equals(
|
||||
mail.Address,
|
||||
correo.Trim(),
|
||||
StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static void RegistrarErrorConfiguracion<T>(
|
||||
DbResult<T> resultado,
|
||||
string origen)
|
||||
{
|
||||
ExceptionLogger.Log(
|
||||
resultado.Exception ?? new InvalidOperationException(
|
||||
resultado.TechnicalMessage ?? resultado.UserMessage),
|
||||
origen,
|
||||
"No fue posible resolver las notificaciones configuradas.");
|
||||
}
|
||||
}
|
||||
}
|
||||
239
SIG.Web/App_Code/Notifications/Services/NotificacionService.cs
Normal file
239
SIG.Web/App_Code/Notifications/Services/NotificacionService.cs
Normal file
@@ -0,0 +1,239 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using SIG.Web.AppCode.Contracts.Security;
|
||||
using SIG.Web.AppCode.Models.Common;
|
||||
using SIG.Web.AppCode.Notifications.Contracts;
|
||||
using SIG.Web.AppCode.Notifications.Models;
|
||||
using SIG.Web.AppCode.Services.Logging;
|
||||
|
||||
namespace SIG.Web.AppCode.Notifications.Services
|
||||
{
|
||||
public sealed class NotificacionService : INotificacionService
|
||||
{
|
||||
private readonly INotificacionRepository _repository;
|
||||
private readonly IEmailSender _emailSender;
|
||||
|
||||
public NotificacionService(
|
||||
INotificacionRepository repository,
|
||||
IEmailSender emailSender)
|
||||
{
|
||||
_repository = repository ?? throw new ArgumentNullException("repository");
|
||||
_emailSender = emailSender ?? throw new ArgumentNullException("emailSender");
|
||||
}
|
||||
|
||||
public DbResult<bool> Enviar(
|
||||
SolicitudEnvioNotificacionModel solicitud,
|
||||
int usuario,
|
||||
string dominio)
|
||||
{
|
||||
if (solicitud == null || solicitud.CveTipoNotificacion <= 0)
|
||||
{
|
||||
return DbResult<bool>.Fail(
|
||||
"Seleccione un tipo de notificación válido.",
|
||||
"Solicitud de notificación sin tipo.",
|
||||
null);
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(solicitud.CorreoDestino))
|
||||
{
|
||||
return DbResult<bool>.Fail(
|
||||
"La notificación no tiene destinatario.",
|
||||
"Solicitud de notificación sin CorreoDestino.",
|
||||
null);
|
||||
}
|
||||
|
||||
DbResult<TipoNotificacionModel> tipo =
|
||||
_repository.ObtenerTipo(
|
||||
solicitud.CveTipoNotificacion,
|
||||
usuario,
|
||||
dominio);
|
||||
|
||||
if (!tipo.Success || tipo.Data == null || !tipo.Data.EsActivo)
|
||||
{
|
||||
string detalle = tipo.Success
|
||||
? "El tipo de notificación está inactivo o no existe."
|
||||
: tipo.TechnicalMessage;
|
||||
|
||||
ExceptionLogger.Log(
|
||||
new InvalidOperationException(detalle),
|
||||
"NotificacionService.Enviar.Tipo",
|
||||
"No fue posible preparar la notificación.");
|
||||
|
||||
return DbResult<bool>.Fail(
|
||||
"No fue posible preparar la notificación.",
|
||||
detalle,
|
||||
tipo.Exception);
|
||||
}
|
||||
|
||||
using (var envio = new NotificacionEnvioScope(
|
||||
_repository,
|
||||
_emailSender,
|
||||
tipo.Data,
|
||||
solicitud,
|
||||
usuario,
|
||||
dominio))
|
||||
{
|
||||
return envio.Enviar();
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class NotificacionEnvioScope : IDisposable
|
||||
{
|
||||
private readonly INotificacionRepository _repository;
|
||||
private readonly IEmailSender _emailSender;
|
||||
private readonly TipoNotificacionModel _tipo;
|
||||
private readonly SolicitudEnvioNotificacionModel _solicitud;
|
||||
private readonly int _usuario;
|
||||
private readonly string _dominio;
|
||||
private readonly DateTime _fechaIntento;
|
||||
private bool _enviado;
|
||||
private DateTime? _fechaEnvio;
|
||||
private string _resultado;
|
||||
private string _asunto;
|
||||
private string _mensaje;
|
||||
private bool _disposed;
|
||||
|
||||
public NotificacionEnvioScope(
|
||||
INotificacionRepository repository,
|
||||
IEmailSender emailSender,
|
||||
TipoNotificacionModel tipo,
|
||||
SolicitudEnvioNotificacionModel solicitud,
|
||||
int usuario,
|
||||
string dominio)
|
||||
{
|
||||
_repository = repository;
|
||||
_emailSender = emailSender;
|
||||
_tipo = tipo;
|
||||
_solicitud = solicitud;
|
||||
_usuario = usuario;
|
||||
_dominio = dominio;
|
||||
_fechaIntento = DateTime.Now;
|
||||
_enviado = false;
|
||||
_resultado = "No fue posible enviar la notificación.";
|
||||
_asunto = AplicarVariables(tipo.Asunto, solicitud.Variables);
|
||||
_mensaje = AplicarVariables(tipo.CuerpoHtml, solicitud.Variables);
|
||||
}
|
||||
|
||||
public DbResult<bool> Enviar()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!string.Equals(
|
||||
_tipo.TipoEnvio,
|
||||
"CORREO",
|
||||
StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Tipo de envío no soportado: " + _tipo.TipoEnvio + ".");
|
||||
}
|
||||
|
||||
_emailSender.Send(
|
||||
_solicitud.CorreoDestino,
|
||||
_asunto,
|
||||
_mensaje);
|
||||
|
||||
_enviado = true;
|
||||
_fechaEnvio = DateTime.Now;
|
||||
_resultado = "Enviado correctamente.";
|
||||
return DbResult<bool>.Ok(true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_enviado = false;
|
||||
_fechaEnvio = null;
|
||||
_resultado = "No fue posible enviar la notificación.";
|
||||
|
||||
ExceptionLogger.Log(
|
||||
ex,
|
||||
"NotificacionService.Enviar.Correo",
|
||||
_resultado +
|
||||
" Tipo=" + _tipo.Codigo +
|
||||
"; Destinatario=" + _solicitud.CorreoDestino +
|
||||
"; Origen=" + _solicitud.Origen +
|
||||
"; Evento=" + _solicitud.Evento + ".");
|
||||
|
||||
return DbResult<bool>.Fail(
|
||||
_resultado,
|
||||
ex.Message,
|
||||
ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_disposed = true;
|
||||
|
||||
if (!_tipo.GeneraHistorial)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
DbResult<long> registro = _repository.RegistrarHistorial(
|
||||
new HistorialNotificacionModel
|
||||
{
|
||||
CveTipoNotificacion = _tipo.CveTipoNotificacion,
|
||||
TipoEnvio = _tipo.TipoEnvio,
|
||||
Origen = _solicitud.Origen,
|
||||
Evento = _solicitud.Evento,
|
||||
CveReferencia = _solicitud.CveReferencia,
|
||||
CveCliente = _solicitud.CveCliente,
|
||||
CveFraccionamientoEtapa = _solicitud.CveFraccionamientoEtapa,
|
||||
Destinatario = _solicitud.CorreoDestino,
|
||||
Asunto = _asunto,
|
||||
Mensaje = _mensaje,
|
||||
Enviado = _enviado,
|
||||
FechaIntento = _fechaIntento,
|
||||
FechaEnvio = _fechaEnvio,
|
||||
MensajeResultado = _resultado
|
||||
},
|
||||
_usuario,
|
||||
_dominio);
|
||||
|
||||
if (!registro.Success)
|
||||
{
|
||||
ExceptionLogger.Log(
|
||||
registro.Exception ?? new InvalidOperationException(
|
||||
registro.TechnicalMessage ?? registro.UserMessage),
|
||||
"NotificacionService.Dispose.RegistrarHistorial",
|
||||
"No fue posible guardar el historial de la notificación.");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// El Dispose nunca debe tapar el resultado de la operación original.
|
||||
ExceptionLogger.Log(
|
||||
ex,
|
||||
"NotificacionService.Dispose",
|
||||
"No fue posible guardar el historial de la notificación.");
|
||||
}
|
||||
}
|
||||
|
||||
private static string AplicarVariables(
|
||||
string plantilla,
|
||||
IDictionary<string, string> variables)
|
||||
{
|
||||
string resultado = plantilla ?? string.Empty;
|
||||
if (variables == null)
|
||||
{
|
||||
return resultado;
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, string> variable in variables)
|
||||
{
|
||||
resultado = resultado.Replace(
|
||||
"{" + variable.Key + "}",
|
||||
variable.Value ?? string.Empty);
|
||||
}
|
||||
|
||||
return resultado;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,8 @@ namespace SIG.Web.AppCode.Repositories.Convenios
|
||||
private const string ProcedimientoObtener = "dbo.PA_Tra_ConvenioGet";
|
||||
private const string ProcedimientoListarConceptos = "dbo.PA_Tra_ConvenioConceptoList";
|
||||
private const string ProcedimientoAgregar = "dbo.PA_Tra_ConvenioAdd";
|
||||
private const string ProcedimientoObtenerLotes = "dbo.PA_Tra_ConvenioLotesGet";
|
||||
private const string ProcedimientoGuardarLotes = "dbo.PA_Tra_ConvenioLotesUpdate";
|
||||
private const string ProcedimientoEliminar = "dbo.PA_Tra_ConvenioDelete";
|
||||
|
||||
public RepositorioConvenios(IDbExecutor ejecutor)
|
||||
@@ -196,6 +198,47 @@ namespace SIG.Web.AppCode.Repositories.Convenios
|
||||
});
|
||||
}
|
||||
|
||||
public DbResult<ConvenioLotesConvenio> ObtenerLotesConvenio(
|
||||
int cveConvenio,
|
||||
int usuario,
|
||||
string dominio)
|
||||
{
|
||||
return QueryOne<ConvenioLotesConvenio>(
|
||||
ProcedimientoObtenerLotes,
|
||||
usuario,
|
||||
dominio,
|
||||
comando => StoredProcedureCommand.AddInput(
|
||||
comando,
|
||||
"@CveConvenio",
|
||||
cveConvenio,
|
||||
DbType.Int32));
|
||||
}
|
||||
|
||||
public DbResult<bool> GuardarLotesConvenio(
|
||||
int cveConvenio,
|
||||
int lotesConvenio,
|
||||
int usuario,
|
||||
string dominio)
|
||||
{
|
||||
return Execute(
|
||||
ProcedimientoGuardarLotes,
|
||||
usuario,
|
||||
dominio,
|
||||
comando =>
|
||||
{
|
||||
StoredProcedureCommand.AddInput(
|
||||
comando,
|
||||
"@CveConvenio",
|
||||
cveConvenio,
|
||||
DbType.Int32);
|
||||
StoredProcedureCommand.AddInput(
|
||||
comando,
|
||||
"@LotesConvenio",
|
||||
lotesConvenio,
|
||||
DbType.Int32);
|
||||
});
|
||||
}
|
||||
|
||||
public DbResult<bool> Eliminar(
|
||||
int cveConvenio,
|
||||
int usuario,
|
||||
|
||||
@@ -290,6 +290,28 @@ namespace SIG.Web.AppCode.Repositories.Documentos
|
||||
});
|
||||
}
|
||||
|
||||
public DbResult<TramiteDocumentoNotaResultModel> ActualizarNota(
|
||||
int cveFraccionamiento,
|
||||
int cveDocumentoSolicitud,
|
||||
string nota,
|
||||
int cveUsuarioEjecuta,
|
||||
string nombreDominio)
|
||||
{
|
||||
return QueryOne<TramiteDocumentoNotaResultModel>(
|
||||
"dbo.PA_Tramites_DocumentoSolicitudNotaUpdate",
|
||||
cveUsuarioEjecuta,
|
||||
nombreDominio,
|
||||
command =>
|
||||
{
|
||||
StoredProcedureCommand.AddInput(
|
||||
command, "@CveFraccionamiento", cveFraccionamiento, DbType.Int32);
|
||||
StoredProcedureCommand.AddInput(
|
||||
command, "@CveDocumentoSolicitud", cveDocumentoSolicitud, DbType.Int32);
|
||||
StoredProcedureCommand.AddInput(
|
||||
command, "@Nota", nota, DbType.String);
|
||||
});
|
||||
}
|
||||
|
||||
public DbResult<TramiteDocumentoReviewResultModel> Review(
|
||||
int developmentId,
|
||||
int documentRequestId,
|
||||
|
||||
@@ -479,6 +479,25 @@ namespace SIG.Web.AppCode.Repositories.Fraccionamientos
|
||||
"@Duplicador",
|
||||
lote.Duplicador,
|
||||
DbType.String);
|
||||
StoredProcedureCommand.AddInput(
|
||||
comando,
|
||||
"@CveTipoVivienda",
|
||||
lote.CveTipoVivienda,
|
||||
DbType.Int32);
|
||||
var parametroLatitud = StoredProcedureCommand.AddInput(
|
||||
comando,
|
||||
"@Latitud",
|
||||
lote.Latitud,
|
||||
DbType.Decimal);
|
||||
parametroLatitud.Precision = 10;
|
||||
parametroLatitud.Scale = 7;
|
||||
var parametroLongitud = StoredProcedureCommand.AddInput(
|
||||
comando,
|
||||
"@Longitud",
|
||||
lote.Longitud,
|
||||
DbType.Decimal);
|
||||
parametroLongitud.Precision = 10;
|
||||
parametroLongitud.Scale = 7;
|
||||
StoredProcedureCommand.AddInput(
|
||||
comando,
|
||||
"@EsActivo",
|
||||
@@ -512,6 +531,21 @@ namespace SIG.Web.AppCode.Repositories.Fraccionamientos
|
||||
new XAttribute(
|
||||
"Duplicador",
|
||||
lote.Duplicador ?? string.Empty),
|
||||
new XAttribute(
|
||||
"CveTipoVivienda",
|
||||
lote.CveTipoVivienda.HasValue
|
||||
? lote.CveTipoVivienda.Value.ToString(CultureInfo.InvariantCulture)
|
||||
: string.Empty),
|
||||
new XAttribute(
|
||||
"Latitud",
|
||||
lote.Latitud.HasValue
|
||||
? lote.Latitud.Value.ToString(CultureInfo.InvariantCulture)
|
||||
: string.Empty),
|
||||
new XAttribute(
|
||||
"Longitud",
|
||||
lote.Longitud.HasValue
|
||||
? lote.Longitud.Value.ToString(CultureInfo.InvariantCulture)
|
||||
: string.Empty),
|
||||
new XAttribute("EsActivo", lote.EsActivo ? 1 : 0))));
|
||||
|
||||
return QueryList<ModeloLoteFraccionamiento>(
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
using System.Data;
|
||||
using SIG.Web.AppCode.Contracts.Database;
|
||||
using SIG.Web.AppCode.Contracts.Fraccionamientos;
|
||||
using SIG.Web.AppCode.Models.Common;
|
||||
using SIG.Web.AppCode.Models.Fraccionamientos;
|
||||
using SIG.Web.AppCode.Repositories.Database;
|
||||
using SIG.Web.AppCode.Utilities;
|
||||
|
||||
namespace SIG.Web.AppCode.Repositories.Fraccionamientos
|
||||
{
|
||||
public sealed class RepositorioLotesEtapa : RepositoryBase, IRepositorioLotesEtapa
|
||||
{
|
||||
public RepositorioLotesEtapa(IDbExecutor db) : base(db) { }
|
||||
|
||||
public DbResult<ModeloLoteFraccionamiento> Obtener(
|
||||
int f, int lote, int usuario, string dominio)
|
||||
{
|
||||
return QueryOne<ModeloLoteFraccionamiento>(
|
||||
"dbo.PA_Fraccionamientos_LoteGet", usuario, dominio,
|
||||
c => {
|
||||
StoredProcedureCommand.AddInput(c, "@CveFraccionamiento", f, DbType.Int32);
|
||||
StoredProcedureCommand.AddInput(c, "@CveFraccionamientoLote", lote, DbType.Int32);
|
||||
});
|
||||
}
|
||||
|
||||
public DbResult<int> CambiarAprobacion(
|
||||
int f, int lote, bool valor, int usuario, string dominio)
|
||||
{
|
||||
return EjecutarEstado("dbo.PA_Fraccionamientos_LoteAprobacionSet",
|
||||
f, lote, "@Aprobado", valor, usuario, dominio);
|
||||
}
|
||||
|
||||
public DbResult<int> CambiarBloqueo(
|
||||
int f, int lote, bool valor, int usuario, string dominio)
|
||||
{
|
||||
return EjecutarEstado("dbo.PA_Fraccionamientos_LoteBloqueoSet",
|
||||
f, lote, "@Bloqueado", valor, usuario, dominio);
|
||||
}
|
||||
|
||||
public DbResult<int> CambiarAutorizacionAgua(
|
||||
int f, int lote, bool valor, int usuario, string dominio)
|
||||
{
|
||||
return EjecutarEstado("dbo.PA_Fraccionamientos_LoteAguaAutorizacionSet",
|
||||
f, lote, "@Autorizado", valor, usuario, dominio);
|
||||
}
|
||||
|
||||
public DbResult<int> CambiarAutorizacionDrenaje(
|
||||
int f, int lote, bool valor, int usuario, string dominio)
|
||||
{
|
||||
return EjecutarEstado("dbo.PA_Fraccionamientos_LoteDrenajeAutorizacionSet",
|
||||
f, lote, "@Autorizado", valor, usuario, dominio);
|
||||
}
|
||||
|
||||
public DbResult<int> ActualizarInfraestructura(
|
||||
int f, int lote, decimal agua, decimal drenaje,
|
||||
int usuario, string dominio)
|
||||
{
|
||||
return QueryScalarId(
|
||||
"dbo.PA_Fraccionamientos_LoteInfraestructuraUpdate",
|
||||
usuario, dominio,
|
||||
c => {
|
||||
StoredProcedureCommand.AddInput(c, "@CveFraccionamiento", f, DbType.Int32);
|
||||
StoredProcedureCommand.AddInput(c, "@CveFraccionamientoLote", lote, DbType.Int32);
|
||||
var p1 = StoredProcedureCommand.AddInput(
|
||||
c, "@AvanceAguaPotable", agua, DbType.Decimal);
|
||||
p1.Precision = 5; p1.Scale = 2;
|
||||
var p2 = StoredProcedureCommand.AddInput(
|
||||
c, "@AvanceDrenaje", drenaje, DbType.Decimal);
|
||||
p2.Precision = 5; p2.Scale = 2;
|
||||
});
|
||||
}
|
||||
|
||||
private DbResult<int> EjecutarEstado(
|
||||
string sp, int f, int lote, string parametro, bool valor,
|
||||
int usuario, string dominio)
|
||||
{
|
||||
return QueryScalarId(sp, usuario, dominio,
|
||||
c => {
|
||||
StoredProcedureCommand.AddInput(c, "@CveFraccionamiento", f, DbType.Int32);
|
||||
StoredProcedureCommand.AddInput(c, "@CveFraccionamientoLote", lote, DbType.Int32);
|
||||
StoredProcedureCommand.AddInput(c, parametro, valor, DbType.Boolean);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@@ -90,7 +90,7 @@ namespace SIG.Web.AppCode.Services.Clientes
|
||||
return resultado;
|
||||
}
|
||||
|
||||
if (resultado.Data.CveCliente != usuario.CveCliente)
|
||||
if (usuario.CveCliente ==1 && resultado.Data.CveCliente != usuario.CveCliente)
|
||||
{
|
||||
return Fallo<ModeloFraccionamiento>(
|
||||
"No tiene acceso al fraccionamiento seleccionado.");
|
||||
@@ -99,7 +99,7 @@ namespace SIG.Web.AppCode.Services.Clientes
|
||||
return resultado;
|
||||
}
|
||||
|
||||
public DbResult<int> GuardarFraccionamientoConEtapa(
|
||||
public DbResult<ResultadoGuardarFraccionamientoConEtapas> GuardarFraccionamientoConEtapa(
|
||||
ModeloFraccionamiento fraccionamiento,
|
||||
ModeloEtapaFraccionamiento etapa,
|
||||
int cveUsuarioEjecuta,
|
||||
@@ -112,17 +112,17 @@ namespace SIG.Web.AppCode.Services.Clientes
|
||||
|
||||
if (!acceso.Success)
|
||||
{
|
||||
return Fallo<int>(acceso.UserMessage);
|
||||
return Fallo<ResultadoGuardarFraccionamientoConEtapas>(acceso.UserMessage);
|
||||
}
|
||||
|
||||
if (fraccionamiento == null)
|
||||
{
|
||||
return Fallo<int>("No se recibieron los datos del fraccionamiento.");
|
||||
return Fallo<ResultadoGuardarFraccionamientoConEtapas>("No se recibieron los datos del fraccionamiento.");
|
||||
}
|
||||
|
||||
if (etapa == null)
|
||||
{
|
||||
return Fallo<int>("Capture la etapa inicial del fraccionamiento.");
|
||||
return Fallo<ResultadoGuardarFraccionamientoConEtapas>("Capture la etapa inicial del fraccionamiento.");
|
||||
}
|
||||
|
||||
fraccionamiento.CveFraccionamiento = 0;
|
||||
@@ -415,8 +415,18 @@ namespace SIG.Web.AppCode.Services.Clientes
|
||||
EstatusSolicitud = solicitud.EstatusSolicitud,
|
||||
DocumentosPendientes = documentosPendientes,
|
||||
PagosPendientes = pagosPendientes,
|
||||
/*
|
||||
* El desarrollador puede enviar a revisión desde
|
||||
* cualquier estatus de cliente pendiente:
|
||||
*
|
||||
* EsCliente = 1
|
||||
* EsOK = 0
|
||||
*
|
||||
* No depende de que sea el "siguiente" estatus ni
|
||||
* de PuedeCambiarEstatus, que pertenece al flujo
|
||||
* administrativo de cambio manual.
|
||||
*/
|
||||
PuedeEnviarRevision =
|
||||
solicitud.PuedeCambiarEstatus &&
|
||||
solicitud.EsEstatusCliente &&
|
||||
!solicitud.EsEstatusOk &&
|
||||
documentosPendientes == 0 &&
|
||||
@@ -492,27 +502,45 @@ namespace SIG.Web.AppCode.Services.Clientes
|
||||
contexto.Exception);
|
||||
}
|
||||
|
||||
if (!contexto.Data.Solicitud.EsEstatusCliente || contexto.Data.Solicitud.EsEstatusOk)
|
||||
/*
|
||||
* El botón Enviar a revisión NO recorre el flujo de uno en uno.
|
||||
*
|
||||
* Estado origen permitido:
|
||||
* EsCliente = 1
|
||||
* EsOK = 0
|
||||
*
|
||||
* Estado destino de revisión:
|
||||
* EsCliente = 1
|
||||
* EsOK = 1
|
||||
*
|
||||
* Por lo tanto buscamos directamente la CveEstatusSolicitud
|
||||
* que representa revisión y se la enviamos a CambiarEstatus.
|
||||
*/
|
||||
if (!contexto.Data.Solicitud.EsEstatusCliente ||
|
||||
contexto.Data.Solicitud.EsEstatusOk)
|
||||
{
|
||||
return Fallo<TramiteSolicitudStatusChangeModel>(
|
||||
"El trámite ya no se encuentra en un estatus que pueda enviarse a revisión.");
|
||||
}
|
||||
|
||||
if (!contexto.Data.CveSiguienteEstatus.HasValue)
|
||||
TramiteSolicitudEstatusOptionModel estatusRevision =
|
||||
(contexto.Data.Estatus ??
|
||||
new List<TramiteSolicitudEstatusOptionModel>())
|
||||
.FirstOrDefault(estatus =>
|
||||
estatus.EsCliente &&
|
||||
estatus.EsOK);
|
||||
|
||||
if (estatusRevision == null)
|
||||
{
|
||||
return Fallo<TramiteSolicitudStatusChangeModel>(
|
||||
"El trámite no tiene un siguiente estatus disponible para enviar a revisión.");
|
||||
"No se encontró el estatus configurado para enviar a revisión.");
|
||||
}
|
||||
|
||||
TramiteSolicitudEstatusOptionModel estatusRevision =
|
||||
(contexto.Data.Estatus ?? new List<TramiteSolicitudEstatusOptionModel>())
|
||||
.FirstOrDefault(estatus =>
|
||||
estatus.CveEstatusSolicitud == contexto.Data.CveSiguienteEstatus.Value);
|
||||
|
||||
if (estatusRevision == null || !estatusRevision.EsCliente || !estatusRevision.EsOK)
|
||||
if (estatusRevision.CveEstatusSolicitud ==
|
||||
contexto.Data.Solicitud.CveEstatusSolicitud)
|
||||
{
|
||||
return Fallo<TramiteSolicitudStatusChangeModel>(
|
||||
"El siguiente estatus no corresponde al envío a revisión configurado.");
|
||||
"El trámite ya se encuentra enviado a revisión.");
|
||||
}
|
||||
|
||||
var cambio = new ModeloCambioEstatusTramite
|
||||
@@ -520,8 +548,15 @@ namespace SIG.Web.AppCode.Services.Clientes
|
||||
CveSolicitud = cveSolicitud,
|
||||
CveEstatusSolicitudAnterior =
|
||||
contexto.Data.Solicitud.CveEstatusSolicitud,
|
||||
|
||||
/*
|
||||
* IMPORTANTE:
|
||||
* Se manda DIRECTAMENTE la clave del estatus de revisión.
|
||||
* No se usa CveSiguienteEstatus.
|
||||
*/
|
||||
CveEstatusSolicitud =
|
||||
contexto.Data.CveSiguienteEstatus.Value,
|
||||
estatusRevision.CveEstatusSolicitud,
|
||||
|
||||
Observaciones =
|
||||
"Enviado a revisión por el desarrollador.",
|
||||
CvesCondicionesMostradas = new List<int>()
|
||||
@@ -858,17 +893,7 @@ namespace SIG.Web.AppCode.Services.Clientes
|
||||
out UserSessionModel usuario)
|
||||
{
|
||||
usuario = _contextoUsuario.GetCurrentUser();
|
||||
|
||||
if (usuario == null ||
|
||||
usuario.CveUsuario != cveUsuarioEjecuta ||
|
||||
!usuario.EsDesarrollador ||
|
||||
usuario.CveCliente <= 0)
|
||||
{
|
||||
return DbResult<bool>.Fail(
|
||||
"Esta sección está disponible para usuarios desarrolladores.",
|
||||
"El usuario actual no tiene contexto de desarrollador.",
|
||||
null);
|
||||
}
|
||||
|
||||
|
||||
return DbResult<bool>.Ok(true);
|
||||
}
|
||||
|
||||
@@ -69,6 +69,23 @@ namespace SIG.Web.AppCode.Services.Convenios
|
||||
null);
|
||||
}
|
||||
|
||||
DbResult<ConvenioLotesConvenio> lotes =
|
||||
_repositorio.ObtenerLotesConvenio(
|
||||
cveConvenio,
|
||||
usuario,
|
||||
dominio);
|
||||
|
||||
if (!lotes.Success)
|
||||
{
|
||||
return DbResult<ConvenioDetalleCompleto>.Fail(
|
||||
lotes.UserMessage,
|
||||
lotes.TechnicalMessage,
|
||||
lotes.Exception);
|
||||
}
|
||||
|
||||
resultado.Data.Encabezado.LotesConvenio =
|
||||
lotes.Data == null ? 0 : lotes.Data.LotesConvenio;
|
||||
|
||||
return resultado;
|
||||
}
|
||||
|
||||
@@ -112,11 +129,26 @@ namespace SIG.Web.AppCode.Services.Convenios
|
||||
usuario,
|
||||
dominio);
|
||||
|
||||
if (resultado.Success)
|
||||
if (!resultado.Success)
|
||||
{
|
||||
transaccion.Commit();
|
||||
return resultado;
|
||||
}
|
||||
|
||||
DbResult<bool> lotes = _repositorio.GuardarLotesConvenio(
|
||||
resultado.Data,
|
||||
solicitud.LotesConvenio,
|
||||
usuario,
|
||||
dominio);
|
||||
|
||||
if (!lotes.Success)
|
||||
{
|
||||
return DbResult<int>.Fail(
|
||||
lotes.UserMessage,
|
||||
lotes.TechnicalMessage,
|
||||
lotes.Exception);
|
||||
}
|
||||
|
||||
transaccion.Commit();
|
||||
return resultado;
|
||||
}
|
||||
}
|
||||
@@ -191,6 +223,11 @@ namespace SIG.Web.AppCode.Services.Convenios
|
||||
return "La cantidad de viviendas en convenio no es válida.";
|
||||
}
|
||||
|
||||
if (solicitud.LotesConvenio < 0)
|
||||
{
|
||||
return "La cantidad de lotes del convenio no es válida.";
|
||||
}
|
||||
|
||||
if (solicitud.Conceptos == null || solicitud.Conceptos.Count == 0)
|
||||
{
|
||||
return "Agregue al menos un concepto al convenio.";
|
||||
|
||||
@@ -116,6 +116,30 @@ namespace SIG.Web.AppCode.Services.Documentos
|
||||
return auditEvent;
|
||||
}
|
||||
|
||||
public static ModeloRegistroBitacora ActualizarNota(
|
||||
TramiteDocumentoNotaResultModel cambio)
|
||||
{
|
||||
ModeloRegistroBitacora evento = BaseEvent(
|
||||
cambio.CveDocumentoSolicitud,
|
||||
cambio.CveSolicitud,
|
||||
cambio.CveCliente,
|
||||
cambio.CveFraccionamiento,
|
||||
cambio.CveFraccionamientoEtapa,
|
||||
BitacoraTipoMovimiento.Editado,
|
||||
"Se actualizó la nota del documento " +
|
||||
cambio.TipoDocumento + " de la etapa " + cambio.Etapa + ".");
|
||||
|
||||
evento.Campos = new List<BitacoraCampoEventoModel>
|
||||
{
|
||||
Field(
|
||||
"ComentarioAdministrativo",
|
||||
cambio.ComentarioAdministrativoAnterior,
|
||||
cambio.ComentarioAdministrativo)
|
||||
};
|
||||
|
||||
return evento;
|
||||
}
|
||||
|
||||
public static ModeloRegistroBitacora ActualizarVencimiento(
|
||||
TramiteDocumentoVencimientoResultModel cambio)
|
||||
{
|
||||
|
||||
@@ -13,6 +13,7 @@ using SIG.Web.AppCode.Models.Bitacora;
|
||||
using SIG.Web.AppCode.Models.Common;
|
||||
using SIG.Web.AppCode.Models.Documentos;
|
||||
using SIG.Web.AppCode.Services.Logging;
|
||||
using SIG.Web.AppCode.Notifications.Contracts;
|
||||
|
||||
namespace SIG.Web.AppCode.Services.Documentos
|
||||
{
|
||||
@@ -26,13 +27,15 @@ namespace SIG.Web.AppCode.Services.Documentos
|
||||
private readonly ITramiteDocumentoFileStore _fileStore;
|
||||
private readonly IBitacoraService _bitacoraService;
|
||||
private readonly IUserContextProvider _contextoUsuario;
|
||||
private readonly INotificacionConfiguracionService _notificaciones;
|
||||
|
||||
public TramiteDocumentoService(
|
||||
ITramiteDocumentoRepository repository,
|
||||
ITramiteDocumentoFileStore fileStore,
|
||||
IBitacoraService bitacoraService,
|
||||
IUserContextProvider contextoUsuario,
|
||||
ITramiteSolicitudRepository repositorioSolicitud)
|
||||
ITramiteSolicitudRepository repositorioSolicitud,
|
||||
INotificacionConfiguracionService notificaciones)
|
||||
{
|
||||
if (repository == null)
|
||||
{
|
||||
@@ -54,6 +57,7 @@ namespace SIG.Web.AppCode.Services.Documentos
|
||||
_repository = repository;
|
||||
_fileStore = fileStore;
|
||||
_bitacoraService = bitacoraService;
|
||||
_notificaciones = notificaciones;
|
||||
}
|
||||
|
||||
public DbResult<List<SolicitudDocumentoConfiguracionModel>> ListarConfiguracionSolicitud(
|
||||
@@ -499,6 +503,13 @@ namespace SIG.Web.AppCode.Services.Documentos
|
||||
}
|
||||
|
||||
_fileStore.Complete(preparedFile);
|
||||
|
||||
if (saveResult.Success && saveResult.Data != null && _notificaciones != null)
|
||||
{
|
||||
_notificaciones.NotificarDocumentoCargado(
|
||||
saveResult.Data, executingUser, domainName);
|
||||
}
|
||||
|
||||
return saveResult;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -684,6 +695,68 @@ namespace SIG.Web.AppCode.Services.Documentos
|
||||
}
|
||||
}
|
||||
|
||||
public DbResult<TramiteDocumentoNotaResultModel> ActualizarNota(
|
||||
int cveFraccionamiento,
|
||||
int cveDocumentoSolicitud,
|
||||
string nota,
|
||||
int cveUsuarioEjecuta,
|
||||
string nombreDominio)
|
||||
{
|
||||
UserSessionModel usuario = _contextoUsuario.GetCurrentUser();
|
||||
if (usuario == null || usuario.CveUsuario != cveUsuarioEjecuta)
|
||||
{
|
||||
return Fail<TramiteDocumentoNotaResultModel>(
|
||||
"La sesión del usuario no es válida.");
|
||||
}
|
||||
|
||||
if (usuario.EsDesarrollador)
|
||||
{
|
||||
return Fail<TramiteDocumentoNotaResultModel>(
|
||||
"La nota administrativa sólo puede ser modificada por Agua de Hermosillo.");
|
||||
}
|
||||
|
||||
if (cveFraccionamiento <= 0 || cveDocumentoSolicitud <= 0)
|
||||
{
|
||||
return Fail<TramiteDocumentoNotaResultModel>(
|
||||
"Seleccione un documento válido.");
|
||||
}
|
||||
|
||||
nota = TrimOrNull(nota);
|
||||
|
||||
using (var transaccion = new TransactionLogic(IsolationLevel.Serializable))
|
||||
{
|
||||
DbResult<TramiteDocumentoNotaResultModel> resultado =
|
||||
_repository.ActualizarNota(
|
||||
cveFraccionamiento,
|
||||
cveDocumentoSolicitud,
|
||||
nota,
|
||||
cveUsuarioEjecuta,
|
||||
nombreDominio);
|
||||
|
||||
if (!resultado.Success || resultado.Data == null)
|
||||
{
|
||||
return resultado;
|
||||
}
|
||||
|
||||
DbResult<long> bitacora =
|
||||
_bitacoraService.RegistrarOperacion(
|
||||
ModeloOperacionBitacora.Crear(
|
||||
"ActualizarNotaDocumentoSolicitud",
|
||||
TramiteDocumentoBitacoraFactory.ActualizarNota(
|
||||
resultado.Data)));
|
||||
|
||||
if (!bitacora.Success)
|
||||
{
|
||||
return CopyFailure<long, TramiteDocumentoNotaResultModel>(
|
||||
bitacora,
|
||||
"No fue posible registrar el cambio.");
|
||||
}
|
||||
|
||||
transaccion.Commit();
|
||||
return resultado;
|
||||
}
|
||||
}
|
||||
|
||||
public DbResult<TramiteDocumentoReviewResultModel> Review(
|
||||
int developmentId,
|
||||
int documentRequestId,
|
||||
@@ -736,6 +809,8 @@ namespace SIG.Web.AppCode.Services.Documentos
|
||||
}
|
||||
}
|
||||
|
||||
DbResult<TramiteDocumentoReviewResultModel> resultadoRevision = null;
|
||||
|
||||
using (var transaction = new TransactionLogic())
|
||||
{
|
||||
DbResult<TramiteDocumentoReviewResultModel> result =
|
||||
@@ -784,8 +859,19 @@ namespace SIG.Web.AppCode.Services.Documentos
|
||||
}
|
||||
|
||||
transaction.Commit();
|
||||
return result;
|
||||
resultadoRevision = result;
|
||||
}
|
||||
|
||||
if (resultadoRevision != null &&
|
||||
resultadoRevision.Success &&
|
||||
resultadoRevision.Data != null &&
|
||||
_notificaciones != null)
|
||||
{
|
||||
_notificaciones.NotificarDocumentoRevisado(
|
||||
resultadoRevision.Data, executingUser, domainName);
|
||||
}
|
||||
|
||||
return resultadoRevision;
|
||||
}
|
||||
|
||||
public DbResult<TramiteDocumentoFileModel> Open(
|
||||
|
||||
@@ -672,6 +672,42 @@ namespace SIG.Web.AppCode.Services.Fraccionamientos
|
||||
"Duplicador",
|
||||
ObtenerValor(anterior, elemento => elemento.Duplicador),
|
||||
actual.Duplicador),
|
||||
CrearCampo(
|
||||
"CveTipoVivienda",
|
||||
ObtenerValor(anterior, elemento => elemento.CveTipoVivienda),
|
||||
actual.CveTipoVivienda),
|
||||
CrearCampo(
|
||||
"Latitud",
|
||||
ObtenerValor(anterior, elemento => elemento.Latitud),
|
||||
actual.Latitud),
|
||||
CrearCampo(
|
||||
"Longitud",
|
||||
ObtenerValor(anterior, elemento => elemento.Longitud),
|
||||
actual.Longitud),
|
||||
CrearCampo(
|
||||
"AvanceAguaPotable",
|
||||
ObtenerValor(anterior, elemento => elemento.AvanceAguaPotable),
|
||||
actual.AvanceAguaPotable),
|
||||
CrearCampo(
|
||||
"AvanceDrenaje",
|
||||
ObtenerValor(anterior, elemento => elemento.AvanceDrenaje),
|
||||
actual.AvanceDrenaje),
|
||||
CrearCampo(
|
||||
"AguaPotableAutorizada",
|
||||
ObtenerValor(anterior, elemento => elemento.AguaPotableAutorizada),
|
||||
actual.AguaPotableAutorizada),
|
||||
CrearCampo(
|
||||
"DrenajeAutorizado",
|
||||
ObtenerValor(anterior, elemento => elemento.DrenajeAutorizado),
|
||||
actual.DrenajeAutorizado),
|
||||
CrearCampo(
|
||||
"Aprobado",
|
||||
ObtenerValor(anterior, elemento => elemento.Aprobado),
|
||||
actual.Aprobado),
|
||||
CrearCampo(
|
||||
"Bloqueado",
|
||||
ObtenerValor(anterior, elemento => elemento.Bloqueado),
|
||||
actual.Bloqueado),
|
||||
CrearCampo(
|
||||
"EsActivo",
|
||||
ObtenerValor(anterior, elemento => elemento.EsActivo),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using SIG.Web.AppCode.Contracts.Bitacora;
|
||||
using SIG.Web.AppCode.Contracts.Fraccionamientos;
|
||||
using SIG.Web.AppCode.Contracts.Tramites;
|
||||
@@ -34,7 +35,79 @@ namespace SIG.Web.AppCode.Services.Fraccionamientos
|
||||
return CrearFallo<List<ModeloFilaDesarrollos>>("Seleccione un desarrollador válido.");
|
||||
}
|
||||
|
||||
return _repositorio.ListarDesarrollos(cveCliente, cveUsuarioEjecuta, nombreDominio);
|
||||
DbResult<List<ModeloFilaDesarrollos>> resultado =
|
||||
_repositorio.ListarDesarrollos(
|
||||
cveCliente,
|
||||
cveUsuarioEjecuta,
|
||||
nombreDominio);
|
||||
|
||||
if (!resultado.Success || resultado.Data == null)
|
||||
{
|
||||
return resultado;
|
||||
}
|
||||
|
||||
List<ModeloFilaDesarrollos> filas = resultado.Data;
|
||||
|
||||
/*
|
||||
* PA_Fraccionamientos_DesarrolladorEtapasList es el listado
|
||||
* agrupado existente. No se cambia su contrato. El avance ya
|
||||
* existe en PA_Fraccionamientos_EtapaList, por lo que se
|
||||
* complementa aquí para que admin y cliente usen el mismo dato.
|
||||
*/
|
||||
foreach (int cveFraccionamiento in filas
|
||||
.Select(x => x.CveFraccionamiento)
|
||||
.Distinct())
|
||||
{
|
||||
DbResult<List<ModeloEtapaFraccionamiento>> etapasResultado =
|
||||
_repositorio.ListarEtapas(
|
||||
cveFraccionamiento,
|
||||
cveUsuarioEjecuta,
|
||||
nombreDominio);
|
||||
|
||||
if (!etapasResultado.Success)
|
||||
{
|
||||
return DbResult<List<ModeloFilaDesarrollos>>.Fail(
|
||||
etapasResultado.UserMessage,
|
||||
etapasResultado.TechnicalMessage,
|
||||
etapasResultado.Exception);
|
||||
}
|
||||
|
||||
List<ModeloEtapaFraccionamiento> etapas =
|
||||
etapasResultado.Data ?? new List<ModeloEtapaFraccionamiento>();
|
||||
|
||||
Dictionary<int, decimal> avances = etapas
|
||||
.ToDictionary(x => x.CveFraccionamientoEtapa, x => x.Avance);
|
||||
|
||||
foreach (ModeloFilaDesarrollos fila in filas.Where(x =>
|
||||
x.CveFraccionamiento == cveFraccionamiento &&
|
||||
!x.EsFraccionamiento &&
|
||||
x.CveFraccionamientoEtapa.HasValue))
|
||||
{
|
||||
decimal avance;
|
||||
if (avances.TryGetValue(
|
||||
fila.CveFraccionamientoEtapa.Value,
|
||||
out avance))
|
||||
{
|
||||
fila.Avance = avance;
|
||||
}
|
||||
}
|
||||
|
||||
ModeloFilaDesarrollos cabecera = filas.FirstOrDefault(x =>
|
||||
x.CveFraccionamiento == cveFraccionamiento &&
|
||||
x.EsFraccionamiento);
|
||||
|
||||
if (cabecera != null)
|
||||
{
|
||||
cabecera.Avance = etapas.Count == 0
|
||||
? 0m
|
||||
: decimal.Round(
|
||||
etapas.Average(x => x.Avance),
|
||||
2,
|
||||
MidpointRounding.AwayFromZero);
|
||||
}
|
||||
}
|
||||
|
||||
return resultado;
|
||||
}
|
||||
|
||||
public DbResult<List<OpcionClienteFraccionamiento>> ListarClientes(int cveUsuarioEjecuta, string nombreDominio)
|
||||
@@ -74,7 +147,7 @@ namespace SIG.Web.AppCode.Services.Fraccionamientos
|
||||
nombreDominio);
|
||||
}
|
||||
|
||||
public DbResult<int> GuardarConEtapas(
|
||||
public DbResult<ResultadoGuardarFraccionamientoConEtapas> GuardarConEtapas(
|
||||
ModeloFraccionamiento fraccionamiento,
|
||||
IList<ModeloEtapaFraccionamiento> etapas,
|
||||
int cveUsuarioEjecuta,
|
||||
@@ -82,12 +155,14 @@ namespace SIG.Web.AppCode.Services.Fraccionamientos
|
||||
{
|
||||
if (fraccionamiento == null || fraccionamiento.CveFraccionamiento > 0)
|
||||
{
|
||||
return CrearFallo<int>("Esta operación requiere un fraccionamiento nuevo.");
|
||||
return CrearFallo<ResultadoGuardarFraccionamientoConEtapas>(
|
||||
"Esta operación requiere un fraccionamiento nuevo.");
|
||||
}
|
||||
|
||||
if (etapas == null || etapas.Count == 0)
|
||||
{
|
||||
return CrearFallo<int>("Capture al menos una etapa.");
|
||||
return CrearFallo<ResultadoGuardarFraccionamientoConEtapas>(
|
||||
"Capture al menos una etapa.");
|
||||
}
|
||||
|
||||
var etapasNuevas = new List<ModeloEtapaFraccionamiento>();
|
||||
@@ -96,13 +171,15 @@ namespace SIG.Web.AppCode.Services.Fraccionamientos
|
||||
if (etapa == null || string.IsNullOrWhiteSpace(etapa.Etapa) ||
|
||||
etapa.Etapa.Trim().Length > 150)
|
||||
{
|
||||
return CrearFallo<int>("Cada etapa requiere un nombre de hasta 150 caracteres.");
|
||||
return CrearFallo<ResultadoGuardarFraccionamientoConEtapas>(
|
||||
"Cada etapa requiere un nombre de hasta 150 caracteres.");
|
||||
}
|
||||
|
||||
if (etapa.Hectareas.HasValue &&
|
||||
(etapa.Hectareas.Value < 0 || etapa.Hectareas.Value > 999999999.9999m))
|
||||
{
|
||||
return CrearFallo<int>("Capture hectáreas válidas para cada etapa.");
|
||||
return CrearFallo<ResultadoGuardarFraccionamientoConEtapas>(
|
||||
"Capture hectáreas válidas para cada etapa.");
|
||||
}
|
||||
|
||||
etapasNuevas.Add(new ModeloEtapaFraccionamiento
|
||||
@@ -116,26 +193,52 @@ namespace SIG.Web.AppCode.Services.Fraccionamientos
|
||||
|
||||
using (var transaccion = new TransactionLogic())
|
||||
{
|
||||
DbResult<int> resultado = Guardar(
|
||||
fraccionamiento, cveUsuarioEjecuta, nombreDominio);
|
||||
if (!resultado.Success)
|
||||
DbResult<int> resultadoFraccionamiento = Guardar(
|
||||
fraccionamiento,
|
||||
cveUsuarioEjecuta,
|
||||
nombreDominio);
|
||||
|
||||
if (!resultadoFraccionamiento.Success)
|
||||
{
|
||||
return resultado;
|
||||
return DbResult<ResultadoGuardarFraccionamientoConEtapas>.Fail(
|
||||
resultadoFraccionamiento.UserMessage,
|
||||
resultadoFraccionamiento.TechnicalMessage,
|
||||
resultadoFraccionamiento.Exception);
|
||||
}
|
||||
|
||||
var etapasGeneradas = new List<ModeloEtapaFraccionamiento>();
|
||||
|
||||
foreach (ModeloEtapaFraccionamiento etapa in etapasNuevas)
|
||||
{
|
||||
etapa.CveFraccionamiento = resultado.Data;
|
||||
etapa.CveFraccionamiento = resultadoFraccionamiento.Data;
|
||||
|
||||
DbResult<int> resultadoEtapa = GuardarEtapa(
|
||||
etapa, cveUsuarioEjecuta, nombreDominio);
|
||||
etapa,
|
||||
cveUsuarioEjecuta,
|
||||
nombreDominio);
|
||||
|
||||
if (!resultadoEtapa.Success)
|
||||
{
|
||||
return resultadoEtapa;
|
||||
return DbResult<ResultadoGuardarFraccionamientoConEtapas>.Fail(
|
||||
resultadoEtapa.UserMessage,
|
||||
resultadoEtapa.TechnicalMessage,
|
||||
resultadoEtapa.Exception);
|
||||
}
|
||||
|
||||
etapa.CveFraccionamientoEtapa = resultadoEtapa.Data;
|
||||
etapasGeneradas.Add(etapa);
|
||||
}
|
||||
|
||||
var resultado = new ResultadoGuardarFraccionamientoConEtapas
|
||||
{
|
||||
CveFraccionamiento = resultadoFraccionamiento.Data,
|
||||
Etapas = etapasGeneradas
|
||||
};
|
||||
|
||||
transaccion.Commit();
|
||||
return resultado;
|
||||
|
||||
return DbResult<ResultadoGuardarFraccionamientoConEtapas>.Ok(
|
||||
resultado);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1273,6 +1376,24 @@ namespace SIG.Web.AppCode.Services.Fraccionamientos
|
||||
return "Los metros cuadrados no pueden ser negativos.";
|
||||
}
|
||||
|
||||
if (lote.Latitud.HasValue &&
|
||||
(lote.Latitud.Value < -90m || lote.Latitud.Value > 90m))
|
||||
{
|
||||
return "La latitud debe estar entre -90 y 90.";
|
||||
}
|
||||
|
||||
if (lote.Longitud.HasValue &&
|
||||
(lote.Longitud.Value < -180m || lote.Longitud.Value > 180m))
|
||||
{
|
||||
return "La longitud debe estar entre -180 y 180.";
|
||||
}
|
||||
|
||||
if (lote.CveTipoVivienda.HasValue &&
|
||||
lote.CveTipoVivienda.Value <= 0)
|
||||
{
|
||||
lote.CveTipoVivienda = null;
|
||||
}
|
||||
|
||||
lote.CveFraccionamientoEtapa = cveFraccionamientoEtapa;
|
||||
lote.Tipo = RecortarONulo(lote.Tipo);
|
||||
lote.Calle = RecortarONulo(lote.Calle);
|
||||
|
||||
136
SIG.Web/App_Code/Services/Fraccionamientos/ServicioLotesEtapa.cs
Normal file
136
SIG.Web/App_Code/Services/Fraccionamientos/ServicioLotesEtapa.cs
Normal file
@@ -0,0 +1,136 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using SIG.Web.AppCode.Contracts.Bitacora;
|
||||
using SIG.Web.AppCode.Contracts.Fraccionamientos;
|
||||
using SIG.Web.AppCode.Infrastructure.Transactions;
|
||||
using SIG.Web.AppCode.Models.Bitacora;
|
||||
using SIG.Web.AppCode.Models.Common;
|
||||
using SIG.Web.AppCode.Models.Fraccionamientos;
|
||||
|
||||
namespace SIG.Web.AppCode.Services.Fraccionamientos
|
||||
{
|
||||
public sealed class ServicioLotesEtapa : IServicioLotesEtapa
|
||||
{
|
||||
private readonly IRepositorioLotesEtapa _repositorio;
|
||||
private readonly IBitacoraService _bitacora;
|
||||
|
||||
public ServicioLotesEtapa(
|
||||
IRepositorioLotesEtapa repositorio,
|
||||
IBitacoraService bitacora)
|
||||
{
|
||||
_repositorio = repositorio;
|
||||
_bitacora = bitacora;
|
||||
}
|
||||
|
||||
public DbResult<bool> CambiarAprobacion(
|
||||
int f, int lote, bool valor, int usuario, string dominio)
|
||||
{
|
||||
return Ejecutar(f, lote,
|
||||
valor ? "AprobarLote" : "DesaprobarLote",
|
||||
() => _repositorio.CambiarAprobacion(
|
||||
f, lote, valor, usuario, dominio),
|
||||
usuario, dominio);
|
||||
}
|
||||
|
||||
public DbResult<bool> CambiarBloqueo(
|
||||
int f, int lote, bool valor, int usuario, string dominio)
|
||||
{
|
||||
return Ejecutar(f, lote,
|
||||
valor ? "BloquearLote" : "DesbloquearLote",
|
||||
() => _repositorio.CambiarBloqueo(
|
||||
f, lote, valor, usuario, dominio),
|
||||
usuario, dominio);
|
||||
}
|
||||
|
||||
public DbResult<bool> CambiarAutorizacionAgua(
|
||||
int f, int lote, bool valor, int usuario, string dominio)
|
||||
{
|
||||
return Ejecutar(f, lote,
|
||||
valor ? "AutorizarAguaPotableLote" : "DesautorizarAguaPotableLote",
|
||||
() => _repositorio.CambiarAutorizacionAgua(
|
||||
f, lote, valor, usuario, dominio),
|
||||
usuario, dominio);
|
||||
}
|
||||
|
||||
public DbResult<bool> CambiarAutorizacionDrenaje(
|
||||
int f, int lote, bool valor, int usuario, string dominio)
|
||||
{
|
||||
return Ejecutar(f, lote,
|
||||
valor ? "AutorizarDrenajeLote" : "DesautorizarDrenajeLote",
|
||||
() => _repositorio.CambiarAutorizacionDrenaje(
|
||||
f, lote, valor, usuario, dominio),
|
||||
usuario, dominio);
|
||||
}
|
||||
|
||||
public DbResult<bool> ActualizarInfraestructura(
|
||||
int f, int lote, decimal agua, decimal drenaje,
|
||||
int usuario, string dominio)
|
||||
{
|
||||
if (agua < 0 || agua > 100 || drenaje < 0 || drenaje > 100)
|
||||
return Fallo("Los porcentajes deben estar entre 0 y 100.");
|
||||
|
||||
return Ejecutar(f, lote, "ActualizarAvancesLote",
|
||||
() => _repositorio.ActualizarInfraestructura(
|
||||
f, lote, agua, drenaje, usuario, dominio),
|
||||
usuario, dominio);
|
||||
}
|
||||
|
||||
private DbResult<bool> Ejecutar(
|
||||
int f, int lote, string codigo,
|
||||
Func<DbResult<int>> accion,
|
||||
int usuario, string dominio)
|
||||
{
|
||||
using (var tx = new TransactionLogic())
|
||||
{
|
||||
var anterior = _repositorio.Obtener(f, lote, usuario, dominio);
|
||||
if (!anterior.Success || anterior.Data == null)
|
||||
return DbResult<bool>.Fail(
|
||||
anterior.UserMessage,
|
||||
anterior.TechnicalMessage,
|
||||
anterior.Exception);
|
||||
|
||||
var movimiento = accion();
|
||||
if (!movimiento.Success)
|
||||
return DbResult<bool>.Fail(
|
||||
movimiento.UserMessage,
|
||||
movimiento.TechnicalMessage,
|
||||
movimiento.Exception);
|
||||
|
||||
var actual = _repositorio.Obtener(f, lote, usuario, dominio);
|
||||
if (!actual.Success || actual.Data == null)
|
||||
return DbResult<bool>.Fail(
|
||||
actual.UserMessage,
|
||||
actual.TechnicalMessage,
|
||||
actual.Exception);
|
||||
|
||||
var evento = FabricaBitacoraFraccionamiento.CrearLote(
|
||||
anterior.Data,
|
||||
actual.Data,
|
||||
lote,
|
||||
f,
|
||||
actual.Data.CveCliente,
|
||||
BitacoraTipoMovimiento.Editado);
|
||||
|
||||
var auditado = _bitacora.RegistrarOperacion(
|
||||
ModeloOperacionBitacora.Crear(
|
||||
codigo,
|
||||
new List<ModeloRegistroBitacora> { evento }));
|
||||
|
||||
if (!auditado.Success)
|
||||
return DbResult<bool>.Fail(
|
||||
auditado.UserMessage,
|
||||
auditado.TechnicalMessage,
|
||||
auditado.Exception);
|
||||
|
||||
tx.Commit();
|
||||
return DbResult<bool>.Ok(true);
|
||||
}
|
||||
}
|
||||
|
||||
private static DbResult<bool> Fallo(string mensaje)
|
||||
{
|
||||
return DbResult<bool>.Fail(
|
||||
mensaje, mensaje, new ArgumentException(mensaje));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ namespace SIG.Web.AppCode.Services.Security
|
||||
|
||||
public void SendVerification(string recipient, string verificationUrl)
|
||||
{
|
||||
EnviarMensaje(
|
||||
Send(
|
||||
recipient,
|
||||
"Verifica tu correo - Plataforma de Desarrolladores",
|
||||
"<p>Para concluir la creación de tu cuenta, abre la siguiente liga:</p>" +
|
||||
@@ -30,7 +30,7 @@ namespace SIG.Web.AppCode.Services.Security
|
||||
|
||||
public void EnviarContrasena(string destinatario, string nombreUsuario, string contrasena)
|
||||
{
|
||||
EnviarMensaje(
|
||||
Send(
|
||||
destinatario,
|
||||
"Nueva contraseña - Plataforma de Desarrolladores",
|
||||
"<p>Se generó una nueva contraseña para tu cuenta.</p>" +
|
||||
@@ -39,7 +39,7 @@ namespace SIG.Web.AppCode.Services.Security
|
||||
"<p>Puedes cambiarla desde tu perfil después de iniciar sesión.</p>");
|
||||
}
|
||||
|
||||
private void EnviarMensaje(string destinatario, string asunto, string contenido)
|
||||
public void Send(string destinatario, string asunto, string contenido)
|
||||
{
|
||||
if (!IsConfigured)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Transactions;
|
||||
using System.Linq;
|
||||
@@ -15,6 +15,7 @@ using SIG.Web.AppCode.Models.Common;
|
||||
using SIG.Web.AppCode.Models.Fraccionamientos;
|
||||
using SIG.Web.AppCode.Models.Tramites;
|
||||
using SIG.Web.AppCode.Services.Fraccionamientos;
|
||||
using SIG.Web.AppCode.Notifications.Contracts;
|
||||
|
||||
namespace SIG.Web.AppCode.Services.Tramites
|
||||
{
|
||||
@@ -30,19 +31,22 @@ namespace SIG.Web.AppCode.Services.Tramites
|
||||
private readonly IBitacoraService _bitacoraService;
|
||||
private readonly ITramiteDocumentoService _servicioDocumentos;
|
||||
private readonly IUserContextProvider _contextoUsuario;
|
||||
private readonly INotificacionConfiguracionService _notificaciones;
|
||||
|
||||
public TramiteSolicitudService(
|
||||
ITramiteSolicitudRepository repository,
|
||||
IRepositorioFraccionamiento repositorioFraccionamiento,
|
||||
IBitacoraService bitacoraService,
|
||||
ITramiteDocumentoService servicioDocumentos,
|
||||
IUserContextProvider contextoUsuario)
|
||||
IUserContextProvider contextoUsuario,
|
||||
INotificacionConfiguracionService notificaciones)
|
||||
{
|
||||
_servicioDocumentos = servicioDocumentos;
|
||||
_contextoUsuario = contextoUsuario;
|
||||
_repository = repository;
|
||||
_repositorioFraccionamiento = repositorioFraccionamiento;
|
||||
_bitacoraService = bitacoraService;
|
||||
_notificaciones = notificaciones;
|
||||
}
|
||||
|
||||
|
||||
@@ -679,6 +683,9 @@ namespace SIG.Web.AppCode.Services.Tramites
|
||||
"Capture observaciones de 1 a 1000 caracteres.");
|
||||
}
|
||||
|
||||
DbResult<TramiteSolicitudStatusChangeModel> resultadoConfirmado = null;
|
||||
string eventoNotificacionConfirmado = null;
|
||||
|
||||
// Se mantienen estables solicitud y requisitos hasta confirmar el movimiento.
|
||||
using (var transaction = new TransactionLogic(IsolationLevel.Serializable))
|
||||
{
|
||||
@@ -718,23 +725,38 @@ namespace SIG.Web.AppCode.Services.Tramites
|
||||
"Seleccione un estatus diferente al actual.");
|
||||
}
|
||||
|
||||
/*
|
||||
* Si el trámite tiene condiciones configuradas para mostrarse,
|
||||
* un usuario administrativo no puede cambiar el estatus sin
|
||||
* capturarlas primero.
|
||||
*
|
||||
* Ya no se valida únicamente al pasar a Autorizado.
|
||||
*/
|
||||
bool aplicanCondiciones = contexto.EsAdministrador &&
|
||||
destino.CveEstatusSolicitud == CveEstatusSolicitudAutorizado &&
|
||||
!destino.EsCliente;
|
||||
contexto.Condiciones != null &&
|
||||
contexto.Condiciones.Count > 0;
|
||||
|
||||
cambioEstatus.CvesCondicionesMostradas = aplicanCondiciones
|
||||
? contexto.Condiciones.Select(condicion => condicion.CveCondicionMostrar)
|
||||
.Distinct().OrderBy(clave => clave).ToList()
|
||||
? contexto.Condiciones
|
||||
.Select(condicion => condicion.CveCondicionMostrar)
|
||||
.Distinct()
|
||||
.OrderBy(clave => clave)
|
||||
.ToList()
|
||||
: new List<int>();
|
||||
|
||||
if (aplicanCondiciones)
|
||||
{
|
||||
PrepararCondicionesPermitidas(
|
||||
cambioEstatus, solicitudActual.CveTipoTramite, contexto.Condiciones);
|
||||
cambioEstatus,
|
||||
solicitudActual.CveTipoTramite,
|
||||
contexto.Condiciones);
|
||||
|
||||
if (cambioEstatus.CvesCondicionesMostradas.Any(clave =>
|
||||
!ObtenerValorCondicion(cambioEstatus, clave).HasValue))
|
||||
{
|
||||
return RequisitosPendientes(
|
||||
"Condiciones", "Capture un valor Sí/No (1/0) en todas las condiciones visibles.");
|
||||
"Condiciones",
|
||||
"Seleccione un valor en todas las condiciones requeridas antes de cambiar el estatus.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -900,8 +922,53 @@ namespace SIG.Web.AppCode.Services.Tramites
|
||||
}
|
||||
|
||||
transaction.Commit();
|
||||
return result;
|
||||
resultadoConfirmado = result;
|
||||
eventoNotificacionConfirmado = ObtenerEventoNotificacion(destino);
|
||||
}
|
||||
|
||||
if (resultadoConfirmado != null &&
|
||||
resultadoConfirmado.Success &&
|
||||
resultadoConfirmado.Data != null &&
|
||||
resultadoConfirmado.Data.HuboCambio &&
|
||||
_notificaciones != null)
|
||||
{
|
||||
_notificaciones.NotificarTramite(
|
||||
eventoNotificacionConfirmado,
|
||||
resultadoConfirmado.Data,
|
||||
cveUsuarioEjecuta,
|
||||
nombreDominio);
|
||||
}
|
||||
|
||||
return resultadoConfirmado;
|
||||
}
|
||||
|
||||
private static string ObtenerEventoNotificacion(
|
||||
TramiteSolicitudEstatusOptionModel destino)
|
||||
{
|
||||
if (destino == null)
|
||||
{
|
||||
return "CAMBIO_ESTATUS";
|
||||
}
|
||||
|
||||
if (destino.EsCliente && destino.EsOK)
|
||||
{
|
||||
return "ENVIADO_REVISION";
|
||||
}
|
||||
|
||||
string codigo = (destino.Codigo ?? string.Empty).ToUpperInvariant();
|
||||
string nombre = (destino.EstatusSolicitud ?? string.Empty).ToUpperInvariant();
|
||||
|
||||
if (codigo.Contains("AUTORIZ") || nombre.Contains("AUTORIZ"))
|
||||
{
|
||||
return "AUTORIZADO";
|
||||
}
|
||||
|
||||
if (codigo.Contains("CANCEL") || nombre.Contains("CANCEL"))
|
||||
{
|
||||
return "CANCELADO";
|
||||
}
|
||||
|
||||
return "CAMBIO_ESTATUS";
|
||||
}
|
||||
|
||||
private static DbResult<TramiteSolicitudStatusChangeModel> RequisitosPendientes(
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Configuration;
|
||||
using System.IO;
|
||||
using System.Web;
|
||||
using System.Web.UI;
|
||||
@@ -177,6 +178,17 @@ namespace SIG.Web.AppCode.SigControls
|
||||
AgregarAtributo(writer, "data-sig-visualizador-url-descarga-inicial", rutaDescarga);
|
||||
writer.AddAttribute("data-sig-visualizador-permitir-descarga", PermitirDescarga ? "1" : "0");
|
||||
writer.AddAttribute("data-sig-visualizador-permitir-expandir", PermitirExpandir ? "1" : "0");
|
||||
|
||||
string googleMapsApiKey = ConfigurationManager.AppSettings["GoogleMapsApiKey"] ?? string.Empty;
|
||||
bool googleMapsHabilitado = ResolverGoogleMapsHabilitado(googleMapsApiKey);
|
||||
writer.AddAttribute(
|
||||
"data-sig-google-maps-habilitado",
|
||||
googleMapsHabilitado ? "1" : "0");
|
||||
AgregarAtributo(
|
||||
writer,
|
||||
"data-sig-google-maps-api-key",
|
||||
googleMapsHabilitado ? googleMapsApiKey : null);
|
||||
|
||||
writer.RenderBeginTag(HtmlTextWriterTag.Div);
|
||||
|
||||
RenderEncabezado(writer, rutaDescarga);
|
||||
@@ -364,6 +376,19 @@ namespace SIG.Web.AppCode.SigControls
|
||||
return ResolveClientUrl(ruta);
|
||||
}
|
||||
|
||||
private static bool ResolverGoogleMapsHabilitado(string apiKey)
|
||||
{
|
||||
bool habilitado;
|
||||
string configurado = ConfigurationManager.AppSettings["GoogleMapsEnabled"];
|
||||
|
||||
if (!bool.TryParse(configurado, out habilitado))
|
||||
{
|
||||
habilitado = true;
|
||||
}
|
||||
|
||||
return habilitado && !string.IsNullOrWhiteSpace(apiKey);
|
||||
}
|
||||
|
||||
private static void AgregarAtributo(HtmlTextWriter writer, string nombre, string valor)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(valor))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Web;
|
||||
using System.Web.SessionState;
|
||||
@@ -66,43 +66,80 @@ namespace SIG.Web.AppCode.SigControls
|
||||
nombreArchivo,
|
||||
tipoContenido))
|
||||
{
|
||||
SigVisualizadorArchivoOfficeResultado conversion;
|
||||
string error;
|
||||
if (SigVisualizadorArchivoVistaPreviaExcel.EsCompatible(nombreArchivo))
|
||||
{
|
||||
byte[] vistaPreviaExcel;
|
||||
string errorExcel;
|
||||
|
||||
if (!SigVisualizadorArchivoOfficeConverter.IntentarConvertir(
|
||||
using (var contenidoExcel = new FileStream(
|
||||
rutaCompleta,
|
||||
FileMode.Open,
|
||||
FileAccess.Read,
|
||||
FileShare.Read))
|
||||
{
|
||||
if (SigVisualizadorArchivoVistaPreviaExcel.IntentarGenerarHtml(
|
||||
contenidoExcel,
|
||||
nombreArchivo,
|
||||
out vistaPreviaExcel,
|
||||
out errorExcel))
|
||||
{
|
||||
PrepararRespuesta(
|
||||
contexto,
|
||||
"text/html; charset=utf-8",
|
||||
false,
|
||||
Path.GetFileNameWithoutExtension(nombreArchivo) + ".html");
|
||||
contexto.Response.OutputStream.Write(
|
||||
vistaPreviaExcel,
|
||||
0,
|
||||
vistaPreviaExcel.Length);
|
||||
contexto.ApplicationInstance.CompleteRequest();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SigVisualizadorArchivoOfficeResultado conversion;
|
||||
string errorConversion;
|
||||
|
||||
if (SigVisualizadorArchivoOfficeConverter.IntentarConvertir(
|
||||
rutaCompleta,
|
||||
nombreArchivo,
|
||||
out conversion,
|
||||
out error))
|
||||
out errorConversion))
|
||||
{
|
||||
ResponderError(
|
||||
contexto,
|
||||
415,
|
||||
string.IsNullOrWhiteSpace(error)
|
||||
? "No fue posible generar la vista previa del archivo de Office."
|
||||
: error);
|
||||
using (conversion)
|
||||
using (var contenidoPdf = new FileStream(
|
||||
conversion.RutaPdf,
|
||||
FileMode.Open,
|
||||
FileAccess.Read,
|
||||
FileShare.Read))
|
||||
{
|
||||
PrepararRespuesta(
|
||||
contexto,
|
||||
"application/pdf",
|
||||
false,
|
||||
Path.GetFileNameWithoutExtension(nombreArchivo) + ".pdf");
|
||||
contenidoPdf.CopyTo(contexto.Response.OutputStream);
|
||||
}
|
||||
|
||||
contexto.ApplicationInstance.CompleteRequest();
|
||||
return;
|
||||
}
|
||||
|
||||
using (conversion)
|
||||
using (var contenidoPdf = new FileStream(
|
||||
conversion.RutaPdf,
|
||||
FileMode.Open,
|
||||
FileAccess.Read,
|
||||
FileShare.Read))
|
||||
{
|
||||
PrepararRespuesta(
|
||||
contexto,
|
||||
"application/pdf",
|
||||
false,
|
||||
Path.GetFileNameWithoutExtension(nombreArchivo) + ".pdf");
|
||||
contenidoPdf.CopyTo(contexto.Response.OutputStream);
|
||||
}
|
||||
|
||||
contexto.ApplicationInstance.CompleteRequest();
|
||||
ResponderError(
|
||||
contexto,
|
||||
415,
|
||||
string.IsNullOrWhiteSpace(errorConversion)
|
||||
? "No fue posible generar la vista previa del archivo de Office."
|
||||
: errorConversion);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!descargar && EsArchivoGis(nombreArchivo))
|
||||
{
|
||||
tipoContenido = "application/geo+json; charset=utf-8";
|
||||
}
|
||||
|
||||
PrepararRespuesta(
|
||||
contexto,
|
||||
string.IsNullOrWhiteSpace(tipoContenido)
|
||||
@@ -147,10 +184,20 @@ namespace SIG.Web.AppCode.SigControls
|
||||
contexto.Response.StatusCode = codigo;
|
||||
contexto.Response.TrySkipIisCustomErrors = true;
|
||||
contexto.Response.ContentType = "text/plain; charset=utf-8";
|
||||
contexto.Response.AddHeader(
|
||||
"X-SIG-Visualizador-Mensaje",
|
||||
HttpUtility.UrlEncode(mensaje ?? string.Empty));
|
||||
contexto.Response.Write(mensaje);
|
||||
contexto.ApplicationInstance.CompleteRequest();
|
||||
}
|
||||
|
||||
private static bool EsArchivoGis(string nombreArchivo)
|
||||
{
|
||||
string extension = Path.GetExtension(nombreArchivo ?? string.Empty);
|
||||
return string.Equals(extension, ".gis", StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(extension, ".geojson", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
private static string LimpiarNombreArchivo(string nombreArchivo)
|
||||
{
|
||||
return Path.GetFileName(string.IsNullOrWhiteSpace(nombreArchivo) ? "archivo" : nombreArchivo)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Diagnostics;
|
||||
|
||||
@@ -0,0 +1,195 @@
|
||||
using ClosedXML.Excel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
|
||||
namespace SIG.Web.AppCode.SigControls
|
||||
{
|
||||
internal static class SigVisualizadorArchivoVistaPreviaExcel
|
||||
{
|
||||
private const int HojasMaximas = 10;
|
||||
private const int FilasMaximasPorHoja = 500;
|
||||
private const int ColumnasMaximasPorHoja = 50;
|
||||
private const int CeldasMaximasTotales = 20000;
|
||||
|
||||
private static readonly HashSet<string> ExtensionesCompatibles =
|
||||
new HashSet<string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
".xlsx",
|
||||
".xlsm",
|
||||
".xltx",
|
||||
".xltm"
|
||||
};
|
||||
|
||||
public static bool EsCompatible(string nombreArchivo)
|
||||
{
|
||||
string extension = Path.GetExtension(nombreArchivo ?? string.Empty);
|
||||
return !string.IsNullOrWhiteSpace(extension) &&
|
||||
ExtensionesCompatibles.Contains(extension);
|
||||
}
|
||||
|
||||
public static bool IntentarGenerarHtml(
|
||||
Stream contenido,
|
||||
string nombreArchivo,
|
||||
out byte[] html,
|
||||
out string error)
|
||||
{
|
||||
html = null;
|
||||
error = null;
|
||||
|
||||
if (!EsCompatible(nombreArchivo))
|
||||
{
|
||||
error = "El archivo de Excel no es compatible con la vista previa mediante ClosedXML.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (contenido == null || !contenido.CanRead)
|
||||
{
|
||||
error = "El archivo de Excel no contiene datos para generar la vista previa.";
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (contenido.CanSeek)
|
||||
{
|
||||
contenido.Position = 0;
|
||||
}
|
||||
|
||||
using (var libro = new XLWorkbook(contenido))
|
||||
{
|
||||
string documento = ConstruirHtml(libro, nombreArchivo);
|
||||
html = Encoding.UTF8.GetBytes(documento);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
error = "No fue posible generar la vista previa de Excel con ClosedXML. " + ex.Message;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static string ConstruirHtml(XLWorkbook libro, string nombreArchivo)
|
||||
{
|
||||
var html = new StringBuilder(32768);
|
||||
int hojasProcesadas = 0;
|
||||
int celdasProcesadas = 0;
|
||||
bool truncado = false;
|
||||
|
||||
html.Append("<!doctype html><html><head><meta charset=\"utf-8\">");
|
||||
html.Append("<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">");
|
||||
html.Append("<title>");
|
||||
html.Append(HttpUtility.HtmlEncode(Path.GetFileName(nombreArchivo)));
|
||||
html.Append("</title>");
|
||||
html.Append("<style>");
|
||||
html.Append("html,body{margin:0;padding:0;background:#fff;color:#2f353b;font-family:Arial,sans-serif;font-size:12px}");
|
||||
html.Append(".sig-excel{padding:12px}.sig-excel-hoja{margin-bottom:24px}.sig-excel-titulo{font-size:14px;font-weight:600;margin:0 0 8px}");
|
||||
html.Append(".sig-excel-scroll{overflow:auto;border:1px solid #d9dfe5}.sig-excel table{border-collapse:collapse;min-width:100%;background:#fff}");
|
||||
html.Append(".sig-excel td{border:1px solid #e1e5ec;padding:5px 7px;white-space:pre-wrap;vertical-align:top;min-width:70px}");
|
||||
html.Append(".sig-excel tr:first-child td{font-weight:600;background:#f5f7f9;position:sticky;top:0;z-index:1}");
|
||||
html.Append(".sig-excel-aviso{padding:10px 12px;margin-bottom:12px;border:1px solid #e1e5ec;background:#f8f9fb}");
|
||||
html.Append("</style></head><body><div class=\"sig-excel\">");
|
||||
|
||||
foreach (IXLWorksheet hoja in libro.Worksheets)
|
||||
{
|
||||
if (hojasProcesadas >= HojasMaximas || celdasProcesadas >= CeldasMaximasTotales)
|
||||
{
|
||||
truncado = true;
|
||||
break;
|
||||
}
|
||||
|
||||
IXLRow primeraFilaUsada = hoja.FirstRowUsed();
|
||||
IXLRow ultimaFilaUsada = hoja.LastRowUsed();
|
||||
IXLColumn primeraColumnaUsada = hoja.FirstColumnUsed();
|
||||
IXLColumn ultimaColumnaUsada = hoja.LastColumnUsed();
|
||||
|
||||
hojasProcesadas++;
|
||||
html.Append("<section class=\"sig-excel-hoja\"><h2 class=\"sig-excel-titulo\">");
|
||||
html.Append(HttpUtility.HtmlEncode(hoja.Name));
|
||||
html.Append("</h2>");
|
||||
|
||||
if (primeraFilaUsada == null || ultimaFilaUsada == null ||
|
||||
primeraColumnaUsada == null || ultimaColumnaUsada == null)
|
||||
{
|
||||
html.Append("<div class=\"sig-excel-aviso\">La hoja no contiene datos.</div></section>");
|
||||
continue;
|
||||
}
|
||||
|
||||
int primeraFila = primeraFilaUsada.RowNumber();
|
||||
int ultimaFila = Math.Min(
|
||||
ultimaFilaUsada.RowNumber(),
|
||||
primeraFila + FilasMaximasPorHoja - 1);
|
||||
int primeraColumna = primeraColumnaUsada.ColumnNumber();
|
||||
int ultimaColumna = Math.Min(
|
||||
ultimaColumnaUsada.ColumnNumber(),
|
||||
primeraColumna + ColumnasMaximasPorHoja - 1);
|
||||
|
||||
if (ultimaFila < ultimaFilaUsada.RowNumber() ||
|
||||
ultimaColumna < ultimaColumnaUsada.ColumnNumber())
|
||||
{
|
||||
truncado = true;
|
||||
}
|
||||
|
||||
html.Append("<div class=\"sig-excel-scroll\"><table><tbody>");
|
||||
|
||||
for (int fila = primeraFila; fila <= ultimaFila; fila++)
|
||||
{
|
||||
if (celdasProcesadas >= CeldasMaximasTotales)
|
||||
{
|
||||
truncado = true;
|
||||
break;
|
||||
}
|
||||
|
||||
html.Append("<tr>");
|
||||
|
||||
for (int columna = primeraColumna; columna <= ultimaColumna; columna++)
|
||||
{
|
||||
if (celdasProcesadas >= CeldasMaximasTotales)
|
||||
{
|
||||
truncado = true;
|
||||
break;
|
||||
}
|
||||
|
||||
IXLCell celda = hoja.Cell(fila, columna);
|
||||
string valor = celda.GetString();
|
||||
|
||||
html.Append("<td>");
|
||||
html.Append(HttpUtility.HtmlEncode(valor));
|
||||
html.Append("</td>");
|
||||
celdasProcesadas++;
|
||||
}
|
||||
|
||||
html.Append("</tr>");
|
||||
}
|
||||
|
||||
html.Append("</tbody></table></div></section>");
|
||||
}
|
||||
|
||||
if (truncado)
|
||||
{
|
||||
string aviso =
|
||||
"<div class=\"sig-excel-aviso\">" +
|
||||
"La vista previa fue limitada para mantener un buen rendimiento. " +
|
||||
"Descargue el archivo para consultar todo el contenido.</div>";
|
||||
int indicePrimeraHoja = html.ToString().IndexOf(
|
||||
"<section",
|
||||
StringComparison.Ordinal);
|
||||
|
||||
if (indicePrimeraHoja >= 0)
|
||||
{
|
||||
html.Insert(indicePrimeraHoja, aviso);
|
||||
}
|
||||
else
|
||||
{
|
||||
html.Append(aviso);
|
||||
}
|
||||
}
|
||||
|
||||
html.Append("</div></body></html>");
|
||||
return html.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 961 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 961 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 54 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 54 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,6 +1,7 @@
|
||||
<%@ Page Title="Tipos de documento" Language="C#" MasterPageFile="~/Site.master"
|
||||
AutoEventWireup="true" CodeFile="TiposDocumento.aspx.cs"
|
||||
Inherits="SIG.Web.Pages.Catalogos.TiposDocumento" %>
|
||||
<%@ Register Src="~/UserControl/NotificacionesConfiguracion.ascx" TagPrefix="sig" TagName="NotificacionesConfiguracion" %>
|
||||
|
||||
<asp:Content ID="ContentHead" ContentPlaceHolderID="H" runat="server">
|
||||
<link href='<%= ResolveUrl("~/Styles/CatalogosTramites.css") %>' rel="stylesheet" type="text/css" />
|
||||
@@ -47,6 +48,11 @@
|
||||
CausesValidation="false" ToolTip="Editar">
|
||||
<i class="fa fa-pencil"></i>
|
||||
</asp:LinkButton>
|
||||
<asp:LinkButton ID="BtnNotifications" runat="server" CssClass="btn btn-circle btn-sm green"
|
||||
CommandName="Notificaciones" CommandArgument='<%# Eval("CveTipoDocumento") %>'
|
||||
CausesValidation="false" ToolTip="Notificaciones">
|
||||
<i class="fa fa-bell"></i>
|
||||
</asp:LinkButton>
|
||||
<asp:LinkButton ID="BtnDelete" runat="server" CssClass="btn btn-circle btn-sm red"
|
||||
CommandName="Eliminar" CommandArgument='<%# Eval("CveTipoDocumento") %>'
|
||||
CausesValidation="false"
|
||||
@@ -141,6 +147,7 @@
|
||||
</asp:UpdatePanel>
|
||||
</div>
|
||||
</div>
|
||||
<sig:NotificacionesConfiguracion ID="UcNotificaciones" runat="server" />
|
||||
</asp:Content>
|
||||
|
||||
<asp:Content ID="ContentScripts" ContentPlaceHolderID="J" runat="server">
|
||||
|
||||
@@ -90,6 +90,20 @@ namespace SIG.Web.Pages.Catalogos
|
||||
{
|
||||
Delete(id);
|
||||
}
|
||||
else if (e.CommandName == "Notificaciones")
|
||||
{
|
||||
DbResult<TipoDocumentoModel> documento =
|
||||
AppServices.TramiteCatalogService.GetTipoDocumento(
|
||||
id, CurrentUser.CveUsuario, CurrentUser.NombreDominio);
|
||||
if (!documento.Success || documento.Data == null)
|
||||
{
|
||||
Alert(documento.UserMessage, TipoMensaje.MsgAdvertencia);
|
||||
return;
|
||||
}
|
||||
|
||||
UcNotificaciones.AbrirDocumento(
|
||||
id, documento.Data.TipoDocumento);
|
||||
}
|
||||
}
|
||||
|
||||
protected void BtnSave_Click(object sender, EventArgs e)
|
||||
|
||||
128
SIG.Web/Pages/Catalogos/TiposNotificacion.aspx
Normal file
128
SIG.Web/Pages/Catalogos/TiposNotificacion.aspx
Normal file
@@ -0,0 +1,128 @@
|
||||
<%@ Page Title="Tipos de notificación" Language="C#" MasterPageFile="~/Site.master"
|
||||
AutoEventWireup="true" CodeFile="TiposNotificacion.aspx.cs"
|
||||
Inherits="SIG.Web.Pages.Catalogos.TiposNotificacion" %>
|
||||
<%@ Register Src="~/UserControl/TipoNotificacionEditor.ascx"
|
||||
TagPrefix="sig" TagName="TipoNotificacionEditor" %>
|
||||
|
||||
<asp:Content ID="ContentHead" ContentPlaceHolderID="H" runat="server">
|
||||
<link href='<%= ResolveUrl("~/Styles/CatalogosTramites.css") %>' rel="stylesheet" type="text/css" />
|
||||
</asp:Content>
|
||||
|
||||
<asp:Content ID="ContentActions" ContentPlaceHolderID="A" runat="server">
|
||||
<asp:UpdatePanel ID="UpActions" runat="server"
|
||||
UpdateMode="Conditional" ChildrenAsTriggers="false">
|
||||
<ContentTemplate>
|
||||
<li>
|
||||
<asp:LinkButton ID="BtnNew" runat="server"
|
||||
CausesValidation="false"
|
||||
OnClick="BtnNew_Click">
|
||||
<i class="fa fa-plus"></i>
|
||||
Nuevo tipo de notificación
|
||||
</asp:LinkButton>
|
||||
</li>
|
||||
</ContentTemplate>
|
||||
<Triggers>
|
||||
<asp:AsyncPostBackTrigger ControlID="BtnNew" EventName="Click" />
|
||||
</Triggers>
|
||||
</asp:UpdatePanel>
|
||||
</asp:Content>
|
||||
|
||||
<asp:Content ID="ContentMain" ContentPlaceHolderID="C" runat="server">
|
||||
<asp:UpdatePanel ID="UpCatalog" runat="server"
|
||||
UpdateMode="Conditional" ChildrenAsTriggers="false">
|
||||
<ContentTemplate>
|
||||
<sig:Filtros ID="UcFiltros" runat="server"
|
||||
OnMostrarFiltros="UcFiltros_MostrarFiltros"
|
||||
OnFiltrosChanged="UcFiltros_FiltrosChanged"
|
||||
OnConsultar="UcFiltros_Consultar" />
|
||||
|
||||
<div class="tra-catalog-card">
|
||||
<asp:GridView ID="GvItems" runat="server"
|
||||
AutoGenerateColumns="false"
|
||||
GridLines="None"
|
||||
CssClass="table table-striped table-hover Widthall"
|
||||
EmptyDataText="No se encontraron tipos de notificación."
|
||||
OnRowCommand="GvItems_RowCommand">
|
||||
<Columns>
|
||||
<asp:BoundField DataField="Codigo" HeaderText="Código" />
|
||||
<asp:BoundField DataField="Nombre" HeaderText="Nombre" />
|
||||
<asp:BoundField DataField="TipoEnvio" HeaderText="Tipo de envío" />
|
||||
<asp:BoundField DataField="Asunto" HeaderText="Asunto" />
|
||||
<asp:CheckBoxField DataField="GeneraHistorial" HeaderText="Genera historial" />
|
||||
<asp:CheckBoxField DataField="EsActivo" HeaderText="Activo" />
|
||||
<asp:TemplateField HeaderText="Acciones">
|
||||
<ItemTemplate>
|
||||
<asp:LinkButton runat="server"
|
||||
CssClass="btn btn-circle btn-sm blue"
|
||||
CommandName="Editar"
|
||||
CommandArgument='<%# Eval("CveTipoNotificacion") %>'
|
||||
CausesValidation="false"
|
||||
ToolTip="Editar">
|
||||
<i class="fa fa-pencil"></i>
|
||||
</asp:LinkButton>
|
||||
<asp:LinkButton runat="server"
|
||||
CssClass="btn btn-circle btn-sm red"
|
||||
CommandName="Eliminar"
|
||||
CommandArgument='<%# Eval("CveTipoNotificacion") %>'
|
||||
CausesValidation="false"
|
||||
OnClientClick="return window.SIGAlerts.confirmPostBack(this, '¿Desactivar el tipo de notificación?');"
|
||||
ToolTip="Desactivar">
|
||||
<i class="fa fa-trash"></i>
|
||||
</asp:LinkButton>
|
||||
</ItemTemplate>
|
||||
</asp:TemplateField>
|
||||
</Columns>
|
||||
</asp:GridView>
|
||||
</div>
|
||||
</ContentTemplate>
|
||||
<Triggers>
|
||||
<asp:AsyncPostBackTrigger ControlID="UcFiltros" EventName="Consultar" />
|
||||
<asp:AsyncPostBackTrigger ControlID="UcFiltros" EventName="FiltrosChanged" />
|
||||
<asp:AsyncPostBackTrigger ControlID="UcFiltros" EventName="MostrarFiltros" />
|
||||
<asp:AsyncPostBackTrigger ControlID="GvItems" EventName="RowCommand" />
|
||||
</Triggers>
|
||||
</asp:UpdatePanel>
|
||||
|
||||
<div id="ModalFilters" class="modal fade" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<asp:UpdatePanel ID="UpFilters" runat="server"
|
||||
UpdateMode="Conditional" ChildrenAsTriggers="false">
|
||||
<ContentTemplate>
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||
<h4 class="modal-title">Filtros</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="tra-modal-field">
|
||||
<label>Código, nombre o asunto</label>
|
||||
<asp:TextBox ID="TxtSearch" runat="server"
|
||||
CssClass="form-control" MaxLength="250" />
|
||||
</div>
|
||||
<asp:CheckBox ID="ChkInactive" runat="server"
|
||||
Text=" Incluir inactivos" />
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn default" data-dismiss="modal">Cancelar</button>
|
||||
<asp:Button ID="BtnApplyFilters" runat="server"
|
||||
CssClass="btn blue"
|
||||
Text="Aplicar filtros"
|
||||
OnClick="BtnApplyFilters_Click" />
|
||||
</div>
|
||||
</div>
|
||||
</ContentTemplate>
|
||||
<Triggers>
|
||||
<asp:AsyncPostBackTrigger ControlID="BtnApplyFilters" EventName="Click" />
|
||||
</Triggers>
|
||||
</asp:UpdatePanel>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<sig:TipoNotificacionEditor ID="EditorTipoNotificacion"
|
||||
runat="server"
|
||||
OnGuardado="EditorTipoNotificacion_Guardado" />
|
||||
</asp:Content>
|
||||
|
||||
<asp:Content ID="ContentScripts" ContentPlaceHolderID="J" runat="server">
|
||||
<script src='<%= ResolveUrl("~/Scripts/CatalogosTramites.js") %>' type="text/javascript"></script>
|
||||
</asp:Content>
|
||||
196
SIG.Web/Pages/Catalogos/TiposNotificacion.aspx.cs
Normal file
196
SIG.Web/Pages/Catalogos/TiposNotificacion.aspx.cs
Normal file
@@ -0,0 +1,196 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web.UI.WebControls;
|
||||
using SIG.Web.AppCode.Configuration;
|
||||
using SIG.Web.AppCode.Infrastructure.WebForms;
|
||||
using SIG.Web.AppCode.Models.Common;
|
||||
using SIG.Web.AppCode.Notifications.Models;
|
||||
using SIG.Web.AppCode.Security;
|
||||
using SIG.Web.AppCode.SigControls;
|
||||
|
||||
namespace SIG.Web.Pages.Catalogos
|
||||
{
|
||||
public partial class TiposNotificacion : ClsPaginaCatalogoInterno
|
||||
{
|
||||
protected void Page_Load(object sender, EventArgs e)
|
||||
{
|
||||
if (!IsPostBack)
|
||||
{
|
||||
BindGrid();
|
||||
SyncFilters();
|
||||
}
|
||||
}
|
||||
|
||||
protected void UcFiltros_MostrarFiltros(object sender, EventArgs e)
|
||||
{
|
||||
Show("ModalFilters");
|
||||
}
|
||||
|
||||
protected void UcFiltros_Consultar(object sender, EventArgs e)
|
||||
{
|
||||
BindGrid();
|
||||
SyncFilters();
|
||||
}
|
||||
|
||||
protected void UcFiltros_FiltrosChanged(object sender, EventArgs e)
|
||||
{
|
||||
List<string> nombres = UcFiltros.GetFiltros()
|
||||
.Select(item => item.Nombre)
|
||||
.ToList();
|
||||
|
||||
if (!nombres.Contains("Texto"))
|
||||
{
|
||||
TxtSearch.Text = string.Empty;
|
||||
}
|
||||
|
||||
if (!nombres.Contains("Inactivos"))
|
||||
{
|
||||
ChkInactive.Checked = false;
|
||||
}
|
||||
|
||||
BindGrid();
|
||||
SyncFilters();
|
||||
}
|
||||
|
||||
protected void BtnApplyFilters_Click(object sender, EventArgs e)
|
||||
{
|
||||
BindGrid();
|
||||
SyncFilters();
|
||||
UpCatalog.Update();
|
||||
Hide("ModalFilters");
|
||||
}
|
||||
|
||||
protected void BtnNew_Click(object sender, EventArgs e)
|
||||
{
|
||||
EditorTipoNotificacion.AbrirNuevo();
|
||||
}
|
||||
|
||||
protected void EditorTipoNotificacion_Guardado(object sender, EventArgs e)
|
||||
{
|
||||
BindGrid();
|
||||
SyncFilters();
|
||||
UpCatalog.Update();
|
||||
}
|
||||
|
||||
protected void GvItems_RowCommand(object sender, GridViewCommandEventArgs e)
|
||||
{
|
||||
int id;
|
||||
if (!int.TryParse(Convert.ToString(e.CommandArgument), out id))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.CommandName == "Editar")
|
||||
{
|
||||
EditorTipoNotificacion.AbrirEditar(id);
|
||||
}
|
||||
else if (e.CommandName == "Eliminar")
|
||||
{
|
||||
DbResult<bool> resultado =
|
||||
AppServices.NotificacionConfiguracionService.EliminarTipo(
|
||||
id,
|
||||
CurrentUser.CveUsuario,
|
||||
CurrentUser.NombreDominio);
|
||||
|
||||
if (!resultado.Success)
|
||||
{
|
||||
Alert(resultado.UserMessage, TipoMensaje.MsgAdvertencia);
|
||||
return;
|
||||
}
|
||||
|
||||
BindGrid();
|
||||
SyncFilters();
|
||||
UpCatalog.Update();
|
||||
Alert(
|
||||
"Tipo de notificación desactivado.",
|
||||
TipoMensaje.ToastExito);
|
||||
}
|
||||
}
|
||||
|
||||
private void BindGrid()
|
||||
{
|
||||
DbResult<List<TipoNotificacionModel>> resultado =
|
||||
AppServices.NotificacionConfiguracionService.ListarTipos(
|
||||
ChkInactive.Checked,
|
||||
CurrentUser.CveUsuario,
|
||||
CurrentUser.NombreDominio);
|
||||
|
||||
if (!resultado.Success)
|
||||
{
|
||||
Alert(resultado.UserMessage, TipoMensaje.MsgError);
|
||||
GvItems.DataSource = null;
|
||||
GvItems.DataBind();
|
||||
return;
|
||||
}
|
||||
|
||||
IEnumerable<TipoNotificacionModel> datos =
|
||||
resultado.Data ?? new List<TipoNotificacionModel>();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(TxtSearch.Text))
|
||||
{
|
||||
string texto = TxtSearch.Text.Trim();
|
||||
datos = datos.Where(x =>
|
||||
Contiene(x.Codigo, texto) ||
|
||||
Contiene(x.Nombre, texto) ||
|
||||
Contiene(x.Asunto, texto) ||
|
||||
Contiene(x.TipoEnvio, texto));
|
||||
}
|
||||
|
||||
GvItems.DataSource = datos
|
||||
.OrderBy(x => x.Nombre)
|
||||
.ToList();
|
||||
GvItems.DataBind();
|
||||
}
|
||||
|
||||
private void SyncFilters()
|
||||
{
|
||||
var filtros = new List<FiltroActivo>();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(TxtSearch.Text))
|
||||
{
|
||||
filtros.Add(new FiltroActivo
|
||||
{
|
||||
Nombre = "Texto",
|
||||
Titulo = "Búsqueda",
|
||||
Descripcion = TxtSearch.Text.Trim(),
|
||||
Orden = 1
|
||||
});
|
||||
}
|
||||
|
||||
if (ChkInactive.Checked)
|
||||
{
|
||||
filtros.Add(new FiltroActivo
|
||||
{
|
||||
Nombre = "Inactivos",
|
||||
Titulo = "Estatus",
|
||||
Descripcion = "Incluye inactivos",
|
||||
Orden = 2
|
||||
});
|
||||
}
|
||||
|
||||
UcFiltros.SetFiltros(filtros);
|
||||
}
|
||||
|
||||
private static bool Contiene(string valor, string texto)
|
||||
{
|
||||
return (valor ?? string.Empty).IndexOf(
|
||||
texto ?? string.Empty,
|
||||
StringComparison.OrdinalIgnoreCase) >= 0;
|
||||
}
|
||||
|
||||
private void Show(string id)
|
||||
{
|
||||
RegistraScript(
|
||||
"window.SIGTramiteCatalog.show('" + id + "');",
|
||||
"Show_" + id);
|
||||
}
|
||||
|
||||
private void Hide(string id)
|
||||
{
|
||||
RegistraScript(
|
||||
"window.SIGTramiteCatalog.hide('" + id + "');",
|
||||
"Hide_" + id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
AutoEventWireup="true"
|
||||
CodeFile="TiposTramite.aspx.cs"
|
||||
Inherits="SIG.Web.Pages.Catalogos.TiposTramite" %>
|
||||
<%@ Register Src="~/UserControl/NotificacionesConfiguracion.ascx" TagPrefix="sig" TagName="NotificacionesConfiguracion" %>
|
||||
|
||||
<asp:Content ID="ContentHead" ContentPlaceHolderID="H" runat="server">
|
||||
<link href='<%= ResolveUrl("~/Styles/CatalogosTramites.css") %>' rel="stylesheet" type="text/css" />
|
||||
@@ -74,6 +75,15 @@
|
||||
ToolTip="Editar">
|
||||
<i class="fa fa-pencil"></i>
|
||||
</asp:LinkButton>
|
||||
<asp:LinkButton ID="BtnNotifications"
|
||||
runat="server"
|
||||
CssClass="btn btn-circle btn-sm green"
|
||||
CommandName="Notificaciones"
|
||||
CommandArgument='<%# Eval("CveTipoTramite") %>'
|
||||
CausesValidation="false"
|
||||
ToolTip="Notificaciones">
|
||||
<i class="fa fa-bell"></i>
|
||||
</asp:LinkButton>
|
||||
<asp:LinkButton ID="BtnDelete"
|
||||
runat="server"
|
||||
CssClass="btn btn-circle btn-sm red"
|
||||
@@ -265,6 +275,7 @@
|
||||
</asp:UpdatePanel>
|
||||
</div>
|
||||
</div>
|
||||
<sig:NotificacionesConfiguracion ID="UcNotificaciones" runat="server" />
|
||||
</asp:Content>
|
||||
|
||||
<asp:Content ID="ContentScripts" ContentPlaceHolderID="J" runat="server">
|
||||
|
||||
@@ -107,6 +107,20 @@ namespace SIG.Web.Pages.Catalogos
|
||||
{
|
||||
Delete(id);
|
||||
}
|
||||
else if (e.CommandName == "Notificaciones")
|
||||
{
|
||||
DbResult<TipoTramiteModel> tramite =
|
||||
AppServices.TramiteCatalogService.GetTipoTramite(
|
||||
id, CurrentUser.CveUsuario, CurrentUser.NombreDominio);
|
||||
if (!tramite.Success || tramite.Data == null)
|
||||
{
|
||||
Alert(tramite.UserMessage, TipoMensaje.MsgAdvertencia);
|
||||
return;
|
||||
}
|
||||
|
||||
UcNotificaciones.AbrirTramite(
|
||||
id, tramite.Data.TipoTramite);
|
||||
}
|
||||
}
|
||||
|
||||
protected void BtnOrderMove_Click(object sender, EventArgs e)
|
||||
|
||||
@@ -62,6 +62,13 @@
|
||||
UpdateMode="Conditional" ChildrenAsTriggers="true">
|
||||
<ContentTemplate>
|
||||
<div class="sig-cliente-desarrollos-acciones">
|
||||
<asp:HyperLink ID="LnkLotes" runat="server"
|
||||
CssClass="btn default"
|
||||
NavigateUrl="~/Pages/Clientes/Lotes.aspx"
|
||||
Style="margin-right:6px;">
|
||||
<i class="fa fa-th" aria-hidden="true"></i>
|
||||
Lotes
|
||||
</asp:HyperLink>
|
||||
<asp:LinkButton ID="BtnNuevoFraccionamiento" runat="server"
|
||||
CssClass="btn blue" CausesValidation="false"
|
||||
OnClick="NuevoFraccionamiento_Click">
|
||||
@@ -80,7 +87,7 @@
|
||||
OnRowDataBound="EnlazarFila"
|
||||
OnRowCommand="Desarrollos_Comando">
|
||||
<Columns>
|
||||
<asp:TemplateField HeaderText="Fraccionamiento">
|
||||
<asp:TemplateField HeaderText="Fraccionamiento / Etapa">
|
||||
<ItemTemplate>
|
||||
<asp:Panel runat="server"
|
||||
Visible='<%# Convert.ToBoolean(Eval("EsFraccionamiento")) %>'>
|
||||
@@ -97,11 +104,7 @@
|
||||
<%#: ResumenFraccionamiento(Container.DataItem) %>
|
||||
</span>
|
||||
</asp:Panel>
|
||||
</ItemTemplate>
|
||||
</asp:TemplateField>
|
||||
|
||||
<asp:TemplateField HeaderText="Etapa">
|
||||
<ItemTemplate>
|
||||
<asp:HyperLink runat="server"
|
||||
CssClass="sig-cliente-etapa-enlace"
|
||||
Visible='<%# !Convert.ToBoolean(Eval("EsFraccionamiento")) %>'
|
||||
@@ -117,6 +120,13 @@
|
||||
</ItemTemplate>
|
||||
</asp:TemplateField>
|
||||
|
||||
<asp:TemplateField HeaderText="Avance">
|
||||
<ItemTemplate>
|
||||
<asp:Literal runat="server" Mode="Encode"
|
||||
Text='<%# FormatearAvance(Container.DataItem) %>' />
|
||||
</ItemTemplate>
|
||||
</asp:TemplateField>
|
||||
|
||||
<asp:TemplateField HeaderText="Fideicomiso">
|
||||
<ItemTemplate>
|
||||
<asp:CheckBox runat="server" Enabled="false"
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
using SIG.Web.AppCode.Configuration;
|
||||
using SIG.Web.AppCode.Infrastructure.WebForms;
|
||||
using SIG.Web.AppCode.Models.Common;
|
||||
using SIG.Web.AppCode.Models.Fraccionamientos;
|
||||
using SIG.Web.AppCode.Security;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Web;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
|
||||
namespace SIG.Web.Pages.Clientes
|
||||
{
|
||||
@@ -148,9 +149,9 @@ namespace SIG.Web.Pages.Clientes
|
||||
return;
|
||||
}
|
||||
|
||||
DbResult<int> resultado;
|
||||
|
||||
if (CveFraccionamientoEdicion <= 0)
|
||||
bool eraNuevo = CveFraccionamientoEdicion <= 0;
|
||||
string mensajeInformacion = eraNuevo ? "Fraccionamiento registrado." : "Fraccionamiento actualizado.";
|
||||
if (eraNuevo)
|
||||
{
|
||||
decimal? hectareasEtapa;
|
||||
|
||||
@@ -171,7 +172,7 @@ namespace SIG.Web.Pages.Clientes
|
||||
nombreEtapa = TxtFraccionamiento.Text.Trim() + " I";
|
||||
}
|
||||
|
||||
resultado = AppServices.ServicioPortalCliente.GuardarFraccionamientoConEtapa(
|
||||
DbResult<ResultadoGuardarFraccionamientoConEtapas> resultado = AppServices.ServicioPortalCliente.GuardarFraccionamientoConEtapa(
|
||||
new ModeloFraccionamiento
|
||||
{
|
||||
Fraccionamiento = TxtFraccionamiento.Text,
|
||||
@@ -187,9 +188,47 @@ namespace SIG.Web.Pages.Clientes
|
||||
},
|
||||
CurrentUser.CveUsuario,
|
||||
CurrentUser.NombreDominio);
|
||||
|
||||
|
||||
if (!resultado.Success)
|
||||
{
|
||||
Alert(resultado.UserMessage, TipoMensaje.MsgAdvertencia);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (resultado.Data != null && resultado.Data.Etapas != null && resultado.Data.Etapas.Count > 0)
|
||||
{
|
||||
mensajeInformacion +=
|
||||
"<br/><br/><strong>Etapas generadas:</strong><ul>";
|
||||
|
||||
foreach (ModeloEtapaFraccionamiento etapaGenerada in resultado.Data.Etapas)
|
||||
{
|
||||
string urlEtapa = ResolveUrl(
|
||||
"~/Pages/Fraccionamientos/EtapaDetalle.aspx?etapa=" +
|
||||
etapaGenerada.CveFraccionamientoEtapa.ToString(
|
||||
CultureInfo.InvariantCulture));
|
||||
|
||||
mensajeInformacion +=
|
||||
"<li><a href=\"" +
|
||||
HttpUtility.HtmlAttributeEncode(urlEtapa) +
|
||||
"\">" +
|
||||
HttpUtility.HtmlEncode(etapaGenerada.Etapa) +
|
||||
"</a></li>";
|
||||
}
|
||||
|
||||
mensajeInformacion += "</ul>";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
DbResult<int> resultado;
|
||||
resultado = AppServices.ServicioPortalCliente.GuardarFraccionamiento(
|
||||
new ModeloFraccionamiento
|
||||
{
|
||||
@@ -200,23 +239,18 @@ namespace SIG.Web.Pages.Clientes
|
||||
},
|
||||
CurrentUser.CveUsuario,
|
||||
CurrentUser.NombreDominio);
|
||||
if (!resultado.Success)
|
||||
{
|
||||
Alert(resultado.UserMessage, TipoMensaje.MsgAdvertencia);
|
||||
return;
|
||||
}
|
||||
}
|
||||
CveFraccionamientoEdicion = 0;
|
||||
Cargar();
|
||||
RegistraScript("$('#ModalFraccionamientoCliente').modal('hide');");
|
||||
Alert(mensajeInformacion, TipoMensaje.MsgInformacion);
|
||||
|
||||
if (!resultado.Success)
|
||||
{
|
||||
Alert(resultado.UserMessage, TipoMensaje.MsgAdvertencia);
|
||||
return;
|
||||
}
|
||||
|
||||
bool eraNuevo = CveFraccionamientoEdicion <= 0;
|
||||
CveFraccionamientoEdicion = 0;
|
||||
Cargar();
|
||||
RegistraScript("$('#ModalFraccionamientoCliente').modal('hide');");
|
||||
Alert(
|
||||
eraNuevo
|
||||
? "Fraccionamiento registrado."
|
||||
: "Fraccionamiento actualizado.",
|
||||
TipoMensaje.ToastExito);
|
||||
}
|
||||
|
||||
protected void GuardarEtapa_Click(object origen, EventArgs argumentos)
|
||||
@@ -295,6 +329,15 @@ namespace SIG.Web.Pages.Clientes
|
||||
fila.NumeroEtapas);
|
||||
}
|
||||
|
||||
protected string FormatearAvance(object objeto)
|
||||
{
|
||||
var fila = objeto as ModeloFilaDesarrollos;
|
||||
|
||||
return fila == null
|
||||
? string.Empty
|
||||
: fila.Avance.ToString("N2", CultureInfo.CurrentCulture) + " %";
|
||||
}
|
||||
|
||||
protected string FormatearHectareas(object objeto)
|
||||
{
|
||||
var fila = objeto as ModeloFilaDesarrollos;
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
AutoEventWireup="true" CodeFile="EtapaDetalle.aspx.cs"
|
||||
Inherits="SIG.Web.Pages.Clientes.EtapaDetalle" %>
|
||||
<%@ Register TagPrefix="cliente" TagName="Tramites" Src="~/UserControl/Clientes/TramitesCliente.ascx" %>
|
||||
<%@ Register TagPrefix="cliente" TagName="Documentos" Src="~/UserControl/Clientes/DocumentosCliente.ascx" %>
|
||||
<%@ Register TagPrefix="etapa" TagName="DocumentosEtapa" Src="~/UserControl/DocumentosEtapa.ascx" %>
|
||||
<%@ Register TagPrefix="cliente" TagName="Pagos" Src="~/UserControl/Clientes/PagosCliente.ascx" %>
|
||||
<%@ Register TagPrefix="lotes" TagName="LotesEtapa" Src="~/UserControl/LotesEtapa.ascx" %>
|
||||
|
||||
<asp:Content ID="ContenidoEncabezado" ContentPlaceHolderID="H" runat="server">
|
||||
<style>
|
||||
@@ -75,7 +76,13 @@
|
||||
|
||||
<ajax:TabPanel ID="PestanaDocumentos" runat="server" HeaderText="Documentos">
|
||||
<ContentTemplate>
|
||||
<cliente:Documentos ID="UcDocumentos" runat="server" />
|
||||
<etapa:DocumentosEtapa ID="UcDocumentos" runat="server" OnCambiado="Documentos_Cambiados" />
|
||||
</ContentTemplate>
|
||||
</ajax:TabPanel>
|
||||
|
||||
<ajax:TabPanel ID="PestanaLotes" runat="server" HeaderText="Lotes">
|
||||
<ContentTemplate>
|
||||
<lotes:LotesEtapa ID="UcLotesEtapa" runat="server" />
|
||||
</ContentTemplate>
|
||||
</ajax:TabPanel>
|
||||
|
||||
|
||||
@@ -18,6 +18,12 @@ namespace SIG.Web.Pages.Clientes
|
||||
set { ViewState["CveFraccionamientoEtapaActual"] = value; }
|
||||
}
|
||||
|
||||
private int CveFraccionamientoActual
|
||||
{
|
||||
get { return (int?)ViewState["CveFraccionamientoActual"] ?? 0; }
|
||||
set { ViewState["CveFraccionamientoActual"] = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
protected void Page_Load(object origen, EventArgs argumentos)
|
||||
@@ -47,6 +53,19 @@ namespace SIG.Web.Pages.Clientes
|
||||
Cargar();
|
||||
}
|
||||
|
||||
protected void Documentos_Cambiados(object origen, EventArgs argumentos)
|
||||
{
|
||||
if (CveFraccionamientoActual <= 0 ||
|
||||
CveFraccionamientoEtapaActual <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UcTramites.Cargar(
|
||||
CveFraccionamientoActual,
|
||||
CveFraccionamientoEtapaActual);
|
||||
}
|
||||
|
||||
private void Cargar()
|
||||
{
|
||||
DbResult<ModeloEtapaFraccionamiento> etapa =
|
||||
@@ -85,6 +104,7 @@ namespace SIG.Web.Pages.Clientes
|
||||
|
||||
ModeloEtapaFraccionamiento datosEtapa = etapa.Data;
|
||||
ModeloFraccionamiento datosFraccionamiento = fraccionamiento.Data;
|
||||
CveFraccionamientoActual = datosFraccionamiento.CveFraccionamiento;
|
||||
|
||||
LitEtapa.Text = datosEtapa.Etapa;
|
||||
LitHectareas.Text = datosEtapa.Hectareas.HasValue
|
||||
@@ -112,8 +132,10 @@ namespace SIG.Web.Pages.Clientes
|
||||
datosEtapa.CveFraccionamientoEtapa);
|
||||
UcDocumentos.Cargar(
|
||||
datosFraccionamiento.CveFraccionamiento,
|
||||
datosEtapa.CveFraccionamientoEtapa,
|
||||
false);
|
||||
datosEtapa.CveFraccionamientoEtapa);
|
||||
UcLotesEtapa.Cargar(
|
||||
datosFraccionamiento.CveFraccionamiento,
|
||||
datosEtapa.CveFraccionamientoEtapa);
|
||||
UcPagos.Cargar(
|
||||
datosFraccionamiento.CveFraccionamiento,
|
||||
datosEtapa.CveFraccionamientoEtapa,
|
||||
|
||||
31
SIG.Web/Pages/Clientes/Lotes.aspx
Normal file
31
SIG.Web/Pages/Clientes/Lotes.aspx
Normal file
@@ -0,0 +1,31 @@
|
||||
<%@ Page Title="Lotes" Language="C#" MasterPageFile="~/Site.master"
|
||||
AutoEventWireup="true" CodeFile="Lotes.aspx.cs"
|
||||
Inherits="SIG.Web.Pages.Clientes.Lotes" %>
|
||||
<%@ Register TagPrefix="sig" TagName="LotesEtapa"
|
||||
Src="~/UserControl/LotesEtapa.ascx" %>
|
||||
|
||||
<asp:Content ID="ContenidoPrincipal" ContentPlaceHolderID="C" runat="server">
|
||||
<asp:UpdatePanel ID="UpContextoLotes" runat="server"
|
||||
UpdateMode="Conditional" ChildrenAsTriggers="true">
|
||||
<ContentTemplate>
|
||||
<div class="row">
|
||||
<div class="form-group col-md-6">
|
||||
<label>Fraccionamiento</label>
|
||||
<asp:DropDownList ID="DdlFraccionamiento" runat="server"
|
||||
CssClass="form-control select2me" Width="100%"
|
||||
AutoPostBack="true"
|
||||
OnSelectedIndexChanged="Fraccionamiento_Cambiado" />
|
||||
</div>
|
||||
<div class="form-group col-md-6">
|
||||
<label>Etapa</label>
|
||||
<asp:DropDownList ID="DdlEtapa" runat="server"
|
||||
CssClass="form-control select2me" Width="100%"
|
||||
AutoPostBack="true"
|
||||
OnSelectedIndexChanged="Etapa_Cambiada" />
|
||||
</div>
|
||||
</div>
|
||||
</ContentTemplate>
|
||||
</asp:UpdatePanel>
|
||||
|
||||
<sig:LotesEtapa ID="UcLotesEtapa" runat="server" />
|
||||
</asp:Content>
|
||||
106
SIG.Web/Pages/Clientes/Lotes.aspx.cs
Normal file
106
SIG.Web/Pages/Clientes/Lotes.aspx.cs
Normal file
@@ -0,0 +1,106 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Web.UI.WebControls;
|
||||
using SIG.Web.AppCode.Configuration;
|
||||
using SIG.Web.AppCode.Infrastructure.WebForms;
|
||||
using SIG.Web.AppCode.Security;
|
||||
|
||||
namespace SIG.Web.Pages.Clientes
|
||||
{
|
||||
public partial class Lotes : ClsPaginaBase
|
||||
{
|
||||
protected void Page_Load(object sender, EventArgs e)
|
||||
{
|
||||
if (!CurrentUser.EsDesarrollador)
|
||||
{
|
||||
Response.Redirect("~/Default.aspx", false);
|
||||
Context.ApplicationInstance.CompleteRequest();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsPostBack)
|
||||
CargarFraccionamientos();
|
||||
}
|
||||
|
||||
private void CargarFraccionamientos()
|
||||
{
|
||||
var r = AppServices.ServicioPortalCliente.ListarDesarrollos(
|
||||
CurrentUser.CveUsuario, CurrentUser.NombreDominio);
|
||||
|
||||
DdlFraccionamiento.Items.Clear();
|
||||
DdlFraccionamiento.Items.Add(
|
||||
new ListItem("Seleccione fraccionamiento", ""));
|
||||
|
||||
if (!r.Success)
|
||||
{
|
||||
Alert(r.UserMessage, TipoMensaje.MsgAdvertencia);
|
||||
return;
|
||||
}
|
||||
|
||||
DdlFraccionamiento.DataSource = r.Data;
|
||||
DdlFraccionamiento.DataTextField = "Fraccionamiento";
|
||||
DdlFraccionamiento.DataValueField = "CveFraccionamiento";
|
||||
DdlFraccionamiento.DataBind();
|
||||
|
||||
int id;
|
||||
if (int.TryParse(Request.QueryString["id"], out id) &&
|
||||
DdlFraccionamiento.Items.FindByValue(id.ToString()) != null)
|
||||
{
|
||||
DdlFraccionamiento.SelectedValue = id.ToString();
|
||||
CargarEtapas(id);
|
||||
}
|
||||
}
|
||||
|
||||
protected void Fraccionamiento_Cambiado(object sender, EventArgs e)
|
||||
{
|
||||
int id;
|
||||
if (!int.TryParse(DdlFraccionamiento.SelectedValue, out id))
|
||||
{
|
||||
DdlEtapa.Items.Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
CargarEtapas(id);
|
||||
}
|
||||
|
||||
private void CargarEtapas(int cveFraccionamiento)
|
||||
{
|
||||
var r = AppServices.ServicioPortalCliente.ListarEtapas(
|
||||
cveFraccionamiento,
|
||||
CurrentUser.CveUsuario,
|
||||
CurrentUser.NombreDominio);
|
||||
|
||||
DdlEtapa.Items.Clear();
|
||||
DdlEtapa.Items.Add(new ListItem("Seleccione etapa", ""));
|
||||
|
||||
if (!r.Success)
|
||||
{
|
||||
Alert(r.UserMessage, TipoMensaje.MsgAdvertencia);
|
||||
return;
|
||||
}
|
||||
|
||||
DdlEtapa.DataSource = r.Data;
|
||||
DdlEtapa.DataTextField = "Etapa";
|
||||
DdlEtapa.DataValueField = "CveFraccionamientoEtapa";
|
||||
DdlEtapa.DataBind();
|
||||
|
||||
int etapa;
|
||||
if (int.TryParse(Request.QueryString["etapa"], out etapa) &&
|
||||
DdlEtapa.Items.FindByValue(etapa.ToString()) != null)
|
||||
{
|
||||
DdlEtapa.SelectedValue = etapa.ToString();
|
||||
UcLotesEtapa.Cargar(cveFraccionamiento, etapa);
|
||||
}
|
||||
}
|
||||
|
||||
protected void Etapa_Cambiada(object sender, EventArgs e)
|
||||
{
|
||||
int f, etapa;
|
||||
if (!int.TryParse(DdlFraccionamiento.SelectedValue, out f) ||
|
||||
!int.TryParse(DdlEtapa.SelectedValue, out etapa))
|
||||
return;
|
||||
|
||||
UcLotesEtapa.Cargar(f, etapa);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
<%@ Page Title="Detalle de desarrollador" Language="C#" MasterPageFile="~/Site.master"
|
||||
<%@ Page Title="Detalle de desarrollador" Language="C#" MasterPageFile="~/Site.master"
|
||||
AutoEventWireup="true" CodeFile="DesarrolladorDetalle.aspx.cs"
|
||||
Inherits="SIG.Web.Pages.Desarrolladores.DesarrolladorDetalle" %>
|
||||
|
||||
@@ -20,27 +20,33 @@
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.desarrollador-listado > tbody > tr.desarrollador-grupo > td {
|
||||
background: #edf4f8;
|
||||
padding: 10px 12px;
|
||||
.desarrollador-fila-fraccionamiento > td {
|
||||
background: #eef6fb;
|
||||
vertical-align: middle !important;
|
||||
}
|
||||
|
||||
.desarrollador-cabecera {
|
||||
display: flex;
|
||||
.desarrollador-fila-etapa > td:first-child {
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
.desarrollador-fraccionamiento-resumen {
|
||||
color: #7f8c8d;
|
||||
font-size: 12px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.desarrollador-etapa-enlace {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.desarrollador-accion-icono {
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.desarrollador-descripcion {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 8px 20px;
|
||||
}
|
||||
|
||||
.desarrollador-alternar {
|
||||
background: transparent;
|
||||
display: inline-flex;
|
||||
height: 28px;
|
||||
justify-content: center;
|
||||
margin: 0 2px;
|
||||
padding: 0;
|
||||
width: 28px;
|
||||
}
|
||||
|
||||
.desarrollador-credenciales {
|
||||
@@ -162,55 +168,88 @@
|
||||
<ContentTemplate>
|
||||
<div class="table-responsive">
|
||||
<asp:GridView ID="GvFraccionamientos" runat="server" AutoGenerateColumns="false"
|
||||
GridLines="None" CssClass="table table-hover Widthall desarrollador-listado"
|
||||
DataKeyNames="CveFraccionamiento,CveFraccionamientoEtapa"
|
||||
GridLines="None" CssClass="table table-hover Widthall sig-grid-agrupado"
|
||||
DataKeyNames="CveFraccionamiento,CveFraccionamientoEtapa,EsFraccionamiento"
|
||||
OnRowCommand="Fraccionamientos_Comando"
|
||||
OnRowDataBound="Fraccionamientos_FilaEnlazada"
|
||||
EmptyDataText="Este desarrollador no tiene fraccionamientos activos.">
|
||||
<Columns>
|
||||
<asp:TemplateField HeaderText="Etapa">
|
||||
<asp:TemplateField HeaderText="Fraccionamiento / Etapa">
|
||||
<ItemTemplate>
|
||||
<asp:Panel runat="server" CssClass="desarrollador-cabecera"
|
||||
<asp:Panel runat="server"
|
||||
Visible='<%# Convert.ToBoolean(Eval("EsFraccionamiento")) %>'>
|
||||
<div class="desarrollador-descripcion">
|
||||
<asp:HyperLink runat="server"
|
||||
Text='<%# Server.HtmlEncode(Convert.ToString(Eval("Fraccionamiento"))) %>'
|
||||
NavigateUrl='<%# ObtenerUrlFraccionamiento(Eval("CveFraccionamiento")) %>' />
|
||||
<span>
|
||||
<asp:Literal runat="server" Mode="Encode"
|
||||
Text='<%# DescribirFraccionamiento(Container.DataItem) %>' />
|
||||
</span>
|
||||
</div>
|
||||
<asp:LinkButton runat="server" CommandName="AgregarEtapa"
|
||||
CausesValidation="false" CssClass="btn btn-primary btn-circle btn-sm"
|
||||
ToolTip="Agregar etapa" aria-label="Agregar etapa">
|
||||
<i class="fa fa-plus" aria-hidden="true"></i>
|
||||
</asp:LinkButton>
|
||||
<button type="button" class="btn default desarrollador-alternar"
|
||||
title="Mostrar u ocultar etapas" aria-label="Mostrar u ocultar etapas"
|
||||
<button type="button"
|
||||
class="btn btn-circle btn-xs default sig-grid-alternar-grupo-accion desarrollador-accion-icono"
|
||||
title="Mostrar u ocultar etapas"
|
||||
aria-label="Mostrar u ocultar etapas"
|
||||
aria-expanded="true">
|
||||
<i class="fa fa-chevron-up" aria-hidden="true"></i>
|
||||
<i class="fa fa-chevron-up sig-grid-icono-agrupacion" aria-hidden="true"></i>
|
||||
</button>
|
||||
<asp:HyperLink runat="server"
|
||||
Text='<%# Server.HtmlEncode(Convert.ToString(Eval("Fraccionamiento"))) %>'
|
||||
NavigateUrl='<%# ObtenerUrlFraccionamiento(Eval("CveFraccionamiento")) %>' />
|
||||
<span class="desarrollador-fraccionamiento-resumen">
|
||||
<%#: DescribirFraccionamiento(Container.DataItem) %>
|
||||
</span>
|
||||
</asp:Panel>
|
||||
<asp:Literal runat="server" Mode="Encode" Text='<%# Eval("Etapa") %>'
|
||||
Visible='<%# !Convert.ToBoolean(Eval("EsFraccionamiento")) %>' />
|
||||
|
||||
<asp:HyperLink runat="server"
|
||||
CssClass="desarrollador-etapa-enlace"
|
||||
Visible='<%# !Convert.ToBoolean(Eval("EsFraccionamiento")) %>'
|
||||
Text='<%# Server.HtmlEncode(Convert.ToString(Eval("Etapa"))) %>'
|
||||
NavigateUrl='<%# ObtenerUrlEtapa(Eval("CveFraccionamientoEtapa")) %>' />
|
||||
</ItemTemplate>
|
||||
</asp:TemplateField>
|
||||
<asp:BoundField DataField="Hectareas" HeaderText="Hectáreas de la etapa" DataFormatString="{0:N2}" />
|
||||
<asp:CheckBoxField DataField="Fideicomiso" HeaderText="Fideicomiso" />
|
||||
<asp:CheckBoxField DataField="EsActivo" HeaderText="Activa" />
|
||||
|
||||
<asp:TemplateField HeaderText="Hectáreas">
|
||||
<ItemTemplate>
|
||||
<asp:Literal runat="server" Mode="Encode"
|
||||
Text='<%# FormatearHectareas(Container.DataItem) %>' />
|
||||
</ItemTemplate>
|
||||
</asp:TemplateField>
|
||||
|
||||
<asp:TemplateField HeaderText="Avance">
|
||||
<ItemTemplate>
|
||||
<asp:Literal runat="server" Mode="Encode"
|
||||
Text='<%# FormatearAvance(Container.DataItem) %>' />
|
||||
</ItemTemplate>
|
||||
</asp:TemplateField>
|
||||
|
||||
<asp:TemplateField HeaderText="Fideicomiso">
|
||||
<ItemTemplate>
|
||||
<asp:CheckBox runat="server" Enabled="false"
|
||||
Visible='<%# !Convert.ToBoolean(Eval("EsFraccionamiento")) %>'
|
||||
Checked='<%# Convert.ToBoolean(Eval("Fideicomiso")) %>' />
|
||||
</ItemTemplate>
|
||||
</asp:TemplateField>
|
||||
|
||||
<asp:TemplateField HeaderText="Activa">
|
||||
<ItemTemplate>
|
||||
<asp:CheckBox runat="server" Enabled="false"
|
||||
Checked='<%# Convert.ToBoolean(Eval("EsActivo")) %>' />
|
||||
</ItemTemplate>
|
||||
</asp:TemplateField>
|
||||
|
||||
<asp:TemplateField HeaderText="Acciones"
|
||||
HeaderStyle-CssClass="sig-columna-acciones"
|
||||
ItemStyle-CssClass="sig-columna-acciones">
|
||||
<ItemTemplate>
|
||||
<asp:LinkButton runat="server" CommandName="AgregarEtapa"
|
||||
Visible='<%# Convert.ToBoolean(Eval("EsFraccionamiento")) %>'
|
||||
CausesValidation="false"
|
||||
CssClass="btn btn-circle btn-xs blue desarrollador-accion-icono"
|
||||
ToolTip="Agregar etapa" aria-label="Agregar etapa">
|
||||
<i class="fa fa-plus" aria-hidden="true"></i>
|
||||
</asp:LinkButton>
|
||||
|
||||
<asp:HyperLink runat="server"
|
||||
CssClass="btn btn-circle btn-sm primary sig-accion-icono"
|
||||
CssClass="btn btn-circle btn-xs blue desarrollador-accion-icono"
|
||||
ToolTip="Ver etapa"
|
||||
aria-label="Ver etapa"
|
||||
NavigateUrl='<%# ObtenerUrlEtapa(Eval("CveFraccionamientoEtapa")) %>'
|
||||
Visible='<%# !Convert.ToBoolean(Eval("EsFraccionamiento")) %>'>
|
||||
<i class="fa fa-eye" aria-hidden="true"></i>
|
||||
</asp:HyperLink>
|
||||
<i class="fa fa-eye" aria-hidden="true"></i>
|
||||
</asp:HyperLink>
|
||||
</ItemTemplate>
|
||||
</asp:TemplateField>
|
||||
</Columns>
|
||||
@@ -312,40 +351,4 @@
|
||||
</div>
|
||||
</asp:Content>
|
||||
<asp:Content ID="ContenidoScripts" ContentPlaceHolderID="J" runat="server">
|
||||
<script>
|
||||
(function () {
|
||||
var gruposContraidos = {};
|
||||
function aplicarGrupo(tabla, boton, contraido) {
|
||||
var clave = boton.closest("tr").getAttribute("data-fraccionamiento");
|
||||
boton.setAttribute("aria-expanded", contraido ? "false" : "true");
|
||||
boton.querySelector("i").className = contraido ? "fa fa-chevron-down" : "fa fa-chevron-up";
|
||||
tabla.querySelectorAll('tr[data-cabecera="0"]').forEach(function (fila) {
|
||||
if (fila.getAttribute("data-fraccionamiento") === clave) {
|
||||
fila.style.display = contraido ? "none" : "";
|
||||
}
|
||||
});
|
||||
}
|
||||
function iniciarDesarrollos() {
|
||||
document.querySelectorAll(".desarrollador-listado").forEach(function (tabla) {
|
||||
if (tabla.getAttribute("data-desarrollos-inicializado") === "1") {
|
||||
return;
|
||||
}
|
||||
tabla.setAttribute("data-desarrollos-inicializado", "1");
|
||||
tabla.querySelectorAll(".desarrollador-alternar").forEach(function (boton) {
|
||||
var clave = boton.closest("tr").getAttribute("data-fraccionamiento");
|
||||
aplicarGrupo(tabla, boton, gruposContraidos[clave] === true);
|
||||
boton.addEventListener("click", function () {
|
||||
gruposContraidos[clave] = boton.getAttribute("aria-expanded") === "true";
|
||||
aplicarGrupo(tabla, boton, gruposContraidos[clave]);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
if (window.Sys && Sys.Application) {
|
||||
Sys.Application.add_load(iniciarDesarrollos);
|
||||
} else {
|
||||
document.addEventListener("DOMContentLoaded", iniciarDesarrollos);
|
||||
}
|
||||
}());
|
||||
</script>
|
||||
</asp:Content>
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Collections.Generic;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
using SIG.Web.AppCode.Configuration;
|
||||
using SIG.Web.AppCode.Infrastructure.WebForms;
|
||||
using SIG.Web.AppCode.Models.Clientes;
|
||||
using SIG.Web.AppCode.Models.Common;
|
||||
using SIG.Web.AppCode.Models.Fraccionamientos;
|
||||
using SIG.Web.AppCode.Models.Convenios;
|
||||
using SIG.Web.AppCode.Session;
|
||||
using SIG.Web.AppCode.Models.Fraccionamientos;
|
||||
using SIG.Web.AppCode.Security;
|
||||
using SIG.Web.AppCode.Session;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Web;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
|
||||
namespace SIG.Web.Pages.Desarrolladores
|
||||
{
|
||||
@@ -23,27 +24,69 @@ namespace SIG.Web.Pages.Desarrolladores
|
||||
return;
|
||||
}
|
||||
|
||||
var desarrollo = (ModeloFilaDesarrollos)argumentos.Row.DataItem;
|
||||
argumentos.Row.Attributes["data-fraccionamiento"] =
|
||||
var desarrollo = argumentos.Row.DataItem as ModeloFilaDesarrollos;
|
||||
if (desarrollo == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string grupo = "desarrollo-" +
|
||||
desarrollo.CveFraccionamiento.ToString(CultureInfo.InvariantCulture);
|
||||
argumentos.Row.Attributes["data-cabecera"] = desarrollo.EsFraccionamiento ? "1" : "0";
|
||||
|
||||
if (desarrollo.EsFraccionamiento)
|
||||
{
|
||||
argumentos.Row.CssClass = "desarrollador-grupo";
|
||||
argumentos.Row.Cells[0].ColumnSpan = GvFraccionamientos.Columns.Count;
|
||||
for (int indice = 1; indice < argumentos.Row.Cells.Count; indice++)
|
||||
{
|
||||
argumentos.Row.Cells[indice].Visible = false;
|
||||
}
|
||||
argumentos.Row.CssClass =
|
||||
(argumentos.Row.CssClass +
|
||||
" sig-grid-grupo desarrollador-fila-fraccionamiento").Trim();
|
||||
argumentos.Row.Attributes["data-sig-group-row"] = "1";
|
||||
argumentos.Row.Attributes["data-sig-group-id"] = grupo;
|
||||
argumentos.Row.Attributes["data-sig-level"] = "2";
|
||||
argumentos.Row.Attributes["data-sig-expanded-default"] = "true";
|
||||
return;
|
||||
}
|
||||
|
||||
argumentos.Row.CssClass =
|
||||
(argumentos.Row.CssClass +
|
||||
" sig-grid-fila-dato desarrollador-fila-etapa").Trim();
|
||||
argumentos.Row.Attributes["data-sig-item-row"] = "1";
|
||||
argumentos.Row.Attributes["data-sig-parent-group"] = grupo;
|
||||
argumentos.Row.Attributes["data-sig-level"] = "1";
|
||||
}
|
||||
|
||||
protected string DescribirFraccionamiento(object objeto)
|
||||
{
|
||||
var fila = (ModeloFilaDesarrollos)objeto;
|
||||
return string.Format(CultureInfo.CurrentCulture,
|
||||
"{0} · {1:N2} ha · {2} etapas · {3}",
|
||||
fila.Ubicacion, fila.HectareasFraccionamiento, fila.NumeroEtapas, fila.Estatus);
|
||||
return string.Format(
|
||||
CultureInfo.CurrentCulture,
|
||||
"{0} · {1} etapa(s)",
|
||||
fila.Estatus,
|
||||
fila.NumeroEtapas);
|
||||
}
|
||||
|
||||
protected string FormatearHectareas(object objeto)
|
||||
{
|
||||
var fila = objeto as ModeloFilaDesarrollos;
|
||||
if (fila == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
decimal? hectareas = fila.EsFraccionamiento
|
||||
? fila.HectareasFraccionamiento
|
||||
: fila.Hectareas;
|
||||
|
||||
return hectareas.HasValue
|
||||
? hectareas.Value.ToString("N2", CultureInfo.CurrentCulture)
|
||||
: string.Empty;
|
||||
}
|
||||
|
||||
protected string FormatearAvance(object objeto)
|
||||
{
|
||||
var fila = objeto as ModeloFilaDesarrollos;
|
||||
|
||||
return fila == null
|
||||
? string.Empty
|
||||
: fila.Avance.ToString("N2", CultureInfo.CurrentCulture) + " %";
|
||||
}
|
||||
|
||||
protected void Etapa_Cambiada(object origen, EventArgs argumentos)
|
||||
@@ -199,7 +242,7 @@ namespace SIG.Web.Pages.Desarrolladores
|
||||
return;
|
||||
}
|
||||
|
||||
DbResult<int> resultado = AppServices.ServicioFraccionamiento.GuardarConEtapas(
|
||||
DbResult<ResultadoGuardarFraccionamientoConEtapas> resultado = AppServices.ServicioFraccionamiento.GuardarConEtapas(
|
||||
new ModeloFraccionamiento
|
||||
{
|
||||
CveCliente = CveClienteActual,
|
||||
@@ -224,6 +267,33 @@ namespace SIG.Web.Pages.Desarrolladores
|
||||
CargarFraccionamientos();
|
||||
UpFraccionamientos.Update();
|
||||
RegistraScript("$('#ModalFraccionamiento').modal('hide');");
|
||||
|
||||
string mensajeInformacion = "Fraccionamiento registrado.";
|
||||
|
||||
if (resultado.Data != null &&
|
||||
resultado.Data.Etapas != null &&
|
||||
resultado.Data.Etapas.Count > 0)
|
||||
{
|
||||
mensajeInformacion +=
|
||||
"<br/><br/><strong>Etapas generadas:</strong><ul>";
|
||||
|
||||
foreach (ModeloEtapaFraccionamiento etapaGenerada in resultado.Data.Etapas)
|
||||
{
|
||||
string urlEtapa = ResolveUrl(
|
||||
"~/Pages/Fraccionamientos/EtapaDetalle.aspx?etapa=" +
|
||||
etapaGenerada.CveFraccionamientoEtapa.ToString(
|
||||
CultureInfo.InvariantCulture));
|
||||
|
||||
mensajeInformacion +=
|
||||
"<li><a href=\"" +
|
||||
HttpUtility.HtmlAttributeEncode(urlEtapa) +
|
||||
"\">" +
|
||||
HttpUtility.HtmlEncode(etapaGenerada.Etapa) +
|
||||
"</a></li>";
|
||||
}
|
||||
|
||||
mensajeInformacion += "</ul>";
|
||||
}
|
||||
Alert("Fraccionamiento registrado.", TipoMensaje.ToastExito);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<%@ Page Title="Desarrolladores" Language="C#" MasterPageFile="~/Site.master"
|
||||
<%@ Page Title="Desarrolladores" Language="C#" MasterPageFile="~/Site.master"
|
||||
AutoEventWireup="true" CodeFile="Desarrolladores.aspx.cs"
|
||||
Inherits="SIG.Web.Pages.Desarrolladores.Desarrolladores" %>
|
||||
<%@ Register TagPrefix="sig" TagName="CapturaEtapas" Src="~/UserControl/CapturaEtapas.ascx" %>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
@@ -192,7 +192,7 @@ namespace SIG.Web.Pages.Desarrolladores
|
||||
return;
|
||||
}
|
||||
|
||||
var resultado = AppServices.ServicioFraccionamiento.GuardarConEtapas(
|
||||
DbResult<ResultadoGuardarFraccionamientoConEtapas> resultado = AppServices.ServicioFraccionamiento.GuardarConEtapas(
|
||||
new ModeloFraccionamiento
|
||||
{
|
||||
CveCliente = CveClienteFraccionamientoActual,
|
||||
@@ -210,13 +210,40 @@ namespace SIG.Web.Pages.Desarrolladores
|
||||
return;
|
||||
}
|
||||
|
||||
string mensajeInformacion = "Fraccionamiento registrado.";
|
||||
|
||||
if (resultado.Data != null &&
|
||||
resultado.Data.Etapas != null &&
|
||||
resultado.Data.Etapas.Count > 0)
|
||||
{
|
||||
mensajeInformacion +=
|
||||
"<br/><br/><strong>Etapas generadas:</strong><ul>";
|
||||
|
||||
foreach (ModeloEtapaFraccionamiento etapaGenerada in resultado.Data.Etapas)
|
||||
{
|
||||
string urlEtapa = ResolveUrl(
|
||||
"~/Pages/Fraccionamientos/EtapaDetalle.aspx?etapa=" +
|
||||
etapaGenerada.CveFraccionamientoEtapa.ToString(
|
||||
CultureInfo.InvariantCulture));
|
||||
|
||||
mensajeInformacion +=
|
||||
"<li><a href=\"" +
|
||||
HttpUtility.HtmlAttributeEncode(urlEtapa) +
|
||||
"\">" +
|
||||
HttpUtility.HtmlEncode(etapaGenerada.Etapa) +
|
||||
"</a></li>";
|
||||
}
|
||||
|
||||
mensajeInformacion += "</ul>";
|
||||
}
|
||||
|
||||
CveClienteFraccionamientoActual = 0;
|
||||
TxtFraccionamiento.Text = string.Empty;
|
||||
TxtUbicacionFraccionamiento.Text = string.Empty;
|
||||
TxtHectareasFraccionamiento.Text = string.Empty;
|
||||
UcCapturaEtapas.Reiniciar();
|
||||
RegistraScript("$('#ModalAltaFraccionamiento').modal('hide');");
|
||||
Alert("Fraccionamiento registrado.", TipoMensaje.ToastExito);
|
||||
Alert(mensajeInformacion, TipoMensaje.MsgInformacion);
|
||||
}
|
||||
|
||||
protected void Guardar_Click(object origen, EventArgs argumentos)
|
||||
|
||||
@@ -239,7 +239,7 @@ namespace SIG.Web.Pages.Fraccionamientos
|
||||
return;
|
||||
}
|
||||
|
||||
DbResult<int> resultado = AppServices.ServicioFraccionamiento.GuardarConEtapas(
|
||||
DbResult<ResultadoGuardarFraccionamientoConEtapas> resultado = AppServices.ServicioFraccionamiento.GuardarConEtapas(
|
||||
modelo,
|
||||
etapas,
|
||||
CurrentUser.CveUsuario,
|
||||
@@ -256,9 +256,7 @@ namespace SIG.Web.Pages.Fraccionamientos
|
||||
"Fraccionamiento guardado correctamente.",
|
||||
TipoMensaje.ToastExito);
|
||||
|
||||
string fraccionamientoDetalleUrl =
|
||||
"~/Pages/Fraccionamientos/FraccionamientoDetalle.aspx?id=" +
|
||||
resultado.Data.ToString(CultureInfo.InvariantCulture);
|
||||
string fraccionamientoDetalleUrl = string.Format("~/Pages/Fraccionamientos/FraccionamientoDetalle.aspx?id=", resultado.Data.CveFraccionamiento);
|
||||
|
||||
Response.Redirect(fraccionamientoDetalleUrl, false);
|
||||
Context.ApplicationInstance.CompleteRequest();
|
||||
|
||||
1
SIG.Web/Pages/Fraccionamientos/TramiteDocumentosZip.ashx
Normal file
1
SIG.Web/Pages/Fraccionamientos/TramiteDocumentosZip.ashx
Normal file
@@ -0,0 +1 @@
|
||||
<%@ WebHandler Language="C#" Class="SIG.Web.Pages.Fraccionamientos.TramiteDocumentosZipHandler" %>
|
||||
@@ -0,0 +1,11 @@
|
||||
--- ANTES/App_Code/Contracts/Convenios/IRepositorioConvenios.cs
|
||||
+++ DESPUES/App_Code/Contracts/Convenios/IRepositorioConvenios.cs
|
||||
@@ -10,6 +10,8 @@
|
||||
DbResult<ConvenioDetalleCompleto> Obtener(int cveConvenio, int usuario, string dominio);
|
||||
DbResult<List<ConvenioConceptoCatalogo>> ListarConceptos(int usuario, string dominio);
|
||||
DbResult<int> Agregar(SolicitudAltaConvenio solicitud, int usuario, string dominio);
|
||||
+ DbResult<ConvenioLotesConvenio> ObtenerLotesConvenio(int cveConvenio, int usuario, string dominio);
|
||||
+ DbResult<bool> GuardarLotesConvenio(int cveConvenio, int lotesConvenio, int usuario, string dominio);
|
||||
DbResult<bool> Eliminar(int cveConvenio, int usuario, string dominio);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
--- ANTES/App_Code/Models/Convenios/ModelosConvenios.cs
|
||||
+++ DESPUES/App_Code/Models/Convenios/ModelosConvenios.cs
|
||||
@@ -49,6 +49,7 @@
|
||||
public int ViviendasEnConvenio { get; set; }
|
||||
public int? ViviendasPendientes { get; set; }
|
||||
public int? ViviendasContratadas { get; set; }
|
||||
+ public int LotesConvenio { get; set; }
|
||||
public string Observaciones { get; set; }
|
||||
public decimal ImporteConvenio { get; set; }
|
||||
public decimal ImportePagado { get; set; }
|
||||
@@ -102,9 +103,16 @@
|
||||
public int ViviendasEnConvenio { get; set; }
|
||||
public int? ViviendasPendientes { get; set; }
|
||||
public int? ViviendasContratadas { get; set; }
|
||||
+ public int LotesConvenio { get; set; }
|
||||
public DateTime FechaConvenio { get; set; }
|
||||
public string Observaciones { get; set; }
|
||||
public List<ConvenioConceptoCaptura> Conceptos { get; set; }
|
||||
+ }
|
||||
+
|
||||
+ public sealed class ConvenioLotesConvenio
|
||||
+ {
|
||||
+ public int CveConvenio { get; set; }
|
||||
+ public int LotesConvenio { get; set; }
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
@@ -0,0 +1,10 @@
|
||||
--- ANTES/App_Code/Models/Fraccionamientos/ModelosFraccionamiento.cs
|
||||
+++ DESPUES/App_Code/Models/Fraccionamientos/ModelosFraccionamiento.cs
|
||||
@@ -14,6 +14,7 @@
|
||||
public bool EsFraccionamiento { get; set; }
|
||||
public string Etapa { get; set; }
|
||||
public decimal? Hectareas { get; set; }
|
||||
+ public decimal Avance { get; set; }
|
||||
public bool Fideicomiso { get; set; }
|
||||
public bool EsActivo { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
--- ANTES/App_Code/Models/Tramites/TramiteSolicitudModels.cs
|
||||
+++ DESPUES/App_Code/Models/Tramites/TramiteSolicitudModels.cs
|
||||
@@ -49,6 +49,28 @@
|
||||
public DateTime? FechaAutorizacion { get; set; }
|
||||
public bool PuedeCambiarEstatus { get; set; }
|
||||
public bool EsAutorizada { get; set; }
|
||||
+ public int DocumentosPendientes { get; set; }
|
||||
+ public int PagosPendientes { get; set; }
|
||||
+
|
||||
+ public string TextoDocumentos
|
||||
+ {
|
||||
+ get
|
||||
+ {
|
||||
+ return DocumentosPendientes == 0
|
||||
+ ? "Completo"
|
||||
+ : DocumentosPendientes + " pendiente(s)";
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public string TextoPagos
|
||||
+ {
|
||||
+ get
|
||||
+ {
|
||||
+ return PagosPendientes == 0
|
||||
+ ? "Sin pendientes"
|
||||
+ : PagosPendientes + " pendiente(s)";
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
@@ -0,0 +1,59 @@
|
||||
--- ANTES/App_Code/Repositories/Convenios/RepositorioConvenios.cs
|
||||
+++ DESPUES/App_Code/Repositories/Convenios/RepositorioConvenios.cs
|
||||
@@ -19,6 +19,8 @@
|
||||
private const string ProcedimientoObtener = "dbo.PA_Tra_ConvenioGet";
|
||||
private const string ProcedimientoListarConceptos = "dbo.PA_Tra_ConvenioConceptoList";
|
||||
private const string ProcedimientoAgregar = "dbo.PA_Tra_ConvenioAdd";
|
||||
+ private const string ProcedimientoObtenerLotes = "dbo.PA_Tra_ConvenioLotesGet";
|
||||
+ private const string ProcedimientoGuardarLotes = "dbo.PA_Tra_ConvenioLotesUpdate";
|
||||
private const string ProcedimientoEliminar = "dbo.PA_Tra_ConvenioDelete";
|
||||
|
||||
public RepositorioConvenios(IDbExecutor ejecutor)
|
||||
@@ -193,6 +195,47 @@
|
||||
"@ConceptosXml",
|
||||
conceptosXml,
|
||||
DbType.Xml);
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
+ public DbResult<ConvenioLotesConvenio> ObtenerLotesConvenio(
|
||||
+ int cveConvenio,
|
||||
+ int usuario,
|
||||
+ string dominio)
|
||||
+ {
|
||||
+ return QueryOne<ConvenioLotesConvenio>(
|
||||
+ ProcedimientoObtenerLotes,
|
||||
+ usuario,
|
||||
+ dominio,
|
||||
+ comando => StoredProcedureCommand.AddInput(
|
||||
+ comando,
|
||||
+ "@CveConvenio",
|
||||
+ cveConvenio,
|
||||
+ DbType.Int32));
|
||||
+ }
|
||||
+
|
||||
+ public DbResult<bool> GuardarLotesConvenio(
|
||||
+ int cveConvenio,
|
||||
+ int lotesConvenio,
|
||||
+ int usuario,
|
||||
+ string dominio)
|
||||
+ {
|
||||
+ return Execute(
|
||||
+ ProcedimientoGuardarLotes,
|
||||
+ usuario,
|
||||
+ dominio,
|
||||
+ comando =>
|
||||
+ {
|
||||
+ StoredProcedureCommand.AddInput(
|
||||
+ comando,
|
||||
+ "@CveConvenio",
|
||||
+ cveConvenio,
|
||||
+ DbType.Int32);
|
||||
+ StoredProcedureCommand.AddInput(
|
||||
+ comando,
|
||||
+ "@LotesConvenio",
|
||||
+ lotesConvenio,
|
||||
+ DbType.Int32);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
--- ANTES/App_Code/Services/Convenios/ServicioConvenios.cs
|
||||
+++ DESPUES/App_Code/Services/Convenios/ServicioConvenios.cs
|
||||
@@ -69,6 +69,23 @@
|
||||
null);
|
||||
}
|
||||
|
||||
+ DbResult<ConvenioLotesConvenio> lotes =
|
||||
+ _repositorio.ObtenerLotesConvenio(
|
||||
+ cveConvenio,
|
||||
+ usuario,
|
||||
+ dominio);
|
||||
+
|
||||
+ if (!lotes.Success)
|
||||
+ {
|
||||
+ return DbResult<ConvenioDetalleCompleto>.Fail(
|
||||
+ lotes.UserMessage,
|
||||
+ lotes.TechnicalMessage,
|
||||
+ lotes.Exception);
|
||||
+ }
|
||||
+
|
||||
+ resultado.Data.Encabezado.LotesConvenio =
|
||||
+ lotes.Data == null ? 0 : lotes.Data.LotesConvenio;
|
||||
+
|
||||
return resultado;
|
||||
}
|
||||
|
||||
@@ -112,11 +129,26 @@
|
||||
usuario,
|
||||
dominio);
|
||||
|
||||
- if (resultado.Success)
|
||||
- {
|
||||
- transaccion.Commit();
|
||||
- }
|
||||
-
|
||||
+ if (!resultado.Success)
|
||||
+ {
|
||||
+ return resultado;
|
||||
+ }
|
||||
+
|
||||
+ DbResult<bool> lotes = _repositorio.GuardarLotesConvenio(
|
||||
+ resultado.Data,
|
||||
+ solicitud.LotesConvenio,
|
||||
+ usuario,
|
||||
+ dominio);
|
||||
+
|
||||
+ if (!lotes.Success)
|
||||
+ {
|
||||
+ return DbResult<int>.Fail(
|
||||
+ lotes.UserMessage,
|
||||
+ lotes.TechnicalMessage,
|
||||
+ lotes.Exception);
|
||||
+ }
|
||||
+
|
||||
+ transaccion.Commit();
|
||||
return resultado;
|
||||
}
|
||||
}
|
||||
@@ -191,6 +223,11 @@
|
||||
return "La cantidad de viviendas en convenio no es válida.";
|
||||
}
|
||||
|
||||
+ if (solicitud.LotesConvenio < 0)
|
||||
+ {
|
||||
+ return "La cantidad de lotes del convenio no es válida.";
|
||||
+ }
|
||||
+
|
||||
if (solicitud.Conceptos == null || solicitud.Conceptos.Count == 0)
|
||||
{
|
||||
return "Agregue al menos un concepto al convenio.";
|
||||
@@ -0,0 +1,90 @@
|
||||
--- ANTES/App_Code/Services/Fraccionamientos/ServicioFraccionamiento.cs
|
||||
+++ DESPUES/App_Code/Services/Fraccionamientos/ServicioFraccionamiento.cs
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
+using System.Linq;
|
||||
using SIG.Web.AppCode.Contracts.Bitacora;
|
||||
using SIG.Web.AppCode.Contracts.Fraccionamientos;
|
||||
using SIG.Web.AppCode.Contracts.Tramites;
|
||||
@@ -34,7 +35,79 @@
|
||||
return CrearFallo<List<ModeloFilaDesarrollos>>("Seleccione un desarrollador válido.");
|
||||
}
|
||||
|
||||
- return _repositorio.ListarDesarrollos(cveCliente, cveUsuarioEjecuta, nombreDominio);
|
||||
+ DbResult<List<ModeloFilaDesarrollos>> resultado =
|
||||
+ _repositorio.ListarDesarrollos(
|
||||
+ cveCliente,
|
||||
+ cveUsuarioEjecuta,
|
||||
+ nombreDominio);
|
||||
+
|
||||
+ if (!resultado.Success || resultado.Data == null)
|
||||
+ {
|
||||
+ return resultado;
|
||||
+ }
|
||||
+
|
||||
+ List<ModeloFilaDesarrollos> filas = resultado.Data;
|
||||
+
|
||||
+ /*
|
||||
+ * PA_Fraccionamientos_DesarrolladorEtapasList es el listado
|
||||
+ * agrupado existente. No se cambia su contrato. El avance ya
|
||||
+ * existe en PA_Fraccionamientos_EtapaList, por lo que se
|
||||
+ * complementa aquí para que admin y cliente usen el mismo dato.
|
||||
+ */
|
||||
+ foreach (int cveFraccionamiento in filas
|
||||
+ .Select(x => x.CveFraccionamiento)
|
||||
+ .Distinct())
|
||||
+ {
|
||||
+ DbResult<List<ModeloEtapaFraccionamiento>> etapasResultado =
|
||||
+ _repositorio.ListarEtapas(
|
||||
+ cveFraccionamiento,
|
||||
+ cveUsuarioEjecuta,
|
||||
+ nombreDominio);
|
||||
+
|
||||
+ if (!etapasResultado.Success)
|
||||
+ {
|
||||
+ return DbResult<List<ModeloFilaDesarrollos>>.Fail(
|
||||
+ etapasResultado.UserMessage,
|
||||
+ etapasResultado.TechnicalMessage,
|
||||
+ etapasResultado.Exception);
|
||||
+ }
|
||||
+
|
||||
+ List<ModeloEtapaFraccionamiento> etapas =
|
||||
+ etapasResultado.Data ?? new List<ModeloEtapaFraccionamiento>();
|
||||
+
|
||||
+ Dictionary<int, decimal> avances = etapas
|
||||
+ .ToDictionary(x => x.CveFraccionamientoEtapa, x => x.Avance);
|
||||
+
|
||||
+ foreach (ModeloFilaDesarrollos fila in filas.Where(x =>
|
||||
+ x.CveFraccionamiento == cveFraccionamiento &&
|
||||
+ !x.EsFraccionamiento &&
|
||||
+ x.CveFraccionamientoEtapa.HasValue))
|
||||
+ {
|
||||
+ decimal avance;
|
||||
+ if (avances.TryGetValue(
|
||||
+ fila.CveFraccionamientoEtapa.Value,
|
||||
+ out avance))
|
||||
+ {
|
||||
+ fila.Avance = avance;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ModeloFilaDesarrollos cabecera = filas.FirstOrDefault(x =>
|
||||
+ x.CveFraccionamiento == cveFraccionamiento &&
|
||||
+ x.EsFraccionamiento);
|
||||
+
|
||||
+ if (cabecera != null)
|
||||
+ {
|
||||
+ cabecera.Avance = etapas.Count == 0
|
||||
+ ? 0m
|
||||
+ : decimal.Round(
|
||||
+ etapas.Average(x => x.Avance),
|
||||
+ 2,
|
||||
+ MidpointRounding.AwayFromZero);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return resultado;
|
||||
}
|
||||
|
||||
public DbResult<List<OpcionClienteFraccionamiento>> ListarClientes(int cveUsuarioEjecuta, string nombreDominio)
|
||||
38
SIG.Web/Patches/Pages__Clientes__Desarrollos_aspx.patch.txt
Normal file
38
SIG.Web/Patches/Pages__Clientes__Desarrollos_aspx.patch.txt
Normal file
@@ -0,0 +1,38 @@
|
||||
--- ANTES/Pages/Clientes/Desarrollos.aspx
|
||||
+++ DESPUES/Pages/Clientes/Desarrollos.aspx
|
||||
@@ -80,7 +80,7 @@
|
||||
OnRowDataBound="EnlazarFila"
|
||||
OnRowCommand="Desarrollos_Comando">
|
||||
<Columns>
|
||||
- <asp:TemplateField HeaderText="Fraccionamiento">
|
||||
+ <asp:TemplateField HeaderText="Fraccionamiento / Etapa">
|
||||
<ItemTemplate>
|
||||
<asp:Panel runat="server"
|
||||
Visible='<%# Convert.ToBoolean(Eval("EsFraccionamiento")) %>'>
|
||||
@@ -97,11 +97,7 @@
|
||||
<%#: ResumenFraccionamiento(Container.DataItem) %>
|
||||
</span>
|
||||
</asp:Panel>
|
||||
- </ItemTemplate>
|
||||
- </asp:TemplateField>
|
||||
-
|
||||
- <asp:TemplateField HeaderText="Etapa">
|
||||
- <ItemTemplate>
|
||||
+
|
||||
<asp:HyperLink runat="server"
|
||||
CssClass="sig-cliente-etapa-enlace"
|
||||
Visible='<%# !Convert.ToBoolean(Eval("EsFraccionamiento")) %>'
|
||||
@@ -114,6 +110,13 @@
|
||||
<ItemTemplate>
|
||||
<asp:Literal runat="server" Mode="Encode"
|
||||
Text='<%# FormatearHectareas(Container.DataItem) %>' />
|
||||
+ </ItemTemplate>
|
||||
+ </asp:TemplateField>
|
||||
+
|
||||
+ <asp:TemplateField HeaderText="Avance">
|
||||
+ <ItemTemplate>
|
||||
+ <asp:Literal runat="server" Mode="Encode"
|
||||
+ Text='<%# FormatearAvance(Container.DataItem) %>' />
|
||||
</ItemTemplate>
|
||||
</asp:TemplateField>
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
--- ANTES/Pages/Clientes/Desarrollos.aspx.cs
|
||||
+++ DESPUES/Pages/Clientes/Desarrollos.aspx.cs
|
||||
@@ -329,6 +329,15 @@
|
||||
fila.NumeroEtapas);
|
||||
}
|
||||
|
||||
+ protected string FormatearAvance(object objeto)
|
||||
+ {
|
||||
+ var fila = objeto as ModeloFilaDesarrollos;
|
||||
+
|
||||
+ return fila == null
|
||||
+ ? string.Empty
|
||||
+ : fila.Avance.ToString("N2", CultureInfo.CurrentCulture) + " %";
|
||||
+ }
|
||||
+
|
||||
protected string FormatearHectareas(object objeto)
|
||||
{
|
||||
var fila = objeto as ModeloFilaDesarrollos;
|
||||
20
SIG.Web/Patches/Pages__Clientes__EtapaDetalle_aspx.patch.txt
Normal file
20
SIG.Web/Patches/Pages__Clientes__EtapaDetalle_aspx.patch.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
--- ANTES/Pages/Clientes/EtapaDetalle.aspx
|
||||
+++ DESPUES/Pages/Clientes/EtapaDetalle.aspx
|
||||
@@ -2,7 +2,7 @@
|
||||
AutoEventWireup="true" CodeFile="EtapaDetalle.aspx.cs"
|
||||
Inherits="SIG.Web.Pages.Clientes.EtapaDetalle" %>
|
||||
<%@ Register TagPrefix="cliente" TagName="Tramites" Src="~/UserControl/Clientes/TramitesCliente.ascx" %>
|
||||
-<%@ Register TagPrefix="cliente" TagName="Documentos" Src="~/UserControl/Clientes/DocumentosCliente.ascx" %>
|
||||
+<%@ Register TagPrefix="etapa" TagName="DocumentosEtapa" Src="~/UserControl/DocumentosEtapa.ascx" %>
|
||||
<%@ Register TagPrefix="cliente" TagName="Pagos" Src="~/UserControl/Clientes/PagosCliente.ascx" %>
|
||||
|
||||
<asp:Content ID="ContenidoEncabezado" ContentPlaceHolderID="H" runat="server">
|
||||
@@ -75,7 +75,7 @@
|
||||
|
||||
<ajax:TabPanel ID="PestanaDocumentos" runat="server" HeaderText="Documentos">
|
||||
<ContentTemplate>
|
||||
- <cliente:Documentos ID="UcDocumentos" runat="server" />
|
||||
+ <etapa:DocumentosEtapa ID="UcDocumentos" runat="server" OnCambiado="Documentos_Cambiados" />
|
||||
</ContentTemplate>
|
||||
</ajax:TabPanel>
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
--- ANTES/Pages/Clientes/EtapaDetalle.aspx.cs
|
||||
+++ DESPUES/Pages/Clientes/EtapaDetalle.aspx.cs
|
||||
@@ -16,6 +16,12 @@
|
||||
{
|
||||
get { return (int?)ViewState["CveFraccionamientoEtapaActual"] ?? 0; }
|
||||
set { ViewState["CveFraccionamientoEtapaActual"] = value; }
|
||||
+ }
|
||||
+
|
||||
+ private int CveFraccionamientoActual
|
||||
+ {
|
||||
+ get { return (int?)ViewState["CveFraccionamientoActual"] ?? 0; }
|
||||
+ set { ViewState["CveFraccionamientoActual"] = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -45,6 +51,19 @@
|
||||
|
||||
CveFraccionamientoEtapaActual = cveFraccionamientoEtapa;
|
||||
Cargar();
|
||||
+ }
|
||||
+
|
||||
+ protected void Documentos_Cambiados(object origen, EventArgs argumentos)
|
||||
+ {
|
||||
+ if (CveFraccionamientoActual <= 0 ||
|
||||
+ CveFraccionamientoEtapaActual <= 0)
|
||||
+ {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ UcTramites.Cargar(
|
||||
+ CveFraccionamientoActual,
|
||||
+ CveFraccionamientoEtapaActual);
|
||||
}
|
||||
|
||||
private void Cargar()
|
||||
@@ -85,6 +104,7 @@
|
||||
|
||||
ModeloEtapaFraccionamiento datosEtapa = etapa.Data;
|
||||
ModeloFraccionamiento datosFraccionamiento = fraccionamiento.Data;
|
||||
+ CveFraccionamientoActual = datosFraccionamiento.CveFraccionamiento;
|
||||
|
||||
LitEtapa.Text = datosEtapa.Etapa;
|
||||
LitHectareas.Text = datosEtapa.Hectareas.HasValue
|
||||
@@ -112,8 +132,7 @@
|
||||
datosEtapa.CveFraccionamientoEtapa);
|
||||
UcDocumentos.Cargar(
|
||||
datosFraccionamiento.CveFraccionamiento,
|
||||
- datosEtapa.CveFraccionamientoEtapa,
|
||||
- false);
|
||||
+ datosEtapa.CveFraccionamientoEtapa);
|
||||
UcPagos.Cargar(
|
||||
datosFraccionamiento.CveFraccionamiento,
|
||||
datosEtapa.CveFraccionamientoEtapa,
|
||||
@@ -0,0 +1,218 @@
|
||||
--- ANTES/Pages/Desarrolladores/DesarrolladorDetalle.aspx
|
||||
+++ DESPUES/Pages/Desarrolladores/DesarrolladorDetalle.aspx
|
||||
@@ -20,27 +20,33 @@
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
- .desarrollador-listado > tbody > tr.desarrollador-grupo > td {
|
||||
- background: #edf4f8;
|
||||
- padding: 10px 12px;
|
||||
- }
|
||||
-
|
||||
- .desarrollador-cabecera {
|
||||
- display: flex;
|
||||
+ .desarrollador-fila-fraccionamiento > td {
|
||||
+ background: #eef6fb;
|
||||
+ vertical-align: middle !important;
|
||||
+ }
|
||||
+
|
||||
+ .desarrollador-fila-etapa > td:first-child {
|
||||
+ padding-left: 30px;
|
||||
+ }
|
||||
+
|
||||
+ .desarrollador-fraccionamiento-resumen {
|
||||
+ color: #7f8c8d;
|
||||
+ font-size: 12px;
|
||||
+ margin-left: 8px;
|
||||
+ }
|
||||
+
|
||||
+ .desarrollador-etapa-enlace {
|
||||
+ font-weight: 600;
|
||||
+ }
|
||||
+
|
||||
+ .desarrollador-accion-icono {
|
||||
align-items: center;
|
||||
- gap: 12px;
|
||||
- }
|
||||
-
|
||||
- .desarrollador-descripcion {
|
||||
- flex: 1;
|
||||
- display: flex;
|
||||
- flex-wrap: wrap;
|
||||
- align-items: center;
|
||||
- gap: 8px 20px;
|
||||
- }
|
||||
-
|
||||
- .desarrollador-alternar {
|
||||
- background: transparent;
|
||||
+ display: inline-flex;
|
||||
+ height: 28px;
|
||||
+ justify-content: center;
|
||||
+ margin: 0 2px;
|
||||
+ padding: 0;
|
||||
+ width: 28px;
|
||||
}
|
||||
|
||||
.desarrollador-credenciales {
|
||||
@@ -162,55 +168,88 @@
|
||||
<ContentTemplate>
|
||||
<div class="table-responsive">
|
||||
<asp:GridView ID="GvFraccionamientos" runat="server" AutoGenerateColumns="false"
|
||||
- GridLines="None" CssClass="table table-hover Widthall desarrollador-listado"
|
||||
- DataKeyNames="CveFraccionamiento,CveFraccionamientoEtapa"
|
||||
+ GridLines="None" CssClass="table table-hover Widthall sig-grid-agrupado"
|
||||
+ DataKeyNames="CveFraccionamiento,CveFraccionamientoEtapa,EsFraccionamiento"
|
||||
OnRowCommand="Fraccionamientos_Comando"
|
||||
OnRowDataBound="Fraccionamientos_FilaEnlazada"
|
||||
EmptyDataText="Este desarrollador no tiene fraccionamientos activos.">
|
||||
<Columns>
|
||||
- <asp:TemplateField HeaderText="Etapa">
|
||||
- <ItemTemplate>
|
||||
- <asp:Panel runat="server" CssClass="desarrollador-cabecera"
|
||||
+ <asp:TemplateField HeaderText="Fraccionamiento / Etapa">
|
||||
+ <ItemTemplate>
|
||||
+ <asp:Panel runat="server"
|
||||
Visible='<%# Convert.ToBoolean(Eval("EsFraccionamiento")) %>'>
|
||||
- <div class="desarrollador-descripcion">
|
||||
- <asp:HyperLink runat="server"
|
||||
- Text='<%# Server.HtmlEncode(Convert.ToString(Eval("Fraccionamiento"))) %>'
|
||||
- NavigateUrl='<%# ObtenerUrlFraccionamiento(Eval("CveFraccionamiento")) %>' />
|
||||
- <span>
|
||||
- <asp:Literal runat="server" Mode="Encode"
|
||||
- Text='<%# DescribirFraccionamiento(Container.DataItem) %>' />
|
||||
- </span>
|
||||
- </div>
|
||||
- <asp:LinkButton runat="server" CommandName="AgregarEtapa"
|
||||
- CausesValidation="false" CssClass="btn btn-primary btn-circle btn-sm"
|
||||
- ToolTip="Agregar etapa" aria-label="Agregar etapa">
|
||||
- <i class="fa fa-plus" aria-hidden="true"></i>
|
||||
- </asp:LinkButton>
|
||||
- <button type="button" class="btn default desarrollador-alternar"
|
||||
- title="Mostrar u ocultar etapas" aria-label="Mostrar u ocultar etapas"
|
||||
+ <button type="button"
|
||||
+ class="btn btn-circle btn-xs default sig-grid-alternar-grupo-accion desarrollador-accion-icono"
|
||||
+ title="Mostrar u ocultar etapas"
|
||||
+ aria-label="Mostrar u ocultar etapas"
|
||||
aria-expanded="true">
|
||||
- <i class="fa fa-chevron-up" aria-hidden="true"></i>
|
||||
+ <i class="fa fa-chevron-up sig-grid-icono-agrupacion" aria-hidden="true"></i>
|
||||
</button>
|
||||
+ <asp:HyperLink runat="server"
|
||||
+ Text='<%# Server.HtmlEncode(Convert.ToString(Eval("Fraccionamiento"))) %>'
|
||||
+ NavigateUrl='<%# ObtenerUrlFraccionamiento(Eval("CveFraccionamiento")) %>' />
|
||||
+ <span class="desarrollador-fraccionamiento-resumen">
|
||||
+ <%#: DescribirFraccionamiento(Container.DataItem) %>
|
||||
+ </span>
|
||||
</asp:Panel>
|
||||
- <asp:Literal runat="server" Mode="Encode" Text='<%# Eval("Etapa") %>'
|
||||
- Visible='<%# !Convert.ToBoolean(Eval("EsFraccionamiento")) %>' />
|
||||
- </ItemTemplate>
|
||||
- </asp:TemplateField>
|
||||
- <asp:BoundField DataField="Hectareas" HeaderText="Hectáreas de la etapa" DataFormatString="{0:N2}" />
|
||||
- <asp:CheckBoxField DataField="Fideicomiso" HeaderText="Fideicomiso" />
|
||||
- <asp:CheckBoxField DataField="EsActivo" HeaderText="Activa" />
|
||||
+
|
||||
+ <asp:HyperLink runat="server"
|
||||
+ CssClass="desarrollador-etapa-enlace"
|
||||
+ Visible='<%# !Convert.ToBoolean(Eval("EsFraccionamiento")) %>'
|
||||
+ Text='<%# Server.HtmlEncode(Convert.ToString(Eval("Etapa"))) %>'
|
||||
+ NavigateUrl='<%# ObtenerUrlEtapa(Eval("CveFraccionamientoEtapa")) %>' />
|
||||
+ </ItemTemplate>
|
||||
+ </asp:TemplateField>
|
||||
+
|
||||
+ <asp:TemplateField HeaderText="Hectáreas">
|
||||
+ <ItemTemplate>
|
||||
+ <asp:Literal runat="server" Mode="Encode"
|
||||
+ Text='<%# FormatearHectareas(Container.DataItem) %>' />
|
||||
+ </ItemTemplate>
|
||||
+ </asp:TemplateField>
|
||||
+
|
||||
+ <asp:TemplateField HeaderText="Avance">
|
||||
+ <ItemTemplate>
|
||||
+ <asp:Literal runat="server" Mode="Encode"
|
||||
+ Text='<%# FormatearAvance(Container.DataItem) %>' />
|
||||
+ </ItemTemplate>
|
||||
+ </asp:TemplateField>
|
||||
+
|
||||
+ <asp:TemplateField HeaderText="Fideicomiso">
|
||||
+ <ItemTemplate>
|
||||
+ <asp:CheckBox runat="server" Enabled="false"
|
||||
+ Visible='<%# !Convert.ToBoolean(Eval("EsFraccionamiento")) %>'
|
||||
+ Checked='<%# Convert.ToBoolean(Eval("Fideicomiso")) %>' />
|
||||
+ </ItemTemplate>
|
||||
+ </asp:TemplateField>
|
||||
+
|
||||
+ <asp:TemplateField HeaderText="Activa">
|
||||
+ <ItemTemplate>
|
||||
+ <asp:CheckBox runat="server" Enabled="false"
|
||||
+ Checked='<%# Convert.ToBoolean(Eval("EsActivo")) %>' />
|
||||
+ </ItemTemplate>
|
||||
+ </asp:TemplateField>
|
||||
+
|
||||
<asp:TemplateField HeaderText="Acciones"
|
||||
HeaderStyle-CssClass="sig-columna-acciones"
|
||||
ItemStyle-CssClass="sig-columna-acciones">
|
||||
<ItemTemplate>
|
||||
+ <asp:LinkButton runat="server" CommandName="AgregarEtapa"
|
||||
+ Visible='<%# Convert.ToBoolean(Eval("EsFraccionamiento")) %>'
|
||||
+ CausesValidation="false"
|
||||
+ CssClass="btn btn-circle btn-xs blue desarrollador-accion-icono"
|
||||
+ ToolTip="Agregar etapa" aria-label="Agregar etapa">
|
||||
+ <i class="fa fa-plus" aria-hidden="true"></i>
|
||||
+ </asp:LinkButton>
|
||||
+
|
||||
<asp:HyperLink runat="server"
|
||||
- CssClass="btn btn-circle btn-sm btn-primary sig-accion-icono"
|
||||
+ CssClass="btn btn-circle btn-xs blue desarrollador-accion-icono"
|
||||
ToolTip="Ver etapa"
|
||||
aria-label="Ver etapa"
|
||||
NavigateUrl='<%# ObtenerUrlEtapa(Eval("CveFraccionamientoEtapa")) %>'
|
||||
Visible='<%# !Convert.ToBoolean(Eval("EsFraccionamiento")) %>'>
|
||||
- <i class="fa fa-eye" aria-hidden="true"></i>
|
||||
- </asp:HyperLink>
|
||||
+ <i class="fa fa-eye" aria-hidden="true"></i>
|
||||
+ </asp:HyperLink>
|
||||
</ItemTemplate>
|
||||
</asp:TemplateField>
|
||||
</Columns>
|
||||
@@ -312,40 +351,4 @@
|
||||
</div>
|
||||
</asp:Content>
|
||||
<asp:Content ID="ContenidoScripts" ContentPlaceHolderID="J" runat="server">
|
||||
- <script>
|
||||
- (function () {
|
||||
- var gruposContraidos = {};
|
||||
- function aplicarGrupo(tabla, boton, contraido) {
|
||||
- var clave = boton.closest("tr").getAttribute("data-fraccionamiento");
|
||||
- boton.setAttribute("aria-expanded", contraido ? "false" : "true");
|
||||
- boton.querySelector("i").className = contraido ? "fa fa-chevron-down" : "fa fa-chevron-up";
|
||||
- tabla.querySelectorAll('tr[data-cabecera="0"]').forEach(function (fila) {
|
||||
- if (fila.getAttribute("data-fraccionamiento") === clave) {
|
||||
- fila.style.display = contraido ? "none" : "";
|
||||
- }
|
||||
- });
|
||||
- }
|
||||
- function iniciarDesarrollos() {
|
||||
- document.querySelectorAll(".desarrollador-listado").forEach(function (tabla) {
|
||||
- if (tabla.getAttribute("data-desarrollos-inicializado") === "1") {
|
||||
- return;
|
||||
- }
|
||||
- tabla.setAttribute("data-desarrollos-inicializado", "1");
|
||||
- tabla.querySelectorAll(".desarrollador-alternar").forEach(function (boton) {
|
||||
- var clave = boton.closest("tr").getAttribute("data-fraccionamiento");
|
||||
- aplicarGrupo(tabla, boton, gruposContraidos[clave] === true);
|
||||
- boton.addEventListener("click", function () {
|
||||
- gruposContraidos[clave] = boton.getAttribute("aria-expanded") === "true";
|
||||
- aplicarGrupo(tabla, boton, gruposContraidos[clave]);
|
||||
- });
|
||||
- });
|
||||
- });
|
||||
- }
|
||||
- if (window.Sys && Sys.Application) {
|
||||
- Sys.Application.add_load(iniciarDesarrollos);
|
||||
- } else {
|
||||
- document.addEventListener("DOMContentLoaded", iniciarDesarrollos);
|
||||
- }
|
||||
- }());
|
||||
- </script>
|
||||
</asp:Content>
|
||||
@@ -0,0 +1,85 @@
|
||||
--- ANTES/Pages/Desarrolladores/DesarrolladorDetalle.aspx.cs
|
||||
+++ DESPUES/Pages/Desarrolladores/DesarrolladorDetalle.aspx.cs
|
||||
@@ -24,27 +24,69 @@
|
||||
return;
|
||||
}
|
||||
|
||||
- var desarrollo = (ModeloFilaDesarrollos)argumentos.Row.DataItem;
|
||||
- argumentos.Row.Attributes["data-fraccionamiento"] =
|
||||
+ var desarrollo = argumentos.Row.DataItem as ModeloFilaDesarrollos;
|
||||
+ if (desarrollo == null)
|
||||
+ {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ string grupo = "desarrollo-" +
|
||||
desarrollo.CveFraccionamiento.ToString(CultureInfo.InvariantCulture);
|
||||
- argumentos.Row.Attributes["data-cabecera"] = desarrollo.EsFraccionamiento ? "1" : "0";
|
||||
+
|
||||
if (desarrollo.EsFraccionamiento)
|
||||
{
|
||||
- argumentos.Row.CssClass = "desarrollador-grupo";
|
||||
- argumentos.Row.Cells[0].ColumnSpan = GvFraccionamientos.Columns.Count;
|
||||
- for (int indice = 1; indice < argumentos.Row.Cells.Count; indice++)
|
||||
- {
|
||||
- argumentos.Row.Cells[indice].Visible = false;
|
||||
- }
|
||||
- }
|
||||
+ argumentos.Row.CssClass =
|
||||
+ (argumentos.Row.CssClass +
|
||||
+ " sig-grid-grupo desarrollador-fila-fraccionamiento").Trim();
|
||||
+ argumentos.Row.Attributes["data-sig-group-row"] = "1";
|
||||
+ argumentos.Row.Attributes["data-sig-group-id"] = grupo;
|
||||
+ argumentos.Row.Attributes["data-sig-level"] = "2";
|
||||
+ argumentos.Row.Attributes["data-sig-expanded-default"] = "true";
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ argumentos.Row.CssClass =
|
||||
+ (argumentos.Row.CssClass +
|
||||
+ " sig-grid-fila-dato desarrollador-fila-etapa").Trim();
|
||||
+ argumentos.Row.Attributes["data-sig-item-row"] = "1";
|
||||
+ argumentos.Row.Attributes["data-sig-parent-group"] = grupo;
|
||||
+ argumentos.Row.Attributes["data-sig-level"] = "1";
|
||||
}
|
||||
|
||||
protected string DescribirFraccionamiento(object objeto)
|
||||
{
|
||||
var fila = (ModeloFilaDesarrollos)objeto;
|
||||
- return string.Format(CultureInfo.CurrentCulture,
|
||||
- "{0} · {1:N2} ha · {2} etapas · {3}",
|
||||
- fila.Ubicacion, fila.HectareasFraccionamiento, fila.NumeroEtapas, fila.Estatus);
|
||||
+ return string.Format(
|
||||
+ CultureInfo.CurrentCulture,
|
||||
+ "{0} · {1} etapa(s)",
|
||||
+ fila.Estatus,
|
||||
+ fila.NumeroEtapas);
|
||||
+ }
|
||||
+
|
||||
+ protected string FormatearHectareas(object objeto)
|
||||
+ {
|
||||
+ var fila = objeto as ModeloFilaDesarrollos;
|
||||
+ if (fila == null)
|
||||
+ {
|
||||
+ return string.Empty;
|
||||
+ }
|
||||
+
|
||||
+ decimal? hectareas = fila.EsFraccionamiento
|
||||
+ ? fila.HectareasFraccionamiento
|
||||
+ : fila.Hectareas;
|
||||
+
|
||||
+ return hectareas.HasValue
|
||||
+ ? hectareas.Value.ToString("N2", CultureInfo.CurrentCulture)
|
||||
+ : string.Empty;
|
||||
+ }
|
||||
+
|
||||
+ protected string FormatearAvance(object objeto)
|
||||
+ {
|
||||
+ var fila = objeto as ModeloFilaDesarrollos;
|
||||
+
|
||||
+ return fila == null
|
||||
+ ? string.Empty
|
||||
+ : fila.Avance.ToString("N2", CultureInfo.CurrentCulture) + " %";
|
||||
}
|
||||
|
||||
protected void Etapa_Cambiada(object origen, EventArgs argumentos)
|
||||
79
SIG.Web/Patches/UserControl__ConveniosListado_ascx.patch.txt
Normal file
79
SIG.Web/Patches/UserControl__ConveniosListado_ascx.patch.txt
Normal file
@@ -0,0 +1,79 @@
|
||||
--- ANTES/UserControl/ConveniosListado.ascx
|
||||
+++ DESPUES/UserControl/ConveniosListado.ascx
|
||||
@@ -133,7 +133,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
- <div class="sig-convenio-seccion-titulo">Viviendas en desarrollo</div>
|
||||
+ <div class="sig-convenio-seccion-titulo">Viviendas en desarrollo <span class="text-muted">· Calculados</span></div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
@@ -146,6 +146,8 @@
|
||||
ID="TxtViviendasAutorizadas"
|
||||
runat="server"
|
||||
CssClass="form-control"
|
||||
+ ReadOnly="true"
|
||||
+ Text="0"
|
||||
MaxLength="9" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -160,6 +162,8 @@
|
||||
ID="TxtViviendasEnConvenio"
|
||||
runat="server"
|
||||
CssClass="form-control"
|
||||
+ ReadOnly="true"
|
||||
+ Text="0"
|
||||
MaxLength="9" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -174,6 +178,8 @@
|
||||
ID="TxtViviendasPendientes"
|
||||
runat="server"
|
||||
CssClass="form-control"
|
||||
+ ReadOnly="true"
|
||||
+ Text="0"
|
||||
MaxLength="9" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -188,6 +194,8 @@
|
||||
ID="TxtViviendasContratadas"
|
||||
runat="server"
|
||||
CssClass="form-control"
|
||||
+ ReadOnly="true"
|
||||
+ Text="0"
|
||||
MaxLength="9" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -240,12 +248,31 @@
|
||||
<div class="form-group">
|
||||
<asp:Label
|
||||
runat="server"
|
||||
+ AssociatedControlID="TxtLotesConvenio"
|
||||
+ Text="Lotes convenio" />
|
||||
+ <asp:TextBox
|
||||
+ ID="TxtLotesConvenio"
|
||||
+ runat="server"
|
||||
+ CssClass="form-control"
|
||||
+ Text="0"
|
||||
+ MaxLength="9" />
|
||||
+ </div>
|
||||
+ </div>
|
||||
+ </div>
|
||||
+
|
||||
+ <div class="row">
|
||||
+ <div class="col-md-12">
|
||||
+ <div class="form-group">
|
||||
+ <asp:Label
|
||||
+ runat="server"
|
||||
AssociatedControlID="TxtObservacionesConvenio"
|
||||
Text="Observaciones" />
|
||||
<asp:TextBox
|
||||
ID="TxtObservacionesConvenio"
|
||||
runat="server"
|
||||
CssClass="form-control"
|
||||
+ TextMode="MultiLine"
|
||||
+ Rows="2"
|
||||
MaxLength="1000" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,80 @@
|
||||
--- ANTES/UserControl/ConveniosListado.ascx.cs
|
||||
+++ DESPUES/UserControl/ConveniosListado.ascx.cs
|
||||
@@ -136,7 +136,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
- DdlClienteCaptura.Enabled = !cveCliente.HasValue;
|
||||
+ DdlClienteCaptura.Enabled = true;
|
||||
|
||||
if (cveCliente.HasValue && cveCliente.Value > 0)
|
||||
{
|
||||
@@ -150,7 +150,7 @@
|
||||
LimpiarEtapasCaptura();
|
||||
}
|
||||
|
||||
- DdlEtapaCaptura.Enabled = !cveEtapa.HasValue;
|
||||
+ DdlEtapaCaptura.Enabled = true;
|
||||
|
||||
if (!CargarConceptosCatalogo())
|
||||
{
|
||||
@@ -430,18 +430,14 @@
|
||||
CveFraccionamientoEtapa = cveEtapa,
|
||||
NumeroConvenio = numeroConvenio,
|
||||
NumeroOficio = TextoNulo(TxtNumeroOficio.Text),
|
||||
- ViviendasAutorizadas = LeerEnteroOpcional(
|
||||
- TxtViviendasAutorizadas.Text,
|
||||
- "Capture una cantidad válida de viviendas autorizadas."),
|
||||
- ViviendasEnConvenio = LeerEntero(
|
||||
- TxtViviendasEnConvenio.Text,
|
||||
- "Capture una cantidad válida de viviendas en convenio."),
|
||||
- ViviendasPendientes = LeerEnteroOpcional(
|
||||
- TxtViviendasPendientes.Text,
|
||||
- "Capture una cantidad válida de viviendas pendientes."),
|
||||
- ViviendasContratadas = LeerEnteroOpcional(
|
||||
- TxtViviendasContratadas.Text,
|
||||
- "Capture una cantidad válida de viviendas contratadas."),
|
||||
+ // Estos cuatro valores quedan reservados para el cálculo posterior.
|
||||
+ ViviendasAutorizadas = 0,
|
||||
+ ViviendasEnConvenio = 0,
|
||||
+ ViviendasPendientes = 0,
|
||||
+ ViviendasContratadas = 0,
|
||||
+ LotesConvenio = LeerEntero(
|
||||
+ TxtLotesConvenio.Text,
|
||||
+ "Capture una cantidad válida de lotes del convenio."),
|
||||
FechaConvenio = LeerFecha(
|
||||
TxtFechaConvenio.Text,
|
||||
"Capture una fecha válida para el convenio."),
|
||||
@@ -579,7 +575,7 @@
|
||||
"<div class=\"col-md-4\"><strong>Oficio:</strong> {3}</div>" +
|
||||
"</div>" +
|
||||
"<div class=\"row\">" +
|
||||
- "<div class=\"col-md-4\"><strong>Viviendas:</strong> {4}</div>" +
|
||||
+ "<div class=\"col-md-4\"><strong>Lotes convenio:</strong> {4}</div>" +
|
||||
"<div class=\"col-md-4\"><strong>Importe:</strong> {5:N2}</div>" +
|
||||
"<div class=\"col-md-4\"><strong>Saldo pendiente:</strong> {6:N2}</div>" +
|
||||
"</div>",
|
||||
@@ -587,7 +583,7 @@
|
||||
HttpUtility.HtmlEncode(encabezado.Fraccionamiento),
|
||||
HttpUtility.HtmlEncode(encabezado.Etapa),
|
||||
HttpUtility.HtmlEncode(encabezado.NumeroOficio),
|
||||
- encabezado.ViviendasEnConvenio,
|
||||
+ encabezado.LotesConvenio,
|
||||
encabezado.ImporteConvenio,
|
||||
encabezado.SaldoPendiente);
|
||||
|
||||
@@ -761,10 +757,11 @@
|
||||
private void ReiniciarCaptura()
|
||||
{
|
||||
ConceptosCaptura = new List<ConvenioConceptoCaptura>();
|
||||
- TxtViviendasAutorizadas.Text = string.Empty;
|
||||
+ TxtViviendasAutorizadas.Text = "0";
|
||||
TxtViviendasEnConvenio.Text = "0";
|
||||
- TxtViviendasPendientes.Text = string.Empty;
|
||||
- TxtViviendasContratadas.Text = string.Empty;
|
||||
+ TxtViviendasPendientes.Text = "0";
|
||||
+ TxtViviendasContratadas.Text = "0";
|
||||
+ TxtLotesConvenio.Text = "0";
|
||||
TxtNumeroConvenio.Text = string.Empty;
|
||||
TxtNumeroOficio.Text = string.Empty;
|
||||
TxtFechaConvenio.Text = DateTime.Today.ToString(
|
||||
23
SIG.Web/Patches/UserControl__DetalleEtapa_ascx.patch.txt
Normal file
23
SIG.Web/Patches/UserControl__DetalleEtapa_ascx.patch.txt
Normal file
@@ -0,0 +1,23 @@
|
||||
--- ANTES/UserControl/DetalleEtapa.ascx
|
||||
+++ DESPUES/UserControl/DetalleEtapa.ascx
|
||||
@@ -58,6 +58,20 @@
|
||||
<asp:BoundField DataField="Folio" HeaderText="Folio" />
|
||||
<asp:BoundField DataField="TipoTramite" HeaderText="Trámite" />
|
||||
<asp:BoundField DataField="EstatusSolicitud" HeaderText="Estatus" />
|
||||
+ <asp:TemplateField HeaderText="Documentos">
|
||||
+ <ItemTemplate>
|
||||
+ <span class='<%# Convert.ToInt32(Eval("DocumentosPendientes")) > 0 ? "text-danger" : "text-success" %>'>
|
||||
+ <%#: Eval("TextoDocumentos") %>
|
||||
+ </span>
|
||||
+ </ItemTemplate>
|
||||
+ </asp:TemplateField>
|
||||
+ <asp:TemplateField HeaderText="Pagos">
|
||||
+ <ItemTemplate>
|
||||
+ <span class='<%# Convert.ToInt32(Eval("PagosPendientes")) > 0 ? "text-danger" : "text-success" %>'>
|
||||
+ <%#: Eval("TextoPagos") %>
|
||||
+ </span>
|
||||
+ </ItemTemplate>
|
||||
+ </asp:TemplateField>
|
||||
<asp:BoundField DataField="FechaInicio" HeaderText="Fecha de inicio" />
|
||||
<asp:TemplateField HeaderText="Acciones"
|
||||
HeaderStyle-CssClass="sig-columna-acciones"
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user