Kuvert-Absender (Feld direkt sichtbar), Textmengen-/Session-Aenderungen
- neuauftrag: Absenderfeld fuers Kuvert IMMER sichtbar (nicht mehr an 'Kuverts generieren' gebunden), Payloads (Vorschau + Anlage) reichen envelope_sender durch. - orders: manual-order speichert envelope_sender, Preview-Proxy reicht sender durch. - bootstrap: Feld envelope_sender. - (enthaelt weiterhin die Session-Aenderungen: signature-order, mehrseitige Vorschau, 'In manuellen Druck uebernehmen', gesendet-Nummern, Generierungs-Fehleranzeige, seitenumbruch-Hinweis.) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
46adf2a2f5
commit
46b5155c27
4 files changed
+179
-33
No files matched your search
@@ -78,14 +78,14 @@ const NeuAuftrag = defineComponent({
|
||||
// Mehrseitiges Schriftstück (Auto-Fluss über mehrere A4-Seiten).
|
||||
mehrseitig: false, seitenInfo: '',
|
||||
// Kuvert-Adresse je Empfänger: '5zeilen' (5 Zeilen) oder 'individuell' (einzeilig).
|
||||
adressModus: '5zeilen', kuverts: false, realistic: true, customer_email: '', text: '', rows: [leereZeile()],
|
||||
adressModus: '5zeilen', kuverts: false, envelopeSender: '', realistic: true, customer_email: '', text: '', rows: [leereZeile()],
|
||||
importOpen: false, importText: '',
|
||||
docs: [], previewSession: null, pLaedt: false, msg: '', err: '', hinweis: '', lb: '', lbDoc: null,
|
||||
});
|
||||
// Kuverts nur generieren, wenn angehakt (Beschriftung aus der Empfängeradresse).
|
||||
const kuvertPayload = () => (neu.kuverts
|
||||
? { needs_envelope: true, envelope_labeling: 'empfaenger', envelope_text: '' }
|
||||
: { needs_envelope: false, envelope_labeling: 'keine', envelope_text: '' });
|
||||
? { needs_envelope: true, envelope_labeling: 'empfaenger', envelope_text: '', envelope_sender: (neu.envelopeSender || '').trim() }
|
||||
: { needs_envelope: false, envelope_labeling: 'keine', envelope_text: '', envelope_sender: '' });
|
||||
|
||||
async function laden() {
|
||||
try {
|
||||
@@ -109,6 +109,35 @@ const NeuAuftrag = defineComponent({
|
||||
try { verbotenRe.value = wl ? new RegExp(`[^${wl}\\n\\r\\t]`, 'g') : null; } catch { verbotenRe.value = null; }
|
||||
neu.product = produkte.value[0]?.key || 'briefe';
|
||||
neu.format = neuFormate()[0]?.key || '';
|
||||
// Übernahme aus dem Produktions-Board (localStorage): Text/Format/Schrift
|
||||
// und alle Empfänger vorbefüllen, danach den Schlüssel wieder entfernen.
|
||||
try {
|
||||
const raw = localStorage.getItem('skrift_neuauftrag_uebernahme');
|
||||
if (raw) {
|
||||
localStorage.removeItem('skrift_neuauftrag_uebernahme');
|
||||
const d = JSON.parse(raw);
|
||||
if (d && typeof d === 'object') {
|
||||
if (d.product) neu.product = d.product;
|
||||
if (d.format) neu.format = d.format;
|
||||
if (d.font) neu.font = d.font;
|
||||
if (typeof d.text === 'string') neu.text = d.text;
|
||||
if (typeof d.multi_page === 'boolean') neu.mehrseitig = d.multi_page;
|
||||
if (typeof d.realistic === 'boolean') neu.realistic = d.realistic;
|
||||
if (d.fontSizeLetter) neu.fontSizeLetter = d.fontSizeLetter;
|
||||
if (d.fontSizeEnvelope) neu.fontSizeEnvelope = d.fontSizeEnvelope;
|
||||
if (typeof d.kuverts === 'boolean') neu.kuverts = d.kuverts;
|
||||
if (d.adressModus) neu.adressModus = d.adressModus;
|
||||
if (Array.isArray(d.rows) && d.rows.length) {
|
||||
neu.rows = d.rows.map((r) => ({
|
||||
free_text: String(r.free_text || ''),
|
||||
placeholders: (r.placeholders && typeof r.placeholders === 'object') ? { ...r.placeholders } : {},
|
||||
}));
|
||||
}
|
||||
neu.previewSession = null;
|
||||
neu.msg = 'Aus Auftrag übernommen – anpassen, dann Vorschau/Anlegen.';
|
||||
}
|
||||
}
|
||||
} catch { /* localStorage nicht verfügbar → ignorieren */ }
|
||||
} catch (e) {
|
||||
neu.err = e?.response?.data?.errors?.[0]?.message || e?.message || 'Laden fehlgeschlagen.';
|
||||
} finally { geladen.value = true; }
|
||||
@@ -237,7 +266,7 @@ const NeuAuftrag = defineComponent({
|
||||
const kv = kuvertPayload();
|
||||
const res = await api.post('/skrift-orders/preview', {
|
||||
text: neu.text, font: neu.font, format: neu.format, realistic: neu.realistic,
|
||||
envelope_labeling: kv.envelope_labeling, envelope_text: kv.envelope_text,
|
||||
envelope_labeling: kv.envelope_labeling, envelope_text: kv.envelope_text, envelope_sender: kv.envelope_sender,
|
||||
font_scale_letter: neu.fontSizeLetter / 100, font_scale_envelope: neu.fontSizeEnvelope / 100,
|
||||
multi_page: neu.mehrseitig,
|
||||
...briefSigPayload(),
|
||||
@@ -278,6 +307,33 @@ const NeuAuftrag = defineComponent({
|
||||
neu.err = e?.response?.data?.error || e?.message || 'Seitenzählung fehlgeschlagen.';
|
||||
}
|
||||
}
|
||||
// Das Backend generiert die Dokumente asynchron (fire-and-forget). Fehler
|
||||
// landen als status_history-Eintrag 'fehler' am Auftrag, Erfolg als 'in_queue'.
|
||||
// Wir pollen kurz und zeigen ein Problem DIREKT hier im Dashboard – statt dass
|
||||
// es still verschluckt wird und „nie Dokumente" entstehen.
|
||||
async function ueberwacheGenerierung(orderId, nr) {
|
||||
for (let i = 0; i < 20; i += 1) {
|
||||
await new Promise((r) => setTimeout(r, 1500));
|
||||
let sh = [];
|
||||
try {
|
||||
sh = (await api.get('/items/status_history', { params: {
|
||||
'filter[order][_eq]': orderId, sort: '-date_created', limit: 4, fields: 'status,note',
|
||||
} })).data?.data || [];
|
||||
} catch { continue; }
|
||||
const fehler = sh.find((s) => s.status === 'fehler');
|
||||
if (fehler) {
|
||||
neu.err = `Generierung fehlgeschlagen: ${fehler.note || 'unbekannter Grund'}`;
|
||||
neu.msg = '';
|
||||
return;
|
||||
}
|
||||
if (sh.some((s) => s.status === 'in_queue')) {
|
||||
neu.msg = `✓ Auftrag ${nr} angelegt & generiert – liegt im Produktions-Board unter „Neu". Felder bleiben stehen.`;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Kein eindeutiges Signal (langsame Generierung oder Datei-Produkt ohne Kuvert).
|
||||
neu.msg = `✓ Auftrag ${nr} angelegt – Dokumente werden noch generiert. Status im Produktions-Board prüfen.`;
|
||||
}
|
||||
async function absenden() {
|
||||
// Empfänger sind optional – ohne Empfänger genau ein Schriftstück (Blankozeile).
|
||||
const ent = entries();
|
||||
@@ -291,16 +347,19 @@ const NeuAuftrag = defineComponent({
|
||||
font_scale_letter: neu.fontSizeLetter / 100, font_scale_envelope: neu.fontSizeEnvelope / 100,
|
||||
multi_page: neu.mehrseitig,
|
||||
...briefSigPayload(),
|
||||
needs_envelope: kv.needs_envelope, envelope_labeling: kv.envelope_labeling, envelope_text: kv.envelope_text,
|
||||
needs_envelope: kv.needs_envelope, envelope_labeling: kv.envelope_labeling, envelope_text: kv.envelope_text, envelope_sender: kv.envelope_sender,
|
||||
shipping_type: 'sammel',
|
||||
customer_email: neu.customer_email.trim() || undefined,
|
||||
text_template: neu.text, preview_session: neu.previewSession || undefined,
|
||||
entries: payloadEntries,
|
||||
});
|
||||
const nr = res.data?.order_number || '';
|
||||
const oid = res.data?.id;
|
||||
// Felder bewusst NICHT zurücksetzen – der letzte Auftrag bleibt stehen,
|
||||
// damit er sich als Vorlage für den nächsten leicht anpassen lässt.
|
||||
neu.msg = `✓ Auftrag ${nr} angelegt – liegt im Produktions-Board unter „Neu". Felder bleiben stehen; mit „Formular leeren" zurücksetzen.`;
|
||||
neu.msg = `✓ Auftrag ${nr} angelegt – Dokumente werden generiert …`;
|
||||
// Generierung im Hintergrund überwachen; ein Backend-Fehler erscheint dann hier.
|
||||
if (oid) ueberwacheGenerierung(oid, nr);
|
||||
} catch (e) { neu.err = e?.response?.data?.error || e?.message || 'Anlegen fehlgeschlagen.'; neu.msg = ''; }
|
||||
}
|
||||
function zuruecksetzen() {
|
||||
@@ -308,7 +367,7 @@ const NeuAuftrag = defineComponent({
|
||||
product: produkte.value[0]?.key || 'briefe', format: neuFormate()[0]?.key || '', font: 'tilda',
|
||||
fontSizeLetter: 100, fontSizeEnvelope: 100,
|
||||
sigSvg: '', sigLabel: '', sigX: 0, sigY: 0, sigScale: 100, mehrseitig: false, seitenInfo: '',
|
||||
adressModus: '5zeilen', kuverts: false, realistic: true, customer_email: '', text: '', rows: [leereZeile()],
|
||||
adressModus: '5zeilen', kuverts: false, envelopeSender: '', realistic: true, customer_email: '', text: '', rows: [leereZeile()],
|
||||
importOpen: false, importText: '',
|
||||
docs: [], previewSession: null, pLaedt: false, msg: '', err: '', hinweis: '', lb: '',
|
||||
});
|
||||
@@ -449,6 +508,17 @@ const NeuAuftrag = defineComponent({
|
||||
h('input', { type: 'checkbox', checked: neu.kuverts, onChange: (e) => { neu.kuverts = e.target.checked; neu.previewSession = null; }, style: 'width:16px;height:16px;' }),
|
||||
'Kuverts generieren',
|
||||
]),
|
||||
h('div', { style: 'margin-top:14px;' }, [
|
||||
label('Absender aufs Kuvert (oben links, max. 5 Zeilen, optional)'),
|
||||
h('textarea', {
|
||||
value: neu.envelopeSender, rows: 5,
|
||||
placeholder: 'Max Mustermann\nMusterstraße 1\n12345 Musterstadt',
|
||||
style: WFELD + 'width:100%;font-family:var(--family-monospace,monospace);',
|
||||
onInput: (e) => { neu.envelopeSender = saeubere(String(e.target.value)).split('\n').slice(0, 5).join('\n'); neu.previewSession = null; },
|
||||
}),
|
||||
h('div', { style: 'font-size:11px;color:var(--foreground-subdued,#888);margin-top:4px;line-height:1.5;' },
|
||||
'Ist ein Absender gesetzt, rutscht der Empfänger auf dem Kuvert automatisch nach unten rechts. Wirkt nur, wenn „Kuverts generieren" aktiv ist.'),
|
||||
]),
|
||||
neu.importOpen ? h('div', { style: 'margin-top:12px;' }, [
|
||||
subdued('Aus Excel kopieren und einfügen – eine Zeile pro Empfänger, Spalten mit Tab/Semikolon/Komma. '
|
||||
+ 'Reihenfolge: erst individuelle Platzhalter, dann ' + (neu.adressModus === 'individuell' ? 'die eine Adresszeile.' : 'Zeile 1–5.'), 'margin-bottom:6px;'),
|
||||
@@ -478,6 +548,8 @@ const NeuAuftrag = defineComponent({
|
||||
neu.previewSession = null;
|
||||
requestAnimationFrame(() => { try { ta.selectionStart = ta.selectionEnd = s + 1; } catch {} });
|
||||
} }),
|
||||
h('div', { style: 'font-size:11px;color:var(--foreground-subdued,#888);margin-top:4px;line-height:1.5;' },
|
||||
'Tipp: [[seitenumbruch]] erzwingt an dieser Stelle eine neue Seite (mehrseitiger Brief). [[signatur1]] setzt die Unterschrift.'),
|
||||
// ── Unterschrift auf den Brief ─────────────────────────────────────
|
||||
h('div', { style: 'margin-top:16px;border-top:1px solid rgba(30,80,165,.15);padding-top:14px;' }, [
|
||||
label('Unterschrift auf den Brief (optional) · Platzhalter [[signatur1]]'),
|
||||
|
||||
Reference in new issue
Block a user