Auftragsname (Zusatz) + Signatur-Abstand-Feld im Neuauftrag
- orders.order_name (optionaler Auftragsname); im Neuauftrag setzbar, auf der Board-Karte als Eyebrow ueber dem Namen angezeigt; in manual-order gespeichert. - Neuauftrag: Signatur-Feld "Abstand (mm)" (leer = Standard halber Zeilenabstand), via signature_offsets.spacing durchgereicht. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -252,6 +252,7 @@ const collections = [
|
|||||||
|
|
||||||
{ collection: 'orders', meta: { icon: 'receipt_long', note: 'Auftrag.' }, fields: [
|
{ collection: 'orders', meta: { icon: 'receipt_long', note: 'Auftrag.' }, fields: [
|
||||||
f('order_number', 'string', { interface: 'input', unique: true, required: true }),
|
f('order_number', 'string', { interface: 'input', unique: true, required: true }),
|
||||||
|
f('order_name', 'string', { interface: 'input', note: 'Optionaler Auftragsname (z. B. „EinDollarBrille Dankeskarten"). Wird zusätzlich zur Nummer angezeigt.' }),
|
||||||
m2o('customer', 'directus_users', { note: 'Kunde = Login-Konto (Zuordnung per E-Mail).' }),
|
m2o('customer', 'directus_users', { note: 'Kunde = Login-Konto (Zuordnung per E-Mail).' }),
|
||||||
f('customer_email', 'string', { interface: 'input', required: true, note: 'Zuordnungsschlüssel.' }),
|
f('customer_email', 'string', { interface: 'input', required: true, note: 'Zuordnungsschlüssel.' }),
|
||||||
m2o('product', 'products'),
|
m2o('product', 'products'),
|
||||||
|
|||||||
@@ -72,11 +72,11 @@ const NeuAuftrag = defineComponent({
|
|||||||
|
|
||||||
const leereZeile = () => ({ free_text: '', placeholders: {} });
|
const leereZeile = () => ({ free_text: '', placeholders: {} });
|
||||||
const neu = reactive({
|
const neu = reactive({
|
||||||
product: '', format: '', font: 'tilda',
|
product: '', format: '', font: 'tilda', orderName: '',
|
||||||
// Relative Schriftgröße in % (getrennt Brief/Kuvert); 100 = Standard.
|
// Relative Schriftgröße in % (getrennt Brief/Kuvert); 100 = Standard.
|
||||||
fontSizeLetter: 100, fontSizeEnvelope: 100,
|
fontSizeLetter: 100, fontSizeEnvelope: 100,
|
||||||
// Unterschrift auf dem Brief ([[signatur1]]): SVG-Inhalt + Feinjustierung.
|
// Unterschrift auf dem Brief ([[signatur1]]): SVG-Inhalt + Feinjustierung.
|
||||||
sigSvg: '', sigLabel: '', sigX: 0, sigY: 0, sigScale: 100,
|
sigSvg: '', sigLabel: '', sigX: 0, sigY: 0, sigScale: 100, sigSpacing: '',
|
||||||
// Mehrseitiges Schriftstück (Auto-Fluss über mehrere A4-Seiten).
|
// Mehrseitiges Schriftstück (Auto-Fluss über mehrere A4-Seiten).
|
||||||
mehrseitig: false, seitenInfo: '',
|
mehrseitig: false, seitenInfo: '',
|
||||||
// Kuvert-Adresse je Empfänger: '5zeilen' (5 Zeilen) oder 'individuell' (einzeilig).
|
// Kuvert-Adresse je Empfänger: '5zeilen' (5 Zeilen) oder 'individuell' (einzeilig).
|
||||||
@@ -311,7 +311,11 @@ const NeuAuftrag = defineComponent({
|
|||||||
// bereits ein sigPayload() für den Unterschriften-Service (PDF) gibt.
|
// bereits ein sigPayload() für den Unterschriften-Service (PDF) gibt.
|
||||||
const briefSigPayload = () => (neu.sigSvg
|
const briefSigPayload = () => (neu.sigSvg
|
||||||
? { signatures: { signatur1: neu.sigSvg },
|
? { signatures: { signatur1: neu.sigSvg },
|
||||||
signature_offsets: { signatur1: { x: Number(neu.sigX) || 0, y: Number(neu.sigY) || 0, scale: (Number(neu.sigScale) || 100) / 100 } } }
|
signature_offsets: { signatur1: {
|
||||||
|
x: Number(neu.sigX) || 0, y: Number(neu.sigY) || 0, scale: (Number(neu.sigScale) || 100) / 100,
|
||||||
|
// Abstand in mm (leer = Backend-Default = halber Zeilenabstand).
|
||||||
|
...(String(neu.sigSpacing).trim() !== '' ? { spacing: Number(neu.sigSpacing) || 0 } : {}),
|
||||||
|
} } }
|
||||||
: {});
|
: {});
|
||||||
|
|
||||||
async function preview() {
|
async function preview() {
|
||||||
@@ -407,7 +411,7 @@ const NeuAuftrag = defineComponent({
|
|||||||
try {
|
try {
|
||||||
const kv = kuvertPayload();
|
const kv = kuvertPayload();
|
||||||
const res = await api.post('/skrift-orders/manual-order', {
|
const res = await api.post('/skrift-orders/manual-order', {
|
||||||
product: neu.product, format: neu.format, font: neu.font,
|
product: neu.product, format: neu.format, font: neu.font, order_name: neu.orderName.trim() || undefined,
|
||||||
realistic: neu.realistic,
|
realistic: neu.realistic,
|
||||||
font_scale_letter: neu.fontSizeLetter / 100, font_scale_envelope: neu.fontSizeEnvelope / 100,
|
font_scale_letter: neu.fontSizeLetter / 100, font_scale_envelope: neu.fontSizeEnvelope / 100,
|
||||||
multi_page: neu.mehrseitig,
|
multi_page: neu.mehrseitig,
|
||||||
@@ -430,9 +434,9 @@ const NeuAuftrag = defineComponent({
|
|||||||
}
|
}
|
||||||
function zuruecksetzen() {
|
function zuruecksetzen() {
|
||||||
Object.assign(neu, {
|
Object.assign(neu, {
|
||||||
product: produkte.value[0]?.key || 'briefe', format: neuFormate()[0]?.key || '', font: 'tilda',
|
product: produkte.value[0]?.key || 'briefe', format: neuFormate()[0]?.key || '', font: 'tilda', orderName: '',
|
||||||
fontSizeLetter: 100, fontSizeEnvelope: 100,
|
fontSizeLetter: 100, fontSizeEnvelope: 100,
|
||||||
sigSvg: '', sigLabel: '', sigX: 0, sigY: 0, sigScale: 100, mehrseitig: false, seitenInfo: '',
|
sigSvg: '', sigLabel: '', sigX: 0, sigY: 0, sigScale: 100, sigSpacing: '', mehrseitig: false, seitenInfo: '',
|
||||||
adressModus: '5zeilen', kuverts: true, absenderAufKuvert: false, envelopeSender: '', envelopeSenderScale: 100, envFormat: '', 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,
|
anzahl: 1,
|
||||||
importOpen: false, importText: '',
|
importOpen: false, importText: '',
|
||||||
@@ -672,10 +676,11 @@ const NeuAuftrag = defineComponent({
|
|||||||
h('span', { style: `color:${ACCENT};font-size:13px;font-weight:600;` }, `✓ ${neu.sigLabel} – als [[signatur1]] im Text`),
|
h('span', { style: `color:${ACCENT};font-size:13px;font-weight:600;` }, `✓ ${neu.sigLabel} – als [[signatur1]] im Text`),
|
||||||
btn('Entfernen', sigEntfernen),
|
btn('Entfernen', sigEntfernen),
|
||||||
]),
|
]),
|
||||||
h('div', { style: 'display:grid;grid-template-columns:1fr 1fr 1fr;gap:12px;' }, [
|
h('div', { style: 'display:grid;grid-template-columns:1fr 1fr 1fr 1fr;gap:12px;' }, [
|
||||||
h('div', {}, [label('Versatz X (mm)'), h('input', { type: 'number', step: 1, value: neu.sigX, style: WFELD + 'width:100%;', onInput: (e) => { neu.sigX = e.target.value; neu.previewSession = null; } })]),
|
h('div', {}, [label('Versatz X (mm)'), h('input', { type: 'number', step: 1, value: neu.sigX, style: WFELD + 'width:100%;', onInput: (e) => { neu.sigX = e.target.value; neu.previewSession = null; } })]),
|
||||||
h('div', {}, [label('Versatz Y (mm)'), h('input', { type: 'number', step: 1, value: neu.sigY, style: WFELD + 'width:100%;', onInput: (e) => { neu.sigY = e.target.value; neu.previewSession = null; } })]),
|
h('div', {}, [label('Versatz Y (mm)'), h('input', { type: 'number', step: 1, value: neu.sigY, style: WFELD + 'width:100%;', onInput: (e) => { neu.sigY = e.target.value; neu.previewSession = null; } })]),
|
||||||
h('div', {}, [label('Größe (%)'), h('input', { type: 'number', step: 5, value: neu.sigScale, style: WFELD + 'width:100%;', onInput: (e) => { neu.sigScale = e.target.value; neu.previewSession = null; } })]),
|
h('div', {}, [label('Größe (%)'), h('input', { type: 'number', step: 5, value: neu.sigScale, style: WFELD + 'width:100%;', onInput: (e) => { neu.sigScale = e.target.value; neu.previewSession = null; } })]),
|
||||||
|
h('div', {}, [label('Abstand (mm)'), h('input', { type: 'number', step: 1, min: 0, placeholder: 'Standard', value: neu.sigSpacing, style: WFELD + 'width:100%;', onInput: (e) => { neu.sigSpacing = e.target.value; neu.previewSession = null; } })]),
|
||||||
]),
|
]),
|
||||||
subdued('Positiv X = nach rechts, positiv Y = nach unten. Nach dem Anpassen „Aktualisieren" in der Vorschau klicken.', 'margin-top:8px;'),
|
subdued('Positiv X = nach rechts, positiv Y = nach unten. Nach dem Anpassen „Aktualisieren" in der Vorschau klicken.', 'margin-top:8px;'),
|
||||||
]) : null,
|
]) : null,
|
||||||
@@ -685,10 +690,16 @@ const NeuAuftrag = defineComponent({
|
|||||||
// Bereich 4 – Kunde
|
// Bereich 4 – Kunde
|
||||||
const b4 = h('div', { style: BEREICH }, [
|
const b4 = h('div', { style: BEREICH }, [
|
||||||
bereichKopf('👤 Kunde'),
|
bereichKopf('👤 Kunde'),
|
||||||
h('div', { style: 'max-width:420px;' }, [
|
h('div', { style: 'display:flex;gap:16px;flex-wrap:wrap;' }, [
|
||||||
|
h('div', { style: 'flex:1 1 280px;max-width:420px;' }, [
|
||||||
|
label('Auftragsname (optional)'),
|
||||||
|
h('input', { type: 'text', value: neu.orderName, placeholder: 'z. B. EinDollarBrille Dankeskarten', style: WFELD + 'width:100%;', onInput: (e) => { neu.orderName = e.target.value; } }),
|
||||||
|
]),
|
||||||
|
h('div', { style: 'flex:1 1 280px;max-width:420px;' }, [
|
||||||
label('Kunde verknüpfen (E-Mail, optional)'),
|
label('Kunde verknüpfen (E-Mail, optional)'),
|
||||||
h('input', { type: 'email', value: neu.customer_email, placeholder: 'kunde@example.de', style: WFELD + 'width:100%;', onInput: (e) => { neu.customer_email = e.target.value; } }),
|
h('input', { type: 'email', value: neu.customer_email, placeholder: 'kunde@example.de', style: WFELD + 'width:100%;', onInput: (e) => { neu.customer_email = e.target.value; } }),
|
||||||
]),
|
]),
|
||||||
|
]),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const aktionen = h('div', { class: 'sk-btnrow', style: 'display:flex;gap:8px;flex-wrap:wrap;' }, [
|
const aktionen = h('div', { class: 'sk-btnrow', style: 'display:flex;gap:8px;flex-wrap:wrap;' }, [
|
||||||
|
|||||||
@@ -2083,6 +2083,7 @@ const handler = (router, { services, getSchema, logger }) => {
|
|||||||
|
|
||||||
const orderData = {
|
const orderData = {
|
||||||
customer: customerId, customer_email: customerEmail,
|
customer: customerId, customer_email: customerEmail,
|
||||||
|
order_name: clean(body.order_name) || null,
|
||||||
product: product.id, format: formatId,
|
product: product.id, format: formatId,
|
||||||
person_type: body.person_type === 'unternehmen' ? 'unternehmen' : 'privat',
|
person_type: body.person_type === 'unternehmen' ? 'unternehmen' : 'privat',
|
||||||
font: ['tilda', 'alva', 'ellie'].includes(body.font) ? body.font : 'tilda',
|
font: ['tilda', 'alva', 'ellie'].includes(body.font) ? body.font : 'tilda',
|
||||||
|
|||||||
@@ -252,7 +252,7 @@ const Board = defineComponent({
|
|||||||
// ── Laden ──
|
// ── Laden ──
|
||||||
// Basis-Felder ohne die evtl. noch nicht gebootstrapten Felder – diese
|
// Basis-Felder ohne die evtl. noch nicht gebootstrapten Felder – diese
|
||||||
// werden separat versucht, damit ein fehlendes Feld nicht das ganze Board sperrt.
|
// werden separat versucht, damit ein fehlendes Feld nicht das ganze Board sperrt.
|
||||||
const ORDER_FELDER = 'id,order_number,status,payment_status,production_status,needs_envelope,envelope_format,'
|
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,'
|
+ 'envelope_labeling,shipping_type,shipping_day,keep_contacts,entries_count,count_inland,count_ausland,brief_gedruckt,kuvert_gedruckt,'
|
||||||
+ 'date_updated,date_created,format.key,format.name,product.name,product.type,product.input_mode,'
|
+ '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,api_client.id,api_client.name,motif_mode,motif.name,shipping_address,'
|
||||||
@@ -1430,6 +1430,7 @@ const Board = defineComponent({
|
|||||||
: h('input', { type: 'checkbox', checked: istGewaehlt(o.id), onClick: (e) => toggleAuswahl(o.id, e),
|
: h('input', { type: 'checkbox', checked: istGewaehlt(o.id), onClick: (e) => toggleAuswahl(o.id, e),
|
||||||
title: 'Für Sammel-Druck auswählen', style: 'width:18px;height:18px;margin-top:5px;cursor:pointer;flex-shrink:0;' }),
|
title: 'Für Sammel-Druck auswählen', style: 'width:18px;height:18px;margin-top:5px;cursor:pointer;flex-shrink:0;' }),
|
||||||
h('div', { style: 'min-width:0;' }, [
|
h('div', { style: 'min-width:0;' }, [
|
||||||
|
o.order_name ? h('div', { style: 'font-size:12px;font-weight:500;color:var(--primary,#1e50a5);text-transform:uppercase;letter-spacing:.03em;margin-bottom:1px;' }, o.order_name) : null,
|
||||||
h('div', { style: 'font-size:19px;font-weight:500;letter-spacing:-.01em;line-height:1.25;' }, kundeName(o) || `#${o.order_number}`),
|
h('div', { style: 'font-size:19px;font-weight:500;letter-spacing:-.01em;line-height:1.25;' }, kundeName(o) || `#${o.order_number}`),
|
||||||
h('div', { style: 'display:flex;align-items:baseline;gap:8px;margin-top:4px;flex-wrap:wrap;' }, [
|
h('div', { style: 'display:flex;align-items:baseline;gap:8px;margin-top:4px;flex-wrap:wrap;' }, [
|
||||||
h('span', { style: `font-size:22px;font-weight:500;color:${ACCENT};line-height:1;` }, String(o.entries_count || 0)),
|
h('span', { style: `font-size:22px;font-weight:500;color:${ACCENT};line-height:1;` }, String(o.entries_count || 0)),
|
||||||
|
|||||||
Reference in New Issue
Block a user