// ══════════════════════════════════════════════════════════ // REDIL — Sistema de Gestión v5.1 // ══════════════════════════════════════════════════════════ var APP={user:null,mod:'',charts:{},hermanos:[],contactos:[],formUrl:'',formUrlPublic:'',config:{}}; const TIPO_REUNION=['Mixta (Reunión Regular)','Niños','Jóvenes','Mujeres','Profesionales']; const METODO_REPORTE=['Digital','Físico']; var SESSION_KEY='ir_sess_v51',SESSION_USER_KEY='ir_user_v51',SESSION_TIME_KEY='ir_time_v51'; var LOGO_KEY='ir_logo_v5',TOTALAPP_LOGO_KEY='ir_totalapp_logo_v5'; // ── DICCIONARIO DE TÍTULOS DE MÓDULOS ────────────────────── var TITLES = { dashboard: 'Dashboard General', reportes: 'Reporte de Grupos', reporteDigital: 'Reporte Digital', formulario: 'Formulario Externo', generador: 'Generador de Reportes', hermanos: 'Hermanos Líderes', cargaMasiva: 'Carga Masiva', supervisores: 'Supervisores de Sector', pastores: 'Pastores de Zona', ayudapastor: 'Ayuda de Pastor', seguimientos: 'Seguimientos', privilegios: 'Privilegios', diezmos: 'Control de Diezmos', gastos: 'Control de Gastos', inventario: 'Inventario', insumos: 'Insumos', envio: 'Centro de Envíos', contactos: 'Tabla de Contactos', usuarios: 'Usuarios', bitacora: 'Bitácora de Accesos', configuracion: 'Configuración', cronograma: 'Cronograma', bautizos: 'Bautizos en Agua' }; function saveSession(token,user,inactMin){[localStorage,sessionStorage].forEach(function(s){try{s.setItem(SESSION_KEY,token);s.setItem(SESSION_USER_KEY,JSON.stringify(user));s.setItem(SESSION_TIME_KEY,Date.now().toString());s.setItem('ir_inact_min',String(inactMin||60));}catch(e){}});} function getToken(){return localStorage.getItem(SESSION_KEY)||sessionStorage.getItem(SESSION_KEY);} function permisoEditar(){return APP.user&&APP.user.PuedeEditar!=='NO';} function clearSession(){var token=localStorage.getItem(SESSION_KEY)||sessionStorage.getItem(SESSION_KEY);if(token)try{call('destroySession',{token:token},function(){});}catch(e){}[SESSION_KEY,SESSION_USER_KEY,SESSION_TIME_KEY,'ir_inact_min'].forEach(function(k){try{localStorage.removeItem(k);sessionStorage.removeItem(k);}catch(e){}});} function getInactMin(){return parseInt(localStorage.getItem('ir_inact_min')||'60',10)||60;} function call(action,payload,cb){ payload=payload||{}; var token=localStorage.getItem(SESSION_KEY)||sessionStorage.getItem(SESSION_KEY); if(token && !payload.token) payload.token=token; try{ var url=window.location.origin+'/api/dispatch'; fetch(url,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({action:action,payload:payload,token:token})}) .then(function(r){return r.json();}) .then(function(r){if(cb)cb(null,r);}) .catch(function(e){if(cb)cb(e,null);try{toast('Error: '+(e.message||e),'er');}catch(ex){}}); }catch(e){if(cb)cb(e,null);} } function g(id){var el=document.getElementById(id);return el?(el.value!==undefined?el.value:el.textContent):'';} function esc(s){return String(s||'').replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"').replace(/'/g,''');} function num(v){return parseFloat(String(v).replace(/[^0-9.\-]/g,''))||0;} function fmtQ(v){return 'Q '+Number(v||0).toLocaleString('es-GT',{minimumFractionDigits:2,maximumFractionDigits:2});} function fmtD(s){if(!s)return'--';try{var d=new Date(s+'T12:00:00');return d.toLocaleDateString('es-GT');}catch(e){return s;}} function fmtF(s){if(!s)return'';try{var d=new Date(s+'T12:00:00');return d.toLocaleDateString('es-GT');}catch(e){return s;}} function today(){var d=new Date();return d.getFullYear()+'-'+String(d.getMonth()+1).padStart(2,'0')+'-'+String(d.getDate()).padStart(2,'0');} function todayStr(){return today();} function fom(){var d=new Date();return d.getFullYear()+'-'+String(d.getMonth()+1).padStart(2,'0')+'-01';} function fom30(){var d=new Date();d.setDate(d.getDate()-30);return d.getFullYear()+'-'+String(d.getMonth()+1).padStart(2,'0')+'-'+String(d.getDate()).padStart(2,'0');} function mesNombre(s){if(!s)return'';var m=['Enero','Febrero','Marzo','Abril','Mayo','Junio','Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'];try{return m[new Date(s+'T12:00:00').getMonth()];}catch(e){return s;}} function exportXLS(data,name,file){ loading(true); call('exportExcel',{data:data,nombreHoja:name,nombreArchivo:file},function(_,res){ loading(false); if(res&&res.ok){ if(res.xlsx_base64){ try{ var bin=atob(res.xlsx_base64); var bytes=new Uint8Array(bin.length); for(var i=0;i'+esc(c.label)+'';}).join('')+''; var body=''; grupos.forEach(function(g){ if(g.titulo){body+=''+esc(grupoPor)+': '+esc(g.titulo)+' ('+g.filas.length+')';} g.filas.forEach(function(r){ body+=''+columnas.map(function(c){var v=r[c.key];if(v===undefined||v===null)v='';return ''+esc(v)+'';}).join('')+''; }); }); var w=window.open('','_blank','width=1000,height=700'); if(!w){toast('Activa ventanas emergentes','wa',5000);return;} w.document.write(''+esc(titulo)+'' +'' +'

'+esc(titulo)+'

'+esc(sysName)+' · '+hoy+'
'+filas.length+' registros
' +''+thead+''+body+'
' +'
'+esc(sysName)+' · iglesiarestauracion.totalappgt.online
' +'