227 lines
6.9 KiB
JavaScript
227 lines
6.9 KiB
JavaScript
const Database = require('better-sqlite3');
|
|
const path = require('path');
|
|
const { app } = require('electron');
|
|
|
|
const dbPath = path.join(app.getPath("documents"), "orden-merito.db");
|
|
let db;
|
|
|
|
function initializeDatabase() {
|
|
try {
|
|
db = new Database(dbPath);
|
|
db.pragma('journal_mode = WAL');
|
|
|
|
db.exec(`
|
|
CREATE TABLE IF NOT EXISTS profesionales (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
grado TEXT NOT NULL,
|
|
nombreApellido TEXT NOT NULL,
|
|
cedula TEXT NOT NULL UNIQUE,
|
|
condicion TEXT NOT NULL DEFAULT 'No posee novedades actualmente',
|
|
conducta INTEGER NOT NULL CHECK (conducta BETWEEN 0 AND 100),
|
|
companeros TEXT NOT NULL,
|
|
om_a TEXT NOT NULL,
|
|
niea REAL NOT NULL
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_condicion ON profesionales (condicion);
|
|
CREATE INDEX IF NOT EXISTS idx_niea ON profesionales (niea);
|
|
`);
|
|
|
|
} catch (err) {
|
|
console.error("Error inicializando base de datos:", err);
|
|
app.quit();
|
|
}
|
|
}
|
|
|
|
initializeDatabase();
|
|
|
|
|
|
|
|
function insertProfesionales(profesionales) {
|
|
const deleteStmt = db.prepare('DELETE FROM profesionales');
|
|
const insertStmt = db.prepare(`
|
|
INSERT INTO profesionales (
|
|
grado, nombreApellido, cedula, condicion,
|
|
conducta, companeros, om_a, niea
|
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
`);
|
|
|
|
const transaction = db.transaction((profesionales) => {
|
|
deleteStmt.run();
|
|
|
|
for (const prof of profesionales) {
|
|
// Normalizar el campo companeros
|
|
let companeros = prof.companeros?.toString().trim() || '0';
|
|
if (companeros === '0' || companeros === '') {
|
|
companeros = '0/0'; // Convertir 0 o vacío a 0/0
|
|
} else if (!companeros.includes('/')) {
|
|
companeros = `${companeros}/90`; // Si solo tiene numerador, asumir denominador 90
|
|
}
|
|
|
|
// Normalizar el campo om_a de la misma manera
|
|
let om_a = prof.om_a?.toString().trim() || '0';
|
|
if (om_a === '0' || om_a === '') {
|
|
om_a = '0/0';
|
|
} else if (!om_a.includes('/')) {
|
|
om_a = `${om_a}/90`;
|
|
}
|
|
|
|
insertStmt.run(
|
|
prof.grado?.toString().trim() || '',
|
|
prof.nombreApellido?.toString().trim() || '',
|
|
prof.cedula?.toString().trim() || '',
|
|
String(prof.condicion || '').trim().toLowerCase() || 'No posee novedades actualmente',
|
|
parseFloat(prof.conducta) || 0,
|
|
companeros,
|
|
om_a,
|
|
parseFloat(prof.niea) || 0
|
|
);
|
|
}
|
|
});
|
|
|
|
try {
|
|
transaction(profesionales);
|
|
} catch (err) {
|
|
console.error("Error insertando profesionales:", err);
|
|
throw err;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function calcularResultado(prof) {
|
|
try {
|
|
const puntajeConducta = (parseFloat(prof.conducta) || 0) * 0.15;
|
|
|
|
// Manejo especial para campo "compañeros"
|
|
let puntajeCompaneros = 0;
|
|
if (prof.companeros && prof.companeros !== '0') {
|
|
if (prof.companeros.includes('/')) {
|
|
const [posCompaneros, totalCompaneros] = prof.companeros.split('/').map(Number);
|
|
puntajeCompaneros = totalCompaneros > 0 ? (1 - (posCompaneros / totalCompaneros)) * 5 : 0;
|
|
} else {
|
|
// Si no tiene formato de fracción, asumir que es el numerador con denominador 90
|
|
const posCompaneros = Number(prof.companeros);
|
|
puntajeCompaneros = (1 - (posCompaneros / 90)) * 5;
|
|
}
|
|
}
|
|
|
|
// Manejo similar para campo "om_a"
|
|
let puntajeOM = 0;
|
|
if (prof.om_a && prof.om_a !== '0') {
|
|
if (prof.om_a.includes('/')) {
|
|
const [posOM, totalOM] = prof.om_a.split('/').map(Number);
|
|
puntajeOM = totalOM > 0 ? (1 - (posOM / totalOM)) * 30 : 0;
|
|
} else {
|
|
const posOM = Number(prof.om_a);
|
|
puntajeOM = (1 - (posOM / 90)) * 30;
|
|
}
|
|
}
|
|
|
|
const puntajeNIEA = (parseFloat(prof.niea) || 0) * 0.5;
|
|
|
|
return puntajeConducta + puntajeCompaneros + puntajeOM + puntajeNIEA;
|
|
} catch (err) {
|
|
console.error("Error calculando resultado:", err);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function getRanking() {
|
|
try {
|
|
const stmt = db.prepare(`
|
|
SELECT *,
|
|
CASE
|
|
WHEN LOWER(condicion) = 'no posee novedades actualmente' THEN 0
|
|
WHEN condicion LIKE '%sancion simple%grados anteriores%' THEN 1
|
|
WHEN condicion LIKE '%privado%libertad%' THEN 3
|
|
ELSE 2
|
|
END AS priority_level,
|
|
|
|
(CAST(conducta AS REAL) * 0.15 +
|
|
(
|
|
(1 - (
|
|
CAST(SUBSTR(companeros, 1, INSTR(companeros, '/') - 1) AS REAL) /
|
|
CAST(SUBSTR(companeros, INSTR(companeros, '/') + 1) AS INTEGER)
|
|
)) * 5
|
|
) +
|
|
(
|
|
(1 - (
|
|
CAST(SUBSTR(om_a, 1, INSTR(om_a, '/') - 1) AS REAL) /
|
|
CAST(SUBSTR(om_a, INSTR(om_a, '/') + 1) AS INTEGER)
|
|
)) * 30
|
|
) +
|
|
(niea * 0.5)
|
|
) AS resultado -- Paréntesis de cierre correcto
|
|
FROM profesionales
|
|
ORDER BY
|
|
priority_level ASC,
|
|
CASE WHEN condicion LIKE '%privado%libertad%' THEN 1 ELSE 0 END,
|
|
resultado DESC
|
|
`);
|
|
|
|
return stmt.all();
|
|
} catch (err) {
|
|
console.error("Error obteniendo ranking:", err);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
|
|
function getNoRecomendados() {
|
|
try {
|
|
return getRanking().filter(p => {
|
|
const cond = p.condicion.toLowerCase();
|
|
|
|
// Lógica para sanciones simples (contar ocurrencias)
|
|
const sancionesSimples = (cond.match(/(\d+)\s*d[ií]as de sanci[oó]n simple/g) || []).length;
|
|
|
|
// Lógica mejorada para sanciones severas (sumar días)
|
|
const sancionesSeverasMatches = cond.match(/(\d+)\s*d[ií]as de sanci[oó]n severa/g) || [];
|
|
let totalDiasSeveros = 0;
|
|
for (const match of sancionesSeverasMatches) {
|
|
const diasMatch = match.match(/\d+/);
|
|
if (diasMatch) totalDiasSeveros += parseInt(diasMatch[0], 10);
|
|
}
|
|
|
|
const investigacionAbierta = /(investigaci[oó]n|juicio).*(abiert|pendiente|vigente)/.test(cond);
|
|
const privadoLibertad = /privado de libertad/i.test(cond);
|
|
|
|
return sancionesSimples >= 15 ||
|
|
totalDiasSeveros >= 8 || // Ahora verifica días totales
|
|
investigacionAbierta ||
|
|
privadoLibertad;
|
|
});
|
|
} catch (err) {
|
|
console.error("Error obteniendo no recomendados:", err);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
|
|
function getTop10() {
|
|
try {
|
|
const ranking = getRanking()
|
|
.filter(p => p.condicion.toLowerCase() === 'no posee novedades actualmente')
|
|
.slice(0, 10);
|
|
|
|
return ranking;
|
|
} catch (err) {
|
|
console.error("Error obteniendo top 10:", err);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
app.on("window-all-closed", () => {
|
|
if (db) db.close();
|
|
});
|
|
|
|
module.exports = {
|
|
insertProfesionales,
|
|
getRanking,
|
|
getNoRecomendados,
|
|
getTop10,
|
|
calcularResultado
|
|
}; |