← Start
Auftrags-Pipeline
Werbung Haldensleben · CRM
–
Kunden
–
Offen
–
Aufträge
–
Gesamt
–
Lade…
Offene Aufgaben
Noch keine Aufgaben — nutze den Kommunikations-Button bei einem Angebot.
🏛 Öffentliche Ausschreibungen
automatisch • wöchentlich
Lade…
// ── AUSSCHREIBUNGEN ─────────────────────────────────────────────── var _ausschreibungen = []; var _curAeid = null; var AS_LABEL = {offen:'Offen', abgelaufen:'Frist abgelaufen', beworben:'Beworben', ignoriert:'Ignoriert'}; var AS_DOT = {offen:'var(--green)', abgelaufen:'var(--text3)', beworben:'var(--blue)', ignoriert:'var(--red)'}; async function loadAusschreibungen() { document.getElementById('ausschr-kachel').innerHTML = '
Lade…
'; try { var r = await fetch('/api/roadie/ausschreibungen'); var d = await r.json(); _ausschreibungen = d.eintraege || []; renderAusschr(); } catch(e) { document.getElementById('ausschr-kachel').innerHTML = '
Verbindungsfehler.
'; } } function renderAusschr() { var el = document.getElementById('ausschr-kachel'); if (!_ausschreibungen.length) { el.innerHTML = '
Noch keine Ausschreibungen — der wöchentliche Scan läuft automatisch.
'; return; } var heute = new Date(); heute.setHours(0,0,0,0); el.innerHTML = _ausschreibungen.map(function(a) { var dot = AS_DOT[a.status] || 'var(--text3)'; var badge = AS_LABEL[a.status] || a.status; var fristTage = ''; if (a.frist) { var fd = new Date(a.frist + 'T12:00:00'); var diff = Math.round((fd - heute) / 86400000); if (diff > 0) fristTage = '⏰ ' + diff + ' Tage verbleibend'; else if (diff === 0) fristTage = '⚠ Frist heute!'; else fristTage = 'Frist: ' + fmtDate(a.frist); } return '
' + '
' + '
' + '
' + esc(a.titel) + '
' + '
' + esc(a.auftraggeber) + (a.ort ? ' · ' + esc(a.ort) : '') + '
' + '
' + (fristTage ? '' + fristTage + '' : '') + (a.cpv ? 'CPV ' + esc(a.cpv) + '' : '') + (a.quelle ? '' + esc(a.quelle) + '' : '') + '
' + '
' + '' + badge + '' + '
'; }).join(''); } function openAuschrDetail(eid) { var a = _ausschreibungen.find(function(x){ return x.id === eid; }); if (!a) return; _curAeid = eid; document.getElementById('ad-titel').textContent = a.titel; document.getElementById('ad-sub').textContent = (a.auftraggeber||'') + (a.ort ? ' · ' + a.ort : ''); document.getElementById('ad-beschr').textContent = a.beschreibung || ''; var meta = []; if (a.frist) meta.push({l:'Frist', v: fmtDate(a.frist)}); if (a.cpv) meta.push({l:'CPV', v: a.cpv}); if (a.quelle) meta.push({l:'Quelle', v: a.quelle}); document.getElementById('ad-meta').innerHTML = meta.map(function(m){ return '
' + '
' + m.l + '
' + '
' + esc(m.v) + '
'; }).join(''); document.getElementById('ad-status-btns').innerHTML = ['offen','beworben','ignoriert','abgelaufen'].map(function(s){ return ''; }).join(''); if (a.url) { document.getElementById('ad-url-wrap').style.display = ''; document.getElementById('ad-url').href = a.url; } else { document.getElementById('ad-url-wrap').style.display = 'none'; } document.getElementById('ov-ausschr-detail').classList.add('open'); } function closeAuschrDetail() { document.getElementById('ov-ausschr-detail').classList.remove('open'); _curAeid=null; } async function setAuschrStatus(status) { if (!_curAeid) return; await fetch('/api/roadie/ausschreibungen/' + _curAeid + '/status', { method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({status:status}) }); await loadAusschreibungen(); openAuschrDetail(_curAeid); } async function auschrInPipeline() { var a = _ausschreibungen.find(function(x){ return x.id === _curAeid; }); if (!a) return; closeAuschrDetail(); var r = await fetch('/api/roadie/kunden/suche?q=' + encodeURIComponent(a.auftraggeber)); var d = await r.json(); var kunde = (d.kunden||[])[0]; if (!kunde) { var r2 = await fetch('/api/roadie/kunden', {method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({name:a.auftraggeber, notiz:'Öffentlicher Auftraggeber — Ausschreibung'})}); kunde = (await r2.json()).kunde; } await fetch('/api/roadie/angebote', {method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({kunde_id:kunde.id, titel:a.titel, beschreibung:a.beschreibung+(a.frist?' | Frist: '+fmtDate(a.frist):'')+(a.cpv?' | CPV: '+a.cpv:''), faellig:a.frist||null})}); await setAuschrStatus('beworben'); await Promise.all([loadAngebote(), loadDashboard()]); alert('✅ Als Angebot in die Pipeline übernommen!'); } function openNeuAusschr() { ['na-titel','na-ag','na-ort','na-beschr','na-cpv','na-url','na-frist'] .forEach(function(id){ document.getElementById(id).value=''; }); document.getElementById('ov-neu-ausschr').classList.add('open'); setTimeout(function(){ document.getElementById('na-titel').focus(); }, 100); } function closeNeuAusschr() { document.getElementById('ov-neu-ausschr').classList.remove('open'); } async function neuAusschrSpeichern() { var titel = document.getElementById('na-titel').value.trim(); if (!titel) { alert('Titel ist Pflicht.'); return; } await fetch('/api/roadie/ausschreibungen', {method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({titel:titel, auftraggeber:document.getElementById('na-ag').value.trim(), ort:document.getElementById('na-ort').value.trim(), frist:document.getElementById('na-frist').value||null, beschreibung:document.getElementById('na-beschr').value.trim(), cpv:document.getElementById('na-cpv').value.trim(), url:document.getElementById('na-url').value.trim()||null, status:'offen', quelle:'manuell'})}); closeNeuAusschr(); await loadAusschreibungen(); }