Validaciones y agregar avace

This commit is contained in:
Jorge Luis caudillo esparza
2026-08-24 05:05:53 -07:00
parent 5033fbbc06
commit e5cfa0f10c
10 changed files with 609 additions and 11 deletions

View File

@@ -12,6 +12,19 @@ namespace SIG.Web.AppCode.Contracts.Tramites
int executingUser,
string domainName);
DbResult<List<TramiteSolicitudTipoOptionModel>> ListAvailableTypesForStage(
int developmentId,
int stageId,
int executingUser,
string domainName);
DbResult<TramiteSolicitudCreateResultModel> AddStageRequest(
int developmentId,
int stageId,
int procedureTypeId,
int executingUser,
string domainName);
DbResult<List<TramiteSolicitudModel>> ListForDevelopment(
int developmentId,
int? stageId,

View File

@@ -6,6 +6,19 @@ namespace SIG.Web.AppCode.Contracts.Tramites
{
public interface ITramiteSolicitudService
{
DbResult<List<TramiteSolicitudTipoOptionModel>> ListAvailableTypesForStage(
int developmentId,
int stageId,
int executingUser,
string domainName);
DbResult<TramiteSolicitudCreateResultModel> AddStageRequest(
int developmentId,
int stageId,
int procedureTypeId,
int executingUser,
string domainName);
DbResult<List<TramiteSolicitudModel>> ListForDevelopment(
int developmentId,
int? stageId,

View File

@@ -50,4 +50,29 @@ namespace SIG.Web.AppCode.Models.Tramites
public DateTime? FechaAutorizacion { get; set; }
public bool HuboCambio { get; set; }
}
public sealed class TramiteSolicitudTipoOptionModel
{
public int CveTipoTramite { get; set; }
public string Codigo { get; set; }
public string TipoTramite { get; set; }
public int Orden { get; set; }
}
public sealed class TramiteSolicitudCreateResultModel
{
public int CveSolicitud { get; set; }
public bool EsNuevo { get; set; }
public string Folio { get; set; }
public int CveCliente { get; set; }
public int CveFraccionamiento { get; set; }
public int CveFraccionamientoEtapa { get; set; }
public string Etapa { get; set; }
public int CveTipoTramite { get; set; }
public string TipoTramite { get; set; }
public int CveEstatusSolicitud { get; set; }
public string EstatusSolicitud { get; set; }
public int? CveUsuarioSolicita { get; set; }
public DateTime? FechaInicio { get; set; }
}
}

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using SIG.Web.AppCode.Contracts.Database;
using SIG.Web.AppCode.Contracts.Tramites;
using SIG.Web.AppCode.Models.Common;
@@ -124,10 +125,41 @@ namespace SIG.Web.AppCode.Repositories.Tramites
});
}
public DbResult<DocumentoRequeridoModel> GetDocumentoRequerido(int id, int usuario, string dominio)
public DbResult<DocumentoRequeridoModel> GetDocumentoRequerido(
int id,
int usuario,
string dominio)
{
return QueryOne<DocumentoRequeridoModel>("dbo.PA_Tra_DocumentoRequeridoGet", usuario, dominio, command =>
Add(command, "@CveDocumentoRequerido", id, DbType.Int32));
/*
* El registro se obtiene desde el listado existente.
* No se utiliza un PA específico Get para documento requerido.
* El control de acceso al módulo permanece en el mecanismo
* existente del proyecto.
*/
return QueryReader(
"dbo.PA_Tra_DocumentoRequeridoList",
usuario,
dominio,
command =>
{
Add(
command,
"@CveTipoTramite",
null,
DbType.Int32);
Add(
command,
"@IncluirInactivos",
true,
DbType.Boolean);
},
reader =>
reader
.ToList<DocumentoRequeridoModel>()
.FirstOrDefault(
item =>
item.CveDocumentoRequerido == id));
}
public DbResult<int> SaveDocumentoRequerido(DocumentoRequeridoModel model, int usuario, string dominio)

View File

