mirror of
https://github.com/cheveguerra/Colaborando.git
synced 2026-08-19 00:46:37 +00:00
- Resumen de activos en la esquina inferior izq del resumen
- Correccion en la habilidad de reordenamiento - Se agregaron los activos, penalizacin y potencial al reordenamiento
This commit is contained in:
@@ -443,9 +443,6 @@ function llenaProyectoGde(proyectoNum) {
|
|||||||
$('#activoReqProyectoCant2').text(proyectos[proyectoNum].activoAsignado2)
|
$('#activoReqProyectoCant2').text(proyectos[proyectoNum].activoAsignado2)
|
||||||
$('#activoReqProyectoCant3').text(proyectos[proyectoNum].activoAsignado3)
|
$('#activoReqProyectoCant3').text(proyectos[proyectoNum].activoAsignado3)
|
||||||
$('#mantoGde').text('MANTENIMIENTO ' + proyectos[proyectoNum].mantenimiento)
|
$('#mantoGde').text('MANTENIMIENTO ' + proyectos[proyectoNum].mantenimiento)
|
||||||
|
|
||||||
// Quitamos el proyecto actual del arreglo siguientesProyectos.
|
|
||||||
siguientesProyectos.splice(0, 1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -972,6 +969,15 @@ function redibujarTablero() {
|
|||||||
// Prioridad 3: Si no hay ninguno 'En proceso', tomar el primero de la cola 'En siguientes'.
|
// Prioridad 3: Si no hay ninguno 'En proceso', tomar el primero de la cola 'En siguientes'.
|
||||||
if (!nuevoProyectoGde) {
|
if (!nuevoProyectoGde) {
|
||||||
nuevoProyectoGde = proyectos.find((p) => p.estatus === 'En siguientes')
|
nuevoProyectoGde = proyectos.find((p) => p.estatus === 'En siguientes')
|
||||||
|
if (nuevoProyectoGde) {
|
||||||
|
let index = siguientesProyectos.findIndex(
|
||||||
|
(p) => p.id === nuevoProyectoGde.id
|
||||||
|
)
|
||||||
|
if (index !== -1) {
|
||||||
|
siguientesProyectos.splice(index, 1)
|
||||||
|
sincronizarColaSiguientes()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Limpiar todos los slots de proyectos chicos.
|
// 2. Limpiar todos los slots de proyectos chicos.
|
||||||
@@ -1980,7 +1986,7 @@ $('#accionHabilidadEspecial').click(function () {
|
|||||||
guardaSesion()
|
guardaSesion()
|
||||||
}
|
}
|
||||||
} else if (accionQuincenal === 'Ordenar los próximos 5 proyectos') {
|
} else if (accionQuincenal === 'Ordenar los próximos 5 proyectos') {
|
||||||
abrirDialogoOrdenarProyectos(elArreglo, quincenaActual);
|
abrirDialogoOrdenarProyectos(elArreglo, quincenaActual)
|
||||||
} else if (accionQuincenal === 'Omitir un mantenimiento') {
|
} else if (accionQuincenal === 'Omitir un mantenimiento') {
|
||||||
// Actualizamos lastUsed
|
// Actualizamos lastUsed
|
||||||
setArrayValue(elArreglo, 'accionEspecialLastUsed', quincenaActual)
|
setArrayValue(elArreglo, 'accionEspecialLastUsed', quincenaActual)
|
||||||
@@ -3373,6 +3379,8 @@ function continuamos() {
|
|||||||
obtenerProyectosPendientes()
|
obtenerProyectosPendientes()
|
||||||
if (siguientesProyectos.length > 0) {
|
if (siguientesProyectos.length > 0) {
|
||||||
llenaProyectoGde(siguientesProyectos[0].id)
|
llenaProyectoGde(siguientesProyectos[0].id)
|
||||||
|
siguientesProyectos.splice(0, 1)
|
||||||
|
sincronizarColaSiguientes()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// JUEGO CARGADO
|
// JUEGO CARGADO
|
||||||
@@ -3431,7 +3439,17 @@ function continuamos() {
|
|||||||
|
|
||||||
// 4. Reconstruir la cola de 'siguientesProyectos'.
|
// 4. Reconstruir la cola de 'siguientesProyectos'.
|
||||||
// Primero, tomar los que ya estaban 'En siguientes' del estado guardado.
|
// Primero, tomar los que ya estaban 'En siguientes' del estado guardado.
|
||||||
siguientesProyectos = proyectos.filter((p) => p.estatus === 'En siguientes')
|
let tempSiguientes = proyectos.filter((p) => p.estatus === 'En siguientes')
|
||||||
|
if (arregloGeneral.siguientesProyectosIds) {
|
||||||
|
tempSiguientes.sort((a, b) => {
|
||||||
|
let idxA = arregloGeneral.siguientesProyectosIds.indexOf(a.id)
|
||||||
|
let idxB = arregloGeneral.siguientesProyectosIds.indexOf(b.id)
|
||||||
|
if (idxA === -1) idxA = 999
|
||||||
|
if (idxB === -1) idxB = 999
|
||||||
|
return idxA - idxB
|
||||||
|
})
|
||||||
|
}
|
||||||
|
siguientesProyectos = tempSiguientes
|
||||||
|
|
||||||
// Luego, completar la cola con proyectos 'Pendiente' si es necesario.
|
// Luego, completar la cola con proyectos 'Pendiente' si es necesario.
|
||||||
const proyectosPendientes = proyectos.filter(
|
const proyectosPendientes = proyectos.filter(
|
||||||
@@ -3455,6 +3473,7 @@ function continuamos() {
|
|||||||
siguientesProyectos.push(proyectoElegido)
|
siguientesProyectos.push(proyectoElegido)
|
||||||
proyectosDisponibles.splice(randomIndex, 1)
|
proyectosDisponibles.splice(randomIndex, 1)
|
||||||
}
|
}
|
||||||
|
sincronizarColaSiguientes()
|
||||||
|
|
||||||
// 5. Llenar el proyecto grande.
|
// 5. Llenar el proyecto grande.
|
||||||
if (proyectoGde) {
|
if (proyectoGde) {
|
||||||
@@ -3462,6 +3481,8 @@ function continuamos() {
|
|||||||
} else if (siguientesProyectos.length > 0) {
|
} else if (siguientesProyectos.length > 0) {
|
||||||
// Si no había ningún proyecto en el tablero, tomar el primero de la cola.
|
// Si no había ningún proyecto en el tablero, tomar el primero de la cola.
|
||||||
llenaProyectoGde(siguientesProyectos[0].id)
|
llenaProyectoGde(siguientesProyectos[0].id)
|
||||||
|
siguientesProyectos.splice(0, 1)
|
||||||
|
sincronizarColaSiguientes()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3696,82 +3717,145 @@ window.confirm = function (message, callback, customWidth) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sincronizarColaSiguientes() {
|
||||||
|
if (typeof arregloGeneral !== 'undefined' && siguientesProyectos) {
|
||||||
|
arregloGeneral.siguientesProyectosIds = siguientesProyectos.map((p) => p.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function abrirDialogoOrdenarProyectos(elArreglo, quincenaActual) {
|
function abrirDialogoOrdenarProyectos(elArreglo, quincenaActual) {
|
||||||
let proyectosAOrdenar = siguientesProyectos.slice(0, 5);
|
let proyectosAOrdenar = siguientesProyectos.slice(0, 5)
|
||||||
let proyectosRestantes = siguientesProyectos.slice(5);
|
let proyectosRestantes = siguientesProyectos.slice(5)
|
||||||
|
|
||||||
let container = $('<div></div>');
|
let container = $('<div></div>')
|
||||||
container.append('<p style="margin-bottom: 15px; font-size: 14px;">Arrastra los proyectos para ordenar la prioridad en la que aparecerán:</p>');
|
container.append(
|
||||||
|
'<p style="margin-bottom: 15px; font-size: 14px;">Arrastra los proyectos para ordenar la prioridad en la que aparecerán:</p>'
|
||||||
|
)
|
||||||
|
|
||||||
|
let list = $(
|
||||||
|
'<ul id="sortable-proyectos" style="list-style-type: none; padding: 0; margin: 0;"></ul>'
|
||||||
|
)
|
||||||
|
const claseMapa = {
|
||||||
|
amarillo: 'actPersonalCalificado',
|
||||||
|
naranjas: 'actAnalistas',
|
||||||
|
verdes: 'actFlujoDeEfectivo',
|
||||||
|
azules: 'actTransporteYMaquinaria',
|
||||||
|
rojos: 'actTecnologia',
|
||||||
|
morados: 'actCreditoEInversion',
|
||||||
|
}
|
||||||
|
const colores = [
|
||||||
|
'amarillo',
|
||||||
|
'naranjas',
|
||||||
|
'verdes',
|
||||||
|
'azules',
|
||||||
|
'rojos',
|
||||||
|
'morados',
|
||||||
|
]
|
||||||
|
|
||||||
let list = $('<ul id="sortable-proyectos" style="list-style-type: none; padding: 0; margin: 0;"></ul>');
|
|
||||||
proyectosAOrdenar.forEach((p, idx) => {
|
proyectosAOrdenar.forEach((p, idx) => {
|
||||||
|
let activosReqHtml = ''
|
||||||
|
colores.forEach((color) => {
|
||||||
|
const valor = p[color]
|
||||||
|
if (valor !== null && valor > 0) {
|
||||||
|
const claseActivo = claseMapa[color]
|
||||||
|
const textColor =
|
||||||
|
color === 'amarillo' || color === 'naranjas' || color === 'verdes'
|
||||||
|
? 'black'
|
||||||
|
: 'white'
|
||||||
|
activosReqHtml += `<span class="${claseActivo}" style="padding: 2px 6px; border-radius: 3px; color: ${textColor}; font-weight: bold; font-size: 11px; margin-right: 4px;">${valor}</span>`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const penVal = parseInt(p.penalizacion) || 0
|
||||||
|
const penalizacionFormateada =
|
||||||
|
penVal > 0 ? '$' + new Intl.NumberFormat('es-MX').format(penVal) : 'N/A'
|
||||||
|
|
||||||
let item = $(`
|
let item = $(`
|
||||||
<li class="ui-state-default" data-id="${p.id}" style="margin: 8px 0; padding: 10px; border: 2px solid gray; border-radius: 4px; background-color: #f9f9f9; cursor: grab; display: flex; justify-content: space-between; align-items: center; font-size: 14px;">
|
<li class="ui-state-default" data-id="${p.id}" style="margin: 8px 0; padding: 10px; border: 2px solid gray; border-radius: 4px; background-color: #f9f9f9; cursor: grab; display: flex; flex-direction: column; gap: 6px; font-size: 14px;">
|
||||||
<span style="font-weight: bold;">${idx + 1}. ${p.nombreProyecto}</span>
|
<div style="display: flex; justify-content: space-between; align-items: center; width: 100%;">
|
||||||
<span style="font-size: 11px; background-color: #eee; padding: 2px 6px; border-radius: 3px; color: #555;">${p.departamento}</span>
|
<span style="font-weight: bold;">${idx + 1}. ${p.nombreProyecto}</span>
|
||||||
|
<span style="font-size: 11px; background-color: #eee; padding: 2px 6px; border-radius: 3px; color: #555;">${p.departamento}</span>
|
||||||
|
</div>
|
||||||
|
<div style="display: flex; justify-content: space-between; align-items: center; width: 100%; font-size: 12px; color: #666;">
|
||||||
|
<div style="display: flex; gap: 4px;">
|
||||||
|
${activosReqHtml}
|
||||||
|
</div>
|
||||||
|
<div style="text-align: left; line-height: 1.4;">
|
||||||
|
Potencial: <b>${p.potencial || 'N/A'}</b><br>
|
||||||
|
Penalización: <b>${penalizacionFormateada}</b>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</li>
|
</li>
|
||||||
`);
|
`)
|
||||||
list.append(item);
|
list.append(item)
|
||||||
});
|
})
|
||||||
container.append(list);
|
container.append(list)
|
||||||
|
|
||||||
container.dialog({
|
container.dialog({
|
||||||
modal: true,
|
modal: true,
|
||||||
title: 'Ordenar Próximos 5 Proyectos',
|
title: 'Ordenar Próximos 5 Proyectos',
|
||||||
width: 500,
|
width: 500,
|
||||||
open: function() {
|
open: function () {
|
||||||
list.sortable({
|
list.sortable({
|
||||||
placeholder: "ui-state-highlight",
|
placeholder: 'ui-state-highlight',
|
||||||
forcePlaceholderSize: true,
|
forcePlaceholderSize: true,
|
||||||
update: function(event, ui) {
|
update: function (event, ui) {
|
||||||
list.find('li').each(function(index) {
|
list.find('li').each(function (index) {
|
||||||
let nombre = $(this).find('span').first().text();
|
let nombre = $(this).find('span').first().text()
|
||||||
nombre = nombre.replace(/^\d+\.\s*/, '');
|
nombre = nombre.replace(/^\d+\.\s*/, '')
|
||||||
$(this).find('span').first().text((index + 1) + '. ' + nombre);
|
$(this)
|
||||||
});
|
.find('span')
|
||||||
}
|
.first()
|
||||||
});
|
.text(index + 1 + '. ' + nombre)
|
||||||
list.disableSelection();
|
})
|
||||||
$('<style id="sortable-style">.ui-state-highlight { height: 40px; background-color: #ffffcc; border: 2px dashed #999; margin: 8px 0; border-radius: 4px; }</style>').appendTo('head');
|
},
|
||||||
|
})
|
||||||
|
list.disableSelection()
|
||||||
|
$(
|
||||||
|
'<style id="sortable-style">.ui-state-highlight { height: 40px; background-color: #ffffcc; border: 2px dashed #999; margin: 8px 0; border-radius: 4px; }</style>'
|
||||||
|
).appendTo('head')
|
||||||
},
|
},
|
||||||
close: function() {
|
close: function () {
|
||||||
$('#sortable-style').remove();
|
$('#sortable-style').remove()
|
||||||
$(this).dialog('destroy').remove();
|
$(this).dialog('destroy').remove()
|
||||||
},
|
},
|
||||||
buttons: {
|
buttons: {
|
||||||
"Guardar Orden": function() {
|
'Guardar Orden': function () {
|
||||||
let nuevoOrdenIds = [];
|
let nuevoOrdenIds = []
|
||||||
list.find('li').each(function() {
|
list.find('li').each(function () {
|
||||||
nuevoOrdenIds.push(parseInt($(this).data('id')));
|
nuevoOrdenIds.push(parseInt($(this).data('id')))
|
||||||
});
|
})
|
||||||
|
|
||||||
let nuevosSiguientes = [];
|
let nuevosSiguientes = []
|
||||||
nuevoOrdenIds.forEach(id => {
|
nuevoOrdenIds.forEach((id) => {
|
||||||
let proj = proyectos.find(p => p.id === id);
|
let proj = proyectos.find((p) => p.id === id)
|
||||||
if (proj) nuevosSiguientes.push(proj);
|
if (proj) nuevosSiguientes.push(proj)
|
||||||
});
|
})
|
||||||
|
|
||||||
nuevosSiguientes = nuevosSiguientes.concat(proyectosRestantes);
|
nuevosSiguientes = nuevosSiguientes.concat(proyectosRestantes)
|
||||||
siguientesProyectos = nuevosSiguientes;
|
siguientesProyectos = nuevosSiguientes
|
||||||
|
sincronizarColaSiguientes()
|
||||||
|
|
||||||
proyectos.forEach(p => {
|
proyectos.forEach((p) => {
|
||||||
if (p.estatus === 'En siguientes') p.estatus = 'Pendiente';
|
if (p.estatus === 'En siguientes') p.estatus = 'Pendiente'
|
||||||
});
|
})
|
||||||
siguientesProyectos.forEach(p => {
|
siguientesProyectos.forEach((p) => {
|
||||||
let proj = proyectos.find(pr => pr.id === p.id);
|
let proj = proyectos.find((pr) => pr.id === p.id)
|
||||||
if (proj) proj.estatus = 'En siguientes';
|
if (proj) proj.estatus = 'En siguientes'
|
||||||
});
|
})
|
||||||
|
|
||||||
setArrayValue(elArreglo, 'accionEspecialLastUsed', quincenaActual);
|
setArrayValue(elArreglo, 'accionEspecialLastUsed', quincenaActual)
|
||||||
var audio = new Audio('./Microwave_bell.wav');
|
var audio = new Audio('./Microwave_bell.wav')
|
||||||
audio.play();
|
audio.play()
|
||||||
window.alert('¡Orden de proyectos actualizado con éxito!');
|
window.alert('¡Orden de proyectos actualizado con éxito!')
|
||||||
|
|
||||||
if (typeof guardaSesion === 'function') guardaSesion();
|
if (typeof guardaSesion === 'function') guardaSesion()
|
||||||
$(this).dialog('close');
|
$(this).dialog('close')
|
||||||
},
|
},
|
||||||
"Cancelar": function() { $(this).dialog('close'); }
|
Cancelar: function () {
|
||||||
}
|
$(this).dialog('close')
|
||||||
});
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
// </script>
|
// </script>
|
||||||
|
|||||||
@@ -164,6 +164,8 @@ function guardarDatosEnServidor() {
|
|||||||
.catch((error) => console.error('Error:', error))
|
.catch((error) => console.error('Error:', error))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const guardaSesion = guardarDatosEnServidor;
|
||||||
|
|
||||||
// Cargar datos al iniciar la página
|
// Cargar datos al iniciar la página
|
||||||
document.addEventListener('DOMContentLoaded', cargarDatosDesdeServidor)
|
document.addEventListener('DOMContentLoaded', cargarDatosDesdeServidor)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
# Plan de Implementación: Contabilización de Activos (Producidos, Recuperados y Perdidos)
|
||||||
|
|
||||||
|
Este documento detalla la lógica matemática y los pasos técnicos necesarios para implementar la visualización y el cálculo de estadísticas de activos en la pantalla de resumen de la aplicación **Colaborando**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Resumen del Enfoque
|
||||||
|
|
||||||
|
Para evitar desincronizaciones de datos y la necesidad de alterar la base de datos o los esquemas JSON de persistencia de sesión, utilizaremos un **cálculo dinámico en el cliente** (JavaScript). Toda la información necesaria ya existe dentro del arreglo global `proyectos` y el objeto `arregloGeneral`, que se guardan y cargan automáticamente con la sesión.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧮 Lógica de Cálculo de Métricas
|
||||||
|
|
||||||
|
Para cada tipo de activo (p. ej., *Personal Calificado*, *Analistas*, *Flujo de Efectivo*, etc.), los valores se calculan recorriendo el arreglo global `proyectos` buscando proyectos con `estatus === 'Completado'`:
|
||||||
|
|
||||||
|
### 1. Activos Producidos (Total)
|
||||||
|
* **Definición:** Activos que fueron creados/asignados para completar los proyectos finalizados.
|
||||||
|
* **Lógica:** Suma de los requerimientos originales de todos los proyectos completados.
|
||||||
|
* **Fórmula:**
|
||||||
|
$$\text{Producidos}(c) = \sum_{p \in \text{Completados}} p[c]$$
|
||||||
|
*(Donde $c$ es el campo de requerimiento del activo, como `amarillo`, `naranjas`, etc.)*
|
||||||
|
|
||||||
|
### 2. Activos Recuperados
|
||||||
|
* **Definición:** Activos que se arrastraron exitosamente desde los proyectos terminados hacia los departamentos (lo cual resta del proyecto y suma al departamento).
|
||||||
|
* **Lógica:** La diferencia entre el requerimiento original del proyecto completado y su valor de asignación actual (que disminuye al ser arrastrado).
|
||||||
|
* **Fórmula:**
|
||||||
|
$$\text{Recuperados}(c) = \sum_{p \in \text{Completados}} (p[c] - p['activoAsignado' + (i+1)])$$
|
||||||
|
*(Donde $i$ es el índice del slot correspondiente al tipo de activo en el proyecto)*
|
||||||
|
|
||||||
|
### 3. Activos Perdidos
|
||||||
|
* **Definición:** Activos que no se pudieron recuperar de proyectos finalizados por falta de recursos o de espacio antes de cambiar de periodo.
|
||||||
|
* **Lógica:** Suma de los activos remanentes (`activoAsignadoX`) en proyectos completados que pertenecen a trimestres anteriores (ya que en el trimestre actual todavía es posible recuperarlos).
|
||||||
|
* **Fórmula:**
|
||||||
|
$$\text{Perdidos}(c) = \sum_{p \in \text{Completados}, p.\text{trimestreCompletado} < \text{trimestreActual}} p['activoAsignado' + (i+1)]$$
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛠️ Archivos y Cambios Requeridos
|
||||||
|
|
||||||
|
Todo el cambio se centraliza en el archivo **[resumen.php](file:///C:/CHV/ludotecaLocal/Colaborando/resumen.php)**.
|
||||||
|
|
||||||
|
### Paso 1: Interfaz de Usuario (HTML)
|
||||||
|
Modificar la estructura de la tabla `#tablaActivos` (líneas ~308-348) para cambiar sus encabezados a:
|
||||||
|
1. **Activo**
|
||||||
|
2. **Producidos**
|
||||||
|
3. **Recuperados**
|
||||||
|
4. **Perdidos**
|
||||||
|
|
||||||
|
Asignar identificadores de celda descriptivos para inyectar los datos, por ejemplo:
|
||||||
|
* Para Personal Calificado: `producidosPersonalCalificado`, `recuperadosPersonalCalificado`, `perdidosPersonalCalificado`.
|
||||||
|
* Para Analistas: `producidosAnalistas`, `recuperadosAnalistas`, `perdidosAnalistas`.
|
||||||
|
* *(Repetir para los 6 tipos de activos)*.
|
||||||
|
|
||||||
|
### Paso 2: Motor de Cálculo (JavaScript)
|
||||||
|
Dentro de la función `actualizarResumenUI()` (línea ~720):
|
||||||
|
1. **Inicializar:** Crear un objeto local para llevar las cuentas por tipo de activo e indicador (ej. `const stats = { PersonalCalificado: { producidos: 0, recuperados: 0, perdidos: 0 }, ... }`).
|
||||||
|
2. **Procesar:** Iterar sobre el arreglo `proyectos` y clasificar según las fórmulas explicadas.
|
||||||
|
3. **Renderizar:** Actualizar el contenido de las celdas del HTML utilizando jQuery (ej. `$('#producidosPersonalCalificado').text(stats.PersonalCalificado.producidos)`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Beneficios de esta Solución
|
||||||
|
* **Integridad de datos:** No requiere modificar la estructura JSON del archivo de datos (`datos.json` / `cheve.json`).
|
||||||
|
* **Sincronización total:** Si el usuario recarga la página o arrastra activos, la tabla se vuelve a calcular en tiempo real reflejando el estado real del juego.
|
||||||
|
* **Mantenibilidad:** El código queda autocontenido en la vista de resumen.
|
||||||
+188
@@ -391,6 +391,57 @@
|
|||||||
<!-- Contenido se llenará con JS -->
|
<!-- Contenido se llenará con JS -->
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="card">
|
||||||
|
<h2>CONTABILIZACIÓN DE ACTIVOS</h2>
|
||||||
|
<table id="tablaConteoActivos" class="summary-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Activo</th>
|
||||||
|
<th>Producidos</th>
|
||||||
|
<th>Recuperados</th>
|
||||||
|
<th>Perdidos</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="actPersonalCalificado" style="color:black!important; font-weight: bold; text-align: left;">Personal calificado</td>
|
||||||
|
<td id="conteoProducidosPersonalCalificado">0</td>
|
||||||
|
<td id="conteoRecuperadosPersonalCalificado">0</td>
|
||||||
|
<td id="conteoPerdidosPersonalCalificado">0</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="actAnalistas" style="color:black!important; font-weight: bold; text-align: left;">Analistas</td>
|
||||||
|
<td id="conteoProducidosAnalistas">0</td>
|
||||||
|
<td id="conteoRecuperadosAnalistas">0</td>
|
||||||
|
<td id="conteoPerdidosAnalistas">0</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="actFlujoDeEfectivo" style="color:black!important; font-weight: bold; text-align: left;">Flujo de efectivo</td>
|
||||||
|
<td id="conteoProducidosFlujoDeEfectivo">0</td>
|
||||||
|
<td id="conteoRecuperadosFlujoDeEfectivo">0</td>
|
||||||
|
<td id="conteoPerdidosFlujoDeEfectivo">0</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="actCreditoEInversion" style="font-weight: bold; text-align: left;">Crédito e Inversión</td>
|
||||||
|
<td id="conteoProducidosCreditoEInversion">0</td>
|
||||||
|
<td id="conteoRecuperadosCreditoEInversion">0</td>
|
||||||
|
<td id="conteoPerdidosCreditoEInversion">0</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="actTecnologia" style="font-weight: bold; text-align: left;">Tecnología</td>
|
||||||
|
<td id="conteoProducidosTecnologia">0</td>
|
||||||
|
<td id="conteoRecuperadosTecnologia">0</td>
|
||||||
|
<td id="conteoPerdidosTecnologia">0</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="actTransporteYMaquinaria" style="font-weight: bold; text-align: left;">Transporte y Maquinaria</td>
|
||||||
|
<td id="conteoProducidosTransporteYMaquinaria">0</td>
|
||||||
|
<td id="conteoRecuperadosTransporteYMaquinaria">0</td>
|
||||||
|
<td id="conteoPerdidosTransporteYMaquinaria">0</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- =================================================================
|
<!-- =================================================================
|
||||||
@@ -426,6 +477,11 @@
|
|||||||
<div style="vertical-align:middle; display:inline-block; font-weight:bold; font-size:16px;" id="capitalCh" class="draggable recurso-item">0</div>
|
<div style="vertical-align:middle; display:inline-block; font-weight:bold; font-size:16px;" id="capitalCh" class="draggable recurso-item">0</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="text-align:center; font-size:11px; color:#c9302c; font-weight:bold; height:15px; padding: 0;" class="beneficioTiempoCh"></td>
|
||||||
|
<td style="text-align:center; font-size:11px; color:#c9302c; font-weight:bold; height:15px; padding: 0;" class="beneficioPersonalCh"></td>
|
||||||
|
<td style="text-align:center; font-size:11px; color:#c9302c; font-weight:bold; height:15px; padding: 0;" class="beneficioCapitalCh"></td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -465,6 +521,11 @@
|
|||||||
<div style="vertical-align:middle; display:inline-block; font-weight:bold; font-size:16px;" id="capitalCh" class="draggable recurso-item">0</div>
|
<div style="vertical-align:middle; display:inline-block; font-weight:bold; font-size:16px;" id="capitalCh" class="draggable recurso-item">0</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="text-align:center; font-size:11px; color:#c9302c; font-weight:bold; height:15px; padding: 0;" class="beneficioTiempoCh"></td>
|
||||||
|
<td style="text-align:center; font-size:11px; color:#c9302c; font-weight:bold; height:15px; padding: 0;" class="beneficioPersonalCh"></td>
|
||||||
|
<td style="text-align:center; font-size:11px; color:#c9302c; font-weight:bold; height:15px; padding: 0;" class="beneficioCapitalCh"></td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -504,6 +565,11 @@
|
|||||||
<div style="vertical-align:middle; display:inline-block; font-weight:bold; font-size:16px;" id="capitalCh" class="draggable recurso-item">0</div>
|
<div style="vertical-align:middle; display:inline-block; font-weight:bold; font-size:16px;" id="capitalCh" class="draggable recurso-item">0</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="text-align:center; font-size:11px; color:#c9302c; font-weight:bold; height:15px; padding: 0;" class="beneficioTiempoCh"></td>
|
||||||
|
<td style="text-align:center; font-size:11px; color:#c9302c; font-weight:bold; height:15px; padding: 0;" class="beneficioPersonalCh"></td>
|
||||||
|
<td style="text-align:center; font-size:11px; color:#c9302c; font-weight:bold; height:15px; padding: 0;" class="beneficioCapitalCh"></td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -543,6 +609,11 @@
|
|||||||
<div style="vertical-align:middle; display:inline-block; font-weight:bold; font-size:16px;" id="capitalCh" class="draggable recurso-item">0</div>
|
<div style="vertical-align:middle; display:inline-block; font-weight:bold; font-size:16px;" id="capitalCh" class="draggable recurso-item">0</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="text-align:center; font-size:11px; color:#c9302c; font-weight:bold; height:15px; padding: 0;" class="beneficioTiempoCh"></td>
|
||||||
|
<td style="text-align:center; font-size:11px; color:#c9302c; font-weight:bold; height:15px; padding: 0;" class="beneficioPersonalCh"></td>
|
||||||
|
<td style="text-align:center; font-size:11px; color:#c9302c; font-weight:bold; height:15px; padding: 0;" class="beneficioCapitalCh"></td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -582,6 +653,11 @@
|
|||||||
<div style="vertical-align:middle; display:inline-block; font-weight:bold; font-size:16px;" id="capitalCh" class="draggable recurso-item">0</div>
|
<div style="vertical-align:middle; display:inline-block; font-weight:bold; font-size:16px;" id="capitalCh" class="draggable recurso-item">0</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="text-align:center; font-size:11px; color:#c9302c; font-weight:bold; height:15px; padding: 0;" class="beneficioTiempoCh"></td>
|
||||||
|
<td style="text-align:center; font-size:11px; color:#c9302c; font-weight:bold; height:15px; padding: 0;" class="beneficioPersonalCh"></td>
|
||||||
|
<td style="text-align:center; font-size:11px; color:#c9302c; font-weight:bold; height:15px; padding: 0;" class="beneficioCapitalCh"></td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -621,6 +697,11 @@
|
|||||||
<div style="vertical-align:middle; display:inline-block; font-weight:bold; font-size:16px;" id="capitalCh" class="draggable recurso-item">0</div>
|
<div style="vertical-align:middle; display:inline-block; font-weight:bold; font-size:16px;" id="capitalCh" class="draggable recurso-item">0</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="text-align:center; font-size:11px; color:#c9302c; font-weight:bold; height:15px; padding: 0;" class="beneficioTiempoCh"></td>
|
||||||
|
<td style="text-align:center; font-size:11px; color:#c9302c; font-weight:bold; height:15px; padding: 0;" class="beneficioPersonalCh"></td>
|
||||||
|
<td style="text-align:center; font-size:11px; color:#c9302c; font-weight:bold; height:15px; padding: 0;" class="beneficioCapitalCh"></td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -706,6 +787,32 @@
|
|||||||
deptoCard.find('#activoCh1').text(findArrayValue(deptoArr, 'activo1'));
|
deptoCard.find('#activoCh1').text(findArrayValue(deptoArr, 'activo1'));
|
||||||
deptoCard.find('#activoCh2').text(findArrayValue(deptoArr, 'activo2'));
|
deptoCard.find('#activoCh2').text(findArrayValue(deptoArr, 'activo2'));
|
||||||
|
|
||||||
|
// Actualizar beneficios de habilidades acreditadas (-1 T, -1 P, -1 C)
|
||||||
|
const habTiempo = findArrayValue(deptoArr, 'habilidadTiempo');
|
||||||
|
const habPersonal = findArrayValue(deptoArr, 'habilidadPersonal');
|
||||||
|
const habCapital = findArrayValue(deptoArr, 'habilidadCapital');
|
||||||
|
|
||||||
|
let txtTiempo = '';
|
||||||
|
let txtPersonal = '';
|
||||||
|
let txtCapital = '';
|
||||||
|
|
||||||
|
if (habTiempo && habTiempo !== 0) {
|
||||||
|
const ben = findArrayValue(arreglosCapacitaciones[habTiempo], 'beneficio');
|
||||||
|
txtTiempo = `${ben} T`;
|
||||||
|
}
|
||||||
|
if (habPersonal && habPersonal !== 0) {
|
||||||
|
const ben = findArrayValue(arreglosCapacitaciones[habPersonal], 'beneficio');
|
||||||
|
txtPersonal = `${ben} P`;
|
||||||
|
}
|
||||||
|
if (habCapital && habCapital !== 0) {
|
||||||
|
const ben = findArrayValue(arreglosCapacitaciones[habCapital], 'beneficio');
|
||||||
|
txtCapital = `${ben} C`;
|
||||||
|
}
|
||||||
|
|
||||||
|
deptoCard.find('.beneficioTiempoCh').text(txtTiempo);
|
||||||
|
deptoCard.find('.beneficioPersonalCh').text(txtPersonal);
|
||||||
|
deptoCard.find('.beneficioCapitalCh').text(txtCapital);
|
||||||
|
|
||||||
// Mostrar/Ocultar Habilidad Especial si ya se acreditó
|
// Mostrar/Ocultar Habilidad Especial si ya se acreditó
|
||||||
const accionEspecial = findArrayValue(deptoArr, 'accionEspecialQuincenal');
|
const accionEspecial = findArrayValue(deptoArr, 'accionEspecialQuincenal');
|
||||||
const rowHE = deptoCard.find('.fila-habilidad-especial');
|
const rowHE = deptoCard.find('.fila-habilidad-especial');
|
||||||
@@ -799,6 +906,87 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// --- 2.5 Contabilización de Activos (Producidos, Recuperados y Perdidos) ---
|
||||||
|
const statsActivos = {
|
||||||
|
PersonalCalificado: {
|
||||||
|
producidos: 0,
|
||||||
|
recuperados: 0,
|
||||||
|
perdidos: 0
|
||||||
|
},
|
||||||
|
Analistas: {
|
||||||
|
producidos: 0,
|
||||||
|
recuperados: 0,
|
||||||
|
perdidos: 0
|
||||||
|
},
|
||||||
|
FlujoDeEfectivo: {
|
||||||
|
producidos: 0,
|
||||||
|
recuperados: 0,
|
||||||
|
perdidos: 0
|
||||||
|
},
|
||||||
|
CreditoEInversion: {
|
||||||
|
producidos: 0,
|
||||||
|
recuperados: 0,
|
||||||
|
perdidos: 0
|
||||||
|
},
|
||||||
|
Tecnologia: {
|
||||||
|
producidos: 0,
|
||||||
|
recuperados: 0,
|
||||||
|
perdidos: 0
|
||||||
|
},
|
||||||
|
TransporteYMaquinaria: {
|
||||||
|
producidos: 0,
|
||||||
|
recuperados: 0,
|
||||||
|
perdidos: 0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapaColoresActivos = {
|
||||||
|
amarillo: 'PersonalCalificado',
|
||||||
|
naranjas: 'Analistas',
|
||||||
|
verdes: 'FlujoDeEfectivo',
|
||||||
|
azules: 'TransporteYMaquinaria',
|
||||||
|
rojos: 'Tecnologia',
|
||||||
|
morados: 'CreditoEInversion'
|
||||||
|
};
|
||||||
|
const listaColores = ['amarillo', 'naranjas', 'verdes', 'azules', 'rojos', 'morados'];
|
||||||
|
|
||||||
|
proyectos.forEach(p => {
|
||||||
|
if (p.estatus === 'Completado') {
|
||||||
|
const coloresConValores = listaColores
|
||||||
|
.filter(color => p[color] !== null && p[color] > 0)
|
||||||
|
.map(color => ({
|
||||||
|
color,
|
||||||
|
valor: p[color]
|
||||||
|
}));
|
||||||
|
|
||||||
|
coloresConValores.forEach((item, idx) => {
|
||||||
|
const tipoActivo = mapaColoresActivos[item.color];
|
||||||
|
const reqOriginal = item.valor;
|
||||||
|
const asignadoActual = parseInt(p['activoAsignado' + (idx + 1)]) || 0;
|
||||||
|
|
||||||
|
// Producidos
|
||||||
|
statsActivos[tipoActivo].producidos += reqOriginal;
|
||||||
|
|
||||||
|
// Recuperados
|
||||||
|
const recuperados = reqOriginal - asignadoActual;
|
||||||
|
statsActivos[tipoActivo].recuperados += (recuperados > 0 ? recuperados : 0);
|
||||||
|
|
||||||
|
// Perdidos (sólo si pertenece a un trimestre anterior)
|
||||||
|
if (p.trimestreCompletado < trimestreActual) {
|
||||||
|
statsActivos[tipoActivo].perdidos += asignadoActual;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Inyectar datos en la tabla HTML (con prefijo conteo)
|
||||||
|
const tiposActivos = ['PersonalCalificado', 'Analistas', 'FlujoDeEfectivo', 'CreditoEInversion', 'Tecnologia', 'TransporteYMaquinaria'];
|
||||||
|
tiposActivos.forEach(tipo => {
|
||||||
|
$(`#conteoProducidos${tipo}`).text(statsActivos[tipo].producidos);
|
||||||
|
$(`#conteoRecuperados${tipo}`).text(statsActivos[tipo].recuperados);
|
||||||
|
$(`#conteoPerdidos${tipo}`).text(statsActivos[tipo].perdidos);
|
||||||
|
});
|
||||||
|
|
||||||
$('#resumen-proyectos').html(`
|
$('#resumen-proyectos').html(`
|
||||||
<thead><tr><th></th><th>T1</th><th>T2</th><th>T3</th><th>T4</th></tr></thead>
|
<thead><tr><th></th><th>T1</th><th>T2</th><th>T3</th><th>T4</th></tr></thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|||||||
Reference in New Issue
Block a user