import { config } from '../../config.js' import { getDocument } from '../appwriteAdmin.js' import { TICKET_DETAILS_MAX, anleitungsLink, kuerze, minimaleTicketDetails } from '../featureRegistry.js' /** * Details des Einrichtungs-Tickets fuer den Webshop (config.features.shop.ticket.details, Spezifikation Abschnitt 6). * ctx = { feature, doc, project, customer } wie ihn markPaid uebergibt (doc = portalFeatures-Dokument, project = websiteProjects- * Dokument, customer = Kunde oder null). Der Text ist deterministisch: Kopfzeilen, Kurzfassung der Anfrage (best effort aus * shopConfig, Dokument-ID = ID des portalFeatures-Dokuments; Lesefehler oder unlesbares JSON => ohne), Snippet und Schritte. * Die Funktion wirft nie (bezahlt ist bezahlt, das Ticket entsteht immer) und enthaelt keine Daten von Kaeufern. */ const WARENART = { waren: 'Waren', lebensmittel: 'Lebensmittel', kleidung: 'Kleidung', kunst: 'Kunst', sonstiges: 'Sonstiges' } const ARTIKELZAHL = { bis20: 'bis 20', bis100: 'bis 100', mehr: 'mehr als 100' } const istObjekt = (wert) => wert !== null && typeof wert === 'object' && !Array.isArray(wert) /** Kurzfassung der Anfrage als Zeile, oder '' (Lesefehler, fehlendes Dokument, leere Anfrage). */ async function anfrageZeile(doc) { try { const shop = await getDocument(config.collections.shopConfig, doc.$id) const anfrage = typeof shop?.anfrage === 'string' && shop.anfrage ? JSON.parse(shop.anfrage) : null if (!istObjekt(anfrage)) return '' const teile = [] if (Object.hasOwn(WARENART, anfrage.warenart)) teile.push(`Warenart: ${WARENART[anfrage.warenart]}`) const lieferung = [anfrage.versand === true ? 'Versand' : '', anfrage.abholung === true ? 'Abholung' : ''].filter(Boolean) if (lieferung.length) teile.push(`Lieferung: ${lieferung.join(' und ')}`) if (Object.hasOwn(ARTIKELZAHL, anfrage.artikelzahl)) teile.push(`Artikelzahl: ${ARTIKELZAHL[anfrage.artikelzahl]}`) return teile.length ? `Anfrage: ${teile.join(', ')}` : '' } catch { return '' } } export async function shopTicketDetails(ctx) { try { const { doc } = ctx const siteKey = doc?.siteKey || '' const kopf = minimaleTicketDetails({ ...ctx, feature: { key: 'Webshop' } }).split('\n').filter((zeile) => !zeile.startsWith('Verweis: ')) const anfrage = doc?.$id ? await anfrageZeile(doc) : '' const zeilen = [ ...kopf, ...(anfrage ? [anfrage] : []), '', 'Snippet (an der Stelle der Shop-Seite einsetzen):', `
`, '', '', 'Schritte:', '1. Shop-Seite und Menüpunkt anlegen, Snippet einsetzen.', `2. Auf allen Seiten im Footer den Link "Vertrag widerrufen" setzen: https://project.webklar.com/shop/${siteKey}/widerruf`, '3. Datenschutz-Absatz Webshop einfügen (docs/funktionen/shop-datenschutz-absatz.md).', '4. Impressum prüfen.', `5. Vorschau prüfen: https://project.webklar.com/shop/${siteKey}`, '6. Ticket schließen: das schaltet die Funktion frei.', '', // Abo-Modell (einrichtungAbrechnung abo oder projekt): die Abrechnung steht allein in der Schlusszeile des Tickets (createFeatureTicket) ...(doc?.einrichtungAbrechnung === 'abo' || doc?.einrichtungAbrechnung === 'projekt' ? [] : ['Zeit im Arbeitsblatt erfassen, nicht auf Abo-Stunden anrechnen.']), `Verweis: ${anleitungsLink(doc?.customerId, doc?.projectId)}`, ] return kuerze(zeilen.join('\n').toWellFormed(), TICKET_DETAILS_MAX, { anZeile: true }) } catch (err) { console.error(`[shop-ticket] Details nicht erzeugbar, Notfall-Details: ${err?.message}`) try { return kuerze(minimaleTicketDetails({ ...ctx, feature: { key: 'Webshop' } }).toWellFormed(), TICKET_DETAILS_MAX) } catch { return 'Funktion: Webshop\nDetails konnten nicht erzeugt werden, im WOMS öffnen (Kunden → Funktionen).' } } }