diff --git a/bootstrap/bootstrap.mjs b/bootstrap/bootstrap.mjs index 6db504e..516d716 100644 --- a/bootstrap/bootstrap.mjs +++ b/bootstrap/bootstrap.mjs @@ -292,6 +292,7 @@ const collections = [ { field: 'production_status_changed_at', type: 'timestamp', meta: { interface: 'datetime', note: 'Zeitpunkt der letzten Produktionsstatus-Änderung (für „status_since" der Public-API).' }, schema: { is_nullable: true } }, dropdown('shipping_type', ['einzeln', 'sammel'], { default: 'sammel' }), f('needs_envelope', 'boolean', { interface: 'boolean', default: false }), + f('kuvertieren', 'boolean', { interface: 'boolean', default: true, note: 'Blatt wird ins Kuvert gelegt (kuvertiert). Leer/false = nur Kuvert beschriften, kein Blatt einlegen.' }), dropdown('envelope_labeling', ['empfaenger', 'freitext', 'keine']), 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.' }), diff --git a/extensions/directus-extension-skrift-produktion/dist/index.js b/extensions/directus-extension-skrift-produktion/dist/index.js index 3cd2c1b..202572c 100644 --- a/extensions/directus-extension-skrift-produktion/dist/index.js +++ b/extensions/directus-extension-skrift-produktion/dist/index.js @@ -195,7 +195,7 @@ function extras(e) { } function kundeName(o) { const c = o.customer || {}; - return [c.first_name, c.last_name].filter(Boolean).join(' ') || c.email || '—'; + return [c.first_name, c.last_name].filter(Boolean).join(' ') || c.company || c.email || o.api_client?.name || '—'; } const Board = defineComponent({ @@ -263,7 +263,7 @@ const Board = defineComponent({ // Basis-Felder ohne die evtl. noch nicht gebootstrapten Felder – diese // werden separat versucht, damit ein fehlendes Feld nicht das ganze Board sperrt. const ORDER_FELDER = 'id,order_number,order_name,status,payment_status,production_status,needs_envelope,envelope_format,' - + 'envelope_labeling,shipping_type,shipping_day,keep_contacts,entries_count,count_inland,count_ausland,brief_gedruckt,kuvert_gedruckt,frankiert,versanddatum,' + + 'envelope_labeling,shipping_type,shipping_day,keep_contacts,entries_count,count_inland,count_ausland,brief_gedruckt,kuvert_gedruckt,frankiert,kuvertieren,versanddatum,' + 'date_updated,date_created,format.key,format.name,product.name,product.type,product.input_mode,' + 'source,api_client.id,api_client.name,motif_mode,motif.name,shipping_address,' + 'source_file,internal_note,approval_status,approval_note,linked_order.id,linked_order.order_number,' @@ -1392,7 +1392,8 @@ const Board = defineComponent({ h('div', { style: 'display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:14px;' }, [ h('div', {}, [feldLabel('Versandart'), segToggle(o.shipping_type === 'einzeln' ? 'einzeln' : 'sammel', [{ key: 'einzeln', label: 'Einzelversand' }, { key: 'sammel', label: 'Sammelversand' }], (k) => setOrderFeld(o, { shipping_type: k }))]), h('div', {}, [feldLabel('Frankierung'), segToggle(((typeof o.frankiert === 'boolean') ? o.frankiert : (o.shipping_type !== 'sammel')) ? 'ja' : 'nein', [{ key: 'ja', label: 'Frankieren' }, { key: 'nein', label: 'Nicht' }], (k) => setOrderFeld(o, { frankiert: k === 'ja' }))]), - h('div', {}, [feldLabel('Kuvertierung'), segToggle(o.needs_envelope ? 'ja' : 'nein', [{ key: 'ja', label: 'Mit Kuvert' }, { key: 'nein', label: 'Ohne' }], (k) => setOrderFeld(o, { needs_envelope: k === 'ja' }))]), + h('div', {}, [feldLabel('Kuvert schreiben'), segToggle(o.needs_envelope ? 'ja' : 'nein', [{ key: 'ja', label: 'Mit Kuvert' }, { key: 'nein', label: 'Ohne' }], (k) => setOrderFeld(o, { needs_envelope: k === 'ja' }))]), + h('div', {}, [feldLabel('Blatt einlegen (kuvertieren)'), segToggle((o.kuvertieren !== false) ? 'ja' : 'nein', [{ key: 'ja', label: 'Blatt rein' }, { key: 'nein', label: 'Nur Kuvert' }], (k) => setOrderFeld(o, { kuvertieren: k === 'ja' }))]), h('div', {}, [feldLabel('Brief gedruckt'), segToggle(o.brief_gedruckt ? 'ja' : 'nein', [{ key: 'ja', label: 'Ja' }, { key: 'nein', label: 'Nein' }], (k) => setOrderFeld(o, { brief_gedruckt: k === 'ja' }))]), h('div', {}, [feldLabel('Kuvert gedruckt'), segToggle(o.kuvert_gedruckt ? 'ja' : 'nein', [{ key: 'ja', label: 'Ja' }, { key: 'nein', label: 'Nein' }], (k) => setOrderFeld(o, { kuvert_gedruckt: k === 'ja' }))]), ]), diff --git a/extensions/directus-extension-skrift-uebersicht/dist/index.js b/extensions/directus-extension-skrift-uebersicht/dist/index.js index b815841..dea2e34 100644 --- a/extensions/directus-extension-skrift-uebersicht/dist/index.js +++ b/extensions/directus-extension-skrift-uebersicht/dist/index.js @@ -66,15 +66,20 @@ const Board = { const aktiveMaschinen = computed(() => machines.value.filter((m) => m.active !== false)); function kundeName(o) { return [o.customer?.company, [o.customer?.first_name, o.customer?.last_name].filter(Boolean).join(' ')].filter(Boolean).join(' · '); } + // „Seite 1" o. Ä. = Seiten eines mehrseitigen Briefs, kein Empfänger. + const istSeitenmarker = (z) => /^seite\s*\d+$/i.test(String(z || '').trim()); + function freitextName(ft) { + const z = ft ? String(ft).split('\n').map((s) => s.trim()).filter(Boolean)[0] : ''; + return istSeitenmarker(z) ? '' : z; + } function empfKurz(e) { if (!e) return ''; - const name = e.company || [e.first_name, e.last_name].filter(Boolean).join(' ') - || (e.free_text ? String(e.free_text).split('\n').map((z) => z.trim()).filter(Boolean)[0] : ''); + const name = [e.first_name, e.last_name].filter(Boolean).join(' ') || freitextName(e.free_text); return [name, e.city].filter(Boolean).join(', '); } function entryName(e) { return [e.salutation, e.first_name, e.last_name].filter(Boolean).join(' ') - || e.company || (e.free_text ? String(e.free_text).split('\n')[0].trim() : '') || '—'; + || freitextName(e.free_text) || '—'; } async function laden(leise = false) { @@ -84,7 +89,7 @@ const Board = { api.get('/items/orders', { params: { limit: -1, sort: 'date_created', filter: { production_status: { _in: AKTIV_STATUS } }, - fields: 'id,order_number,order_name,production_status,needs_envelope,brief_gedruckt,kuvert_gedruckt,frankiert,' + fields: 'id,order_number,order_name,production_status,needs_envelope,kuvertieren,brief_gedruckt,kuvert_gedruckt,frankiert,' + 'format.key,format.name,shipping_day,shipping_type,versanddatum,date_created,entries_count,source,' + 'envelope_labeling,envelope_format,api_client.id,api_client.name,product.name,' + 'customer.first_name,customer.last_name,customer.company', @@ -282,10 +287,11 @@ const Board = { const fertig = ['versandfertig', 'versendet'].includes(o.production_status); const versendet = o.production_status === 'versendet'; const frankiert = (typeof o.frankiert === 'boolean') ? o.frankiert : (o.shipping_type !== 'sammel'); + const kuvertieren = !!o.needs_envelope && o.kuvertieren !== false; // nur Kuvert ohne Blatt → kein Kuvertieren const steps = [ ['Druck Schriftstück', true, !!o.brief_gedruckt], ['Druck Kuvert', !!o.needs_envelope, !!o.kuvert_gedruckt], - ['Kuvertieren', !!o.needs_envelope, fertig], + ['Kuvertieren', kuvertieren, fertig], ['Frankieren', !!frankiert, fertig], ['Versand', true, versendet], ]; @@ -313,13 +319,14 @@ const Board = { // Aggregierter Ablauf über alle Aufträge einer Charge. function ablaufStripAgg(orders) { const needEnv = orders.filter((o) => o.needs_envelope); + const needKuv = orders.filter((o) => o.needs_envelope && o.kuvertieren !== false); const needFrank = orders.filter((o) => (typeof o.frankiert === 'boolean') ? o.frankiert : (o.shipping_type !== 'sammel')); const alle = (arr, fn) => arr.length > 0 && arr.every(fn); const fertigOrder = (o) => ['versandfertig', 'versendet'].includes(o.production_status); const steps = [ ['Druck Schriftstück', true, alle(orders, (o) => !!o.brief_gedruckt)], ['Druck Kuvert', needEnv.length > 0, alle(needEnv, (o) => !!o.kuvert_gedruckt)], - ['Kuvertieren', needEnv.length > 0, alle(needEnv, fertigOrder)], + ['Kuvertieren', needKuv.length > 0, alle(needKuv, fertigOrder)], ['Frankieren', needFrank.length > 0, alle(needFrank, fertigOrder)], ['Versand', true, alle(orders, (o) => o.production_status === 'versendet')], ];