This commit is contained in:
Jorge Luis caudillo esparza
2026-09-28 08:26:04 -07:00
parent 329b8b70d4
commit 1daf15d92f
46 changed files with 7232 additions and 1212 deletions

View File

@@ -1,8 +1,11 @@
using System; using System;
using System.Configuration; using System.Configuration;
using SIG.Web.AppCode.Contracts.Clientes; using SIG.Web.AppCode.Contracts.Clientes;
using SIG.Web.AppCode.Contracts.Convenios;
using SIG.Web.AppCode.Repositories.Clientes; using SIG.Web.AppCode.Repositories.Clientes;
using SIG.Web.AppCode.Repositories.Convenios;
using SIG.Web.AppCode.Services.Clientes; using SIG.Web.AppCode.Services.Clientes;
using SIG.Web.AppCode.Services.Convenios;
using SIG.Web.AppCode.Contracts.Bitacora; using SIG.Web.AppCode.Contracts.Bitacora;
using SIG.Web.AppCode.Contracts.Database; using SIG.Web.AppCode.Contracts.Database;
using SIG.Web.AppCode.Contracts.Documentos; using SIG.Web.AppCode.Contracts.Documentos;
@@ -66,6 +69,7 @@ namespace SIG.Web.AppCode.Configuration
public static ITramiteSolicitudService TramiteSolicitudService { get; private set; } public static ITramiteSolicitudService TramiteSolicitudService { get; private set; }
public static IServicioVentaTramite ServicioVentaTramite { get; private set; } public static IServicioVentaTramite ServicioVentaTramite { get; private set; }
public static IServicioPagosConvenios ServicioPagosConvenios { get; private set; } public static IServicioPagosConvenios ServicioPagosConvenios { get; private set; }
public static IServicioConvenios ServicioConvenios { get; private set; }
public static IServicioTimbradoCfdi ServicioTimbradoCfdi { get; private set; } public static IServicioTimbradoCfdi ServicioTimbradoCfdi { get; private set; }
public static IPublicRegistrationService PublicRegistrationService { get; private set; } public static IPublicRegistrationService PublicRegistrationService { get; private set; }
public static ILoginAttemptRepository LoginAttemptRepository { get; private set; } public static ILoginAttemptRepository LoginAttemptRepository { get; private set; }
@@ -207,6 +211,7 @@ namespace SIG.Web.AppCode.Configuration
PermissionService = new PermissionService( PermissionService = new PermissionService(
permissionRepository); permissionRepository);
ServicioConvenios = new ServicioConvenios(new RepositorioConvenios(DbExecutor), UserContext);
ServicioPagosConvenios = new ServicioPagosConvenios( ServicioPagosConvenios = new ServicioPagosConvenios(
new RepositorioPagosConvenios(DbExecutor), new RepositorioPagosConvenios(DbExecutor),
tramiteSolicitudRepository, tramiteSolicitudRepository,

View File

@@ -65,7 +65,8 @@ namespace SIG.Web.AppCode.Configuration
"~/Scripts/sig-alerts.js", "~/Scripts/sig-alerts.js",
"~/Scripts/filtrosig.js", "~/Scripts/filtrosig.js",
"~/Scripts/scrollsig.js", "~/Scripts/scrollsig.js",
"~/Scripts/sig-grid-agrupado.js" "~/Scripts/sig-grid-agrupado.js",
"~/Scripts/Convenios.js"
)); ));
bundles.Add(new ScriptBundle("~/bundles/WebFormsJs").Include( bundles.Add(new ScriptBundle("~/bundles/WebFormsJs").Include(
"~/Scripts/WebForms/WebForms.js", "~/Scripts/WebForms/WebForms.js",
@@ -130,6 +131,7 @@ namespace SIG.Web.AppCode.Configuration
"~/Styles/filtrosig.css", "~/Styles/filtrosig.css",
"~/Styles/scrollsig.css", "~/Styles/scrollsig.css",
"~/Styles/sig-grid-agrupado.css", "~/Styles/sig-grid-agrupado.css",
"~/Styles/Convenios.css",
"~/Metronic/assets/global/plugins/bootstrap-switch/css/bootstrap-switch.min.css", "~/Metronic/assets/global/plugins/bootstrap-switch/css/bootstrap-switch.min.css",
"~/Metronic/assets/global/plugins/bootstrap-toastr/toastr.min.css", "~/Metronic/assets/global/plugins/bootstrap-toastr/toastr.min.css",
"~/Metronic/assets/layouts/layout3/css/jquery.datetimepicker.css", "~/Metronic/assets/layouts/layout3/css/jquery.datetimepicker.css",

View File

@@ -0,0 +1,34 @@
using System.Collections.Generic;
using SIG.Web.AppCode.Models.Clientes;
using SIG.Web.AppCode.Models.Common;
namespace SIG.Web.AppCode.Contracts.Clientes
{
public interface IRepositorioPortalCliente
{
DbResult<List<PagoConvenioClienteFila>> ListarPagos(
int cveCliente,
int? cveFraccionamiento,
int? cveFraccionamientoEtapa,
string agrupacion,
int cveUsuarioEjecuta,
string nombreDominio);
DbResult<List<ReciboConvenioDisponibleCliente>> ListarRecibosDisponibles(
int cveCliente,
int? cveFraccionamiento,
int cveUsuarioEjecuta,
string nombreDominio);
DbResult<int> AgregarPago(
SolicitudPagoConvenioCliente pago,
int cveUsuarioEjecuta,
string nombreDominio);
DbResult<ArchivoPagoConvenioCliente> ObtenerArchivoPago(
int cveConvenioPago,
int cveCliente,
int cveUsuarioEjecuta,
string nombreDominio);
}
}

View File

@@ -0,0 +1,63 @@
using System.Collections.Generic;
using System.IO;
using SIG.Web.AppCode.Models.Clientes;
using SIG.Web.AppCode.Models.Common;
using SIG.Web.AppCode.Models.Fraccionamientos;
using SIG.Web.AppCode.Models.Tramites;
namespace SIG.Web.AppCode.Contracts.Clientes
{
public interface IServicioPortalCliente
{
DbResult<List<ModeloFilaDesarrollos>> ListarDesarrollos(
int cveUsuarioEjecuta,
string nombreDominio);
DbResult<ModeloFraccionamiento> ObtenerFraccionamiento(
int cveFraccionamiento,
int cveUsuarioEjecuta,
string nombreDominio);
DbResult<List<ModeloEtapaFraccionamiento>> ListarEtapas(
int cveFraccionamiento,
int cveUsuarioEjecuta,
string nombreDominio);
DbResult<List<TramiteClienteListado>> ListarTramites(
int cveFraccionamiento,
int cveUsuarioEjecuta,
string nombreDominio);
DbResult<TramiteSolicitudStatusChangeModel> EnviarRevision(
int cveSolicitud,
int cveFraccionamiento,
int cveUsuarioEjecuta,
string nombreDominio);
DbResult<List<DocumentoClientePortal>> ListarDocumentos(
FiltroDocumentosCliente filtro,
int cveUsuarioEjecuta,
string nombreDominio);
DbResult<List<PagoConvenioClienteFila>> ListarPagos(
FiltroPagosCliente filtro,
int cveUsuarioEjecuta,
string nombreDominio);
DbResult<List<ReciboConvenioDisponibleCliente>> ListarRecibosDisponibles(
int? cveFraccionamiento,
int cveUsuarioEjecuta,
string nombreDominio);
DbResult<int> RegistrarPago(
SolicitudPagoConvenioCliente pago,
Stream contenido,
int cveUsuarioEjecuta,
string nombreDominio);
DbResult<ArchivoPagoConvenioCliente> ObtenerArchivoPago(
int cveConvenioPago,
int cveUsuarioEjecuta,
string nombreDominio);
}
}

View File

@@ -0,0 +1,15 @@
using System.Collections.Generic;
using SIG.Web.AppCode.Models.Common;
using SIG.Web.AppCode.Models.Convenios;
namespace SIG.Web.AppCode.Contracts.Convenios
{
public interface IRepositorioConvenios
{
DbResult<List<ConvenioListado>> Listar(FiltroConvenios filtro, int usuario, string dominio);
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<bool> Eliminar(int cveConvenio, int usuario, string dominio);
}
}

View File

@@ -0,0 +1,15 @@
using System.Collections.Generic;
using SIG.Web.AppCode.Models.Common;
using SIG.Web.AppCode.Models.Convenios;
namespace SIG.Web.AppCode.Contracts.Convenios
{
public interface IServicioConvenios
{
DbResult<List<ConvenioListado>> Listar(FiltroConvenios filtro, int usuario, string dominio);
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<bool> Eliminar(int cveConvenio, int usuario, string dominio);
}
}

View File

@@ -0,0 +1,20 @@
using System.IO;
using SIG.Web.AppCode.Models.Clientes;
namespace SIG.Web.AppCode.Contracts.Documentos
{
public interface IAlmacenComprobantesConvenio
{
void Guardar(
SolicitudPagoConvenioCliente pago,
Stream contenido);
string Resolver(
int cveCliente,
string nombreFisico);
void Eliminar(
int cveCliente,
string nombreFisico);
}
}

View File

@@ -0,0 +1,73 @@
using System;
using System.Globalization;
using System.IO;
using System.Web;
using System.Web.SessionState;
using SIG.Web.AppCode.Configuration;
using SIG.Web.AppCode.Models.Clientes;
using SIG.Web.AppCode.Session;
namespace SIG.Web.Pages.Clientes
{
public sealed class ComprobanteConvenioPagoHandler
: IHttpHandler, IReadOnlySessionState
{
public bool IsReusable
{
get { return false; }
}
public void ProcessRequest(HttpContext contexto)
{
UserSessionModel usuario = AppServices.UserContext.GetCurrentUser();
if (usuario == null ||
!AppServices.UserContext.IsAuthenticated() ||
!usuario.EsDesarrollador)
{
contexto.Response.StatusCode = 401;
return;
}
int cvePago;
if (!int.TryParse(
contexto.Request.QueryString["id"],
NumberStyles.Integer,
CultureInfo.InvariantCulture,
out cvePago) ||
cvePago <= 0)
{
contexto.Response.StatusCode = 404;
return;
}
var resultado = AppServices.ServicioPortalCliente.ObtenerArchivoPago(
cvePago,
usuario.CveUsuario,
usuario.NombreDominio);
if (!resultado.Success ||
resultado.Data == null ||
string.IsNullOrWhiteSpace(resultado.Data.RutaFisica) ||
!File.Exists(resultado.Data.RutaFisica))
{
contexto.Response.StatusCode = 404;
return;
}
ArchivoPagoConvenioCliente archivo = resultado.Data;
contexto.Response.Clear();
contexto.Response.ContentType = archivo.TipoContenido;
contexto.Response.AddHeader("X-Content-Type-Options", "nosniff");
contexto.Response.AddHeader(
"Content-Disposition",
"attachment; filename*=UTF-8''" +
Uri.EscapeDataString(archivo.NombreArchivo));
contexto.Response.Cache.SetCacheability(HttpCacheability.NoCache);
contexto.Response.Cache.SetNoStore();
contexto.Response.TransmitFile(archivo.RutaFisica);
contexto.ApplicationInstance.CompleteRequest();
}
}
}

View File

@@ -0,0 +1,204 @@
using System;
using System.Collections.Generic;
namespace SIG.Web.AppCode.Models.Clientes
{
[Serializable]
public sealed class FiltroDocumentosCliente
{
public int? CveFraccionamiento { get; set; }
public int? CveFraccionamientoEtapa { get; set; }
public string Agrupacion { get; set; }
}
[Serializable]
public sealed class DocumentoClientePortal
{
public int CveDocumentoSolicitud { get; set; }
public int CveSolicitud { get; set; }
public int CveCliente { get; set; }
public int CveFraccionamiento { get; set; }
public string Fraccionamiento { 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 Nota { get; set; }
public bool? EsAprobado { get; set; }
public DateTime? FechaDocumento { get; set; }
public DateTime? FechaVencimiento { get; set; }
public bool TieneArchivo { get; set; }
public bool EsCliente { get; set; }
public bool PuedeActualizarArchivo { get; set; }
public bool EsRequerido { get; set; }
public bool TieneVigencia { get; set; }
public bool FechaExpirada { get; set; }
public string EstadoDocumento { get; set; }
public string Agrupacion { get; set; }
}
[Serializable]
public sealed class FiltroPagosCliente
{
public int? CveFraccionamiento { get; set; }
public int? CveFraccionamientoEtapa { get; set; }
public string Agrupacion { get; set; }
}
[Serializable]
public sealed class PagoConvenioClienteFila
{
public string TipoRegistro { get; set; }
public string Agrupacion { get; set; }
public int CveCliente { get; set; }
public int CveFraccionamiento { get; set; }
public string Fraccionamiento { get; set; }
public int CveFraccionamientoEtapa { get; set; }
public string Etapa { get; set; }
public int? CveSolicitud { get; set; }
public int CveConvenio { get; set; }
public string NumeroConvenio { get; set; }
public int? CveConvenioDetalle { get; set; }
public string Concepto { get; set; }
public int? CveConvenioRecibo { get; set; }
public string NumeroRecibo { get; set; }
public int? CveConvenioPago { get; set; }
public decimal Importe { get; set; }
public decimal ImporteAplicado { get; set; }
public decimal SaldoPendiente { get; set; }
public DateTime Fecha { get; set; }
public string Estatus { get; set; }
public string Referencia { get; set; }
public string NumeroOperacion { get; set; }
public string NombreArchivo { get; set; }
public string RecibosAplicados { get; set; }
public string Observaciones { get; set; }
public bool EsReciboPendiente
{
get
{
return string.Equals(
TipoRegistro,
"RECIBO",
StringComparison.OrdinalIgnoreCase) &&
string.Equals(
Agrupacion,
"Pendientes",
StringComparison.OrdinalIgnoreCase);
}
}
}
[Serializable]
public sealed class ReciboConvenioDisponibleCliente
{
public int CveConvenioRecibo { get; set; }
public int CveCliente { get; set; }
public int CveFraccionamiento { get; set; }
public string Fraccionamiento { get; set; }
public int CveFraccionamientoEtapa { get; set; }
public string Etapa { get; set; }
public int CveConvenio { get; set; }
public string NumeroConvenio { get; set; }
public string Concepto { get; set; }
public string NumeroRecibo { get; set; }
public decimal Importe { get; set; }
public decimal ImporteAplicado { get; set; }
public decimal SaldoPendiente { get; set; }
public DateTime FechaVencimiento { get; set; }
public string Descripcion
{
get
{
return string.Format(
System.Globalization.CultureInfo.CurrentCulture,
"{0} · {1} · {2} · saldo {3:N2}",
Fraccionamiento,
Etapa,
NumeroRecibo,
SaldoPendiente);
}
}
}
[Serializable]
public sealed class AplicacionPagoConvenioCliente
{
public int CveConvenioRecibo { get; set; }
public string NumeroRecibo { get; set; }
public string Fraccionamiento { get; set; }
public string Etapa { get; set; }
public string Concepto { get; set; }
public decimal SaldoPendiente { get; set; }
public decimal ImporteAplicado { get; set; }
}
[Serializable]
public sealed class SolicitudPagoConvenioCliente
{
public int CveCliente { get; set; }
public decimal Importe { get; set; }
public DateTime FechaPago { get; set; }
public string Referencia { get; set; }
public string Banco { get; set; }
public string NumeroOperacion { get; set; }
public string Observaciones { get; set; }
public string NombreArchivo { get; set; }
public string NombreFisico { get; set; }
public string TipoContenido { get; set; }
public long TamanoBytes { get; set; }
public List<AplicacionPagoConvenioCliente> Aplicaciones { get; set; }
}
public sealed class ArchivoPagoConvenioCliente
{
public int CveConvenioPago { get; set; }
public int CveCliente { get; set; }
public string NombreArchivo { get; set; }
public string NombreFisico { get; set; }
public string TipoContenido { get; set; }
public long TamanoBytes { get; set; }
public string RutaFisica { get; set; }
}
public sealed class TramiteClienteListado
{
public int CveSolicitud { get; set; }
public string Folio { 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 CveEstatusSolicitud { get; set; }
public string EstatusSolicitud { get; set; }
public int DocumentosPendientes { get; set; }
public int PagosPendientes { get; set; }
public bool PuedeEnviarRevision { 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)";
}
}
}
}

View File

@@ -0,0 +1,131 @@
using System;
using System.Collections.Generic;
namespace SIG.Web.AppCode.Models.Convenios
{
[Serializable]
public sealed class FiltroConvenios
{
public int? CveCliente { get; set; }
public int? CveFraccionamiento { get; set; }
public int? CveFraccionamientoEtapa { get; set; }
public string Estatus { get; set; }
public bool? ConSaldoPendiente { get; set; }
}
public sealed class ConvenioListado
{
public int CveConvenio { get; set; }
public int CveCliente { get; set; }
public string Cliente { get; set; }
public int CveFraccionamiento { get; set; }
public string Fraccionamiento { get; set; }
public int CveFraccionamientoEtapa { get; set; }
public string Etapa { get; set; }
public string NumeroConvenio { get; set; }
public string NumeroOficio { get; set; }
public string Estatus { get; set; }
public DateTime FechaConvenio { get; set; }
public decimal ImporteConvenio { get; set; }
public decimal ImportePagado { get; set; }
public decimal SaldoPendiente { get; set; }
public bool TienePagos { get; set; }
public bool PuedeEliminar { get { return !TienePagos; } }
}
public sealed class ConvenioDetalleEncabezado
{
public int CveConvenio { get; set; }
public int CveCliente { get; set; }
public int CveFraccionamientoEtapa { get; set; }
public string NumeroConvenio { get; set; }
public string NumeroOficio { get; set; }
public string Cliente { get; set; }
public string Fraccionamiento { get; set; }
public string Etapa { get; set; }
public string Estatus { get; set; }
public DateTime FechaConvenio { get; set; }
public int? ViviendasAutorizadas { get; set; }
public int ViviendasEnConvenio { get; set; }
public int? ViviendasPendientes { get; set; }
public int? ViviendasContratadas { get; set; }
public string Observaciones { get; set; }
public decimal ImporteConvenio { get; set; }
public decimal ImportePagado { get; set; }
public decimal SaldoPendiente { get; set; }
}
public sealed class ConvenioConceptoDetalle
{
public int CveConvenioDetalle { get; set; }
public int CveConvenioConcepto { get; set; }
public string Concepto { get; set; }
public decimal Importe { get; set; }
public string Tipo { get; set; }
public int NumeroPagos { get; set; }
}
public sealed class ConvenioReciboDetalle
{
public int CveConvenioRecibo { get; set; }
public int CveConvenioDetalle { get; set; }
public string NumeroRecibo { get; set; }
public decimal Importe { get; set; }
public decimal ImportePagado { get; set; }
public decimal SaldoPendiente { get; set; }
public DateTime FechaVencimiento { get; set; }
public string Estatus { get; set; }
}
public sealed class ConvenioDetalleCompleto
{
public ConvenioDetalleEncabezado Encabezado { get; set; }
public List<ConvenioConceptoDetalle> Conceptos { get; set; }
public List<ConvenioReciboDetalle> Recibos { get; set; }
}
public sealed class ConvenioConceptoCatalogo
{
public int CveConvenioConcepto { get; set; }
public string Concepto { get; set; }
public string Descripcion { get; set; }
}
[Serializable]
public sealed class SolicitudAltaConvenio
{
public int CveCliente { get; set; }
public int CveFraccionamientoEtapa { get; set; }
public string NumeroConvenio { get; set; }
public string NumeroOficio { get; set; }
public int? ViviendasAutorizadas { get; set; }
public int ViviendasEnConvenio { get; set; }
public int? ViviendasPendientes { get; set; }
public int? ViviendasContratadas { get; set; }
public DateTime FechaConvenio { get; set; }
public string Observaciones { get; set; }
public List<ConvenioConceptoCaptura> Conceptos { get; set; }
}
[Serializable]
public sealed class ConvenioConceptoCaptura
{
public int ClaveTemporal { get; set; }
public int CveConvenioConcepto { get; set; }
public string Concepto { get; set; }
public decimal Importe { get; set; }
public string Tipo { get; set; }
public int NumeroPagos { get; set; }
public List<ConvenioReciboCaptura> Parcialidades { get; set; }
}
[Serializable]
public sealed class ConvenioReciboCaptura
{
public int Orden { get; set; }
public string NumeroRecibo { get; set; }
public decimal Importe { get; set; }
public DateTime FechaVencimiento { get; set; }
public string Estatus { get; set; }
}
}

View File

@@ -0,0 +1,216 @@
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.Linq;
using System.Xml.Linq;
using SIG.Web.AppCode.Contracts.Clientes;
using SIG.Web.AppCode.Contracts.Database;
using SIG.Web.AppCode.Models.Clientes;
using SIG.Web.AppCode.Models.Common;
using SIG.Web.AppCode.Repositories.Database;
namespace SIG.Web.AppCode.Repositories.Clientes
{
public sealed class RepositorioPortalCliente
: RepositoryBase, IRepositorioPortalCliente
{
private const string ProcedimientoPagosListar =
"dbo.PA_Clientes_ConvenioPagoList";
private const string ProcedimientoRecibosListar =
"dbo.PA_Clientes_ConvenioReciboPendienteList";
private const string ProcedimientoPagoAgregar =
"dbo.PA_Clientes_ConvenioPagoAdd";
private const string ProcedimientoPagoArchivoObtener =
"dbo.PA_Clientes_ConvenioPagoArchivoGet";
public RepositorioPortalCliente(IDbExecutor ejecutor)
: base(ejecutor)
{
}
public DbResult<List<PagoConvenioClienteFila>> ListarPagos(
int cveCliente,
int? cveFraccionamiento,
int? cveFraccionamientoEtapa,
string agrupacion,
int cveUsuarioEjecuta,
string nombreDominio)
{
return QueryList<PagoConvenioClienteFila>(
ProcedimientoPagosListar,
cveUsuarioEjecuta,
nombreDominio,
comando =>
{
StoredProcedureCommand.AddInput(
comando,
"@CveCliente",
cveCliente,
DbType.Int32);
StoredProcedureCommand.AddInput(
comando,
"@CveFraccionamiento",
cveFraccionamiento,
DbType.Int32);
StoredProcedureCommand.AddInput(
comando,
"@CveFraccionamientoEtapa",
cveFraccionamientoEtapa,
DbType.Int32);
StoredProcedureCommand.AddInput(
comando,
"@Agrupacion",
agrupacion,
DbType.String);
});
}
public DbResult<List<ReciboConvenioDisponibleCliente>> ListarRecibosDisponibles(
int cveCliente,
int? cveFraccionamiento,
int cveUsuarioEjecuta,
string nombreDominio)
{
return QueryList<ReciboConvenioDisponibleCliente>(
ProcedimientoRecibosListar,
cveUsuarioEjecuta,
nombreDominio,
comando =>
{
StoredProcedureCommand.AddInput(
comando,
"@CveCliente",
cveCliente,
DbType.Int32);
StoredProcedureCommand.AddInput(
comando,
"@CveFraccionamiento",
cveFraccionamiento,
DbType.Int32);
});
}
public DbResult<int> AgregarPago(
SolicitudPagoConvenioCliente pago,
int cveUsuarioEjecuta,
string nombreDominio)
{
return QueryScalarId(
ProcedimientoPagoAgregar,
cveUsuarioEjecuta,
nombreDominio,
comando =>
{
StoredProcedureCommand.AddInput(
comando,
"@CveCliente",
pago.CveCliente,
DbType.Int32);
StoredProcedureCommand.AddInput(
comando,
"@Importe",
pago.Importe,
DbType.Decimal);
StoredProcedureCommand.AddInput(
comando,
"@FechaPago",
pago.FechaPago,
DbType.DateTime);
StoredProcedureCommand.AddInput(
comando,
"@Referencia",
pago.Referencia,
DbType.String);
StoredProcedureCommand.AddInput(
comando,
"@Banco",
pago.Banco,
DbType.String);
StoredProcedureCommand.AddInput(
comando,
"@NumeroOperacion",
pago.NumeroOperacion,
DbType.String);
StoredProcedureCommand.AddInput(
comando,
"@Observaciones",
pago.Observaciones,
DbType.String);
StoredProcedureCommand.AddInput(
comando,
"@NombreArchivo",
pago.NombreArchivo,
DbType.String);
StoredProcedureCommand.AddInput(
comando,
"@NombreFisico",
pago.NombreFisico,
DbType.String);
StoredProcedureCommand.AddInput(
comando,
"@TipoContenido",
pago.TipoContenido,
DbType.String);
StoredProcedureCommand.AddInput(
comando,
"@TamanoBytes",
pago.TamanoBytes,
DbType.Int64);
StoredProcedureCommand.AddInput(
comando,
"@AplicacionesXml",
SerializarAplicaciones(pago.Aplicaciones),
DbType.Xml);
});
}
public DbResult<ArchivoPagoConvenioCliente> ObtenerArchivoPago(
int cveConvenioPago,
int cveCliente,
int cveUsuarioEjecuta,
string nombreDominio)
{
return QueryOne<ArchivoPagoConvenioCliente>(
ProcedimientoPagoArchivoObtener,
cveUsuarioEjecuta,
nombreDominio,
comando =>
{
StoredProcedureCommand.AddInput(
comando,
"@CveConvenioPago",
cveConvenioPago,
DbType.Int32);
StoredProcedureCommand.AddInput(
comando,
"@CveCliente",
cveCliente,
DbType.Int32);
});
}
private static string SerializarAplicaciones(
IEnumerable<AplicacionPagoConvenioCliente> aplicaciones)
{
IEnumerable<AplicacionPagoConvenioCliente> lista =
aplicaciones ?? Enumerable.Empty<AplicacionPagoConvenioCliente>();
var raiz = new XElement(
"Aplicaciones",
lista.Select((aplicacion, indice) =>
new XElement(
"Aplicacion",
new XAttribute("Orden", indice + 1),
new XAttribute(
"CveConvenioRecibo",
aplicacion.CveConvenioRecibo),
new XAttribute(
"ImporteAplicado",
aplicacion.ImporteAplicado.ToString(
"0.######",
CultureInfo.InvariantCulture)))));
return raiz.ToString(SaveOptions.DisableFormatting);
}
}
}

View File

@@ -0,0 +1,264 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.Linq;
using System.Xml.Linq;
using SIG.Web.AppCode.Contracts.Convenios;
using SIG.Web.AppCode.Contracts.Database;
using SIG.Web.AppCode.Models.Common;
using SIG.Web.AppCode.Models.Convenios;
using SIG.Web.AppCode.Repositories.Database;
using SIG.Web.AppCode.Utilities;
namespace SIG.Web.AppCode.Repositories.Convenios
{
public sealed class RepositorioConvenios : RepositoryBase, IRepositorioConvenios
{
private const string ProcedimientoListar = "dbo.PA_Tra_ConvenioList";
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 ProcedimientoEliminar = "dbo.PA_Tra_ConvenioDelete";
public RepositorioConvenios(IDbExecutor ejecutor)
: base(ejecutor)
{
}
public DbResult<List<ConvenioListado>> Listar(
FiltroConvenios filtro,
int usuario,
string dominio)
{
filtro = filtro ?? new FiltroConvenios();
return QueryList<ConvenioListado>(
ProcedimientoListar,
usuario,
dominio,
comando =>
{
StoredProcedureCommand.AddInput(
comando,
"@CveCliente",
filtro.CveCliente,
DbType.Int32);
StoredProcedureCommand.AddInput(
comando,
"@CveFraccionamiento",
filtro.CveFraccionamiento,
DbType.Int32);
StoredProcedureCommand.AddInput(
comando,
"@CveFraccionamientoEtapa",
filtro.CveFraccionamientoEtapa,
DbType.Int32);
StoredProcedureCommand.AddInput(
comando,
"@Estatus",
filtro.Estatus,
DbType.String);
StoredProcedureCommand.AddInput(
comando,
"@ConSaldoPendiente",
filtro.ConSaldoPendiente,
DbType.Boolean);
});
}
public DbResult<ConvenioDetalleCompleto> Obtener(
int cveConvenio,
int usuario,
string dominio)
{
return QueryReader(
ProcedimientoObtener,
usuario,
dominio,
comando => StoredProcedureCommand.AddInput(
comando,
"@CveConvenio",
cveConvenio,
DbType.Int32),
lector =>
{
var resultado = new ConvenioDetalleCompleto
{
Encabezado = lector.ToObject<ConvenioDetalleEncabezado>(),
Conceptos = new List<ConvenioConceptoDetalle>(),
Recibos = new List<ConvenioReciboDetalle>()
};
if (!lector.NextResult())
{
throw new InvalidOperationException(
"Falta el resultado de conceptos del convenio.");
}
resultado.Conceptos = lector.ToList<ConvenioConceptoDetalle>();
if (!lector.NextResult())
{
throw new InvalidOperationException(
"Falta el resultado de recibos del convenio.");
}
resultado.Recibos = lector.ToList<ConvenioReciboDetalle>();
return resultado;
});
}
public DbResult<List<ConvenioConceptoCatalogo>> ListarConceptos(
int usuario,
string dominio)
{
return QueryList<ConvenioConceptoCatalogo>(
ProcedimientoListarConceptos,
usuario,
dominio,
null);
}
public DbResult<int> Agregar(
SolicitudAltaConvenio solicitud,
int usuario,
string dominio)
{
if (solicitud == null)
{
throw new ArgumentNullException("solicitud");
}
string conceptosXml = SerializarConceptos(solicitud.Conceptos);
return QueryScalarId(
ProcedimientoAgregar,
usuario,
dominio,
comando =>
{
StoredProcedureCommand.AddInput(
comando,
"@CveCliente",
solicitud.CveCliente,
DbType.Int32);
StoredProcedureCommand.AddInput(
comando,
"@CveFraccionamientoEtapa",
solicitud.CveFraccionamientoEtapa,
DbType.Int32);
StoredProcedureCommand.AddInput(
comando,
"@NumeroConvenio",
solicitud.NumeroConvenio,
DbType.String);
StoredProcedureCommand.AddInput(
comando,
"@NumeroOficio",
solicitud.NumeroOficio,
DbType.String);
StoredProcedureCommand.AddInput(
comando,
"@ViviendasAutorizadas",
solicitud.ViviendasAutorizadas,
DbType.Int32);
StoredProcedureCommand.AddInput(
comando,
"@ViviendasEnConvenio",
solicitud.ViviendasEnConvenio,
DbType.Int32);
StoredProcedureCommand.AddInput(
comando,
"@ViviendasPendientes",
solicitud.ViviendasPendientes,
DbType.Int32);
StoredProcedureCommand.AddInput(
comando,
"@ViviendasContratadas",
solicitud.ViviendasContratadas,
DbType.Int32);
StoredProcedureCommand.AddInput(
comando,
"@FechaConvenio",
solicitud.FechaConvenio,
DbType.Date);
StoredProcedureCommand.AddInput(
comando,
"@Observaciones",
solicitud.Observaciones,
DbType.String);
StoredProcedureCommand.AddInput(
comando,
"@ConceptosXml",
conceptosXml,
DbType.Xml);
});
}
public DbResult<bool> Eliminar(
int cveConvenio,
int usuario,
string dominio)
{
return Execute(
ProcedimientoEliminar,
usuario,
dominio,
comando => StoredProcedureCommand.AddInput(
comando,
"@CveConvenio",
cveConvenio,
DbType.Int32));
}
private static string SerializarConceptos(
IEnumerable<ConvenioConceptoCaptura> conceptos)
{
IEnumerable<ConvenioConceptoCaptura> lista =
conceptos ?? Enumerable.Empty<ConvenioConceptoCaptura>();
var raiz = new XElement(
"Conceptos",
lista.Select((concepto, indiceConcepto) =>
new XElement(
"Concepto",
new XAttribute("Orden", indiceConcepto + 1),
new XAttribute(
"CveConvenioConcepto",
concepto.CveConvenioConcepto),
new XAttribute(
"Importe",
concepto.Importe.ToString(
"0.######",
CultureInfo.InvariantCulture)),
new XAttribute("Tipo", concepto.Tipo ?? string.Empty),
new XAttribute("NumeroPagos", concepto.NumeroPagos),
new XElement(
"Recibos",
(concepto.Parcialidades ??
new List<ConvenioReciboCaptura>())
.Select((recibo, indiceRecibo) =>
new XElement(
"Recibo",
new XAttribute("Orden", indiceRecibo + 1),
new XAttribute(
"Importe",
recibo.Importe.ToString(
"0.######",
CultureInfo.InvariantCulture)),
new XAttribute(
"FechaVencimiento",
recibo.FechaVencimiento.ToString(
"yyyy-MM-dd",
CultureInfo.InvariantCulture)),
new XAttribute(
"Estatus",
string.IsNullOrWhiteSpace(recibo.Estatus)
? "PENDIENTE"
: recibo.Estatus)))))));
return raiz.ToString(SaveOptions.DisableFormatting);
}
}
}

View File

@@ -0,0 +1,708 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Transactions;
using SIG.Web.AppCode.Contracts.Clientes;
using SIG.Web.AppCode.Contracts.Documentos;
using SIG.Web.AppCode.Contracts.Fraccionamientos;
using SIG.Web.AppCode.Contracts.Security;
using SIG.Web.AppCode.Contracts.Tramites;
using SIG.Web.AppCode.Infrastructure;
using SIG.Web.AppCode.Infrastructure.Transactions;
using SIG.Web.AppCode.Models.Clientes;
using SIG.Web.AppCode.Models.Common;
using SIG.Web.AppCode.Models.Documentos;
using SIG.Web.AppCode.Models.Fraccionamientos;
using SIG.Web.AppCode.Models.Tramites;
using SIG.Web.AppCode.Session;
namespace SIG.Web.AppCode.Services.Clientes
{
public sealed class ServicioPortalCliente : IServicioPortalCliente
{
private readonly IRepositorioPortalCliente _repositorio;
private readonly IServicioFraccionamiento _servicioFraccionamiento;
private readonly ITramiteDocumentoService _servicioDocumentos;
private readonly ITramiteSolicitudService _servicioTramites;
private readonly IAlmacenComprobantesConvenio _almacenComprobantes;
private readonly IUserContextProvider _contextoUsuario;
public ServicioPortalCliente(
IRepositorioPortalCliente repositorio,
IServicioFraccionamiento servicioFraccionamiento,
ITramiteDocumentoService servicioDocumentos,
ITramiteSolicitudService servicioTramites,
IAlmacenComprobantesConvenio almacenComprobantes,
IUserContextProvider contextoUsuario)
{
_repositorio = repositorio;
_servicioFraccionamiento = servicioFraccionamiento;
_servicioDocumentos = servicioDocumentos;
_servicioTramites = servicioTramites;
_almacenComprobantes = almacenComprobantes;
_contextoUsuario = contextoUsuario;
}
public DbResult<List<ModeloFilaDesarrollos>> ListarDesarrollos(
int cveUsuarioEjecuta,
string nombreDominio)
{
UserSessionModel usuario;
DbResult<bool> acceso = ValidarCliente(
cveUsuarioEjecuta,
out usuario);
if (!acceso.Success)
{
return Fallo<List<ModeloFilaDesarrollos>>(acceso.UserMessage);
}
return _servicioFraccionamiento.ListarDesarrollos(
usuario.CveCliente,
cveUsuarioEjecuta,
nombreDominio);
}
public DbResult<ModeloFraccionamiento> ObtenerFraccionamiento(
int cveFraccionamiento,
int cveUsuarioEjecuta,
string nombreDominio)
{
UserSessionModel usuario;
DbResult<bool> acceso = ValidarCliente(
cveUsuarioEjecuta,
out usuario);
if (!acceso.Success)
{
return Fallo<ModeloFraccionamiento>(acceso.UserMessage);
}
DbResult<ModeloFraccionamiento> resultado =
_servicioFraccionamiento.Obtener(
cveFraccionamiento,
cveUsuarioEjecuta,
nombreDominio);
if (!resultado.Success || resultado.Data == null)
{
return resultado;
}
if (resultado.Data.CveCliente != usuario.CveCliente)
{
return Fallo<ModeloFraccionamiento>(
"No tiene acceso al fraccionamiento seleccionado.");
}
return resultado;
}
public DbResult<List<ModeloEtapaFraccionamiento>> ListarEtapas(
int cveFraccionamiento,
int cveUsuarioEjecuta,
string nombreDominio)
{
DbResult<ModeloFraccionamiento> fraccionamiento =
ObtenerFraccionamiento(
cveFraccionamiento,
cveUsuarioEjecuta,
nombreDominio);
if (!fraccionamiento.Success)
{
return Fallo<List<ModeloEtapaFraccionamiento>>(
fraccionamiento.UserMessage);
}
return _servicioFraccionamiento.ListarEtapas(
cveFraccionamiento,
cveUsuarioEjecuta,
nombreDominio);
}
public DbResult<List<TramiteClienteListado>> ListarTramites(
int cveFraccionamiento,
int cveUsuarioEjecuta,
string nombreDominio)
{
UserSessionModel usuario;
DbResult<bool> acceso = ValidarCliente(
cveUsuarioEjecuta,
out usuario);
if (!acceso.Success)
{
return Fallo<List<TramiteClienteListado>>(acceso.UserMessage);
}
DbResult<ModeloFraccionamiento> fraccionamiento =
ObtenerFraccionamiento(
cveFraccionamiento,
cveUsuarioEjecuta,
nombreDominio);
if (!fraccionamiento.Success)
{
return Fallo<List<TramiteClienteListado>>(
fraccionamiento.UserMessage);
}
DbResult<List<TramiteSolicitudModel>> solicitudes =
_servicioTramites.ListForDevelopment(
cveFraccionamiento,
null,
null,
null,
cveUsuarioEjecuta,
nombreDominio);
if (!solicitudes.Success)
{
return DbResult<List<TramiteClienteListado>>.Fail(
solicitudes.UserMessage,
solicitudes.TechnicalMessage,
solicitudes.Exception);
}
DbResult<List<TramiteDocumentoSolicitudModel>> documentos =
_servicioDocumentos.ListarRequisitos(
cveFraccionamiento,
null,
null,
cveUsuarioEjecuta,
nombreDominio);
if (!documentos.Success)
{
return DbResult<List<TramiteClienteListado>>.Fail(
documentos.UserMessage,
documentos.TechnicalMessage,
documentos.Exception);
}
DbResult<List<PagoConvenioClienteFila>> pagos =
_repositorio.ListarPagos(
usuario.CveCliente,
cveFraccionamiento,
null,
null,
cveUsuarioEjecuta,
nombreDominio);
if (!pagos.Success)
{
return DbResult<List<TramiteClienteListado>>.Fail(
pagos.UserMessage,
pagos.TechnicalMessage,
pagos.Exception);
}
List<TramiteDocumentoSolicitudModel> documentosActuales =
documentos.Data ?? new List<TramiteDocumentoSolicitudModel>();
List<PagoConvenioClienteFila> pagosActuales =
pagos.Data ?? new List<PagoConvenioClienteFila>();
List<TramiteClienteListado> resultado =
(solicitudes.Data ?? new List<TramiteSolicitudModel>())
.Select(solicitud =>
{
int documentosPendientes = documentosActuales.Count(documento =>
(
documento.CveSolicitud == solicitud.CveSolicitud ||
(
documento.CveSolicitud <= 0 &&
documento.CveFraccionamientoEtapa ==
solicitud.CveFraccionamientoEtapa &&
documento.CveTipoTramite ==
solicitud.CveTipoTramite
)
) &&
documento.EsRequerido &&
(!documento.TieneArchivo || documento.FechaExpirada));
int pagosPendientes = pagosActuales.Count(pago =>
(
pago.CveSolicitud == solicitud.CveSolicitud ||
(
!pago.CveSolicitud.HasValue &&
pago.CveFraccionamientoEtapa ==
solicitud.CveFraccionamientoEtapa
)
) &&
pago.EsReciboPendiente &&
pago.SaldoPendiente > 0m);
return new TramiteClienteListado
{
CveSolicitud = solicitud.CveSolicitud,
Folio = solicitud.Folio,
CveFraccionamiento = solicitud.CveFraccionamiento,
CveFraccionamientoEtapa = solicitud.CveFraccionamientoEtapa,
Etapa = solicitud.Etapa,
CveTipoTramite = solicitud.CveTipoTramite,
TipoTramite = solicitud.TipoTramite,
CveEstatusSolicitud = solicitud.CveEstatusSolicitud,
EstatusSolicitud = solicitud.EstatusSolicitud,
DocumentosPendientes = documentosPendientes,
PagosPendientes = pagosPendientes,
PuedeEnviarRevision =
solicitud.PuedeCambiarEstatus &&
solicitud.EsEstatusCliente &&
documentosPendientes == 0 &&
pagosPendientes == 0
};
})
.OrderBy(x => x.Etapa)
.ThenBy(x => x.TipoTramite)
.ToList();
return DbResult<List<TramiteClienteListado>>.Ok(resultado);
}
public DbResult<TramiteSolicitudStatusChangeModel> EnviarRevision(
int cveSolicitud,
int cveFraccionamiento,
int cveUsuarioEjecuta,
string nombreDominio)
{
DbResult<List<TramiteClienteListado>> tramites =
ListarTramites(
cveFraccionamiento,
cveUsuarioEjecuta,
nombreDominio);
if (!tramites.Success)
{
return DbResult<TramiteSolicitudStatusChangeModel>.Fail(
tramites.UserMessage,
tramites.TechnicalMessage,
tramites.Exception);
}
TramiteClienteListado tramite =
(tramites.Data ?? new List<TramiteClienteListado>())
.FirstOrDefault(x => x.CveSolicitud == cveSolicitud);
if (tramite == null)
{
return Fallo<TramiteSolicitudStatusChangeModel>(
"No se encontró el trámite seleccionado.");
}
if (tramite.DocumentosPendientes > 0)
{
return Fallo<TramiteSolicitudStatusChangeModel>(
"Existen documentos requeridos pendientes de cargar o renovar.");
}
if (tramite.PagosPendientes > 0)
{
return Fallo<TramiteSolicitudStatusChangeModel>(
"Existen recibos pendientes de pago.");
}
DbResult<ModeloContextoCambioEstatus> contexto =
_servicioTramites.ObtenerContextoCambioEstatus(
cveSolicitud,
cveUsuarioEjecuta,
nombreDominio);
if (!contexto.Success || contexto.Data == null)
{
return DbResult<TramiteSolicitudStatusChangeModel>.Fail(
contexto.UserMessage,
contexto.TechnicalMessage,
contexto.Exception);
}
if (!contexto.Data.CveSiguienteEstatus.HasValue)
{
return Fallo<TramiteSolicitudStatusChangeModel>(
"El trámite no tiene un siguiente estatus disponible para enviar a revisión.");
}
var cambio = new ModeloCambioEstatusTramite
{
CveSolicitud = cveSolicitud,
CveEstatusSolicitudAnterior =
contexto.Data.Solicitud.CveEstatusSolicitud,
CveEstatusSolicitud =
contexto.Data.CveSiguienteEstatus.Value,
Observaciones =
"Enviado a revisión por el desarrollador.",
CvesCondicionesMostradas = new List<int>()
};
return _servicioTramites.CambiarEstatus(
cambio,
cveUsuarioEjecuta,
nombreDominio,
false);
}
public DbResult<List<DocumentoClientePortal>> ListarDocumentos(
FiltroDocumentosCliente filtro,
int cveUsuarioEjecuta,
string nombreDominio)
{
UserSessionModel usuario;
DbResult<bool> acceso = ValidarCliente(
cveUsuarioEjecuta,
out usuario);
if (!acceso.Success)
{
return Fallo<List<DocumentoClientePortal>>(acceso.UserMessage);
}
filtro = filtro ?? new FiltroDocumentosCliente();
DbResult<List<ModeloFilaDesarrollos>> desarrollos =
_servicioFraccionamiento.ListarDesarrollos(
usuario.CveCliente,
cveUsuarioEjecuta,
nombreDominio);
if (!desarrollos.Success)
{
return DbResult<List<DocumentoClientePortal>>.Fail(
desarrollos.UserMessage,
desarrollos.TechnicalMessage,
desarrollos.Exception);
}
var fraccionamientos =
(desarrollos.Data ?? new List<ModeloFilaDesarrollos>())
.Where(x => x.CveFraccionamiento > 0)
.GroupBy(x => x.CveFraccionamiento)
.Select(grupo => new
{
CveFraccionamiento = grupo.Key,
Fraccionamiento = grupo.First().Fraccionamiento
})
.Where(x =>
!filtro.CveFraccionamiento.HasValue ||
x.CveFraccionamiento == filtro.CveFraccionamiento.Value)
.OrderBy(x => x.Fraccionamiento)
.ToList();
var resultado = new List<DocumentoClientePortal>();
foreach (var fraccionamiento in fraccionamientos)
{
DbResult<List<TramiteDocumentoSolicitudModel>> documentos =
_servicioDocumentos.ListarRequisitos(
fraccionamiento.CveFraccionamiento,
filtro.CveFraccionamientoEtapa,
null,
cveUsuarioEjecuta,
nombreDominio);
if (!documentos.Success)
{
return DbResult<List<DocumentoClientePortal>>.Fail(
documentos.UserMessage,
documentos.TechnicalMessage,
documentos.Exception);
}
foreach (TramiteDocumentoSolicitudModel documento in
documentos.Data ?? new List<TramiteDocumentoSolicitudModel>())
{
string agrupacion = documento.Agrupacion;
if (!string.IsNullOrWhiteSpace(filtro.Agrupacion) &&
!string.Equals(
filtro.Agrupacion,
agrupacion,
StringComparison.OrdinalIgnoreCase))
{
continue;
}
resultado.Add(new DocumentoClientePortal
{
CveDocumentoSolicitud = documento.CveDocumentoSolicitud,
CveSolicitud = documento.CveSolicitud,
CveCliente = documento.CveCliente,
CveFraccionamiento = documento.CveFraccionamiento,
Fraccionamiento = fraccionamiento.Fraccionamiento,
CveFraccionamientoEtapa = documento.CveFraccionamientoEtapa,
Etapa = documento.Etapa,
CveTipoTramite = documento.CveTipoTramite,
TipoTramite = documento.TipoTramite,
CveTipoDocumento = documento.CveTipoDocumento,
TipoDocumento = documento.TipoDocumento,
NombreArchivo = documento.NombreArchivo,
Nota = documento.Nota,
EsAprobado = documento.EsAprobado,
FechaDocumento = documento.FechaDocumento,
FechaVencimiento = documento.FechaVencimiento,
TieneArchivo = documento.TieneArchivo,
EsCliente = documento.EsCliente,
PuedeActualizarArchivo = documento.PuedeActualizarArchivo,
EsRequerido = documento.EsRequerido,
TieneVigencia = documento.TieneVigencia,
FechaExpirada = documento.FechaExpirada,
EstadoDocumento = documento.EstadoDocumento,
Agrupacion = agrupacion
});
}
}
return DbResult<List<DocumentoClientePortal>>.Ok(
resultado
.OrderBy(x => x.Fraccionamiento)
.ThenBy(x => x.Etapa)
.ThenBy(x => x.Agrupacion)
.ThenBy(x => x.TipoDocumento)
.ToList());
}
public DbResult<List<PagoConvenioClienteFila>> ListarPagos(
FiltroPagosCliente filtro,
int cveUsuarioEjecuta,
string nombreDominio)
{
UserSessionModel usuario;
DbResult<bool> acceso = ValidarCliente(
cveUsuarioEjecuta,
out usuario);
if (!acceso.Success)
{
return Fallo<List<PagoConvenioClienteFila>>(acceso.UserMessage);
}
filtro = filtro ?? new FiltroPagosCliente();
return _repositorio.ListarPagos(
usuario.CveCliente,
filtro.CveFraccionamiento,
filtro.CveFraccionamientoEtapa,
filtro.Agrupacion,
cveUsuarioEjecuta,
nombreDominio);
}
public DbResult<List<ReciboConvenioDisponibleCliente>> ListarRecibosDisponibles(
int? cveFraccionamiento,
int cveUsuarioEjecuta,
string nombreDominio)
{
UserSessionModel usuario;
DbResult<bool> acceso = ValidarCliente(
cveUsuarioEjecuta,
out usuario);
if (!acceso.Success)
{
return Fallo<List<ReciboConvenioDisponibleCliente>>(
acceso.UserMessage);
}
return _repositorio.ListarRecibosDisponibles(
usuario.CveCliente,
cveFraccionamiento,
cveUsuarioEjecuta,
nombreDominio);
}
public DbResult<int> RegistrarPago(
SolicitudPagoConvenioCliente pago,
Stream contenido,
int cveUsuarioEjecuta,
string nombreDominio)
{
UserSessionModel usuario;
DbResult<bool> acceso = ValidarCliente(
cveUsuarioEjecuta,
out usuario);
if (!acceso.Success)
{
return Fallo<int>(acceso.UserMessage);
}
if (pago == null)
{
return Fallo<int>("Capture los datos del pago.");
}
pago.CveCliente = usuario.CveCliente;
pago.Referencia = RecortarONulo(pago.Referencia, 200);
pago.Banco = RecortarONulo(pago.Banco, 200);
pago.NumeroOperacion = RecortarONulo(pago.NumeroOperacion, 200);
pago.Observaciones = RecortarONulo(pago.Observaciones, 1000);
if (pago.Importe <= 0m)
{
return Fallo<int>("Capture un importe de pago mayor a cero.");
}
if (pago.Aplicaciones == null || pago.Aplicaciones.Count == 0)
{
return Fallo<int>("Vincule al menos un recibo al comprobante.");
}
if (pago.Aplicaciones.Any(x =>
x.CveConvenioRecibo <= 0 ||
x.ImporteAplicado <= 0m))
{
return Fallo<int>(
"Revise los recibos y los importes aplicados.");
}
if (pago.Aplicaciones
.GroupBy(x => x.CveConvenioRecibo)
.Any(grupo => grupo.Count() > 1))
{
return Fallo<int>(
"El mismo recibo no puede agregarse dos veces al pago.");
}
decimal totalAplicado = pago.Aplicaciones.Sum(
x => x.ImporteAplicado);
if (totalAplicado > pago.Importe)
{
return Fallo<int>(
"El importe aplicado a recibos no puede ser mayor al importe del pago.");
}
bool archivoGuardado = false;
try
{
_almacenComprobantes.Guardar(pago, contenido);
archivoGuardado = true;
using (var transaccion = new TransactionLogic(
IsolationLevel.Serializable))
{
DbResult<int> resultado = _repositorio.AgregarPago(
pago,
cveUsuarioEjecuta,
nombreDominio);
if (!resultado.Success)
{
_almacenComprobantes.Eliminar(
pago.CveCliente,
pago.NombreFisico);
archivoGuardado = false;
return resultado;
}
transaccion.Commit();
return resultado;
}
}
catch (ControlledApplicationException excepcion)
{
if (archivoGuardado)
{
_almacenComprobantes.Eliminar(
pago.CveCliente,
pago.NombreFisico);
}
return DbResult<int>.Fail(
excepcion.Message,
excepcion.Message,
excepcion);
}
catch
{
if (archivoGuardado)
{
_almacenComprobantes.Eliminar(
pago.CveCliente,
pago.NombreFisico);
}
throw;
}
}
public DbResult<ArchivoPagoConvenioCliente> ObtenerArchivoPago(
int cveConvenioPago,
int cveUsuarioEjecuta,
string nombreDominio)
{
UserSessionModel usuario;
DbResult<bool> acceso = ValidarCliente(
cveUsuarioEjecuta,
out usuario);
if (!acceso.Success)
{
return Fallo<ArchivoPagoConvenioCliente>(acceso.UserMessage);
}
DbResult<ArchivoPagoConvenioCliente> resultado =
_repositorio.ObtenerArchivoPago(
cveConvenioPago,
usuario.CveCliente,
cveUsuarioEjecuta,
nombreDominio);
if (!resultado.Success || resultado.Data == null)
{
return resultado;
}
resultado.Data.RutaFisica = _almacenComprobantes.Resolver(
resultado.Data.CveCliente,
resultado.Data.NombreFisico);
return resultado;
}
private DbResult<bool> ValidarCliente(
int cveUsuarioEjecuta,
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);
}
private static string RecortarONulo(
string texto,
int longitudMaxima)
{
if (string.IsNullOrWhiteSpace(texto))
{
return null;
}
string valor = texto.Trim();
return valor.Length <= longitudMaxima
? valor
: valor.Substring(0, longitudMaxima);
}
private static DbResult<T> Fallo<T>(string mensaje)
{
return DbResult<T>.Fail(
mensaje,
mensaje,
null);
}
}
}

View File

@@ -0,0 +1,240 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Transactions;
using SIG.Web.AppCode.Contracts.Convenios;
using SIG.Web.AppCode.Contracts.Security;
using SIG.Web.AppCode.Infrastructure.Transactions;
using SIG.Web.AppCode.Models.Common;
using SIG.Web.AppCode.Models.Convenios;
namespace SIG.Web.AppCode.Services.Convenios
{
public sealed class ServicioConvenios : IServicioConvenios
{
private readonly IRepositorioConvenios _repositorio;
private readonly IUserContextProvider _usuario;
public ServicioConvenios(
IRepositorioConvenios repositorio,
IUserContextProvider usuario)
{
_repositorio = repositorio;
_usuario = usuario;
}
public DbResult<List<ConvenioListado>> Listar(
FiltroConvenios filtro,
int usuario,
string dominio)
{
filtro = filtro ?? new FiltroConvenios();
var actual = _usuario.GetCurrentUser();
if (actual != null && actual.EsDesarrollador)
{
filtro.CveCliente = actual.CveCliente;
}
return _repositorio.Listar(filtro, usuario, dominio);
}
public DbResult<ConvenioDetalleCompleto> Obtener(
int cveConvenio,
int usuario,
string dominio)
{
var resultado = _repositorio.Obtener(
cveConvenio,
usuario,
dominio);
if (!resultado.Success ||
resultado.Data == null ||
resultado.Data.Encabezado == null)
{
return resultado;
}
var actual = _usuario.GetCurrentUser();
if (actual != null &&
actual.EsDesarrollador &&
resultado.Data.Encabezado.CveCliente != actual.CveCliente)
{
return DbResult<ConvenioDetalleCompleto>.Fail(
"No tiene acceso al convenio solicitado.",
"Convenio fuera del cliente asignado.",
null);
}
return resultado;
}
public DbResult<List<ConvenioConceptoCatalogo>> ListarConceptos(
int usuario,
string dominio)
{
return _repositorio.ListarConceptos(usuario, dominio);
}
public DbResult<int> Agregar(
SolicitudAltaConvenio solicitud,
int usuario,
string dominio)
{
var actual = _usuario.GetCurrentUser();
if (actual != null && actual.EsDesarrollador)
{
return DbResult<int>.Fail(
"La captura de convenios está disponible para usuarios administrativos.",
"Un usuario desarrollador intentó registrar un convenio.",
null);
}
string mensajeValidacion = ValidarSolicitud(solicitud);
if (!string.IsNullOrWhiteSpace(mensajeValidacion))
{
return DbResult<int>.Fail(
mensajeValidacion,
mensajeValidacion,
null);
}
using (var transaccion = new TransactionLogic(
IsolationLevel.Serializable))
{
var resultado = _repositorio.Agregar(
solicitud,
usuario,
dominio);
if (resultado.Success)
{
transaccion.Commit();
}
return resultado;
}
}
public DbResult<bool> Eliminar(
int cveConvenio,
int usuario,
string dominio)
{
var acceso = Obtener(cveConvenio, usuario, dominio);
if (!acceso.Success)
{
return DbResult<bool>.Fail(
acceso.UserMessage,
acceso.TechnicalMessage,
acceso.Exception);
}
var actual = _usuario.GetCurrentUser();
if (actual != null && actual.EsDesarrollador)
{
return DbResult<bool>.Fail(
"No tiene permiso para eliminar convenios.",
"El rol desarrollador intentó eliminar un convenio.",
null);
}
using (var transaccion = new TransactionLogic(
IsolationLevel.Serializable))
{
var resultado = _repositorio.Eliminar(
cveConvenio,
usuario,
dominio);
if (resultado.Success)
{
transaccion.Commit();
}
return resultado;
}
}
private static string ValidarSolicitud(
SolicitudAltaConvenio solicitud)
{
if (solicitud == null)
{
return "Capture los datos del convenio.";
}
if (solicitud.CveCliente <= 0)
{
return "Seleccione el desarrollador del convenio.";
}
if (solicitud.CveFraccionamientoEtapa <= 0)
{
return "Seleccione el fraccionamiento y etapa del convenio.";
}
if (string.IsNullOrWhiteSpace(solicitud.NumeroConvenio))
{
return "Capture el número de convenio.";
}
if (solicitud.ViviendasEnConvenio < 0)
{
return "La cantidad de viviendas en convenio no es válida.";
}
if (solicitud.Conceptos == null || solicitud.Conceptos.Count == 0)
{
return "Agregue al menos un concepto al convenio.";
}
foreach (var concepto in solicitud.Conceptos)
{
if (concepto.CveConvenioConcepto <= 0 || concepto.Importe <= 0)
{
return "Revise los conceptos e importes del convenio.";
}
if (string.IsNullOrWhiteSpace(concepto.Tipo))
{
return "Seleccione el tipo de moneda de cada concepto.";
}
if (concepto.NumeroPagos < 1 || concepto.NumeroPagos > 12)
{
return "Cada concepto debe tener entre 1 y 12 parcialidades.";
}
var parcialidades = concepto.Parcialidades ??
new List<ConvenioReciboCaptura>();
if (parcialidades.Count != concepto.NumeroPagos)
{
return "La cantidad de parcialidades debe coincidir con el número de pagos del concepto.";
}
if (parcialidades.Any(x => x.Importe <= 0))
{
return "Todas las parcialidades deben tener un importe mayor a cero.";
}
decimal suma = parcialidades.Sum(x => x.Importe);
if (suma != concepto.Importe)
{
return "La suma de las parcialidades debe coincidir con el importe del concepto.";
}
}
return string.Empty;
}
}
}

View File

@@ -0,0 +1,199 @@
using System;
using System.Globalization;
using System.IO;
using System.Web.Hosting;
using SIG.Web.AppCode.Contracts.Documentos;
using SIG.Web.AppCode.Infrastructure;
using SIG.Web.AppCode.Models.Clientes;
namespace SIG.Web.AppCode.Services.Documentos
{
public sealed class AlmacenComprobantesConvenio
: IAlmacenComprobantesConvenio
{
private const int TamanoMaximo = 5 * 1024 * 1024;
public void Guardar(
SolicitudPagoConvenioCliente pago,
Stream contenido)
{
if (pago == null)
{
throw new ControlledApplicationException(
"Capture el comprobante del pago.");
}
string extension = Path.GetExtension(
pago.NombreArchivo ?? string.Empty).ToLowerInvariant();
string tipoContenido = ObtenerTipoContenido(extension);
if (tipoContenido == null ||
contenido == null ||
!contenido.CanRead ||
pago.TamanoBytes <= 0 ||
pago.TamanoBytes > TamanoMaximo ||
!string.Equals(
tipoContenido,
pago.TipoContenido,
StringComparison.OrdinalIgnoreCase))
{
throw new ControlledApplicationException(
"Seleccione un comprobante PDF, JPG o PNG de hasta 5 MB.");
}
byte[] archivo;
using (var memoria = new MemoryStream())
{
var bloque = new byte[81920];
int leidos;
while ((leidos = contenido.Read(
bloque,
0,
bloque.Length)) > 0)
{
if (memoria.Length + leidos > TamanoMaximo)
{
throw new ControlledApplicationException(
"El comprobante excede 5 MB.");
}
memoria.Write(bloque, 0, leidos);
}
archivo = memoria.ToArray();
}
if (archivo.Length != pago.TamanoBytes ||
archivo.Length < 12 ||
!SIG.Web.AppCode.Services.Visitas.AlmacenDocumentosVisita
.FirmaValida(extension, archivo, 12))
{
throw new ControlledApplicationException(
"El contenido del comprobante no corresponde al formato indicado.");
}
pago.NombreArchivo = Path.GetFileName(pago.NombreArchivo);
if (string.IsNullOrWhiteSpace(pago.NombreArchivo) ||
pago.NombreArchivo.Length > 255)
{
throw new ControlledApplicationException(
"El nombre del comprobante no es válido.");
}
pago.NombreFisico = Guid.NewGuid().ToString("N") + extension;
pago.TipoContenido = tipoContenido;
string raizDocumentos = HostingEnvironment.MapPath("~/Documentos/");
if (string.IsNullOrWhiteSpace(raizDocumentos))
{
throw new ControlledApplicationException(
"No fue posible resolver la carpeta de documentos.");
}
Directory.CreateDirectory(raizDocumentos);
Directory.CreateDirectory(
Path.Combine(raizDocumentos, "Generales"));
Directory.CreateDirectory(
Path.Combine(raizDocumentos, "Clientes"));
string ruta = Resolver(
pago.CveCliente,
pago.NombreFisico);
Directory.CreateDirectory(Path.GetDirectoryName(ruta));
try
{
using (var destino = new FileStream(
ruta,
FileMode.CreateNew,
FileAccess.Write,
FileShare.None))
{
destino.Write(archivo, 0, archivo.Length);
}
}
catch
{
Eliminar(pago.CveCliente, pago.NombreFisico);
throw;
}
}
public string Resolver(
int cveCliente,
string nombreFisico)
{
Guid identificador;
if (cveCliente <= 0 ||
string.IsNullOrWhiteSpace(nombreFisico) ||
Path.GetFileName(nombreFisico) != nombreFisico ||
!Guid.TryParseExact(
Path.GetFileNameWithoutExtension(nombreFisico),
"N",
out identificador))
{
throw new ControlledApplicationException(
"El comprobante no está disponible.");
}
string raizClientes = HostingEnvironment.MapPath(
"~/Documentos/Clientes/");
if (string.IsNullOrWhiteSpace(raizClientes))
{
throw new ControlledApplicationException(
"El comprobante no está disponible.");
}
return Path.Combine(
raizClientes,
cveCliente.ToString(CultureInfo.InvariantCulture),
"Convenios",
"Pagos",
nombreFisico);
}
public void Eliminar(
int cveCliente,
string nombreFisico)
{
if (string.IsNullOrWhiteSpace(nombreFisico))
{
return;
}
string ruta = Resolver(cveCliente, nombreFisico);
if (File.Exists(ruta))
{
File.Delete(ruta);
}
}
private static string ObtenerTipoContenido(string extension)
{
if (extension == ".pdf")
{
return "application/pdf";
}
if (extension == ".png")
{
return "image/png";
}
if (extension == ".jpg" || extension == ".jpeg")
{
return "image/jpeg";
}
return null;
}
}
}

View File

@@ -0,0 +1,14 @@
INTEGRACIÓN CONVENIOS - NUEVA ESTRUCTURA
1. Ejecutar SQL/ConveniosIntegracion.sql después de haber creado las tablas Convenios* acordadas.
2. El script NO modifica ni elimina las tablas heredadas de pagos/timbrado.
3. Se agregó UserControl/ConveniosListado.ascx reutilizable:
- En DetalleEtapa se carga filtrado por CveFraccionamientoEtapa y no muestra filtros.
- En Pages/Desarrolladores/Convenios.aspx se usa el mismo control con el control sig:Filtros.
4. El detalle abre modal y muestra Concepto -> Recibos con sig-grid-agrupado.
5. El botón Eliminar sólo se muestra a usuarios internos cuando el listado indica que no hay pagos vinculados. El PA vuelve a validar esta condición antes del DELETE.
6. Scripts/Convenios.js y Styles/Convenios.css son recursos compartidos del UserControl y quedaron agregados al BundleConfig global.
7. Se incluyeron Scripts/sig-grid-agrupado.js y Styles/sig-grid-agrupado.css porque BundleConfig ya los referenciaba y el ZIP recibido no contenía físicamente esos archivos. El JS conserva el estado independiente de niveles inferiores al cerrar/abrir un padre y es idempotente ante UpdatePanel.
IMPORTANTE SOBRE NOMBRES DE BD:
Los PA usan dbo.Clientes(CveCliente, Cliente), dbo.Fraccionamientos(CveFraccionamiento, Fraccionamiento) y dbo.FraccionamientosEtapas(CveFraccionamientoEtapa, CveFraccionamiento, Etapa), conforme a los nombres que usa el modelo de la plataforma. Si en la BD física el campo descriptivo de Clientes tiene otro nombre, ajustar únicamente CL.Cliente en los dos SELECT del SQL antes de ejecutarlo.

View File

@@ -0,0 +1 @@
<%@ WebHandler Language="C#" Class="SIG.Web.Pages.Clientes.ComprobanteConvenioPagoHandler" %>

View File

@@ -0,0 +1,52 @@
<%@ Page Title="Mis desarrollos" Language="C#" MasterPageFile="~/Site.master"
AutoEventWireup="true" CodeFile="Desarrollos.aspx.cs"
Inherits="SIG.Web.Pages.Clientes.Desarrollos" %>
<asp:Content ID="ContenidoEncabezado" ContentPlaceHolderID="H" runat="server">
<style>
.sig-cliente-desarrollo-cabecera {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
width: 100%;
}
.sig-cliente-desarrollo-cabecera a {
font-weight: 600;
}
.sig-cliente-desarrollo-resumen {
color: #7f8c8d;
margin-left: 8px;
}
</style>
</asp:Content>
<asp:Content ID="ContenidoPrincipal" ContentPlaceHolderID="C" runat="server">
<asp:UpdatePanel ID="UpDesarrollos" runat="server"
UpdateMode="Conditional" ChildrenAsTriggers="true">
<ContentTemplate>
<div class="table-responsive">
<asp:GridView ID="GvDesarrollos" runat="server"
AutoGenerateColumns="false"
GridLines="None"
CssClass="table table-hover Widthall sig-grid-agrupado"
DataKeyNames="CveFraccionamiento,CveFraccionamientoEtapa,EsFraccionamiento"
EmptyDataText="No tiene fraccionamientos activos."
OnRowDataBound="EnlazarFila">
<Columns>
<asp:BoundField DataField="Etapa" HeaderText="Etapa" />
<asp:BoundField DataField="Hectareas" HeaderText="Hectáreas"
DataFormatString="{0:N2}" />
<asp:CheckBoxField DataField="Fideicomiso" HeaderText="Fideicomiso" />
<asp:CheckBoxField DataField="EsActivo" HeaderText="Activa" />
</Columns>
</asp:GridView>
</div>
</ContentTemplate>
</asp:UpdatePanel>
</asp:Content>
<asp:Content ID="ContenidoScripts" ContentPlaceHolderID="J" runat="server">
</asp:Content>

View File

@@ -0,0 +1,124 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using SIG.Web.AppCode.Configuration;
using SIG.Web.AppCode.Infrastructure.WebForms;
using SIG.Web.AppCode.Models.Fraccionamientos;
using SIG.Web.AppCode.Security;
namespace SIG.Web.Pages.Clientes
{
public partial class Desarrollos : ClsPaginaBase
{
protected void Page_Load(object origen, EventArgs argumentos)
{
if (!IsPostBack)
{
Cargar();
}
}
protected void EnlazarFila(object origen, GridViewRowEventArgs argumentos)
{
if (argumentos.Row.RowType != DataControlRowType.DataRow)
{
return;
}
var fila = argumentos.Row.DataItem as ModeloFilaDesarrollos;
if (fila == null)
{
return;
}
string grupo = "desarrollo-" +
fila.CveFraccionamiento.ToString(CultureInfo.InvariantCulture);
if (fila.EsFraccionamiento)
{
argumentos.Row.CssClass = "sig-grid-grupo";
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";
int columnas = GvDesarrollos.Columns
.Cast<DataControlField>()
.Count(columna => columna.Visible);
argumentos.Row.Cells.Clear();
var celda = new TableCell { ColumnSpan = columnas };
var contenedor = new HtmlGenericControl("div");
contenedor.Attributes["class"] =
"sig-cliente-desarrollo-cabecera";
var informacion = new HtmlGenericControl("div");
var enlace = new HyperLink
{
Text = fila.Fraccionamiento,
NavigateUrl = ResolveUrl(
"~/Pages/Clientes/FraccionamientoDetalle.aspx?id=" +
fila.CveFraccionamiento.ToString(
CultureInfo.InvariantCulture))
};
informacion.Controls.Add(enlace);
var resumen = new HtmlGenericControl("span");
resumen.Attributes["class"] =
"sig-cliente-desarrollo-resumen";
resumen.InnerText = string.Format(
CultureInfo.CurrentCulture,
"{0} · {1} etapa(s)",
fila.Estatus,
fila.NumeroEtapas);
informacion.Controls.Add(resumen);
var alternar = new HtmlGenericControl("button");
alternar.Attributes["type"] = "button";
alternar.Attributes["class"] =
"btn btn-sm default sig-grid-alternar-grupo";
alternar.Attributes["aria-expanded"] = "true";
alternar.Attributes["title"] = "Mostrar u ocultar etapas";
var icono = new HtmlGenericControl("i");
icono.Attributes["class"] =
"fa fa-chevron-up sig-grid-icono-agrupacion";
icono.Attributes["aria-hidden"] = "true";
alternar.Controls.Add(icono);
contenedor.Controls.Add(informacion);
contenedor.Controls.Add(alternar);
celda.Controls.Add(contenedor);
argumentos.Row.Cells.Add(celda);
return;
}
argumentos.Row.Attributes["data-sig-item-row"] = "1";
argumentos.Row.Attributes["data-sig-parent-group"] = grupo;
argumentos.Row.Attributes["data-sig-level"] = "1";
}
private void Cargar()
{
var resultado = AppServices.ServicioPortalCliente.ListarDesarrollos(
CurrentUser.CveUsuario,
CurrentUser.NombreDominio);
GvDesarrollos.DataSource = resultado.Success
? resultado.Data
: new List<ModeloFilaDesarrollos>();
GvDesarrollos.DataBind();
UpDesarrollos.Update();
if (!resultado.Success)
{
Alert(resultado.UserMessage, TipoMensaje.MsgAdvertencia);
}
}
}
}

View File

@@ -0,0 +1,14 @@
<%@ Page Title="Mis documentos" Language="C#" MasterPageFile="~/Site.master"
AutoEventWireup="true" CodeFile="Documentos.aspx.cs"
Inherits="SIG.Web.Pages.Clientes.Documentos" %>
<%@ Register TagPrefix="cliente" TagName="Documentos" Src="~/UserControl/Clientes/DocumentosCliente.ascx" %>
<asp:Content ID="ContenidoEncabezado" ContentPlaceHolderID="H" runat="server">
</asp:Content>
<asp:Content ID="ContenidoPrincipal" ContentPlaceHolderID="C" runat="server">
<cliente:Documentos ID="UcDocumentos" runat="server" />
</asp:Content>
<asp:Content ID="ContenidoScripts" ContentPlaceHolderID="J" runat="server">
</asp:Content>

View File

@@ -0,0 +1,16 @@
using System;
using SIG.Web.AppCode.Security;
namespace SIG.Web.Pages.Clientes
{
public partial class Documentos : ClsPaginaBase
{
protected void Page_Load(object origen, EventArgs argumentos)
{
if (!IsPostBack)
{
UcDocumentos.Cargar(null, true);
}
}
}
}

View File

@@ -0,0 +1,88 @@
<%@ Page Title="Detalle del desarrollo" Language="C#" MasterPageFile="~/Site.master"
AutoEventWireup="true" CodeFile="FraccionamientoDetalle.aspx.cs"
Inherits="SIG.Web.Pages.Clientes.FraccionamientoDetalle" %>
<%@ Register TagPrefix="cliente" TagName="Tramites" Src="~/UserControl/Clientes/TramitesCliente.ascx" %>
<%@ Register TagPrefix="cliente" TagName="Documentos" Src="~/UserControl/Clientes/DocumentosCliente.ascx" %>
<%@ Register TagPrefix="cliente" TagName="Pagos" Src="~/UserControl/Clientes/PagosCliente.ascx" %>
<asp:Content ID="ContenidoEncabezado" ContentPlaceHolderID="H" runat="server">
<style>
.sig-cliente-resumen-desarrollo {
background: #fff;
border: 1px solid #e7ecf1;
margin-bottom: 15px;
padding: 12px;
}
.sig-cliente-resumen-desarrollo h3 {
margin-top: 0;
}
</style>
</asp:Content>
<asp:Content ID="ContenidoPrincipal" ContentPlaceHolderID="C" runat="server">
<asp:Panel ID="PanelContenido" runat="server">
<div class="sig-cliente-resumen-desarrollo">
<h3><asp:Literal ID="LitFraccionamiento" runat="server" Mode="Encode" /></h3>
<div>
<strong>Ubicación:</strong>
<asp:Literal ID="LitUbicacion" runat="server" Mode="Encode" />
&nbsp; · &nbsp;
<strong>Estatus:</strong>
<asp:Literal ID="LitEstatus" runat="server" Mode="Encode" />
</div>
</div>
<ajax:TabContainer ID="Pestanas" runat="server"
Width="100%" AutoPostBack="false"
CssClass="ajax__tab_xp">
<ajax:TabPanel ID="PestanaEtapas" runat="server" HeaderText="Etapas">
<ContentTemplate>
<asp:UpdatePanel ID="UpEtapas" runat="server"
UpdateMode="Conditional" ChildrenAsTriggers="true">
<ContentTemplate>
<div class="table-responsive">
<asp:GridView ID="GvEtapas" runat="server"
AutoGenerateColumns="false"
GridLines="None"
CssClass="table table-striped table-hover Widthall"
EmptyDataText="No hay etapas registradas.">
<Columns>
<asp:BoundField DataField="Etapa" HeaderText="Etapa" />
<asp:BoundField DataField="Hectareas" HeaderText="Hectáreas"
DataFormatString="{0:N2}" />
<asp:BoundField DataField="Avance" HeaderText="Avance"
DataFormatString="{0:N2} %" />
<asp:CheckBoxField DataField="Fideicomiso" HeaderText="Fideicomiso" />
<asp:CheckBoxField DataField="EsActivo" HeaderText="Activa" />
</Columns>
</asp:GridView>
</div>
</ContentTemplate>
</asp:UpdatePanel>
</ContentTemplate>
</ajax:TabPanel>
<ajax:TabPanel ID="PestanaTramites" runat="server" HeaderText="Trámites">
<ContentTemplate>
<cliente:Tramites ID="UcTramites" runat="server" />
</ContentTemplate>
</ajax:TabPanel>
<ajax:TabPanel ID="PestanaDocumentos" runat="server" HeaderText="Documentos">
<ContentTemplate>
<cliente:Documentos ID="UcDocumentos" runat="server" />
</ContentTemplate>
</ajax:TabPanel>
<ajax:TabPanel ID="PestanaPagos" runat="server" HeaderText="Pagos">
<ContentTemplate>
<cliente:Pagos ID="UcPagos" runat="server" />
</ContentTemplate>
</ajax:TabPanel>
</ajax:TabContainer>
</asp:Panel>
</asp:Content>
<asp:Content ID="ContenidoScripts" ContentPlaceHolderID="J" runat="server">
</asp:Content>

View File

@@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using SIG.Web.AppCode.Configuration;
using SIG.Web.AppCode.Infrastructure.WebForms;
using SIG.Web.AppCode.Models.Fraccionamientos;
using SIG.Web.AppCode.Security;
namespace SIG.Web.Pages.Clientes
{
public partial class FraccionamientoDetalle : ClsPaginaBase
{
private int CveFraccionamientoActual
{
get { return (int?)ViewState["CveFraccionamientoActual"] ?? 0; }
set { ViewState["CveFraccionamientoActual"] = value; }
}
protected void Page_Load(object origen, EventArgs argumentos)
{
if (IsPostBack)
{
return;
}
int cveFraccionamiento;
if (!int.TryParse(
Request.QueryString["id"],
NumberStyles.Integer,
CultureInfo.InvariantCulture,
out cveFraccionamiento) ||
cveFraccionamiento <= 0)
{
Alert(
"Seleccione un fraccionamiento válido.",
TipoMensaje.MsgAdvertencia);
PanelContenido.Visible = false;
return;
}
CveFraccionamientoActual = cveFraccionamiento;
Cargar();
}
private void Cargar()
{
var fraccionamiento =
AppServices.ServicioPortalCliente.ObtenerFraccionamiento(
CveFraccionamientoActual,
CurrentUser.CveUsuario,
CurrentUser.NombreDominio);
if (!fraccionamiento.Success || fraccionamiento.Data == null)
{
PanelContenido.Visible = false;
Alert(
fraccionamiento.Success
? "No se encontró el fraccionamiento."
: fraccionamiento.UserMessage,
TipoMensaje.MsgAdvertencia);
return;
}
ModeloFraccionamiento datos = fraccionamiento.Data;
LitFraccionamiento.Text = datos.Fraccionamiento;
LitUbicacion.Text = datos.Ubicacion;
LitEstatus.Text = datos.Estatus;
Page.Title = datos.Fraccionamiento;
var etapas = AppServices.ServicioPortalCliente.ListarEtapas(
CveFraccionamientoActual,
CurrentUser.CveUsuario,
CurrentUser.NombreDominio);
GvEtapas.DataSource = etapas.Success
? etapas.Data
: new List<ModeloEtapaFraccionamiento>();
GvEtapas.DataBind();
UpEtapas.Update();
if (!etapas.Success)
{
Alert(etapas.UserMessage, TipoMensaje.MsgAdvertencia);
}
UcTramites.Cargar(CveFraccionamientoActual);
UcDocumentos.Cargar(CveFraccionamientoActual, false);
UcPagos.Cargar(CveFraccionamientoActual, false);
}
}
}

View File

@@ -0,0 +1,14 @@
<%@ Page Title="Mis pagos" Language="C#" MasterPageFile="~/Site.master"
AutoEventWireup="true" CodeFile="Pagos.aspx.cs"
Inherits="SIG.Web.Pages.Clientes.Pagos" %>
<%@ Register TagPrefix="cliente" TagName="Pagos" Src="~/UserControl/Clientes/PagosCliente.ascx" %>
<asp:Content ID="ContenidoEncabezado" ContentPlaceHolderID="H" runat="server">
</asp:Content>
<asp:Content ID="ContenidoPrincipal" ContentPlaceHolderID="C" runat="server">
<cliente:Pagos ID="UcPagos" runat="server" />
</asp:Content>
<asp:Content ID="ContenidoScripts" ContentPlaceHolderID="J" runat="server">
</asp:Content>

View File

@@ -0,0 +1,16 @@
using System;
using SIG.Web.AppCode.Security;
namespace SIG.Web.Pages.Clientes
{
public partial class Pagos : ClsPaginaBase
{
protected void Page_Load(object origen, EventArgs argumentos)
{
if (!IsPostBack)
{
UcPagos.Cargar(null, true);
}
}
}
}

View File

@@ -1,157 +0,0 @@
<%@ Page Title="Detalle de convenio" Language="C#" MasterPageFile="~/Site.master"
AutoEventWireup="true" CodeFile="ConvenioDetalle.aspx.cs" Inherits="SIG.Web.Pages.Desarrolladores.ConvenioDetalle" %>
<asp:Content ID="ContenidoEncabezado" ContentPlaceHolderID="H" runat="server">
</asp:Content>
<asp:Content ID="ContenidoAcciones" ContentPlaceHolderID="A" runat="server">
<li><asp:HyperLink runat="server" NavigateUrl="~/Pages/Desarrolladores/Convenios.aspx" Text="Consultar convenios" /></li>
</asp:Content>
<asp:Content ID="ContenidoPrincipal" ContentPlaceHolderID="C" runat="server">
<asp:Panel ID="PnlCaptura" runat="server" CssClass="sig-convenio-captura">
<asp:UpdatePanel ID="UpCabecera" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Panel ID="PnlSeleccionOrigen" runat="server">
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="DdlCliente" Text="Cliente" />
<asp:DropDownList ID="DdlCliente" runat="server" CssClass="form-control select2me"
AutoPostBack="true" OnSelectedIndexChanged="CambiarCliente" />
</div>
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="DdlOrigen" Text="Adeudo con saldo pendiente" />
<asp:DropDownList ID="DdlOrigen" runat="server" CssClass="form-control select2me"
AutoPostBack="true" OnSelectedIndexChanged="CambiarOrigen" />
</div>
</asp:Panel>
<p><asp:Literal ID="LitOrigen" runat="server" Mode="Encode" /></p>
<div class="row">
<div class="col-md-6 form-group">
<asp:Label runat="server" AssociatedControlID="TxtSaldoConvenido" Text="Saldo que entra al convenio" />
<asp:TextBox ID="TxtSaldoConvenido" runat="server" CssClass="form-control" MaxLength="24" />
</div>
<div class="col-md-6 form-group">
<asp:Label runat="server" AssociatedControlID="TxtImporte" Text="Importe del nuevo convenio" />
<asp:TextBox ID="TxtImporte" runat="server" CssClass="form-control" MaxLength="24" />
</div>
</div>
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="TxtDescripcion" Text="Descripción" />
<asp:TextBox ID="TxtDescripcion" runat="server" CssClass="form-control" MaxLength="1000" />
</div>
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="TxtObservaciones" Text="Observaciones" />
<asp:TextBox ID="TxtObservaciones" runat="server" CssClass="form-control"
TextMode="MultiLine" Rows="3" MaxLength="2000" />
</div>
<asp:CheckBox ID="ChkRequerido" runat="server" Text=" Pago requerido" Checked="true" />
<p>Los importes se capturan en la unidad del adeudo origen, con hasta seis decimales.</p>
<asp:LinkButton ID="BtnSugerir" runat="server" CssClass="btn blue" OnClick="SugerirDistribucion">
<i class="fa fa-calculator" aria-hidden="true"></i> Sugerir distribución
</asp:LinkButton>
</ContentTemplate>
</asp:UpdatePanel>
<ajax:TabContainer ID="PestanasConvenio" runat="server" ActiveTabIndex="0" Width="100%">
<ajax:TabPanel ID="TabProductos" runat="server" HeaderText="Productos">
<ContentTemplate>
<asp:UpdatePanel ID="UpProductos" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<p>Ajuste los importes y pulse Guardar convenio. La suma debe coincidir con el importe del convenio.</p>
<asp:GridView ID="GvProductos" runat="server" AutoGenerateColumns="false" GridLines="None"
CssClass="table table-striped table-hover Widthall" DataKeyNames="CvePS"
OnRowCommand="ProductoComando" EmptyDataText="Seleccione un adeudo y sugiera la distribución.">
<Columns>
<asp:BoundField DataField="Descripcion" HeaderText="Producto" />
<asp:TemplateField HeaderText="Importe del convenio">
<ItemTemplate>
<asp:TextBox ID="TxtImporteProducto" runat="server" CssClass="form-control"
MaxLength="24" Text='<%# Convert.ToDecimal(Eval("Importe")).ToString("0.######", System.Globalization.CultureInfo.InvariantCulture) %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:ButtonField CommandName="QuitarProducto" Text="Quitar"
ControlStyle-CssClass="btn btn-xs red" />
</Columns>
</asp:GridView>
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="DdlProducto" Text="Agregar producto del catálogo existente" />
<asp:DropDownList ID="DdlProducto" runat="server" CssClass="form-control select2me" />
<asp:LinkButton ID="BtnAgregarProducto" runat="server" CssClass="btn blue" OnClick="AgregarProducto">
<i class="fa fa-plus" aria-hidden="true"></i> Agregar producto
</asp:LinkButton>
</div>
</ContentTemplate>
</asp:UpdatePanel>
</ContentTemplate>
</ajax:TabPanel>
<ajax:TabPanel ID="TabParcialidades" runat="server" HeaderText="Parcialidades">
<ContentTemplate>
<asp:UpdatePanel ID="UpParcialidades" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:GridView ID="GvParcialidades" runat="server" AutoGenerateColumns="false" GridLines="None"
CssClass="table table-striped table-hover Widthall" OnRowCommand="ParcialidadComando"
EmptyDataText="Agregue al menos una parcialidad con su vencimiento.">
<Columns>
<asp:BoundField DataField="NumeroParcialidad" HeaderText="Parcialidad" />
<asp:TemplateField HeaderText="Vencimiento">
<ItemTemplate>
<asp:TextBox ID="TxtVencimiento" runat="server" TextMode="Date" CssClass="form-control"
Text='<%# Convert.ToDateTime(Eval("FechaVencimiento")) == DateTime.MinValue ? "" : Convert.ToDateTime(Eval("FechaVencimiento")).ToString("yyyy-MM-dd") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Importe">
<ItemTemplate>
<asp:TextBox ID="TxtImporteParcialidad" runat="server" CssClass="form-control" MaxLength="24"
Text='<%# Convert.ToDecimal(Eval("Importe")).ToString("0.######", System.Globalization.CultureInfo.InvariantCulture) %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Prórroga opcional">
<ItemTemplate>
<asp:TextBox ID="TxtProrroga" runat="server" TextMode="Date" CssClass="form-control"
Text='<%# Eval("FechaProrroga") == null ? "" : Convert.ToDateTime(Eval("FechaProrroga")).ToString("yyyy-MM-dd") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:ButtonField CommandName="QuitarParcialidad" Text="Quitar"
ControlStyle-CssClass="btn btn-xs red" />
</Columns>
</asp:GridView>
<asp:LinkButton ID="BtnAgregarParcialidad" runat="server" CssClass="btn blue" OnClick="AgregarParcialidad">
<i class="fa fa-plus" aria-hidden="true"></i> Agregar parcialidad
</asp:LinkButton>
</ContentTemplate>
</asp:UpdatePanel>
</ContentTemplate>
</ajax:TabPanel>
<ajax:TabPanel ID="TabOrigen" runat="server" HeaderText="Saldo de origen">
<ContentTemplate>
<asp:UpdatePanel ID="UpOrigen" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<p>La propuesta toma el saldo por producto proporcionalmente y las parcialidades por vencimiento. Revise este desglose antes de guardar.</p>
<asp:GridView ID="GvOrigen" runat="server" AutoGenerateColumns="false" GridLines="None"
CssClass="table table-striped table-hover Widthall" EmptyDataText="No hay distribución de origen.">
<Columns>
<asp:BoundField DataField="Producto" HeaderText="Producto" />
<asp:BoundField DataField="Parcialidad" HeaderText="Parcialidad" />
<asp:BoundField DataField="Vencimiento" HeaderText="Vencimiento" DataFormatString="{0:dd/MM/yyyy}" />
<asp:BoundField DataField="ImporteTomadoConvenio" HeaderText="Saldo tomado" DataFormatString="{0:N6}" />
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
</ContentTemplate>
</ajax:TabPanel>
</ajax:TabContainer>
<asp:UpdatePanel ID="UpAcciones" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:LinkButton ID="BtnGuardar" runat="server" CssClass="btn blue" OnClick="Guardar">
<i class="fa fa-save" aria-hidden="true"></i> Guardar convenio
</asp:LinkButton>
<asp:LinkButton ID="BtnConfirmarCancelacion" runat="server" CssClass="btn red" OnClick="ConfirmarCancelacion">
<i class="fa fa-times" aria-hidden="true"></i> Cancelar convenio
</asp:LinkButton>
<asp:LinkButton ID="BtnCancelar" runat="server" CssClass="hidden" OnClick="Cancelar" />
</ContentTemplate>
</asp:UpdatePanel>
</asp:Panel>
<asp:UpdateProgress ID="AvanceGuardado" runat="server" DisplayAfter="250">
<ProgressTemplate><p>Procesando convenio...</p></ProgressTemplate>
</asp:UpdateProgress>
</asp:Content>
<asp:Content ID="ContenidoScripts" ContentPlaceHolderID="J" runat="server">
</asp:Content>

View File

@@ -1,583 +0,0 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Web;
using System.Web.UI.WebControls;
using SIG.Web.AppCode.Configuration;
using SIG.Web.AppCode.Infrastructure.WebForms;
using SIG.Web.AppCode.Models.Tramites;
using SIG.Web.AppCode.Security;
namespace SIG.Web.Pages.Desarrolladores
{
public partial class ConvenioDetalle : ClsPaginaBase
{
private ModeloObligacionPago AdeudoOrigen
{
get { return ViewState["AdeudoOrigen"] as ModeloObligacionPago; }
set { ViewState["AdeudoOrigen"] = value; }
}
private ModeloObligacionPago ConvenioActual
{
get { return ViewState["ConvenioActual"] as ModeloObligacionPago; }
set { ViewState["ConvenioActual"] = value; }
}
private List<ModeloCapturaProductoPago> Productos
{
get { return ViewState["Productos"] as List<ModeloCapturaProductoPago> ?? new List<ModeloCapturaProductoPago>(); }
set { ViewState["Productos"] = value; }
}
private List<ModeloCapturaParcialidadPago> Parcialidades
{
get { return ViewState["Parcialidades"] as List<ModeloCapturaParcialidadPago> ?? new List<ModeloCapturaParcialidadPago>(); }
set { ViewState["Parcialidades"] = value; }
}
private List<ModeloDetalleOrigenConvenio> DetallesOrigen
{
get { return ViewState["DetallesOrigen"] as List<ModeloDetalleOrigenConvenio> ?? new List<ModeloDetalleOrigenConvenio>(); }
set { ViewState["DetallesOrigen"] = value; }
}
protected void Page_Load(object origen, EventArgs argumentos)
{
if (CurrentUser.EsDesarrollador)
{
PnlCaptura.Visible = false;
Alert("La captura de convenios está disponible para usuarios administrativos.", TipoMensaje.MsgAdvertencia);
return;
}
if (!IsPostBack)
{
int clave;
if (int.TryParse(Request.QueryString["id"], out clave) && clave > 0)
{
CargarConvenio(clave);
}
else
{
CargarClientes();
if (int.TryParse(Request.QueryString["origen"], out clave) && clave > 0)
{
CargarOrigen(clave);
}
}
CargarProductosCatalogo();
EnlazarProductos();
EnlazarParcialidades();
}
BtnGuardar.Visible = TienePermiso(ConvenioActual == null ? "Convenios.Crear" : "Convenios.Modificar");
BtnConfirmarCancelacion.Visible = ConvenioActual != null && TienePermiso("Convenios.Cancelar");
}
private bool TienePermiso(string permiso)
{
return !CurrentUser.EsDesarrollador &&
AppServices.PermissionService.HasPermission(CurrentUser.CveUsuario, permiso);
}
private void CargarClientes()
{
var resultado = AppServices.ServicioPagosConvenios.ListarObligaciones(
new ModeloFiltroObligacionesPago { SoloPendientes = true, EstadoAdministrativo = "ACTIVO" },
CurrentUser.CveUsuario, CurrentUser.NombreDominio);
DdlCliente.Items.Clear();
DdlCliente.Items.Add(new ListItem("Seleccione cliente", ""));
DdlOrigen.Items.Clear();
DdlOrigen.Items.Add(new ListItem("Seleccione un adeudo", ""));
if (!resultado.Success)
{
Alert(resultado.UserMessage, TipoMensaje.MsgError);
return;
}
foreach (var grupo in resultado.Data.GroupBy(pago => pago.CveCliente).OrderBy(grupo => grupo.First().Cliente))
{
DdlCliente.Items.Add(new ListItem(grupo.First().Cliente, grupo.Key.ToString(CultureInfo.InvariantCulture)));
}
}
private void CargarProductosCatalogo()
{
var resultado = AppServices.ServicioProductoServicio.Listar(
"", false, CurrentUser.CveUsuario, CurrentUser.NombreDominio);
DdlProducto.Items.Clear();
DdlProducto.Items.Add(new ListItem("Seleccione producto", ""));
if (!resultado.Success)
{
Alert(resultado.UserMessage, TipoMensaje.MsgError);
return;
}
foreach (var producto in resultado.Data)
{
DdlProducto.Items.Add(new ListItem(producto.PS, producto.CvePS.ToString(CultureInfo.InvariantCulture)));
}
}
protected void CambiarCliente(object origen, EventArgs argumentos)
{
if (ConvenioActual != null)
{
return;
}
LimpiarOrigen();
int cliente;
if (int.TryParse(DdlCliente.SelectedValue, out cliente))
{
CargarAdeudosCliente(cliente);
}
}
private void CargarAdeudosCliente(int cliente)
{
DdlOrigen.Items.Clear();
DdlOrigen.Items.Add(new ListItem("Seleccione un adeudo", ""));
var resultado = AppServices.ServicioPagosConvenios.ListarObligaciones(
new ModeloFiltroObligacionesPago
{
CveCliente = cliente,
SoloPendientes = true,
EstadoAdministrativo = "ACTIVO"
}, CurrentUser.CveUsuario, CurrentUser.NombreDominio);
if (!resultado.Success)
{
Alert(resultado.UserMessage, TipoMensaje.MsgError);
return;
}
foreach (var pago in resultado.Data)
{
DdlOrigen.Items.Add(new ListItem(string.Format(CultureInfo.CurrentCulture,
"{0} / {1} · {2} · Saldo {3:N2} {4}", pago.Fraccionamiento, pago.Etapa,
pago.Descripcion, pago.SaldoPendiente, pago.UnidadCobro),
pago.CveSolicitudPago.ToString(CultureInfo.InvariantCulture)));
}
}
protected void CambiarOrigen(object origen, EventArgs argumentos)
{
if (ConvenioActual != null)
{
return;
}
LimpiarOrigen();
int clave;
if (int.TryParse(DdlOrigen.SelectedValue, out clave))
{
CargarOrigen(clave);
}
}
private void LimpiarOrigen()
{
AdeudoOrigen = null;
Productos = new List<ModeloCapturaProductoPago>();
Parcialidades = new List<ModeloCapturaParcialidadPago>();
DetallesOrigen = new List<ModeloDetalleOrigenConvenio>();
LitOrigen.Text = "";
TxtSaldoConvenido.Text = "";
TxtImporte.Text = "";
TxtDescripcion.Text = "";
EnlazarProductos();
EnlazarParcialidades();
MostrarOrigen();
}
private void CargarOrigen(int clave)
{
var resultado = AppServices.ServicioPagosConvenios.ObtenerObligacion(
clave, CurrentUser.CveUsuario, CurrentUser.NombreDominio);
if (!resultado.Success)
{
Alert(resultado.UserMessage, TipoMensaje.MsgError);
return;
}
var adeudo = resultado.Data;
if (adeudo.EstadoAdministrativo != "ACTIVO" || adeudo.SaldoPendiente <= 0)
{
Alert("Seleccione un adeudo activo con saldo pendiente.", TipoMensaje.MsgAdvertencia);
return;
}
AdeudoOrigen = adeudo;
var cliente = DdlCliente.Items.FindByValue(adeudo.CveCliente.ToString(CultureInfo.InvariantCulture));
if (cliente != null)
{
DdlCliente.SelectedValue = cliente.Value;
CargarAdeudosCliente(adeudo.CveCliente);
DdlOrigen.SelectedValue = clave.ToString(CultureInfo.InvariantCulture);
}
LitOrigen.Text = adeudo.Cliente + " · " + adeudo.Fraccionamiento + " / " + adeudo.Etapa +
" · Unidad: " + adeudo.UnidadCobro;
TxtDescripcion.Text = "Convenio de " + adeudo.Descripcion;
TxtSaldoConvenido.Text = adeudo.SaldoPendiente.ToString("0.######", CultureInfo.InvariantCulture);
TxtImporte.Text = TxtSaldoConvenido.Text;
UpCabecera.Update();
}
private void CargarConvenio(int clave)
{
var resultado = AppServices.ServicioPagosConvenios.ObtenerObligacion(
clave, CurrentUser.CveUsuario, CurrentUser.NombreDominio);
if (!resultado.Success || resultado.Data.Convenio == null)
{
PnlCaptura.Visible = false;
Alert(resultado.Success ? "El registro no corresponde a un convenio." : resultado.UserMessage, TipoMensaje.MsgAdvertencia);
return;
}
ConvenioActual = resultado.Data;
DetallesOrigen = ConvenioActual.DetallesOrigen;
Productos = ConvenioActual.Productos.Select(producto => new ModeloCapturaProductoPago
{
CvePS = producto.CvePS,
Descripcion = producto.Descripcion,
Cantidad = producto.Cantidad,
PrecioUnitario = producto.PrecioUnitario,
Importe = producto.Importe
}).ToList();
Parcialidades = ConvenioActual.Parcialidades.Select(parcialidad => new ModeloCapturaParcialidadPago
{
NumeroParcialidad = parcialidad.NumeroParcialidad,
FechaVencimiento = parcialidad.FechaVencimiento,
FechaProrroga = parcialidad.FechaProrroga,
Importe = parcialidad.Importe
}).ToList();
TxtDescripcion.Text = ConvenioActual.Descripcion;
TxtObservaciones.Text = ConvenioActual.Convenio.Observaciones;
TxtImporte.Text = ConvenioActual.Importe.ToString("0.######", CultureInfo.InvariantCulture);
TxtSaldoConvenido.Text = ConvenioActual.Convenio.ImporteSaldoConvenido.ToString(
"0.######", CultureInfo.InvariantCulture);
TxtSaldoConvenido.ReadOnly = true;
PnlSeleccionOrigen.Visible = false;
BtnSugerir.Visible = false;
ChkRequerido.Checked = ConvenioActual.EsRequerido;
ChkRequerido.Visible = false;
LitOrigen.Text = ConvenioActual.Cliente + " · " + ConvenioActual.Fraccionamiento +
" / " + ConvenioActual.Etapa + " · Unidad: " + ConvenioActual.UnidadCobro +
" · " + ConvenioActual.EstadoAdministrativo +
(ConvenioActual.EsRequerido ? " · Pago requerido" : " · Pago opcional") +
". Se conserva el saldo de origen; el cambio de requerido se realiza desde el detalle del pago.";
MostrarOrigen();
}
protected void SugerirDistribucion(object origen, EventArgs argumentos)
{
try
{
if (ConvenioActual != null)
{
return;
}
if (AdeudoOrigen == null)
{
throw new FormatException("Seleccione el adeudo origen.");
}
decimal importe = LeerImporte(TxtImporte.Text);
decimal saldo = LeerImporte(TxtSaldoConvenido.Text);
ValidarImporteConvenio(importe, saldo);
var propuesta = AppServices.ServicioPagosConvenios.PrepararDistribucionConvenio(
AdeudoOrigen.CveSolicitudPago, saldo, importe,
CurrentUser.CveUsuario, CurrentUser.NombreDominio);
if (!propuesta.Success)
{
Alert(propuesta.UserMessage, TipoMensaje.MsgAdvertencia);
return;
}
Productos = propuesta.Data.Productos.Select(producto => new ModeloCapturaProductoPago
{
CvePS = producto.CvePS,
Descripcion = producto.Descripcion,
Cantidad = 1,
PrecioUnitario = producto.ImportePropuesto,
Importe = producto.ImportePropuesto
}).ToList();
DetallesOrigen = propuesta.Data.Origenes;
EnlazarProductos();
MostrarOrigen();
Alert("Distribución sugerida. Revise los productos, el saldo de origen y las parcialidades antes de guardar.",
TipoMensaje.ToastExito);
}
catch (FormatException error)
{
Alert(error.Message, TipoMensaje.MsgAdvertencia);
}
}
private void MostrarOrigen()
{
GvOrigen.DataSource = DetallesOrigen;
GvOrigen.DataBind();
UpOrigen.Update();
}
private void EnlazarProductos()
{
GvProductos.DataSource = Productos;
GvProductos.DataBind();
UpProductos.Update();
}
private void EnlazarParcialidades()
{
GvParcialidades.DataSource = Parcialidades;
GvParcialidades.DataBind();
UpParcialidades.Update();
}
private List<ModeloCapturaProductoPago> LeerProductos()
{
var productos = Productos;
for (int indice = 0; indice < GvProductos.Rows.Count; indice++)
{
decimal importe = LeerImporte(((TextBox)GvProductos.Rows[indice].FindControl("TxtImporteProducto")).Text);
if (productos[indice].Importe != importe)
{
productos[indice].Importe = importe;
productos[indice].Cantidad = 1;
productos[indice].PrecioUnitario = importe;
}
}
return productos;
}
private List<ModeloCapturaParcialidadPago> LeerParcialidades()
{
var parcialidades = new List<ModeloCapturaParcialidadPago>();
foreach (GridViewRow fila in GvParcialidades.Rows)
{
DateTime vencimiento = LeerFecha(((TextBox)fila.FindControl("TxtVencimiento")).Text);
string prorroga = ((TextBox)fila.FindControl("TxtProrroga")).Text;
var parcialidad = new ModeloCapturaParcialidadPago
{
NumeroParcialidad = fila.RowIndex + 1,
FechaVencimiento = vencimiento,
Importe = LeerImporte(((TextBox)fila.FindControl("TxtImporteParcialidad")).Text),
FechaProrroga = string.IsNullOrEmpty(prorroga) ? (DateTime?)null : LeerFecha(prorroga)
};
if (parcialidad.FechaProrroga < vencimiento)
{
throw new FormatException("La prórroga no puede ser anterior al vencimiento.");
}
parcialidades.Add(parcialidad);
}
return parcialidades;
}
protected void AgregarProducto(object origen, EventArgs argumentos)
{
try
{
var productos = LeerProductos();
int clave;
if (!int.TryParse(DdlProducto.SelectedValue, out clave))
{
throw new FormatException("Seleccione un producto del catálogo.");
}
if (productos.Any(producto => producto.CvePS == clave))
{
throw new FormatException("El producto ya está agregado; ajuste su importe.");
}
productos.Add(new ModeloCapturaProductoPago
{
CvePS = clave,
Descripcion = DdlProducto.SelectedItem.Text,
Cantidad = 1
});
Productos = productos;
EnlazarProductos();
}
catch (FormatException error)
{
Alert(error.Message, TipoMensaje.MsgAdvertencia);
}
}
protected void ProductoComando(object origen, GridViewCommandEventArgs argumentos)
{
if (argumentos.CommandName != "QuitarProducto")
{
return;
}
try
{
var productos = LeerProductos();
int indice = Convert.ToInt32(argumentos.CommandArgument, CultureInfo.InvariantCulture);
if (indice >= 0 && indice < productos.Count)
{
productos.RemoveAt(indice);
Productos = productos;
EnlazarProductos();
}
}
catch (FormatException error)
{
Alert(error.Message, TipoMensaje.MsgAdvertencia);
}
}
protected void AgregarParcialidad(object origen, EventArgs argumentos)
{
try
{
var parcialidades = LeerParcialidades();
parcialidades.Add(new ModeloCapturaParcialidadPago
{
NumeroParcialidad = parcialidades.Count + 1,
FechaVencimiento = DateTime.MinValue
});
Parcialidades = parcialidades;
EnlazarParcialidades();
}
catch (FormatException error)
{
Alert(error.Message, TipoMensaje.MsgAdvertencia);
}
}
protected void ParcialidadComando(object origen, GridViewCommandEventArgs argumentos)
{
if (argumentos.CommandName != "QuitarParcialidad")
{
return;
}
try
{
var parcialidades = LeerParcialidades();
int indice = Convert.ToInt32(argumentos.CommandArgument, CultureInfo.InvariantCulture);
if (indice >= 0 && indice < parcialidades.Count)
{
parcialidades.RemoveAt(indice);
for (int numero = 0; numero < parcialidades.Count; numero++)
{
parcialidades[numero].NumeroParcialidad = numero + 1;
}
Parcialidades = parcialidades;
EnlazarParcialidades();
}
}
catch (FormatException error)
{
Alert(error.Message, TipoMensaje.MsgAdvertencia);
}
}
internal static decimal LeerImporte(string texto)
{
decimal importe;
string normalizado = (texto ?? "").Trim().Replace(',', '.');
if (!decimal.TryParse(normalizado, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out importe) ||
importe < 0 || importe > 9999999999999.999999m || decimal.Round(importe, 6) != importe)
{
throw new FormatException("Capture un importe válido, sin separadores de miles y con hasta seis decimales.");
}
return importe;
}
private static DateTime LeerFecha(string texto)
{
DateTime fecha;
if (!DateTime.TryParseExact(texto, "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out fecha))
{
throw new FormatException("Capture una fecha de vencimiento válida.");
}
return fecha;
}
private void ValidarImporteConvenio(decimal importe, decimal saldo)
{
if (importe < saldo && !TienePermiso("Convenios.DisminuirImporte"))
{
throw new FormatException("El importe del convenio no puede ser menor al saldo seleccionado.");
}
}
protected void Guardar(object origen, EventArgs argumentos)
{
try
{
var contexto = ConvenioActual ?? AdeudoOrigen;
if (contexto == null)
{
throw new FormatException("Seleccione un adeudo.");
}
decimal importe = LeerImporte(TxtImporte.Text);
decimal saldo = LeerImporte(TxtSaldoConvenido.Text);
ValidarImporteConvenio(importe, saldo);
if (DetallesOrigen.Count == 0 || DetallesOrigen.Sum(detalle => detalle.ImporteTomadoConvenio) != saldo)
{
throw new FormatException("Sugiera nuevamente la distribución del saldo de origen y revísela antes de guardar.");
}
var captura = new ModeloCapturaConvenio
{
Obligacion = new ModeloCapturaObligacion
{
CveSolicitudPago = ConvenioActual == null ? (int?)null : ConvenioActual.CveSolicitudPago,
CveCliente = contexto.CveCliente,
CveFraccionamiento = contexto.CveFraccionamiento,
CveFraccionamientoEtapa = contexto.CveFraccionamientoEtapa,
CveUnidadCobro = contexto.CveUnidadCobro,
Descripcion = TxtDescripcion.Text.Trim(),
Importe = importe,
EsRequerido = ConvenioActual == null ? ChkRequerido.Checked : ConvenioActual.EsRequerido,
FechaGeneracion = ConvenioActual == null ? DateTime.Now : ConvenioActual.FechaGeneracion,
Productos = LeerProductos(),
Parcialidades = LeerParcialidades()
},
Observaciones = TxtObservaciones.Text.Trim(),
Origenes = DetallesOrigen.Select(detalle => new ModeloCapturaOrigenConvenio
{
CveSolicitudPagoOrigen = detalle.CveSolicitudPagoOrigen,
CveSolicitudPagoDetalleOrigen = detalle.CveSolicitudPagoDetalleOrigen,
CveSolicitudPagoParcialidadOrigen = detalle.CveSolicitudPagoParcialidadOrigen,
ImporteTomadoConvenio = detalle.ImporteTomadoConvenio
}).ToList()
};
var resultado = AppServices.ServicioPagosConvenios.GuardarConvenio(
captura, CurrentUser.CveUsuario, CurrentUser.NombreDominio);
if (!resultado.Success)
{
Alert(resultado.UserMessage, TipoMensaje.MsgAdvertencia);
return;
}
AlertNextRequest("Convenio guardado correctamente.", TipoMensaje.ToastExito);
RegistraScript("SIGPagosConvenios.salirGuardado('" +
HttpUtility.JavaScriptStringEncode(ResolveUrl("~/Pages/Desarrolladores/PagoDetalle.aspx?id=" +
resultado.Data.ToString(CultureInfo.InvariantCulture))) + "');");
}
catch (FormatException error)
{
Alert(error.Message, TipoMensaje.MsgAdvertencia);
}
}
protected void ConfirmarCancelacion(object origen, EventArgs argumentos)
{
if (ConvenioActual == null || !TienePermiso("Convenios.Cancelar"))
{
Alert("No hay un convenio disponible para cancelar.", TipoMensaje.MsgAdvertencia);
return;
}
Alert("Se cancelará el convenio y se liberará su saldo de origen si no tiene movimientos que lo impidan. ¿Desea continuar?",
TipoMensaje.MsgConfirmacion, "__doPostBack('" + HttpUtility.JavaScriptStringEncode(BtnCancelar.UniqueID) + "','');");
}
protected void Cancelar(object origen, EventArgs argumentos)
{
if (ConvenioActual == null)
{
return;
}
var resultado = AppServices.ServicioPagosConvenios.CancelarConvenio(
ConvenioActual.CveSolicitudPago, CurrentUser.CveUsuario, CurrentUser.NombreDominio);
if (!resultado.Success)
{
Alert(resultado.UserMessage, TipoMensaje.MsgAdvertencia);
return;
}
AlertNextRequest("Convenio cancelado.", TipoMensaje.ToastExito);
RegistraScript("SIGPagosConvenios.salirGuardado('" +
HttpUtility.JavaScriptStringEncode(ResolveUrl("~/Pages/Desarrolladores/Convenios.aspx")) + "');");
}
}
}

View File

@@ -1,78 +1,31 @@
<%@ Page Title="Convenios" Language="C#" MasterPageFile="~/Site.master" <%@ Page Title="Convenios" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="Convenios.aspx.cs" Inherits="SIG.Web.Pages.Desarrolladores.Convenios" %>
AutoEventWireup="true" CodeFile="Convenios.aspx.cs" Inherits="SIG.Web.Pages.Desarrolladores.Convenios" %> <%@ Register TagPrefix="convenios" TagName="Listado" Src="~/UserControl/ConveniosListado.ascx" %>
<asp:Content ID="ContenidoEncabezado" ContentPlaceHolderID="H" runat="server"> <asp:Content ID="ContenidoEncabezado" ContentPlaceHolderID="H" runat="server"></asp:Content>
</asp:Content>
<asp:Content ID="ContenidoAcciones" ContentPlaceHolderID="A" runat="server">
<li>
<asp:HyperLink ID="LnkNuevoConvenio" runat="server" NavigateUrl="~/Pages/Desarrolladores/ConvenioDetalle.aspx">
<i class="fa fa-plus" aria-hidden="true"></i> Agregar convenio
</asp:HyperLink>
</li>
</asp:Content>
<asp:Content ID="ContenidoPrincipal" ContentPlaceHolderID="C" runat="server"> <asp:Content ID="ContenidoPrincipal" ContentPlaceHolderID="C" runat="server">
<asp:UpdatePanel ID="UpBarraFiltros" runat="server" UpdateMode="Conditional"> <asp:UpdatePanel ID="UpBarraFiltros" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="true">
<ContentTemplate> <ContentTemplate>
<sig:Filtros ID="FiltrosListado" runat="server" OnConsultar="Consultar" <sig:Filtros ID="FiltrosListado" runat="server" OnConsultar="Consultar" OnMostrarFiltros="MostrarFiltros" OnFiltrosChanged="QuitarFiltros" />
OnMostrarFiltros="MostrarFiltros" OnFiltrosChanged="QuitarFiltros" />
</ContentTemplate> </ContentTemplate>
</asp:UpdatePanel> </asp:UpdatePanel>
<ajax:TabContainer ID="PestanasPagos" runat="server" ActiveTabIndex="0" <convenios:Listado ID="UcConvenios" runat="server" OnCambiado="ConveniosCambiados" />
AutoPostBack="true" OnActiveTabChanged="Consultar" Width="100%"> <div id="ModalFiltrosConvenios" class="modal fade" tabindex="-1" role="dialog" aria-label="Filtros de convenios">
<ajax:TabPanel ID="TabPendientes" runat="server" HeaderText="Pendientes">
<ContentTemplate>
<sig:PagosSolicitud ID="PagosPendientes" runat="server" OnCambiado="Consultar" />
</ContentTemplate>
</ajax:TabPanel>
<ajax:TabPanel ID="TabHistorico" runat="server" HeaderText="Histórico">
<ContentTemplate>
<p>Obligaciones sin saldo pendiente y canceladas. El saldo convenido se muestra separado de lo abonado.</p>
<sig:PagosSolicitud ID="PagosHistorico" runat="server" OnCambiado="Consultar" />
</ContentTemplate>
</ajax:TabPanel>
</ajax:TabContainer>
<asp:UpdateProgress ID="AvanceConsulta" runat="server" DisplayAfter="250">
<ProgressTemplate><p>Consultando...</p></ProgressTemplate>
</asp:UpdateProgress>
<div id="ModalFiltrosPagos" class="modal fade" tabindex="-1" role="dialog" aria-label="Filtros de pagos">
<div class="modal-dialog"> <div class="modal-dialog">
<asp:UpdatePanel ID="UpFiltros" runat="server" UpdateMode="Conditional"> <asp:UpdatePanel ID="UpFiltros" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="true">
<ContentTemplate> <ContentTemplate>
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-label="Cerrar">&times;</button><h4>Filtros</h4></div>
<button type="button" class="close" data-dismiss="modal" aria-label="Cerrar">&times;</button>
<h4>Filtros</h4>
</div>
<div class="modal-body"> <div class="modal-body">
<asp:Label runat="server" AssociatedControlID="DdlCliente" Text="Cliente" /> <div class="form-group"><asp:Label runat="server" AssociatedControlID="DdlCliente" Text="Desarrollador" /><asp:DropDownList ID="DdlCliente" runat="server" CssClass="form-control select2me" /></div>
<asp:DropDownList ID="DdlCliente" runat="server" CssClass="form-control select2me" /> <div class="form-group"><asp:Label runat="server" AssociatedControlID="DdlFraccionamiento" Text="Fraccionamiento" /><asp:DropDownList ID="DdlFraccionamiento" runat="server" CssClass="form-control select2me" /></div>
<asp:Label runat="server" AssociatedControlID="DdlFraccionamiento" Text="Fraccionamiento" /> <div class="form-group"><asp:Label runat="server" AssociatedControlID="DdlEtapa" Text="Etapa" /><asp:DropDownList ID="DdlEtapa" runat="server" CssClass="form-control select2me" /></div>
<asp:DropDownList ID="DdlFraccionamiento" runat="server" CssClass="form-control select2me" /> <div class="form-group"><asp:Label runat="server" AssociatedControlID="DdlEstatus" Text="Estado" /><asp:DropDownList ID="DdlEstatus" runat="server" CssClass="form-control select2me"><asp:ListItem Value="" Text="Todos" /><asp:ListItem Value="ACTIVO" Text="Activo" /><asp:ListItem Value="LIQUIDADO" Text="Liquidado" /><asp:ListItem Value="SUSTITUIDO" Text="Sustituido" /><asp:ListItem Value="CANCELADO" Text="Cancelado" /></asp:DropDownList></div>
<asp:Label runat="server" AssociatedControlID="DdlTramite" Text="Trámite" /> <div class="form-group"><asp:DropDownList ID="DdlSaldo" runat="server" CssClass="form-control"><asp:ListItem Value="" Text="Con o sin saldo" /><asp:ListItem Value="1" Text="Con saldo pendiente" /><asp:ListItem Value="0" Text="Sin saldo pendiente" /></asp:DropDownList></div>
<asp:DropDownList ID="DdlTramite" runat="server" CssClass="form-control select2me" />
<asp:Label runat="server" AssociatedControlID="DdlEstado" Text="Estado administrativo" />
<asp:DropDownList ID="DdlEstado" runat="server" CssClass="form-control select2me">
<asp:ListItem Value="" Text="Todos" />
<asp:ListItem Value="ACTIVO" Text="Activo" />
<asp:ListItem Value="CANCELADO" Text="Cancelado" />
</asp:DropDownList>
<asp:Label runat="server" AssociatedControlID="TxtDesde" Text="Generación desde" />
<asp:TextBox ID="TxtDesde" runat="server" TextMode="Date" CssClass="form-control" />
<asp:Label runat="server" AssociatedControlID="TxtHasta" Text="Generación hasta" />
<asp:TextBox ID="TxtHasta" runat="server" TextMode="Date" CssClass="form-control" />
<asp:CheckBox ID="ChkVencidos" runat="server" Text=" Sólo vencidos" />
</div>
<div class="modal-footer">
<button type="button" class="btn default" data-dismiss="modal">Cancelar</button>
<asp:Button ID="BtnFiltrar" runat="server" Text="Aplicar filtros"
CssClass="btn blue" OnClick="AplicarFiltros" />
</div> </div>
<div class="modal-footer"><button type="button" class="btn default" data-dismiss="modal">Cancelar</button><asp:Button ID="BtnFiltrar" runat="server" Text="Aplicar filtros" CssClass="btn blue" OnClick="AplicarFiltros" /></div>
</div> </div>
</ContentTemplate> </ContentTemplate>
</asp:UpdatePanel> </asp:UpdatePanel>
</div> </div>
</div> </div>
</asp:Content> </asp:Content>
<asp:Content ID="ContenidoScripts" ContentPlaceHolderID="J" runat="server"> <asp:Content ID="ContenidoScripts" ContentPlaceHolderID="J" runat="server"></asp:Content>
</asp:Content>

View File

@@ -5,7 +5,7 @@ using System.Linq;
using System.Web.UI.WebControls; using System.Web.UI.WebControls;
using SIG.Web.AppCode.Configuration; using SIG.Web.AppCode.Configuration;
using SIG.Web.AppCode.Infrastructure.WebForms; using SIG.Web.AppCode.Infrastructure.WebForms;
using SIG.Web.AppCode.Models.Tramites; using SIG.Web.AppCode.Models.Convenios;
using SIG.Web.AppCode.Security; using SIG.Web.AppCode.Security;
using SIG.Web.AppCode.SigControls; using SIG.Web.AppCode.SigControls;
@@ -13,171 +13,63 @@ namespace SIG.Web.Pages.Desarrolladores
{ {
public partial class Convenios : ClsPaginaBase public partial class Convenios : ClsPaginaBase
{ {
private ModeloFiltroObligacionesPago FiltroActual private FiltroConvenios FiltroActual { get { return ViewState["FiltroActual"] as FiltroConvenios ?? new FiltroConvenios(); } set { ViewState["FiltroActual"] = value; } }
{
get { return ViewState["FiltroActual"] as ModeloFiltroObligacionesPago ?? new ModeloFiltroObligacionesPago(); }
set { ViewState["FiltroActual"] = value; }
}
protected void Page_Load(object origen, EventArgs argumentos) protected void Page_Load(object origen, EventArgs argumentos)
{ {
if (!IsPostBack) if (!IsPostBack) { CargarOpciones(); Consultar(origen, argumentos); }
{
CargarOpciones();
Consultar(origen, argumentos);
}
LnkNuevoConvenio.Visible = !CurrentUser.EsDesarrollador &&
AppServices.PermissionService.HasPermission(CurrentUser.CveUsuario, "Convenios.Crear");
} }
private void CargarOpciones() private void CargarOpciones()
{ {
var resultado = AppServices.ServicioPagosConvenios.ListarConvenios(null, null, false, var resultado = AppServices.ServicioConvenios.Listar(new FiltroConvenios(), CurrentUser.CveUsuario, CurrentUser.NombreDominio);
CurrentUser.CveUsuario, CurrentUser.NombreDominio); var datos = resultado.Success ? resultado.Data : new List<ConvenioListado>();
var obligaciones = resultado.Success ? resultado.Data : new List<ModeloObligacionPago>(); Llenar(DdlCliente, datos.GroupBy(x => x.CveCliente).Select(x => new ListItem(x.First().Cliente, x.Key.ToString(CultureInfo.InvariantCulture))));
if (!resultado.Success) Llenar(DdlFraccionamiento, datos.GroupBy(x => x.CveFraccionamiento).Select(x => new ListItem(x.First().Fraccionamiento, x.Key.ToString(CultureInfo.InvariantCulture))));
{ Llenar(DdlEtapa, datos.GroupBy(x => x.CveFraccionamientoEtapa).Select(x => new ListItem(x.First().Fraccionamiento + " · " + x.First().Etapa, x.Key.ToString(CultureInfo.InvariantCulture))));
Alert(resultado.UserMessage, TipoMensaje.MsgError); if (!resultado.Success) Alert(resultado.UserMessage, TipoMensaje.MsgError);
}
LlenarOpciones(DdlCliente, obligaciones.GroupBy(pago => pago.CveCliente)
.Select(grupo => new ListItem(grupo.First().Cliente, grupo.Key.ToString(CultureInfo.InvariantCulture))));
LlenarOpciones(DdlFraccionamiento, obligaciones.GroupBy(pago => pago.CveFraccionamiento)
.Select(grupo => new ListItem(grupo.First().Fraccionamiento, grupo.Key.ToString(CultureInfo.InvariantCulture))));
LlenarOpciones(DdlTramite, obligaciones.Where(pago => pago.CveTipoTramite.HasValue)
.GroupBy(pago => pago.CveTipoTramite.Value)
.Select(grupo => new ListItem(grupo.First().TipoTramite, grupo.Key.ToString(CultureInfo.InvariantCulture))));
} }
private static void LlenarOpciones(DropDownList lista, IEnumerable<ListItem> opciones) private static void Llenar(DropDownList lista, IEnumerable<ListItem> opciones)
{ {
lista.Items.Clear(); lista.Items.Clear(); lista.Items.Add(new ListItem("Todos", ""));
lista.Items.Add(new ListItem("Todos", "")); foreach (var opcion in opciones.OrderBy(x => x.Text)) lista.Items.Add(opcion);
foreach (var opcion in opciones.OrderBy(opcion => opcion.Text))
{
lista.Items.Add(opcion);
}
} }
protected void Consultar(object origen, EventArgs argumentos) protected void Consultar(object origen, EventArgs argumentos) { UcConvenios.Cargar(FiltroActual); MostrarFiltrosActivos(); }
{ protected void ConveniosCambiados(object origen, EventArgs argumentos) { CargarOpciones(); MostrarFiltrosActivos(); }
var filtro = FiltroActual;
filtro.SoloPendientes = null;
var resultado = AppServices.ServicioPagosConvenios.ListarConvenios(
filtro.CveCliente, filtro.SoloPendientes, filtro.SoloVencidos,
CurrentUser.CveUsuario, CurrentUser.NombreDominio);
var pagos = resultado.Success ? resultado.Data : new List<ModeloObligacionPago>();
pagos = pagos.Where(pago =>
((PestanasPagos.ActiveTabIndex == 0) ==
(pago.SaldoPendiente > 0 && pago.EstadoAdministrativo == "ACTIVO")) &&
(!filtro.CveFraccionamiento.HasValue || pago.CveFraccionamiento == filtro.CveFraccionamiento) &&
(!filtro.CveTipoTramite.HasValue || pago.CveTipoTramite == filtro.CveTipoTramite) &&
(string.IsNullOrEmpty(filtro.EstadoAdministrativo) || pago.EstadoAdministrativo == filtro.EstadoAdministrativo) &&
(!filtro.Desde.HasValue || pago.FechaGeneracion.Date >= filtro.Desde.Value) &&
(!filtro.Hasta.HasValue || pago.FechaGeneracion.Date <= filtro.Hasta.Value)).ToList();
var listado = PestanasPagos.ActiveTabIndex == 0 ? PagosPendientes : PagosHistorico;
listado.PermitirCambioRequerido = false;
listado.Mostrar(pagos);
if (!resultado.Success)
{
Alert(resultado.UserMessage, TipoMensaje.MsgError);
}
MostrarFiltrosActivos();
}
protected void MostrarFiltros(object origen, EventArgs argumentos) protected void MostrarFiltros(object origen, EventArgs argumentos)
{ {
var filtro = FiltroActual; var f = FiltroActual;
DdlCliente.SelectedValue = Convert.ToString(filtro.CveCliente, CultureInfo.InvariantCulture); DdlCliente.SelectedValue = Valor(f.CveCliente); DdlFraccionamiento.SelectedValue = Valor(f.CveFraccionamiento); DdlEtapa.SelectedValue = Valor(f.CveFraccionamientoEtapa); DdlEstatus.SelectedValue = f.Estatus ?? ""; DdlSaldo.SelectedValue = f.ConSaldoPendiente.HasValue ? (f.ConSaldoPendiente.Value ? "1" : "0") : "";
DdlFraccionamiento.SelectedValue = Convert.ToString(filtro.CveFraccionamiento, CultureInfo.InvariantCulture); UpFiltros.Update(); RegistraScript("SIGConvenios.mostrarModal('ModalFiltrosConvenios');");
DdlTramite.SelectedValue = Convert.ToString(filtro.CveTipoTramite, CultureInfo.InvariantCulture);
DdlEstado.SelectedValue = filtro.EstadoAdministrativo ?? "";
TxtDesde.Text = filtro.Desde.HasValue ? filtro.Desde.Value.ToString("yyyy-MM-dd") : "";
TxtHasta.Text = filtro.Hasta.HasValue ? filtro.Hasta.Value.ToString("yyyy-MM-dd") : "";
ChkVencidos.Checked = filtro.SoloVencidos;
UpFiltros.Update();
RegistraScript("SIGPagosConvenios.mostrarModal('ModalFiltrosPagos');");
} }
protected void AplicarFiltros(object origen, EventArgs argumentos) protected void AplicarFiltros(object origen, EventArgs argumentos)
{ {
DateTime desde; FiltroActual = new FiltroConvenios { CveCliente = Clave(DdlCliente), CveFraccionamiento = Clave(DdlFraccionamiento), CveFraccionamientoEtapa = Clave(DdlEtapa), Estatus = DdlEstatus.SelectedValue, ConSaldoPendiente = DdlSaldo.SelectedValue == "" ? (bool?)null : DdlSaldo.SelectedValue == "1" };
DateTime hasta; Consultar(origen, argumentos); RegistraScript("SIGConvenios.ocultarModal('ModalFiltrosConvenios');");
if ((!string.IsNullOrEmpty(TxtDesde.Text) && !DateTime.TryParseExact(TxtDesde.Text, "yyyy-MM-dd",
CultureInfo.InvariantCulture, DateTimeStyles.None, out desde)) ||
(!string.IsNullOrEmpty(TxtHasta.Text) && !DateTime.TryParseExact(TxtHasta.Text, "yyyy-MM-dd",
CultureInfo.InvariantCulture, DateTimeStyles.None, out hasta)))
{
Alert("Revise las fechas de los filtros.", TipoMensaje.MsgAdvertencia);
return;
}
var filtro = new ModeloFiltroObligacionesPago
{
CveCliente = Clave(DdlCliente),
CveFraccionamiento = Clave(DdlFraccionamiento),
CveTipoTramite = Clave(DdlTramite),
EstadoAdministrativo = DdlEstado.SelectedValue,
SoloVencidos = ChkVencidos.Checked,
Desde = string.IsNullOrEmpty(TxtDesde.Text) ? (DateTime?)null : DateTime.ParseExact(TxtDesde.Text, "yyyy-MM-dd", CultureInfo.InvariantCulture),
Hasta = string.IsNullOrEmpty(TxtHasta.Text) ? (DateTime?)null : DateTime.ParseExact(TxtHasta.Text, "yyyy-MM-dd", CultureInfo.InvariantCulture)
};
if (filtro.Desde > filtro.Hasta)
{
Alert("La fecha inicial no puede ser posterior a la final.", TipoMensaje.MsgAdvertencia);
return;
}
FiltroActual = filtro;
Consultar(origen, argumentos);
RegistraScript("SIGPagosConvenios.ocultarModal('ModalFiltrosPagos');");
}
private static int? Clave(DropDownList lista)
{
int clave;
return int.TryParse(lista.SelectedValue, out clave) && clave > 0 ? (int?)clave : null;
} }
protected void QuitarFiltros(object origen, EventArgs argumentos) protected void QuitarFiltros(object origen, EventArgs argumentos)
{ {
var nombres = new HashSet<string>(FiltrosListado.GetFiltros().Select(filtro => filtro.Nombre)); var nombres = new HashSet<string>(FiltrosListado.GetFiltros().Select(x => x.Nombre)); var f = FiltroActual;
var filtroActual = FiltroActual; if (!nombres.Contains("Cliente")) f.CveCliente = null; if (!nombres.Contains("Fraccionamiento")) f.CveFraccionamiento = null; if (!nombres.Contains("Etapa")) f.CveFraccionamientoEtapa = null; if (!nombres.Contains("Estatus")) f.Estatus = null; if (!nombres.Contains("Saldo")) f.ConSaldoPendiente = null;
if (!nombres.Contains("Cliente")) { filtroActual.CveCliente = null; } FiltroActual = f; Consultar(origen, argumentos);
if (!nombres.Contains("Fraccionamiento")) { filtroActual.CveFraccionamiento = null; }
if (!nombres.Contains("Tramite")) { filtroActual.CveTipoTramite = null; }
if (!nombres.Contains("Estado")) { filtroActual.EstadoAdministrativo = null; }
if (!nombres.Contains("Desde")) { filtroActual.Desde = null; }
if (!nombres.Contains("Hasta")) { filtroActual.Hasta = null; }
filtroActual.SoloVencidos = nombres.Contains("Vencidos");
FiltroActual = filtroActual;
Consultar(origen, argumentos);
} }
private void MostrarFiltrosActivos() private void MostrarFiltrosActivos()
{ {
var filtro = FiltroActual; var f = FiltroActual; var activos = new List<FiltroActivo>();
var activos = new List<FiltroActivo>(); Agregar(activos, "Cliente", Texto(DdlCliente, f.CveCliente)); Agregar(activos, "Fraccionamiento", Texto(DdlFraccionamiento, f.CveFraccionamiento)); Agregar(activos, "Etapa", Texto(DdlEtapa, f.CveFraccionamientoEtapa)); Agregar(activos, "Estatus", f.Estatus); Agregar(activos, "Saldo", f.ConSaldoPendiente.HasValue ? (f.ConSaldoPendiente.Value ? "Con saldo pendiente" : "Sin saldo pendiente") : null);
AgregarFiltro(activos, "Cliente", filtro.CveCliente.HasValue ? DdlCliente.Items.FindByValue(filtro.CveCliente.Value.ToString()).Text : null); FiltrosListado.SetFiltros(activos); UpBarraFiltros.Update();
AgregarFiltro(activos, "Fraccionamiento", filtro.CveFraccionamiento.HasValue ? DdlFraccionamiento.Items.FindByValue(filtro.CveFraccionamiento.Value.ToString()).Text : null);
AgregarFiltro(activos, "Tramite", filtro.CveTipoTramite.HasValue ? DdlTramite.Items.FindByValue(filtro.CveTipoTramite.Value.ToString()).Text : null);
AgregarFiltro(activos, "Estado", filtro.EstadoAdministrativo);
AgregarFiltro(activos, "Desde", filtro.Desde.HasValue ? filtro.Desde.Value.ToString("dd/MM/yyyy") : null);
AgregarFiltro(activos, "Hasta", filtro.Hasta.HasValue ? filtro.Hasta.Value.ToString("dd/MM/yyyy") : null);
AgregarFiltro(activos, "Vencidos", filtro.SoloVencidos ? "Sólo vencidos" : null);
FiltrosListado.SetFiltros(activos);
UpBarraFiltros.Update();
} }
private static void AgregarFiltro(List<FiltroActivo> filtros, string nombre, string descripcion) private static void Agregar(List<FiltroActivo> lista, string nombre, string descripcion) { if (!string.IsNullOrWhiteSpace(descripcion)) lista.Add(new FiltroActivo { Nombre = nombre, Titulo = nombre, Descripcion = descripcion, Orden = lista.Count }); }
{ private static string Texto(DropDownList lista, int? valor) { if (!valor.HasValue) return null; var item = lista.Items.FindByValue(valor.Value.ToString(CultureInfo.InvariantCulture)); return item == null ? null : item.Text; }
if (!string.IsNullOrWhiteSpace(descripcion)) private static int? Clave(DropDownList lista) { int valor; return int.TryParse(lista.SelectedValue, out valor) && valor > 0 ? (int?)valor : null; }
{ private static string Valor(int? valor) { return valor.HasValue ? valor.Value.ToString(CultureInfo.InvariantCulture) : ""; }
filtros.Add(new FiltroActivo private void RegistraScript(string script) { PageScriptRegistrar.RegistraScript(Page, script); }
{
Nombre = nombre,
Titulo = nombre == "Tramite" ? "Trámite" : nombre,
Descripcion = descripcion,
Orden = filtros.Count
});
}
}
} }
} }

View File

@@ -3,6 +3,7 @@
Inherits="SIG.Web.Pages.Desarrolladores.DesarrolladorDetalle" %> Inherits="SIG.Web.Pages.Desarrolladores.DesarrolladorDetalle" %>
<%@ Register TagPrefix="sig" TagName="CapturaEtapas" Src="~/UserControl/CapturaEtapas.ascx" %> <%@ Register TagPrefix="sig" TagName="CapturaEtapas" Src="~/UserControl/CapturaEtapas.ascx" %>
<%@ Register TagPrefix="sig" TagName="DetalleEtapa" Src="~/UserControl/DetalleEtapa.ascx" %> <%@ Register TagPrefix="sig" TagName="DetalleEtapa" Src="~/UserControl/DetalleEtapa.ascx" %>
<%@ Register TagPrefix="sig" TagName="ConveniosListado" Src="~/UserControl/ConveniosListado.ascx" %>
<asp:Content ID="ContenidoEncabezado" ContentPlaceHolderID="H" runat="server"> <asp:Content ID="ContenidoEncabezado" ContentPlaceHolderID="H" runat="server">
<style> <style>
.desarrollador-panel-etapa { .desarrollador-panel-etapa {
@@ -223,6 +224,7 @@
</ajax:TabPanel> </ajax:TabPanel>
<ajax:TabPanel ID="PestanaConvenios" runat="server" HeaderText="Convenios"> <ajax:TabPanel ID="PestanaConvenios" runat="server" HeaderText="Convenios">
<ContentTemplate> <ContentTemplate>
<sig:ConveniosListado ID="UcConveniosDesarrollador" runat="server" />
</ContentTemplate> </ContentTemplate>
</ajax:TabPanel> </ajax:TabPanel>
<ajax:TabPanel ID="PestanaDocumentacion" runat="server" HeaderText="Documentación"> <ajax:TabPanel ID="PestanaDocumentacion" runat="server" HeaderText="Documentación">

View File

@@ -8,6 +8,7 @@ using SIG.Web.AppCode.Infrastructure.WebForms;
using SIG.Web.AppCode.Models.Clientes; using SIG.Web.AppCode.Models.Clientes;
using SIG.Web.AppCode.Models.Common; using SIG.Web.AppCode.Models.Common;
using SIG.Web.AppCode.Models.Fraccionamientos; using SIG.Web.AppCode.Models.Fraccionamientos;
using SIG.Web.AppCode.Models.Convenios;
using SIG.Web.AppCode.Session; using SIG.Web.AppCode.Session;
using SIG.Web.AppCode.Security; using SIG.Web.AppCode.Security;
@@ -135,6 +136,7 @@ namespace SIG.Web.Pages.Desarrolladores
PnlDetalle.Visible = true; PnlDetalle.Visible = true;
MostrarDatos(consulta.Data); MostrarDatos(consulta.Data);
CargarFraccionamientos(); CargarFraccionamientos();
UcConveniosDesarrollador.Cargar(new FiltroConvenios { CveCliente = CveClienteActual });
CargarEstatus(); CargarEstatus();
BuscadorDesarrolladores.SelectedValue = cveCliente.ToString(CultureInfo.InvariantCulture); BuscadorDesarrolladores.SelectedValue = cveCliente.ToString(CultureInfo.InvariantCulture);
BuscadorDesarrolladores.Text = consulta.Data.RFC + " - " + consulta.Data.Nombre; BuscadorDesarrolladores.Text = consulta.Data.RFC + " - " + consulta.Data.Nombre;

Binary file not shown.

View File

@@ -0,0 +1,8 @@
(function (window, $) {
'use strict';
if (!$) { return; }
window.SIGConvenios = window.SIGConvenios || {
mostrarModal: function (id) { $('#' + id).modal('show'); },
ocultarModal: function (id) { $('#' + id).modal('hide'); }
};
})(window, window.jQuery);

View File

@@ -1,207 +1,190 @@
 (function (ventana, documento, $) { (function (window, $) {
"use strict"; 'use strict';
var SIG = ventana.SIGGridAgrupado = ventana.SIGGridAgrupado || {}; if (!$) {
SIG.estados = SIG.estados || {};
function claveGrid(tabla) {
var $tabla = $(tabla);
var clave = $tabla.attr("data-sig-grid-key");
if (!clave) {
clave = tabla.id || ("sig-grid-" + $(".sig-grid-agrupado").index(tabla));
$tabla.attr("data-sig-grid-key", clave);
}
return clave;
}
function estadoGrid(tabla) {
var clave = claveGrid(tabla);
if (!SIG.estados[clave]) {
SIG.estados[clave] = {};
}
return SIG.estados[clave];
}
function filasGrupo(tabla) {
return $(tabla).find("tbody > tr[data-sig-group-row='1']");
}
function obtenerGrupos(tabla) {
var grupos = {};
filasGrupo(tabla).each(function () {
var fila = $(this);
var id = fila.attr("data-sig-group-id");
if (!id) {
return; return;
} }
grupos[id] = { function estadoGrupo($fila) {
fila: fila, var estado = $fila.attr('data-sig-expanded');
padre: fila.attr("data-sig-parent-group") || ""
}; if (estado === 'true' || estado === 'false') {
return estado === 'true';
}
return $fila.attr('data-sig-expanded-default') !== 'false';
}
function actualizarIcono($fila, abierto) {
var $iconos = $fila.find('.sig-grid-icono-agrupacion');
/*
* Compatibilidad con agrupaciones existentes que todavía
* tienen el icono dentro del elemento alternador pero aún no
* usan la clase explícita sig-grid-icono-agrupacion.
*/
if ($iconos.length === 0) {
$iconos = $fila.find('.sig-grid-alternar-grupo i.fa');
}
$iconos
.removeClass('fa-chevron-up fa-chevron-down')
.addClass(abierto ? 'fa-chevron-up' : 'fa-chevron-down');
}
function inicializar() {
$('.sig-grid-agrupado:not(.rendered)').each(function () {
var $grid = $(this);
$grid.find('tr[data-sig-group-row="1"]').each(function () {
var $fila = $(this);
var abierto = estadoGrupo($fila);
$fila.attr(
'data-sig-expanded',
abierto ? 'true' : 'false'
);
$fila.find('.sig-grid-alternar-grupo, .sig-grid-alternar-grupo-accion')
.attr(
'aria-expanded',
abierto ? 'true' : 'false'
);
}); });
return grupos; refrescar($grid);
}
function inicializarEstados(tabla) { /*
var estado = estadoGrid(tabla); * Se marca hasta que terminó correctamente la inicialización.
* En cada load se revisan todos los grids, pero sólo se
filasGrupo(tabla).each(function () { * procesan los que todavía no tienen la clase rendered.
var fila = $(this); */
var id = fila.attr("data-sig-group-id"); $grid.addClass('rendered');
if (!id || Object.prototype.hasOwnProperty.call(estado, id)) {
return;
}
estado[id] = fila.attr("data-sig-expanded-default") !== "false";
}); });
} }
function grupoVisible(idGrupo, grupos, estado, visitados) { function refrescar($grid) {
if (!idGrupo) { var estados = {};
return true;
$grid.find('tr[data-sig-group-row="1"]').each(function () {
var $fila = $(this);
estados[$fila.attr('data-sig-group-id')] = estadoGrupo($fila);
});
$grid.find('tr[data-sig-level]').each(function () {
var $fila = $(this);
var padre = $fila.attr('data-sig-parent-group');
var visible = true;
var visitados = {};
while (padre) {
if (visitados[padre]) {
break;
} }
var grupo = grupos[idGrupo]; visitados[padre] = true;
// Si el padre ya no existe en el HTML actual, no bloqueamos la fila. if (estados[padre] === false) {
if (!grupo) { visible = false;
return true; break;
} }
visitados = visitados || {}; var $padre = $grid
.find(
'tr[data-sig-group-id="' +
escaparSelector(padre) +
'"]'
)
.first();
// Protección contra una configuración accidentalmente circular. padre = $padre.attr('data-sig-parent-group');
if (visitados[idGrupo]) {
return true;
} }
visitados[idGrupo] = true; $fila.toggle(visible);
});
if (!grupoVisible(grupo.padre, grupos, estado, visitados)) { $grid.find('tr[data-sig-group-row="1"]').each(function () {
return false; var $fila = $(this);
} var abierto = estadoGrupo($fila);
return estado[idGrupo] !== false; $fila.find('.sig-grid-alternar-grupo, .sig-grid-alternar-grupo-accion')
} .attr(
'aria-expanded',
abierto ? 'true' : 'false'
);
function ancestrosVisibles(parentGroupId, grupos, estado) { actualizarIcono($fila, abierto);
if (!parentGroupId) {
return true;
}
var padre = grupos[parentGroupId];
if (!padre) {
return true;
}
if (!grupoVisible(padre.padre, grupos, estado, {})) {
return false;
}
return estado[parentGroupId] !== false;
}
function actualizarBoton(filaGrupo, expandido) {
var boton = filaGrupo.find(".sig-grid-alternar-grupo").first();
boton.attr("aria-expanded", expandido ? "true" : "false");
boton.find(".fa")
.toggleClass("fa-chevron-up", expandido)
.toggleClass("fa-chevron-down", !expandido);
}
function actualizarTabla(tabla) {
var $tabla = $(tabla);
var estado = estadoGrid(tabla);
var grupos = obtenerGrupos(tabla);
$tabla.find("tbody > tr").each(function () {
var fila = $(this);
var parentGroupId = fila.attr("data-sig-parent-group") || "";
var visible = ancestrosVisibles(parentGroupId, grupos, estado);
fila.toggleClass("sig-grid-fila-oculta", !visible);
if (fila.attr("data-sig-group-row") === "1") {
var id = fila.attr("data-sig-group-id");
actualizarBoton(fila, estado[id] !== false);
}
}); });
} }
SIG.inicializar = function (contexto) { function escaparSelector(valor) {
var raiz = contexto || documento; return String(valor || '')
var grids = $(raiz).find("table.sig-grid-agrupado"); .replace(
/([!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~])/g,
if ($(raiz).is && $(raiz).is("table.sig-grid-agrupado")) { '\\$1'
grids = grids.add(raiz); );
} }
grids.each(function () { /*
inicializarEstados(this); * Compatibilidad:
actualizarTabla(this); * - sig-grid-alternar-grupo conserva el comportamiento existente.
}); * - sig-grid-alternar-grupo-accion permite agregar un alternador
}; * compacto sin heredar los estilos visuales del alternador de fila.
* El icono visual se identifica con sig-grid-icono-agrupacion.
*/
if (window.SIG_GRID_AGRUPADO_EVENTOS !== true) {
window.SIG_GRID_AGRUPADO_EVENTOS = true;
SIG.refrescar = function (tabla) { $(document).on(
if (!tabla) { 'click.sigGridAgrupado',
return; '.sig-grid-agrupado .sig-grid-alternar-grupo, ' +
} '.sig-grid-agrupado .sig-grid-alternar-grupo-accion',
inicializarEstados(tabla);
actualizarTabla(tabla);
};
if (ventana.SIG_EVENTOS_GRID_AGRUPADO_REGISTRADOS !== true) {
$(documento).on(
"click.sigGridAgrupado",
"table.sig-grid-agrupado .sig-grid-alternar-grupo",
function (evento) { function (evento) {
evento.preventDefault(); evento.preventDefault();
var boton = $(this); var $fila = $(this)
var tabla = boton.closest("table.sig-grid-agrupado")[0]; .closest('tr[data-sig-group-row="1"]');
var fila = boton.closest("tr[data-sig-group-row='1']");
var idGrupo = fila.attr("data-sig-group-id");
if (!tabla || !idGrupo) { if ($fila.length === 0) {
return; return;
} }
var estado = estadoGrid(tabla); var $grid = $fila.closest('.sig-grid-agrupado');
inicializarEstados(tabla); $fila.attr(
estado[idGrupo] = !(estado[idGrupo] !== false); 'data-sig-expanded',
actualizarTabla(tabla); estadoGrupo($fila) ? 'false' : 'true'
}
); );
ventana.SIG_EVENTOS_GRID_AGRUPADO_REGISTRADOS = true; refrescar($grid);
}
);
} }
$(function () { window.SIGGridAgrupado = {
SIG.inicializar(documento); inicializar: inicializar,
}); refrescar: refrescar
};
/* /*
* Sys.Application.load se ejecuta también después de un async postback. * Sys.Application.load se ejecuta en la carga inicial y después
* Como el estado vive fuera del HTML, al reemplazarse un UpdatePanel se * de cada postback parcial. No se inspecciona qué UpdatePanel
* reaplican los estados anteriores de cada grupo. * cambió: se revisan todos los grids no renderizados.
*/ */
if (ventana.Sys && ventana.Sys.Application) { if (
ventana.Sys.Application.add_load(function () { window.Sys &&
SIG.inicializar(documento); Sys.Application &&
window.SIG_GRID_AGRUPADO_LOAD !== true
) {
window.SIG_GRID_AGRUPADO_LOAD = true;
Sys.Application.add_load(function () {
inicializar();
});
} else if (!(window.Sys && Sys.Application)) {
$(function () {
inicializar();
}); });
} }
}(window, document, jQuery)); })(window, window.jQuery);

View File

@@ -0,0 +1,113 @@
.sig-convenios-listado .sig-convenio-saldo-pendiente {
font-weight: 600;
}
.sig-convenio-modal .modal-dialog {
width: 90%;
max-width: 1180px;
}
.sig-convenio-modal-captura .modal-dialog {
width: 94%;
max-width: 1380px;
}
.sig-convenio-resumen {
margin-bottom: 18px;
}
.sig-convenio-resumen .row {
margin-bottom: 8px;
}
.sig-convenios-acciones {
margin-bottom: 15px;
}
.sig-convenio-seccion-titulo {
margin: 6px 0 12px 0;
padding-bottom: 6px;
border-bottom: 1px solid #e5e5e5;
font-weight: 600;
}
.sig-convenio-contexto-captura {
margin-bottom: 4px;
}
.sig-convenio-concepto-captura {
margin-top: 10px;
padding-top: 8px;
border-top: 1px solid #e5e5e5;
}
.sig-convenio-agregar-concepto-boton {
padding-top: 24px;
}
.sig-convenio-captura-grid {
margin-top: 12px;
}
.sig-convenio-fila-concepto > td {
background: #eef5fb !important;
vertical-align: middle !important;
font-weight: 600;
}
.sig-convenio-fila-parcialidad > td {
vertical-align: middle !important;
}
.sig-convenio-fila-parcialidad > td:first-child {
padding-left: 34px;
}
.sig-convenio-concepto-texto {
padding: 0;
border: 0;
background: transparent;
font: inherit;
color: inherit;
text-align: left;
cursor: pointer;
}
.sig-convenio-concepto-texto:hover,
.sig-convenio-concepto-texto:focus {
text-decoration: underline;
outline: none;
}
.sig-convenio-captura-grid .sig-convenio-acciones-concepto {
display: inline-flex;
align-items: center;
white-space: nowrap;
}
.sig-convenio-captura-grid .sig-convenio-acciones-concepto > .btn + .btn,
.sig-convenio-captura-grid .sig-convenio-acciones-concepto > .btn + button {
margin-left: 4px;
}
.sig-convenio-captura-grid .sig-convenio-alternar-concepto {
width: 32px;
min-width: 32px;
padding-left: 8px;
padding-right: 8px;
text-align: center;
vertical-align: middle;
}
.sig-convenio-captura-grid .sig-convenio-alternar-concepto .fa {
float: none;
margin: 0;
}
.sig-convenio-captura-grid .form-control.input-sm {
min-width: 110px;
}
.sig-convenio-captura-grid td:last-child {
white-space: nowrap;
}

View File

@@ -1,72 +1,6 @@
/* ============================================================ .sig-grid-agrupado .sig-grid-grupo > td { padding: 0; background: #eef5f9; }
GRID AGRUPADO SIG .sig-grid-agrupado .sig-grid-alternar-grupo { width: 100%; border: 0; background: transparent; padding: 10px 12px; text-align: left; font-weight: 600; }
Comportamiento visual genérico para GridView con grupos. .sig-grid-agrupado .sig-grid-alternar-grupo .fa { float: right; margin-top: 3px; }
============================================================ */ .sig-grid-agrupado tr[data-sig-level="1"] > td:first-child { padding-left: 24px; }
.sig-grid-agrupado tr[data-sig-level="2"] > td:first-child { padding-left: 42px; }
table.sig-grid-agrupado > tbody > tr.sig-grid-grupo > td { .sig-grid-agrupado tr[data-sig-level="3"] > td:first-child { padding-left: 60px; }
padding: 0;
background: #eef3f7;
}
table.sig-grid-agrupado .sig-grid-alternar-grupo {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
padding: 12px;
border: 0;
background: transparent;
color: #34495e;
font-weight: 600;
text-align: left;
cursor: pointer;
}
table.sig-grid-agrupado .sig-grid-alternar-grupo:hover {
background: rgba(0, 0, 0, 0.015);
}
table.sig-grid-agrupado .sig-grid-alternar-grupo:focus {
outline: 2px solid #3598dc;
outline-offset: -2px;
}
table.sig-grid-agrupado .sig-grid-grupo-titulo {
min-width: 0;
overflow-wrap: anywhere;
}
table.sig-grid-agrupado tr.sig-grid-fila-oculta {
display: none;
}
/*
* Los niveles se conservan como data-sig-level para comportamiento y para
* permitir personalización futura. No se fuerza sangría aquí porque el
* encabezado debe conservar el aspecto compacto del tablero de trámites.
*/
.sig-documentos-etapa {
width: 100%;
}
.sig-documentos-etapa > .btn {
margin-bottom: 15px;
}
.sig-documentos-etapa .sig-documentos-fecha-vencida {
color: #d9534f;
font-weight: 600;
}
.sig-documentos-etapa table.sig-grid-agrupado {
margin-bottom: 0;
}
.sig-documentos-etapa table.sig-grid-agrupado td:last-child {
white-space: normal;
}
.sig-documentos-etapa table.sig-grid-agrupado td:last-child .btn {
margin-bottom: 3px;
}

View File

@@ -0,0 +1,155 @@
<%@ Control Language="C#" AutoEventWireup="false" CodeFile="DocumentosCliente.ascx.cs"
Inherits="SIG.Web.UserControl.Clientes.DocumentosCliente" %>
<asp:UpdatePanel ID="UpDocumentos" runat="server"
UpdateMode="Conditional" ChildrenAsTriggers="true">
<ContentTemplate>
<asp:Panel ID="PanelFiltros" runat="server">
<sig:Filtros ID="FiltrosDocumentos" runat="server"
OnMostrarFiltros="MostrarModalFiltros"
OnConsultar="Consultar"
OnFiltrosChanged="FiltrosCambiados" />
</asp:Panel>
<div class="table-responsive">
<asp:GridView ID="GvDocumentos" runat="server"
AutoGenerateColumns="false"
GridLines="None"
CssClass="table table-hover Widthall sig-grid-agrupado"
DataKeyNames="EsGrupo,CveDocumentoSolicitud,CveFraccionamiento,CveFraccionamientoEtapa,CveTipoDocumento"
EmptyDataText="No hay documentos para mostrar."
OnRowDataBound="EnlazarFila"
OnRowCommand="ComandoDocumento">
<Columns>
<asp:BoundField DataField="Fraccionamiento" HeaderText="Fraccionamiento" />
<asp:BoundField DataField="Etapa" HeaderText="Etapa" />
<asp:BoundField DataField="TipoDocumento" HeaderText="Documento" />
<asp:BoundField DataField="TipoTramite" HeaderText="Trámite" />
<asp:BoundField DataField="EstadoDocumento" HeaderText="Estado" />
<asp:BoundField DataField="FechaVencimiento" HeaderText="Vencimiento"
DataFormatString="{0:dd/MM/yyyy}" />
<asp:TemplateField HeaderText="Acciones">
<ItemTemplate>
<asp:HyperLink ID="LnkVerDocumento" runat="server"
CssClass="btn btn-sm default"
Visible='<%# Convert.ToBoolean(Eval("TieneArchivo")) %>'
NavigateUrl='<%# UrlDocumento(Eval("CveFraccionamiento"), Eval("CveDocumentoSolicitud")) %>'>
<i class="fa fa-download" aria-hidden="true"></i>
Ver
</asp:HyperLink>
<asp:LinkButton ID="BtnCargarDocumento" runat="server"
CssClass="btn btn-sm blue"
CommandName="Cargar"
CausesValidation="false"
Visible='<%# Convert.ToBoolean(Eval("PuedeCargar")) %>'>
<i class="fa fa-upload" aria-hidden="true"></i>
Cargar / renovar
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
</ContentTemplate>
</asp:UpdatePanel>
<div id="ModalFiltrosDocumentosCliente" runat="server"
class="modal fade" tabindex="-1" role="dialog"
aria-label="Filtros de documentos">
<div class="modal-dialog">
<asp:UpdatePanel ID="UpFiltrosDocumentos" runat="server"
UpdateMode="Conditional" ChildrenAsTriggers="true">
<ContentTemplate>
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Cerrar">&times;</button>
<h4>Filtros de documentos</h4>
</div>
<div class="modal-body">
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="DdlFraccionamientoFiltro"
Text="Fraccionamiento" />
<asp:DropDownList ID="DdlFraccionamientoFiltro" runat="server"
CssClass="form-control select2me" Width="100%" />
</div>
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="DdlEtapaFiltro"
Text="Etapa" />
<asp:DropDownList ID="DdlEtapaFiltro" runat="server"
CssClass="form-control select2me" Width="100%" />
</div>
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="DdlAgrupacionFiltro"
Text="Estado" />
<asp:DropDownList ID="DdlAgrupacionFiltro" runat="server"
CssClass="form-control select2me" Width="100%">
<asp:ListItem Value="" Text="Todos" />
<asp:ListItem Value="Pendientes" Text="Pendientes" />
<asp:ListItem Value="Por aprobar" Text="Por aprobar" />
<asp:ListItem Value="Aprobados" Text="Aprobados" />
<asp:ListItem Value="Vencidos" Text="Vencidos" />
</asp:DropDownList>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn default" data-dismiss="modal">Cancelar</button>
<asp:Button ID="BtnAplicarFiltros" runat="server"
CssClass="btn blue" Text="Aplicar filtros"
CausesValidation="false" OnClick="AplicarFiltros" />
</div>
</div>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</div>
<div id="ModalCargaDocumentoCliente" runat="server"
class="modal fade" tabindex="-1" role="dialog"
aria-label="Cargar documento">
<div class="modal-dialog">
<asp:UpdatePanel ID="UpCargaDocumento" runat="server"
UpdateMode="Conditional" ChildrenAsTriggers="true">
<ContentTemplate>
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Cerrar">&times;</button>
<h4><asp:Literal ID="TituloCargaDocumento" runat="server" Mode="Encode" /></h4>
</div>
<div class="modal-body">
<p><asp:Literal ID="ReglasArchivoDocumento" runat="server" Mode="Encode" /></p>
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="ArchivoDocumento"
Text="Archivo" />
<asp:FileUpload ID="ArchivoDocumento" runat="server"
CssClass="form-control" />
</div>
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="FechaDocumento"
Text="Fecha del documento" />
<asp:TextBox ID="FechaDocumento" runat="server"
TextMode="Date" CssClass="form-control" />
</div>
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="FechaVencimientoDocumento"
Text="Fecha de vencimiento" />
<asp:TextBox ID="FechaVencimientoDocumento" runat="server"
TextMode="Date" CssClass="form-control" />
</div>
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="NotaDocumento"
Text="Notas" />
<asp:TextBox ID="NotaDocumento" runat="server"
TextMode="MultiLine" Rows="3" CssClass="form-control" />
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn default" data-dismiss="modal">Cancelar</button>
<asp:Button ID="BtnGuardarDocumento" runat="server"
CssClass="btn blue" Text="Guardar documento"
CausesValidation="false" OnClick="GuardarDocumento" />
</div>
</div>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</div>

View File

@@ -0,0 +1,777 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
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.Session;
using SIG.Web.AppCode.SigControls;
namespace SIG.Web.UserControl.Clientes
{
public partial class DocumentosCliente : System.Web.UI.UserControl
{
private UserSessionModel Usuario
{
get { return AppServices.UserContext.GetCurrentUser(); }
}
private int? CveFraccionamientoFijo
{
get { return (int?)ViewState["CveFraccionamientoFijo"]; }
set { ViewState["CveFraccionamientoFijo"] = value; }
}
private bool MostrarFiltrosActual
{
get { return (bool?)ViewState["MostrarFiltrosActual"] ?? false; }
set { ViewState["MostrarFiltrosActual"] = value; }
}
private FiltroDocumentosCliente FiltroActual
{
get
{
return ViewState["FiltroActual"] as FiltroDocumentosCliente ??
new FiltroDocumentosCliente();
}
set { ViewState["FiltroActual"] = value; }
}
private DocumentoClientePortal DocumentoSeleccionado
{
get
{
return ViewState["DocumentoSeleccionado"] as DocumentoClientePortal;
}
set { ViewState["DocumentoSeleccionado"] = value; }
}
private List<DocumentoClientePortal> DocumentosActuales
{
get
{
return ViewState["DocumentosActuales"] as List<DocumentoClientePortal> ??
new List<DocumentoClientePortal>();
}
set { ViewState["DocumentosActuales"] = value; }
}
protected override void OnInit(EventArgs argumentos)
{
base.OnInit(argumentos);
ScriptManager administrador = ScriptManager.GetCurrent(Page);
if (administrador != null)
{
administrador.RegisterPostBackControl(BtnGuardarDocumento);
}
}
public void Cargar(
int? cveFraccionamiento,
bool mostrarFiltros)
{
CveFraccionamientoFijo = cveFraccionamiento;
MostrarFiltrosActual = mostrarFiltros;
PanelFiltros.Visible = mostrarFiltros;
FiltroDocumentosCliente filtro = FiltroActual;
filtro.CveFraccionamiento = cveFraccionamiento ?? filtro.CveFraccionamiento;
FiltroActual = filtro;
Refrescar();
}
protected void Consultar(object origen, EventArgs argumentos)
{
Refrescar();
}
protected void MostrarModalFiltros(object origen, EventArgs argumentos)
{
CargarOpcionesFiltros();
SincronizarModalFiltros();
UpFiltrosDocumentos.Update();
MostrarModal(ModalFiltrosDocumentosCliente.ClientID);
}
protected void AplicarFiltros(object origen, EventArgs argumentos)
{
FiltroActual = new FiltroDocumentosCliente
{
CveFraccionamiento = CveFraccionamientoFijo ?? LeerClave(DdlFraccionamientoFiltro),
CveFraccionamientoEtapa = LeerClave(DdlEtapaFiltro),
Agrupacion = string.IsNullOrWhiteSpace(DdlAgrupacionFiltro.SelectedValue)
? null
: DdlAgrupacionFiltro.SelectedValue
};
Refrescar();
OcultarModal(ModalFiltrosDocumentosCliente.ClientID);
}
protected void FiltrosCambiados(object origen, EventArgs argumentos)
{
var nombres = new HashSet<string>(
FiltrosDocumentos.GetFiltros().Select(x => x.Nombre));
FiltroDocumentosCliente filtro = FiltroActual;
if (!nombres.Contains("Fraccionamiento") && !CveFraccionamientoFijo.HasValue)
{
filtro.CveFraccionamiento = null;
}
if (!nombres.Contains("Etapa"))
{
filtro.CveFraccionamientoEtapa = null;
}
if (!nombres.Contains("Estado"))
{
filtro.Agrupacion = null;
}
FiltroActual = filtro;
Refrescar();
}
protected void EnlazarFila(object origen, GridViewRowEventArgs argumentos)
{
if (argumentos.Row.RowType != DataControlRowType.DataRow)
{
return;
}
var fila = argumentos.Row.DataItem as FilaDocumentoCliente;
if (fila == null)
{
return;
}
argumentos.Row.Attributes["data-sig-level"] =
fila.Nivel.ToString(CultureInfo.InvariantCulture);
if (fila.EsGrupo)
{
argumentos.Row.CssClass = "sig-grid-grupo";
argumentos.Row.Attributes["data-sig-group-row"] = "1";
argumentos.Row.Attributes["data-sig-group-id"] = fila.GroupId;
argumentos.Row.Attributes["data-sig-expanded-default"] = "true";
if (!string.IsNullOrWhiteSpace(fila.ParentGroupId))
{
argumentos.Row.Attributes["data-sig-parent-group"] =
fila.ParentGroupId;
}
int columnas = GvDocumentos.Columns
.Cast<DataControlField>()
.Count(columna => columna.Visible);
argumentos.Row.Cells.Clear();
var celda = new TableCell { ColumnSpan = columnas };
var boton = new HtmlGenericControl("button");
boton.Attributes["type"] = "button";
boton.Attributes["class"] = "sig-grid-alternar-grupo";
boton.Attributes["aria-expanded"] = "true";
var titulo = new HtmlGenericControl("span");
titulo.Attributes["class"] = "sig-grid-grupo-titulo";
titulo.InnerText = fila.TituloGrupo;
var flecha = new HtmlGenericControl("i");
flecha.Attributes["class"] =
"fa fa-chevron-up sig-grid-icono-agrupacion";
flecha.Attributes["aria-hidden"] = "true";
boton.Controls.Add(titulo);
boton.Controls.Add(flecha);
celda.Controls.Add(boton);
argumentos.Row.Cells.Add(celda);
return;
}
argumentos.Row.Attributes["data-sig-item-row"] = "1";
argumentos.Row.Attributes["data-sig-parent-group"] =
fila.ParentGroupId;
}
protected void ComandoDocumento(
object origen,
GridViewCommandEventArgs argumentos)
{
if (!string.Equals(
argumentos.CommandName,
"Cargar",
StringComparison.Ordinal))
{
return;
}
var boton = argumentos.CommandSource as Control;
var fila = boton == null
? null
: boton.NamingContainer as GridViewRow;
if (fila == null || fila.RowIndex < 0)
{
return;
}
DataKey claves = GvDocumentos.DataKeys[fila.RowIndex];
if (Convert.ToBoolean(claves.Values["EsGrupo"]))
{
return;
}
int cveDocumentoSolicitud = Convert.ToInt32(
claves.Values["CveDocumentoSolicitud"]);
int cveFraccionamiento = Convert.ToInt32(
claves.Values["CveFraccionamiento"]);
int cveFraccionamientoEtapa = Convert.ToInt32(
claves.Values["CveFraccionamientoEtapa"]);
int cveTipoDocumento = Convert.ToInt32(
claves.Values["CveTipoDocumento"]);
DocumentoSeleccionado = DocumentosActuales.FirstOrDefault(x =>
x.CveFraccionamiento == cveFraccionamiento &&
x.CveFraccionamientoEtapa == cveFraccionamientoEtapa &&
x.CveTipoDocumento == cveTipoDocumento &&
x.CveDocumentoSolicitud == cveDocumentoSolicitud);
if (DocumentoSeleccionado == null)
{
Avisar("El documento ya no está disponible.");
return;
}
if (cveTipoDocumento == 2)
{
Avisar("El archivo GIS se administra desde la etapa correspondiente.");
return;
}
UserSessionModel usuario = Usuario;
var contexto = AppServices.TramiteDocumentoService.GetUploadContext(
cveFraccionamiento,
DocumentoSeleccionado.CveSolicitud,
cveTipoDocumento,
usuario.CveUsuario,
usuario.NombreDominio,
cveFraccionamientoEtapa);
if (!contexto.Success || contexto.Data == null)
{
Avisar(contexto.UserMessage);
return;
}
TituloCargaDocumento.Text = DocumentoSeleccionado.TipoDocumento;
ReglasArchivoDocumento.Text =
"Permitidos: " + contexto.Data.ExtensionesPermitidas +
(contexto.Data.TamanoMaximoMb.HasValue
? " · Máximo " + contexto.Data.TamanoMaximoMb + " MB"
: string.Empty);
FechaDocumento.Text = FormatearFecha(
contexto.Data.FechaDocumentoAnterior);
FechaVencimientoDocumento.Text = FormatearFecha(
contexto.Data.FechaVencimientoAnterior);
NotaDocumento.Text = contexto.Data.ComentarioClienteAnterior ?? string.Empty;
UpCargaDocumento.Update();
MostrarModal(ModalCargaDocumentoCliente.ClientID);
}
protected void GuardarDocumento(object origen, EventArgs argumentos)
{
DateTime? fechaDocumento;
DateTime? fechaVencimiento;
if (DocumentoSeleccionado == null ||
!ArchivoDocumento.HasFile ||
!LeerFecha(FechaDocumento.Text, out fechaDocumento) ||
!LeerFecha(FechaVencimientoDocumento.Text, out fechaVencimiento))
{
MostrarModal(ModalCargaDocumentoCliente.ClientID);
Avisar("Seleccione un archivo y capture fechas válidas.");
return;
}
UserSessionModel usuario = Usuario;
var resultado = AppServices.TramiteDocumentoService.Upload(
DocumentoSeleccionado.CveFraccionamiento,
DocumentoSeleccionado.CveSolicitud,
DocumentoSeleccionado.CveTipoDocumento,
ArchivoDocumento.FileName,
ArchivoDocumento.PostedFile.ContentType,
ArchivoDocumento.PostedFile.InputStream,
ArchivoDocumento.PostedFile.ContentLength,
NotaDocumento.Text,
usuario.CveUsuario,
usuario.NombreDominio,
fechaDocumento,
fechaVencimiento,
DocumentoSeleccionado.CveFraccionamientoEtapa);
if (!resultado.Success)
{
MostrarModal(ModalCargaDocumentoCliente.ClientID);
Avisar(resultado.UserMessage);
return;
}
DocumentoSeleccionado = null;
Refrescar();
Avisar(
"Documento guardado; pendiente de revisión.",
TipoMensaje.ToastExito);
}
public string UrlDocumento(
object cveFraccionamiento,
object cveDocumentoSolicitud)
{
int fraccionamiento = Convert.ToInt32(cveFraccionamiento);
int documento = Convert.ToInt32(cveDocumentoSolicitud);
if (fraccionamiento <= 0 || documento <= 0)
{
return string.Empty;
}
return ResolveUrl("~/Pages/Fraccionamientos/TramiteDocumento.ashx") +
"?fraccionamiento=" + fraccionamiento.ToString(CultureInfo.InvariantCulture) +
"&documento=" + documento.ToString(CultureInfo.InvariantCulture);
}
private void Refrescar()
{
UserSessionModel usuario = Usuario;
if (usuario == null)
{
return;
}
FiltroDocumentosCliente filtro = FiltroActual;
if (CveFraccionamientoFijo.HasValue)
{
filtro.CveFraccionamiento = CveFraccionamientoFijo;
}
var resultado = AppServices.ServicioPortalCliente.ListarDocumentos(
filtro,
usuario.CveUsuario,
usuario.NombreDominio);
if (!resultado.Success)
{
DocumentosActuales = new List<DocumentoClientePortal>();
GvDocumentos.DataSource = new List<FilaDocumentoCliente>();
GvDocumentos.DataBind();
UpDocumentos.Update();
Avisar(resultado.UserMessage, TipoMensaje.MsgError);
return;
}
DocumentosActuales = resultado.Data ?? new List<DocumentoClientePortal>();
GvDocumentos.DataSource = ConstruirFilas(DocumentosActuales);
GvDocumentos.DataBind();
ActualizarFiltrosActivos();
UpDocumentos.Update();
}
private List<FilaDocumentoCliente> ConstruirFilas(
IEnumerable<DocumentoClientePortal> documentos)
{
var filas = new List<FilaDocumentoCliente>();
bool incluirFraccionamiento = !CveFraccionamientoFijo.HasValue;
int nivelDocumento = 1;
int nivelEstado = 2;
int nivelFraccionamiento = 3;
foreach (var grupoFraccionamiento in documentos
.GroupBy(x => new { x.CveFraccionamiento, x.Fraccionamiento })
.OrderBy(x => x.Key.Fraccionamiento))
{
string grupoFraccionamientoId =
"doc-fracc-" + grupoFraccionamiento.Key.CveFraccionamiento;
if (incluirFraccionamiento)
{
filas.Add(FilaDocumentoCliente.CrearGrupo(
grupoFraccionamientoId,
null,
nivelFraccionamiento,
grupoFraccionamiento.Key.Fraccionamiento));
}
foreach (var grupoEstado in grupoFraccionamiento
.GroupBy(x => x.Agrupacion)
.OrderBy(x => OrdenAgrupacion(x.Key)))
{
string grupoEstadoId = grupoFraccionamientoId +
"-estado-" + NormalizarClave(grupoEstado.Key);
filas.Add(FilaDocumentoCliente.CrearGrupo(
grupoEstadoId,
incluirFraccionamiento ? grupoFraccionamientoId : null,
nivelEstado,
grupoEstado.Key));
filas.AddRange(grupoEstado
.OrderBy(x => x.Etapa)
.ThenBy(x => x.TipoDocumento)
.Select(documento => FilaDocumentoCliente.CrearDocumento(
grupoEstadoId,
nivelDocumento,
documento)));
}
}
return filas;
}
private void CargarOpcionesFiltros()
{
UserSessionModel usuario = Usuario;
var resultado = AppServices.ServicioPortalCliente.ListarDesarrollos(
usuario.CveUsuario,
usuario.NombreDominio);
List<ModeloFilaDesarrollos> desarrollos = resultado.Success
? resultado.Data ?? new List<ModeloFilaDesarrollos>()
: new List<ModeloFilaDesarrollos>();
DdlFraccionamientoFiltro.Items.Clear();
DdlFraccionamientoFiltro.Items.Add(new ListItem("Todos", string.Empty));
foreach (var fraccionamiento in desarrollos
.Where(x => x.CveFraccionamiento > 0)
.GroupBy(x => x.CveFraccionamiento)
.Select(x => x.First())
.OrderBy(x => x.Fraccionamiento))
{
DdlFraccionamientoFiltro.Items.Add(new ListItem(
fraccionamiento.Fraccionamiento,
fraccionamiento.CveFraccionamiento.ToString(
CultureInfo.InvariantCulture)));
}
DdlEtapaFiltro.Items.Clear();
DdlEtapaFiltro.Items.Add(new ListItem("Todas", string.Empty));
foreach (var etapa in desarrollos
.Where(x => x.CveFraccionamientoEtapa.HasValue)
.OrderBy(x => x.Fraccionamiento)
.ThenBy(x => x.Etapa))
{
DdlEtapaFiltro.Items.Add(new ListItem(
etapa.Fraccionamiento + " · " + etapa.Etapa,
etapa.CveFraccionamientoEtapa.Value.ToString(
CultureInfo.InvariantCulture)));
}
if (!resultado.Success)
{
Avisar(resultado.UserMessage, TipoMensaje.MsgError);
}
}
private void SincronizarModalFiltros()
{
FiltroDocumentosCliente filtro = FiltroActual;
Seleccionar(DdlFraccionamientoFiltro, filtro.CveFraccionamiento);
Seleccionar(DdlEtapaFiltro, filtro.CveFraccionamientoEtapa);
DdlAgrupacionFiltro.SelectedValue = filtro.Agrupacion ?? string.Empty;
}
private void ActualizarFiltrosActivos()
{
if (!MostrarFiltrosActual)
{
return;
}
var filtros = new List<FiltroActivo>();
FiltroDocumentosCliente filtro = FiltroActual;
if (filtro.CveFraccionamiento.HasValue)
{
string nombre = DocumentosActuales
.Where(x => x.CveFraccionamiento == filtro.CveFraccionamiento.Value)
.Select(x => x.Fraccionamiento)
.FirstOrDefault();
filtros.Add(new FiltroActivo
{
Nombre = "Fraccionamiento",
Titulo = "Fraccionamiento",
Descripcion = nombre ?? filtro.CveFraccionamiento.Value.ToString(),
Orden = 1,
Visible = true
});
}
if (filtro.CveFraccionamientoEtapa.HasValue)
{
string etapa = DocumentosActuales
.Where(x => x.CveFraccionamientoEtapa == filtro.CveFraccionamientoEtapa.Value)
.Select(x => x.Etapa)
.FirstOrDefault();
filtros.Add(new FiltroActivo
{
Nombre = "Etapa",
Titulo = "Etapa",
Descripcion = etapa ?? filtro.CveFraccionamientoEtapa.Value.ToString(),
Orden = 2,
Visible = true
});
}
if (!string.IsNullOrWhiteSpace(filtro.Agrupacion))
{
filtros.Add(new FiltroActivo
{
Nombre = "Estado",
Titulo = "Estado",
Descripcion = filtro.Agrupacion,
Orden = 3,
Visible = true
});
}
FiltrosDocumentos.SetFiltros(filtros);
}
private void MostrarModal(string id)
{
PageScriptRegistrar.RegistraScript(
Page,
"jQuery('#" + HttpUtility.JavaScriptStringEncode(id) + "').modal('show')");
}
private void OcultarModal(string id)
{
PageScriptRegistrar.RegistraScript(
Page,
"jQuery('#" + HttpUtility.JavaScriptStringEncode(id) + "').modal('hide')");
}
private void Avisar(
string mensaje,
TipoMensaje tipo = TipoMensaje.MsgAdvertencia)
{
PageAlertManager.Alert(Page, mensaje, tipo);
}
private static int? LeerClave(DropDownList lista)
{
int valor;
return int.TryParse(lista.SelectedValue, out valor) && valor > 0
? (int?)valor
: null;
}
private static void Seleccionar(
DropDownList lista,
int? valor)
{
lista.ClearSelection();
string clave = valor.HasValue
? valor.Value.ToString(CultureInfo.InvariantCulture)
: string.Empty;
ListItem opcion = lista.Items.FindByValue(clave);
if (opcion != null)
{
opcion.Selected = true;
}
}
private static string FormatearFecha(DateTime? fecha)
{
return fecha.HasValue
? fecha.Value.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture)
: string.Empty;
}
private static bool LeerFecha(
string texto,
out DateTime? fecha)
{
fecha = null;
if (string.IsNullOrWhiteSpace(texto))
{
return true;
}
DateTime valor;
if (!DateTime.TryParseExact(
texto,
"yyyy-MM-dd",
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out valor))
{
return false;
}
fecha = valor;
return true;
}
private static int OrdenAgrupacion(string agrupacion)
{
if (string.Equals(agrupacion, "Pendientes", StringComparison.OrdinalIgnoreCase))
{
return 1;
}
if (string.Equals(agrupacion, "Por aprobar", StringComparison.OrdinalIgnoreCase))
{
return 2;
}
if (string.Equals(agrupacion, "Aprobados", StringComparison.OrdinalIgnoreCase))
{
return 3;
}
if (string.Equals(agrupacion, "Vencidos", StringComparison.OrdinalIgnoreCase))
{
return 4;
}
return 99;
}
private static string NormalizarClave(string texto)
{
return new string((texto ?? string.Empty)
.ToLowerInvariant()
.Select(caracter => char.IsLetterOrDigit(caracter) ? caracter : '-')
.ToArray());
}
[Serializable]
public sealed class FilaDocumentoCliente
{
public bool EsGrupo { get; set; }
public string GroupId { get; set; }
public string ParentGroupId { get; set; }
public int Nivel { get; set; }
public string TituloGrupo { get; set; }
public DocumentoClientePortal Documento { get; set; }
public int CveDocumentoSolicitud
{
get { return Documento == null ? 0 : Documento.CveDocumentoSolicitud; }
}
public int CveFraccionamiento
{
get { return Documento == null ? 0 : Documento.CveFraccionamiento; }
}
public int CveFraccionamientoEtapa
{
get { return Documento == null ? 0 : Documento.CveFraccionamientoEtapa; }
}
public int CveTipoDocumento
{
get { return Documento == null ? 0 : Documento.CveTipoDocumento; }
}
public string Fraccionamiento
{
get { return Documento == null ? string.Empty : Documento.Fraccionamiento; }
}
public string Etapa
{
get { return Documento == null ? string.Empty : Documento.Etapa; }
}
public string TipoDocumento
{
get { return Documento == null ? string.Empty : Documento.TipoDocumento; }
}
public string TipoTramite
{
get { return Documento == null ? string.Empty : Documento.TipoTramite; }
}
public string EstadoDocumento
{
get { return Documento == null ? string.Empty : Documento.EstadoDocumento; }
}
public DateTime? FechaVencimiento
{
get { return Documento == null ? null : Documento.FechaVencimiento; }
}
public bool TieneArchivo
{
get { return Documento != null && Documento.TieneArchivo; }
}
public bool PuedeCargar
{
get
{
return Documento != null &&
Documento.PuedeActualizarArchivo;
}
}
public static FilaDocumentoCliente CrearGrupo(
string groupId,
string parentGroupId,
int nivel,
string titulo)
{
return new FilaDocumentoCliente
{
EsGrupo = true,
GroupId = groupId,
ParentGroupId = parentGroupId,
Nivel = nivel,
TituloGrupo = titulo
};
}
public static FilaDocumentoCliente CrearDocumento(
string parentGroupId,
int nivel,
DocumentoClientePortal documento)
{
return new FilaDocumentoCliente
{
EsGrupo = false,
ParentGroupId = parentGroupId,
Nivel = nivel,
Documento = documento
};
}
}
}
}

View File

@@ -0,0 +1,278 @@
<%@ Control Language="C#" AutoEventWireup="false" CodeFile="PagosCliente.ascx.cs"
Inherits="SIG.Web.UserControl.Clientes.PagosCliente" %>
<asp:UpdatePanel ID="UpPagos" runat="server"
UpdateMode="Conditional" ChildrenAsTriggers="true">
<ContentTemplate>
<asp:Panel ID="PanelFiltros" runat="server">
<sig:Filtros ID="FiltrosPagos" runat="server"
OnMostrarFiltros="MostrarModalFiltros"
OnConsultar="Consultar"
OnFiltrosChanged="FiltrosCambiados" />
</asp:Panel>
<div class="table-responsive">
<asp:GridView ID="GvPagos" runat="server"
AutoGenerateColumns="false"
GridLines="None"
CssClass="table table-hover Widthall sig-grid-agrupado"
DataKeyNames="EsGrupo,TipoRegistro,CveConvenioRecibo,CveConvenioPago,CveFraccionamiento"
EmptyDataText="No hay pagos o recibos para mostrar."
OnRowDataBound="EnlazarFila"
OnRowCommand="ComandoPago">
<Columns>
<asp:BoundField DataField="Fraccionamiento" HeaderText="Fraccionamiento" />
<asp:BoundField DataField="Etapa" HeaderText="Etapa" />
<asp:BoundField DataField="NumeroConvenio" HeaderText="Convenio" />
<asp:TemplateField HeaderText="Concepto / recibos">
<ItemTemplate>
<%#: Eval("DescripcionPrincipal") %>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Importe" HeaderText="Importe"
DataFormatString="{0:N2}" ItemStyle-HorizontalAlign="Right" />
<asp:BoundField DataField="SaldoPendiente" HeaderText="Saldo"
DataFormatString="{0:N2}" ItemStyle-HorizontalAlign="Right" />
<asp:BoundField DataField="Fecha" HeaderText="Fecha"
DataFormatString="{0:dd/MM/yyyy}" />
<asp:BoundField DataField="Estatus" HeaderText="Estado" />
<asp:TemplateField HeaderText="Comprobante">
<ItemTemplate>
<asp:HyperLink ID="LnkComprobante" runat="server"
CssClass="btn btn-sm default"
Visible='<%# Convert.ToInt32(Eval("CveConvenioPago")) > 0 && !string.IsNullOrWhiteSpace(Convert.ToString(Eval("NombreArchivo"))) %>'
NavigateUrl='<%# UrlComprobante(Eval("CveConvenioPago")) %>'>
<i class="fa fa-download" aria-hidden="true"></i>
<%#: Eval("NombreArchivo") %>
</asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Acciones">
<ItemTemplate>
<asp:LinkButton ID="BtnPagar" runat="server"
CssClass="btn btn-sm blue"
CommandName="Pagar"
CausesValidation="false"
Visible='<%# Convert.ToBoolean(Eval("PuedePagar")) %>'>
<i class="fa fa-credit-card" aria-hidden="true"></i>
Pagar
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
</ContentTemplate>
</asp:UpdatePanel>
<div id="ModalFiltrosPagosCliente" runat="server"
class="modal fade" tabindex="-1" role="dialog"
aria-label="Filtros de pagos">
<div class="modal-dialog">
<asp:UpdatePanel ID="UpFiltrosPagos" runat="server"
UpdateMode="Conditional" ChildrenAsTriggers="true">
<ContentTemplate>
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Cerrar">&times;</button>
<h4>Filtros de pagos</h4>
</div>
<div class="modal-body">
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="DdlFraccionamientoFiltro"
Text="Fraccionamiento" />
<asp:DropDownList ID="DdlFraccionamientoFiltro" runat="server"
CssClass="form-control select2me" Width="100%" />
</div>
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="DdlEtapaFiltro"
Text="Etapa" />
<asp:DropDownList ID="DdlEtapaFiltro" runat="server"
CssClass="form-control select2me" Width="100%" />
</div>
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="DdlAgrupacionFiltro"
Text="Estado" />
<asp:DropDownList ID="DdlAgrupacionFiltro" runat="server"
CssClass="form-control select2me" Width="100%">
<asp:ListItem Value="" Text="Todos" />
<asp:ListItem Value="Pendientes" Text="Pendientes" />
<asp:ListItem Value="Pagados" Text="Pagados" />
<asp:ListItem Value="Aprobados" Text="Aprobados" />
</asp:DropDownList>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn default" data-dismiss="modal">Cancelar</button>
<asp:Button ID="BtnAplicarFiltros" runat="server"
CssClass="btn blue" Text="Aplicar filtros"
CausesValidation="false" OnClick="AplicarFiltros" />
</div>
</div>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</div>
<div id="ModalPagoConvenioCliente" runat="server"
class="modal fade" tabindex="-1" role="dialog"
aria-label="Registrar pago">
<div class="modal-dialog modal-lg">
<asp:UpdatePanel ID="UpCapturaPago" runat="server"
UpdateMode="Conditional" ChildrenAsTriggers="true">
<ContentTemplate>
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Cerrar">&times;</button>
<h4>Registrar pago</h4>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-4">
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="TxtImportePago"
Text="Importe de la transferencia" />
<asp:TextBox ID="TxtImportePago" runat="server"
CssClass="form-control" />
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="TxtFechaPago"
Text="Fecha de pago" />
<asp:TextBox ID="TxtFechaPago" runat="server"
CssClass="form-control" TextMode="Date" />
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="ArchivoPago"
Text="Comprobante" />
<asp:FileUpload ID="ArchivoPago" runat="server"
CssClass="form-control" />
<span class="help-block">PDF, JPG o PNG; máximo 5 MB.</span>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="TxtReferenciaPago"
Text="Referencia" />
<asp:TextBox ID="TxtReferenciaPago" runat="server"
CssClass="form-control" MaxLength="200" />
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="TxtBancoPago"
Text="Banco" />
<asp:TextBox ID="TxtBancoPago" runat="server"
CssClass="form-control" MaxLength="200" />
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="TxtNumeroOperacionPago"
Text="Número de operación" />
<asp:TextBox ID="TxtNumeroOperacionPago" runat="server"
CssClass="form-control" MaxLength="200" />
</div>
</div>
</div>
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="TxtObservacionesPago"
Text="Notas" />
<asp:TextBox ID="TxtObservacionesPago" runat="server"
CssClass="form-control" TextMode="MultiLine" Rows="3"
MaxLength="1000" />
</div>
<hr />
<div class="row">
<div class="col-md-8">
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="DdlReciboAgregar"
Text="Agregar otro recibo" />
<asp:DropDownList ID="DdlReciboAgregar" runat="server"
CssClass="form-control select2me" Width="100%" />
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="TxtImporteAplicarAgregar"
Text="Importe" />
<asp:TextBox ID="TxtImporteAplicarAgregar" runat="server"
CssClass="form-control" />
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label>&nbsp;</label>
<asp:LinkButton ID="BtnAgregarRecibo" runat="server"
CssClass="btn blue btn-block"
CausesValidation="false"
OnClick="AgregarRecibo">
<i class="fa fa-plus" aria-hidden="true"></i>
Agregar
</asp:LinkButton>
</div>
</div>
</div>
<div class="table-responsive">
<asp:GridView ID="GvAplicaciones" runat="server"
AutoGenerateColumns="false"
GridLines="None"
CssClass="table table-striped table-hover Widthall"
DataKeyNames="CveConvenioRecibo"
EmptyDataText="Agregue al menos un recibo."
OnRowCommand="ComandoAplicacion">
<Columns>
<asp:BoundField DataField="Fraccionamiento" HeaderText="Fraccionamiento" />
<asp:BoundField DataField="Etapa" HeaderText="Etapa" />
<asp:BoundField DataField="NumeroRecibo" HeaderText="Recibo" />
<asp:BoundField DataField="Concepto" HeaderText="Concepto" />
<asp:BoundField DataField="SaldoPendiente" HeaderText="Saldo pendiente"
DataFormatString="{0:N2}" ItemStyle-HorizontalAlign="Right" />
<asp:TemplateField HeaderText="Importe aplicado">
<ItemTemplate>
<asp:TextBox ID="TxtImporteAplicado" runat="server"
CssClass="form-control"
Text='<%# Bind("ImporteAplicado", "{0:0.00}") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Acciones">
<ItemTemplate>
<asp:LinkButton runat="server"
CssClass="btn btn-sm red"
CommandName="EliminarAplicacion"
CausesValidation="false"
ToolTip="Quitar recibo">
<i class="fa fa-trash" aria-hidden="true"></i>
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
<p class="text-right">
<strong>Total aplicado:</strong>
<asp:Literal ID="LitTotalAplicado" runat="server" />
</p>
</div>
<div class="modal-footer">
<button type="button" class="btn default" data-dismiss="modal">Cancelar</button>
<asp:Button ID="BtnGuardarPago" runat="server"
CssClass="btn blue" Text="Guardar pago"
CausesValidation="false" OnClick="GuardarPago" />
</div>
</div>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</div>

View File

@@ -0,0 +1,999 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
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.Fraccionamientos;
using SIG.Web.AppCode.Session;
using SIG.Web.AppCode.SigControls;
namespace SIG.Web.UserControl.Clientes
{
public partial class PagosCliente : System.Web.UI.UserControl
{
private UserSessionModel Usuario
{
get { return AppServices.UserContext.GetCurrentUser(); }
}
private int? CveFraccionamientoFijo
{
get { return (int?)ViewState["CveFraccionamientoFijo"]; }
set { ViewState["CveFraccionamientoFijo"] = value; }
}
private bool MostrarFiltrosActual
{
get { return (bool?)ViewState["MostrarFiltrosActual"] ?? false; }
set { ViewState["MostrarFiltrosActual"] = value; }
}
private FiltroPagosCliente FiltroActual
{
get
{
return ViewState["FiltroActual"] as FiltroPagosCliente ??
new FiltroPagosCliente();
}
set { ViewState["FiltroActual"] = value; }
}
private List<AplicacionPagoConvenioCliente> AplicacionesCaptura
{
get
{
return ViewState["AplicacionesCaptura"] as List<AplicacionPagoConvenioCliente> ??
new List<AplicacionPagoConvenioCliente>();
}
set { ViewState["AplicacionesCaptura"] = value; }
}
private List<ReciboConvenioDisponibleCliente> RecibosDisponibles
{
get
{
return ViewState["RecibosDisponibles"] as List<ReciboConvenioDisponibleCliente> ??
new List<ReciboConvenioDisponibleCliente>();
}
set { ViewState["RecibosDisponibles"] = value; }
}
protected override void OnInit(EventArgs argumentos)
{
base.OnInit(argumentos);
ScriptManager administrador = ScriptManager.GetCurrent(Page);
if (administrador != null)
{
administrador.RegisterPostBackControl(BtnGuardarPago);
}
}
public void Cargar(
int? cveFraccionamiento,
bool mostrarFiltros)
{
CveFraccionamientoFijo = cveFraccionamiento;
MostrarFiltrosActual = mostrarFiltros;
PanelFiltros.Visible = mostrarFiltros;
FiltroPagosCliente filtro = FiltroActual;
filtro.CveFraccionamiento = cveFraccionamiento ?? filtro.CveFraccionamiento;
FiltroActual = filtro;
Refrescar();
}
protected void Consultar(object origen, EventArgs argumentos)
{
Refrescar();
}
protected void MostrarModalFiltros(object origen, EventArgs argumentos)
{
CargarOpcionesFiltros();
SincronizarModalFiltros();
UpFiltrosPagos.Update();
MostrarModal(ModalFiltrosPagosCliente.ClientID);
}
protected void AplicarFiltros(object origen, EventArgs argumentos)
{
FiltroActual = new FiltroPagosCliente
{
CveFraccionamiento = CveFraccionamientoFijo ?? LeerClave(DdlFraccionamientoFiltro),
CveFraccionamientoEtapa = LeerClave(DdlEtapaFiltro),
Agrupacion = string.IsNullOrWhiteSpace(DdlAgrupacionFiltro.SelectedValue)
? null
: DdlAgrupacionFiltro.SelectedValue
};
Refrescar();
OcultarModal(ModalFiltrosPagosCliente.ClientID);
}
protected void FiltrosCambiados(object origen, EventArgs argumentos)
{
var nombres = new HashSet<string>(
FiltrosPagos.GetFiltros().Select(x => x.Nombre));
FiltroPagosCliente filtro = FiltroActual;
if (!nombres.Contains("Fraccionamiento") && !CveFraccionamientoFijo.HasValue)
{
filtro.CveFraccionamiento = null;
}
if (!nombres.Contains("Etapa"))
{
filtro.CveFraccionamientoEtapa = null;
}
if (!nombres.Contains("Estado"))
{
filtro.Agrupacion = null;
}
FiltroActual = filtro;
Refrescar();
}
protected void EnlazarFila(object origen, GridViewRowEventArgs argumentos)
{
if (argumentos.Row.RowType != DataControlRowType.DataRow)
{
return;
}
var fila = argumentos.Row.DataItem as FilaPagoCliente;
if (fila == null)
{
return;
}
argumentos.Row.Attributes["data-sig-level"] =
fila.Nivel.ToString(CultureInfo.InvariantCulture);
if (fila.EsGrupo)
{
argumentos.Row.CssClass = "sig-grid-grupo";
argumentos.Row.Attributes["data-sig-group-row"] = "1";
argumentos.Row.Attributes["data-sig-group-id"] = fila.GroupId;
argumentos.Row.Attributes["data-sig-expanded-default"] = "true";
if (!string.IsNullOrWhiteSpace(fila.ParentGroupId))
{
argumentos.Row.Attributes["data-sig-parent-group"] =
fila.ParentGroupId;
}
int columnas = GvPagos.Columns
.Cast<DataControlField>()
.Count(columna => columna.Visible);
argumentos.Row.Cells.Clear();
var celda = new TableCell { ColumnSpan = columnas };
var boton = new HtmlGenericControl("button");
boton.Attributes["type"] = "button";
boton.Attributes["class"] = "sig-grid-alternar-grupo";
boton.Attributes["aria-expanded"] = "true";
var titulo = new HtmlGenericControl("span");
titulo.Attributes["class"] = "sig-grid-grupo-titulo";
titulo.InnerText = fila.TituloGrupo;
var flecha = new HtmlGenericControl("i");
flecha.Attributes["class"] =
"fa fa-chevron-up sig-grid-icono-agrupacion";
flecha.Attributes["aria-hidden"] = "true";
boton.Controls.Add(titulo);
boton.Controls.Add(flecha);
celda.Controls.Add(boton);
argumentos.Row.Cells.Add(celda);
return;
}
argumentos.Row.Attributes["data-sig-item-row"] = "1";
argumentos.Row.Attributes["data-sig-parent-group"] =
fila.ParentGroupId;
}
protected void ComandoPago(
object origen,
GridViewCommandEventArgs argumentos)
{
if (!string.Equals(argumentos.CommandName, "Pagar", StringComparison.Ordinal))
{
return;
}
var boton = argumentos.CommandSource as Control;
var fila = boton == null
? null
: boton.NamingContainer as GridViewRow;
if (fila == null || fila.RowIndex < 0)
{
return;
}
DataKey claves = GvPagos.DataKeys[fila.RowIndex];
if (Convert.ToBoolean(claves.Values["EsGrupo"]))
{
return;
}
int cveRecibo = Convert.ToInt32(claves.Values["CveConvenioRecibo"]);
AbrirCapturaPago(cveRecibo);
}
protected void AgregarRecibo(object origen, EventArgs argumentos)
{
CapturarImportesAplicaciones();
int cveRecibo;
decimal importe;
if (!int.TryParse(DdlReciboAgregar.SelectedValue, out cveRecibo) ||
cveRecibo <= 0 ||
!LeerDecimal(TxtImporteAplicarAgregar.Text, out importe) ||
importe <= 0m)
{
MostrarModal(ModalPagoConvenioCliente.ClientID);
Avisar("Seleccione un recibo y capture un importe mayor a cero.");
return;
}
List<AplicacionPagoConvenioCliente> aplicaciones = AplicacionesCaptura;
if (aplicaciones.Any(x => x.CveConvenioRecibo == cveRecibo))
{
MostrarModal(ModalPagoConvenioCliente.ClientID);
Avisar("El recibo ya está incluido en este pago.");
return;
}
ReciboConvenioDisponibleCliente recibo = RecibosDisponibles
.FirstOrDefault(x => x.CveConvenioRecibo == cveRecibo);
if (recibo == null || importe > recibo.SaldoPendiente)
{
MostrarModal(ModalPagoConvenioCliente.ClientID);
Avisar("El importe aplicado no puede ser mayor al saldo del recibo.");
return;
}
aplicaciones.Add(CrearAplicacion(recibo, importe));
AplicacionesCaptura = aplicaciones;
TxtImporteAplicarAgregar.Text = string.Empty;
EnlazarAplicaciones();
CargarComboRecibos();
UpCapturaPago.Update();
MostrarModal(ModalPagoConvenioCliente.ClientID);
}
protected void ComandoAplicacion(
object origen,
GridViewCommandEventArgs argumentos)
{
if (!string.Equals(
argumentos.CommandName,
"EliminarAplicacion",
StringComparison.Ordinal))
{
return;
}
CapturarImportesAplicaciones();
var boton = argumentos.CommandSource as Control;
var fila = boton == null
? null
: boton.NamingContainer as GridViewRow;
if (fila == null || fila.RowIndex < 0)
{
return;
}
int cveRecibo = Convert.ToInt32(
GvAplicaciones.DataKeys[fila.RowIndex].Value);
List<AplicacionPagoConvenioCliente> aplicaciones = AplicacionesCaptura;
aplicaciones.RemoveAll(x => x.CveConvenioRecibo == cveRecibo);
AplicacionesCaptura = aplicaciones;
EnlazarAplicaciones();
CargarComboRecibos();
UpCapturaPago.Update();
MostrarModal(ModalPagoConvenioCliente.ClientID);
}
protected void GuardarPago(object origen, EventArgs argumentos)
{
CapturarImportesAplicaciones();
decimal importePago;
DateTime fechaPago;
if (!LeerDecimal(TxtImportePago.Text, out importePago) ||
importePago <= 0m ||
!DateTime.TryParseExact(
TxtFechaPago.Text,
"yyyy-MM-dd",
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out fechaPago) ||
!ArchivoPago.HasFile)
{
MostrarModal(ModalPagoConvenioCliente.ClientID);
Avisar("Capture importe, fecha y comprobante del pago.");
return;
}
List<AplicacionPagoConvenioCliente> aplicaciones = AplicacionesCaptura;
if (aplicaciones.Count == 0 || aplicaciones.Any(x => x.ImporteAplicado <= 0m))
{
MostrarModal(ModalPagoConvenioCliente.ClientID);
Avisar("Vincule al menos un recibo con un importe mayor a cero.");
return;
}
decimal totalAplicado = aplicaciones.Sum(x => x.ImporteAplicado);
if (totalAplicado > importePago)
{
MostrarModal(ModalPagoConvenioCliente.ClientID);
Avisar("El total aplicado a recibos no puede ser mayor al importe de la transferencia.");
return;
}
foreach (AplicacionPagoConvenioCliente aplicacion in aplicaciones)
{
ReciboConvenioDisponibleCliente recibo = RecibosDisponibles
.FirstOrDefault(x => x.CveConvenioRecibo == aplicacion.CveConvenioRecibo);
if (recibo == null || aplicacion.ImporteAplicado > recibo.SaldoPendiente)
{
MostrarModal(ModalPagoConvenioCliente.ClientID);
Avisar("Uno de los importes aplicados excede el saldo disponible del recibo.");
return;
}
}
UserSessionModel usuario = Usuario;
var solicitud = new SolicitudPagoConvenioCliente
{
Importe = importePago,
FechaPago = fechaPago,
Referencia = TxtReferenciaPago.Text,
Banco = TxtBancoPago.Text,
NumeroOperacion = TxtNumeroOperacionPago.Text,
Observaciones = TxtObservacionesPago.Text,
NombreArchivo = ArchivoPago.FileName,
TipoContenido = ArchivoPago.PostedFile.ContentType,
TamanoBytes = ArchivoPago.PostedFile.ContentLength,
Aplicaciones = aplicaciones
};
var resultado = AppServices.ServicioPortalCliente.RegistrarPago(
solicitud,
ArchivoPago.PostedFile.InputStream,
usuario.CveUsuario,
usuario.NombreDominio);
if (!resultado.Success)
{
MostrarModal(ModalPagoConvenioCliente.ClientID);
Avisar(resultado.UserMessage);
return;
}
LimpiarCapturaPago();
Refrescar();
Avisar(
"Pago registrado; quedó pendiente de aprobación.",
TipoMensaje.ToastExito);
}
public string UrlComprobante(object cveConvenioPago)
{
int clave = Convert.ToInt32(cveConvenioPago);
return clave <= 0
? string.Empty
: ResolveUrl("~/Pages/Clientes/ComprobanteConvenioPago.ashx") +
"?id=" + clave.ToString(CultureInfo.InvariantCulture);
}
private void AbrirCapturaPago(int cveRecibo)
{
UserSessionModel usuario = Usuario;
int? filtroFraccionamiento = CveFraccionamientoFijo;
var recibos = AppServices.ServicioPortalCliente.ListarRecibosDisponibles(
filtroFraccionamiento,
usuario.CveUsuario,
usuario.NombreDominio);
if (!recibos.Success)
{
Avisar(recibos.UserMessage, TipoMensaje.MsgError);
return;
}
RecibosDisponibles = recibos.Data ?? new List<ReciboConvenioDisponibleCliente>();
ReciboConvenioDisponibleCliente inicial = RecibosDisponibles
.FirstOrDefault(x => x.CveConvenioRecibo == cveRecibo);
if (inicial == null)
{
Avisar("El recibo ya no tiene saldo disponible.");
Refrescar();
return;
}
AplicacionesCaptura = new List<AplicacionPagoConvenioCliente>
{
CrearAplicacion(inicial, inicial.SaldoPendiente)
};
TxtImportePago.Text = inicial.SaldoPendiente.ToString(
"0.00",
CultureInfo.InvariantCulture);
TxtFechaPago.Text = DateTime.Today.ToString(
"yyyy-MM-dd",
CultureInfo.InvariantCulture);
TxtReferenciaPago.Text = string.Empty;
TxtBancoPago.Text = string.Empty;
TxtNumeroOperacionPago.Text = string.Empty;
TxtObservacionesPago.Text = string.Empty;
TxtImporteAplicarAgregar.Text = string.Empty;
EnlazarAplicaciones();
CargarComboRecibos();
UpCapturaPago.Update();
MostrarModal(ModalPagoConvenioCliente.ClientID);
}
private void Refrescar()
{
UserSessionModel usuario = Usuario;
if (usuario == null)
{
return;
}
FiltroPagosCliente filtro = FiltroActual;
if (CveFraccionamientoFijo.HasValue)
{
filtro.CveFraccionamiento = CveFraccionamientoFijo;
}
var resultado = AppServices.ServicioPortalCliente.ListarPagos(
filtro,
usuario.CveUsuario,
usuario.NombreDominio);
if (!resultado.Success)
{
GvPagos.DataSource = new List<FilaPagoCliente>();
GvPagos.DataBind();
UpPagos.Update();
Avisar(resultado.UserMessage, TipoMensaje.MsgError);
return;
}
List<PagoConvenioClienteFila> pagos =
resultado.Data ?? new List<PagoConvenioClienteFila>();
GvPagos.DataSource = ConstruirFilas(pagos);
GvPagos.DataBind();
ActualizarFiltrosActivos(pagos);
UpPagos.Update();
}
private List<FilaPagoCliente> ConstruirFilas(
IEnumerable<PagoConvenioClienteFila> pagos)
{
var filas = new List<FilaPagoCliente>();
bool incluirFraccionamiento = !CveFraccionamientoFijo.HasValue;
foreach (var grupoFraccionamiento in pagos
.GroupBy(x => new { x.CveFraccionamiento, x.Fraccionamiento })
.OrderBy(x => x.Key.Fraccionamiento))
{
string idFraccionamiento =
"pago-fracc-" + grupoFraccionamiento.Key.CveFraccionamiento;
if (incluirFraccionamiento)
{
filas.Add(FilaPagoCliente.CrearGrupo(
idFraccionamiento,
null,
4,
grupoFraccionamiento.Key.Fraccionamiento));
}
foreach (var grupoEstado in grupoFraccionamiento
.GroupBy(x => x.Agrupacion)
.OrderBy(x => OrdenAgrupacion(x.Key)))
{
string idEstado = idFraccionamiento +
"-estado-" + NormalizarClave(grupoEstado.Key);
filas.Add(FilaPagoCliente.CrearGrupo(
idEstado,
incluirFraccionamiento ? idFraccionamiento : null,
3,
grupoEstado.Key));
foreach (var grupoConvenio in grupoEstado
.GroupBy(x => new
{
x.CveConvenio,
x.NumeroConvenio,
x.Concepto
})
.OrderBy(x => x.Key.NumeroConvenio)
.ThenBy(x => x.Key.Concepto))
{
string idConvenio = idEstado +
"-convenio-" + grupoConvenio.Key.CveConvenio +
"-" + NormalizarClave(grupoConvenio.Key.Concepto);
string titulo = "Convenio " + grupoConvenio.Key.NumeroConvenio;
if (!string.IsNullOrWhiteSpace(grupoConvenio.Key.Concepto))
{
titulo += " · " + grupoConvenio.Key.Concepto;
}
filas.Add(FilaPagoCliente.CrearGrupo(
idConvenio,
idEstado,
2,
titulo));
filas.AddRange(grupoConvenio
.OrderBy(x => x.Fecha)
.ThenBy(x => x.NumeroRecibo)
.Select(x => FilaPagoCliente.CrearDato(
idConvenio,
1,
x)));
}
}
}
return filas;
}
private void CapturarImportesAplicaciones()
{
List<AplicacionPagoConvenioCliente> aplicaciones = AplicacionesCaptura;
foreach (GridViewRow fila in GvAplicaciones.Rows)
{
if (fila.RowType != DataControlRowType.DataRow)
{
continue;
}
int cveRecibo = Convert.ToInt32(
GvAplicaciones.DataKeys[fila.RowIndex].Value);
var texto = fila.FindControl("TxtImporteAplicado") as TextBox;
decimal importe;
if (texto != null && LeerDecimal(texto.Text, out importe))
{
AplicacionPagoConvenioCliente aplicacion = aplicaciones
.FirstOrDefault(x => x.CveConvenioRecibo == cveRecibo);
if (aplicacion != null)
{
aplicacion.ImporteAplicado = importe;
}
}
}
AplicacionesCaptura = aplicaciones;
}
private void EnlazarAplicaciones()
{
GvAplicaciones.DataSource = AplicacionesCaptura;
GvAplicaciones.DataBind();
LitTotalAplicado.Text = AplicacionesCaptura
.Sum(x => x.ImporteAplicado)
.ToString("N2", CultureInfo.CurrentCulture);
}
private void CargarComboRecibos()
{
HashSet<int> seleccionados = new HashSet<int>(
AplicacionesCaptura.Select(x => x.CveConvenioRecibo));
DdlReciboAgregar.Items.Clear();
DdlReciboAgregar.Items.Add(new ListItem("Seleccione", string.Empty));
foreach (ReciboConvenioDisponibleCliente recibo in RecibosDisponibles
.Where(x => !seleccionados.Contains(x.CveConvenioRecibo))
.OrderBy(x => x.Fraccionamiento)
.ThenBy(x => x.Etapa)
.ThenBy(x => x.FechaVencimiento))
{
DdlReciboAgregar.Items.Add(new ListItem(
recibo.Descripcion,
recibo.CveConvenioRecibo.ToString(CultureInfo.InvariantCulture)));
}
}
private void LimpiarCapturaPago()
{
AplicacionesCaptura = new List<AplicacionPagoConvenioCliente>();
RecibosDisponibles = new List<ReciboConvenioDisponibleCliente>();
TxtImportePago.Text = string.Empty;
TxtFechaPago.Text = string.Empty;
TxtReferenciaPago.Text = string.Empty;
TxtBancoPago.Text = string.Empty;
TxtNumeroOperacionPago.Text = string.Empty;
TxtObservacionesPago.Text = string.Empty;
TxtImporteAplicarAgregar.Text = string.Empty;
}
private void CargarOpcionesFiltros()
{
UserSessionModel usuario = Usuario;
var resultado = AppServices.ServicioPortalCliente.ListarDesarrollos(
usuario.CveUsuario,
usuario.NombreDominio);
List<ModeloFilaDesarrollos> desarrollos = resultado.Success
? resultado.Data ?? new List<ModeloFilaDesarrollos>()
: new List<ModeloFilaDesarrollos>();
DdlFraccionamientoFiltro.Items.Clear();
DdlFraccionamientoFiltro.Items.Add(new ListItem("Todos", string.Empty));
foreach (var fraccionamiento in desarrollos
.Where(x => x.CveFraccionamiento > 0)
.GroupBy(x => x.CveFraccionamiento)
.Select(x => x.First())
.OrderBy(x => x.Fraccionamiento))
{
DdlFraccionamientoFiltro.Items.Add(new ListItem(
fraccionamiento.Fraccionamiento,
fraccionamiento.CveFraccionamiento.ToString(
CultureInfo.InvariantCulture)));
}
DdlEtapaFiltro.Items.Clear();
DdlEtapaFiltro.Items.Add(new ListItem("Todas", string.Empty));
foreach (var etapa in desarrollos
.Where(x => x.CveFraccionamientoEtapa.HasValue)
.OrderBy(x => x.Fraccionamiento)
.ThenBy(x => x.Etapa))
{
DdlEtapaFiltro.Items.Add(new ListItem(
etapa.Fraccionamiento + " · " + etapa.Etapa,
etapa.CveFraccionamientoEtapa.Value.ToString(
CultureInfo.InvariantCulture)));
}
if (!resultado.Success)
{
Avisar(resultado.UserMessage, TipoMensaje.MsgError);
}
}
private void SincronizarModalFiltros()
{
FiltroPagosCliente filtro = FiltroActual;
Seleccionar(DdlFraccionamientoFiltro, filtro.CveFraccionamiento);
Seleccionar(DdlEtapaFiltro, filtro.CveFraccionamientoEtapa);
DdlAgrupacionFiltro.SelectedValue = filtro.Agrupacion ?? string.Empty;
}
private void ActualizarFiltrosActivos(
IList<PagoConvenioClienteFila> pagos)
{
if (!MostrarFiltrosActual)
{
return;
}
FiltroPagosCliente filtro = FiltroActual;
var activos = new List<FiltroActivo>();
if (filtro.CveFraccionamiento.HasValue)
{
string fraccionamiento = pagos
.Where(x => x.CveFraccionamiento == filtro.CveFraccionamiento.Value)
.Select(x => x.Fraccionamiento)
.FirstOrDefault();
activos.Add(new FiltroActivo
{
Nombre = "Fraccionamiento",
Titulo = "Fraccionamiento",
Descripcion = fraccionamiento ?? filtro.CveFraccionamiento.Value.ToString(),
Orden = 1,
Visible = true
});
}
if (filtro.CveFraccionamientoEtapa.HasValue)
{
string etapa = pagos
.Where(x => x.CveFraccionamientoEtapa == filtro.CveFraccionamientoEtapa.Value)
.Select(x => x.Etapa)
.FirstOrDefault();
activos.Add(new FiltroActivo
{
Nombre = "Etapa",
Titulo = "Etapa",
Descripcion = etapa ?? filtro.CveFraccionamientoEtapa.Value.ToString(),
Orden = 2,
Visible = true
});
}
if (!string.IsNullOrWhiteSpace(filtro.Agrupacion))
{
activos.Add(new FiltroActivo
{
Nombre = "Estado",
Titulo = "Estado",
Descripcion = filtro.Agrupacion,
Orden = 3,
Visible = true
});
}
FiltrosPagos.SetFiltros(activos);
}
private static AplicacionPagoConvenioCliente CrearAplicacion(
ReciboConvenioDisponibleCliente recibo,
decimal importe)
{
return new AplicacionPagoConvenioCliente
{
CveConvenioRecibo = recibo.CveConvenioRecibo,
NumeroRecibo = recibo.NumeroRecibo,
Fraccionamiento = recibo.Fraccionamiento,
Etapa = recibo.Etapa,
Concepto = recibo.Concepto,
SaldoPendiente = recibo.SaldoPendiente,
ImporteAplicado = importe
};
}
private void MostrarModal(string id)
{
PageScriptRegistrar.RegistraScript(
Page,
"jQuery('#" + HttpUtility.JavaScriptStringEncode(id) + "').modal('show')");
}
private void OcultarModal(string id)
{
PageScriptRegistrar.RegistraScript(
Page,
"jQuery('#" + HttpUtility.JavaScriptStringEncode(id) + "').modal('hide')");
}
private void Avisar(
string mensaje,
TipoMensaje tipo = TipoMensaje.MsgAdvertencia)
{
PageAlertManager.Alert(Page, mensaje, tipo);
}
private static bool LeerDecimal(
string texto,
out decimal valor)
{
return decimal.TryParse(
texto,
NumberStyles.Number,
CultureInfo.CurrentCulture,
out valor) ||
decimal.TryParse(
texto,
NumberStyles.Number,
CultureInfo.InvariantCulture,
out valor);
}
private static int? LeerClave(DropDownList lista)
{
int valor;
return int.TryParse(lista.SelectedValue, out valor) && valor > 0
? (int?)valor
: null;
}
private static void Seleccionar(
DropDownList lista,
int? valor)
{
lista.ClearSelection();
string clave = valor.HasValue
? valor.Value.ToString(CultureInfo.InvariantCulture)
: string.Empty;
ListItem opcion = lista.Items.FindByValue(clave);
if (opcion != null)
{
opcion.Selected = true;
}
}
private static int OrdenAgrupacion(string agrupacion)
{
if (string.Equals(agrupacion, "Pendientes", StringComparison.OrdinalIgnoreCase))
{
return 1;
}
if (string.Equals(agrupacion, "Pagados", StringComparison.OrdinalIgnoreCase))
{
return 2;
}
if (string.Equals(agrupacion, "Aprobados", StringComparison.OrdinalIgnoreCase))
{
return 3;
}
return 99;
}
private static string NormalizarClave(string texto)
{
return new string((texto ?? string.Empty)
.ToLowerInvariant()
.Select(caracter => char.IsLetterOrDigit(caracter) ? caracter : '-')
.ToArray());
}
[Serializable]
public sealed class FilaPagoCliente
{
public bool EsGrupo { get; set; }
public string GroupId { get; set; }
public string ParentGroupId { get; set; }
public int Nivel { get; set; }
public string TituloGrupo { get; set; }
public PagoConvenioClienteFila Pago { get; set; }
public string TipoRegistro
{
get { return Pago == null ? string.Empty : Pago.TipoRegistro; }
}
public int CveConvenioRecibo
{
get { return Pago == null ? 0 : Pago.CveConvenioRecibo.GetValueOrDefault(); }
}
public int CveConvenioPago
{
get { return Pago == null ? 0 : Pago.CveConvenioPago.GetValueOrDefault(); }
}
public int CveFraccionamiento
{
get { return Pago == null ? 0 : Pago.CveFraccionamiento; }
}
public string Fraccionamiento
{
get { return Pago == null ? string.Empty : Pago.Fraccionamiento; }
}
public string Etapa
{
get { return Pago == null ? string.Empty : Pago.Etapa; }
}
public string NumeroConvenio
{
get { return Pago == null ? string.Empty : Pago.NumeroConvenio; }
}
public string DescripcionPrincipal
{
get
{
if (Pago == null)
{
return string.Empty;
}
return string.Equals(
Pago.TipoRegistro,
"RECIBO",
StringComparison.OrdinalIgnoreCase)
? string.Join(
" · ",
new[] { Pago.Concepto, Pago.NumeroRecibo }
.Where(x => !string.IsNullOrWhiteSpace(x)))
: Pago.RecibosAplicados;
}
}
public decimal Importe
{
get { return Pago == null ? 0m : Pago.Importe; }
}
public decimal SaldoPendiente
{
get { return Pago == null ? 0m : Pago.SaldoPendiente; }
}
public DateTime Fecha
{
get { return Pago == null ? DateTime.MinValue : Pago.Fecha; }
}
public string Estatus
{
get { return Pago == null ? string.Empty : Pago.Estatus; }
}
public string NombreArchivo
{
get { return Pago == null ? string.Empty : Pago.NombreArchivo; }
}
public bool PuedePagar
{
get { return Pago != null && Pago.EsReciboPendiente; }
}
public static FilaPagoCliente CrearGrupo(
string groupId,
string parentGroupId,
int nivel,
string titulo)
{
return new FilaPagoCliente
{
EsGrupo = true,
GroupId = groupId,
ParentGroupId = parentGroupId,
Nivel = nivel,
TituloGrupo = titulo
};
}
public static FilaPagoCliente CrearDato(
string parentGroupId,
int nivel,
PagoConvenioClienteFila pago)
{
return new FilaPagoCliente
{
EsGrupo = false,
ParentGroupId = parentGroupId,
Nivel = nivel,
Pago = pago
};
}
}
}
}

View File

@@ -0,0 +1,49 @@
<%@ Control Language="C#" AutoEventWireup="false" CodeFile="TramitesCliente.ascx.cs"
Inherits="SIG.Web.UserControl.Clientes.TramitesCliente" %>
<asp:UpdatePanel ID="UpTramites" runat="server"
UpdateMode="Conditional" ChildrenAsTriggers="true">
<ContentTemplate>
<div class="table-responsive">
<asp:GridView ID="GvTramites" runat="server"
AutoGenerateColumns="false"
GridLines="None"
CssClass="table table-striped table-hover Widthall"
DataKeyNames="CveSolicitud"
EmptyDataText="No hay trámites para este fraccionamiento."
OnRowCommand="ComandoTramite">
<Columns>
<asp:BoundField DataField="Etapa" HeaderText="Etapa" />
<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:TemplateField HeaderText="Acciones">
<ItemTemplate>
<asp:LinkButton ID="BtnEnviarRevision" runat="server"
CssClass="btn btn-sm blue"
CommandName="EnviarRevision"
CausesValidation="false"
Visible='<%# Convert.ToBoolean(Eval("PuedeEnviarRevision")) %>'>
<i class="fa fa-paper-plane" aria-hidden="true"></i>
Enviar a revisión
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
</ContentTemplate>
</asp:UpdatePanel>

View File

@@ -0,0 +1,140 @@
using System;
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.Session;
namespace SIG.Web.UserControl.Clientes
{
public partial class TramitesCliente : System.Web.UI.UserControl
{
public event EventHandler Cambiado;
private UserSessionModel Usuario
{
get { return AppServices.UserContext.GetCurrentUser(); }
}
private int CveFraccionamientoActual
{
get
{
return (int?)ViewState["CveFraccionamientoActual"] ?? 0;
}
set
{
ViewState["CveFraccionamientoActual"] = value;
}
}
public void Cargar(int cveFraccionamiento)
{
CveFraccionamientoActual = cveFraccionamiento;
Refrescar();
}
protected void ComandoTramite(
object origen,
GridViewCommandEventArgs argumentos)
{
if (!string.Equals(
argumentos.CommandName,
"EnviarRevision",
StringComparison.Ordinal))
{
return;
}
var boton = argumentos.CommandSource as Control;
var fila = boton == null
? null
: boton.NamingContainer as GridViewRow;
if (fila == null || fila.RowIndex < 0)
{
return;
}
int cveSolicitud = Convert.ToInt32(
GvTramites.DataKeys[fila.RowIndex].Value);
UserSessionModel usuario = Usuario;
if (usuario == null)
{
Avisar(
"La sesión ya no está disponible.",
TipoMensaje.MsgAdvertencia);
return;
}
var resultado = AppServices.ServicioPortalCliente.EnviarRevision(
cveSolicitud,
CveFraccionamientoActual,
usuario.CveUsuario,
usuario.NombreDominio);
if (!resultado.Success)
{
Avisar(
resultado.UserMessage,
TipoMensaje.MsgAdvertencia);
return;
}
Refrescar();
Avisar(
"El trámite fue enviado a revisión.",
TipoMensaje.ToastExito);
if (Cambiado != null)
{
Cambiado(this, EventArgs.Empty);
}
}
private void Refrescar()
{
UserSessionModel usuario = Usuario;
if (usuario == null || CveFraccionamientoActual <= 0)
{
GvTramites.DataSource = new List<TramiteClienteListado>();
GvTramites.DataBind();
UpTramites.Update();
return;
}
var resultado = AppServices.ServicioPortalCliente.ListarTramites(
CveFraccionamientoActual,
usuario.CveUsuario,
usuario.NombreDominio);
if (!resultado.Success)
{
GvTramites.DataSource = new List<TramiteClienteListado>();
GvTramites.DataBind();
UpTramites.Update();
Avisar(resultado.UserMessage, TipoMensaje.MsgError);
return;
}
GvTramites.DataSource =
resultado.Data ?? new List<TramiteClienteListado>();
GvTramites.DataBind();
UpTramites.Update();
}
private void Avisar(
string mensaje,
TipoMensaje tipo)
{
PageAlertManager.Alert(
Page,
mensaje,
tipo);
}
}
}

View File

@@ -0,0 +1,557 @@
<%@ Control Language="C#" AutoEventWireup="false" CodeFile="ConveniosListado.ascx.cs" Inherits="SIG.Web.UserControl.ConveniosListado" %>
<asp:UpdatePanel ID="UpConvenios" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="true">
<ContentTemplate>
<div class="sig-convenios-listado">
<div class="sig-convenios-acciones">
<asp:LinkButton
ID="BtnAgregarConvenio"
runat="server"
CssClass="btn blue"
CausesValidation="false"
OnClick="AgregarConvenio">
<i class="fa fa-plus" aria-hidden="true"></i>
Agregar convenio
</asp:LinkButton>
</div>
<div class="table-responsive">
<asp:GridView
ID="GvConvenios"
runat="server"
AutoGenerateColumns="false"
GridLines="None"
CssClass="table table-striped table-hover Widthall"
DataKeyNames="CveConvenio"
EmptyDataText="No hay convenios para mostrar."
OnRowCommand="ComandoConvenio">
<Columns>
<asp:BoundField DataField="NumeroConvenio" HeaderText="Convenio" />
<asp:BoundField DataField="NumeroOficio" HeaderText="Oficio" />
<asp:BoundField DataField="Cliente" HeaderText="Desarrollador" />
<asp:TemplateField HeaderText="Fraccionamiento · Etapa">
<ItemTemplate>
<%#: Eval("Fraccionamiento") %> · <%#: Eval("Etapa") %>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Estatus" HeaderText="Estado" />
<asp:BoundField
DataField="ImporteConvenio"
HeaderText="Importe"
DataFormatString="{0:N2}"
ItemStyle-HorizontalAlign="Right" />
<asp:TemplateField HeaderText="Saldo pendiente" ItemStyle-HorizontalAlign="Right">
<ItemTemplate>
<span class='<%# Convert.ToDecimal(Eval("SaldoPendiente")) > 0 ? "sig-convenio-saldo-pendiente" : "" %>'>
<%#: Eval("SaldoPendiente", "{0:N2}") %>
</span>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Acciones">
<ItemTemplate>
<asp:LinkButton
ID="BtnDetalleConvenio"
runat="server"
CommandName="Detalle"
Text="Detalle"
CssClass="btn btn-sm blue"
CausesValidation="false" />
<asp:LinkButton
ID="BtnEliminarConvenio"
runat="server"
CommandName="Eliminar"
Text="Eliminar"
CssClass="btn btn-sm red"
CausesValidation="false"
Visible='<%# MostrarEliminar(Container.DataItem) %>'
OnClientClick="return confirm('¿Eliminar este convenio? Esta acción no se puede deshacer.');" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
</div>
</ContentTemplate>
</asp:UpdatePanel>
<div
id="ModalCapturaConvenio"
runat="server"
class="modal fade sig-convenio-modal sig-convenio-modal-captura"
tabindex="-1"
role="dialog"
aria-label="Agregar convenio">
<div class="modal-dialog modal-lg">
<asp:UpdatePanel
ID="UpCapturaConvenio"
runat="server"
UpdateMode="Conditional"
ChildrenAsTriggers="true">
<ContentTemplate>
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Cerrar">&times;</button>
<h4>Agregar convenio</h4>
</div>
<div class="modal-body">
<div class="row sig-convenio-contexto-captura">
<div class="col-md-6">
<div class="form-group">
<asp:Label
runat="server"
AssociatedControlID="DdlClienteCaptura"
Text="Cliente" />
<asp:DropDownList
ID="DdlClienteCaptura"
runat="server"
CssClass="form-control select2me"
Width="100%"
AutoPostBack="true"
OnSelectedIndexChanged="ClienteCapturaCambiado" />
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<asp:Label
runat="server"
AssociatedControlID="DdlEtapaCaptura"
Text="Fraccionamiento · Etapa" />
<asp:DropDownList
ID="DdlEtapaCaptura"
runat="server"
CssClass="form-control select2me"
Width="100%" />
</div>
</div>
</div>
<div class="sig-convenio-seccion-titulo">Viviendas en desarrollo</div>
<div class="row">
<div class="col-md-3">
<div class="form-group">
<asp:Label
runat="server"
AssociatedControlID="TxtViviendasAutorizadas"
Text="Autorizadas" />
<asp:TextBox
ID="TxtViviendasAutorizadas"
runat="server"
CssClass="form-control"
MaxLength="9" />
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<asp:Label
runat="server"
AssociatedControlID="TxtViviendasEnConvenio"
Text="En convenio" />
<asp:TextBox
ID="TxtViviendasEnConvenio"
runat="server"
CssClass="form-control"
MaxLength="9" />
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<asp:Label
runat="server"
AssociatedControlID="TxtViviendasPendientes"
Text="Pendientes" />
<asp:TextBox
ID="TxtViviendasPendientes"
runat="server"
CssClass="form-control"
MaxLength="9" />
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<asp:Label
runat="server"
AssociatedControlID="TxtViviendasContratadas"
Text="Contratadas" />
<asp:TextBox
ID="TxtViviendasContratadas"
runat="server"
CssClass="form-control"
MaxLength="9" />
</div>
</div>
</div>
<div class="row">
<div class="col-md-3">
<div class="form-group">
<asp:Label
runat="server"
AssociatedControlID="TxtNumeroConvenio"
Text="N° convenio" />
<asp:TextBox
ID="TxtNumeroConvenio"
runat="server"
CssClass="form-control"
MaxLength="100" />
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<asp:Label
runat="server"
AssociatedControlID="TxtNumeroOficio"
Text="N° oficio" />
<asp:TextBox
ID="TxtNumeroOficio"
runat="server"
CssClass="form-control"
MaxLength="100" />
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<asp:Label
runat="server"
AssociatedControlID="TxtFechaConvenio"
Text="Fecha convenio" />
<asp:TextBox
ID="TxtFechaConvenio"
runat="server"
CssClass="form-control"
TextMode="Date" />
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<asp:Label
runat="server"
AssociatedControlID="TxtObservacionesConvenio"
Text="Observaciones" />
<asp:TextBox
ID="TxtObservacionesConvenio"
runat="server"
CssClass="form-control"
MaxLength="1000" />
</div>
</div>
</div>
<div class="sig-convenio-concepto-captura">
<div class="sig-convenio-seccion-titulo">Agregar concepto</div>
<div class="row">
<div class="col-md-5">
<div class="form-group">
<asp:Label
runat="server"
AssociatedControlID="DdlConceptoCaptura"
Text="Concepto" />
<asp:DropDownList
ID="DdlConceptoCaptura"
runat="server"
CssClass="form-control select2me"
Width="100%" />
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<asp:Label
runat="server"
AssociatedControlID="TxtImporteConcepto"
Text="Importe" />
<asp:TextBox
ID="TxtImporteConcepto"
runat="server"
CssClass="form-control"
MaxLength="30" />
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<asp:Label
runat="server"
AssociatedControlID="DdlTipoConcepto"
Text="Tipo" />
<asp:DropDownList
ID="DdlTipoConcepto"
runat="server"
CssClass="form-control select2me"
Width="100%">
<asp:ListItem Value="PESOS" Text="PESOS" />
<asp:ListItem Value="UDIS" Text="UDIS" />
<asp:ListItem Value="UMA" Text="UMA" />
</asp:DropDownList>
</div>
</div>
<div class="col-md-1">
<div class="form-group">
<asp:Label
runat="server"
AssociatedControlID="TxtNumeroPagosConcepto"
Text="Pagos" />
<asp:TextBox
ID="TxtNumeroPagosConcepto"
runat="server"
CssClass="form-control"
Text="1"
MaxLength="2" />
</div>
</div>
<div class="col-md-2 sig-convenio-agregar-concepto-boton">
<asp:LinkButton
ID="BtnAgregarConcepto"
runat="server"
CssClass="btn blue"
CausesValidation="false"
OnClick="AgregarConcepto">
<i class="fa fa-plus" aria-hidden="true"></i>
Agregar
</asp:LinkButton>
</div>
</div>
</div>
<div class="table-responsive sig-convenio-captura-grid">
<asp:GridView
ID="GvCapturaConvenio"
runat="server"
AutoGenerateColumns="false"
GridLines="None"
CssClass="table table-striped table-hover Widthall sig-grid-agrupado"
EmptyDataText="Agregue los conceptos que formarán el convenio."
OnRowDataBound="EnlazarFilaCaptura"
OnRowCommand="ComandoCaptura">
<Columns>
<asp:TemplateField HeaderText="Concepto / Recibo">
<ItemTemplate>
<asp:PlaceHolder
ID="PhConceptoFila"
runat="server"
Visible='<%# Convert.ToBoolean(Eval("EsConcepto")) %>'>
<button
type="button"
class="sig-grid-alternar-grupo sig-convenio-concepto-texto"
aria-expanded="true"
title="Ocultar/mostrar parcialidades">
<strong><%#: Eval("Concepto") %></strong>
</button>
</asp:PlaceHolder>
<asp:PlaceHolder
ID="PhReciboFila"
runat="server"
Visible='<%# !Convert.ToBoolean(Eval("EsConcepto")) %>'>
<%#: Eval("NumeroReciboMostrar") %>
</asp:PlaceHolder>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Importe">
<ItemTemplate>
<asp:Label
ID="LblImporteConceptoFila"
runat="server"
Visible='<%# Convert.ToBoolean(Eval("EsConcepto")) %>'
Text='<%# Eval("Importe", "{0:N6}") %>' />
<asp:TextBox
ID="TxtImporteParcialidad"
runat="server"
Visible='<%# !Convert.ToBoolean(Eval("EsConcepto")) %>'
CssClass="form-control input-sm"
Text='<%# Eval("ImporteTexto") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Tipo">
<ItemTemplate>
<asp:Label
ID="LblTipoConceptoFila"
runat="server"
Visible='<%# Convert.ToBoolean(Eval("EsConcepto")) %>'
Text='<%#: Eval("Tipo") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Pagos">
<ItemTemplate>
<asp:Label
ID="LblPagosConceptoFila"
runat="server"
Visible='<%# Convert.ToBoolean(Eval("EsConcepto")) %>'
Text='<%#: Eval("NumeroPagos") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Vencimiento">
<ItemTemplate>
<asp:TextBox
ID="TxtVencimientoParcialidad"
runat="server"
Visible='<%# !Convert.ToBoolean(Eval("EsConcepto")) %>'
CssClass="form-control input-sm"
TextMode="Date"
Text='<%# Eval("FechaVencimientoTexto") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Estado">
<ItemTemplate>
<asp:Label
ID="LblEstadoParcialidad"
runat="server"
Visible='<%# !Convert.ToBoolean(Eval("EsConcepto")) %>'
Text='<%#: Eval("Estatus") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Acciones">
<ItemTemplate>
<asp:PlaceHolder
ID="PhAccionesConcepto"
runat="server"
Visible='<%# Convert.ToBoolean(Eval("EsConcepto")) %>'>
<span class="sig-convenio-acciones-concepto">
<asp:LinkButton
ID="BtnAgregarParcialidad"
runat="server"
CssClass="btn btn-sm blue"
CommandName="AgregarParcialidad"
CommandArgument='<%# Eval("ComandoClave") %>'
CausesValidation="false"
ToolTip="Agregar parcialidad">
<i class="fa fa-plus" aria-hidden="true"></i>
</asp:LinkButton>
<asp:LinkButton
ID="BtnEliminarConceptoFila"
runat="server"
CssClass="btn btn-sm red"
CommandName="EliminarConcepto"
CommandArgument='<%# Eval("ComandoClave") %>'
CausesValidation="false"
ToolTip="Eliminar concepto">
<i class="fa fa-trash" aria-hidden="true"></i>
</asp:LinkButton>
<button
type="button"
class="btn btn-sm default sig-grid-alternar-grupo-accion sig-convenio-alternar-concepto"
aria-expanded="true"
title="Ocultar/mostrar parcialidades">
<i
class="fa fa-chevron-up sig-grid-icono-agrupacion"
aria-hidden="true"></i>
</button>
</span>
</asp:PlaceHolder>
<asp:LinkButton
ID="BtnEliminarParcialidad"
runat="server"
Visible='<%# !Convert.ToBoolean(Eval("EsConcepto")) %>'
CssClass="btn btn-sm red"
CommandName="EliminarParcialidad"
CommandArgument='<%# Eval("ComandoClave") %>'
CausesValidation="false"
ToolTip="Eliminar parcialidad">
<i class="fa fa-trash" aria-hidden="true"></i>
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn default" data-dismiss="modal">Cancelar</button>
<asp:Button
ID="BtnGuardarConvenio"
runat="server"
Text="Guardar convenio"
CssClass="btn green"
OnClick="GuardarConvenio" />
</div>
</div>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</div>
<div
id="ModalDetalleConvenio"
runat="server"
class="modal fade sig-convenio-modal"
tabindex="-1"
role="dialog"
aria-label="Detalle del convenio">
<div class="modal-dialog modal-lg">
<asp:UpdatePanel
ID="UpDetalle"
runat="server"
UpdateMode="Conditional"
ChildrenAsTriggers="true">
<ContentTemplate>
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Cerrar">&times;</button>
<h4>
<asp:Literal ID="LitTituloDetalle" runat="server" Mode="Encode" />
</h4>
</div>
<div class="modal-body">
<div class="sig-convenio-resumen">
<asp:Literal ID="LitResumenDetalle" runat="server" />
</div>
<div class="table-responsive">
<asp:GridView
ID="GvDetalle"
runat="server"
AutoGenerateColumns="false"
GridLines="None"
CssClass="table table-hover Widthall sig-grid-agrupado"
EmptyDataText="El convenio no tiene conceptos."
OnRowDataBound="EnlazarFilaDetalle">
<Columns>
<asp:BoundField DataField="NumeroRecibo" HeaderText="Recibo" />
<asp:BoundField DataField="Importe" HeaderText="Importe" DataFormatString="{0:N2}" ItemStyle-HorizontalAlign="Right" />
<asp:BoundField DataField="ImportePagado" HeaderText="Pagado" DataFormatString="{0:N2}" ItemStyle-HorizontalAlign="Right" />
<asp:BoundField DataField="SaldoPendiente" HeaderText="Saldo" DataFormatString="{0:N2}" ItemStyle-HorizontalAlign="Right" />
<asp:BoundField DataField="FechaVencimiento" HeaderText="Vencimiento" DataFormatString="{0:dd/MM/yyyy}" />
<asp:BoundField DataField="Estatus" HeaderText="Estado" />
</Columns>
</asp:GridView>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn default" data-dismiss="modal">Cerrar</button>
</div>
</div>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</div>

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,7 @@
<%@ Register TagPrefix="etapa" TagName="SupervisionesEtapa" Src="~/UserControl/SupervisionesEtapa.ascx" %> <%@ Register TagPrefix="etapa" TagName="SupervisionesEtapa" Src="~/UserControl/SupervisionesEtapa.ascx" %>
<%@ Register TagPrefix="etapa" TagName="EstatusSolicitud" Src="~/UserControl/EstatusSolicitud.ascx" %> <%@ Register TagPrefix="etapa" TagName="EstatusSolicitud" Src="~/UserControl/EstatusSolicitud.ascx" %>
<%@ Register TagPrefix="etapa" TagName="CondicionesSolicitud" Src="~/UserControl/CondicionesSolicitud.ascx" %> <%@ Register TagPrefix="etapa" TagName="CondicionesSolicitud" Src="~/UserControl/CondicionesSolicitud.ascx" %>
<%@ Register TagPrefix="etapa" TagName="ConveniosListado" Src="~/UserControl/ConveniosListado.ascx" %>
<asp:UpdatePanel ID="UpBuscadorEtapas" runat="server" UpdateMode="Conditional"> <asp:UpdatePanel ID="UpBuscadorEtapas" runat="server" UpdateMode="Conditional">
<ContentTemplate> <ContentTemplate>
<sig:BuscadorCatalogo ID="BuscadorEtapas" runat="server" <sig:BuscadorCatalogo ID="BuscadorEtapas" runat="server"
@@ -186,7 +187,7 @@
</ajax:TabPanel> </ajax:TabPanel>
<ajax:TabPanel ID="PestanaConvenios" runat="server" HeaderText="Convenios"> <ajax:TabPanel ID="PestanaConvenios" runat="server" HeaderText="Convenios">
<ContentTemplate> <ContentTemplate>
<etapa:ConveniosListado ID="UcConvenios" runat="server" />
</ContentTemplate> </ContentTemplate>
</ajax:TabPanel> </ajax:TabPanel>
<ajax:TabPanel ID="PestanaCondicionesEtapa" runat="server" HeaderText="Condiciones"> <ajax:TabPanel ID="PestanaCondicionesEtapa" runat="server" HeaderText="Condiciones">

View File

@@ -7,6 +7,7 @@ using System.Web.UI.WebControls;
using SIG.Web.AppCode.Configuration; using SIG.Web.AppCode.Configuration;
using SIG.Web.AppCode.Infrastructure.WebForms; using SIG.Web.AppCode.Infrastructure.WebForms;
using SIG.Web.AppCode.Models.Fraccionamientos; using SIG.Web.AppCode.Models.Fraccionamientos;
using SIG.Web.AppCode.Models.Convenios;
using SIG.Web.AppCode.Models.Tramites; using SIG.Web.AppCode.Models.Tramites;
using SIG.Web.AppCode.Security; using SIG.Web.AppCode.Security;
using SIG.Web.AppCode.Session; using SIG.Web.AppCode.Session;
@@ -93,6 +94,7 @@ namespace SIG.Web.UserControl
CargarTiposCatalogo(); CargarTiposCatalogo();
CargarLotes(); CargarLotes();
UcSupervisiones.Cargar(); UcSupervisiones.Cargar();
UcConvenios.Cargar(new FiltroConvenios { CveFraccionamientoEtapa = CveEtapaActual });
CargarCondiciones(); CargarCondiciones();
BuscadorEtapas.SelectedValue = CveEtapaActual.ToString(CultureInfo.InvariantCulture); BuscadorEtapas.SelectedValue = CveEtapaActual.ToString(CultureInfo.InvariantCulture);
BuscadorEtapas.Text = LitContexto.Text; BuscadorEtapas.Text = LitContexto.Text;