From bbbc637a810cae725f8bb3c3538fe010c83943a3 Mon Sep 17 00:00:00 2001 From: s4luorth Date: Wed, 30 Sep 2026 12:07:07 +0200 Subject: [PATCH] C4-Kuvert NUR im Neuauftrag-Formular waehlbar - neuauftrag: neues Dropdown "Kuvertformat" (Automatisch/DIN Lang/C6/C4 quer), envelope_format an Preview + manual-order durchgereicht. - orders /preview: honoriert body.envelope_format (statt hart A4->DIN/A6->C6), ENVELOPE_TPL/ENV_LABEL um c4 (Template-Aufloesung, kein Selektor). - produktion: C4-Option + Absenderfeld im Muster-Popup wieder entfernt (C4 gibt es ausschliesslich im Neuauftrag). Co-Authored-By: Claude Opus 4.8 --- .../dist/index.js | 14 +++++++++++-- .../dist/index.js | 21 ++++++++++--------- .../dist/index.js | 14 ++++--------- 3 files changed, 27 insertions(+), 22 deletions(-) diff --git a/extensions/directus-extension-skrift-neuauftrag/dist/index.js b/extensions/directus-extension-skrift-neuauftrag/dist/index.js index 4f19fb3..712ab8e 100644 --- a/extensions/directus-extension-skrift-neuauftrag/dist/index.js +++ b/extensions/directus-extension-skrift-neuauftrag/dist/index.js @@ -81,6 +81,8 @@ const NeuAuftrag = defineComponent({ mehrseitig: false, seitenInfo: '', // Kuvert-Adresse je Empfänger: '5zeilen' (5 Zeilen) oder 'individuell' (einzeilig). adressModus: '5zeilen', kuverts: true, absenderAufKuvert: false, envelopeSender: '', envelopeSenderScale: 100, realistic: true, customer_email: '', text: '', rows: [leereZeile()], + // Kuvertformat: '' = automatisch (A4→DIN Lang, A6→C6), sonst dinlang/c6/c4. + envFormat: '', // Ohne Kuvert & ohne eigene Platzhalter: einfach N identische Schriftstücke. anzahl: 1, importOpen: false, importText: '', @@ -100,7 +102,8 @@ const NeuAuftrag = defineComponent({ return neu.kuverts ? { needs_envelope: true, envelope_labeling: 'empfaenger', envelope_text: '', envelope_sender: neu.absenderAufKuvert ? (neu.envelopeSender || '').trim() : '', - envelope_sender_scale: (Number(neu.envelopeSenderScale) || 100) / 100 } + envelope_sender_scale: (Number(neu.envelopeSenderScale) || 100) / 100, + envelope_format: neu.envFormat || undefined } : { needs_envelope: false, envelope_labeling: 'keine', envelope_text: '', envelope_sender: '', envelope_sender_scale: 1 }; }; @@ -322,6 +325,7 @@ const NeuAuftrag = defineComponent({ 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_sender: kv.envelope_sender, envelope_sender_scale: kv.envelope_sender_scale, + envelope_format: kv.envelope_format, font_scale_letter: neu.fontSizeLetter / 100, font_scale_envelope: neu.fontSizeEnvelope / 100, multi_page: neu.mehrseitig, ...briefSigPayload(), @@ -409,6 +413,7 @@ const NeuAuftrag = defineComponent({ multi_page: neu.mehrseitig, ...briefSigPayload(), needs_envelope: kv.needs_envelope, envelope_labeling: kv.envelope_labeling, envelope_text: kv.envelope_text, envelope_sender: kv.envelope_sender, envelope_sender_scale: kv.envelope_sender_scale, + envelope_format: kv.envelope_format, shipping_type: 'sammel', customer_email: neu.customer_email.trim() || undefined, text_template: neu.text, preview_session: neu.previewSession || undefined, @@ -428,7 +433,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: true, absenderAufKuvert: false, envelopeSender: '', envelopeSenderScale: 100, realistic: true, customer_email: '', text: '', rows: [leereZeile()], + adressModus: '5zeilen', kuverts: true, absenderAufKuvert: false, envelopeSender: '', envelopeSenderScale: 100, envFormat: '', realistic: true, customer_email: '', text: '', rows: [leereZeile()], anzahl: 1, importOpen: false, importText: '', docs: [], previewSession: null, pLaedt: false, msg: '', err: '', hinweis: '', lb: '', @@ -589,6 +594,11 @@ 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', ]) : null, + (!istPostkarte() && neu.kuverts) ? h('div', { style: 'margin-top:8px;max-width:280px;' }, [ + label('Kuvertformat'), + h('select', { value: neu.envFormat, style: WFELD + 'width:100%;', onChange: (e) => { neu.envFormat = e.target.value; neu.previewSession = null; } }, + [['', 'Automatisch (A4 → DIN Lang, A6 → C6)'], ['dinlang', 'DIN Lang'], ['c6', 'C6'], ['c4', 'C4 (quer)']].map(([v, l]) => h('option', { value: v, selected: neu.envFormat === v }, l))), + ]) : null, (!istPostkarte() && neu.kuverts) ? h('label', { style: 'display:flex;align-items:center;gap:8px;font-size:14px;cursor:pointer;margin-top:8px;' }, [ h('input', { type: 'checkbox', checked: neu.absenderAufKuvert, onChange: (e) => { neu.absenderAufKuvert = e.target.checked; neu.previewSession = null; }, style: 'width:16px;height:16px;' }), 'Absender aufs Kuvert (oben links)', diff --git a/extensions/directus-extension-skrift-orders/dist/index.js b/extensions/directus-extension-skrift-orders/dist/index.js index 0d0f67a..3c18cf7 100644 --- a/extensions/directus-extension-skrift-orders/dist/index.js +++ b/extensions/directus-extension-skrift-orders/dist/index.js @@ -733,8 +733,11 @@ const handler = (router, { services, getSchema, logger }) => { // Formate) unverändert durchreichen – das Backend kennt sie aus render_formats. const LETTER_FORMAT = { a4: 'a4', a6_hoch: 'a6p', a6_quer: 'a6l' }; const briefFormat = LETTER_FORMAT[body.format] || body.format || 'a4'; - // A4 → DIN Lang, A6 → C6 - const umschlagFormat = briefFormat === 'a4' ? 'din_lang' : 'c6'; + // Kuvertformat: explizit gewählt (dinlang/c6/c4) hat Vorrang, sonst A4 → DIN Lang, A6 → C6. + const ENV_FMT_PV = { dinlang: 'din_lang', c6: 'c6', c4: 'c4' }; + const umschlagFormat = body.envelope_format + ? (ENV_FMT_PV[body.envelope_format] || body.envelope_format) + : (briefFormat === 'a4' ? 'din_lang' : 'c6'); // Postkarte (Text links, Adresse rechts, ein SVG) – Erkennung über render_formats.kind. const istPk = (await svc('render_formats').readByQuery({ filter: { key: { _eq: briefFormat } }, limit: 1, fields: ['kind'], @@ -1213,10 +1216,10 @@ const handler = (router, { services, getSchema, logger }) => { // Legt pro Typ (Schriftstück / Umschlag) einen Job mit aufgelöstem Template // für die gewählte Maschine an. Kein Statuswechsel am Auftrag (bewusst). const LETTER_TPL = { a4: 'a4_single', a6_hoch: 'a6_v1', a6_quer: 'a6l_v1' }; - const ENVELOPE_TPL = { dinlang: 'kuvert_a_v1', c6: 'kuvert_b_v1' }; + const ENVELOPE_TPL = { dinlang: 'kuvert_a_v1', c6: 'kuvert_b_v1', c4: 'kuvert_c4_v1' }; // Lesbare Labels + Format-Schlüssel je Job-Typ. Der Schlüssel steuert die // Format-Warteschlange (Agent druckt nur Jobs mit passendem machines.current_format). - const ENV_LABEL = { dinlang: 'DIN Lang', c6: 'C6' }; + const ENV_LABEL = { dinlang: 'DIN Lang', c6: 'C6', c4: 'C4' }; const LETTER_LABEL = { a4: 'A4', a6_hoch: 'A6 hoch', a6_quer: 'A6 quer' }; const briefFormatOf = (order) => ({ key: order.format?.key || 'a4', label: order.format?.name || LETTER_LABEL[order.format?.key] || order.format?.key || 'A4' }); const umschlagFormatOf = (order) => ({ key: order.envelope_format || 'c6', label: ENV_LABEL[order.envelope_format] || order.envelope_format || 'C6' }); @@ -1535,16 +1538,15 @@ const handler = (router, { services, getSchema, logger }) => { const font = ['tilda', 'alva', 'ellie'].includes(body.font) ? body.font : 'tilda'; const format = TEST_FORMAT[body.format] || 'a4'; - // Kuvert (Empfänger aus der Anfrage, Absender optional als Freitext) mitdrucken. - const ENV_FMT = { dinlang: 'din_lang', c6: 'c6', c4: 'c4' }; + // Kuvert (Adresse aus der Anfrage) optional mitdrucken. + const ENV_FMT = { dinlang: 'din_lang', c6: 'c6' }; const envAddr = clean(String(body.envelope || '')).trim(); const wantsEnv = !!(envAddr && body.envelope_template); const envFormat = ENV_FMT[body.envelope_format] || 'din_lang'; - const envSender = clean(String(body.envelope_sender || '')).trim(); const letters = [{ index: 1, type: 'letter', text: clean(String(body.text)), format, font, realisticHandwriting: body.realistic !== false }]; if (wantsEnv) { - letters.push({ index: 1, type: 'envelope', envelopeType: 'recipient', text: envAddr, format: envFormat, font, realisticHandwriting: body.realistic !== false, sender: envSender }); + letters.push({ index: 1, type: 'envelope', envelopeType: 'recipient', text: envAddr, format: envFormat, font, realisticHandwriting: body.realistic !== false }); } const gen = await fetch(`${BACKEND_URL}/api/order/generate`, { @@ -1553,8 +1555,7 @@ const handler = (router, { services, getSchema, logger }) => { body: JSON.stringify({ orderNumber: ref, letters, - // envelopeSender: Backend rendert das Kuvert damit frisch (Absender oben links). - metadata: { rawText: String(body.text), envelopeSender: envSender }, + metadata: { rawText: String(body.text) }, }), }); if (!gen.ok) { diff --git a/extensions/directus-extension-skrift-produktion/dist/index.js b/extensions/directus-extension-skrift-produktion/dist/index.js index 272d809..676933e 100644 --- a/extensions/directus-extension-skrift-produktion/dist/index.js +++ b/extensions/directus-extension-skrift-produktion/dist/index.js @@ -204,7 +204,7 @@ const Board = defineComponent({ const druck = reactive({ open: false, order: null, machine: null, mode: 'queue', busy: false, brief: null, umschlag: null, spaltenweise: false, msg: '', err: '', deNums: '', intNums: '', deN: 0, intN: 0 }); const manuell = reactive({ open: false, req: null, form: 'sie', vorlageId: '', roh: '', font: 'tilda', format: 'a4', template: null, machine: null, mode: 'queue', text: '', // Adresse automatisch aufs Kuvert (Standard an) + eigenes Kuvert-Template/-Format. - kuvert: true, envFormat: 'dinlang', envTemplate: null, envSender: '', msg: '', err: '' }); + kuvert: true, envFormat: 'dinlang', envTemplate: null, msg: '', err: '' }); const empf = reactive({ open: false, mode: 'order', titel: '', order: null, suche: '', rows: [], files: [], info: '', laden: false, selected: null, pl: '', pe: '', pLoad: false, perr: '', lb: '', lbTitel: '' }); // Massenauswahl (Auftrags-IDs) + Sammel-Druck-Popup (pro Format Template+Maschine). @@ -906,11 +906,10 @@ const Board = defineComponent({ text: manuell.text, font: manuell.font, format: manuell.format, template: manuell.template, machine: manuell.machine, mode: manuell.mode, offer_request: manuell.req?.id || null, - // Adresse automatisch aufs Kuvert (Empfänger aus Tabelle, Absender aus Freitext). + // Adresse automatisch aufs Kuvert. envelope: manuell.kuvert ? musterAdresse() : '', envelope_format: manuell.kuvert ? manuell.envFormat : '', envelope_template: manuell.kuvert ? manuell.envTemplate : null, - envelope_sender: manuell.kuvert ? String(manuell.envSender || '').trim() : '', }); const modus = res.data?.mode === 'direct' ? 'Direktdruck' : 'Warteschlange'; flash(`Muster erzeugt & eingereiht (${modus})${manuell.kuvert ? ' inkl. Kuvert' : ''}.`); @@ -1830,15 +1829,10 @@ const Board = defineComponent({ '✉ Adresse aufs Kuvert', ]), manuell.kuvert ? h('select', { style: S_SELECT + 'width:auto;', value: manuell.envFormat, onChange: (e) => { manuell.envFormat = e.target.value; manuell.envTemplate = tplForFormat(e.target.value, 'umschlag')?.id ?? manuell.envTemplate; } }, - [['dinlang', 'DIN Lang'], ['c6', 'C6'], ['c4', 'C4 (quer)']].map(([v, l]) => h('option', { value: v, selected: manuell.envFormat === v }, l))) : null, + [['dinlang', 'DIN Lang'], ['c6', 'C6']].map(([v, l]) => h('option', { value: v, selected: manuell.envFormat === v }, l))) : null, manuell.kuvert ? h('select', { style: S_SELECT + 'flex:1;min-width:160px;', value: manuell.envTemplate, onChange: (e) => { manuell.envTemplate = e.target.value; } }, umschlagTpls.map((t) => h('option', { value: t.id, selected: String(manuell.envTemplate) === String(t.id) }, t.name))) : null, - manuell.kuvert ? subdued('Empfänger → ' + (musterAdresse().replace(/\n/g, ', ') || 'keine Adresse')) : null, + manuell.kuvert ? subdued('→ ' + (musterAdresse().replace(/\n/g, ', ') || 'keine Adresse')) : null, ]), - // Absender aufs Kuvert (oben links) – Freitext, 5 Zeilen. Empfänger kommt aus der Tabelle. - manuell.kuvert ? h('div', { style: 'display:flex;flex-direction:column;gap:4px;background:var(--background-subdued,#f1f4f9);border-radius:8px;padding:10px 12px;' }, [ - h('label', { style: 'font-size:11px;color:var(--foreground-subdued);' }, '✉ Absender (oben links, optional, max. 5 Zeilen)'), - h('textarea', { style: S_INPUT + 'width:100%;min-height:96px;font-family:var(--family-monospace,monospace);', placeholder: 'Absender Zeile 1\n…', value: manuell.envSender, onInput: (e) => { manuell.envSender = e.target.value.split('\n').slice(0, 5).join('\n'); } }), - ]) : null, h('div', { style: 'display:grid;grid-template-columns:repeat(4,1fr);gap:8px;' }, [ h('div', {}, [h('label', { style: 'font-size:11px;color:var(--foreground-subdued);' }, 'Schrift'), h('select', { style: S_SELECT + 'width:100%;', value: manuell.font, onChange: (e) => { manuell.font = e.target.value; } }, ['tilda', 'alva', 'ellie'].map((f) => h('option', { value: f, selected: manuell.font === f }, f)))]),