1102 lines
31 KiB
JavaScript
1102 lines
31 KiB
JavaScript
(function (window, document) {
|
|
'use strict';
|
|
|
|
if (window.SIGDocumentosEtapaCargaMasiva) {
|
|
return;
|
|
}
|
|
|
|
var stopWords = {
|
|
'de': true,
|
|
'del': true,
|
|
'la': true,
|
|
'las': true,
|
|
'el': true,
|
|
'los': true,
|
|
'y': true,
|
|
'para': true,
|
|
'por': true,
|
|
'en': true,
|
|
'un': true,
|
|
'una': true,
|
|
'copia': true,
|
|
'archivo': true,
|
|
'documento': true,
|
|
'pdf': true
|
|
};
|
|
|
|
function texto(valor) {
|
|
return valor == null ? '' : String(valor);
|
|
}
|
|
|
|
function quitarExtension(nombre) {
|
|
var valor = texto(nombre);
|
|
var indice = valor.lastIndexOf('.');
|
|
return indice > 0 ? valor.substring(0, indice) : valor;
|
|
}
|
|
|
|
function sinAcentos(valor) {
|
|
var resultado = texto(valor);
|
|
|
|
if (resultado.normalize) {
|
|
return resultado
|
|
.normalize('NFD')
|
|
.replace(/[\u0300-\u036f]/g, '');
|
|
}
|
|
|
|
return resultado
|
|
.replace(/[áàäâ]/gi, 'a')
|
|
.replace(/[éèëê]/gi, 'e')
|
|
.replace(/[íìïî]/gi, 'i')
|
|
.replace(/[óòöô]/gi, 'o')
|
|
.replace(/[úùüû]/gi, 'u')
|
|
.replace(/ñ/gi, 'n');
|
|
}
|
|
|
|
function normalizar(valor) {
|
|
return sinAcentos(quitarExtension(valor))
|
|
.toLowerCase()
|
|
.replace(/[_\-\.(),/\\]+/g, ' ')
|
|
.replace(/[^a-z0-9\s]/g, ' ')
|
|
.replace(/\s+/g, ' ')
|
|
.trim();
|
|
}
|
|
|
|
function tokens(valor) {
|
|
return normalizar(valor)
|
|
.split(' ')
|
|
.filter(function (item) {
|
|
return item && !stopWords[item] && !/^\d+$/.test(item);
|
|
});
|
|
}
|
|
|
|
function puntaje(nombreArchivo, tipoDocumento) {
|
|
var archivo = normalizar(nombreArchivo);
|
|
var tipo = normalizar(tipoDocumento);
|
|
|
|
if (!archivo || !tipo) {
|
|
return 0;
|
|
}
|
|
|
|
if (archivo === tipo) {
|
|
return 1;
|
|
}
|
|
|
|
if (archivo.indexOf(tipo) >= 0 || tipo.indexOf(archivo) >= 0) {
|
|
return 0.95;
|
|
}
|
|
|
|
var archivoTokens = tokens(nombreArchivo);
|
|
var tipoTokens = tokens(tipoDocumento);
|
|
|
|
if (!archivoTokens.length || !tipoTokens.length) {
|
|
return 0;
|
|
}
|
|
|
|
var tipoMapa = {};
|
|
var interseccion = 0;
|
|
var indice;
|
|
|
|
for (indice = 0; indice < tipoTokens.length; indice++) {
|
|
tipoMapa[tipoTokens[indice]] = true;
|
|
}
|
|
|
|
for (indice = 0; indice < archivoTokens.length; indice++) {
|
|
if (tipoMapa[archivoTokens[indice]]) {
|
|
interseccion++;
|
|
}
|
|
}
|
|
|
|
var coberturaArchivo = interseccion / archivoTokens.length;
|
|
var coberturaTipo = interseccion / tipoTokens.length;
|
|
|
|
return (coberturaArchivo * 0.65) + (coberturaTipo * 0.35);
|
|
}
|
|
|
|
function buscarCoincidencia(nombreArchivo, catalogo) {
|
|
var candidatos = [];
|
|
var indice;
|
|
|
|
for (indice = 0; indice < catalogo.length; indice++) {
|
|
candidatos.push({
|
|
indice: indice,
|
|
puntaje: puntaje(nombreArchivo, catalogo[indice].TipoDocumento)
|
|
});
|
|
}
|
|
|
|
candidatos.sort(function (a, b) {
|
|
return b.puntaje - a.puntaje;
|
|
});
|
|
|
|
if (!candidatos.length || candidatos[0].puntaje < 0.58) {
|
|
return -1;
|
|
}
|
|
|
|
if (candidatos.length > 1 &&
|
|
Math.abs(candidatos[0].puntaje - candidatos[1].puntaje) < 0.05) {
|
|
return -1;
|
|
}
|
|
|
|
return candidatos[0].indice;
|
|
}
|
|
|
|
function leerCatalogo(root) {
|
|
var campo = root.querySelector('input[id$="CatalogoCargaMasiva"]');
|
|
if (!campo || !campo.value) {
|
|
return [];
|
|
}
|
|
|
|
try {
|
|
return JSON.parse(campo.value) || [];
|
|
}
|
|
catch (error) {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
function fechaHoy(root) {
|
|
var campo = root.querySelector('input[id$="FechaHoyCargaMasiva"]');
|
|
return campo ? campo.value : '';
|
|
}
|
|
|
|
/*
|
|
* La carga masiva utiliza el control genérico ADSdropzoneLocal.
|
|
* Ese control parte de un input hidden y genera un contenedor
|
|
* {ClientID}-drop con el input type=file real.
|
|
*/
|
|
function obtenerControlCarga(root) {
|
|
return root.querySelector(
|
|
'.ADSdropzoneLocal[data-sig-carga-masiva-archivo]'
|
|
);
|
|
}
|
|
|
|
function obtenerContenedorDropzone(root) {
|
|
var control = obtenerControlCarga(root);
|
|
|
|
if (!control || !control.id) {
|
|
return null;
|
|
}
|
|
|
|
return document.getElementById(control.id + '-drop');
|
|
}
|
|
|
|
function claveArchivo(archivo) {
|
|
if (!archivo) {
|
|
return '';
|
|
}
|
|
|
|
return [
|
|
texto(archivo.name),
|
|
texto(archivo.size),
|
|
texto(archivo.lastModified)
|
|
].join('|');
|
|
}
|
|
|
|
/*
|
|
* ADSdropzoneLocal puede conservar más de un input type=file
|
|
* internamente. No debemos tomar únicamente el primero porque,
|
|
* después de seleccionar archivos, el control puede crear otro
|
|
* input vacío para permitir una nueva selección.
|
|
*/
|
|
function obtenerArchivosInputs(root) {
|
|
var contenedor = obtenerContenedorDropzone(root);
|
|
var archivos = [];
|
|
var vistos = {};
|
|
|
|
if (!contenedor) {
|
|
return archivos;
|
|
}
|
|
|
|
var inputs = contenedor.querySelectorAll('input[type="file"]');
|
|
var indiceInput;
|
|
var indiceArchivo;
|
|
|
|
for (
|
|
indiceInput = 0;
|
|
indiceInput < inputs.length;
|
|
indiceInput++
|
|
) {
|
|
var input = inputs[indiceInput];
|
|
|
|
if (!input.files) {
|
|
continue;
|
|
}
|
|
|
|
for (
|
|
indiceArchivo = 0;
|
|
indiceArchivo < input.files.length;
|
|
indiceArchivo++
|
|
) {
|
|
var archivo = input.files[indiceArchivo];
|
|
var clave = claveArchivo(archivo);
|
|
|
|
if (!vistos[clave]) {
|
|
vistos[clave] = true;
|
|
archivos.push(archivo);
|
|
}
|
|
}
|
|
}
|
|
|
|
return archivos;
|
|
}
|
|
|
|
/*
|
|
* Cuando el control genérico está respaldado por Dropzone,
|
|
* la fuente más confiable después de que éste reemplaza su
|
|
* input interno es la colección dropzone.files.
|
|
*/
|
|
function obtenerArchivosDropzone(root) {
|
|
var contenedor = obtenerContenedorDropzone(root);
|
|
var instancia = null;
|
|
var archivos = [];
|
|
|
|
if (!contenedor) {
|
|
return archivos;
|
|
}
|
|
|
|
if (contenedor.dropzone) {
|
|
instancia = contenedor.dropzone;
|
|
}
|
|
else if (
|
|
window.Dropzone &&
|
|
typeof window.Dropzone.forElement === 'function'
|
|
) {
|
|
try {
|
|
instancia = window.Dropzone.forElement(contenedor);
|
|
}
|
|
catch (error) {
|
|
instancia = null;
|
|
}
|
|
}
|
|
|
|
if (!instancia || !instancia.files) {
|
|
return archivos;
|
|
}
|
|
|
|
for (var indice = 0; indice < instancia.files.length; indice++) {
|
|
var archivo = instancia.files[indice];
|
|
|
|
if (!archivo || !archivo.name) {
|
|
continue;
|
|
}
|
|
|
|
/*
|
|
* removeFile() elimina el archivo de la colección. Este filtro
|
|
* solamente evita tomar archivos cancelados si la versión de
|
|
* Dropzone conserva alguno temporalmente.
|
|
*/
|
|
if (
|
|
window.Dropzone &&
|
|
window.Dropzone.CANCELED &&
|
|
archivo.status === window.Dropzone.CANCELED
|
|
) {
|
|
continue;
|
|
}
|
|
|
|
archivos.push(archivo);
|
|
}
|
|
|
|
return archivos;
|
|
}
|
|
|
|
function obtenerArchivos(root) {
|
|
/*
|
|
* Primero usamos los inputs reales porque mantienen el mismo orden
|
|
* que Request.Files durante el postback. Si el control genérico ya
|
|
* sustituyó esos inputs y quedaron vacíos, usamos dropzone.files.
|
|
*/
|
|
var archivos = obtenerArchivosInputs(root);
|
|
|
|
if (archivos.length > 0) {
|
|
return archivos;
|
|
}
|
|
|
|
return obtenerArchivosDropzone(root);
|
|
}
|
|
|
|
function crearOpcion(textoOpcion, valor) {
|
|
var opcion = document.createElement('option');
|
|
opcion.value = valor;
|
|
opcion.textContent = textoOpcion;
|
|
return opcion;
|
|
}
|
|
|
|
function actualizarVencimiento(fila, catalogo) {
|
|
var select = fila.querySelector('[data-sig-carga-tipo]');
|
|
var contenedor = fila.querySelector('[data-sig-carga-vencimiento-contenedor]');
|
|
var input = fila.querySelector('[data-sig-carga-vencimiento]');
|
|
var noAplica = fila.querySelector('[data-sig-carga-vencimiento-no-aplica]');
|
|
var indice = select && select.value !== '' ? parseInt(select.value, 10) : -1;
|
|
var requiere = indice >= 0 && catalogo[indice] &&
|
|
catalogo[indice].TieneVigencia === true;
|
|
|
|
if (requiere) {
|
|
contenedor.style.display = '';
|
|
noAplica.style.display = 'none';
|
|
input.disabled = false;
|
|
input.required = true;
|
|
}
|
|
else {
|
|
input.value = '';
|
|
input.disabled = true;
|
|
input.required = false;
|
|
contenedor.style.display = 'none';
|
|
noAplica.style.display = '';
|
|
}
|
|
}
|
|
|
|
function actualizarFilaIncluida(fila, catalogo) {
|
|
var incluir = fila.querySelector(
|
|
'[data-sig-carga-incluir]'
|
|
);
|
|
var incluida = !incluir || incluir.checked;
|
|
var select = fila.querySelector(
|
|
'[data-sig-carga-tipo]'
|
|
);
|
|
var fecha = fila.querySelector(
|
|
'[data-sig-carga-fecha]'
|
|
);
|
|
var vencimiento = fila.querySelector(
|
|
'[data-sig-carga-vencimiento]'
|
|
);
|
|
|
|
if (incluida) {
|
|
fila.classList.remove(
|
|
'sig-carga-masiva-fila-omitida'
|
|
);
|
|
|
|
if (select) {
|
|
select.disabled = false;
|
|
}
|
|
|
|
if (fecha) {
|
|
fecha.disabled = false;
|
|
}
|
|
|
|
actualizarVencimiento(fila, catalogo);
|
|
return;
|
|
}
|
|
|
|
fila.classList.add(
|
|
'sig-carga-masiva-fila-omitida'
|
|
);
|
|
|
|
if (select) {
|
|
select.disabled = true;
|
|
}
|
|
|
|
if (fecha) {
|
|
fecha.disabled = true;
|
|
fecha.required = false;
|
|
}
|
|
|
|
if (vencimiento) {
|
|
vencimiento.disabled = true;
|
|
vencimiento.required = false;
|
|
}
|
|
}
|
|
|
|
function crearFila(root, archivo, indiceArchivo, catalogo) {
|
|
var fila = document.createElement('tr');
|
|
fila.setAttribute('data-sig-carga-fila', '1');
|
|
fila.setAttribute('data-index', String(indiceArchivo));
|
|
|
|
var celdaIncluir = document.createElement('td');
|
|
celdaIncluir.className = 'sig-carga-masiva-col-incluir';
|
|
|
|
var incluir = document.createElement('input');
|
|
incluir.type = 'checkbox';
|
|
incluir.checked = true;
|
|
incluir.setAttribute('data-sig-carga-incluir', '1');
|
|
incluir.setAttribute(
|
|
'aria-label',
|
|
'Incluir ' + archivo.name
|
|
);
|
|
incluir.title = 'Incluir archivo en la carga';
|
|
|
|
celdaIncluir.appendChild(incluir);
|
|
fila.appendChild(celdaIncluir);
|
|
|
|
var celdaArchivo = document.createElement('td');
|
|
var nombre = document.createElement('strong');
|
|
nombre.className = 'sig-carga-masiva-nombre';
|
|
nombre.textContent = archivo.name;
|
|
celdaArchivo.appendChild(nombre);
|
|
|
|
var estado = document.createElement('span');
|
|
estado.className = 'sig-carga-masiva-coincidencia';
|
|
estado.setAttribute('data-sig-carga-coincidencia', '1');
|
|
celdaArchivo.appendChild(estado);
|
|
fila.appendChild(celdaArchivo);
|
|
|
|
var celdaTipo = document.createElement('td');
|
|
var select = document.createElement('select');
|
|
select.className = 'form-control input-sm';
|
|
select.setAttribute('data-sig-carga-tipo', '1');
|
|
select.appendChild(crearOpcion('Seleccione tipo de documento', ''));
|
|
|
|
var indice;
|
|
for (indice = 0; indice < catalogo.length; indice++) {
|
|
select.appendChild(
|
|
crearOpcion(catalogo[indice].Etiqueta, String(indice))
|
|
);
|
|
}
|
|
|
|
var coincidencia = buscarCoincidencia(archivo.name, catalogo);
|
|
if (coincidencia >= 0) {
|
|
select.value = String(coincidencia);
|
|
estado.textContent = 'Coincidencia automática';
|
|
estado.className += ' sig-carga-masiva-coincidencia-ok';
|
|
}
|
|
else {
|
|
estado.textContent = 'Revise el tipo de documento';
|
|
}
|
|
|
|
select.addEventListener('change', function () {
|
|
estado.textContent = select.value === ''
|
|
? 'Revise el tipo de documento'
|
|
: 'Tipo seleccionado';
|
|
|
|
actualizarVencimiento(fila, catalogo);
|
|
});
|
|
|
|
celdaTipo.appendChild(select);
|
|
fila.appendChild(celdaTipo);
|
|
|
|
var celdaFecha = document.createElement('td');
|
|
var fecha = document.createElement('input');
|
|
fecha.type = 'date';
|
|
fecha.className = 'form-control input-sm';
|
|
fecha.setAttribute('data-sig-carga-fecha', '1');
|
|
fecha.required = true;
|
|
fecha.value = fechaHoy(root);
|
|
fecha.max = fechaHoy(root);
|
|
celdaFecha.appendChild(fecha);
|
|
fila.appendChild(celdaFecha);
|
|
|
|
var celdaVencimiento = document.createElement('td');
|
|
|
|
var vencimientoContenedor = document.createElement('div');
|
|
vencimientoContenedor.setAttribute(
|
|
'data-sig-carga-vencimiento-contenedor',
|
|
'1'
|
|
);
|
|
|
|
var vencimiento = document.createElement('input');
|
|
vencimiento.type = 'date';
|
|
vencimiento.className = 'form-control input-sm';
|
|
vencimiento.setAttribute('data-sig-carga-vencimiento', '1');
|
|
vencimientoContenedor.appendChild(vencimiento);
|
|
celdaVencimiento.appendChild(vencimientoContenedor);
|
|
|
|
var noAplica = document.createElement('span');
|
|
noAplica.className = 'text-muted';
|
|
noAplica.setAttribute(
|
|
'data-sig-carga-vencimiento-no-aplica',
|
|
'1'
|
|
);
|
|
noAplica.textContent = 'No aplica';
|
|
celdaVencimiento.appendChild(noAplica);
|
|
|
|
fila.appendChild(celdaVencimiento);
|
|
|
|
incluir.addEventListener('change', function () {
|
|
actualizarFilaIncluida(fila, catalogo);
|
|
});
|
|
|
|
actualizarVencimiento(fila, catalogo);
|
|
actualizarFilaIncluida(fila, catalogo);
|
|
|
|
return fila;
|
|
}
|
|
|
|
function mostrarError(root, mensaje) {
|
|
var contenedor = root.querySelector(
|
|
'[data-sig-carga-masiva-error]'
|
|
);
|
|
|
|
if (!contenedor) {
|
|
return;
|
|
}
|
|
|
|
if (!mensaje) {
|
|
contenedor.style.display = 'none';
|
|
contenedor.textContent = '';
|
|
return;
|
|
}
|
|
|
|
contenedor.textContent = mensaje;
|
|
contenedor.style.display = '';
|
|
}
|
|
|
|
function mostrarEstadoListado(root, mensaje) {
|
|
var cuerpo = root.querySelector(
|
|
'[data-sig-carga-masiva-filas]'
|
|
);
|
|
|
|
if (!cuerpo) {
|
|
return;
|
|
}
|
|
|
|
cuerpo.innerHTML = '';
|
|
|
|
var vacio = document.createElement('tr');
|
|
vacio.className = 'sig-carga-masiva-vacio';
|
|
|
|
var celda = document.createElement('td');
|
|
celda.colSpan = 5;
|
|
celda.textContent =
|
|
mensaje || 'Seleccione archivos para continuar.';
|
|
|
|
vacio.appendChild(celda);
|
|
cuerpo.appendChild(vacio);
|
|
}
|
|
|
|
function actualizarResumenSeleccion(root) {
|
|
var archivos = obtenerArchivos(root);
|
|
var resumen = root.querySelector(
|
|
'[data-sig-carga-masiva-resumen]'
|
|
);
|
|
var enlistar = root.querySelector(
|
|
'[data-sig-carga-masiva-enlistar]'
|
|
);
|
|
var cantidad = archivos.length || 0;
|
|
|
|
if (enlistar) {
|
|
enlistar.disabled = cantidad === 0;
|
|
}
|
|
|
|
if (!resumen) {
|
|
return;
|
|
}
|
|
|
|
if (cantidad === 0) {
|
|
resumen.textContent =
|
|
'Seleccione o arrastre archivos para continuar.';
|
|
return;
|
|
}
|
|
|
|
resumen.textContent =
|
|
cantidad === 1
|
|
? '1 archivo seleccionado. Presione "Enlistar archivos".'
|
|
: cantidad +
|
|
' archivos seleccionados. Presione "Enlistar archivos".';
|
|
}
|
|
|
|
function seleccionCambiada(root) {
|
|
var archivos = obtenerArchivos(root);
|
|
var cantidad = archivos.length || 0;
|
|
|
|
mostrarError(root, '');
|
|
actualizarResumenSeleccion(root);
|
|
|
|
if (cantidad === 0) {
|
|
mostrarEstadoListado(
|
|
root,
|
|
'Seleccione archivos para continuar.'
|
|
);
|
|
return;
|
|
}
|
|
|
|
mostrarEstadoListado(
|
|
root,
|
|
cantidad === 1
|
|
? '1 archivo seleccionado. Presione "Enlistar archivos" para prepararlo.'
|
|
: cantidad +
|
|
' archivos seleccionados. Presione "Enlistar archivos" para prepararlos.'
|
|
);
|
|
}
|
|
|
|
function renderizar(root) {
|
|
var archivos = obtenerArchivos(root);
|
|
var cuerpo = root.querySelector(
|
|
'[data-sig-carga-masiva-filas]'
|
|
);
|
|
var catalogo = leerCatalogo(root);
|
|
|
|
if (!cuerpo) {
|
|
return;
|
|
}
|
|
|
|
cuerpo.innerHTML = '';
|
|
mostrarError(root, '');
|
|
|
|
if (!archivos || archivos.length === 0) {
|
|
mostrarEstadoListado(
|
|
root,
|
|
'Seleccione archivos para continuar.'
|
|
);
|
|
actualizarResumenSeleccion(root);
|
|
return;
|
|
}
|
|
|
|
var indice;
|
|
for (indice = 0; indice < archivos.length; indice++) {
|
|
cuerpo.appendChild(
|
|
crearFila(
|
|
root,
|
|
archivos[indice],
|
|
indice,
|
|
catalogo
|
|
)
|
|
);
|
|
}
|
|
|
|
actualizarResumenSeleccion(root);
|
|
}
|
|
|
|
function serializar(root) {
|
|
var archivos = obtenerArchivos(root);
|
|
var hidden = root.querySelector(
|
|
'input[id$="MetadataCargaMasiva"]'
|
|
);
|
|
var catalogo = leerCatalogo(root);
|
|
var filas = root.querySelectorAll(
|
|
'[data-sig-carga-fila]'
|
|
);
|
|
var datos = [];
|
|
var errores = [];
|
|
var destinos = {};
|
|
var incluidos = 0;
|
|
var indice;
|
|
|
|
if (!archivos || archivos.length === 0) {
|
|
errores.push('Seleccione al menos un archivo.');
|
|
}
|
|
else if (filas.length !== archivos.length) {
|
|
errores.push(
|
|
'Presione "Enlistar archivos" antes de guardar.'
|
|
);
|
|
}
|
|
|
|
for (indice = 0; indice < filas.length; indice++) {
|
|
var fila = filas[indice];
|
|
var indexArchivo = parseInt(
|
|
fila.getAttribute('data-index'),
|
|
10
|
|
);
|
|
|
|
var archivo =
|
|
!isNaN(indexArchivo) &&
|
|
indexArchivo >= 0 &&
|
|
indexArchivo < archivos.length
|
|
? archivos[indexArchivo]
|
|
: null;
|
|
|
|
if (!archivo) {
|
|
errores.push(
|
|
'La selección de archivos cambió. Presione "Enlistar archivos" nuevamente.'
|
|
);
|
|
continue;
|
|
}
|
|
|
|
var incluir = fila.querySelector(
|
|
'[data-sig-carga-incluir]'
|
|
);
|
|
var estaIncluido = !incluir || incluir.checked;
|
|
|
|
if (!estaIncluido) {
|
|
datos.push({
|
|
Index: indexArchivo,
|
|
Incluir: false
|
|
});
|
|
continue;
|
|
}
|
|
|
|
incluidos++;
|
|
|
|
var select = fila.querySelector(
|
|
'[data-sig-carga-tipo]'
|
|
);
|
|
var fecha = fila.querySelector(
|
|
'[data-sig-carga-fecha]'
|
|
);
|
|
var vencimiento = fila.querySelector(
|
|
'[data-sig-carga-vencimiento]'
|
|
);
|
|
|
|
if (!select || select.value === '') {
|
|
errores.push(
|
|
'Seleccione el tipo de documento para ' +
|
|
archivo.name +
|
|
'.'
|
|
);
|
|
continue;
|
|
}
|
|
|
|
var indiceCatalogo = parseInt(
|
|
select.value,
|
|
10
|
|
);
|
|
var opcion = catalogo[indiceCatalogo];
|
|
|
|
if (!opcion) {
|
|
errores.push(
|
|
'El tipo de documento seleccionado ya no está disponible.'
|
|
);
|
|
continue;
|
|
}
|
|
|
|
if (!fecha || !fecha.value) {
|
|
errores.push(
|
|
'Capture la fecha del documento para ' +
|
|
archivo.name +
|
|
'.'
|
|
);
|
|
continue;
|
|
}
|
|
|
|
if (
|
|
opcion.TieneVigencia === true &&
|
|
(!vencimiento || !vencimiento.value)
|
|
) {
|
|
errores.push(
|
|
'Capture el vencimiento para ' +
|
|
archivo.name +
|
|
'.'
|
|
);
|
|
continue;
|
|
}
|
|
|
|
if (
|
|
vencimiento &&
|
|
vencimiento.value &&
|
|
vencimiento.value < fecha.value
|
|
) {
|
|
errores.push(
|
|
'El vencimiento no puede ser anterior a la fecha del documento en ' +
|
|
archivo.name +
|
|
'.'
|
|
);
|
|
continue;
|
|
}
|
|
|
|
var destino =
|
|
opcion.CveFraccionamientoEtapa +
|
|
'|' +
|
|
opcion.CveTipoDocumento;
|
|
|
|
if (destinos[destino]) {
|
|
errores.push(
|
|
'Hay más de un archivo asignado al mismo documento: ' +
|
|
opcion.TipoDocumento +
|
|
'.'
|
|
);
|
|
continue;
|
|
}
|
|
|
|
destinos[destino] = true;
|
|
|
|
datos.push({
|
|
Index: indexArchivo,
|
|
Incluir: true,
|
|
CveFraccionamientoEtapa:
|
|
opcion.CveFraccionamientoEtapa,
|
|
CveTipoDocumento:
|
|
opcion.CveTipoDocumento,
|
|
FechaDocumento:
|
|
fecha.value,
|
|
FechaVencimiento:
|
|
opcion.TieneVigencia === true &&
|
|
vencimiento
|
|
? vencimiento.value
|
|
: ''
|
|
});
|
|
}
|
|
|
|
if (incluidos === 0 && errores.length === 0) {
|
|
errores.push(
|
|
'Marque al menos un archivo para guardar.'
|
|
);
|
|
}
|
|
|
|
if (errores.length) {
|
|
mostrarError(root, errores.join('\n'));
|
|
return false;
|
|
}
|
|
|
|
if (hidden) {
|
|
hidden.value = JSON.stringify(datos);
|
|
}
|
|
|
|
mostrarError(root, '');
|
|
return true;
|
|
}
|
|
|
|
function ancestroConAtributo(elemento, atributo, limite) {
|
|
var actual = elemento;
|
|
|
|
while (actual && actual !== limite) {
|
|
if (
|
|
actual.getAttribute &&
|
|
actual.getAttribute(atributo) !== null
|
|
) {
|
|
return actual;
|
|
}
|
|
|
|
actual = actual.parentNode;
|
|
}
|
|
|
|
if (
|
|
limite &&
|
|
limite.getAttribute &&
|
|
limite.getAttribute(atributo) !== null
|
|
) {
|
|
return limite;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
function ancestroConClase(elemento, clase, limite) {
|
|
var actual = elemento;
|
|
|
|
while (actual && actual !== limite) {
|
|
if (
|
|
actual.classList &&
|
|
actual.classList.contains(clase)
|
|
) {
|
|
return actual;
|
|
}
|
|
|
|
actual = actual.parentNode;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
function esInputDelDropzone(root, elemento) {
|
|
if (
|
|
!elemento ||
|
|
elemento.tagName !== 'INPUT' ||
|
|
texto(elemento.type).toLowerCase() !== 'file'
|
|
) {
|
|
return false;
|
|
}
|
|
|
|
var contenedor = ancestroConClase(
|
|
elemento,
|
|
'ADSdropzoneLocalContainer',
|
|
root
|
|
);
|
|
|
|
return !!contenedor;
|
|
}
|
|
|
|
function sincronizarDespuesDeQuitar(root) {
|
|
window.setTimeout(function () {
|
|
seleccionCambiada(root);
|
|
}, 0);
|
|
}
|
|
|
|
/*
|
|
* El ADSdropzoneLocal agrega/quita previews de forma dinámica y puede
|
|
* reemplazar su input type=file. Observamos únicamente el contenedor
|
|
* del dropzone para mantener el botón "Enlistar archivos" sincronizado
|
|
* aunque el change del input interno no llegue hasta este script.
|
|
*/
|
|
function observarDropzone(root) {
|
|
var contenedor = obtenerContenedorDropzone(root);
|
|
|
|
if (
|
|
!contenedor ||
|
|
!window.MutationObserver ||
|
|
contenedor.getAttribute(
|
|
'data-sig-carga-masiva-observado'
|
|
) === '1'
|
|
) {
|
|
return;
|
|
}
|
|
|
|
contenedor.setAttribute(
|
|
'data-sig-carga-masiva-observado',
|
|
'1'
|
|
);
|
|
|
|
var pendiente = false;
|
|
var observador = new MutationObserver(function () {
|
|
if (pendiente) {
|
|
return;
|
|
}
|
|
|
|
pendiente = true;
|
|
|
|
window.setTimeout(function () {
|
|
pendiente = false;
|
|
seleccionCambiada(root);
|
|
}, 0);
|
|
});
|
|
|
|
observador.observe(contenedor, {
|
|
childList: true,
|
|
subtree: true
|
|
});
|
|
}
|
|
|
|
function inicializar(root) {
|
|
if (!root) {
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* El modal contiene un UpdatePanel. Los eventos se delegan
|
|
* desde el contenedor exterior para que sigan funcionando
|
|
* aunque ASP.NET reemplace el control ADSdropzoneLocal,
|
|
* el botón o la tabla.
|
|
*/
|
|
if (
|
|
root.getAttribute(
|
|
'data-sig-carga-masiva-inicializado'
|
|
) !== '1'
|
|
) {
|
|
root.setAttribute(
|
|
'data-sig-carga-masiva-inicializado',
|
|
'1'
|
|
);
|
|
|
|
root.addEventListener(
|
|
'change',
|
|
function (evento) {
|
|
var objetivo =
|
|
evento.target ||
|
|
evento.srcElement;
|
|
|
|
if (
|
|
esInputDelDropzone(
|
|
root,
|
|
objetivo
|
|
)
|
|
) {
|
|
seleccionCambiada(root);
|
|
}
|
|
}
|
|
);
|
|
|
|
root.addEventListener(
|
|
'click',
|
|
function (evento) {
|
|
var objetivo =
|
|
evento.target ||
|
|
evento.srcElement;
|
|
|
|
var enlistar =
|
|
ancestroConAtributo(
|
|
objetivo,
|
|
'data-sig-carga-masiva-enlistar',
|
|
root
|
|
);
|
|
|
|
if (enlistar) {
|
|
evento.preventDefault();
|
|
renderizar(root);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* El propio ADSdropzoneLocal muestra "Quitar archivo".
|
|
* Cuando se quite uno, invalidamos el grid para que
|
|
* el usuario vuelva a enlistar la selección actual.
|
|
*/
|
|
var quitarPreview =
|
|
ancestroConClase(
|
|
objetivo,
|
|
'dz-remove',
|
|
root
|
|
);
|
|
|
|
if (quitarPreview) {
|
|
sincronizarDespuesDeQuitar(root);
|
|
return;
|
|
}
|
|
|
|
var guardar =
|
|
ancestroConAtributo(
|
|
objetivo,
|
|
'data-sig-carga-masiva-guardar',
|
|
root
|
|
);
|
|
|
|
if (guardar) {
|
|
if (!serializar(root)) {
|
|
evento.preventDefault();
|
|
evento.stopPropagation();
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
* No deshabilitamos el submit.
|
|
*
|
|
* Si existe el loader global de custom.js,
|
|
* lo mostramos después de validar/serializar
|
|
* y dejamos continuar el click/postback normal.
|
|
*/
|
|
if (
|
|
typeof window.loaderinit === 'function'
|
|
) {
|
|
window.loaderinit();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
);
|
|
}
|
|
|
|
/*
|
|
* El control genérico puede terminar de crear su input real
|
|
* durante el load de Microsoft Ajax. Esperamos un ciclo para
|
|
* sincronizar el resumen sin interferir con su inicialización.
|
|
*/
|
|
window.setTimeout(function () {
|
|
observarDropzone(root);
|
|
actualizarResumenSeleccion(root);
|
|
|
|
var archivos = obtenerArchivos(root);
|
|
|
|
if (!archivos || archivos.length === 0) {
|
|
mostrarEstadoListado(
|
|
root,
|
|
'Seleccione archivos para continuar.'
|
|
);
|
|
}
|
|
}, 0);
|
|
}
|
|
|
|
function inicializarTodos() {
|
|
var controles = document.querySelectorAll(
|
|
'[data-sig-carga-masiva]'
|
|
);
|
|
var indice;
|
|
|
|
for (
|
|
indice = 0;
|
|
indice < controles.length;
|
|
indice++
|
|
) {
|
|
inicializar(controles[indice]);
|
|
}
|
|
}
|
|
|
|
if (window.Sys && window.Sys.Application) {
|
|
window.Sys.Application.add_load(
|
|
inicializarTodos
|
|
);
|
|
}
|
|
else if (document.readyState === 'loading') {
|
|
document.addEventListener(
|
|
'DOMContentLoaded',
|
|
inicializarTodos
|
|
);
|
|
}
|
|
else {
|
|
inicializarTodos();
|
|
}
|
|
|
|
window.SIGDocumentosEtapaCargaMasiva = {
|
|
inicializar: inicializarTodos,
|
|
enlistar: renderizar
|
|
};
|
|
|
|
}(window, document));
|