diff --git a/AGENTS.md b/AGENTS.md index c98da90..c8b0c3e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -55,6 +55,11 @@ Database --- +## Terminología de usuarios y asociado CANADEVI + +- Los usuarios que no son clientes se denominan **usuarios de Agua de Hermosillo** o **mojados**. +- Sólo los usuarios de Agua de Hermosillo (mojados) pueden activar o desactivar **Asociado CANADEVI** en el registro de un desarrollador. Los usuarios clientes pueden consultar ese dato, pero no modificarlo. La restricción debe aplicarse también en servidor al guardar, no sólo en la interfaz. + ## Source code readability rules All generated or modified source code must be formatted for human maintenance. @@ -88,6 +93,11 @@ All generated or modified source code must be formatted for human maintenance. ## Mandatory complementary instruction files +- Antes de trabajar en cada solicitud del proyecto, leer `AGENTS.md` y los agentes complementarios aplicables. Nunca omitirlos al corregir errores o reutilizar código existente; verificar también el código que se conserva. +- El CSS y JavaScript específicos de una página `.aspx` deben permanecer dentro de ese mismo `.aspx`: CSS en un bloque ` + + + + +
  • + +
  • +
    +
    +
    + + +
    + + +
    +
    + +
    + + +

    Intervalos por día

    +

    Puede agregar varios intervalos por día. Si la hora de fin es menor que la de inicio, el intervalo termina al día siguiente.

    + + Agregar horario + + +

    Los cambios de intervalos se aplican al guardar el turno.

    +
    + + + + + + + + + + + + + + + + + +
    +
    +
    + + Guardar turno + +
    +
    + + Eliminar turno + + +
    +
    +
    +
    + + + + +

    Procesando turno...

    +
    +
    + +
    + + + + diff --git a/SIG.Web/Pages/Catalogos/TurnoDetalle.aspx.cs b/SIG.Web/Pages/Catalogos/TurnoDetalle.aspx.cs new file mode 100644 index 0000000..ff25b47 --- /dev/null +++ b/SIG.Web/Pages/Catalogos/TurnoDetalle.aspx.cs @@ -0,0 +1,326 @@ +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.Bitacora; +using SIG.Web.AppCode.Models.Common; +using SIG.Web.AppCode.Models.General; +using SIG.Web.AppCode.Security; + +namespace SIG.Web.Pages.Catalogos +{ + public partial class TurnoDetalle : ClsPaginaCatalogoInterno + { + #region "Propiedades" + private int CveTurnoActual + { + get { return ViewState["CveTurnoActual"] as int? ?? 0; } + set { ViewState["CveTurnoActual"] = value; } + } + + private int IndiceHorarioActual + { + get { return ViewState["IndiceHorarioActual"] as int? ?? -1; } + set { ViewState["IndiceHorarioActual"] = value; } + } + private List HorariosActuales + { + get { return ViewState["HorariosActuales"] as List ?? new List(); } + set { ViewState["HorariosActuales"] = value; } + } + + private List HorariosOriginales + { + get { return ViewState["HorariosOriginales"] as List ?? new List(); } + set { ViewState["HorariosOriginales"] = value; } + } + #endregion + + protected void Page_Load(object origen, EventArgs argumentos) + { + if (!IsPostBack) + { + int clave; + if (Request.QueryString["id"] != null && + (!int.TryParse(Request.QueryString["id"], out clave) || clave <= 0)) + { + Alert("La clave del turno no es válida.", TipoMensaje.MsgAdvertencia); + } + else + { + CveTurnoActual = int.TryParse(Request.QueryString["id"], out clave) ? clave : 0; + CargarTurno(); + } + + TxtTurno.Attributes["data-turno-original"] = TxtTurno.Text; + TxtTurno.Attributes["data-activo-original"] = ChkActivo.Checked ? "1" : "0"; + } + + PnlDatos.Visible = true; + AccionGuardar.Visible = true; + AccionEliminar.Visible = true && CveTurnoActual > 0; + } + + private void CargarTurno() + { + if (CveTurnoActual > 0) + { + DbResult consulta = AppServices.ServicioTurnos.Obtener( + CveTurnoActual, CurrentUser.CveUsuario, CurrentUser.NombreDominio); + if (!consulta.Success || consulta.Data == null) + { + Alert(consulta.Success ? "El turno ya no existe." : consulta.UserMessage, TipoMensaje.MsgError); + return; + } + + TxtTurno.Text = consulta.Data.Turno; + ChkActivo.Checked = consulta.Data.EsActivo; + HorariosActuales = consulta.Data.Horarios; + BitacoraTurno.Visible = true; + BitacoraTurno.ConfigurarConsulta( + new List + { + new BitacoraCampoFiltroModel + { + NombreTablaSQL = "Sis_Turnos", + NombreCampoSQL = "CveTurno", + Valor = CveTurnoActual.ToString(CultureInfo.InvariantCulture) + } + }, + new List()); + BitacoraTurno.Consultar(true); + } + HorariosOriginales = HorariosActuales.Select(ObtenerFirmaHorario).ToList(); + EnlazarHorarios(); + } + + protected override void OnPreRender(EventArgs argumentos) + { + HdnHorariosPendientes.Value = HorariosOriginales.SequenceEqual( + HorariosActuales.Select(ObtenerFirmaHorario)) ? "0" : "1"; + RegistraScript("window.SIGTurnoDetalle.actualizarAviso();", "AvisoTurnoPendiente"); + base.OnPreRender(argumentos); + } + + private static string ObtenerFirmaHorario(ModeloHorarioTurno horario) + { + return string.Join("|", new[] + { + horario.CveTurnoHorario.ToString(CultureInfo.InvariantCulture), + horario.DiaSemana.ToString(CultureInfo.InvariantCulture), + horario.HoraInicio.Ticks.ToString(CultureInfo.InvariantCulture), + horario.HoraFin.Ticks.ToString(CultureInfo.InvariantCulture) + }); + } + + protected void Horarios_EnlazarFila(object origen, GridViewRowEventArgs argumentos) + { + if (argumentos.Row.RowType != DataControlRowType.DataRow) + { + return; + } + + var horario = (ModeloHorarioTurno)argumentos.Row.DataItem; + if (!HorariosOriginales.Contains(ObtenerFirmaHorario(horario))) + { + argumentos.Row.CssClass = "sig-horario-pendiente"; + argumentos.Row.ToolTip = "Horario nuevo o modificado, pendiente de guardar el turno."; + } + + if (argumentos.Row.RowIndex == IndiceHorarioActual) + { + argumentos.Row.CssClass += " sig-horario-edicion"; + argumentos.Row.ToolTip = "Horario en edición."; + } + } + + protected void NuevoHorario_Click(object origen, EventArgs argumentos) + { + LimpiarCapturaHorario(); + ChkContinuarAgregando.Checked = true; + UpModalHorario.Update(); + RegistraScript("window.SIGTurnoDetalle.mostrarHorario();", "MostrarHorario"); + } + + private void EnlazarHorarios() + { + GvHorarios.DataSource = HorariosActuales; + GvHorarios.DataBind(); + } + + protected void AgregarHorario_Click(object origen, EventArgs argumentos) + { + int dia; + TimeSpan inicio; + TimeSpan fin; + if (!int.TryParse(DdlDia.SelectedValue, out dia) || dia < 1 || dia > 7 || + !TimeSpan.TryParseExact(TxtInicio.Text, @"hh\:mm", CultureInfo.InvariantCulture, out inicio) || + !TimeSpan.TryParseExact(TxtFin.Text, @"hh\:mm", CultureInfo.InvariantCulture, out fin) || + inicio >= TimeSpan.FromDays(1) || fin >= TimeSpan.FromDays(1) || inicio == fin) + { + Alert("Capture un día y horas válidas. Inicio y fin deben ser diferentes.", TipoMensaje.MsgAdvertencia); + return; + } + + List horarios = HorariosActuales; + var horario = new ModeloHorarioTurno + { + CveTurno = CveTurnoActual, + DiaSemana = dia, + HoraInicio = inicio, + HoraFin = fin + }; + bool esEdicion = IndiceHorarioActual >= 0 && IndiceHorarioActual < horarios.Count; + if (esEdicion) + { + horario.CveTurnoHorario = horarios[IndiceHorarioActual].CveTurnoHorario; + horarios[IndiceHorarioActual] = horario; + } + else + { + horarios.Add(horario); + } + + HorariosActuales = horarios; + // La edición se aplica una sola vez; continuar agrega un horario nuevo. + IndiceHorarioActual = -1; + LitTituloHorario.Text = "Agregar horario"; + EnlazarHorarios(); + UpHorarios.Update(); + + if (ChkContinuarAgregando.Checked) + { + RegistraScript("window.SIGTurnoDetalle.mostrarHorario();", "ContinuarHorario"); + } + else + { + LimpiarCapturaHorario(); + RegistraScript("window.SIGTurnoDetalle.cerrarHorario();", "CerrarHorario"); + } + + Alert( + esEdicion + ? "Horario actualizado en la lista. Pulse Guardar turno para conservar los cambios." + : "Horario agregado a la lista. Pulse Guardar turno para conservar los cambios.", + TipoMensaje.ToastExito); + } + + protected void Horarios_Comando(object origen, GridViewCommandEventArgs argumentos) + { + int indice; + List horarios = HorariosActuales; + if (!int.TryParse(Convert.ToString(argumentos.CommandArgument), out indice) || + indice < 0 || indice >= horarios.Count) + { + return; + } + + if (argumentos.CommandName == "EditarHorario") + { + ModeloHorarioTurno horario = horarios[indice]; + IndiceHorarioActual = indice; + DdlDia.SelectedValue = horario.DiaSemana.ToString(CultureInfo.InvariantCulture); + TxtInicio.Text = horario.HoraInicio.ToString(@"hh\:mm", CultureInfo.InvariantCulture); + TxtFin.Text = horario.HoraFin.ToString(@"hh\:mm", CultureInfo.InvariantCulture); + ChkContinuarAgregando.Checked = false; + LitTituloHorario.Text = "Editar horario"; + EnlazarHorarios(); + UpModalHorario.Update(); + RegistraScript("window.SIGTurnoDetalle.mostrarHorario();", "EditarHorario"); + } + else if (argumentos.CommandName == "QuitarHorario") + { + horarios.RemoveAt(indice); + HorariosActuales = horarios; + IndiceHorarioActual = -1; + EnlazarHorarios(); + } + } + + protected void CancelarHorario_Click(object origen, EventArgs argumentos) + { + LimpiarCapturaHorario(); + EnlazarHorarios(); + UpHorarios.Update(); + RegistraScript("window.SIGTurnoDetalle.cerrarHorario();", "CancelarHorario"); + } + + private void LimpiarCapturaHorario() + { + IndiceHorarioActual = -1; + DdlDia.SelectedValue = ""; + TxtInicio.Text = ""; + TxtFin.Text = ""; + ChkContinuarAgregando.Checked = false; + LitTituloHorario.Text = "Agregar horario"; + } + + protected void Guardar_Click(object origen, EventArgs argumentos) + { + var turno = new ModeloTurno + { + CveTurno = CveTurnoActual, + Turno = TxtTurno.Text, + EsActivo = ChkActivo.Checked, + Horarios = HorariosActuales + }; + DbResult resultado = AppServices.ServicioTurnos.Guardar( + turno, CurrentUser.CveUsuario, CurrentUser.NombreDominio); + if (!resultado.Success) + { + Alert(resultado.UserMessage, TipoMensaje.MsgError); + return; + } + + AlertNextRequest("Turno guardado correctamente.", TipoMensaje.ToastExito); + SalirDespuesDeGuardar("~/Pages/Catalogos/TurnoDetalle.aspx?id=" + + resultado.Data.ToString(CultureInfo.InvariantCulture)); + } + + protected void ConfirmarEliminacion_Click(object origen, EventArgs argumentos) + { + if (CveTurnoActual <= 0) + { + return; + } + + string destino = HttpUtility.JavaScriptStringEncode(BtnEjecutarEliminacion.UniqueID); + Alert( + "Se eliminará el turno con sus intervalos. No puede eliminarse si está asignado a un usuario. ¿Desea continuar?", + TipoMensaje.MsgConfirmacion, + "__doPostBack('" + destino + "','');"); + } + + protected void Eliminar_Click(object origen, EventArgs argumentos) + { + if (CveTurnoActual <= 0) + { + return; + } + + DbResult resultado = AppServices.ServicioTurnos.Eliminar( + CveTurnoActual, CurrentUser.CveUsuario, CurrentUser.NombreDominio); + if (!resultado.Success) + { + Alert(resultado.UserMessage, TipoMensaje.MsgError); + return; + } + + AlertNextRequest("Turno eliminado correctamente.", TipoMensaje.ToastExito); + SalirDespuesDeGuardar("~/Pages/Catalogos/Turnos.aspx"); + } + + private void SalirDespuesDeGuardar(string destino) + { + // El aviso se omite únicamente después de que el servicio confirma el éxito. + RegistraScript( + "window.SIGTurnoDetalle.salirGuardado('" + + HttpUtility.JavaScriptStringEncode(ResolveUrl(destino)) + "');", + "SalirTurnoGuardado"); + } + } +} diff --git a/SIG.Web/Pages/Catalogos/Turnos.aspx b/SIG.Web/Pages/Catalogos/Turnos.aspx new file mode 100644 index 0000000..e4f25a9 --- /dev/null +++ b/SIG.Web/Pages/Catalogos/Turnos.aspx @@ -0,0 +1,75 @@ +<%@ Page Title="Turnos" Language="C#" MasterPageFile="~/Site.master" + AutoEventWireup="true" CodeFile="Turnos.aspx.cs" Inherits="SIG.Web.Pages.Catalogos.Turnos" %> + + " rel="stylesheet" /> + + + +
  • + + Nuevo turno + +
  • +
    + + + + + + + +

    Consultando turnos...

    +
    +
    + +
    + + + diff --git a/SIG.Web/Pages/Catalogos/Turnos.aspx.cs b/SIG.Web/Pages/Catalogos/Turnos.aspx.cs new file mode 100644 index 0000000..1f87c00 --- /dev/null +++ b/SIG.Web/Pages/Catalogos/Turnos.aspx.cs @@ -0,0 +1,117 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using SIG.Web.AppCode.Configuration; +using SIG.Web.AppCode.Infrastructure.WebForms; +using SIG.Web.AppCode.Models.Common; +using SIG.Web.AppCode.Models.General; +using SIG.Web.AppCode.Security; +using SIG.Web.AppCode.SigControls; + +namespace SIG.Web.Pages.Catalogos +{ + public partial class Turnos : ClsPaginaCatalogoInterno + { + private string TextoFiltro + { + get { return ViewState["TextoFiltro"] as string ?? ""; } + set { ViewState["TextoFiltro"] = value; } + } + + private bool IncluirInactivos + { + get { return ViewState["IncluirInactivos"] as bool? ?? false; } + set { ViewState["IncluirInactivos"] = value; } + } + + protected void Page_Load(object origen, EventArgs argumentos) + { + if (!IsPostBack) + { + Consultar(); + } + } + + protected void Consultar_Click(object origen, EventArgs argumentos) + { + Consultar(); + } + + protected void MostrarFiltros_Click(object origen, EventArgs argumentos) + { + TxtBusqueda.Text = TextoFiltro; + ChkInactivos.Checked = IncluirInactivos; + + UpFiltros.Update(); + RegistraScript("SIGCatalogosUsuariosTurnos.mostrarModal('ModalFiltrosCatalogo');", "MostrarFiltros"); + } + + protected void AplicarFiltros_Click(object origen, EventArgs argumentos) + { + TextoFiltro = TxtBusqueda.Text.Trim(); + IncluirInactivos = ChkInactivos.Checked; + + Consultar(); + UpListado.Update(); + RegistraScript("SIGCatalogosUsuariosTurnos.ocultarModal('ModalFiltrosCatalogo');", "OcultarFiltros"); + } + + protected void Filtros_Cambiados(object origen, EventArgs argumentos) + { + IList filtros = FiltrosCatalogo.GetFiltros(); + if (!filtros.Any(filtro => filtro.Nombre == "Texto")) + { + TextoFiltro = ""; + } + + IncluirInactivos = filtros.Any(filtro => filtro.Nombre == "Inactivos"); + + Consultar(); + } + + protected string ObtenerUrlDetalle(object clave) + { + return ResolveUrl("~/Pages/Catalogos/TurnoDetalle.aspx?id=" + + Convert.ToInt32(clave).ToString(CultureInfo.InvariantCulture)); + } + + private void Consultar() + { + DbResult> resultado = + AppServices.ServicioTurnos.Listar( + TextoFiltro, IncluirInactivos, CurrentUser.CveUsuario, CurrentUser.NombreDominio); + GvListado.DataSource = resultado.Success ? resultado.Data : null; + GvListado.DataBind(); + if (!resultado.Success) + { + Alert(resultado.UserMessage, TipoMensaje.MsgError); + } + + var filtros = new List(); + if (!string.IsNullOrWhiteSpace(TextoFiltro)) + { + filtros.Add(new FiltroActivo + { + Nombre = "Texto", + Titulo = "Buscar", + Descripcion = TextoFiltro, + Orden = 1 + }); + } + + if (IncluirInactivos) + { + filtros.Add(new FiltroActivo + { + Nombre = "Inactivos", + Titulo = "Estado", + Descripcion = "Incluye inactivos", + Orden = 3 + }); + } + + FiltrosCatalogo.SetFiltros(filtros); + } + } +} diff --git a/SIG.Web/Pages/Catalogos/UnidadesMedida.aspx.designer.cs b/SIG.Web/Pages/Catalogos/UnidadesMedida.aspx.designer.cs deleted file mode 100644 index ac39380..0000000 --- a/SIG.Web/Pages/Catalogos/UnidadesMedida.aspx.designer.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace SIG.Web.Pages.Catalogos -{ - public partial class UnidadesMedida - { - protected global::System.Web.UI.UpdatePanel UpAcciones; - protected global::System.Web.UI.WebControls.LinkButton BtnNuevo; - protected global::System.Web.UI.UpdatePanel UpCatalogo; - protected global::SIG.Web.AppCode.SigControls.Filtros UcFiltros; - protected global::System.Web.UI.WebControls.GridView GvUnidadesMedida; - protected global::System.Web.UI.UpdatePanel UpFiltros; - protected global::System.Web.UI.WebControls.TextBox TxtBusqueda; - protected global::System.Web.UI.WebControls.CheckBox ChkInactivos; - protected global::System.Web.UI.WebControls.Button BtnAplicarFiltros; - protected global::System.Web.UI.UpdatePanel UpEdicion; - protected global::System.Web.UI.WebControls.Literal LitTituloModal; - protected global::System.Web.UI.WebControls.TextBox TxtUnidadMedida; - protected global::System.Web.UI.WebControls.TextBox TxtAbreviatura; - protected global::System.Web.UI.WebControls.CheckBox ChkActivo; - protected global::System.Web.UI.WebControls.Button BtnGuardar; - protected global::SIG.Web.AppCode.SigControls.BitacoraGrid - UcBitacoraCatalogo; - } -} diff --git a/SIG.Web/Pages/Catalogos/UsuarioDetalle.aspx b/SIG.Web/Pages/Catalogos/UsuarioDetalle.aspx new file mode 100644 index 0000000..4e0caf8 --- /dev/null +++ b/SIG.Web/Pages/Catalogos/UsuarioDetalle.aspx @@ -0,0 +1,100 @@ +<%@ Page Title="Detalle de usuario" Language="C#" MasterPageFile="~/Site.master" + AutoEventWireup="true" CodeFile="UsuarioDetalle.aspx.cs" Inherits="SIG.Web.Pages.Catalogos.UsuarioDetalle" %> + + " rel="stylesheet" /> + + + + + +
  • + + Guardar usuario + +
  • +
  • + + Reiniciar y enviar contraseña + + +
  • +
  • + +
  • +
    +
    +
    + + + + +

    Los datos de los usuarios cliente son de consulta. Solo puede reiniciar y enviar su contraseña.

    +
    +
    Usuario
    +
    + +
    +
    Correo registrado
    +
    + +
    +
    Rol
    +
    + +
    +
    Estado
    +
    + +
    +
    +
    + +
    +
    + + +
    +
    + + +
    +
    +
    +
    + + +
    +
    + + +

    Obligatoria al crear el usuario. Al editar, déjela vacía para conservarla.

    +
    +
    +
    + +
    +
    + +
    +
    + + + +
    +
    +
    +
    + + +

    Procesando usuario...

    +
    +
    + +
    + + + diff --git a/SIG.Web/Pages/Catalogos/UsuarioDetalle.aspx.cs b/SIG.Web/Pages/Catalogos/UsuarioDetalle.aspx.cs new file mode 100644 index 0000000..a8bc213 --- /dev/null +++ b/SIG.Web/Pages/Catalogos/UsuarioDetalle.aspx.cs @@ -0,0 +1,248 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Web; +using SIG.Web.AppCode.Configuration; +using SIG.Web.AppCode.Infrastructure.WebForms; +using SIG.Web.AppCode.Models.Bitacora; +using SIG.Web.AppCode.Models.Common; +using SIG.Web.AppCode.Models.General; +using SIG.Web.AppCode.Models.Security; +using SIG.Web.AppCode.Security; + +namespace SIG.Web.Pages.Catalogos +{ + public partial class UsuarioDetalle : ClsPaginaCatalogoInterno + { + private int CveUsuarioActual + { + get { return ViewState["CveUsuarioActual"] as int? ?? 0; } + set { ViewState["CveUsuarioActual"] = value; } + } + + private UserAdministrationModel UsuarioActual + { + get { return ViewState["UsuarioActual"] as UserAdministrationModel; } + set { ViewState["UsuarioActual"] = value; } + } + + private bool DatosDisponibles + { + get { return ViewState["DatosDisponibles"] as bool? ?? false; } + set { ViewState["DatosDisponibles"] = value; } + } + + protected void Page_Load(object origen, EventArgs argumentos) + { + if (!IsPostBack) + { + int clave; + if (Request.QueryString["id"] != null && + (!int.TryParse(Request.QueryString["id"], out clave) || clave <= 0)) + { + Alert("La clave del usuario no es válida.", TipoMensaje.MsgAdvertencia); + ConfigurarVista(); + return; + } + + CveUsuarioActual = int.TryParse(Request.QueryString["id"], out clave) ? clave : 0; + CargarUsuario(); + } + + ConfigurarVista(); + } + + private void CargarUsuario() + { + if (CveUsuarioActual > 0) + { + DbResult consulta = AppServices.UserAdministrationService.GetUser( + CveUsuarioActual, CurrentUser.CveUsuario, CurrentUser.NombreDominio); + if (!consulta.Success || consulta.Data == null) + { + Alert(consulta.Success ? "El usuario ya no existe." : consulta.UserMessage, TipoMensaje.MsgError); + return; + } + + UsuarioActual = consulta.Data; + } + + DatosDisponibles = true; + bool esCliente = UsuarioActual != null && UsuarioActual.CveRol == 3; + if (esCliente) + { + LitUsuario.Text = UsuarioActual.NombreUsuario; + LitCorreo.Text = UsuarioActual.CorreoElectronico; + LitRol.Text = UsuarioActual.NombreRol; + LitEstado.Text = UsuarioActual.Activo ? "Activo" : "Inactivo"; + } + else + { + CargarOpciones(); + if (UsuarioActual != null) + { + TxtUsuario.Text = UsuarioActual.NombreUsuario; + TxtCorreo.Text = UsuarioActual.CorreoElectronico; + SeleccionarOpcion(DdlRol, UsuarioActual.CveRol); + ChkActivo.Checked = UsuarioActual.Activo; + ChkSupervisor.Checked = UsuarioActual.EsSupervisor; + SeleccionarOpcion(DdlTurno, UsuarioActual.CveTurno); + } + } + + CargarBitacora(); + } + + private void CargarOpciones() + { + DbResult> roles = AppServices.UserAdministrationService.ListRoles( + CurrentUser.CveUsuario, CurrentUser.NombreDominio); + if (!roles.Success) + { + Alert(roles.UserMessage, TipoMensaje.MsgError); + return; + } + + DdlRol.DataSource = roles.Data.Where(rol => rol.CveRol != 3).ToList(); + DdlRol.DataTextField = "NombreRol"; + DdlRol.DataValueField = "CveRol"; + DdlRol.DataBind(); + + DbResult> turnos = AppServices.ServicioTurnos.Listar( + null, true, CurrentUser.CveUsuario, CurrentUser.NombreDominio); + if (!turnos.Success) + { + Alert(turnos.UserMessage, TipoMensaje.MsgError); + return; + } + + DdlTurno.DataSource = turnos.Data.Where(turno => + turno.EsActivo || (UsuarioActual != null && UsuarioActual.CveTurno == turno.CveTurno)).ToList(); + DdlTurno.DataTextField = "Turno"; + DdlTurno.DataValueField = "CveTurno"; + DdlTurno.DataBind(); + DdlTurno.Items.Insert(0, new System.Web.UI.WebControls.ListItem("Seleccione un turno", "")); + } + + protected void Supervisor_Cambiado(object origen, EventArgs argumentos) + { + ConfigurarVista(); + } + + private void ConfigurarVista() + { + bool esCliente = UsuarioActual != null && UsuarioActual.CveRol == 3; + bool puedeEditar = DatosDisponibles && !esCliente; + PnlConsultaCliente.Visible = DatosDisponibles && esCliente; + PnlEdicion.Visible = puedeEditar; + CampoTurno.Visible = puedeEditar && ChkSupervisor.Checked; + AccionGuardar.Visible = puedeEditar; + AccionReiniciar.Visible = DatosDisponibles && CveUsuarioActual > 0; + } + + protected void Guardar_Click(object origen, EventArgs argumentos) + { + if (!DatosDisponibles || (UsuarioActual != null && UsuarioActual.CveRol == 3)) + { + Alert("Los usuarios cliente solo admiten reinicio de contraseña y envío por correo.", TipoMensaje.MsgAdvertencia); + return; + } + + int rol; + int turno; + if (!int.TryParse(DdlRol.SelectedValue, out rol)) + { + Alert("Seleccione un rol.", TipoMensaje.MsgAdvertencia); + return; + } + + var usuario = new UserAdministrationModel + { + CveUsuario = CveUsuarioActual, + NombreUsuario = TxtUsuario.Text, + CorreoElectronico = TxtCorreo.Text, + CveRol = rol, + Activo = ChkActivo.Checked, + EsSupervisor = ChkSupervisor.Checked, + CveTurno = int.TryParse(DdlTurno.SelectedValue, out turno) ? (int?)turno : null, + DebeCambiarContrasena = UsuarioActual != null && UsuarioActual.DebeCambiarContrasena, + CorreoVerificado = UsuarioActual == null || UsuarioActual.CorreoVerificado + }; + DbResult resultado = AppServices.UserAdministrationService.SaveUser( + usuario, TxtContrasena.Text, CurrentUser.CveUsuario, CurrentUser.NombreDominio); + TxtContrasena.Text = ""; + if (!resultado.Success) + { + Alert(resultado.UserMessage, TipoMensaje.MsgError); + UpDatos.Update(); + return; + } + + AlertNextRequest("Usuario guardado correctamente.", TipoMensaje.ToastExito); + Response.Redirect(ResolveUrl("~/Pages/Catalogos/UsuarioDetalle.aspx?id=" + + resultado.Data.ToString(CultureInfo.InvariantCulture)), false); + Context.ApplicationInstance.CompleteRequest(); + } + + protected void ConfirmarReinicio_Click(object origen, EventArgs argumentos) + { + if (!DatosDisponibles || CveUsuarioActual <= 0) + { + return; + } + + string destino = HttpUtility.JavaScriptStringEncode(BtnEjecutarReinicio.UniqueID); + Alert( + "Se generará una nueva contraseña y se enviará al correo registrado del usuario. ¿Desea continuar?", + TipoMensaje.MsgConfirmacion, + "__doPostBack('" + destino + "','');"); + } + + protected void Reiniciar_Click(object origen, EventArgs argumentos) + { + if (!DatosDisponibles || CveUsuarioActual <= 0) + { + return; + } + + DbResult resultado = AppServices.UserAdministrationService.ReiniciarContrasenaYEnviar( + CveUsuarioActual, CurrentUser.CveUsuario, CurrentUser.NombreDominio); + Alert( + resultado.Success ? "Se reinició la contraseña y se envió al correo registrado." : resultado.UserMessage, + resultado.Success ? TipoMensaje.ToastExito : TipoMensaje.MsgError); + CargarBitacora(); + } + + private void CargarBitacora() + { + if (CveUsuarioActual <= 0) + { + return; + } + + BitacoraUsuario.Visible = true; + BitacoraUsuario.ConfigurarConsulta( + new List + { + new BitacoraCampoFiltroModel + { + NombreTablaSQL = "Sis_Usuarios", + NombreCampoSQL = "CveUsuario", + Valor = CveUsuarioActual.ToString(CultureInfo.InvariantCulture) + } + }, + new List()); + BitacoraUsuario.Consultar(true); + } + + private static void SeleccionarOpcion(System.Web.UI.WebControls.DropDownList lista, int? clave) + { + string valor = clave.HasValue ? clave.Value.ToString(CultureInfo.InvariantCulture) : ""; + if (lista.Items.FindByValue(valor) != null) + { + lista.SelectedValue = valor; + } + } + } +} diff --git a/SIG.Web/Pages/Catalogos/Usuarios.aspx b/SIG.Web/Pages/Catalogos/Usuarios.aspx new file mode 100644 index 0000000..c61ca03 --- /dev/null +++ b/SIG.Web/Pages/Catalogos/Usuarios.aspx @@ -0,0 +1,86 @@ +<%@ Page Title="Usuarios" Language="C#" MasterPageFile="~/Site.master" + AutoEventWireup="true" CodeFile="Usuarios.aspx.cs" Inherits="SIG.Web.Pages.Catalogos.Usuarios" %> + + " rel="stylesheet" /> + + + +
  • + + Nuevo usuario + +
  • +
    + + + + + + + +

    Consultando usuarios...

    +
    +
    + +
    + + + diff --git a/SIG.Web/Pages/Catalogos/Usuarios.aspx.cs b/SIG.Web/Pages/Catalogos/Usuarios.aspx.cs new file mode 100644 index 0000000..4a37f3d --- /dev/null +++ b/SIG.Web/Pages/Catalogos/Usuarios.aspx.cs @@ -0,0 +1,139 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using SIG.Web.AppCode.Configuration; +using SIG.Web.AppCode.Infrastructure.WebForms; +using SIG.Web.AppCode.Models.Common; +using SIG.Web.AppCode.Models.Security; +using SIG.Web.AppCode.Security; +using SIG.Web.AppCode.SigControls; + +namespace SIG.Web.Pages.Catalogos +{ + public partial class Usuarios : ClsPaginaCatalogoInterno + { + private string TextoFiltro + { + get { return ViewState["TextoFiltro"] as string ?? ""; } + set { ViewState["TextoFiltro"] = value; } + } + + private bool IncluirInactivos + { + get { return ViewState["IncluirInactivos"] as bool? ?? false; } + set { ViewState["IncluirInactivos"] = value; } + } + + private int TipoUsuarioFiltro + { + get { return ViewState["TipoUsuarioFiltro"] as int? ?? 1; } + set { ViewState["TipoUsuarioFiltro"] = value; } + } + + protected void Page_Load(object origen, EventArgs argumentos) + { + if (!IsPostBack) + { + Consultar(); + } + } + + protected void Consultar_Click(object origen, EventArgs argumentos) + { + Consultar(); + } + + protected void MostrarFiltros_Click(object origen, EventArgs argumentos) + { + TxtBusqueda.Text = TextoFiltro; + ChkInactivos.Checked = IncluirInactivos; + DdlTipoUsuario.SelectedValue = TipoUsuarioFiltro.ToString(CultureInfo.InvariantCulture); + UpFiltros.Update(); + RegistraScript("SIGCatalogosUsuariosTurnos.mostrarModal('ModalFiltrosCatalogo');", "MostrarFiltros"); + } + + protected void AplicarFiltros_Click(object origen, EventArgs argumentos) + { + TextoFiltro = TxtBusqueda.Text.Trim(); + IncluirInactivos = ChkInactivos.Checked; + TipoUsuarioFiltro = Convert.ToInt32(DdlTipoUsuario.SelectedValue, CultureInfo.InvariantCulture); + Consultar(); + UpListado.Update(); + RegistraScript("SIGCatalogosUsuariosTurnos.ocultarModal('ModalFiltrosCatalogo');", "OcultarFiltros"); + } + + protected void Filtros_Cambiados(object origen, EventArgs argumentos) + { + IList filtros = FiltrosCatalogo.GetFiltros(); + if (!filtros.Any(filtro => filtro.Nombre == "Texto")) + { + TextoFiltro = ""; + } + + IncluirInactivos = filtros.Any(filtro => filtro.Nombre == "Inactivos"); + if (!filtros.Any(filtro => filtro.Nombre == "TipoUsuario")) + { + TipoUsuarioFiltro = 0; + } + + Consultar(); + } + + protected string ObtenerUrlDetalle(object clave) + { + return ResolveUrl("~/Pages/Catalogos/UsuarioDetalle.aspx?id=" + + Convert.ToInt32(clave).ToString(CultureInfo.InvariantCulture)); + } + + private void Consultar() + { + DbResult> resultado = + AppServices.UserAdministrationService.ListarCatalogo( + TextoFiltro, TipoUsuarioFiltro, IncluirInactivos, CurrentUser.CveUsuario, CurrentUser.NombreDominio); + GvListado.DataSource = resultado.Success ? resultado.Data : null; + GvListado.DataBind(); + if (!resultado.Success) + { + Alert(resultado.UserMessage, TipoMensaje.MsgError); + } + + var filtros = new List(); + if (!string.IsNullOrWhiteSpace(TextoFiltro)) + { + filtros.Add(new FiltroActivo + { + Nombre = "Texto", + Titulo = "Buscar", + Descripcion = TextoFiltro, + Orden = 1 + }); + } + + if (TipoUsuarioFiltro != 0) + { + string[] tipos = { "Todos", "Internos", "Clientes", "Supervisores" }; + filtros.Add(new FiltroActivo + { + Nombre = "TipoUsuario", + Titulo = "Usuarios", + Descripcion = tipos[TipoUsuarioFiltro], + Orden = 2 + }); + } + + if (IncluirInactivos) + { + filtros.Add(new FiltroActivo + { + Nombre = "Inactivos", + Titulo = "Estado", + Descripcion = "Incluye inactivos", + Orden = 3 + }); + } + + FiltrosCatalogo.SetFiltros(filtros); + } + } +} diff --git a/SIG.Web/Pages/Desarrolladores/ComprobantePago.ashx b/SIG.Web/Pages/Desarrolladores/ComprobantePago.ashx new file mode 100644 index 0000000..6eb6ed1 --- /dev/null +++ b/SIG.Web/Pages/Desarrolladores/ComprobantePago.ashx @@ -0,0 +1,42 @@ +<%@ WebHandler Language="C#" Class="DescargaComprobantePago" %> + +using System; +using System.Web; +using System.Web.SessionState; +using SIG.Web.AppCode.Configuration; + +public sealed class DescargaComprobantePago : IHttpHandler, IReadOnlySessionState +{ + public bool IsReusable { get { return false; } } + + public void ProcessRequest(HttpContext contexto) + { + var usuario = AppServices.UserContext.GetCurrentUser(); + int clave; + if (usuario == null || !AppServices.UserContext.IsAuthenticated()) + { + contexto.Response.StatusCode = 401; + return; + } + if (!int.TryParse(contexto.Request.QueryString["id"], out clave)) + { + contexto.Response.StatusCode = 404; + return; + } + var archivo = AppServices.ServicioPagosConvenios.ObtenerArchivoComprobante( + clave, usuario.CveUsuario, usuario.NombreDominio); + if (!archivo.Success || archivo.Data == null) + { + contexto.Response.StatusCode = 404; + return; + } + contexto.Response.ContentType = archivo.Data.TipoContenido; + contexto.Response.AddHeader("X-Content-Type-Options", "nosniff"); + contexto.Response.AddHeader("Content-Disposition", "attachment; filename*=UTF-8''" + + Uri.EscapeDataString(archivo.Data.NombreArchivo)); + contexto.Response.Cache.SetCacheability(HttpCacheability.NoCache); + contexto.Response.Cache.SetNoStore(); + contexto.Response.TransmitFile(archivo.Data.RutaFisica); + contexto.ApplicationInstance.CompleteRequest(); + } +} diff --git a/SIG.Web/Pages/Desarrolladores/ConsultaTramites.aspx.designer.cs b/SIG.Web/Pages/Desarrolladores/ConsultaTramites.aspx.designer.cs deleted file mode 100644 index 8b855e0..0000000 --- a/SIG.Web/Pages/Desarrolladores/ConsultaTramites.aspx.designer.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace SIG.Web.Pages.Desarrolladores -{ - public partial class ConsultaTramites - { - } -} diff --git a/SIG.Web/Pages/Desarrolladores/ConvenioDetalle.aspx b/SIG.Web/Pages/Desarrolladores/ConvenioDetalle.aspx new file mode 100644 index 0000000..336b2c0 --- /dev/null +++ b/SIG.Web/Pages/Desarrolladores/ConvenioDetalle.aspx @@ -0,0 +1,157 @@ +<%@ Page Title="Detalle de convenio" Language="C#" MasterPageFile="~/Site.master" + AutoEventWireup="true" CodeFile="ConvenioDetalle.aspx.cs" Inherits="SIG.Web.Pages.Desarrolladores.ConvenioDetalle" %> + + + +
  • +
    + + + + + +
    + + +
    +
    + + +
    +
    +

    +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    +
    + + +
    + +

    Los importes se capturan en la unidad del adeudo origen, con hasta seis decimales.

    + + Sugerir distribución + +
    +
    + + + + + +

    Ajuste los importes y pulse Guardar convenio. La suma debe coincidir con el importe del convenio.

    + + + + + + + + + + + +
    + + + + Agregar producto + +
    +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + Agregar parcialidad + + + + + + + + + +

    La propuesta toma el saldo por producto proporcionalmente y las parcialidades por vencimiento. Revise este desglose antes de guardar.

    + + + + + + + + +
    +
    +
    +
    +
    + + + + Guardar convenio + + + Cancelar convenio + + + + +
    + +

    Procesando convenio...

    +
    +
    + + diff --git a/SIG.Web/Pages/Desarrolladores/ConvenioDetalle.aspx.cs b/SIG.Web/Pages/Desarrolladores/ConvenioDetalle.aspx.cs new file mode 100644 index 0000000..d8d811b --- /dev/null +++ b/SIG.Web/Pages/Desarrolladores/ConvenioDetalle.aspx.cs @@ -0,0 +1,583 @@ +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 Productos + { + get { return ViewState["Productos"] as List ?? new List(); } + set { ViewState["Productos"] = value; } + } + + private List Parcialidades + { + get { return ViewState["Parcialidades"] as List ?? new List(); } + set { ViewState["Parcialidades"] = value; } + } + + private List DetallesOrigen + { + get { return ViewState["DetallesOrigen"] as List ?? new List(); } + 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(); + Parcialidades = new List(); + DetallesOrigen = new List(); + 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 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 LeerParcialidades() + { + var parcialidades = new List(); + 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")) + "');"); + } + } +} diff --git a/SIG.Web/Pages/Desarrolladores/Convenios.aspx b/SIG.Web/Pages/Desarrolladores/Convenios.aspx new file mode 100644 index 0000000..983de24 --- /dev/null +++ b/SIG.Web/Pages/Desarrolladores/Convenios.aspx @@ -0,0 +1,78 @@ +<%@ Page Title="Convenios" Language="C#" MasterPageFile="~/Site.master" + AutoEventWireup="true" CodeFile="Convenios.aspx.cs" Inherits="SIG.Web.Pages.Desarrolladores.Convenios" %> + + + +
  • + + Agregar convenio + +
  • +
    + + + + + + + + + + + + + + +

    Obligaciones sin saldo pendiente y canceladas. El saldo convenido se muestra separado de lo abonado.

    + +
    +
    + +
    + +

    Consultando...

    +
    + +
    + + + diff --git a/SIG.Web/Pages/Desarrolladores/Convenios.aspx.cs b/SIG.Web/Pages/Desarrolladores/Convenios.aspx.cs new file mode 100644 index 0000000..b0afa49 --- /dev/null +++ b/SIG.Web/Pages/Desarrolladores/Convenios.aspx.cs @@ -0,0 +1,183 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +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; +using SIG.Web.AppCode.SigControls; + +namespace SIG.Web.Pages.Desarrolladores +{ + public partial class Convenios : ClsPaginaBase + { + private ModeloFiltroObligacionesPago FiltroActual + { + get { return ViewState["FiltroActual"] as ModeloFiltroObligacionesPago ?? new ModeloFiltroObligacionesPago(); } + set { ViewState["FiltroActual"] = value; } + } + + protected void Page_Load(object origen, EventArgs argumentos) + { + if (!IsPostBack) + { + CargarOpciones(); + Consultar(origen, argumentos); + } + LnkNuevoConvenio.Visible = !CurrentUser.EsDesarrollador && + AppServices.PermissionService.HasPermission(CurrentUser.CveUsuario, "Convenios.Crear"); + } + + private void CargarOpciones() + { + var resultado = AppServices.ServicioPagosConvenios.ListarConvenios(null, null, false, + CurrentUser.CveUsuario, CurrentUser.NombreDominio); + var obligaciones = resultado.Success ? resultado.Data : new List(); + 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 opciones) + { + lista.Items.Clear(); + lista.Items.Add(new ListItem("Todos", "")); + foreach (var opcion in opciones.OrderBy(opcion => opcion.Text)) + { + lista.Items.Add(opcion); + } + } + + protected void Consultar(object origen, EventArgs argumentos) + { + 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(); + 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) + { + var filtro = FiltroActual; + DdlCliente.SelectedValue = Convert.ToString(filtro.CveCliente, CultureInfo.InvariantCulture); + DdlFraccionamiento.SelectedValue = Convert.ToString(filtro.CveFraccionamiento, CultureInfo.InvariantCulture); + 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) + { + DateTime desde; + DateTime hasta; + 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) + { + var nombres = new HashSet(FiltrosListado.GetFiltros().Select(filtro => filtro.Nombre)); + var filtroActual = FiltroActual; + if (!nombres.Contains("Cliente")) { filtroActual.CveCliente = null; } + 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() + { + var filtro = FiltroActual; + var activos = new List(); + AgregarFiltro(activos, "Cliente", filtro.CveCliente.HasValue ? DdlCliente.Items.FindByValue(filtro.CveCliente.Value.ToString()).Text : null); + 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 filtros, string nombre, string descripcion) + { + if (!string.IsNullOrWhiteSpace(descripcion)) + { + filtros.Add(new FiltroActivo + { + Nombre = nombre, + Titulo = nombre == "Tramite" ? "Trámite" : nombre, + Descripcion = descripcion, + Orden = filtros.Count + }); + } + } + } +} diff --git a/SIG.Web/Pages/Desarrolladores/DesarrolladorDetalle.aspx b/SIG.Web/Pages/Desarrolladores/DesarrolladorDetalle.aspx new file mode 100644 index 0000000..95c1afd --- /dev/null +++ b/SIG.Web/Pages/Desarrolladores/DesarrolladorDetalle.aspx @@ -0,0 +1,349 @@ +<%@ Page Title="Detalle de desarrollador" Language="C#" MasterPageFile="~/Site.master" + AutoEventWireup="true" CodeFile="DesarrolladorDetalle.aspx.cs" + Inherits="SIG.Web.Pages.Desarrolladores.DesarrolladorDetalle" %> +<%@ Register TagPrefix="sig" TagName="CapturaEtapas" Src="~/UserControl/CapturaEtapas.ascx" %> +<%@ Register TagPrefix="sig" TagName="DetalleEtapa" Src="~/UserControl/DetalleEtapa.ascx" %> + + + + +
  • + +
  • +
    + + + + + + + + + + + + + + + + + + + +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    + + + + +
    +
    +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + + + + +

    Sólo los usuarios de Agua de Hermosillo pueden cambiar este dato.

    +
    +
    +
    + +
    +
    +
    +
    +
    + + +
    +
    + +
    + + +
    + + + + + +
    + + + + +
    + + + + +
    + +
    +
    + + + + + + + + +
    +
    +
    +
    +
    +
    +
    +
    + + + + + + + + + + + + +
    +
    + + +

    Procesando...

    +
    +
    + + +
    + + + diff --git a/SIG.Web/Pages/Desarrolladores/DesarrolladorDetalle.aspx.cs b/SIG.Web/Pages/Desarrolladores/DesarrolladorDetalle.aspx.cs new file mode 100644 index 0000000..437e608 --- /dev/null +++ b/SIG.Web/Pages/Desarrolladores/DesarrolladorDetalle.aspx.cs @@ -0,0 +1,505 @@ +using System; +using System.Globalization; +using System.Collections.Generic; +using System.Web.UI; +using System.Web.UI.WebControls; +using SIG.Web.AppCode.Configuration; +using SIG.Web.AppCode.Infrastructure.WebForms; +using SIG.Web.AppCode.Models.Clientes; +using SIG.Web.AppCode.Models.Common; +using SIG.Web.AppCode.Models.Fraccionamientos; +using SIG.Web.AppCode.Session; +using SIG.Web.AppCode.Security; + +namespace SIG.Web.Pages.Desarrolladores +{ + public partial class DesarrolladorDetalle : ClsPaginaBase + { + protected void Fraccionamientos_FilaEnlazada(object origen, GridViewRowEventArgs argumentos) + { + if (argumentos.Row.RowType != DataControlRowType.DataRow) + { + return; + } + + var desarrollo = (ModeloFilaDesarrollos)argumentos.Row.DataItem; + argumentos.Row.Attributes["data-fraccionamiento"] = + desarrollo.CveFraccionamiento.ToString(CultureInfo.InvariantCulture); + argumentos.Row.Attributes["data-cabecera"] = desarrollo.EsFraccionamiento ? "1" : "0"; + if (desarrollo.EsFraccionamiento) + { + argumentos.Row.CssClass = "desarrollador-grupo"; + argumentos.Row.Cells[0].ColumnSpan = GvFraccionamientos.Columns.Count; + for (int indice = 1; indice < argumentos.Row.Cells.Count; indice++) + { + argumentos.Row.Cells[indice].Visible = false; + } + } + } + + protected string DescribirFraccionamiento(object objeto) + { + var fila = (ModeloFilaDesarrollos)objeto; + return string.Format(CultureInfo.CurrentCulture, + "{0} · {1:N2} ha · {2} etapas · {3}", + fila.Ubicacion, fila.HectareasFraccionamiento, fila.NumeroEtapas, fila.Estatus); + } + + protected void AbrirEtapa_Click(object origen, EventArgs argumentos) + { + int clave; + if (int.TryParse(Request.Form["__EVENTARGUMENT"], out clave)) + { + DetalleEtapa.Cargar(clave); + RegistraScript("SIGPanelLateral.abrir('" + PanelDetalleEtapa.ClientID + "');"); + } + } + + protected void Etapa_Cambiada(object origen, EventArgs argumentos) + { + CargarFraccionamientos(); + UpFraccionamientos.Update(); + } + + protected void BuscarDesarrolladores(object origen, + SIG.Web.AppCode.SigControls.ConsultaCatalogoEventArgs argumentos) + { + var tabla = new System.Data.DataTable(); + foreach (string columna in new[] { "Clave", "Descripcion", "RFC", "Nombre", "Estatus", "AsociadoCanadevi" }) + { + tabla.Columns.Add(columna); + } + argumentos.Resultados = tabla; + var consulta = AppServices.ServicioDesarrolladores.Listar(string.Empty, true); + if (!consulta.Success) + { + argumentos.Error = consulta.UserMessage; + return; + } + foreach (var cliente in consulta.Data) + { + tabla.Rows.Add(cliente.CveCliente.ToString(CultureInfo.InvariantCulture), + cliente.RFC + " - " + cliente.Nombre, cliente.RFC, cliente.Nombre, + cliente.Estatus ? "Activo" : "Inactivo", cliente.AsociadoCanadevi ? "Sí" : "No"); + } + } + + protected void SeleccionarDesarrollador(object origen, EventArgs argumentos) + { + int clave; + if (int.TryParse(BuscadorDesarrolladores.SelectedValue, out clave)) + { + Response.Redirect(ResolveUrl("~/Pages/Desarrolladores/DesarrolladorDetalle.aspx") + + "?cveCliente=" + clave.ToString(CultureInfo.InvariantCulture), false); + Context.ApplicationInstance.CompleteRequest(); + } + } + + private int CveClienteActual + { + get { return ViewState["CveClienteActual"] as int? ?? 0; } + set { ViewState["CveClienteActual"] = value; } + } + + private int CveFraccionamientoEtapaActual + { + get { return ViewState["CveFraccionamientoEtapaActual"] as int? ?? 0; } + set { ViewState["CveFraccionamientoEtapaActual"] = value; } + } + + private bool AsociadoCanadeviActual + { + get { return ViewState["AsociadoCanadeviActual"] as bool? ?? false; } + set { ViewState["AsociadoCanadeviActual"] = value; } + } + + protected void Page_Load(object origen, EventArgs argumentos) + { + if (!IsPostBack) + { + int cveCliente; + if (!int.TryParse(Request.QueryString["cveCliente"], out cveCliente) || cveCliente <= 0) + { + Alert("Seleccione un desarrollador válido.", TipoMensaje.MsgAdvertencia); + return; + } + + CveClienteActual = cveCliente; + DbResult consulta = AppServices.ServicioDesarrolladores.Obtener(cveCliente); + if (!consulta.Success) + { + Alert(consulta.UserMessage, TipoMensaje.MsgAdvertencia); + return; + } + + PnlDetalle.Visible = true; + MostrarDatos(consulta.Data); + CargarFraccionamientos(); + CargarEstatus(); + BuscadorDesarrolladores.SelectedValue = cveCliente.ToString(CultureInfo.InvariantCulture); + BuscadorDesarrolladores.Text = consulta.Data.RFC + " - " + consulta.Data.Nombre; + int etapa; + if (int.TryParse(Request.QueryString["etapa"], out etapa)) + { + DetalleEtapa.Cargar(etapa); + RegistraScript("SIGPanelLateral.abrir('" + PanelDetalleEtapa.ClientID + "');"); + } + } + + ConfigurarCanadevi(AsociadoCanadeviActual); + } + + protected override void OnPreRender(EventArgs argumentos) + { + base.OnPreRender(argumentos); + var administrador = ScriptManager.GetCurrent(Page); + string destinoPostback = Request.Form["__EVENTTARGET"] ?? string.Empty; + bool postbackDelDetalle = destinoPostback.StartsWith(DetalleEtapa.UniqueID + "$", StringComparison.Ordinal); + foreach (string claveFormulario in Request.Form.AllKeys) + { + if (claveFormulario != null && + claveFormulario.StartsWith(DetalleEtapa.UniqueID + "$", StringComparison.Ordinal) && + Request.Form[claveFormulario] != null && + (claveFormulario.EndsWith("$GuardarArchivo", StringComparison.Ordinal) || + claveFormulario.EndsWith("$GuardarDocumento", StringComparison.Ordinal))) + { + postbackDelDetalle = true; + } + } + if (IsPostBack && administrador != null && !administrador.IsInAsyncPostBack && postbackDelDetalle) + { + RegistraScript("SIGPanelLateral.abrir('" + PanelDetalleEtapa.ClientID + "');"); + } + var sitio = Master as SIG.Web.Site; + if (sitio != null) + { + sitio.SetPageNavigation("Detalle de desarrollador", new[] + { + new BreadcrumbItemModel { Texto = "Inicio", Url = "~/Inicio.aspx" }, + new BreadcrumbItemModel + { + Texto = "Desarrolladores", + Url = "~/Pages/Desarrolladores/Desarrolladores.aspx" + }, + new BreadcrumbItemModel { Texto = "Detalle de desarrollador" } + }); + } + } + + protected void GuardarDatos_Click(object origen, EventArgs argumentos) + { + ModeloDesarrollador desarrollador = LeerDesarrollador(); + desarrollador.CveCliente = CveClienteActual; + if (!AppServices.ServicioDesarrolladores.PuedeCambiarAsociadoCanadevi) + { + desarrollador.AsociadoCanadevi = AsociadoCanadeviActual; + } + + DbResult resultado = AppServices.ServicioDesarrolladores.Actualizar(desarrollador); + if (!resultado.Success) + { + Alert(resultado.UserMessage, TipoMensaje.MsgAdvertencia); + return; + } + + AsociadoCanadeviActual = desarrollador.AsociadoCanadevi; + ConfigurarCanadevi(AsociadoCanadeviActual); + Alert("Datos del desarrollador guardados.", TipoMensaje.ToastExito); + } + + protected void GuardarFraccionamiento_Click(object origen, EventArgs argumentos) + { + if (!ValidarDesarrollador()) + { + return; + } + + decimal? hectareas; + int cveEstatus; + if (!LeerHectareas(TxtHectareasFraccionamiento.Text, out hectareas) || + !int.TryParse(DdlEstatus.SelectedValue, out cveEstatus)) + { + Alert("Capture hectáreas válidas y seleccione un estatus.", TipoMensaje.MsgAdvertencia); + return; + } + + List etapas; + string mensajeEtapas; + if (!UcCapturaEtapas.Capturar(out etapas, out mensajeEtapas)) + { + Alert(mensajeEtapas, TipoMensaje.MsgAdvertencia); + return; + } + + DbResult resultado = AppServices.ServicioFraccionamiento.GuardarConEtapas( + new ModeloFraccionamiento + { + CveCliente = CveClienteActual, + Fraccionamiento = TxtFraccionamiento.Text, + Ubicacion = TxtUbicacion.Text, + Hectareas = hectareas, + CveEstatus = cveEstatus, + EsActivo = true + }, + etapas, + CurrentUser.CveUsuario, CurrentUser.NombreDominio); + if (!resultado.Success) + { + Alert(resultado.UserMessage, TipoMensaje.MsgAdvertencia); + return; + } + + TxtFraccionamiento.Text = string.Empty; + TxtUbicacion.Text = string.Empty; + TxtHectareasFraccionamiento.Text = string.Empty; + UcCapturaEtapas.Reiniciar(); + CargarFraccionamientos(); + UpFraccionamientos.Update(); + RegistraScript("$('#ModalFraccionamiento').modal('hide');"); + Alert("Fraccionamiento registrado.", TipoMensaje.ToastExito); + } + + protected void Fraccionamientos_Comando(object origen, GridViewCommandEventArgs argumentos) + { + if ((argumentos.CommandName != "AgregarEtapa" && argumentos.CommandName != "VerEtapa") || + !ValidarDesarrollador()) + { + return; + } + + var control = argumentos.CommandSource as Control; + var fila = control == null ? null : control.NamingContainer as GridViewRow; + if (fila == null) + { + return; + } + + int cveFraccionamiento = Convert.ToInt32(GvFraccionamientos.DataKeys[fila.RowIndex].Value); + ModeloFraccionamiento fraccionamiento = ObtenerFraccionamientoDelCliente(cveFraccionamiento); + if (fraccionamiento == null) + { + return; + } + + CveFraccionamientoEtapaActual = cveFraccionamiento; + if (argumentos.CommandName == "VerEtapa") + { + int clave = Convert.ToInt32( + GvFraccionamientos.DataKeys[fila.RowIndex].Values["CveFraccionamientoEtapa"]); + if (clave > 0) + { + DetalleEtapa.Cargar(clave); + RegistraScript("SIGPanelLateral.abrir('" + PanelDetalleEtapa.ClientID + "');"); + } + + return; + } + + LitFraccionamientoEtapa.Text = fraccionamiento.Fraccionamiento; + TxtEtapa.Text = string.Empty; + TxtHectareasEtapa.Text = string.Empty; + UpModalEtapa.Update(); + RegistraScript("$('#ModalEtapa').modal('show');"); + } + + protected void GuardarEtapa_Click(object origen, EventArgs argumentos) + { + if (!ValidarDesarrollador() || + ObtenerFraccionamientoDelCliente(CveFraccionamientoEtapaActual) == null) + { + return; + } + + decimal? hectareas; + if (!LeerHectareas(TxtHectareasEtapa.Text, out hectareas)) + { + Alert("Capture hectáreas válidas.", TipoMensaje.MsgAdvertencia); + return; + } + + DbResult resultado = AppServices.ServicioFraccionamiento.GuardarEtapa( + new ModeloEtapaFraccionamiento + { + CveCliente = CveClienteActual, + CveFraccionamiento = CveFraccionamientoEtapaActual, + Etapa = TxtEtapa.Text, + Hectareas = hectareas, + EsActivo = true + }, + CurrentUser.CveUsuario, CurrentUser.NombreDominio); + if (!resultado.Success) + { + Alert(resultado.UserMessage, TipoMensaje.MsgAdvertencia); + return; + } + + CveFraccionamientoEtapaActual = 0; + CargarFraccionamientos(); + UpFraccionamientos.Update(); + RegistraScript("$('#ModalEtapa').modal('hide');"); + Alert("Etapa registrada.", TipoMensaje.ToastExito); + } + + private bool ValidarDesarrollador() + { + DbResult consulta = AppServices.ServicioDesarrolladores.Obtener(CveClienteActual); + if (!consulta.Success) + { + Alert(consulta.UserMessage, TipoMensaje.MsgAdvertencia); + return false; + } + + return true; + } + + private ModeloFraccionamiento ObtenerFraccionamientoDelCliente(int cveFraccionamiento) + { + DbResult consulta = AppServices.ServicioFraccionamiento.Obtener( + cveFraccionamiento, CurrentUser.CveUsuario, CurrentUser.NombreDominio); + if (!consulta.Success || consulta.Data == null || + consulta.Data.CveCliente != CveClienteActual || !consulta.Data.EsActivo) + { + Alert(consulta.Success ? "El fraccionamiento no está activo o no pertenece a este desarrollador." : + consulta.UserMessage, TipoMensaje.MsgAdvertencia); + return null; + } + + return consulta.Data; + } + + protected string ObtenerUrlFraccionamiento(object clave) + { + return ResolveUrl("~/Pages/Fraccionamientos/FraccionamientoDetalle.aspx?id=" + + Convert.ToInt32(clave).ToString(CultureInfo.InvariantCulture)); + } + + private void CargarFraccionamientos() + { + var resultado = AppServices.ServicioFraccionamiento.ListarDesarrollos( + CveClienteActual, CurrentUser.CveUsuario, CurrentUser.NombreDominio); + GvFraccionamientos.DataSource = resultado.Success ? resultado.Data : null; + GvFraccionamientos.DataBind(); + if (!resultado.Success) + { + Alert(resultado.UserMessage, TipoMensaje.MsgAdvertencia); + } + } + + private void CargarEstatus() + { + var resultado = AppServices.ServicioFraccionamiento.ListarEstatus( + CurrentUser.CveUsuario, CurrentUser.NombreDominio); + DdlEstatus.DataSource = resultado.Success ? resultado.Data : null; + DdlEstatus.DataTextField = "Estatus"; + DdlEstatus.DataValueField = "CveEstatus"; + DdlEstatus.DataBind(); + DdlEstatus.SelectedValue= "1"; + if (!resultado.Success) + { + Alert(resultado.UserMessage, TipoMensaje.MsgAdvertencia); + } + } + + private void MostrarDatos(ModeloDesarrollador desarrollador) + { + TxtRFC.Text = desarrollador.RFC; + TxtNombre.Text = desarrollador.Nombre; + TxtDireccion.Text = desarrollador.Direccion; + TxtNoExt.Text = desarrollador.NoExt; + TxtDuplicador.Text = desarrollador.Duplicador; + TxtReferencia.Text = desarrollador.Referencia; + TxtTelefono.Text = desarrollador.Telefono; + TxtMail.Text = desarrollador.Mail; + TxtAdherente.Text = desarrollador.Adherente; + TxtCP.Text = desarrollador.CP; + if (CargarColonias()) + { + ListItem colonia = DdlColonia.Items.FindByValue( + desarrollador.CveColonia.ToString(CultureInfo.InvariantCulture)); + if (colonia != null) + { + DdlColonia.SelectedValue = colonia.Value; + } + } + + AsociadoCanadeviActual = desarrollador.AsociadoCanadevi; + ChkCanadevi.Checked = desarrollador.AsociadoCanadevi; + } + + private static bool LeerHectareas(string texto, out decimal? hectareas) + { + hectareas = null; + if (string.IsNullOrWhiteSpace(texto)) + { + return true; + } + + decimal valor; + if (!decimal.TryParse(texto.Trim(), NumberStyles.AllowDecimalPoint, + CultureInfo.InvariantCulture, out valor) || valor < 0 || valor > 999999999.9999m) + { + return false; + } + + hectareas = valor; + return true; + } + + private ModeloDesarrollador LeerDesarrollador() + { + int cveColonia; + int.TryParse(DdlColonia.SelectedValue, out cveColonia); + return new ModeloDesarrollador + { + RFC = TxtRFC.Text, + Nombre = TxtNombre.Text, + Direccion = TxtDireccion.Text, + NoExt = TxtNoExt.Text, + Duplicador = TxtDuplicador.Text, + Referencia = TxtReferencia.Text, + Telefono = TxtTelefono.Text, + Mail = TxtMail.Text, + Adherente = TxtAdherente.Text, + CP = TxtCP.Text, + CveColonia = cveColonia, + AsociadoCanadevi = ChkCanadevi.Checked + }; + } + + protected void ConsultarCP_Click(object origen, EventArgs argumentos) + { + CargarColonias(); + } + + private bool CargarColonias() + { + DdlColonia.Items.Clear(); + LitUbicacionPostal.Text = string.Empty; + var resultado = AppServices.ServicioDesarrolladores.ConsultarCodigoPostal(TxtCP.Text); + if (!resultado.Success || resultado.Data == null) + { + Alert(resultado.Success ? "No se encontró el código postal." : resultado.UserMessage, + TipoMensaje.MsgAdvertencia); + return false; + } + + DdlColonia.DataSource = resultado.Data.Colonias; + DdlColonia.DataTextField = "NombreAsentamiento"; + DdlColonia.DataValueField = "CveColonia"; + DdlColonia.DataBind(); + DdlColonia.Items.Insert(0, new ListItem("Seleccione una colonia", "")); + LitUbicacionPostal.Text = resultado.Data.Ciudad + ", " + resultado.Data.Estado; + return true; + } + + private void ConfigurarCanadevi(bool asociado) + { + bool puedeEditar = AppServices.ServicioDesarrolladores.PuedeCambiarAsociadoCanadevi; + PnlEditarCanadevi.Visible = puedeEditar; + PnlConsultarCanadevi.Visible = !puedeEditar; + LitCanadevi.Text = "Asociado CANADEVI: " + (asociado ? "Sí" : "No"); + } + + } +} + diff --git a/SIG.Web/Pages/Desarrolladores/Desarrolladores.aspx b/SIG.Web/Pages/Desarrolladores/Desarrolladores.aspx new file mode 100644 index 0000000..f344a67 --- /dev/null +++ b/SIG.Web/Pages/Desarrolladores/Desarrolladores.aspx @@ -0,0 +1,300 @@ +<%@ Page Title="Desarrolladores" Language="C#" MasterPageFile="~/Site.master" + AutoEventWireup="true" CodeFile="Desarrolladores.aspx.cs" + Inherits="SIG.Web.Pages.Desarrolladores.Desarrolladores" %> +<%@ Register TagPrefix="sig" TagName="CapturaEtapas" Src="~/UserControl/CapturaEtapas.ascx" %> + + + + +
  • + + Agregar desarrollador + +
  • +
    + + + + + + + +

    Procesando...

    +
    +
    + + + + +
    + + + + + diff --git a/SIG.Web/Pages/Desarrolladores/Desarrolladores.aspx.cs b/SIG.Web/Pages/Desarrolladores/Desarrolladores.aspx.cs new file mode 100644 index 0000000..951051f --- /dev/null +++ b/SIG.Web/Pages/Desarrolladores/Desarrolladores.aspx.cs @@ -0,0 +1,376 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Web; +using System.Web.UI; +using System.Web.UI.WebControls; +using SIG.Web.AppCode.Configuration; +using SIG.Web.AppCode.Infrastructure.WebForms; +using SIG.Web.AppCode.Models.Clientes; +using SIG.Web.AppCode.Models.Common; +using SIG.Web.AppCode.Models.Fraccionamientos; +using SIG.Web.AppCode.Security; +using SIG.Web.AppCode.SigControls; + +namespace SIG.Web.Pages.Desarrolladores +{ + public partial class Desarrolladores : ClsPaginaBase + { + private int CveClienteFraccionamientoActual + { + get { return ViewState["CveClienteFraccionamientoActual"] as int? ?? 0; } + set { ViewState["CveClienteFraccionamientoActual"] = value; } + } + + private string TextoFiltro + { + get { return ViewState["TextoFiltroDesarrolladores"] as string ?? string.Empty; } + set { ViewState["TextoFiltroDesarrolladores"] = value; } + } + + private bool IncluirInactivos + { + get { return ViewState["IncluirDesarrolladoresInactivos"] as bool? ?? false; } + set { ViewState["IncluirDesarrolladoresInactivos"] = value; } + } + + protected void Page_Load(object origen, EventArgs argumentos) + { + Response.Cache.SetCacheability(HttpCacheability.NoCache); + Response.Cache.SetNoStore(); + ConfigurarCanadevi(false); + if (!IsPostBack) + { + Consultar(); + } + } + + protected void Consultar_Click(object origen, EventArgs argumentos) + { + GvDesarrolladores.PageIndex = 0; + Consultar(); + } + + protected void MostrarFiltros_Click(object origen, EventArgs argumentos) + { + TxtBusqueda.Text = TextoFiltro; + ChkInactivos.Checked = IncluirInactivos; + UpFiltros.Update(); + RegistraScript("$('#ModalFiltros').modal('show');"); + } + + protected void AplicarFiltros_Click(object origen, EventArgs argumentos) + { + TextoFiltro = TxtBusqueda.Text.Trim(); + IncluirInactivos = ChkInactivos.Checked; + GvDesarrolladores.PageIndex = 0; + Consultar(); + UpListado.Update(); + RegistraScript("$('#ModalFiltros').modal('hide');"); + } + + protected void Filtros_Cambiados(object origen, EventArgs argumentos) + { + IList filtros = FiltrosCatalogo.GetFiltros(); + if (!filtros.Any(filtro => filtro.Nombre == "Texto")) + { + TextoFiltro = string.Empty; + } + + IncluirInactivos = filtros.Any(filtro => filtro.Nombre == "Inactivos"); + GvDesarrolladores.PageIndex = 0; + Consultar(); + } + + protected void Pagina_Cambiada(object origen, GridViewPageEventArgs argumentos) + { + GvDesarrolladores.PageIndex = argumentos.NewPageIndex; + Consultar(); + } + + protected void GenerarUsuario_Cambiado(object origen, EventArgs argumentos) + { + PnlUsuario.Visible = ChkGenerarUsuario.Checked; + } + + protected void Desarrolladores_Comando(object origen, GridViewCommandEventArgs argumentos) + { + if (argumentos.CommandName != "AgregarFraccionamiento") + { + return; + } + + CveClienteFraccionamientoActual = 0; + LitDesarrolladorFraccionamiento.Text = string.Empty; + TxtFraccionamiento.Text = string.Empty; + TxtUbicacionFraccionamiento.Text = string.Empty; + TxtHectareasFraccionamiento.Text = string.Empty; + UcCapturaEtapas.Reiniciar(); + DdlEstatusFraccionamiento.Items.Clear(); + UpAltaFraccionamiento.Update(); + + var control = argumentos.CommandSource as Control; + var fila = control == null ? null : control.NamingContainer as GridViewRow; + if (fila == null) + { + return; + } + + int cveCliente = Convert.ToInt32(GvDesarrolladores.DataKeys[fila.RowIndex].Value); + var desarrollador = AppServices.ServicioDesarrolladores.Obtener(cveCliente); + if (!desarrollador.Success || desarrollador.Data == null) + { + Alert(desarrollador.Success ? "No se encontró el desarrollador." : + desarrollador.UserMessage, TipoMensaje.MsgAdvertencia); + return; + } + + var estatus = AppServices.ServicioFraccionamiento.ListarEstatus( + CurrentUser.CveUsuario, CurrentUser.NombreDominio); + if (!estatus.Success) + { + Alert(estatus.UserMessage, TipoMensaje.MsgAdvertencia); + return; + } + + CveClienteFraccionamientoActual = cveCliente; + LitDesarrolladorFraccionamiento.Text = desarrollador.Data.Nombre; + DdlEstatusFraccionamiento.DataSource = estatus.Data; + DdlEstatusFraccionamiento.DataTextField = "Estatus"; + DdlEstatusFraccionamiento.DataValueField = "CveEstatus"; + + DdlEstatusFraccionamiento.SelectedValue = "1"; + DdlEstatusFraccionamiento.DataBind(); + DdlEstatusFraccionamiento.Items.Insert(0, new ListItem("Seleccione un estatus", "")); + RegistraScript("$('#ModalAltaFraccionamiento').modal('show');"); + } + + protected void GuardarFraccionamiento_Click(object origen, EventArgs argumentos) + { + if (CveClienteFraccionamientoActual <= 0) + { + Alert("Seleccione un desarrollador desde el listado.", TipoMensaje.MsgAdvertencia); + return; + } + + var desarrollador = AppServices.ServicioDesarrolladores.Obtener(CveClienteFraccionamientoActual); + if (!desarrollador.Success || desarrollador.Data == null) + { + Alert(desarrollador.Success ? "No se encontró el desarrollador." : + desarrollador.UserMessage, TipoMensaje.MsgAdvertencia); + return; + } + + decimal? hectareas = null; + if (!string.IsNullOrWhiteSpace(TxtHectareasFraccionamiento.Text)) + { + decimal valor; + if (!decimal.TryParse(TxtHectareasFraccionamiento.Text.Trim(), + NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out valor) || + valor < 0 || valor > 999999999.9999m) + { + Alert("Capture hectáreas válidas.", TipoMensaje.MsgAdvertencia); + return; + } + + hectareas = valor; + } + + int cveEstatus; + if (!int.TryParse(DdlEstatusFraccionamiento.SelectedValue, out cveEstatus)) + { + Alert("Seleccione un estatus.", TipoMensaje.MsgAdvertencia); + return; + } + + List etapas; + string mensajeEtapas; + if (!UcCapturaEtapas.Capturar(out etapas, out mensajeEtapas)) + { + Alert(mensajeEtapas, TipoMensaje.MsgAdvertencia); + return; + } + + var resultado = AppServices.ServicioFraccionamiento.GuardarConEtapas( + new ModeloFraccionamiento + { + CveCliente = CveClienteFraccionamientoActual, + Fraccionamiento = TxtFraccionamiento.Text, + Ubicacion = TxtUbicacionFraccionamiento.Text, + Hectareas = hectareas, + CveEstatus = cveEstatus, + EsActivo = true + }, + etapas, + CurrentUser.CveUsuario, CurrentUser.NombreDominio); + if (!resultado.Success) + { + Alert(resultado.UserMessage, TipoMensaje.MsgAdvertencia); + return; + } + + CveClienteFraccionamientoActual = 0; + TxtFraccionamiento.Text = string.Empty; + TxtUbicacionFraccionamiento.Text = string.Empty; + TxtHectareasFraccionamiento.Text = string.Empty; + UcCapturaEtapas.Reiniciar(); + RegistraScript("$('#ModalAltaFraccionamiento').modal('hide');"); + Alert("Fraccionamiento registrado.", TipoMensaje.ToastExito); + } + + protected void Guardar_Click(object origen, EventArgs argumentos) + { + var solicitud = new SolicitudAltaDesarrollador + { + Desarrollador = LeerDesarrollador(), + GenerarUsuario = ChkGenerarUsuario.Checked, + NombreUsuario = TxtUsuario.Text, + CorreoUsuario = TxtCorreoUsuario.Text + }; + DbResult resultado = + AppServices.ServicioDesarrolladores.Agregar(solicitud); + if (!resultado.Success) + { + Alert(resultado.UserMessage, TipoMensaje.MsgAdvertencia); + return; + } + + bool mostrarCredenciales = solicitud.GenerarUsuario; + if (mostrarCredenciales) + { + LitUsuarioCreado.Text = solicitud.NombreUsuario; + LitContrasenaTemporal.Text = resultado.Data.ContrasenaTemporal; + LnkDetalleCreado.NavigateUrl = ObtenerUrlDesarrollador(resultado.Data.CveCliente); + UpCredenciales.Update(); + } + + TxtRFC.Text = string.Empty; + TxtNombre.Text = string.Empty; + TxtDireccion.Text = string.Empty; + TxtNoExt.Text = string.Empty; + TxtDuplicador.Text = string.Empty; + TxtReferencia.Text = string.Empty; + TxtTelefono.Text = string.Empty; + TxtMail.Text = string.Empty; + TxtAdherente.Text = string.Empty; + TxtCP.Text = string.Empty; + TxtUsuario.Text = string.Empty; + TxtCorreoUsuario.Text = string.Empty; + DdlColonia.Items.Clear(); + LitUbicacionPostal.Text = string.Empty; + ChkCanadevi.Checked = false; + ChkGenerarUsuario.Checked = false; + PnlUsuario.Visible = false; + GvDesarrolladores.PageIndex = 0; + Consultar(); + UpListado.Update(); + RegistraScript( + "SIGPanelLateral.cerrar('PanelAltaDesarrollador');" + + (mostrarCredenciales ? "$('#ModalCredenciales').modal('show');" : string.Empty)); + if (!mostrarCredenciales) + { + Alert("Desarrollador registrado.", TipoMensaje.ToastExito); + } + } + + protected string ObtenerUrlDesarrollador(object clave) + { + return ResolveUrl("~/Pages/Desarrolladores/DesarrolladorDetalle.aspx?cveCliente=" + + Convert.ToInt32(clave).ToString(CultureInfo.InvariantCulture)); + } + + private void Consultar() + { + DbResult> resultado = + AppServices.ServicioDesarrolladores.Listar(TextoFiltro, IncluirInactivos); + GvDesarrolladores.DataSource = resultado.Success ? resultado.Data : null; + GvDesarrolladores.DataBind(); + if (!resultado.Success) + { + Alert(resultado.UserMessage, TipoMensaje.MsgAdvertencia); + } + + var filtros = new List(); + if (!string.IsNullOrWhiteSpace(TextoFiltro)) + { + filtros.Add(new FiltroActivo + { + Nombre = "Texto", + Titulo = "Buscar", + Descripcion = TextoFiltro, + Orden = 1 + }); + } + + if (IncluirInactivos) + { + filtros.Add(new FiltroActivo + { + Nombre = "Inactivos", + Titulo = "Estado", + Descripcion = "Incluye inactivos", + Orden = 2 + }); + } + + FiltrosCatalogo.SetFiltros(filtros); + } + + private ModeloDesarrollador LeerDesarrollador() + { + int cveColonia; + int.TryParse(DdlColonia.SelectedValue, out cveColonia); + return new ModeloDesarrollador + { + RFC = TxtRFC.Text, + Nombre = TxtNombre.Text, + Direccion = TxtDireccion.Text, + NoExt = TxtNoExt.Text, + Duplicador = TxtDuplicador.Text, + Referencia = TxtReferencia.Text, + Telefono = TxtTelefono.Text, + Mail = TxtMail.Text, + Adherente = TxtAdherente.Text, + CP = TxtCP.Text, + CveColonia = cveColonia, + AsociadoCanadevi = ChkCanadevi.Checked + }; + } + + protected void ConsultarCP_Click(object origen, EventArgs argumentos) + { + CargarColonias(); + } + + private bool CargarColonias() + { + DdlColonia.Items.Clear(); + LitUbicacionPostal.Text = string.Empty; + var resultado = AppServices.ServicioDesarrolladores.ConsultarCodigoPostal(TxtCP.Text); + if (!resultado.Success || resultado.Data == null) + { + Alert(resultado.Success ? "No se encontró el código postal." : resultado.UserMessage, + TipoMensaje.MsgAdvertencia); + return false; + } + + DdlColonia.DataSource = resultado.Data.Colonias; + DdlColonia.DataTextField = "NombreAsentamiento"; + DdlColonia.DataValueField = "CveColonia"; + DdlColonia.DataBind(); + DdlColonia.Items.Insert(0, new ListItem("Seleccione una colonia", "")); + LitUbicacionPostal.Text = resultado.Data.Ciudad + ", " + resultado.Data.Estado; + return true; + } + + private void ConfigurarCanadevi(bool asociado) + { + bool puedeEditar = AppServices.ServicioDesarrolladores.PuedeCambiarAsociadoCanadevi; + PnlEditarCanadevi.Visible = puedeEditar; + PnlConsultarCanadevi.Visible = !puedeEditar; + LitCanadevi.Text = "Asociado CANADEVI: " + (asociado ? "Sí" : "No"); + } + + } +} diff --git a/SIG.Web/Pages/Desarrolladores/FacturasCfdi.aspx.designer.cs b/SIG.Web/Pages/Desarrolladores/FacturasCfdi.aspx.designer.cs deleted file mode 100644 index a5a3b4f..0000000 --- a/SIG.Web/Pages/Desarrolladores/FacturasCfdi.aspx.designer.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace SIG.Web.Pages.Desarrolladores -{ - public partial class FacturasCfdi - { - } -} diff --git a/SIG.Web/Pages/Desarrolladores/FacturasComerciales.aspx.designer.cs b/SIG.Web/Pages/Desarrolladores/FacturasComerciales.aspx.designer.cs deleted file mode 100644 index d52282e..0000000 --- a/SIG.Web/Pages/Desarrolladores/FacturasComerciales.aspx.designer.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace SIG.Web.Pages.Desarrolladores -{ - public partial class FacturasComerciales - { - } -} diff --git a/SIG.Web/Pages/Desarrolladores/FacturasComercialesListado.aspx.designer.cs b/SIG.Web/Pages/Desarrolladores/FacturasComercialesListado.aspx.designer.cs deleted file mode 100644 index 946ab4e..0000000 --- a/SIG.Web/Pages/Desarrolladores/FacturasComercialesListado.aspx.designer.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace SIG.Web.Pages.Desarrolladores -{ - public partial class FacturasComercialesListado - { - } -} diff --git a/SIG.Web/Pages/Desarrolladores/HistorialFacturas.aspx.designer.cs b/SIG.Web/Pages/Desarrolladores/HistorialFacturas.aspx.designer.cs deleted file mode 100644 index eaf9043..0000000 --- a/SIG.Web/Pages/Desarrolladores/HistorialFacturas.aspx.designer.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace SIG.Web.Pages.Desarrolladores -{ - public partial class HistorialFacturas - { - } -} diff --git a/SIG.Web/Pages/Desarrolladores/PagoDetalle.aspx b/SIG.Web/Pages/Desarrolladores/PagoDetalle.aspx new file mode 100644 index 0000000..7354542 --- /dev/null +++ b/SIG.Web/Pages/Desarrolladores/PagoDetalle.aspx @@ -0,0 +1,237 @@ +<%@ Page Title="Detalle de pago" Language="C#" MasterPageFile="~/Site.master" + AutoEventWireup="true" CodeFile="PagoDetalle.aspx.cs" Inherits="SIG.Web.Pages.Desarrolladores.PagoDetalle" %> + + + +
  • +
    + + + + +

    +

    +

    +

    + +
    +
    + + +

    Comprobantes de pago

    +

    Los comprobantes pendientes no se abonan al saldo hasta su aprobación.

    + +
    + + +
    +
    + + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + +
    +
    + + + + + + + + + + + + + + + +
    +
    +
    + + + +
    + + + + + + + + + + + +
    +
    +
    + + +
    + + + + + + + + + + + +
    +
    +
    + + +
    + + + + + + + + + + + + +
    +
    +
    + + +
    + + + + + + + + +
    +
    +
    + + + + + +
    + + + + + + + + +
    +
    +
    +
    +
    +
    +
    + +

    Abono recibido

    +

    +

    +

    Aplicaciones

    +
    + + + + + + + + + + +
    +

    Documentación fiscal registrada

    +
    + + + + + + + + + + + + +
    +
    +
    diff --git a/SIG.Web/Pages/Desarrolladores/PagoDetalle.aspx.cs b/SIG.Web/Pages/Desarrolladores/PagoDetalle.aspx.cs new file mode 100644 index 0000000..cb18222 --- /dev/null +++ b/SIG.Web/Pages/Desarrolladores/PagoDetalle.aspx.cs @@ -0,0 +1,226 @@ +using System; +using System.Globalization; +using System.Linq; +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.Tramites; +using SIG.Web.AppCode.Security; + +namespace SIG.Web.Pages.Desarrolladores +{ + public partial class PagoDetalle : ClsPaginaBase + { + private int CveObligacionActual + { + get { return (int?)ViewState["CveObligacionActual"] ?? 0; } + set { ViewState["CveObligacionActual"] = value; } + } + + private bool PuedeAprobarComprobantes + { + get + { + return !CurrentUser.EsDesarrollador && + AppServices.PermissionService.HasPermission(CurrentUser.CveUsuario, "Pagos.AprobarPagos"); + } + } + + protected void Page_Load(object origen, EventArgs argumentos) + { + ScriptManager.GetCurrent(Page).RegisterPostBackControl(EnviarComprobante); + if (!IsPostBack) + { + Recargar(origen, argumentos); + } + } + + protected void Recargar(object origen, EventArgs argumentos) + { + int clave; + if (int.TryParse(Request.QueryString["pago"], out clave) && clave > 0) + { + CargarAbono(clave); + } + else if (int.TryParse(Request.QueryString["id"], out clave) && clave > 0) + { + CargarObligacion(clave); + } + else + { + Alert("Seleccione un pago desde el listado.", TipoMensaje.MsgAdvertencia); + } + } + + private void CargarObligacion(int clave) + { + var resultado = AppServices.ServicioPagosConvenios.ObtenerObligacion( + clave, CurrentUser.CveUsuario, CurrentUser.NombreDominio); + if (!resultado.Success) + { + PnlObligacion.Visible = false; + Alert(resultado.UserMessage, TipoMensaje.MsgError); + return; + } + var pago = resultado.Data; + CveObligacionActual = clave; + CargarComprobantes(pago); + PnlObligacion.Visible = true; + LitDescripcion.Text = pago.Descripcion; + LitCliente.Text = pago.Cliente; + LnkFraccionamiento.Text = pago.Fraccionamiento + " / " + pago.Etapa; + LnkFraccionamiento.NavigateUrl = ResolveUrl("~/Pages/Fraccionamientos/FraccionamientoDetalle.aspx?id=" + + pago.CveFraccionamiento.ToString(CultureInfo.InvariantCulture)); + LitResumen.Text = string.Format(CultureInfo.CurrentCulture, + "{0} · {1} · {2} · Importe: {3:N2} {4} · Abonado: {5:N2} · Convenido: {6:N2} · Saldo: {7:N2}", + pago.TipoTramite, pago.EstadoAdministrativo, pago.EstatusFinanciero, + pago.Importe, pago.UnidadCobro, pago.ImporteAbonado, pago.ImporteConvenido, pago.SaldoPendiente); + GvProductos.DataSource = pago.Productos; + GvProductos.DataBind(); + GvParcialidades.RowDataBound += MarcarParcialidad; + GvParcialidades.DataSource = pago.Parcialidades; + GvParcialidades.DataBind(); + GvAplicaciones.DataSource = pago.Aplicaciones; + GvAplicaciones.DataBind(); + GvOrigenes.DataSource = pago.Origenes; + GvOrigenes.DataBind(); + GvRequerido.DataSource = pago.CambiosRequerido; + GvRequerido.DataBind(); + UpHistorialRequerido.Update(); + PagoRequerido.Cargar(new ModeloFiltroObligacionesPago { CveSolicitudPago = clave }); + LnkConvenio.Visible = !CurrentUser.EsDesarrollador && pago.EstadoAdministrativo == "ACTIVO" && + AppServices.PermissionService.HasPermission(CurrentUser.CveUsuario, + pago.Convenio == null ? "Convenios.Crear" : "Convenios.Modificar"); + LnkConvenio.Text = pago.Convenio == null ? "Crear convenio" : "Editar convenio"; + LnkConvenio.NavigateUrl = ResolveUrl("~/Pages/Desarrolladores/ConvenioDetalle.aspx?" + + (pago.Convenio == null ? "origen=" : "id=") + clave.ToString(CultureInfo.InvariantCulture)); + UpResumen.Update(); + } + + private void CargarAbono(int clave) + { + var resultado = AppServices.ServicioPagosConvenios.ObtenerAbono( + clave, CurrentUser.CveUsuario, CurrentUser.NombreDominio); + if (!resultado.Success) + { + Alert(resultado.UserMessage, TipoMensaje.MsgError); + return; + } + var abono = resultado.Data; + PnlAbono.Visible = true; + LitResumenAbono.Text = string.Format(CultureInfo.CurrentCulture, + "{0} · {1:dd/MM/yyyy} · Referencia: {2} · {3} · {4:N6} {5} · Conversión: {6:N6} · {7:N2} MXN · Sin aplicar: {8:N6} {5}", + abono.Cliente, abono.FechaPago, abono.Referencia, abono.EsActivo ? "Activo" : "Cancelado", + abono.Importe, abono.UnidadCobro, abono.ValorConversion, abono.ImporteMXN, abono.ImporteSinAplicar); + LitObservacionesAbono.Text = abono.Observaciones; + GvDetalleAbono.DataSource = abono.Aplicaciones; + GvDetalleAbono.DataBind(); + GvDocumentos.DataSource = abono.Documentos; + GvDocumentos.DataBind(); + } + + private void CargarComprobantes(ModeloObligacionPago obligacion) + { + CapturaComprobante.Visible = CurrentUser.EsDesarrollador; + UnidadComprobante.Text = " (" + obligacion.UnidadCobro + ")"; + var formas = AppServices.ServicioPagosConvenios.ListarFormasComprobante( + CurrentUser.CveUsuario, CurrentUser.NombreDominio); + FormaComprobante.DataSource = formas.Success ? formas.Data : null; + FormaComprobante.DataTextField = "FormaPago"; + FormaComprobante.DataValueField = "CveFormaPago"; + FormaComprobante.DataBind(); + if (!formas.Success) + { + Alert(formas.UserMessage, TipoMensaje.MsgAdvertencia); + } + FechaComprobante.Text = DateTime.Today.ToString("yyyy-MM-dd"); + var consulta = AppServices.ServicioPagosConvenios.ListarComprobantes( + obligacion.CveSolicitudPago, CurrentUser.CveUsuario, CurrentUser.NombreDominio); + Comprobantes.Columns[Comprobantes.Columns.Count - 1].Visible = PuedeAprobarComprobantes; + Comprobantes.DataSource = consulta.Success ? consulta.Data : null; + Comprobantes.DataBind(); + if (!consulta.Success) + { + Alert(consulta.UserMessage, TipoMensaje.MsgAdvertencia); + } + UpComprobantes.Update(); + } + + protected void EnviarComprobante_Click(object origen, EventArgs argumentos) + { + decimal importe; + DateTime fecha; + byte forma; + if (!ArchivoComprobante.HasFile || + !decimal.TryParse(ImporteComprobante.Text, NumberStyles.AllowDecimalPoint, + CultureInfo.CurrentCulture, out importe) || + !DateTime.TryParseExact(FechaComprobante.Text, "yyyy-MM-dd", + CultureInfo.InvariantCulture, DateTimeStyles.None, out fecha) || + !byte.TryParse(FormaComprobante.SelectedValue, out forma)) + { + Alert("Capture los datos del pago y seleccione su comprobante.", TipoMensaje.MsgAdvertencia); + return; + } + var resultado = AppServices.ServicioPagosConvenios.EnviarComprobante(new ModeloComprobantePago + { + CveSolicitudPago = CveObligacionActual, + FechaPago = fecha, + Importe = importe, + CveFormaPago = forma, + Referencia = ReferenciaComprobante.Text.Trim(), + NombreArchivo = ArchivoComprobante.FileName, + TipoContenido = ArchivoComprobante.PostedFile.ContentType, + TamanoBytes = ArchivoComprobante.PostedFile.ContentLength + }, ArchivoComprobante.PostedFile.InputStream, CurrentUser.CveUsuario, CurrentUser.NombreDominio); + if (!resultado.Success) + { + Alert(resultado.UserMessage, TipoMensaje.MsgAdvertencia); + return; + } + ImporteComprobante.Text = string.Empty; + ReferenciaComprobante.Text = string.Empty; + CargarObligacion(CveObligacionActual); + Alert("Comprobante enviado. El pago queda pendiente de aprobación.", TipoMensaje.ToastExito); + } + + protected void Comprobante_Enlazar(object origen, GridViewRowEventArgs argumentos) + { + var comprobante = argumentos.Row.DataItem as ModeloComprobantePago; + if (comprobante != null) + { + argumentos.Row.FindControl("AprobarComprobante").Visible = + PuedeAprobarComprobantes && !comprobante.CvePago.HasValue; + } + } + + protected void Comprobante_Comando(object origen, GridViewCommandEventArgs argumentos) + { + int indice; + if (argumentos.CommandName != "Aprobar" || !PuedeAprobarComprobantes || + !int.TryParse(Convert.ToString(argumentos.CommandArgument), out indice) || + indice < 0 || indice >= Comprobantes.DataKeys.Count) + { + return; + } + var resultado = AppServices.ServicioPagosConvenios.AprobarComprobante( + Convert.ToInt32(Comprobantes.DataKeys[indice].Value), + CurrentUser.CveUsuario, CurrentUser.NombreDominio); + if (resultado.Success) + { + CargarObligacion(CveObligacionActual); + } + Alert(resultado.Success ? "Pago aprobado y aplicado al saldo." : resultado.UserMessage, + resultado.Success ? TipoMensaje.ToastExito : TipoMensaje.MsgAdvertencia); + } + + private void MarcarParcialidad(object origen, GridViewRowEventArgs argumentos) + { + var parcialidad = argumentos.Row.DataItem as ModeloParcialidadObligacion; + if (parcialidad != null && parcialidad.EstaVencida) + { + argumentos.Row.CssClass = "danger"; + } + } + } +} diff --git a/SIG.Web/Pages/Desarrolladores/Pagos.aspx b/SIG.Web/Pages/Desarrolladores/Pagos.aspx new file mode 100644 index 0000000..2e30894 --- /dev/null +++ b/SIG.Web/Pages/Desarrolladores/Pagos.aspx @@ -0,0 +1,94 @@ +<%@ Page Title="Pagos" Language="C#" MasterPageFile="~/Site.master" + AutoEventWireup="true" CodeFile="Pagos.aspx.cs" Inherits="SIG.Web.Pages.Desarrolladores.Pagos" %> + + + + + + + + + + + + + + + + +

    Obligaciones sin saldo pendiente y canceladas. El saldo convenido se muestra separado de lo abonado.

    + +
    +
    + + + + +

    Los filtros de cliente, fraccionamiento y fechas se aplican a los abonos. Las fechas corresponden al pago recibido.

    + + + + + + + + + + + + + +
    +
    +
    +
    +
    + +

    Consultando...

    +
    + +
    + + diff --git a/SIG.Web/Pages/Desarrolladores/Pagos.aspx.cs b/SIG.Web/Pages/Desarrolladores/Pagos.aspx.cs new file mode 100644 index 0000000..1e445e4 --- /dev/null +++ b/SIG.Web/Pages/Desarrolladores/Pagos.aspx.cs @@ -0,0 +1,195 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +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; +using SIG.Web.AppCode.SigControls; + +namespace SIG.Web.Pages.Desarrolladores +{ + public partial class Pagos : ClsPaginaBase + { + private ModeloFiltroObligacionesPago FiltroActual + { + get { return ViewState["FiltroActual"] as ModeloFiltroObligacionesPago ?? new ModeloFiltroObligacionesPago(); } + set { ViewState["FiltroActual"] = value; } + } + + protected void Page_Load(object origen, EventArgs argumentos) + { + if (!IsPostBack) + { + CargarOpciones(); + Consultar(origen, argumentos); + } + + } + + private void CargarOpciones() + { + var resultado = AppServices.ServicioPagosConvenios.ListarObligaciones(new ModeloFiltroObligacionesPago(), + CurrentUser.CveUsuario, CurrentUser.NombreDominio); + var obligaciones = resultado.Success ? resultado.Data : new List(); + 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 opciones) + { + lista.Items.Clear(); + lista.Items.Add(new ListItem("Todos", "")); + foreach (var opcion in opciones.OrderBy(opcion => opcion.Text)) + { + lista.Items.Add(opcion); + } + } + + protected void Consultar(object origen, EventArgs argumentos) + { + var filtro = FiltroActual; + filtro.SoloPendientes = null; + if (PestanasPagos.ActiveTabIndex == 2) + { + var resultado = AppServices.ServicioPagosConvenios.ListarAbonos( + new ModeloFiltroAbonos + { + CveCliente = filtro.CveCliente, + CveFraccionamiento = filtro.CveFraccionamiento, + Desde = filtro.Desde, + Hasta = filtro.Hasta + }, CurrentUser.CveUsuario, CurrentUser.NombreDominio); + GvAbonos.DataSource = resultado.Success ? resultado.Data : null; + GvAbonos.DataBind(); + UpAbonos.Update(); + if (!resultado.Success) + { + Alert(resultado.UserMessage, TipoMensaje.MsgError); + } + } + else + { + var resultado = AppServices.ServicioPagosConvenios.ListarObligaciones( + filtro, CurrentUser.CveUsuario, CurrentUser.NombreDominio); + var obligaciones = resultado.Success ? resultado.Data : new List(); + bool pendientes = PestanasPagos.ActiveTabIndex == 0; + obligaciones = obligaciones.Where(pago => + pendientes == (pago.SaldoPendiente > 0 && pago.EstadoAdministrativo == "ACTIVO")).ToList(); + (pendientes ? PagosPendientes : PagosHistorico).Mostrar(obligaciones, filtro); + if (!resultado.Success) + { + Alert(resultado.UserMessage, TipoMensaje.MsgError); + } + } + MostrarFiltrosActivos(); + } + + protected void MostrarFiltros(object origen, EventArgs argumentos) + { + var filtro = FiltroActual; + DdlCliente.SelectedValue = Convert.ToString(filtro.CveCliente, CultureInfo.InvariantCulture); + DdlFraccionamiento.SelectedValue = Convert.ToString(filtro.CveFraccionamiento, CultureInfo.InvariantCulture); + 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) + { + DateTime desde; + DateTime hasta; + 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) + { + var nombres = new HashSet(FiltrosListado.GetFiltros().Select(filtro => filtro.Nombre)); + var filtroActual = FiltroActual; + if (!nombres.Contains("Cliente")) { filtroActual.CveCliente = null; } + 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() + { + var filtro = FiltroActual; + var activos = new List(); + AgregarFiltro(activos, "Cliente", filtro.CveCliente.HasValue ? DdlCliente.Items.FindByValue(filtro.CveCliente.Value.ToString()).Text : null); + 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 filtros, string nombre, string descripcion) + { + if (!string.IsNullOrWhiteSpace(descripcion)) + { + filtros.Add(new FiltroActivo + { + Nombre = nombre, + Titulo = nombre == "Tramite" ? "Trámite" : nombre, + Descripcion = descripcion, + Orden = filtros.Count + }); + } + } + } +} diff --git a/SIG.Web/Pages/Desarrolladores/Predios.aspx.designer.cs b/SIG.Web/Pages/Desarrolladores/Predios.aspx.designer.cs deleted file mode 100644 index c2e47a4..0000000 --- a/SIG.Web/Pages/Desarrolladores/Predios.aspx.designer.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace SIG.Web.Pages.Desarrolladores -{ - public partial class Predios - { - } -} diff --git a/SIG.Web/Pages/Desarrolladores/Tramites.aspx b/SIG.Web/Pages/Desarrolladores/Tramites.aspx index fa08764..e5ab53c 100644 --- a/SIG.Web/Pages/Desarrolladores/Tramites.aspx +++ b/SIG.Web/Pages/Desarrolladores/Tramites.aspx @@ -1,8 +1,244 @@ -<%@ Page Title="Trámites" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="Tramites.aspx.cs" Inherits="SIG.Web.Pages.Desarrolladores.Tramites" %> - +<%@ Page Title="Trámites" Language="C#" MasterPageFile="~/Site.master" + AutoEventWireup="true" CodeFile="Tramites.aspx.cs" + Inherits="SIG.Web.Pages.Desarrolladores.Tramites" %> + + + " rel="stylesheet" /> - -

    Trámites

    + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + + + +
    + + Consultando trámites... +
    +
    +
    + + + + +
    - + + + diff --git a/SIG.Web/Pages/Desarrolladores/Tramites.aspx.cs b/SIG.Web/Pages/Desarrolladores/Tramites.aspx.cs index db54787..3c21f02 100644 --- a/SIG.Web/Pages/Desarrolladores/Tramites.aspx.cs +++ b/SIG.Web/Pages/Desarrolladores/Tramites.aspx.cs @@ -1,12 +1,606 @@ -using System; +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.Common; +using SIG.Web.AppCode.Models.Tramites; using SIG.Web.AppCode.Security; +using SIG.Web.AppCode.SigControls; namespace SIG.Web.Pages.Desarrolladores { public partial class Tramites : ClsPaginaBase { - protected void Page_Load(object sender, EventArgs e) + private ModeloFiltroTableroTramites FiltrosTableroActuales { + get + { + return ViewState["FiltrosTableroActuales"] as ModeloFiltroTableroTramites + ?? new ModeloFiltroTableroTramites(); + } + set + { + ViewState["FiltrosTableroActuales"] = value; + } } + + // Permite reconstruir las filas agrupadoras sin repetir la consulta en cada postback. + private List FilasTableroActuales + { + get + { + return ViewState["FilasTableroActuales"] as List + ?? new List(); + } + set + { + ViewState["FilasTableroActuales"] = value; + } + } + + protected override void OnInit(EventArgs argumentos) + { + base.OnInit(argumentos); + UcEstatusSolicitud.ObtenerCondiciones = UcCondicionesSolicitud.Capturar; + + bool esCliente = CurrentUser.EsDesarrollador; + PestanaSeguimientoCondiciones.Visible = !esCliente; + GvTramites.Columns[0].Visible = !esCliente; + CampoSoloBloqueados.Visible = !esCliente; + + DdlAgrupacion.Items.Add(new ListItem( + "Por trámite", + ((byte)AgrupacionTableroTramites.PorTramite).ToString(CultureInfo.InvariantCulture))); + + if (!esCliente) + { + DdlAgrupacion.Items.Add(new ListItem( + "Por cliente", + ((byte)AgrupacionTableroTramites.PorCliente).ToString(CultureInfo.InvariantCulture))); + } + } + + protected void Page_Load(object origen, EventArgs argumentos) + { + ScriptManager.GetCurrent(Page).RegisterAsyncPostBackControl(UcFiltros); + + if (!IsPostBack) + { + CargarTablero(); + return; + } + + EnlazarTablero(); + } + + protected void UcFiltros_MostrarFiltros(object origen, EventArgs argumentos) + { + SincronizarModalFiltros(); + UpFiltros.Update(); + RegistraScript( + "SIGTableroTramites.mostrarModal('ModalFiltrosTramites');", + "MostrarFiltrosTramites"); + } + + protected void UcFiltros_Consultar(object origen, EventArgs argumentos) + { + CargarTablero(); + UpTablero.Update(); + } + + protected void UcFiltros_FiltrosCambiados(object origen, EventArgs argumentos) + { + IList filtrosVisibles = UcFiltros.GetFiltros(); + ModeloFiltroTableroTramites filtros = FiltrosTableroActuales; + + if (!filtrosVisibles.Any(filtro => filtro.Nombre == "Agrupacion")) + { + filtros.Agrupacion = AgrupacionTableroTramites.PorTramite; + } + + if (!filtrosVisibles.Any(filtro => filtro.Nombre == "Fraccionamiento")) + { + filtros.CveFraccionamiento = null; + } + + filtros.SoloActivos = filtrosVisibles.Any(filtro => filtro.Nombre == "SoloActivos"); + filtros.SoloBloqueados = !CurrentUser.EsDesarrollador && + filtrosVisibles.Any(filtro => filtro.Nombre == "SoloBloqueados"); + if (!filtrosVisibles.Any(filtro => filtro.Nombre == "Estatus")) + { + filtros.EstatusSeleccionados.Clear(); + filtros.MostrarAutorizados = false; + filtros.MostrarCancelados = false; + } + FiltrosTableroActuales = filtros; + + CargarTablero(); + UpTablero.Update(); + } + + protected void BtnAplicarFiltros_Click(object origen, EventArgs argumentos) + { + byte cveAgrupacion; + int cveFraccionamiento; + + if (!byte.TryParse(DdlAgrupacion.SelectedValue, out cveAgrupacion) || + !Enum.IsDefined(typeof(AgrupacionTableroTramites), cveAgrupacion)) + { + Alert("Seleccione una agrupación válida.", TipoMensaje.MsgAdvertencia); + return; + } + + FiltrosTableroActuales = new ModeloFiltroTableroTramites + { + Agrupacion = (AgrupacionTableroTramites)cveAgrupacion, + CveFraccionamiento = int.TryParse(DdlFraccionamiento.SelectedValue, out cveFraccionamiento) + && cveFraccionamiento > 0 ? (int?)cveFraccionamiento : null, + EstatusSeleccionados = LstEstatus.Items.Cast() + .Where(estatus => estatus.Selected) + .Select(estatus => int.Parse(estatus.Value, CultureInfo.InvariantCulture)).ToList(), + MostrarAutorizados = ChkMostrarAutorizados.Checked, + MostrarCancelados = ChkMostrarCancelados.Checked, + SoloActivos = ChkSoloActivos.Checked, + SoloBloqueados = !CurrentUser.EsDesarrollador && ChkSoloBloqueados.Checked + }; + + bool consultaCorrecta = CargarTablero(); + UpTablero.Update(); + + if (consultaCorrecta) + { + RegistraScript( + "SIGTableroTramites.ocultarModal('ModalFiltrosTramites');", + "OcultarFiltrosTramites"); + } + } + + protected void GvTramites_FilaEnlazada(object origen, GridViewRowEventArgs argumentos) + { + if (argumentos.Row.RowType != DataControlRowType.DataRow) + { + return; + } + + var solicitud = (ModeloFilaTableroTramites)argumentos.Row.DataItem; + argumentos.Row.Attributes["data-cve-agrupacion"] = + solicitud.CveAgrupacion.ToString(CultureInfo.InvariantCulture); + argumentos.Row.Attributes["data-nivel"] = + solicitud.Nivel.ToString(CultureInfo.InvariantCulture); + + if (solicitud.Nivel == 2) + { + int columnasVisibles = GvTramites.Columns + .Cast() + .Count(columna => columna.Visible); + + argumentos.Row.Cells.Clear(); + argumentos.Row.CssClass = "sig-tramites-agrupacion"; + + var celda = new TableCell + { + ColumnSpan = columnasVisibles + }; + var boton = new HtmlGenericControl("button"); + boton.Attributes["type"] = "button"; + boton.Attributes["class"] = "sig-tramites-alternar-grupo"; + boton.Attributes["aria-expanded"] = "true"; + + var nombreGrupo = new HtmlGenericControl("span") + { + InnerText = solicitud.Agrupacion + }; + var flecha = new HtmlGenericControl("i"); + flecha.Attributes["class"] = "fa fa-chevron-up"; + flecha.Attributes["aria-hidden"] = "true"; + + boton.Controls.Add(nombreGrupo); + boton.Controls.Add(flecha); + celda.Controls.Add(boton); + argumentos.Row.Cells.Add(celda); + return; + } + + argumentos.Row.CssClass = "sig-proceso-" + + solicitud.EstatusProceso.ToString(CultureInfo.InvariantCulture); + argumentos.Row.ToolTip = solicitud.NombreEstatusProceso; + + var enlaceFraccionamiento = + (HyperLink)argumentos.Row.FindControl("EnlaceFraccionamiento"); + var nombreFraccionamientoEtapa = + (Literal)enlaceFraccionamiento.FindControl("NombreFraccionamientoEtapa"); + nombreFraccionamientoEtapa.Text = string.Join(" · ", + new[] { solicitud.Fraccionamiento, solicitud.Etapa } + .Where(nombre => !string.IsNullOrWhiteSpace(nombre))); + if (solicitud.CveFraccionamiento.GetValueOrDefault() > 0) + { + enlaceFraccionamiento.NavigateUrl = ResolveUrl( + "~/Pages/Fraccionamientos/FraccionamientoDetalle.aspx?id=" + + solicitud.CveFraccionamiento.Value.ToString(CultureInfo.InvariantCulture)); + } + + foreach (string nombreBoton in new[] { "BtnEditarEstatus", "BtnDocumentos", "BtnComentarios" }) + { + var boton = argumentos.Row.FindControl(nombreBoton) as LinkButton; + if (boton != null) + { + boton.Attributes["data-sig-panel-abrir"] = "#" + PanelSeguimiento.ClientID; + // Ejecuta el postback de WebForms; el evento del panel cancela el href para no duplicarlo. + boton.OnClientClick = Page.ClientScript.GetPostBackEventReference(boton, string.Empty) + ";"; + ScriptManager.GetCurrent(Page).RegisterAsyncPostBackControl(boton); + } + } + } + + protected void GvTramites_Comando(object origen, GridViewCommandEventArgs argumentos) + { + if (argumentos.CommandName != "EditarEstatus" && + argumentos.CommandName != "Documentos" && + argumentos.CommandName != "Comentarios") + { + return; + } + + var control = argumentos.CommandSource as Control; + var fila = control == null ? null : control.NamingContainer as GridViewRow; + if (fila == null || fila.RowIndex < 0 || fila.RowIndex >= GvTramites.DataKeys.Count) + { + Alert("Seleccione una solicitud válida.", TipoMensaje.MsgAdvertencia); + return; + } + + DataKey claveFila = GvTramites.DataKeys[fila.RowIndex]; + int cveSolicitud; + if (Convert.ToInt32(claveFila.Values["Nivel"]) != 1 || + !int.TryParse(Convert.ToString(claveFila.Values["CveSolicitud"]), out cveSolicitud)) + { + Alert("Seleccione una solicitud válida.", TipoMensaje.MsgAdvertencia); + return; + } + + string pestana = argumentos.CommandName == "Comentarios" ? "comentarios" : + argumentos.CommandName == "Documentos" ? "documentos" : "estatus"; + AbrirSeguimiento(cveSolicitud, null, pestana); + } + + protected void SeguimientoTramite_Cambiado(object origen, EventArgs argumentos) + { + CargarTablero(); + UpTablero.Update(); + } + + private bool CargarTablero() + { + DbResult resultado = + AppServices.TramiteSolicitudService.ConsultarTablero( + FiltrosTableroActuales, + CurrentUser.CveUsuario, + CurrentUser.NombreDominio); + + if (!resultado.Success || resultado.Data == null) + { + FilasTableroActuales = new List(); + EnlazarTablero(); + Alert( + resultado.Success ? "No se pudo obtener el tablero." : resultado.UserMessage, + TipoMensaje.MsgError); + return false; + } + + LstEstatus.Items.Clear(); + foreach (TramiteSolicitudEstatusOptionModel estatus in resultado.Data.Estatus) + { + var opcionEstatus = new ListItem( + estatus.EstatusSolicitud, + estatus.CveEstatusSolicitud.ToString(CultureInfo.InvariantCulture)); + opcionEstatus.Attributes["data-codigo-estatus"] = estatus.Codigo; + LstEstatus.Items.Add(opcionEstatus); + } + + FilasTableroActuales = resultado.Data.Filas; + DdlFraccionamiento.DataSource = resultado.Data.Fraccionamientos; + DdlFraccionamiento.DataTextField = "Fraccionamiento"; + DdlFraccionamiento.DataValueField = "CveFraccionamiento"; + DdlFraccionamiento.DataBind(); + DdlFraccionamiento.Items.Insert(0, new ListItem("Todos", "")); + + SincronizarModalFiltros(); + SincronizarFiltrosActivos(); + EnlazarTablero(); + return true; + } + + private void EnlazarTablero() + { + GvTramites.DataSource = FilasTableroActuales; + GvTramites.DataBind(); + } + + private void SincronizarModalFiltros() + { + ModeloFiltroTableroTramites filtros = FiltrosTableroActuales; + DdlAgrupacion.SelectedValue = ((byte)filtros.Agrupacion).ToString(CultureInfo.InvariantCulture); + string cveFraccionamiento = filtros.CveFraccionamiento.HasValue + ? filtros.CveFraccionamiento.Value.ToString(CultureInfo.InvariantCulture) : ""; + + DdlFraccionamiento.ClearSelection(); + ListItem opcion = DdlFraccionamiento.Items.FindByValue(cveFraccionamiento); + if (opcion != null) + { + opcion.Selected = true; + } + + foreach (ListItem estatus in LstEstatus.Items) + { + estatus.Selected = filtros.EstatusSeleccionados.Contains( + int.Parse(estatus.Value, CultureInfo.InvariantCulture)); + } + + ChkMostrarAutorizados.Checked = filtros.MostrarAutorizados; + ChkMostrarCancelados.Checked = filtros.MostrarCancelados; + LstEstatus.Attributes["data-sig-estatus-anteriores"] = + string.Join(",", filtros.EstatusSeleccionados); + ChkSoloActivos.Checked = filtros.SoloActivos; + ChkSoloBloqueados.Checked = !CurrentUser.EsDesarrollador && filtros.SoloBloqueados; + } + + private void SincronizarFiltrosActivos() + { + ModeloFiltroTableroTramites filtros = FiltrosTableroActuales; + var filtrosActivos = new List + { + new FiltroActivo + { + Nombre = "Agrupacion", + Titulo = "Agrupación", + Descripcion = DdlAgrupacion.SelectedItem.Text, + Orden = 1, + Visible = true + } + }; + + if (filtros.CveFraccionamiento.HasValue) + { + filtrosActivos.Add(new FiltroActivo + { + Nombre = "Fraccionamiento", + Titulo = "Fraccionamiento", + Descripcion = DdlFraccionamiento.SelectedItem.Text, + Orden = 2, + Visible = true + }); + } + + if (filtros.SoloActivos) + { + filtrosActivos.Add(new FiltroActivo + { + Nombre = "SoloActivos", + Titulo = "Solo activos", + Descripcion = "Tipos de trámite activos", + Orden = 3, + Visible = true + }); + } + + if (filtros.SoloBloqueados && !CurrentUser.EsDesarrollador) + { + filtrosActivos.Add(new FiltroActivo + { + Nombre = "SoloBloqueados", + Titulo = "Solo bloqueados", + Descripcion = "Pendiente de habilitar", + Orden = 4, + Visible = true + }); + } + + if (filtros.EstatusSeleccionados.Count > 0 || + filtros.MostrarAutorizados || filtros.MostrarCancelados) + { + filtrosActivos.Add(new FiltroActivo + { + Nombre = "Estatus", + Titulo = "Estatus", + Descripcion = string.Join(", ", LstEstatus.Items.Cast() + .Where(estatus => estatus.Selected) + .Select(estatus => estatus.Text)), + Orden = 5, + Visible = true + }); + } + + UcFiltros.SetFiltros(filtrosActivos); + } + private int CveSolicitudSeguimiento + { + get { return (int?)ViewState["CveSolicitudSeguimiento"] ?? 0; } + set { ViewState["CveSolicitudSeguimiento"] = value; } + } + + private int CveFraccionamientoSeguimiento + { + get { return (int?)ViewState["CveFraccionamientoSeguimiento"] ?? 0; } + set { ViewState["CveFraccionamientoSeguimiento"] = value; } + } + + private void AbrirSeguimiento(int cveSolicitud, int? cveFraccionamiento = null, string seccion = null) + { + DbResult resultado = + AppServices.TramiteSolicitudService.ObtenerContextoCambioEstatus( + cveSolicitud, CurrentUser.CveUsuario, CurrentUser.NombreDominio); + if (!resultado.Success || resultado.Data == null) + { + Alert(resultado.UserMessage, TipoMensaje.MsgAdvertencia); + return; + } + ModeloContextoCambioEstatus contexto = resultado.Data; + if (cveFraccionamiento.HasValue && + contexto.Solicitud.CveFraccionamiento != cveFraccionamiento.Value) + { + Alert("La solicitud no pertenece al fraccionamiento.", TipoMensaje.MsgAdvertencia); + return; + } + CveSolicitudSeguimiento = cveSolicitud; + CveFraccionamientoSeguimiento = contexto.Solicitud.CveFraccionamiento; + TituloSeguimiento.Text = contexto.Solicitud.Folio + " · " + contexto.Solicitud.TipoTramite; + NombreFraccionamientoEtapaSeguimiento.Text = string.Join(" · ", + new[] { contexto.Solicitud.Fraccionamiento, contexto.Solicitud.Etapa } + .Where(nombre => !string.IsNullOrWhiteSpace(nombre))); + EnlaceFraccionamientoSeguimiento.NavigateUrl = ResolveUrl( + "~/Pages/Fraccionamientos/FraccionamientoDetalle.aspx?id=" + + CveFraccionamientoSeguimiento.ToString(CultureInfo.InvariantCulture)); + PestanaSeguimientoCondiciones.Visible = !CurrentUser.EsDesarrollador; + if (!CurrentUser.EsDesarrollador) + { + UcCondicionesSolicitud.Cargar(contexto); + } + UcEstatusSolicitud.Cargar(contexto); + UcDocumentosSolicitud.Cargar(cveSolicitud, CveFraccionamientoSeguimiento, contexto.Documentos); + UcComentariosSolicitud.Cargar(cveSolicitud); + UcSupervisionesSolicitud.CveFraccionamiento = CveFraccionamientoSeguimiento; + UcSupervisionesSolicitud.CveFraccionamientoEtapa = contexto.Solicitud.CveFraccionamientoEtapa; + UcSupervisionesSolicitud.CveSolicitud = cveSolicitud; + UcSupervisionesSolicitud.Cargar(); + UcPagosSolicitud.Cargar(new ModeloFiltroObligacionesPago { CveSolicitud = cveSolicitud }); + MostrarPagosSeguimiento(contexto.Pagos); + CargarAccionesPendientesSeguimiento(); + UpEncabezadoSeguimiento.Update(); + MostrarSeguimiento(seccion); + } + + private void MostrarSeguimiento(string seccion = null) + { + if (CurrentUser.EsDesarrollador && seccion == "condiciones") + { + seccion = null; + } + int indice = seccion == "condiciones" ? 1 : seccion == "documentos" ? 2 : + seccion == "comentarios" ? 3 : seccion == "supervisiones" ? 4 : seccion == "pagos" ? 5 : 0; + PestanasSeguimiento.ActiveTabIndex = indice; + // El clic abre el panel. Restaurarlo sólo si una carga de archivo recargó la página. + if (!ScriptManager.GetCurrent(Page).IsInAsyncPostBack) + { + RegistraScript("SIGPanelLateral.abrir('" + PanelSeguimiento.ClientID + "');"); + return; + } + RegistraScript( + "$find('" + PestanasSeguimiento.ClientID + "').set_activeTabIndex(" + + indice.ToString(CultureInfo.InvariantCulture) + ");"); + } + + private void ActualizarSeguimiento() + { + CargarAccionesPendientesSeguimiento(); + UpEncabezadoSeguimiento.Update(); + SeguimientoTramite_Cambiado(this, EventArgs.Empty); + } + + protected void EstatusSeguimiento_SeleccionCambiada(object origen, EventArgs argumentos) + { + UcCondicionesSolicitud.AjustarEstatus(UcEstatusSolicitud.EstatusSeleccionado); + } + + protected void EstatusSeguimiento_RequisitosPendientes(object origen, EventArgs argumentos) + { + RefrescarRequisitosSeguimiento(); + MostrarSeguimiento(UcEstatusSolicitud.SeccionPendiente); + } + + protected void EstatusSeguimiento_Cambiado(object origen, EventArgs argumentos) + { + bool ofrecerProgramacion = UcEstatusSolicitud.OfrecerProgramacion; + AbrirSeguimiento(CveSolicitudSeguimiento, CveFraccionamientoSeguimiento); + SeguimientoTramite_Cambiado(this, EventArgs.Empty); + if (ofrecerProgramacion) + { + UcSupervisionesSolicitud.Programar(); + } + } + + protected void CondicionesSeguimiento_Cambiado(object origen, EventArgs argumentos) + { + ActualizarSeguimiento(); + MostrarSeguimiento("condiciones"); + } + + protected void DocumentosSeguimiento_Cambiados(object origen, EventArgs argumentos) + { + ActualizarSeguimiento(); + MostrarSeguimiento("documentos"); + } + + protected void DocumentosSeguimiento_MostrarSolicitado(object origen, EventArgs argumentos) + { + MostrarSeguimiento("documentos"); + } + + protected void ComentariosSeguimiento_Cambiado(object origen, EventArgs argumentos) + { + ActualizarSeguimiento(); + MostrarSeguimiento("comentarios"); + } + + protected void ComentariosSeguimiento_MostrarSolicitado(object origen, EventArgs argumentos) + { + MostrarSeguimiento("comentarios"); + } + + protected void PagosSeguimiento_Cambiados(object origen, EventArgs argumentos) + { + UcPagosSolicitud.Cargar(new ModeloFiltroObligacionesPago { CveSolicitud = CveSolicitudSeguimiento }); + RefrescarRequisitosSeguimiento(); + ActualizarSeguimiento(); + MostrarSeguimiento("pagos"); + } + + private void CargarAccionesPendientesSeguimiento() + { + DbResult> resultado = + AppServices.TramiteSolicitudService.ListarAccionesPendientes( + CveSolicitudSeguimiento, CurrentUser.CveUsuario, CurrentUser.NombreDominio); + List acciones = resultado.Success && resultado.Data != null + ? resultado.Data : new List(); + SeccionAccionesPendientesSeguimiento.Visible = acciones.Count > 0; + AccionesPendientesSeguimiento.DataSource = acciones; + AccionesPendientesSeguimiento.DataBind(); + if (!resultado.Success) + { + Alert(resultado.UserMessage, TipoMensaje.MsgAdvertencia); + } + } + + private void MostrarPagosSeguimiento(List pagos) + { + List pendientes = pagos.Where(pago => pago.EstaPendiente).ToList(); + AvisoPagosSeguimiento.Text = pendientes.Count == 0 ? string.Empty : + "
    " + + "Pagos pendientes: " + + System.Web.HttpUtility.HtmlEncode(string.Join(", ", pendientes.Select(pago => pago.NombrePago))) + + ". Realice estos pagos desde el módulo correspondiente.
    "; + } + + private bool RefrescarRequisitosSeguimiento() + { + DbResult resultado = + AppServices.TramiteSolicitudService.ObtenerContextoCambioEstatus( + CveSolicitudSeguimiento, CurrentUser.CveUsuario, CurrentUser.NombreDominio); + if (!resultado.Success || resultado.Data == null) + { + Alert(resultado.UserMessage, TipoMensaje.MsgAdvertencia); + return false; + } + UcDocumentosSolicitud.Cargar(CveSolicitudSeguimiento, CveFraccionamientoSeguimiento, resultado.Data.Documentos); + MostrarPagosSeguimiento(resultado.Data.Pagos); + UpEncabezadoSeguimiento.Update(); + return true; + } + + } } diff --git a/SIG.Web/Pages/Desarrolladores/Tramites.aspx.designer.cs b/SIG.Web/Pages/Desarrolladores/Tramites.aspx.designer.cs deleted file mode 100644 index 0f02268..0000000 --- a/SIG.Web/Pages/Desarrolladores/Tramites.aspx.designer.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace SIG.Web.Pages.Desarrolladores -{ - public partial class Tramites - { - } -} diff --git a/SIG.Web/Pages/Fraccionamientos/EtapaDetalle.aspx b/SIG.Web/Pages/Fraccionamientos/EtapaDetalle.aspx new file mode 100644 index 0000000..e8f8092 --- /dev/null +++ b/SIG.Web/Pages/Fraccionamientos/EtapaDetalle.aspx @@ -0,0 +1,4 @@ +<%@ Page Title="Detalle de etapa" Language="C#" MasterPageFile="~/Site.master" + AutoEventWireup="true" CodeFile="EtapaDetalle.aspx.cs" + Inherits="SIG.Web.Pages.Fraccionamientos.EtapaDetalle" %> + diff --git a/SIG.Web/Pages/Fraccionamientos/EtapaDetalle.aspx.cs b/SIG.Web/Pages/Fraccionamientos/EtapaDetalle.aspx.cs new file mode 100644 index 0000000..6ce7fc0 --- /dev/null +++ b/SIG.Web/Pages/Fraccionamientos/EtapaDetalle.aspx.cs @@ -0,0 +1,32 @@ +using System; +using System.Globalization; +using SIG.Web.AppCode.Configuration; +using SIG.Web.AppCode.Security; +using SIG.Web.AppCode.Infrastructure.WebForms; + +namespace SIG.Web.Pages.Fraccionamientos +{ + public partial class EtapaDetalle : ClsPaginaBase + { + protected void Page_Load(object origen, EventArgs argumentos) + { + int clave; + if (!int.TryParse(Request.QueryString["etapa"], out clave)) + { + Alert("Seleccione una etapa válida.", TipoMensaje.MsgAdvertencia); + return; + } + var consulta = AppServices.ServicioFraccionamiento.ObtenerEtapa( + clave, CurrentUser.CveUsuario, CurrentUser.NombreDominio); + if (!consulta.Success || consulta.Data == null) + { + Alert(consulta.UserMessage, TipoMensaje.MsgAdvertencia); + return; + } + Response.Redirect(ResolveUrl("~/Pages/Desarrolladores/DesarrolladorDetalle.aspx") + + "?cveCliente=" + consulta.Data.CveCliente.ToString(CultureInfo.InvariantCulture) + + "&etapa=" + clave.ToString(CultureInfo.InvariantCulture), false); + Context.ApplicationInstance.CompleteRequest(); + } + } +} diff --git a/SIG.Web/Pages/Fraccionamientos/FraccionamientoDetalle.aspx b/SIG.Web/Pages/Fraccionamientos/FraccionamientoDetalle.aspx index ea2a17f..c03235e 100644 --- a/SIG.Web/Pages/Fraccionamientos/FraccionamientoDetalle.aspx +++ b/SIG.Web/Pages/Fraccionamientos/FraccionamientoDetalle.aspx @@ -1,10 +1,12 @@ -<%@ Page Title="Detalle de fraccionamiento" +<%@ Page Title="Detalle de fraccionamiento" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="FraccionamientoDetalle.aspx.cs" Inherits="SIG.Web.Pages.Fraccionamientos.FraccionamientoDetalle" %> +<%@ Register TagPrefix="doc" TagName="DocumentosEtapa" Src="~/UserControl/DocumentosEtapa.ascx" %> + + ChildrenAsTriggers="true">
    @@ -183,31 +185,35 @@
    - - -
    - - - - - - - Etapas + ActiveTabIndex="0" + Width="100%"> + + + + Etapas + + - + + + + +
    @@ -348,17 +354,31 @@ - + + + - - - - Lotes + + + + Lotes + + - + + + + +
    @@ -561,17 +581,31 @@
    -
    + + + - - - - Trámites + + + + Trámites + + - + + + + +
    @@ -592,6 +626,7 @@ GridLines="None" DataKeyNames="CveSolicitud" CssClass="table table-hover Widthall" + OnRowDataBound="GvTramites_FilaEnlazada" OnRowCommand="GvTramites_FilaComando"> + + Configurar documentos + - Cambiar estatus + Seguimiento @@ -653,24 +696,38 @@
    -
    - + + + - - - - Pagos + + + + + Pagos + + - + + + + +

    Pagos pendientes

    -

    Pagos configurados para los trámites del fraccionamiento que todavía no tienen una venta relacionada.

    +

    Obligaciones con saldo pendiente del fraccionamiento y sus etapas.

    @@ -679,68 +736,28 @@ runat="server" AutoGenerateColumns="false" GridLines="None" - CssClass="table table-striped table-hover Widthall"> + CssClass="table table-striped table-hover Widthall" + EmptyDataText="No hay registros para este fraccionamiento."> - - - - - - - - - - - - - Generar - - - - - Pagar - - - + + + + + + + + + + + - -
    - - - - No hay pagos pendientes. -
    -
    @@ -749,7 +766,7 @@

    Pagos realizados

    -

    Ventas relacionadas de forma explícita con una solicitud y su grupo de pago.

    +

    Abonos recibidos con aplicaciones a obligaciones de este fraccionamiento.

    @@ -758,74 +775,54 @@ runat="server" AutoGenerateColumns="false" GridLines="None" - CssClass="table table-striped table-hover Widthall"> + CssClass="table table-striped table-hover Widthall" + EmptyDataText="No hay registros para este fraccionamiento."> - - + - - - - - - - - - - - - + + + + + + - -
    - - - - No hay ventas relacionadas con pagos de trámites. -
    -
    - - + + + - - - - Documentos + + + + + Documentos + + - + + + + +
    @@ -840,139 +837,39 @@ OnConsultar="UcDocumentoFiltros_Consultar" />
    - - - - - - - - - - - - - - - - - - - <%#: Convert.ToString(Eval("EstadoDocumento")) %> - - - - - - - <%#: ObtenerTextoNotaDocumento(Eval("Nota")) %> - - - - - - - - - - <%#: ObtenerTextoBotonCargaDocumento(Eval("TieneArchivo")) %> - - - - - Administrar GIS - - - - - Aprobar - - - - - Rechazar - - - - - -
    - - - - No hay documentos que coincidan con los filtros seleccionados. -
    -
    -
    + <%-- El padre cambia por filtros; el control actualiza sus operaciones internas. --%> +
    -
    + + + - - - - Notas - - -
    - -

    No hay notas registradas.

    -
    -
    -
    - - - - + + + + Notas + + +
    + +

    No hay notas registradas.

    +
    +
    +
    + + + +
    +
    +
    +
    @@ -986,7 +883,7 @@ + ChildrenAsTriggers="true"> - - - - @@ -1066,7 +955,7 @@ + ChildrenAsTriggers="true"> - - - @@ -1144,7 +1028,7 @@ + ChildrenAsTriggers="true"> - - - + + + + + @@ -1225,6 +1193,20 @@ +
    + + +
    +
    + + +
    + ChildrenAsTriggers="true"> - - -
    @@ -1420,7 +1399,7 @@ + ChildrenAsTriggers="true"> - - - @@ -1494,7 +1470,7 @@ + ChildrenAsTriggers="true"> - - - @@ -1645,7 +1616,7 @@ + ChildrenAsTriggers="true"> - - - - - @@ -2319,7 +2182,7 @@ -