Cobranza: buscador para abrir cualquier proyecto desde el resumen (también sin cotización aceptada)

Sin él, un proyecto nuevo no se podía abrir para marcar su primera
cotización aceptada (el resumen solo lista proyectos con contrato).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Efrain (Helgen) 2026-10-21 11:36:29 -06:00
parent b99630ba00
commit 06ef8249c3
2 changed files with 16 additions and 0 deletions

View File

@ -170,6 +170,13 @@ const esperar=async(n=10)=>{for(let i=0;i<n;i++) await new Promise(r=>setImmedia
assert.equal(csv[0].charCodeAt(0),0xFEFF,'BOM para Excel'); assert(csv[0].includes('"Contratado con IVA","Cobrado","Saldo"')); assert.equal(csv[0].charCodeAt(0),0xFEFF,'BOM para Excel'); assert(csv[0].includes('"Contratado con IVA","Cobrado","Saldo"'));
assert.equal(csv[1],'"PRY-2026-0003","Techo","\'=Luis, ""SA""","Helgen","Firmado","MXN",11600.00,5000.00,6600.00,43.1,"Instalación",3480.00,"2026-10-20",2,4850.00,5150.00,51.5'); assert.equal(csv[1],'"PRY-2026-0003","Techo","\'=Luis, ""SA""","Helgen","Firmado","MXN",11600.00,5000.00,6600.00,43.1,"Instalación",3480.00,"2026-10-20",2,4850.00,5150.00,51.5');
assert(csv[3].endsWith(',0,,,'),'sin margen: celdas vacías'); assert.equal(csv.length,4); assert(csv[3].endsWith(',0,,,'),'sin margen: celdas vacías'); assert.equal(csv.length,4);
// Desde el resumen se abre cualquier proyecto, también uno sin cotización aceptada (no está en la tabla)
const nAntes=B.llamadas.filter(c=>c.funcion==='getCobranzaProyecto').length;
B.$('resProyecto').value='PRY-2026-0001 — Luis — Solar MX — Techo'; B.$('resProyecto').disparar('change'); await esperar();
const abiertos=B.llamadas.filter(c=>c.funcion==='getCobranzaProyecto');
assert.equal(abiertos.length,nAntes+1); assert.equal(abiertos.pop().args[0],'PRY-2026-0001');
assert(!B.$('cobVistaProyecto').classList.contains('oculto')&&B.$('resProyecto').value==='','abre el proyecto y limpia el buscador');
B.run('verResumenCob()'); await esperar();
// Clic en un renglón abre el proyecto; "← Resumen" regresa // Clic en un renglón abre el proyecto; "← Resumen" regresa
B.respuestas.getCobranzaProyecto={ok:true,datos:{proyecto:PRY,cotizaciones:[],contrato:null,esquema:[],resumen:null,pagos:[],puedeAceptar:true,puedeFirmar:false,metodos:[],hoy:'2026-10-20'}}; B.respuestas.getCobranzaProyecto={ok:true,datos:{proyecto:PRY,cotizaciones:[],contrato:null,esquema:[],resumen:null,pagos:[],puedeAceptar:true,puedeFirmar:false,metodos:[],hoy:'2026-10-20'}};
B.run("abrirProyectoCob('PRY-2026-0001')"); await esperar(); B.run("abrirProyectoCob('PRY-2026-0001')"); await esperar();

View File

@ -278,6 +278,9 @@
<div id="cobVistaResumen"> <div id="cobVistaResumen">
<div class="modulo"> <div class="modulo">
<h2>1 · Resumen de cobranza</h2> <h2>1 · Resumen de cobranza</h2>
<!-- Todos los proyectos (también sin cotización aceptada): desde aquí se marca la primera aceptada -->
<div style="margin-bottom:12px"><label>Abrir un proyecto (todos, también sin cotización aceptada)</label>
<input id="resProyecto" list="cobProyectosList" autocomplete="off" placeholder="Busca por folio, cliente o nombre"></div>
<div id="resTotales" class="nota">Cargando…</div> <div id="resTotales" class="nota">Cargando…</div>
<div class="acciones"> <div class="acciones">
<input id="resBuscar" placeholder="Buscar por folio, cliente o nombre…" oninput="pintarResumenCob()" style="flex:1; min-width:220px"> <input id="resBuscar" placeholder="Buscar por folio, cliente o nombre…" oninput="pintarResumenCob()" style="flex:1; min-width:220px">
@ -1010,6 +1013,12 @@
return (folio && COB_PROYECTOS.find(p => p.folio === folio)) || null; return (folio && COB_PROYECTOS.find(p => p.folio === folio)) || null;
} }
$('cobProyecto').addEventListener('change', () => { const p = proyectoCobElegido(); if (p) abrirProyectoCob(p.folio); }); $('cobProyecto').addEventListener('change', () => { const p = proyectoCobElegido(); if (p) abrirProyectoCob(p.folio); });
// Desde el resumen: cualquier proyecto (el resumen solo lista los que tienen contrato)
$('resProyecto').addEventListener('change', () => {
const folio = ($('resProyecto').value.trim().match(/^PRY-\d{4}-\d{4}/i) || [''])[0].toUpperCase();
const p = folio && COB_PROYECTOS.find(x => x.folio === folio);
if (p) { $('resProyecto').value = ''; abrirProyectoCob(p.folio); }
});
function abrirProyectoCob(folio) { function abrirProyectoCob(folio) {
$('cobVistaResumen').classList.add('oculto'); $('cobVistaProyecto').classList.remove('oculto'); $('cobVistaResumen').classList.add('oculto'); $('cobVistaProyecto').classList.remove('oculto');