mirror of
https://github.com/cheveguerra/Colaborando.git
synced 2026-08-19 00:46:37 +00:00
Commit inicial
This commit is contained in:
+870
@@ -0,0 +1,870 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Resumen de Colaborando</title>
|
||||
<!-- Estilos y scripts base de colaborando2.php -->
|
||||
<link rel="stylesheet" href="js/jquery-ui.min.css">
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=Ubuntu&display=swap');
|
||||
|
||||
body,
|
||||
input,
|
||||
button {
|
||||
font-family: 'Ubuntu', sans-serif;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.draggable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* --- Estilos para la nueva maqueta --- */
|
||||
.main-container {
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.column-left {
|
||||
flex: 1 1 0px;
|
||||
/* 1/5 del ancho */
|
||||
}
|
||||
|
||||
.column-depts {
|
||||
flex: 1 1 0px;
|
||||
/* 1/5 del ancho */
|
||||
}
|
||||
|
||||
.column-completed {
|
||||
flex: 1 1 0px;
|
||||
/* 1/5 del ancho */
|
||||
}
|
||||
|
||||
.column-active {
|
||||
flex: 2 1 0px;
|
||||
/* 2/5 del ancho */
|
||||
}
|
||||
|
||||
.card {
|
||||
border: 2px solid #ccc;
|
||||
border-radius: 5px;
|
||||
padding: 8px;
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
h2 {
|
||||
text-align: center;
|
||||
margin-top: 0;
|
||||
font-size: 1.2em;
|
||||
background-color: gray;
|
||||
color: white;
|
||||
padding: 5px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
/* Estilos para las tablas de resumen */
|
||||
.summary-table {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.summary-table th,
|
||||
.summary-table td {
|
||||
border: 1px solid #ddd;
|
||||
padding: 4px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.summary-table th {
|
||||
background-color: #e9e9e9;
|
||||
}
|
||||
|
||||
/* Estilos para los departamentos en una columna */
|
||||
.departamentos.card {
|
||||
padding: 0;
|
||||
border: solid 3px gray;
|
||||
}
|
||||
|
||||
.departamentos #nombreDeptoCh {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.departamentos td {
|
||||
padding: 2px 5px;
|
||||
}
|
||||
|
||||
/* Estilos para los proyectos (activos y completados) */
|
||||
.project-card {
|
||||
border: 2px solid gray;
|
||||
font-size: 12px;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.project-card.completado {
|
||||
background-color: lightgray;
|
||||
}
|
||||
|
||||
.project-header {
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
padding: 4px;
|
||||
border-bottom: 1px solid gray;
|
||||
}
|
||||
|
||||
.project-body {
|
||||
padding: 5px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.project-assets-req,
|
||||
.project-assets-asig {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 5px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.project-assets-req span,
|
||||
.project-assets-asig span {
|
||||
padding: 4px;
|
||||
color: white;
|
||||
border-radius: 3px;
|
||||
min-width: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.project-footer {
|
||||
background-color: silver;
|
||||
text-align: center;
|
||||
padding: 3px;
|
||||
font-size: 11px;
|
||||
border-top: 1px solid gray;
|
||||
}
|
||||
|
||||
/* Clases de activos (copiadas de colaborando2.php) */
|
||||
.actNinguno {
|
||||
background-color: white;
|
||||
color: black !important;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.actPersonalCalificado {
|
||||
background-color: yellow;
|
||||
color: black !important;
|
||||
}
|
||||
|
||||
.actAnalistas {
|
||||
background-color: orange;
|
||||
color: black !important;
|
||||
}
|
||||
|
||||
.actFlujoDeEfectivo {
|
||||
background-color: limegreen;
|
||||
color: black !important;
|
||||
}
|
||||
|
||||
.actCreditoEInversion {
|
||||
background-color: blueviolet;
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
.actTecnologia {
|
||||
background-color: red;
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
.actTransporteYMaquinaria {
|
||||
background-color: blue;
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
/* Estilo para drag-drop de recuperación */
|
||||
.asset-recover {
|
||||
cursor: grab;
|
||||
}
|
||||
|
||||
.nav-button {
|
||||
display: inline-block;
|
||||
padding: 6px 10px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
color: #fff !important;
|
||||
background-color: #007bff;
|
||||
border-radius: 4px;
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.nav-button:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
</style>
|
||||
<!-- Scripts base -->
|
||||
<script src="js/jquery-3.5.1.min.js"></script>
|
||||
<script src="js/jquery-ui.min.js"></script>
|
||||
<script src="colaborando_arreglos.js?v=<?php echo filemtime('colaborando_arreglos.js'); ?>"></script>
|
||||
<script src="manejoDeSesiones.js?v=<?php echo filemtime('manejoDeSesiones.js'); ?>"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="main-container">
|
||||
|
||||
<!-- =================================================================
|
||||
COLUMNA 1: RESUMEN GENERAL (IZQUIERDA)
|
||||
================================================================== -->
|
||||
<div class="column column-left">
|
||||
<div class="card">
|
||||
<img id="logo" src="img/logoColaborando-tablero.png" style="width:100%">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; padding: 5px 10px;">
|
||||
<div id="nombreSesion" style="font-weight: bold; font-size: 16px; color: #555;"></div>
|
||||
<a href="colaborando2.php?n=<?php echo htmlspecialchars($_GET['n'] ?? $_GET['nombre'] ?? ''); ?>" class="nav-button">Ir al Tablero</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<table style="width:100%; text-align:center; vertical-align: top;">
|
||||
<tr>
|
||||
<td style="width:40%; padding-top: 20px;">
|
||||
<span id="resumenTrimestre" style="font-size:1.5em; font-weight:bold; color: #007bff;">
|
||||
</span>
|
||||
|
||||
<span id="resumenQuincena" style="font-size:1.5em; font-weight:bold; color: #007bff;">
|
||||
</span>
|
||||
</td>
|
||||
<td style="width:60%;">
|
||||
<div id="timer"><span id="time" style="font-size:20px;">2:00</span></div>
|
||||
<div class="button-container">
|
||||
<button id="relojStartPauseButton" onclick="relojToggleTimer()">Iniciar</button>
|
||||
<!-- <button onclick="relojPauseTimer()">Pausar</button> -->
|
||||
<button onclick="relojResumeTimer()">Continuar</button>
|
||||
</div>
|
||||
<input type="range" id="timeRange" min="1" max="3" value="1" step="1" oninput="relojUpdateTime()">
|
||||
<div id="rangeValue" style="font-weight: bold;">2 min</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!-- Hidden elements to keep jsCode.js and other logic working -->
|
||||
<div style="display:none;">
|
||||
<div id="trimestre">
|
||||
<table>
|
||||
<tr>
|
||||
<td id="T1">1</td>
|
||||
<td id="T2">2</td>
|
||||
<td id="T3">3</td>
|
||||
<td id="T4">4</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div id="quincena">
|
||||
<table id="tablaQuincena">
|
||||
<tr>
|
||||
<td><button id="bMenos"></button></td>
|
||||
<td><input id="etQuincena" type="text" value="1"></td>
|
||||
<td><button id="bMas"></button></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<table id="tablaActivos" class="summary-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">ACTIVOS</th>
|
||||
<th>Producción</th>
|
||||
<th>Recuperación</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td colspan="2" class="actPersonalCalificado" style="color:black!important;">Personal calificado</td>
|
||||
<td id="activosPersonalCalificado"></td>
|
||||
<td id="recuperacionPersonalCalificado"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" class="actAnalistas" style="color:black!important;">Analistas</td>
|
||||
<td id="activosAnalistas"></td>
|
||||
<td id="recuperacionAnalistas"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" class="actFlujoDeEfectivo" style="color:black!important;">Flujo de efectivo</td>
|
||||
<td id="activosFlujoDeEfectivo"></td>
|
||||
<td id="recuperacionFlujoDeEfectivo"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" class="actCreditoEInversion">Crédito e Inversión</td>
|
||||
<td id="activosCreditoEInversion"></td>
|
||||
<td id="recuperacionCreditoEInversion"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" class="actTecnologia">Tecnología</td>
|
||||
<td id="activosTecnologia"></td>
|
||||
<td id="recuperacionTecnologia"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" class="actTransporteYMaquinaria">Transporte y Maquinaria</td>
|
||||
<td id="activosTransporteYMaquinaria"></td>
|
||||
<td id="recuperacionTransporteYMaquinaria"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h2>PROGRESIÓN</h2>
|
||||
<!-- Aquí se podría agregar una librería de gráficos para la gráfica -->
|
||||
<div id="grafico-progresion" style="height: 100px; background-color: #f0f0f0; border: 1px solid #ccc;"></div>
|
||||
<table class="summary-table" style="margin-top: 10px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>T1</th>
|
||||
<th>T2</th>
|
||||
<th>T3</th>
|
||||
<th>T4</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Ingreso</td>
|
||||
<td id="ingresoT1">$0</td>
|
||||
<td id="ingresoT2">$0</td>
|
||||
<td id="ingresoT3">$0</td>
|
||||
<td id="ingresoT4">$0</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Acumulado</td>
|
||||
<td id="acumuladoT1">$0</td>
|
||||
<td id="acumuladoT2">$0</td>
|
||||
<td id="acumuladoT3">$0</td>
|
||||
<td id="acumuladoT4">$0</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h2>PROYECTOS</h2>
|
||||
<table id="resumen-proyectos" class="summary-table">
|
||||
<!-- Contenido se llenará con JS -->
|
||||
</table>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h2>INCIDENCIAS</h2>
|
||||
<table id="resumen-incidencias" class="summary-table">
|
||||
<!-- Contenido se llenará con JS -->
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- =================================================================
|
||||
COLUMNA 2: DEPARTAMENTOS
|
||||
================================================================== -->
|
||||
<div class="column column-depts">
|
||||
<h2>DEPARTAMENTOS</h2>
|
||||
<?php
|
||||
$deptos = [
|
||||
["id" => "MarketingYVentas", "nombre" => "MARKETING Y VENTAS", "img" => "depto-marketing.png", "act1_class" => "actPersonalCalificado", "act2_class" => "actFlujoDeEfectivo"],
|
||||
["id" => "Finanzas", "nombre" => "FINANZAS", "img" => "depto-finanzas.png", "act1_class" => "actFlujoDeEfectivo", "act2_class" => "actCreditoEInversion"],
|
||||
["id" => "InvestigacionYDesarrollo", "nombre" => "INVESTIGACIÓN Y DESARROLLO", "img" => "depto-investigacion.png", "act1_class" => "actCreditoEInversion", "act2_class" => "actTecnologia"],
|
||||
["id" => "LogisticaYSistemas", "nombre" => "LOGÍSTICA Y SISTEMAS", "img" => "depto-logistica.png", "act1_class" => "actTecnologia", "act2_class" => "actTransporteYMaquinaria"],
|
||||
["id" => "Operaciones", "nombre" => "OPERACIONES", "img" => "depto-operaciones.png", "act1_class" => "actTransporteYMaquinaria", "act2_class" => "actAnalistas"],
|
||||
["id" => "RecursosHumanos", "nombre" => "RECURSOS HUMANOS", "img" => "depto-recursos.png", "act1_class" => "actPersonalCalificado", "act2_class" => "actAnalistas"]
|
||||
];
|
||||
|
||||
foreach ($deptos as $depto) {
|
||||
?>
|
||||
<div class="card departamentos droppable-asset-recovery" id="<?= $depto['id'] ?>">
|
||||
<table style="width:100%;">
|
||||
<tr style="border-bottom: 1px solid gray;">
|
||||
<td style="width: 80%;"><span id="nombreDeptoCh"><?= $depto['nombre'] ?></span></td>
|
||||
<td style="text-align:right;">
|
||||
<span style="border:1px solid black;padding:5px;" class="<?= $depto['act1_class'] ?> draggable activo-item" id="activoCh1">0</span>
|
||||
<span style="border:1px solid black;padding:5px;" class="<?= $depto['act2_class'] ?> draggable activo-item" id="activoCh2">0</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr style="vertical-align:middle;">
|
||||
<td colspan="2">
|
||||
<table style="width:100%;">
|
||||
<tr>
|
||||
<td style="text-align:center;">
|
||||
<img src="img/tiempoCH.png" style="width: 30px; height: 30px; vertical-align: middle;">
|
||||
<span style="vertical-align:middle; font-weight:bold; font-size:16px;" id="tiempoCh" class="draggable recurso-item recurso-tiempo">0</span>
|
||||
<div class="beneficio-recurso beneficio-tiempo" style="font-size: 12px; font-weight: bold; color: #28a745;"></div>
|
||||
</td>
|
||||
<td style="text-align:center;">
|
||||
<img src="img/personalCH.png" style="width: 30px; height: 30px; vertical-align: middle;">
|
||||
<span style="vertical-align:middle; font-weight:bold; font-size:16px;" id="personalCh" class="draggable recurso-item recurso-personal">0</span>
|
||||
<div class="beneficio-recurso beneficio-personal" style="font-size: 12px; font-weight: bold; color: #28a745;"></div>
|
||||
</td>
|
||||
<td style="text-align:center;">
|
||||
<img src="img/capitalCH.png" style="width: 30px; height: 30px; vertical-align: middle;">
|
||||
<span style="vertical-align:middle; font-weight:bold; font-size:16px;" id="capitalCh" class="draggable recurso-item recurso-capital">0</span>
|
||||
<div class="beneficio-recurso beneficio-capital" style="font-size: 12px; font-weight: bold; color: #28a745;"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr style="border-top: 1px solid gray;">
|
||||
<td colspan="2" style="font-size:11px; text-align:center; background-color: #e0e0e0;">
|
||||
Habilidad Especial: <span id="accionEspecialGde" style="font-weight:bold;"></span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
|
||||
<!-- =================================================================
|
||||
COLUMNA 3: PROYECTOS TERMINADOS
|
||||
================================================================== -->
|
||||
<div class="column column-completed">
|
||||
<h2>PROYECTOS TERMINADOS (T)</h2>
|
||||
<div id="completed-projects-container">
|
||||
<!-- Los proyectos completados del trimestre se insertan aquí por JS -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- =================================================================
|
||||
COLUMNA 4: PROYECTOS ACTIVOS
|
||||
================================================================== -->
|
||||
<div class="column column-active">
|
||||
<h2>PROYECTOS ACTIVOS</h2>
|
||||
<div id="active-projects-container" style="display: flex; flex-wrap: wrap; gap: 10px; align-content: flex-start;">
|
||||
<!-- Los proyectos activos se insertan aquí por JS -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- =================================================================
|
||||
JAVASCRIPT
|
||||
================================================================== -->
|
||||
<script src="jsCode.js?v=<?php echo filemtime('jsCode.js'); ?>"></script>
|
||||
|
||||
<script>
|
||||
// Sobreescribimos 'continuamos' para añadir la lógica de esta pantalla
|
||||
const originalContinuamos = continuamos;
|
||||
continuamos = function() {
|
||||
originalContinuamos();
|
||||
actualizarResumenUI();
|
||||
};
|
||||
|
||||
// En resumen.php, la función llenaDepartamentoGde no tiene utilidad y causa problemas.
|
||||
// La sobrescribimos para que no haga nada y así evitamos que deshabilite el 'drop' en las tarjetas.
|
||||
function llenaDepartamentoGde(depto) {
|
||||
console.log(`[RESUMEN] Se bloqueó la llamada a llenaDepartamentoGde para el depto: ${depto}`);
|
||||
// No hacer nada es la solución.
|
||||
}
|
||||
|
||||
function formatCurrency(value) {
|
||||
return new Intl.NumberFormat('es-MX', {
|
||||
style: 'currency',
|
||||
currency: 'MXN',
|
||||
minimumFractionDigits: 0,
|
||||
maximumFractionDigits: 0,
|
||||
}).format(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Actualiza correctamente la UI de una tarjeta de departamento en la pantalla de resumen,
|
||||
* usando selectores de clase para evitar conflictos con IDs duplicados.
|
||||
*/
|
||||
function actualizarTarjetaDepto(deptoId) {
|
||||
const deptoArr = arreglosDeptos['arr' + deptoId];
|
||||
const deptoCard = $('#' + deptoId);
|
||||
|
||||
if (!deptoArr || !deptoCard.length) return;
|
||||
|
||||
// Actualizar recursos
|
||||
deptoCard.find('.recurso-tiempo').text(findArrayValue(deptoArr, 'recursoTiempo'));
|
||||
deptoCard.find('.recurso-personal').text(findArrayValue(deptoArr, 'recursoPersonal'));
|
||||
deptoCard.find('.recurso-capital').text(findArrayValue(deptoArr, 'recursoCapital'));
|
||||
|
||||
// --- START: NEW LOGIC FOR BENEFITS ---
|
||||
// Limpiar beneficios anteriores
|
||||
deptoCard.find('.beneficio-recurso').text('');
|
||||
|
||||
const skillSlots = ['habilidadTiempo', 'habilidadPersonal', 'habilidadCapital'];
|
||||
|
||||
skillSlots.forEach(slot => {
|
||||
const skillName = findArrayValue(deptoArr, slot);
|
||||
if (skillName && arreglosCapacitaciones[skillName]) {
|
||||
const skillData = arreglosCapacitaciones[skillName];
|
||||
const beneficio = findArrayValue(skillData, 'beneficio');
|
||||
const tipoRecurso = findArrayValue(skillData, 'tipoRecurso');
|
||||
|
||||
if (beneficio !== 0) { // Solo mostrar si hay beneficio
|
||||
let targetClass = '';
|
||||
let resourceChar = '';
|
||||
if (tipoRecurso === 'Tiempo') {
|
||||
targetClass = '.beneficio-tiempo';
|
||||
resourceChar = 'T';
|
||||
} else if (tipoRecurso === 'Personal') {
|
||||
targetClass = '.beneficio-personal';
|
||||
resourceChar = 'P';
|
||||
} else if (tipoRecurso === 'Capital') {
|
||||
targetClass = '.beneficio-capital';
|
||||
resourceChar = 'C';
|
||||
}
|
||||
|
||||
if (targetClass) {
|
||||
deptoCard.find(targetClass).text(`${beneficio}${resourceChar}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
// --- END: NEW LOGIC FOR BENEFITS ---
|
||||
|
||||
// Actualizar activos
|
||||
deptoCard.find('.activo-item').first().text(findArrayValue(deptoArr, 'activo1'));
|
||||
deptoCard.find('.activo-item').last().text(findArrayValue(deptoArr, 'activo2'));
|
||||
|
||||
deptoCard.find('#accionEspecialGde').text(findArrayValue(deptoArr, 'accionEspecialQuincenal'));
|
||||
}
|
||||
|
||||
function actualizarResumenUI() {
|
||||
console.log("Actualizando UI de Resumen...");
|
||||
|
||||
const quincena = parseInt($('#etQuincena').val()) || 1;
|
||||
const trimestreActual = Math.floor((quincena - 1) / 6) + 1;
|
||||
|
||||
$('#resumenTrimestre').text(`T${trimestreActual}`);
|
||||
$('#resumenQuincena').text(`Q${quincena}`);
|
||||
|
||||
// --- 1. Actualizar Progresión ---
|
||||
$('#ingresoT1').text(formatCurrency(arregloGeneral.trimestre1 || 0));
|
||||
$('#ingresoT2').text(formatCurrency(arregloGeneral.trimestre2 || 0));
|
||||
$('#ingresoT3').text(formatCurrency(arregloGeneral.trimestre3 || 0));
|
||||
$('#ingresoT4').text(formatCurrency(arregloGeneral.trimestre4 || 0));
|
||||
|
||||
let acumulado = 0;
|
||||
acumulado += (arregloGeneral.trimestre1 || 0);
|
||||
$('#acumuladoT1').text(formatCurrency(acumulado));
|
||||
acumulado += (arregloGeneral.trimestre2 || 0);
|
||||
$('#acumuladoT2').text(formatCurrency(acumulado));
|
||||
acumulado += (arregloGeneral.trimestre3 || 0);
|
||||
$('#acumuladoT3').text(formatCurrency(acumulado));
|
||||
acumulado += (arregloGeneral.trimestre4 || 0);
|
||||
$('#acumuladoT4').text(formatCurrency(acumulado));
|
||||
|
||||
// --- 2. Contar y mostrar resumen de Proyectos e Incidencias ---
|
||||
let conteoProyectos = {
|
||||
1: {
|
||||
concretados: 0
|
||||
},
|
||||
2: {
|
||||
concretados: 0
|
||||
},
|
||||
3: {
|
||||
concretados: 0
|
||||
},
|
||||
4: {
|
||||
concretados: 0
|
||||
}
|
||||
};
|
||||
let conteoIncidencias = {
|
||||
1: {
|
||||
resueltos: 0
|
||||
},
|
||||
2: {
|
||||
resueltos: 0
|
||||
},
|
||||
3: {
|
||||
resueltos: 0
|
||||
},
|
||||
4: {
|
||||
resueltos: 0
|
||||
}
|
||||
};
|
||||
let proyectosEnProceso = 0;
|
||||
let incidenciasEnProceso = 0;
|
||||
|
||||
proyectos.forEach(p => {
|
||||
const esIncidencia = p.dificultad === 'Incidencia';
|
||||
const trimestreCompletado = p.trimestreCompletado;
|
||||
|
||||
if (p.estatus === 'Completado') {
|
||||
if (esIncidencia) {
|
||||
if (!conteoIncidencias[trimestreCompletado]) conteoIncidencias[trimestreCompletado] = {
|
||||
resueltos: 0
|
||||
};
|
||||
conteoIncidencias[trimestreCompletado].resueltos++;
|
||||
} else {
|
||||
if (!conteoProyectos[trimestreCompletado]) conteoProyectos[trimestreCompletado] = {
|
||||
concretados: 0
|
||||
};
|
||||
conteoProyectos[trimestreCompletado].concretados++;
|
||||
}
|
||||
} else if (p.estatus === 'En proceso') {
|
||||
if (esIncidencia) {
|
||||
incidenciasEnProceso++;
|
||||
} else {
|
||||
proyectosEnProceso++;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('#resumen-proyectos').html(`
|
||||
<thead><tr><th></th><th>T1</th><th>T2</th><th>T3</th><th>T4</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>En Proceso</td><td colspan="4">${proyectosEnProceso}</td></tr>
|
||||
<tr><td>Concretados</td><td>${conteoProyectos[1].concretados}</td><td>${conteoProyectos[2].concretados}</td><td>${conteoProyectos[3].concretados}</td><td>${conteoProyectos[4].concretados}</td></tr>
|
||||
</tbody>
|
||||
`);
|
||||
$('#resumen-incidencias').html(`
|
||||
<thead><tr><th></th><th>T1</th><th>T2</th><th>T3</th><th>T4</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>En Proceso</td><td colspan="4">${incidenciasEnProceso}</td></tr>
|
||||
<tr><td>Resueltos</td><td>${conteoIncidencias[1].resueltos}</td><td>${conteoIncidencias[2].resueltos}</td><td>${conteoIncidencias[3].resueltos}</td><td>${conteoIncidencias[4].resueltos}</td></tr>
|
||||
</tbody>
|
||||
`);
|
||||
|
||||
// --- 3. Llenar columnas de proyectos ---
|
||||
const completedContainer = $('#completed-projects-container');
|
||||
const activeContainer = $('#active-projects-container');
|
||||
completedContainer.empty();
|
||||
activeContainer.empty();
|
||||
|
||||
$('.column-completed h2').text(`PROYECTOS TERMINADOS (T${trimestreActual})`);
|
||||
|
||||
proyectos.forEach(p => {
|
||||
if (p.estatus === 'Completado' && p.trimestreCompletado === trimestreActual) {
|
||||
completedContainer.append(crearTarjetaProyecto(p, true));
|
||||
} else if (p.estatus === 'En proceso') {
|
||||
activeContainer.append(crearTarjetaProyecto(p, false));
|
||||
}
|
||||
});
|
||||
|
||||
// --- 4. Actualizar todas las tarjetas de departamento con los datos cargados ---
|
||||
const deptoIds = ["MarketingYVentas", "Finanzas", "InvestigacionYDesarrollo", "LogisticaYSistemas", "Operaciones", "RecursosHumanos"];
|
||||
deptoIds.forEach(deptoId => {
|
||||
actualizarTarjetaDepto(deptoId);
|
||||
});
|
||||
|
||||
// --- 5. Inicializar todas las interacciones de Drag & Drop ---
|
||||
inicializarInteraccionesDragDrop();
|
||||
}
|
||||
|
||||
function crearTarjetaProyecto(proyecto, esCompletado) {
|
||||
const colores = ['amarillo', 'naranjas', 'verdes', 'azules', 'rojos', 'morados'];
|
||||
let activosReqHtml = '';
|
||||
let activosAsigHtml = '';
|
||||
|
||||
const coloresConValores = colores
|
||||
.filter(color => proyecto[color] !== null && proyecto[color] > 0)
|
||||
.map(color => ({
|
||||
color,
|
||||
valor: proyecto[color]
|
||||
}));
|
||||
|
||||
let laClase = '';
|
||||
for (let i = 0; i < 3; i++) {
|
||||
if (i < coloresConValores.length) {
|
||||
const activo = coloresConValores[i];
|
||||
const claseActivo = 'act' + getClassNameFromColor(activo.color);
|
||||
activosReqHtml += `<span class="${claseActivo}">${activo.valor}</span>`;
|
||||
|
||||
const draggableClass = esCompletado ? 'asset-recover' : '';
|
||||
const assetId = `asset-${proyecto.id}-${i}`;
|
||||
activosAsigHtml += `<span id="${assetId}" class="${claseActivo} ${draggableClass}" data-asset-type="${getClassNameFromColor(activo.color)}">${proyecto['activoAsignado' + (i + 1)]}</span>`;
|
||||
} else {
|
||||
activosReqHtml += `<span class="actNinguno"></span>`;
|
||||
activosAsigHtml += `<span class="actNinguno"></span>`;
|
||||
}
|
||||
}
|
||||
|
||||
const completadoClass = esCompletado ? 'completado' : '';
|
||||
|
||||
return `
|
||||
<div class="project-card ${completadoClass}" style="flex-basis: 48%;">
|
||||
<div class="project-header">${proyecto.nombreProyecto.toUpperCase()}</div>
|
||||
<div class="project-body">
|
||||
<i>${proyecto.descripcion}</i>
|
||||
<div class="project-assets-req">${activosReqHtml}</div>
|
||||
<div class="project-assets-asig">${activosAsigHtml}</div>
|
||||
</div>
|
||||
<div class="project-footer">MANTENIMIENTO: ${proyecto.mantenimiento}</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function getClassNameFromColor(color) {
|
||||
switch (color) {
|
||||
case 'amarillo':
|
||||
return 'PersonalCalificado';
|
||||
case 'naranjas':
|
||||
return 'Analistas';
|
||||
case 'verdes':
|
||||
return 'FlujoDeEfectivo';
|
||||
case 'azules':
|
||||
return 'TransporteYMaquinaria';
|
||||
case 'rojos':
|
||||
return 'Tecnologia';
|
||||
case 'morados':
|
||||
return 'CreditoEInversion';
|
||||
default:
|
||||
return 'Ninguno';
|
||||
}
|
||||
}
|
||||
|
||||
function inicializarInteraccionesDragDrop() {
|
||||
console.log("[RESUMEN] Inicializando interacciones de Drag & Drop...");
|
||||
|
||||
// 1. DRAGGABLE: Activos recuperables de proyectos terminados
|
||||
$('.asset-recover').draggable({
|
||||
revert: "invalid",
|
||||
helper: "clone",
|
||||
start: function(event, ui) {
|
||||
if (parseInt($(this).text()) === 0) {
|
||||
return false;
|
||||
}
|
||||
ui.helper.css('z-index', 100);
|
||||
}
|
||||
});
|
||||
|
||||
// 2. DRAGGABLE: Recursos intercambiables entre departamentos
|
||||
$('.column-depts .recurso-item').draggable({
|
||||
revert: "invalid",
|
||||
helper: "clone",
|
||||
start: function(event, ui) {
|
||||
const sourceDeptoId = $(this).closest('.departamentos').attr('id');
|
||||
ui.helper.data('source-depto', sourceDeptoId);
|
||||
ui.helper.css('z-index', 100);
|
||||
}
|
||||
});
|
||||
|
||||
// 3. DROPPABLE: Tarjetas de departamento que aceptan activos Y recursos
|
||||
$('.droppable-asset-recovery').droppable({
|
||||
accept: ".asset-recover, .recurso-item", // Acepta ambos tipos de elementos
|
||||
drop: function(event, ui) {
|
||||
$(this).css('background-color', ''); // Limpiar feedback visual al soltar
|
||||
|
||||
// --- LÓGICA PARA SOLTAR ACTIVOS ---
|
||||
if (ui.draggable.hasClass('asset-recover')) {
|
||||
const deptoId = $(this).attr('id');
|
||||
const assetType = ui.draggable.data('asset-type');
|
||||
const assetElementId = ui.draggable.attr('id');
|
||||
|
||||
const costoRecuperacion = arreglosActivos['arr' + assetType];
|
||||
const costoT = findArrayValue(costoRecuperacion, 'recuperacionTiempo');
|
||||
const costoP = findArrayValue(costoRecuperacion, 'recuperacionPersonal');
|
||||
const costoC = findArrayValue(costoRecuperacion, 'recuperacionCapital');
|
||||
|
||||
const deptoArr = arreglosDeptos['arr' + deptoId];
|
||||
const recT = findArrayValue(deptoArr, 'recursoTiempo');
|
||||
const recP = findArrayValue(deptoArr, 'recursoPersonal');
|
||||
const recC = findArrayValue(deptoArr, 'recursoCapital');
|
||||
|
||||
if (recT >= costoT && recP >= costoP && recC >= costoC) {
|
||||
setArrayValue(deptoArr, 'recursoTiempo', recT - costoT);
|
||||
setArrayValue(deptoArr, 'recursoPersonal', recP - costoP);
|
||||
setArrayValue(deptoArr, 'recursoCapital', recC - costoC);
|
||||
|
||||
let activoSlot = '';
|
||||
if (findArrayValue(deptoArr, 'activo1Tipo') === assetType) activoSlot = 'activo1';
|
||||
else if (findArrayValue(deptoArr, 'activo2Tipo') === assetType) activoSlot = 'activo2';
|
||||
|
||||
if (activoSlot) {
|
||||
const valorActualActivo = findArrayValue(deptoArr, activoSlot);
|
||||
setArrayValue(deptoArr, activoSlot, valorActualActivo + 1);
|
||||
|
||||
const assetElement = $(`#${assetElementId}`);
|
||||
const currentCount = parseInt(assetElement.text());
|
||||
assetElement.text(currentCount - 1);
|
||||
|
||||
// --- INICIO: CORRECCIÓN PARA ACTUALIZAR ARREGLO DE PROYECTOS ---
|
||||
const assetIdParts = assetElementId.split('-'); // e.g., "asset-15-0"
|
||||
const projectId = parseInt(assetIdParts[1]);
|
||||
const assetIndex = parseInt(assetIdParts[2]); // 0-based index
|
||||
|
||||
const projectToUpdate = proyectos.find(p => p.id === projectId);
|
||||
if (projectToUpdate) {
|
||||
const assetSlotName = `activoAsignado${assetIndex + 1}`;
|
||||
if (projectToUpdate[assetSlotName] > 0) {
|
||||
projectToUpdate[assetSlotName]--;
|
||||
console.log(`[RESUMEN] Activo recuperado del proyecto ${projectId}. Slot: ${assetSlotName}, nuevo valor: ${projectToUpdate[assetSlotName]}`);
|
||||
}
|
||||
}
|
||||
// --- FIN: CORRECCIÓN ---
|
||||
actualizarTarjetaDepto(deptoId);
|
||||
var audio = new Audio('./Microwave_bell.wav');
|
||||
audio.play();
|
||||
} else {
|
||||
alert(`El departamento ${deptoId} no puede almacenar activos de tipo ${assetType}.`);
|
||||
setArrayValue(deptoArr, 'recursoTiempo', recT);
|
||||
setArrayValue(deptoArr, 'recursoPersonal', recP);
|
||||
setArrayValue(deptoArr, 'recursoCapital', recC);
|
||||
}
|
||||
} else {
|
||||
alert("Recursos insuficientes en el departamento para recuperar este activo.");
|
||||
}
|
||||
}
|
||||
// --- LÓGICA PARA SOLTAR RECURSOS ---
|
||||
else if (ui.draggable.hasClass('recurso-item')) {
|
||||
const targetDeptoId = $(this).attr('id');
|
||||
const sourceDeptoId = ui.helper.data('source-depto');
|
||||
|
||||
if (!sourceDeptoId || targetDeptoId === sourceDeptoId) return;
|
||||
|
||||
let resourceType = '';
|
||||
if (ui.draggable.hasClass('recurso-tiempo')) resourceType = 'recursoTiempo';
|
||||
if (ui.draggable.hasClass('recurso-personal')) resourceType = 'recursoPersonal';
|
||||
if (ui.draggable.hasClass('recurso-capital')) resourceType = 'recursoCapital';
|
||||
|
||||
if (!resourceType) return;
|
||||
|
||||
const sourceDeptoArr = arreglosDeptos['arr' + sourceDeptoId];
|
||||
const targetDeptoArr = arreglosDeptos['arr' + targetDeptoId];
|
||||
const sourceVal = findArrayValue(sourceDeptoArr, resourceType);
|
||||
|
||||
if (sourceVal > 0) {
|
||||
const targetVal = findArrayValue(targetDeptoArr, resourceType);
|
||||
|
||||
setArrayValue(sourceDeptoArr, resourceType, sourceVal - 1);
|
||||
setArrayValue(targetDeptoArr, resourceType, targetVal + 1);
|
||||
|
||||
actualizarTarjetaDepto(sourceDeptoId);
|
||||
actualizarTarjetaDepto(targetDeptoId);
|
||||
|
||||
var audio = new Audio('./Microwave_bell.wav');
|
||||
audio.play();
|
||||
}
|
||||
}
|
||||
},
|
||||
over: function(event, ui) {
|
||||
if (ui.draggable.hasClass('recurso-item') && $(this).attr('id') !== ui.helper.data('source-depto')) {
|
||||
$(this).css('background-color', '#e9f5e9');
|
||||
} else if (ui.draggable.hasClass('asset-recover')) {
|
||||
$(this).css('background-color', '#e9f5e9');
|
||||
}
|
||||
},
|
||||
out: function(event, ui) {
|
||||
$(this).css('background-color', '');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Listener para los botones de quincena para actualizar la UI
|
||||
$('#bMas, #bMenos').on('click', function() {
|
||||
// Pequeño delay para asegurar que el valor del input se actualice antes de leerlo
|
||||
setTimeout(actualizarResumenUI, 100);
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user