gis 5
This commit is contained in:
@@ -100,7 +100,8 @@ namespace SIG.Web.AppCode.Configuration
|
|||||||
new FraccionamientoGisFileStore();
|
new FraccionamientoGisFileStore();
|
||||||
FraccionamientoGisService = new FraccionamientoGisService(
|
FraccionamientoGisService = new FraccionamientoGisService(
|
||||||
gisRepository,
|
gisRepository,
|
||||||
gisFileStore);
|
gisFileStore,
|
||||||
|
BitacoraService);
|
||||||
TramiteCatalogService = new TramiteCatalogService(
|
TramiteCatalogService = new TramiteCatalogService(
|
||||||
new TramiteCatalogRepository(DbExecutor),
|
new TramiteCatalogRepository(DbExecutor),
|
||||||
BitacoraService);
|
BitacoraService);
|
||||||
|
|||||||
@@ -21,5 +21,10 @@ namespace SIG.Web.AppCode.Contracts.Fraccionamientos
|
|||||||
IList<FraccionamientoGisLotLinkModel> links,
|
IList<FraccionamientoGisLotLinkModel> links,
|
||||||
int executingUser,
|
int executingUser,
|
||||||
string domainName);
|
string domainName);
|
||||||
|
|
||||||
|
DbResult<bool> ClearLinks(
|
||||||
|
int stageId,
|
||||||
|
int executingUser,
|
||||||
|
string domainName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,11 @@ namespace SIG.Web.AppCode.Contracts.Fraccionamientos
|
|||||||
int executingUser,
|
int executingUser,
|
||||||
string domainName);
|
string domainName);
|
||||||
|
|
||||||
|
DbResult<FraccionamientoGisSaveResultModel> Delete(
|
||||||
|
int stageId,
|
||||||
|
int executingUser,
|
||||||
|
string domainName);
|
||||||
|
|
||||||
DbResult<FraccionamientoGisFileModel> OpenFile(
|
DbResult<FraccionamientoGisFileModel> OpenFile(
|
||||||
int stageId,
|
int stageId,
|
||||||
int executingUser,
|
int executingUser,
|
||||||
|
|||||||
@@ -53,21 +53,27 @@ namespace SIG.Web.Pages.Fraccionamientos
|
|||||||
"POST",
|
"POST",
|
||||||
StringComparison.OrdinalIgnoreCase))
|
StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
if (!string.Equals(method, "Save", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(method, "Save", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
WriteJson(
|
Save(context, currentUser);
|
||||||
context,
|
|
||||||
405,
|
|
||||||
new
|
|
||||||
{
|
|
||||||
success = false,
|
|
||||||
message = "La operación GIS solicitada no es válida.",
|
|
||||||
codigo = string.Empty
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Save(context, currentUser);
|
if (string.Equals(method, "Delete", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
Delete(context, currentUser);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteJson(
|
||||||
|
context,
|
||||||
|
405,
|
||||||
|
new
|
||||||
|
{
|
||||||
|
success = false,
|
||||||
|
message = "La operación GIS solicitada no es válida.",
|
||||||
|
codigo = string.Empty
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,6 +241,48 @@ namespace SIG.Web.Pages.Fraccionamientos
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void Delete(
|
||||||
|
HttpContext context,
|
||||||
|
UserSessionModel currentUser)
|
||||||
|
{
|
||||||
|
int stageId;
|
||||||
|
if (!TryGetStageId(context, out stageId))
|
||||||
|
{
|
||||||
|
WriteJson(
|
||||||
|
context,
|
||||||
|
400,
|
||||||
|
new
|
||||||
|
{
|
||||||
|
success = false,
|
||||||
|
message = "Seleccione una etapa válida.",
|
||||||
|
codigo = string.Empty
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DbResult<FraccionamientoGisSaveResultModel> result =
|
||||||
|
AppServices.FraccionamientoGisService.Delete(
|
||||||
|
stageId,
|
||||||
|
currentUser.CveUsuario,
|
||||||
|
currentUser.NombreDominio);
|
||||||
|
|
||||||
|
if (!result.Success)
|
||||||
|
{
|
||||||
|
WriteResultFailure(context, result, 400);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteJson(
|
||||||
|
context,
|
||||||
|
200,
|
||||||
|
new
|
||||||
|
{
|
||||||
|
success = true,
|
||||||
|
message = "GIS eliminado y lotes desvinculados correctamente.",
|
||||||
|
data = result.Data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private static void OpenFile(
|
private static void OpenFile(
|
||||||
HttpContext context,
|
HttpContext context,
|
||||||
UserSessionModel currentUser,
|
UserSessionModel currentUser,
|
||||||
|
|||||||
@@ -89,5 +89,21 @@ namespace SIG.Web.AppCode.Repositories.Fraccionamientos
|
|||||||
DbType.Xml);
|
DbType.Xml);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DbResult<bool> ClearLinks(
|
||||||
|
int stageId,
|
||||||
|
int executingUser,
|
||||||
|
string domainName)
|
||||||
|
{
|
||||||
|
return Execute(
|
||||||
|
"dbo.PA_Fraccionamientos_EtapaGISVinculosClear",
|
||||||
|
executingUser,
|
||||||
|
domainName,
|
||||||
|
command => StoredProcedureCommand.AddInput(
|
||||||
|
command,
|
||||||
|
"@CveFraccionamientoEtapa",
|
||||||
|
stageId,
|
||||||
|
DbType.Int32));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -161,6 +161,85 @@ namespace SIG.Web.AppCode.Services.Fraccionamientos
|
|||||||
return auditEvent;
|
return auditEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static BitacoraEventoModel CreateStageGisFileChange(
|
||||||
|
FraccionamientoGisContextModel context,
|
||||||
|
bool hadFile,
|
||||||
|
bool fileUploaded,
|
||||||
|
int previousLinkedLots,
|
||||||
|
int currentLinkedLots)
|
||||||
|
{
|
||||||
|
string description;
|
||||||
|
|
||||||
|
if (!hadFile && fileUploaded)
|
||||||
|
{
|
||||||
|
description =
|
||||||
|
"Se agregó el GIS de la etapa " + context.Etapa +
|
||||||
|
". Se vincularon " + currentLinkedLots + " lotes.";
|
||||||
|
}
|
||||||
|
else if (hadFile && fileUploaded)
|
||||||
|
{
|
||||||
|
description =
|
||||||
|
"Se reemplazó el GIS de la etapa " + context.Etapa +
|
||||||
|
". Se desvincularon " + previousLinkedLots +
|
||||||
|
" lotes y se vincularon " + currentLinkedLots +
|
||||||
|
" lotes al nuevo GIS.";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
description =
|
||||||
|
"Se modificaron los vínculos GIS de la etapa " +
|
||||||
|
context.Etapa + ". Vínculos anteriores: " +
|
||||||
|
previousLinkedLots + "; vínculos actuales: " +
|
||||||
|
currentLinkedLots + ".";
|
||||||
|
}
|
||||||
|
|
||||||
|
return CreateStageGisFileEvent(
|
||||||
|
context,
|
||||||
|
BitacoraTipoMovimiento.Editado,
|
||||||
|
description);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BitacoraEventoModel CreateStageGisFileDelete(
|
||||||
|
FraccionamientoGisContextModel context,
|
||||||
|
int unlinkedLots)
|
||||||
|
{
|
||||||
|
return CreateStageGisFileEvent(
|
||||||
|
context,
|
||||||
|
BitacoraTipoMovimiento.Eliminado,
|
||||||
|
"Se eliminó el GIS de la etapa " + context.Etapa +
|
||||||
|
". Se desvincularon " + unlinkedLots + " lotes.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static BitacoraEventoModel CreateStageGisFileEvent(
|
||||||
|
FraccionamientoGisContextModel context,
|
||||||
|
BitacoraTipoMovimiento movementType,
|
||||||
|
string description)
|
||||||
|
{
|
||||||
|
var auditEvent = CreateEvent(
|
||||||
|
"FraccionamientosEtapas",
|
||||||
|
movementType,
|
||||||
|
context.CveFraccionamientoEtapa,
|
||||||
|
description,
|
||||||
|
context.CveCliente);
|
||||||
|
|
||||||
|
auditEvent.Relaciones.Add(
|
||||||
|
CreateRelation(
|
||||||
|
BitacoraTipoRelacion.Directa,
|
||||||
|
"FraccionamientosEtapas",
|
||||||
|
"CveFraccionamientoEtapa",
|
||||||
|
context.CveFraccionamientoEtapa,
|
||||||
|
"Etapa del GIS."));
|
||||||
|
auditEvent.Relaciones.Add(
|
||||||
|
CreateRelation(
|
||||||
|
BitacoraTipoRelacion.Relacionada,
|
||||||
|
"Fraccionamientos",
|
||||||
|
"CveFraccionamiento",
|
||||||
|
context.CveFraccionamiento,
|
||||||
|
"Fraccionamiento de la etapa."));
|
||||||
|
|
||||||
|
return auditEvent;
|
||||||
|
}
|
||||||
|
|
||||||
public static BitacoraEventoModel CreateLot(
|
public static BitacoraEventoModel CreateLot(
|
||||||
FraccionamientoLoteModel previous,
|
FraccionamientoLoteModel previous,
|
||||||
FraccionamientoLoteModel current,
|
FraccionamientoLoteModel current,
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using SIG.Web.AppCode.Contracts.Bitacora;
|
||||||
using SIG.Web.AppCode.Contracts.Fraccionamientos;
|
using SIG.Web.AppCode.Contracts.Fraccionamientos;
|
||||||
using SIG.Web.AppCode.Infrastructure.Transactions;
|
using SIG.Web.AppCode.Infrastructure.Transactions;
|
||||||
|
using SIG.Web.AppCode.Models.Bitacora;
|
||||||
using SIG.Web.AppCode.Models.Common;
|
using SIG.Web.AppCode.Models.Common;
|
||||||
using SIG.Web.AppCode.Models.Fraccionamientos;
|
using SIG.Web.AppCode.Models.Fraccionamientos;
|
||||||
using SIG.Web.AppCode.Services.Logging;
|
using SIG.Web.AppCode.Services.Logging;
|
||||||
@@ -18,10 +20,12 @@ namespace SIG.Web.AppCode.Services.Fraccionamientos
|
|||||||
|
|
||||||
private readonly IFraccionamientoGisRepository _repository;
|
private readonly IFraccionamientoGisRepository _repository;
|
||||||
private readonly IFraccionamientoGisFileStore _fileStore;
|
private readonly IFraccionamientoGisFileStore _fileStore;
|
||||||
|
private readonly IBitacoraService _bitacoraService;
|
||||||
|
|
||||||
public FraccionamientoGisService(
|
public FraccionamientoGisService(
|
||||||
IFraccionamientoGisRepository repository,
|
IFraccionamientoGisRepository repository,
|
||||||
IFraccionamientoGisFileStore fileStore)
|
IFraccionamientoGisFileStore fileStore,
|
||||||
|
IBitacoraService bitacoraService)
|
||||||
{
|
{
|
||||||
if (repository == null)
|
if (repository == null)
|
||||||
{
|
{
|
||||||
@@ -33,8 +37,14 @@ namespace SIG.Web.AppCode.Services.Fraccionamientos
|
|||||||
throw new ArgumentNullException("fileStore");
|
throw new ArgumentNullException("fileStore");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bitacoraService == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("bitacoraService");
|
||||||
|
}
|
||||||
|
|
||||||
_repository = repository;
|
_repository = repository;
|
||||||
_fileStore = fileStore;
|
_fileStore = fileStore;
|
||||||
|
_bitacoraService = bitacoraService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DbResult<FraccionamientoGisViewModel> Get(
|
public DbResult<FraccionamientoGisViewModel> Get(
|
||||||
@@ -167,6 +177,24 @@ namespace SIG.Web.AppCode.Services.Fraccionamientos
|
|||||||
}
|
}
|
||||||
|
|
||||||
FraccionamientoGisContextModel gisContext = contextResult.Data;
|
FraccionamientoGisContextModel gisContext = contextResult.Data;
|
||||||
|
|
||||||
|
DbResult<List<FraccionamientoGisLotLinkModel>> previousLinksResult =
|
||||||
|
_repository.ListLinks(
|
||||||
|
stageId,
|
||||||
|
executingUser,
|
||||||
|
domainName);
|
||||||
|
|
||||||
|
if (!previousLinksResult.Success)
|
||||||
|
{
|
||||||
|
return CopyFailure<List<FraccionamientoGisLotLinkModel>, FraccionamientoGisSaveResultModel>(
|
||||||
|
previousLinksResult,
|
||||||
|
"No fue posible consultar los vínculos GIS actuales.");
|
||||||
|
}
|
||||||
|
|
||||||
|
IList<FraccionamientoGisLotLinkModel> previousLinks =
|
||||||
|
previousLinksResult.Data ??
|
||||||
|
new List<FraccionamientoGisLotLinkModel>();
|
||||||
|
|
||||||
bool hadFile;
|
bool hadFile;
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -234,6 +262,40 @@ namespace SIG.Web.AppCode.Services.Fraccionamientos
|
|||||||
fileWasWritten = true;
|
fileWasWritten = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool linksChanged = !LinksEqual(previousLinks, links);
|
||||||
|
bool hasChange = hasUploadedFile || linksChanged;
|
||||||
|
|
||||||
|
if (hasChange)
|
||||||
|
{
|
||||||
|
BitacoraEventoModel auditEvent =
|
||||||
|
FraccionamientoBitacoraFactory.CreateStageGisFileChange(
|
||||||
|
gisContext,
|
||||||
|
hadFile,
|
||||||
|
hasUploadedFile,
|
||||||
|
CountLinked(previousLinks),
|
||||||
|
links.Count);
|
||||||
|
|
||||||
|
DbResult<long> auditResult =
|
||||||
|
_bitacoraService.Registrar(auditEvent);
|
||||||
|
|
||||||
|
if (!auditResult.Success)
|
||||||
|
{
|
||||||
|
if (fileWasWritten)
|
||||||
|
{
|
||||||
|
RestorePreviousFile(
|
||||||
|
gisContext,
|
||||||
|
hadFile,
|
||||||
|
previousFile);
|
||||||
|
fileWasWritten = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DbResult<FraccionamientoGisSaveResultModel>.Fail(
|
||||||
|
auditResult.UserMessage,
|
||||||
|
auditResult.TechnicalMessage,
|
||||||
|
auditResult.Exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
transaction.Commit();
|
transaction.Commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,6 +330,167 @@ namespace SIG.Web.AppCode.Services.Fraccionamientos
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DbResult<FraccionamientoGisSaveResultModel> Delete(
|
||||||
|
int stageId,
|
||||||
|
int executingUser,
|
||||||
|
string domainName)
|
||||||
|
{
|
||||||
|
if (stageId <= 0)
|
||||||
|
{
|
||||||
|
return Fail<FraccionamientoGisSaveResultModel>(
|
||||||
|
"Seleccione una etapa válida.");
|
||||||
|
}
|
||||||
|
|
||||||
|
DbResult<FraccionamientoGisContextModel> contextResult =
|
||||||
|
_repository.GetContext(
|
||||||
|
stageId,
|
||||||
|
executingUser,
|
||||||
|
domainName);
|
||||||
|
|
||||||
|
if (!contextResult.Success || contextResult.Data == null)
|
||||||
|
{
|
||||||
|
return CopyFailure<FraccionamientoGisContextModel, FraccionamientoGisSaveResultModel>(
|
||||||
|
contextResult,
|
||||||
|
"No fue posible obtener el contexto GIS de la etapa.");
|
||||||
|
}
|
||||||
|
|
||||||
|
DbResult<List<FraccionamientoGisLotLinkModel>> linksResult =
|
||||||
|
_repository.ListLinks(
|
||||||
|
stageId,
|
||||||
|
executingUser,
|
||||||
|
domainName);
|
||||||
|
|
||||||
|
if (!linksResult.Success)
|
||||||
|
{
|
||||||
|
return CopyFailure<List<FraccionamientoGisLotLinkModel>, FraccionamientoGisSaveResultModel>(
|
||||||
|
linksResult,
|
||||||
|
"No fue posible consultar los vínculos GIS actuales.");
|
||||||
|
}
|
||||||
|
|
||||||
|
FraccionamientoGisContextModel gisContext = contextResult.Data;
|
||||||
|
IList<FraccionamientoGisLotLinkModel> previousLinks =
|
||||||
|
linksResult.Data ?? new List<FraccionamientoGisLotLinkModel>();
|
||||||
|
bool hadFile;
|
||||||
|
byte[] previousFile = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
hadFile = _fileStore.Exists(gisContext);
|
||||||
|
|
||||||
|
if (hadFile)
|
||||||
|
{
|
||||||
|
using (Stream previous = _fileStore.OpenRead(gisContext))
|
||||||
|
using (var backup = new MemoryStream())
|
||||||
|
{
|
||||||
|
previous.CopyTo(backup);
|
||||||
|
previousFile = backup.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return FileFailure<FraccionamientoGisSaveResultModel>(
|
||||||
|
ex,
|
||||||
|
"FraccionamientoGisService.Delete.Backup");
|
||||||
|
}
|
||||||
|
|
||||||
|
int linkedCount = CountLinked(previousLinks);
|
||||||
|
|
||||||
|
if (!hadFile && linkedCount == 0)
|
||||||
|
{
|
||||||
|
return Fail<FraccionamientoGisSaveResultModel>(
|
||||||
|
"La etapa no tiene un GIS para eliminar.");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool fileWasDeleted = false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var transaction = new TransactionLogic())
|
||||||
|
{
|
||||||
|
DbResult<bool> clearResult =
|
||||||
|
_repository.ClearLinks(
|
||||||
|
stageId,
|
||||||
|
executingUser,
|
||||||
|
domainName);
|
||||||
|
|
||||||
|
if (!clearResult.Success)
|
||||||
|
{
|
||||||
|
return DbResult<FraccionamientoGisSaveResultModel>.Fail(
|
||||||
|
clearResult.UserMessage,
|
||||||
|
clearResult.TechnicalMessage,
|
||||||
|
clearResult.Exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hadFile)
|
||||||
|
{
|
||||||
|
_fileStore.Delete(gisContext);
|
||||||
|
fileWasDeleted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DbResult<long> auditResult =
|
||||||
|
_bitacoraService.Registrar(
|
||||||
|
FraccionamientoBitacoraFactory.CreateStageGisFileDelete(
|
||||||
|
gisContext,
|
||||||
|
linkedCount));
|
||||||
|
|
||||||
|
if (!auditResult.Success)
|
||||||
|
{
|
||||||
|
if (fileWasDeleted && previousFile != null)
|
||||||
|
{
|
||||||
|
using (var backup = new MemoryStream(previousFile, false))
|
||||||
|
{
|
||||||
|
_fileStore.Save(gisContext, backup);
|
||||||
|
}
|
||||||
|
fileWasDeleted = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DbResult<FraccionamientoGisSaveResultModel>.Fail(
|
||||||
|
auditResult.UserMessage,
|
||||||
|
auditResult.TechnicalMessage,
|
||||||
|
auditResult.Exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
transaction.Commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
return DbResult<FraccionamientoGisSaveResultModel>.Ok(
|
||||||
|
new FraccionamientoGisSaveResultModel
|
||||||
|
{
|
||||||
|
CveFraccionamientoEtapa = stageId,
|
||||||
|
VinculosGuardados = 0,
|
||||||
|
ArchivoGuardado = false,
|
||||||
|
TieneArchivo = false,
|
||||||
|
NombreArchivo = string.Empty,
|
||||||
|
FechaArchivo = null
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
if (fileWasDeleted && previousFile != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var backup = new MemoryStream(previousFile, false))
|
||||||
|
{
|
||||||
|
_fileStore.Save(gisContext, backup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception restoreException)
|
||||||
|
{
|
||||||
|
ExceptionLogger.Log(
|
||||||
|
restoreException,
|
||||||
|
"FraccionamientoGisService.Delete.Restore",
|
||||||
|
"No fue posible restaurar el GIS después de un error al eliminarlo.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FileFailure<FraccionamientoGisSaveResultModel>(
|
||||||
|
ex,
|
||||||
|
"FraccionamientoGisService.Delete");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public DbResult<FraccionamientoGisFileModel> OpenFile(
|
public DbResult<FraccionamientoGisFileModel> OpenFile(
|
||||||
int stageId,
|
int stageId,
|
||||||
int executingUser,
|
int executingUser,
|
||||||
@@ -345,6 +568,50 @@ namespace SIG.Web.AppCode.Services.Fraccionamientos
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int CountLinked(
|
||||||
|
IEnumerable<FraccionamientoGisLotLinkModel> links)
|
||||||
|
{
|
||||||
|
return links == null
|
||||||
|
? 0
|
||||||
|
: links.Count(link =>
|
||||||
|
link != null &&
|
||||||
|
link.CveFraccionamientoLote > 0 &&
|
||||||
|
!string.IsNullOrWhiteSpace(link.GISPoligonoClave));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool LinksEqual(
|
||||||
|
IEnumerable<FraccionamientoGisLotLinkModel> previous,
|
||||||
|
IEnumerable<FraccionamientoGisLotLinkModel> current)
|
||||||
|
{
|
||||||
|
var previousMap = (previous ?? Enumerable.Empty<FraccionamientoGisLotLinkModel>())
|
||||||
|
.Where(link =>
|
||||||
|
link != null &&
|
||||||
|
link.CveFraccionamientoLote > 0 &&
|
||||||
|
!string.IsNullOrWhiteSpace(link.GISPoligonoClave))
|
||||||
|
.ToDictionary(
|
||||||
|
link => link.GISPoligonoClave.Trim(),
|
||||||
|
link => link.CveFraccionamientoLote,
|
||||||
|
StringComparer.Ordinal);
|
||||||
|
|
||||||
|
var currentMap = (current ?? Enumerable.Empty<FraccionamientoGisLotLinkModel>())
|
||||||
|
.Where(link =>
|
||||||
|
link != null &&
|
||||||
|
link.CveFraccionamientoLote > 0 &&
|
||||||
|
!string.IsNullOrWhiteSpace(link.GISPoligonoClave))
|
||||||
|
.ToDictionary(
|
||||||
|
link => link.GISPoligonoClave.Trim(),
|
||||||
|
link => link.CveFraccionamientoLote,
|
||||||
|
StringComparer.Ordinal);
|
||||||
|
|
||||||
|
return previousMap.Count == currentMap.Count &&
|
||||||
|
previousMap.All(item =>
|
||||||
|
{
|
||||||
|
int lotId;
|
||||||
|
return currentMap.TryGetValue(item.Key, out lotId) &&
|
||||||
|
lotId == item.Value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private static string ValidateLinks(
|
private static string ValidateLinks(
|
||||||
IList<FraccionamientoGisLotLinkModel> links)
|
IList<FraccionamientoGisLotLinkModel> links)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
<link href='<%= ResolveUrl("~/Styles/CatalogosTramites.css") %>'
|
<link href='<%= ResolveUrl("~/Styles/CatalogosTramites.css") %>'
|
||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
type="text/css" />
|
type="text/css" />
|
||||||
<link href='<%= ResolveUrl("~/Styles/fraccionamiento-gis.css?v=20260818-1") %>'
|
<link href='<%= ResolveUrl("~/Styles/fraccionamiento-gis.css?v=20260818-2") %>'
|
||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
type="text/css" />
|
type="text/css" />
|
||||||
</asp:Content>
|
</asp:Content>
|
||||||
@@ -1004,6 +1004,14 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
|
<button type="button"
|
||||||
|
id="BtnDeleteStageGis"
|
||||||
|
class="btn red"
|
||||||
|
style="display:none;">
|
||||||
|
<i class="fa fa-trash"></i>
|
||||||
|
Eliminar GIS
|
||||||
|
</button>
|
||||||
|
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="btn default"
|
class="btn default"
|
||||||
data-dismiss="modal">
|
data-dismiss="modal">
|
||||||
@@ -1012,7 +1020,8 @@
|
|||||||
|
|
||||||
<button type="button"
|
<button type="button"
|
||||||
id="BtnSaveStageGis"
|
id="BtnSaveStageGis"
|
||||||
class="btn blue">
|
class="btn blue"
|
||||||
|
disabled="disabled">
|
||||||
<i class="fa fa-save"></i>
|
<i class="fa fa-save"></i>
|
||||||
Guardar GIS
|
Guardar GIS
|
||||||
</button>
|
</button>
|
||||||
@@ -1314,7 +1323,7 @@
|
|||||||
<asp:Content ID="ContentScripts" ContentPlaceHolderID="J" runat="server">
|
<asp:Content ID="ContentScripts" ContentPlaceHolderID="J" runat="server">
|
||||||
<script src='<%= ResolveUrl("~/Scripts/CatalogosTramites.js") %>'
|
<script src='<%= ResolveUrl("~/Scripts/CatalogosTramites.js") %>'
|
||||||
type="text/javascript"></script>
|
type="text/javascript"></script>
|
||||||
<script src='<%= ResolveUrl("~/Scripts/fraccionamiento-gis.js?v=20260818-1") %>'
|
<script src='<%= ResolveUrl("~/Scripts/fraccionamiento-gis.js?v=20260818-2") %>'
|
||||||
type="text/javascript"></script>
|
type="text/javascript"></script>
|
||||||
<script>
|
<script>
|
||||||
window.FraccionamientoGISOptions = {
|
window.FraccionamientoGISOptions = {
|
||||||
@@ -1325,6 +1334,7 @@
|
|||||||
linksTableId: 'GisVinculos',
|
linksTableId: 'GisVinculos',
|
||||||
statusId: 'GisVinculosStatus',
|
statusId: 'GisVinculosStatus',
|
||||||
saveButtonId: 'BtnSaveStageGis',
|
saveButtonId: 'BtnSaveStageGis',
|
||||||
|
deleteButtonId: 'BtnDeleteStageGis',
|
||||||
refreshButtonId: 'BtnRefreshStageGis',
|
refreshButtonId: 'BtnRefreshStageGis',
|
||||||
handlerUrl: '<%= ResolveUrl("~/Pages/Fraccionamientos/FraccionamientoGis.ashx") %>'
|
handlerUrl: '<%= ResolveUrl("~/Pages/Fraccionamientos/FraccionamientoGis.ashx") %>'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -456,11 +456,12 @@ namespace SIG.Web.Pages.Fraccionamientos
|
|||||||
{
|
{
|
||||||
HideStageGisMessage();
|
HideStageGisMessage();
|
||||||
BindSelectedStageLotsContext();
|
BindSelectedStageLotsContext();
|
||||||
|
RefreshBitacoraDetalle();
|
||||||
UpDetailTabs.Update();
|
UpDetailTabs.Update();
|
||||||
UpStageGisModal.Update();
|
UpStageGisModal.Update();
|
||||||
HideStageGisModal();
|
HideStageGisModal();
|
||||||
Alert(
|
Alert(
|
||||||
"GIS y vínculos guardados correctamente.",
|
"GIS actualizado correctamente.",
|
||||||
TipoMensaje.ToastExito);
|
TipoMensaje.ToastExito);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1614,11 +1614,6 @@ function ADDropzoneLocal(txtid) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof Dropzone === 'undefined') {
|
|
||||||
console.error('Dropzone no está disponible para #' + txtid);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (txt.attr('data-sig-dropzone-local-initialized') === '1') {
|
if (txt.attr('data-sig-dropzone-local-initialized') === '1') {
|
||||||
return window.ADSLocalDropzone
|
return window.ADSLocalDropzone
|
||||||
? window.ADSLocalDropzone.instance(txtid)
|
? window.ADSLocalDropzone.instance(txtid)
|
||||||
@@ -1641,7 +1636,7 @@ function ADDropzoneLocal(txtid) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var mydiv = $(
|
var mydiv = $(
|
||||||
'<div id="' + dropId + '" class="addropzone ADSdropzoneLocalContainer">' +
|
'<div id="' + dropId + '" class="addropzone ADSdropzoneLocalContainer" tabindex="0">' +
|
||||||
' <div class="dz-message">' + $('<div/>').text(message).html() + '</div>' +
|
' <div class="dz-message">' + $('<div/>').text(message).html() + '</div>' +
|
||||||
'</div>');
|
'</div>');
|
||||||
|
|
||||||
@@ -1651,6 +1646,237 @@ function ADDropzoneLocal(txtid) {
|
|||||||
txt.after(mydiv);
|
txt.after(mydiv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function registerInstance(instance) {
|
||||||
|
txt.attr('data-sig-dropzone-local-initialized', '1');
|
||||||
|
window.ADSLocalDropzone = window.ADSLocalDropzone || {};
|
||||||
|
window.ADSLocalDropzone.instances =
|
||||||
|
window.ADSLocalDropzone.instances || {};
|
||||||
|
window.ADSLocalDropzone.instances[txtid] = instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isAccepted(file) {
|
||||||
|
if (!acceptedFiles) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var name = String(file && file.name || '').toLowerCase();
|
||||||
|
var type = String(file && file.type || '').toLowerCase();
|
||||||
|
var accepted = acceptedFiles.split(',');
|
||||||
|
|
||||||
|
for (var i = 0; i < accepted.length; i++) {
|
||||||
|
var rule = $.trim(accepted[i]).toLowerCase();
|
||||||
|
if (!rule) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rule.charAt(0) === '.' && name.slice(-rule.length) === rule) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rule.slice(-2) === '/*' &&
|
||||||
|
type.indexOf(rule.substring(0, rule.length - 1)) === 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type && type === rule) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function readFile(file, instance) {
|
||||||
|
if (!file) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isAccepted(file)) {
|
||||||
|
txt.trigger('adsdropzone:fileerror', [
|
||||||
|
file,
|
||||||
|
'El tipo de archivo no está permitido.',
|
||||||
|
instance
|
||||||
|
]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file.size > maxFilesize * 1024 * 1024) {
|
||||||
|
txt.trigger('adsdropzone:fileerror', [
|
||||||
|
file,
|
||||||
|
'El archivo excede el tamaño permitido.',
|
||||||
|
instance
|
||||||
|
]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var reader = new FileReader();
|
||||||
|
|
||||||
|
reader.onload = function (event) {
|
||||||
|
txt.trigger('adsdropzone:fileadded', [
|
||||||
|
file,
|
||||||
|
event.target.result,
|
||||||
|
instance
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
reader.onerror = function () {
|
||||||
|
txt.trigger('adsdropzone:fileerror', [
|
||||||
|
file,
|
||||||
|
'No fue posible leer el archivo seleccionado.',
|
||||||
|
instance
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
reader.readAsText(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* El proyecto recibido conserva el helper histórico ADDropzone(), pero no
|
||||||
|
* contiene la librería Dropzone dentro de sus bundles. Para que el GIS no
|
||||||
|
* dependa de una referencia externa, este componente tiene un fallback
|
||||||
|
* nativo que mantiene la misma experiencia: clic, drag/drop, vista del
|
||||||
|
* archivo y los mismos eventos adsdropzone:* consumidos por la pantalla.
|
||||||
|
* Si Dropzone está cargado en otra instalación, se usa normalmente.
|
||||||
|
*/
|
||||||
|
if (typeof Dropzone === 'undefined') {
|
||||||
|
var input = $('<input type="file" style="display:none;" />');
|
||||||
|
if (acceptedFiles) {
|
||||||
|
input.attr('accept', acceptedFiles);
|
||||||
|
}
|
||||||
|
if (isNaN(maxFile) || maxFile !== 1) {
|
||||||
|
input.attr('multiple', 'multiple');
|
||||||
|
}
|
||||||
|
mydiv.append(input);
|
||||||
|
|
||||||
|
var fallback = {
|
||||||
|
files: [],
|
||||||
|
removeFile: function (file) {
|
||||||
|
var index = this.files.indexOf(file);
|
||||||
|
if (index >= 0) {
|
||||||
|
this.files.splice(index, 1);
|
||||||
|
}
|
||||||
|
renderFallback();
|
||||||
|
txt.trigger('adsdropzone:fileremoved', [file, fallback]);
|
||||||
|
},
|
||||||
|
removeAllFiles: function () {
|
||||||
|
var files = this.files.slice(0);
|
||||||
|
this.files = [];
|
||||||
|
renderFallback();
|
||||||
|
$.each(files, function (_, file) {
|
||||||
|
txt.trigger('adsdropzone:fileremoved', [file, fallback]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function renderFallback() {
|
||||||
|
mydiv.find('.ADSdropzoneLocalFallbackPreview').remove();
|
||||||
|
mydiv.find('.dz-message').toggle(fallback.files.length === 0);
|
||||||
|
|
||||||
|
$.each(fallback.files, function (_, file) {
|
||||||
|
var preview = $('<div class="ADSdropzoneLocalFallbackPreview"></div>');
|
||||||
|
$('<div class="ADSdropzoneLocalFileName"></div>')
|
||||||
|
.text(file.name)
|
||||||
|
.appendTo(preview);
|
||||||
|
$('<button type="button" class="btn btn-sm btn-block default">Quitar archivo</button>')
|
||||||
|
.on('click', function (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
fallback.removeFile(file);
|
||||||
|
})
|
||||||
|
.appendTo(preview);
|
||||||
|
mydiv.append(preview);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function addFallbackFile(file) {
|
||||||
|
if (!file) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isAccepted(file)) {
|
||||||
|
txt.trigger('adsdropzone:fileerror', [
|
||||||
|
file,
|
||||||
|
'El tipo de archivo no está permitido.',
|
||||||
|
fallback
|
||||||
|
]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file.size > maxFilesize * 1024 * 1024) {
|
||||||
|
txt.trigger('adsdropzone:fileerror', [
|
||||||
|
file,
|
||||||
|
'El archivo excede el tamaño permitido.',
|
||||||
|
fallback
|
||||||
|
]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isNaN(maxFile) && maxFile > 0 && fallback.files.length >= maxFile) {
|
||||||
|
fallback.removeAllFiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
fallback.files.push(file);
|
||||||
|
renderFallback();
|
||||||
|
readFile(file, fallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
input.on('change', function () {
|
||||||
|
var files = this.files || [];
|
||||||
|
for (var i = 0; i < files.length; i++) {
|
||||||
|
addFallbackFile(files[i]);
|
||||||
|
}
|
||||||
|
this.value = '';
|
||||||
|
});
|
||||||
|
|
||||||
|
mydiv.on('click', function (event) {
|
||||||
|
if ($(event.target).is('button')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
input.trigger('click');
|
||||||
|
});
|
||||||
|
|
||||||
|
mydiv.on('keydown', function (event) {
|
||||||
|
if (event.which === 13 || event.which === 32) {
|
||||||
|
event.preventDefault();
|
||||||
|
input.trigger('click');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mydiv.on('dragenter dragover', function (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
mydiv.addClass('is-dragging');
|
||||||
|
});
|
||||||
|
|
||||||
|
mydiv.on('dragleave', function (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
mydiv.removeClass('is-dragging');
|
||||||
|
});
|
||||||
|
|
||||||
|
mydiv.on('drop', function (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
mydiv.removeClass('is-dragging');
|
||||||
|
|
||||||
|
var original = event.originalEvent;
|
||||||
|
var files = original && original.dataTransfer
|
||||||
|
? original.dataTransfer.files
|
||||||
|
: null;
|
||||||
|
|
||||||
|
if (!files) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < files.length; i++) {
|
||||||
|
addFallbackFile(files[i]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return registerInstance(fallback);
|
||||||
|
}
|
||||||
|
|
||||||
var instance;
|
var instance;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -1663,6 +1889,7 @@ function ADDropzoneLocal(txtid) {
|
|||||||
maxFilesize: maxFilesize,
|
maxFilesize: maxFilesize,
|
||||||
acceptedFiles: acceptedFiles,
|
acceptedFiles: acceptedFiles,
|
||||||
addRemoveLinks: true,
|
addRemoveLinks: true,
|
||||||
|
dictDefaultMessage: message,
|
||||||
dictRemoveFile: 'Quitar archivo',
|
dictRemoveFile: 'Quitar archivo',
|
||||||
dictInvalidFileType: 'El tipo de archivo no está permitido.',
|
dictInvalidFileType: 'El tipo de archivo no está permitido.',
|
||||||
dictFileTooBig: 'El archivo excede el tamaño permitido.',
|
dictFileTooBig: 'El archivo excede el tamaño permitido.',
|
||||||
@@ -1676,26 +1903,7 @@ function ADDropzoneLocal(txtid) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var reader = new FileReader();
|
readFile(file, dz);
|
||||||
|
|
||||||
reader.onload = function (event) {
|
|
||||||
txt.trigger('adsdropzone:fileadded', [
|
|
||||||
file,
|
|
||||||
event.target.result,
|
|
||||||
dz
|
|
||||||
]);
|
|
||||||
};
|
|
||||||
|
|
||||||
reader.onerror = function () {
|
|
||||||
dz.removeFile(file);
|
|
||||||
txt.trigger('adsdropzone:fileerror', [
|
|
||||||
file,
|
|
||||||
'No fue posible leer el archivo seleccionado.',
|
|
||||||
dz
|
|
||||||
]);
|
|
||||||
};
|
|
||||||
|
|
||||||
reader.readAsText(file);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
dz.on('removedfile', function (file) {
|
dz.on('removedfile', function (file) {
|
||||||
@@ -1720,14 +1928,7 @@ function ADDropzoneLocal(txtid) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
txt.attr('data-sig-dropzone-local-initialized', '1');
|
return registerInstance(instance);
|
||||||
|
|
||||||
window.ADSLocalDropzone = window.ADSLocalDropzone || {};
|
|
||||||
window.ADSLocalDropzone.instances =
|
|
||||||
window.ADSLocalDropzone.instances || {};
|
|
||||||
window.ADSLocalDropzone.instances[txtid] = instance;
|
|
||||||
|
|
||||||
return instance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window.ADSLocalDropzone = window.ADSLocalDropzone || {};
|
window.ADSLocalDropzone = window.ADSLocalDropzone || {};
|
||||||
@@ -1737,7 +1938,7 @@ window.ADSLocalDropzone.instance = function (txtid) {
|
|||||||
};
|
};
|
||||||
window.ADSLocalDropzone.getFiles = function (txtid) {
|
window.ADSLocalDropzone.getFiles = function (txtid) {
|
||||||
var instance = window.ADSLocalDropzone.instance(txtid);
|
var instance = window.ADSLocalDropzone.instance(txtid);
|
||||||
return instance ? instance.files.slice(0) : [];
|
return instance && instance.files ? instance.files.slice(0) : [];
|
||||||
};
|
};
|
||||||
window.ADSLocalDropzone.getFile = function (txtid) {
|
window.ADSLocalDropzone.getFile = function (txtid) {
|
||||||
var files = window.ADSLocalDropzone.getFiles(txtid);
|
var files = window.ADSLocalDropzone.getFiles(txtid);
|
||||||
@@ -1745,7 +1946,7 @@ window.ADSLocalDropzone.getFile = function (txtid) {
|
|||||||
};
|
};
|
||||||
window.ADSLocalDropzone.clear = function (txtid) {
|
window.ADSLocalDropzone.clear = function (txtid) {
|
||||||
var instance = window.ADSLocalDropzone.instance(txtid);
|
var instance = window.ADSLocalDropzone.instance(txtid);
|
||||||
if (instance) {
|
if (instance && typeof instance.removeAllFiles === 'function') {
|
||||||
instance.removeAllFiles(true);
|
instance.removeAllFiles(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
linksTableId: 'GisVinculos',
|
linksTableId: 'GisVinculos',
|
||||||
statusId: 'GisVinculosStatus',
|
statusId: 'GisVinculosStatus',
|
||||||
saveButtonId: 'BtnSaveStageGis',
|
saveButtonId: 'BtnSaveStageGis',
|
||||||
|
deleteButtonId: 'BtnDeleteStageGis',
|
||||||
refreshButtonId: 'BtnRefreshStageGis',
|
refreshButtonId: 'BtnRefreshStageGis',
|
||||||
handlerUrl: '/Pages/Fraccionamientos/FraccionamientoGis.ashx',
|
handlerUrl: '/Pages/Fraccionamientos/FraccionamientoGis.ashx',
|
||||||
initialZoom: 16,
|
initialZoom: 16,
|
||||||
@@ -34,6 +35,8 @@
|
|||||||
geojson: null,
|
geojson: null,
|
||||||
file: null,
|
file: null,
|
||||||
hasServerFile: false,
|
hasServerFile: false,
|
||||||
|
isDirty: false,
|
||||||
|
busy: false,
|
||||||
mapMode: null,
|
mapMode: null,
|
||||||
map: null,
|
map: null,
|
||||||
dataLayer: null
|
dataLayer: null
|
||||||
@@ -193,10 +196,13 @@
|
|||||||
state.polygonByLotId[id] = key;
|
state.polygonByLotId[id] = key;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
setDirty(state, false);
|
||||||
|
updateActionButtons(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadServerFile(state) {
|
function loadServerFile(state) {
|
||||||
$.ajax({
|
return $.ajax({
|
||||||
url: state.options.handlerUrl,
|
url: state.options.handlerUrl,
|
||||||
type: 'GET',
|
type: 'GET',
|
||||||
dataType: 'text',
|
dataType: 'text',
|
||||||
@@ -209,6 +215,7 @@
|
|||||||
try {
|
try {
|
||||||
state.file = null;
|
state.file = null;
|
||||||
loadGeoJson(state, parseJsonText(text));
|
loadGeoJson(state, parseJsonText(text));
|
||||||
|
setDirty(state, false);
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
clearViewer(state);
|
clearViewer(state);
|
||||||
renderLinks(state);
|
renderLinks(state);
|
||||||
@@ -603,28 +610,37 @@
|
|||||||
|
|
||||||
function assign(state, polygonKeyValue, lotId) {
|
function assign(state, polygonKeyValue, lotId) {
|
||||||
var priorLot = state.linksByPolygonKey[polygonKeyValue];
|
var priorLot = state.linksByPolygonKey[polygonKeyValue];
|
||||||
|
var priorPolygon = state.polygonByLotId[lotId];
|
||||||
|
|
||||||
|
if (priorLot === lotId &&
|
||||||
|
(!priorPolygon || priorPolygon === polygonKeyValue)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (priorLot) {
|
if (priorLot) {
|
||||||
delete state.polygonByLotId[priorLot];
|
delete state.polygonByLotId[priorLot];
|
||||||
}
|
}
|
||||||
|
|
||||||
var priorPolygon = state.polygonByLotId[lotId];
|
|
||||||
if (priorPolygon && priorPolygon !== polygonKeyValue) {
|
if (priorPolygon && priorPolygon !== polygonKeyValue) {
|
||||||
delete state.linksByPolygonKey[priorPolygon];
|
delete state.linksByPolygonKey[priorPolygon];
|
||||||
}
|
}
|
||||||
|
|
||||||
state.linksByPolygonKey[polygonKeyValue] = lotId;
|
state.linksByPolygonKey[polygonKeyValue] = lotId;
|
||||||
state.polygonByLotId[lotId] = polygonKeyValue;
|
state.polygonByLotId[lotId] = polygonKeyValue;
|
||||||
|
setDirty(state, true);
|
||||||
refreshMapStyles(state);
|
refreshMapStyles(state);
|
||||||
renderLinks(state);
|
renderLinks(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
function unlink(state, polygonKeyValue) {
|
function unlink(state, polygonKeyValue) {
|
||||||
var lotId = state.linksByPolygonKey[polygonKeyValue];
|
var lotId = state.linksByPolygonKey[polygonKeyValue];
|
||||||
if (lotId) {
|
if (!lotId) {
|
||||||
delete state.polygonByLotId[lotId];
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete state.polygonByLotId[lotId];
|
||||||
delete state.linksByPolygonKey[polygonKeyValue];
|
delete state.linksByPolygonKey[polygonKeyValue];
|
||||||
|
setDirty(state, true);
|
||||||
refreshMapStyles(state);
|
refreshMapStyles(state);
|
||||||
renderLinks(state);
|
renderLinks(state);
|
||||||
}
|
}
|
||||||
@@ -765,6 +781,8 @@
|
|||||||
|
|
||||||
state.hasServerFile = true;
|
state.hasServerFile = true;
|
||||||
state.file = null;
|
state.file = null;
|
||||||
|
setDirty(state, false);
|
||||||
|
updateActionButtons(state);
|
||||||
showMessage(
|
showMessage(
|
||||||
response.message || 'GIS y vínculos guardados correctamente.',
|
response.message || 'GIS y vínculos guardados correctamente.',
|
||||||
false);
|
false);
|
||||||
@@ -793,17 +811,35 @@
|
|||||||
$input.on('adsdropzone:fileadded.sigGis', function (_, file, text) {
|
$input.on('adsdropzone:fileadded.sigGis', function (_, file, text) {
|
||||||
try {
|
try {
|
||||||
state.file = file;
|
state.file = file;
|
||||||
|
|
||||||
|
// Un GIS nuevo/reemplazado debe volver a vincularse completo.
|
||||||
|
// Las relaciones guardadas no se tocan en SQL hasta Guardar GIS.
|
||||||
|
state.linksByPolygonKey = {};
|
||||||
|
state.polygonByLotId = {};
|
||||||
|
|
||||||
loadGeoJson(state, parseJsonText(text));
|
loadGeoJson(state, parseJsonText(text));
|
||||||
|
setDirty(state, true);
|
||||||
clearMessage();
|
clearMessage();
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
state.file = null;
|
state.file = null;
|
||||||
clearViewer(state);
|
|
||||||
renderLinks(state);
|
|
||||||
|
|
||||||
if (window.ADSLocalDropzone) {
|
if (window.ADSLocalDropzone) {
|
||||||
window.ADSLocalDropzone.clear(state.options.fileInputId);
|
window.ADSLocalDropzone.clear(state.options.fileInputId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (state.hasServerFile) {
|
||||||
|
applyContext(state, {
|
||||||
|
Contexto: state.context,
|
||||||
|
Lotes: state.lots,
|
||||||
|
TieneArchivo: true
|
||||||
|
});
|
||||||
|
loadServerFile(state);
|
||||||
|
} else {
|
||||||
|
clearViewer(state);
|
||||||
|
renderLinks(state);
|
||||||
|
setDirty(state, false);
|
||||||
|
}
|
||||||
|
|
||||||
showMessage(
|
showMessage(
|
||||||
ex.message || 'El archivo GIS no es válido.',
|
ex.message || 'El archivo GIS no es válido.',
|
||||||
true);
|
true);
|
||||||
@@ -818,10 +854,16 @@
|
|||||||
state.file = null;
|
state.file = null;
|
||||||
|
|
||||||
if (state.hasServerFile) {
|
if (state.hasServerFile) {
|
||||||
|
applyContext(state, {
|
||||||
|
Contexto: state.context,
|
||||||
|
Lotes: state.lots,
|
||||||
|
TieneArchivo: true
|
||||||
|
});
|
||||||
loadServerFile(state);
|
loadServerFile(state);
|
||||||
} else {
|
} else {
|
||||||
clearViewer(state);
|
clearViewer(state);
|
||||||
renderLinks(state);
|
renderLinks(state);
|
||||||
|
setDirty(state, false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -835,13 +877,135 @@
|
|||||||
.off('click.sigGis')
|
.off('click.sigGis')
|
||||||
.on('click.sigGis', function (event) {
|
.on('click.sigGis', function (event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
|
if (!state.isDirty || state.busy) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
save(state);
|
save(state);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function bindDelete(state) {
|
||||||
|
$('#' + state.options.deleteButtonId)
|
||||||
|
.off('click.sigGis')
|
||||||
|
.on('click.sigGis', function (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
if (!state.hasServerFile || state.busy) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var executeDelete = function () {
|
||||||
|
deleteGis(state);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (window.bootbox && typeof bootbox.confirm === 'function') {
|
||||||
|
bootbox.confirm(
|
||||||
|
'Se eliminará el archivo GIS y se desvincularán todos los lotes de esta etapa. ¿Desea continuar?',
|
||||||
|
function (confirmed) {
|
||||||
|
if (confirmed) {
|
||||||
|
executeDelete();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window.confirm(
|
||||||
|
'Se eliminará el archivo GIS y se desvincularán todos los lotes de esta etapa. ¿Desea continuar?')) {
|
||||||
|
executeDelete();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteGis(state) {
|
||||||
|
setBusy(true);
|
||||||
|
clearMessage();
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: state.options.handlerUrl,
|
||||||
|
type: 'POST',
|
||||||
|
dataType: 'json',
|
||||||
|
data: {
|
||||||
|
metodo: 'Delete',
|
||||||
|
CveFraccionamientoEtapa: state.stageId
|
||||||
|
}
|
||||||
|
}).done(function (response) {
|
||||||
|
if (!response || response.success !== true) {
|
||||||
|
showServerError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
state.hasServerFile = false;
|
||||||
|
state.file = null;
|
||||||
|
state.linksByPolygonKey = {};
|
||||||
|
state.polygonByLotId = {};
|
||||||
|
|
||||||
|
$.each(state.lots, function (_, lot) {
|
||||||
|
if (lot) {
|
||||||
|
lot.GISPoligonoClave = null;
|
||||||
|
lot.gisPoligonoClave = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (window.ADSLocalDropzone) {
|
||||||
|
window.ADSLocalDropzone.clear(state.options.fileInputId);
|
||||||
|
}
|
||||||
|
|
||||||
|
clearViewer(state);
|
||||||
|
renderLinks(state);
|
||||||
|
setDirty(state, false);
|
||||||
|
updateActionButtons(state);
|
||||||
|
|
||||||
|
showMessage(
|
||||||
|
response.message || 'GIS eliminado y lotes desvinculados correctamente.',
|
||||||
|
false);
|
||||||
|
|
||||||
|
$(document).trigger('siggis:deleted', [response]);
|
||||||
|
|
||||||
|
var refreshButton = $('#' + state.options.refreshButtonId);
|
||||||
|
if (refreshButton.length) {
|
||||||
|
refreshButton.click();
|
||||||
|
}
|
||||||
|
}).fail(function (xhr) {
|
||||||
|
showXhrError(xhr);
|
||||||
|
}).always(function () {
|
||||||
|
setBusy(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setDirty(state, value) {
|
||||||
|
if (!state) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
state.isDirty = !!value;
|
||||||
|
updateActionButtons(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateActionButtons(state) {
|
||||||
|
if (!state) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#' + state.options.saveButtonId)
|
||||||
|
.prop('disabled', state.busy || !state.isDirty);
|
||||||
|
|
||||||
|
$('#' + state.options.deleteButtonId)
|
||||||
|
.toggle(!!state.hasServerFile)
|
||||||
|
.prop('disabled', !!state.busy);
|
||||||
|
}
|
||||||
|
|
||||||
function setBusy(value) {
|
function setBusy(value) {
|
||||||
var config = options();
|
var config = options();
|
||||||
$('#' + config.saveButtonId).prop('disabled', !!value);
|
|
||||||
|
if (current) {
|
||||||
|
current.busy = !!value;
|
||||||
|
updateActionButtons(current);
|
||||||
|
} else {
|
||||||
|
$('#' + config.saveButtonId).prop('disabled', true);
|
||||||
|
$('#' + config.deleteButtonId).prop('disabled', !!value);
|
||||||
|
}
|
||||||
|
|
||||||
if (window.Metronic && typeof Metronic.blockUI === 'function' && value) {
|
if (window.Metronic && typeof Metronic.blockUI === 'function' && value) {
|
||||||
Metronic.blockUI({ target: '#' + config.modalId + ' .modal-content', animate: true });
|
Metronic.blockUI({ target: '#' + config.modalId + ' .modal-content', animate: true });
|
||||||
@@ -920,7 +1084,9 @@
|
|||||||
current = createState(stageId);
|
current = createState(stageId);
|
||||||
bindFile(current);
|
bindFile(current);
|
||||||
bindSave(current);
|
bindSave(current);
|
||||||
|
bindDelete(current);
|
||||||
renderLinks(current);
|
renderLinks(current);
|
||||||
|
updateActionButtons(current);
|
||||||
loadContext(current);
|
loadContext(current);
|
||||||
return current;
|
return current;
|
||||||
};
|
};
|
||||||
@@ -961,6 +1127,8 @@
|
|||||||
window.ADSLocalDropzone.clear(config.fileInputId);
|
window.ADSLocalDropzone.clear(config.fileInputId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$('#' + config.saveButtonId).prop('disabled', true);
|
||||||
|
$('#' + config.deleteButtonId).hide().prop('disabled', false);
|
||||||
current = null;
|
current = null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,3 +146,21 @@
|
|||||||
height: 360px;
|
height: 360px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.ADSdropzoneLocalContainer.is-dragging {
|
||||||
|
border-style: solid;
|
||||||
|
background: #eef6fb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ADSdropzoneLocalFallbackPreview {
|
||||||
|
padding: 10px;
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #d9dee4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ADSdropzoneLocalFileName {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
font-weight: 600;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user