@@ -42,6 +42,62 @@ namespace SIG.Web.AppCode.Repositories.Tramites
});
}
public DbResult<List<TramiteSolicitudTipoOptionModel>> ListAvailableTypesForStage(
int developmentId,
int stageId,
int executingUser,
string domainName)
{
return QueryList<TramiteSolicitudTipoOptionModel>(
"dbo.PA_Tramites_TipoTramiteDisponibleEtapaList",
executingUser,
domainName,
command =>
{
StoredProcedureCommand.AddInput(
command,
"@CveFraccionamiento",
developmentId,
DbType.Int32);
StoredProcedureCommand.AddInput(
command,
"@CveFraccionamientoEtapa",
stageId,
DbType.Int32);
});
}
public DbResult<TramiteSolicitudCreateResultModel> AddStageRequest(
int developmentId,
int stageId,
int procedureTypeId,
int executingUser,
string domainName)
{
return QueryOne<TramiteSolicitudCreateResultModel>(
"dbo.PA_Tramites_SolicitudEtapaSave",
executingUser,
domainName,
command =>
{
StoredProcedureCommand.AddInput(
command,
"@CveFraccionamientoEtapa",
stageId,
DbType.Int32);
StoredProcedureCommand.AddInput(
command,
"@CveTipoTramite",
procedureTypeId,
DbType.Int32);
StoredProcedureCommand.AddInput(
command,
"@CveFraccionamiento",
developmentId,
DbType.Int32);
});
}
public DbResult<List<TramiteSolicitudModel>> ListForDevelopment(
int developmentId,
int? stageId,

View File

@@ -7,6 +7,67 @@ namespace SIG.Web.AppCode.Services.Tramites
{
internal static class TramiteSolicitudBitacoraFactory
{
public static BitacoraEventoModel Create(
TramiteSolicitudCreateResultModel request)
{
var auditEvent = new BitacoraEventoModel
{
NombreTablaSQL = "Tra_Solicitudes",
TipoMovimiento = BitacoraTipoMovimiento.Agregado,
LlaveRegistro = Convert.ToString(request.CveSolicitud),
DescripcionMovimiento =
"Se agregó el trámite " + request.TipoTramite +
" a la etapa " + request.Etapa +
" con folio " + request.Folio + ".",
DiscriminarCamposSinCambios = false,
Campos = new List<BitacoraCampoEventoModel>
{
Field("CveCliente", null, request.CveCliente),
Field("CveFraccionamiento", null, request.CveFraccionamiento),
Field("CveFraccionamientoEtapa", null, request.CveFraccionamientoEtapa),
Field("CveTipoTramite", null, request.CveTipoTramite),
Field("CveEstatusSolicitud", null, request.CveEstatusSolicitud),
Field("CveUsuarioSolicita", null, request.CveUsuarioSolicita),
Field("FechaInicio", null, request.FechaInicio)
}
};
auditEvent.Relaciones.Add(
Relation(
BitacoraTipoRelacion.Directa,
"Tra_Solicitudes",
"CveSolicitud",
request.CveSolicitud,
true,
"Solicitud creada."));
auditEvent.Relaciones.Add(
Relation(
BitacoraTipoRelacion.Relacionada,
"Clientes",
"CveCliente",
request.CveCliente,
true,
"Cliente propietario de la solicitud."));
auditEvent.Relaciones.Add(
Relation(
BitacoraTipoRelacion.Relacionada,
"Fraccionamientos",
"CveFraccionamiento",
request.CveFraccionamiento,
true,
"Fraccionamiento de la solicitud."));
auditEvent.Relaciones.Add(
Relation(
BitacoraTipoRelacion.Relacionada,
"FraccionamientosEtapas",
"CveFraccionamientoEtapa",
request.CveFraccionamientoEtapa,
true,
"Etapa de la solicitud."));
return auditEvent;
}
public static BitacoraEventoModel StatusChange(
TramiteSolicitudStatusChangeModel change)
{
@@ -75,6 +136,19 @@ namespace SIG.Web.AppCode.Services.Tramites
return auditEvent;
}
private static BitacoraCampoEventoModel Field(
string name,
object previous,
object current)
{
return new BitacoraCampoEventoModel
{
NombreCampoSQL = name,
ValorAnterior = previous,
ValorNuevo = current
};
}
private static BitacoraRelacionEventoModel Relation(
BitacoraTipoRelacion relationType,
string tableName,

View File

@@ -22,6 +22,98 @@ namespace SIG.Web.AppCode.Services.Tramites
_bitacoraService = bitacoraService;
}
public DbResult<List<TramiteSolicitudTipoOptionModel>> ListAvailableTypesForStage(
int developmentId,
int stageId,
int executingUser,
string domainName)
{
if (developmentId <= 0)
{
return Fail<List<TramiteSolicitudTipoOptionModel>>(
"Seleccione un fraccionamiento válido.");
}
if (stageId <= 0)
{
return Fail<List<TramiteSolicitudTipoOptionModel>>(
"Seleccione una etapa válida.");
}
return _repository.ListAvailableTypesForStage(
developmentId,
stageId,
executingUser,
domainName);
}
public DbResult<TramiteSolicitudCreateResultModel> AddStageRequest(
int developmentId,
int stageId,
int procedureTypeId,
int executingUser,
string domainName)
{
if (developmentId <= 0)
{
return Fail<TramiteSolicitudCreateResultModel>(
"Seleccione un fraccionamiento válido.");
}
if (stageId <= 0)
{
return Fail<TramiteSolicitudCreateResultModel>(
"Seleccione una etapa válida.");
}
if (procedureTypeId <= 0)
{
return Fail<TramiteSolicitudCreateResultModel>(
"Seleccione un tipo de trámite válido.");
}
using (var transaction = new TransactionLogic())
{
DbResult<TramiteSolicitudCreateResultModel> result =
_repository.AddStageRequest(
developmentId,
stageId,
procedureTypeId,
executingUser,
domainName);
if (!result.Success || result.Data == null)
{
return result;
}
if (result.Data.EsNuevo)
{
if (_bitacoraService == null)
{
return Fail<TramiteSolicitudCreateResultModel>(
"El servicio de bitácora no está configurado.");
}
DbResult<long> auditResult =
_bitacoraService.Registrar(
TramiteSolicitudBitacoraFactory.Create(
result.Data));
if (!auditResult.Success)
{
return DbResult<TramiteSolicitudCreateResultModel>.Fail(
auditResult.UserMessage,
auditResult.TechnicalMessage,
auditResult.Exception);
}
}
transaction.Commit();
return result;
}
}
public DbResult<List<TramiteSolicitudModel>> ListForDevelopment(
int developmentId,
int? stageId,

View File

@@ -26,6 +26,15 @@
Volver al catálogo
</asp:HyperLink>
</li>
<li>
<asp:LinkButton ID="BtnAddProcedure"
runat="server"
CausesValidation="false"
OnClick="BtnAddProcedure_Click">
<i class="fa fa-plus-circle"></i>
Agregar trámite
</asp:LinkButton>
</li>
<li>
<asp:LinkButton ID="BtnEditStageProgress"
runat="server"
@@ -809,6 +818,86 @@
</div>
<div id="ModalAddProcedure"
class="modal fade fraction-modal"
tabindex="-1"
role="dialog"
aria-hidden="true">
<div class="modal-dialog">
<asp:UpdatePanel ID="UpAddProcedureModal"
runat="server"
UpdateMode="Conditional"
ChildrenAsTriggers="false">
<ContentTemplate>
<div class="modal-content">
<div class="modal-header">
<button type="button"
class="close"
data-dismiss="modal"
aria-label="Cerrar">
&times;
</button>
<h4 class="modal-title">
<i class="fa fa-plus-circle"></i>
Agregar trámite
</h4>
</div>
<div class="modal-body">
<asp:Label ID="LblAddProcedureMessage"
runat="server"
CssClass="alert alert-danger"
Visible="false" />
<div class="form-group">
<label>Etapa</label>
<asp:DropDownList ID="DdlAddProcedureStage"
runat="server"
CssClass="form-control select2me Widthall"
Style="width:100%;"
AutoPostBack="true"
OnSelectedIndexChanged="DdlAddProcedureStage_SelectedIndexChanged" />
</div>
<div class="form-group">
<label>Tipo de trámite</label>
<asp:DropDownList ID="DdlAddProcedureType"
runat="server"
CssClass="form-control select2me Widthall"
Style="width:100%;" />
<span class="help-block">
Sólo se muestran los trámites que todavía no tienen una solicitud en la etapa seleccionada.
</span>
</div>
</div>
<div class="modal-footer">
<button type="button"
class="btn default"
data-dismiss="modal">
Cancelar
</button>
<asp:Button ID="BtnSaveAddProcedure"
runat="server"
CssClass="btn blue"
Text="Agregar trámite"
CausesValidation="false"
OnClick="BtnSaveAddProcedure_Click" />
</div>
</div>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger
ControlID="DdlAddProcedureStage"
EventName="SelectedIndexChanged" />
<asp:AsyncPostBackTrigger
ControlID="BtnSaveAddProcedure"
EventName="Click" />
</Triggers>
</asp:UpdatePanel>
</div>
</div>
<div id="ModalProcedureFilters"
class="modal fade fraction-modal"
tabindex="-1"

View File

@@ -247,6 +247,8 @@ namespace SIG.Web.Pages.Fraccionamientos
{
scriptManager.RegisterAsyncPostBackControl(
BtnEditStageProgress);
scriptManager.RegisterAsyncPostBackControl(
BtnAddProcedure);
}
if (IsPostBack)
@@ -373,6 +375,83 @@ namespace SIG.Web.Pages.Fraccionamientos
ShowStageModal();
}
protected void BtnAddProcedure_Click(
object sender,
EventArgs e)
{
BindAddProcedureStageOptions();
BindAddProcedureTypeOptions();
HideAddProcedureMessage();
UpAddProcedureModal.Update();
ShowAddProcedureModal();
}
protected void DdlAddProcedureStage_SelectedIndexChanged(
object sender,
EventArgs e)
{
BindAddProcedureTypeOptions();
HideAddProcedureMessage();
UpAddProcedureModal.Update();
ShowAddProcedureModal();
}
protected void BtnSaveAddProcedure_Click(
object sender,
EventArgs e)
{
int stageId;
int procedureTypeId;
if (!int.TryParse(
DdlAddProcedureStage.SelectedValue,
out stageId) ||
stageId <= 0)
{
ShowAddProcedureValidation(
"Seleccione una etapa válida.");
return;
}
if (!int.TryParse(
DdlAddProcedureType.SelectedValue,
out procedureTypeId) ||
procedureTypeId <= 0)
{
ShowAddProcedureValidation(
"Seleccione un tipo de trámite válido.");
return;
}
DbResult<TramiteSolicitudCreateResultModel> result =
AppServices.TramiteSolicitudService.AddStageRequest(
CveFraccionamientoActual,
stageId,
procedureTypeId,
CurrentUser.CveUsuario,
CurrentUser.NombreDominio);
if (!result.Success || result.Data == null)
{
ShowAddProcedureValidation(result.UserMessage);
return;
}
BindProcedures();
BindDocuments();
RefreshBitacoraDetalle();
UpDetailTabs.Update();
HideAddProcedureModal();
Alert(
result.Data.EsNuevo
? "Trámite agregado correctamente."
: "El trámite ya se encontraba registrado para la etapa.",
result.Data.EsNuevo
? TipoMensaje.ToastExito
: TipoMensaje.MsgAdvertencia);
}
protected void UcProcedureFilters_MostrarFiltrosClick(
object sender,
EventArgs e)
@@ -1782,14 +1861,7 @@ namespace SIG.Web.Pages.Fraccionamientos
Orden = 2,
NombreTablaSQL = "FraccionamientosEtapas",
NombreCampoMostrarSQL = "Etapa"
},
new BitacoraRelacionMostrarModel
{
Orden = 3,
NombreTablaSQL = "Tra_Solicitudes",
NombreCampoMostrarSQL = "Folio"
}
});
} });
UcBitacoraDetalle.Consultar(true);
}
@@ -2249,6 +2321,96 @@ namespace SIG.Web.Pages.Fraccionamientos
return control.SelectedItem.Text;
}
private void BindAddProcedureStageOptions()
{
DbResult<List<FraccionamientoEtapaModel>> result =
AppServices.FraccionamientoService.ListStages(
CveFraccionamientoActual,
CurrentUser.CveUsuario,
CurrentUser.NombreDominio);
if (!result.Success)
{
ShowAddProcedureValidation(result.UserMessage);
return;
}
string selectedValue =
DdlAddProcedureStage.SelectedValue;
DdlAddProcedureStage.DataSource =
(result.Data ?? new List<FraccionamientoEtapaModel>())
.Where(item => item.EsActivo)
.ToList();
DdlAddProcedureStage.DataTextField = "Etapa";
DdlAddProcedureStage.DataValueField =
"CveFraccionamientoEtapa";
DdlAddProcedureStage.DataBind();
DdlAddProcedureStage.Items.Insert(
0,
new ListItem(
"Seleccione una etapa",
string.Empty));
RestoreSelectedValue(
DdlAddProcedureStage,
selectedValue);
}
private void BindAddProcedureTypeOptions()
{
DdlAddProcedureType.Items.Clear();
DdlAddProcedureType.Items.Add(
new ListItem(
"Seleccione un tipo de trámite",
string.Empty));
int stageId;
if (!int.TryParse(
DdlAddProcedureStage.SelectedValue,
out stageId) ||
stageId <= 0)
{
return;
}
DbResult<List<TramiteSolicitudTipoOptionModel>> result =
AppServices.TramiteSolicitudService
.ListAvailableTypesForStage(
CveFraccionamientoActual,
stageId,
CurrentUser.CveUsuario,
CurrentUser.NombreDominio);
if (!result.Success)
{
ShowAddProcedureValidation(result.UserMessage);
return;
}
List<TramiteSolicitudTipoOptionModel> types =
result.Data ??
new List<TramiteSolicitudTipoOptionModel>();
foreach (TramiteSolicitudTipoOptionModel item in types)
{
DdlAddProcedureType.Items.Add(
new ListItem(
item.TipoTramite,
item.CveTipoTramite.ToString(
CultureInfo.InvariantCulture)));
}
BtnSaveAddProcedure.Enabled = types.Count > 0;
if (types.Count == 0)
{
ShowAddProcedureValidation(
"La etapa seleccionada ya tiene solicitud para todos los trámites activos.");
}
}
private void BindProcedureStageOptions(
IList<FraccionamientoEtapaModel> stages)
{
@@ -2991,6 +3153,36 @@ namespace SIG.Web.Pages.Fraccionamientos
LblDocumentRejectMessage.Text = string.Empty;
}
private void ShowAddProcedureValidation(
string message)
{
LblAddProcedureMessage.Text = Server.HtmlEncode(
message ?? string.Empty);
LblAddProcedureMessage.Visible = true;
UpAddProcedureModal.Update();
ShowAddProcedureModal();
}
private void HideAddProcedureMessage()
{
LblAddProcedureMessage.Visible = false;
LblAddProcedureMessage.Text = string.Empty;
}
private void ShowAddProcedureModal()
{
RegistraScript(
"$('#ModalAddProcedure').modal('show');",
"AddProcedureModal");
}
private void HideAddProcedureModal()
{
RegistraScript(
"$('#ModalAddProcedure').modal('hide');",
"AddProcedureModalHide");
}
private void ShowProcedureFiltersModal()
{
RegistraScript(

View File

@@ -26,6 +26,8 @@ namespace SIG.Web.Pages.Fraccionamientos
/// <summary>
/// BtnEditStageProgress control.
/// </summary>
protected global::System.Web.UI.WebControls.LinkButton BtnAddProcedure;
protected global::System.Web.UI.WebControls.LinkButton BtnEditStageProgress;
/// <summary>
@@ -336,6 +338,16 @@ namespace SIG.Web.Pages.Fraccionamientos
/// <summary>
/// UpProcedureFiltersModal control.
/// </summary>
protected global::System.Web.UI.UpdatePanel UpAddProcedureModal;
protected global::System.Web.UI.WebControls.Label LblAddProcedureMessage;
protected global::System.Web.UI.WebControls.DropDownList DdlAddProcedureStage;
protected global::System.Web.UI.WebControls.DropDownList DdlAddProcedureType;
protected global::System.Web.UI.WebControls.Button BtnSaveAddProcedure;
protected global::System.Web.UI.UpdatePanel UpProcedureFiltersModal;
/// <summary>