diff --git a/bootstrap/bootstrap.mjs b/bootstrap/bootstrap.mjs index a68cec4..ed0a031 100644 --- a/bootstrap/bootstrap.mjs +++ b/bootstrap/bootstrap.mjs @@ -292,7 +292,7 @@ const collections = [ f('envelope_text', 'text', { interface: 'input-multiline', note: 'Individueller Kuverttext (bei envelope_labeling = freitext).' }), f('envelope_sender', 'text', { interface: 'input-multiline', note: 'Absender fürs Kuvert (oben links, 5 Zeilen); manuelle Aufträge. Empfänger rutscht dann unten rechts.' }), f('envelope_sender_scale', 'float', { interface: 'input', default: 1, note: 'Relative Größe des Kuvert-Absenders (0.5–2, 1 = 100%).' }), - dropdown('envelope_format', ['c6', 'dinlang'], { note: 'Automatisch aus Format.' }), + dropdown('envelope_format', ['c6', 'dinlang', 'c4'], { note: 'Automatisch aus Format; c4 nur manueller Druck.' }), dropdown('motif_mode', ['katalog', 'upload', 'ohne', 'eigene_karten']), m2o('motif', 'motifs'), m2o('motif_upload', 'directus_files'), @@ -1009,6 +1009,8 @@ async function applySeed() { // C6 – v1 = Empfängeradresse, v2 = individuelle Beschriftung. { key: 'kuvert_b_v1', name: 'Kuvert C6 – Variante 1', type: 'umschlag', width: 4.49, height: 6.38, xpos: 4.2, ypos: -0.2, scale: 1.0, rotation: 90 }, { key: 'kuvert_b_v2', name: 'Kuvert C6 – Variante 2', type: 'umschlag', width: 4.33, height: 6.38, xpos: 4.0, ypos: -0.2, scale: 1.0, rotation: 90 }, + // C4 quer (324x229 mm = 12.76x9.02 Zoll). Querformat, maschinenseitig quer eingelegt (rotation 0). + { key: 'kuvert_c4_v1', name: 'Kuvert C4 quer', type: 'umschlag', width: 12.76, height: 9.02, xpos: -0.3, ypos: -0.3, scale: 1.0, rotation: 0 }, ]; // Nur bei LEERER Collection anlegen (Erstinstallation). Der Betreiber pflegt die // Templates danach selbst (löschen/umbenennen/eigene) – Bootstrap fügt sie NICHT @@ -1035,6 +1037,8 @@ async function applySeed() { { key: 'dinlang_karte', name: 'DIN lang (komplett beschrieben)', kind: 'brief', page_width_mm: 210, page_height_mm: 105, margin_top_mm: 8, margin_left_mm: 10, line_height_factor: 1.2, line_limit: 11, active: true }, { key: 'din_lang', name: 'DIN Lang Kuvert', kind: 'umschlag', page_width_mm: 220, page_height_mm: 110, margin_top_mm: 50, margin_left_mm: 10, line_height_factor: 1.2, active: true }, { key: 'c6', name: 'C6 Kuvert', kind: 'umschlag', page_width_mm: 162, page_height_mm: 114, margin_top_mm: 60, margin_left_mm: 10, line_height_factor: 1.2, active: true }, + // C4 quer (Querformat-Beschriftung, maschinenseitig quer eingelegt) – nur manueller Druck. + { key: 'c4', name: 'C4 Kuvert (quer)', kind: 'umschlag', page_width_mm: 324, page_height_mm: 229, margin_top_mm: 70, margin_left_mm: 20, line_height_factor: 1.2, active: true }, // Postkarten (nur manueller Druck): Text links, Absender+Empfänger rechts, // Briefmarkenfeld oben rechts frei. Ein SVG je Karte (ein Plotter-Durchlauf). { key: 'a6_postkarte', name: 'A6 Postkarte (Text + Adresse)', kind: 'postkarte', page_width_mm: 148, page_height_mm: 105, margin_top_mm: 8, margin_left_mm: 8, line_height_factor: 1.2, active: true }, diff --git a/extensions/directus-extension-skrift-orders/dist/index.js b/extensions/directus-extension-skrift-orders/dist/index.js index fb5ceed..a038048 100644 --- a/extensions/directus-extension-skrift-orders/dist/index.js +++ b/extensions/directus-extension-skrift-orders/dist/index.js @@ -1533,15 +1533,16 @@ 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 (Adresse aus der Anfrage) optional mitdrucken. - const ENV_FMT = { dinlang: 'din_lang', c6: 'c6' }; + // Kuvert (Empfänger aus der Anfrage, Absender optional als Freitext) mitdrucken. + const ENV_FMT = { dinlang: 'din_lang', c6: 'c6', c4: 'c4' }; 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 }); + letters.push({ index: 1, type: 'envelope', envelopeType: 'recipient', text: envAddr, format: envFormat, font, realisticHandwriting: body.realistic !== false, sender: envSender }); } const gen = await fetch(`${BACKEND_URL}/api/order/generate`, { @@ -1550,7 +1551,8 @@ const handler = (router, { services, getSchema, logger }) => { body: JSON.stringify({ orderNumber: ref, letters, - metadata: { rawText: String(body.text) }, + // envelopeSender: Backend rendert das Kuvert damit frisch (Absender oben links). + metadata: { rawText: String(body.text), envelopeSender: envSender }, }), }); if (!gen.ok) { diff --git a/extensions/directus-extension-skrift-produktion/dist/index.js b/extensions/directus-extension-skrift-produktion/dist/index.js index dd80709..272d809 100644 --- a/extensions/directus-extension-skrift-produktion/dist/index.js +++ b/extensions/directus-extension-skrift-produktion/dist/index.js @@ -26,9 +26,9 @@ import { useApi } from '@directus/extensions-sdk'; const LETTER_TPL = { a4: 'a4_single', a5p: 'a5_v1', a5l: 'a5l_v1', dinlang_karte: 'dl_v1', a6_hoch: 'a6_v1', a6_quer: 'a6l_v1' }; // v1 = Empfängeradresse (Standardvorschlag). Für individuelle Beschriftung // wählt der Operator im Popup die Variante 2 (kuvert_a_v2 / kuvert_b_v2). -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 Kuvert-Formatlabels (für Sammel-Druck + Format-Warteschlange). -const ENV_LABEL = { dinlang: 'DIN Lang', c6: 'C6' }; +const ENV_LABEL = { dinlang: 'DIN Lang', c6: 'C6', c4: 'C4' }; const INLAND = /^(de|deutschland|germany)$/i; // Versandtag → Wochentag (0=So…6=Sa). Für die Frist-Berechnung. @@ -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, msg: '', err: '' }); + kuvert: true, envFormat: 'dinlang', envTemplate: null, envSender: '', 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,10 +906,11 @@ 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. + // Adresse automatisch aufs Kuvert (Empfänger aus Tabelle, Absender aus Freitext). 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' : ''}.`); @@ -1829,10 +1830,15 @@ 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']].map(([v, l]) => h('option', { value: v, selected: manuell.envFormat === v }, l))) : null, + [['dinlang', 'DIN Lang'], ['c6', 'C6'], ['c4', 'C4 (quer)']].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('→ ' + (musterAdresse().replace(/\n/g, ', ') || 'keine Adresse')) : null, + manuell.kuvert ? subdued('Empfänger → ' + (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)))]),