diff --git a/extensions/directus-extension-skrift-api/dist/index.js b/extensions/directus-extension-skrift-api/dist/index.js index 9d3b417..1fd9fb3 100644 --- a/extensions/directus-extension-skrift-api/dist/index.js +++ b/extensions/directus-extension-skrift-api/dist/index.js @@ -368,13 +368,13 @@ const handler = (router, { services, getSchema, logger }) => { // „versendet" markiert (Status-API liefert dann „shipped"). Schutz = geheimer // Pfad-Token (kein Konto). Ohne gesetzten Token ist die Seite aus. const escH = (s) => String(s == null ? '' : s).replace(/[&<>"]/g, (c) => ({ '&': '&', '<': '<', '>': '>', '"': '"' }[c])); - const VS_LABEL = { eingegangen: 'Eingegangen', im_druck: 'Im Druck', kuvertieren: 'Kuvertierung', versandfertig: 'Versandfertig' }; - const versandSeite = ({ orders = [], message = '', error = '' } = {}) => { - const rows = orders.length ? orders.map((o) => ` + // Eine Zeile je FTP-Sendung (Bündel), benannt wie die FTP-Datei (__). + const versandSeite = ({ bundles = [], message = '', error = '' } = {}) => { + const rows = bundles.length ? bundles.map((b) => `
-
${escH(o.order_number)}${escH(VS_LABEL[o.production_status] || o.production_status || 'offen')} · ${Number(o.entries_count) || 1} Empf. · ${escH(String(o.date_created || '').slice(0, 10))}
-
-
`).join('') : '

Keine offenen Aufträge – alles versendet.

'; +
${escH(b.name)}${Number(b.count) || 0} Empfänger · ${escH(String(b.date || '').slice(0, 10))}
+
+ `).join('') : '

Keine offenen Sendungen – alles versendet.

'; return ` Versand bestätigen

Versand bestätigen

-

Alle offenen Aufträge. Bitte pro Auftrag „Versendet" klicken, sobald er verschickt ist.

+

Jede Zeile ist eine FTP-Sendung. Bitte „Versendet" klicken, sobald die Sendung verschickt ist.

${error ? `
${escH(error)}
` : ''} ${message ? `
${escH(message)}
` : ''} ${rows}
`; }; - // Offene Aufträge (noch nicht versendet/storniert) – nur Nummer/Status/Menge/Datum. - async function ladeOffeneAuftraege(svc) { - return svc('orders').readByQuery({ - filter: { production_status: { _nin: ['versendet', 'storniert'] }, status: { _neq: 'entwurf' } }, - sort: ['-date_created'], limit: 500, - fields: ['id', 'order_number', 'production_status', 'entries_count', 'date_created'], + // Offene FTP-Sendungen: gebündelte Übermittlungen, noch nicht versendet, je bundle_name gruppiert. + async function ladeBuendel(svc) { + const rows = await svc('batch_submissions').readByQuery({ + filter: { status: { _eq: 'bundled' }, versendet: { _neq: true }, bundle_name: { _nnull: true } }, + limit: -1, sort: ['-bundle_name'], fields: ['id', 'bundle_name', 'date_created'], }); + const m = new Map(); + for (const r of rows || []) { + if (!m.has(r.bundle_name)) m.set(r.bundle_name, { name: r.bundle_name, count: 0, date: r.date_created }); + m.get(r.bundle_name).count += 1; + } + return [...m.values()]; } router.get('/v1/versand/:token', async (req, res) => { if (!VERSAND_TOKEN || req.params.token !== VERSAND_TOKEN) return res.status(404).type('html').send('Not found.'); try { const svc = svcFactory(await getSchema()); - return res.type('html').send(versandSeite({ orders: (await ladeOffeneAuftraege(svc)) || [] })); + return res.type('html').send(versandSeite({ bundles: await ladeBuendel(svc) })); } catch (e) { logger.error(`[skrift-api] versand list: ${e.message}`); - return res.type('html').send(versandSeite({ error: 'Aufträge konnten nicht geladen werden.' })); + return res.type('html').send(versandSeite({ error: 'Sendungen konnten nicht geladen werden.' })); } }); router.post('/v1/versand/:token', async (req, res) => { if (!VERSAND_TOKEN || req.params.token !== VERSAND_TOKEN) return res.status(404).type('html').send('Not found.'); - const nr = String((req.body && (req.body.order_number ?? req.body.nummer)) || req.query.order_number || '').trim(); + const bundle = String((req.body && (req.body.bundle ?? req.body.name)) || req.query.bundle || '').trim(); try { const svc = svcFactory(await getSchema()); let message = '', error = ''; - if (!nr) { - error = 'Bitte einen Auftrag wählen.'; + if (!bundle) { + error = 'Bitte eine Sendung wählen.'; } else { - const rows = await svc('orders').readByQuery({ filter: { order_number: { _eq: nr } }, limit: 1, fields: ['id', 'order_number', 'production_status'] }); - const order = rows?.[0]; - if (!order) error = `Auftrag ${nr} wurde nicht gefunden.`; - else if (order.production_status === 'versendet') message = `Auftrag ${nr} war bereits als versendet markiert.`; - else if (order.production_status === 'storniert') error = `Auftrag ${nr} ist storniert.`; - else { await svc('orders').updateOne(order.id, { production_status: 'versendet', versandt_am: new Date().toISOString() }); message = `Auftrag ${nr} als versendet markiert.`; } + const rows = await svc('batch_submissions').readByQuery({ filter: { bundle_name: { _eq: bundle }, status: { _eq: 'bundled' } }, limit: -1, fields: ['id'] }); + const ids = (rows || []).map((r) => r.id); + if (!ids.length) error = `Sendung ${bundle} nicht gefunden oder bereits versendet.`; + else { await svc('batch_submissions').updateMany(ids, { versendet: true }); message = `Sendung ${bundle} als versendet markiert (${ids.length}).`; } } - return res.type('html').send(versandSeite({ orders: (await ladeOffeneAuftraege(svc)) || [], message, error })); + return res.type('html').send(versandSeite({ bundles: await ladeBuendel(svc), message, error })); } catch (e) { logger.error(`[skrift-api] versand: ${e.stack || e.message}`); return res.type('html').send(versandSeite({ error: 'Konnte nicht gespeichert werden. Bitte erneut versuchen.' }));