import { prisma } from "@/lib/prisma"; import { insensitiveEquals } from "@/lib/prisma-search"; import type { Order, OrderItem, Shipment, Pickup, Invoice, Address, ReturnRequest } from "@/generated/prisma/client"; export type OrderWithDetails = Order & { items: (OrderItem & { product: { slug: string } })[]; shipment: Shipment | null; pickup: Pickup | null; invoice: Invoice | null; returnRequest: ReturnRequest | null; }; /** * Bestellungen eines Kontos — OHNE die noch unbezahlten. * * Eine Bestellung entsteht bereits beim Start des Checkouts und steht bis zur * bestaetigten Zahlung auf "NEU". Die allermeisten dieser Datensaetze sind * keine Bestellungen, sondern abgebrochene Kaufversuche: geschlossener Tab, * Zurueck-Knopf, weggelegtes Handy. Sie verschwinden von selbst wieder (siehe * lib/order-release.ts), aber bis dahin vergehen je nach Weg bis zu 45 * Minuten. * * In dieser Zeit standen sie hier wie vollwertige Bestellungen in der Liste — * mit Bestellnummer, Summe und Statuskennzeichen. Wer den Kauf gerade * abgebrochen hatte, fand ihn also im Konto trotzdem als Bestellung wieder * und musste annehmen, dass doch etwas zustande gekommen ist. * * Bezahlte Bestellungen sind davon nicht betroffen: der Webhook setzt sie * binnen Sekunden auf "BEZAHLT", danach erscheinen sie hier wie gewohnt. * "STORNIERT" bleibt bewusst sichtbar — dort gab es einen Vorgang, den die * Kundschaft nachvollziehen koennen muss (fehlgeschlagener Einzug, Storno * durch die Imkerei). */ export async function getOrdersForCustomer(customerId: string): Promise { return prisma.order.findMany({ where: { customerId, status: { not: "NEU" } }, include: { items: { include: { product: { select: { slug: true } } } }, shipment: true, pickup: true, invoice: true, returnRequest: true, }, orderBy: { createdAt: "desc" }, }); } /** * Oeffentliche Bestellverfolgung ohne Login (auch fuer Gastbestellungen): * Bestellnummer allein reicht nicht — die E-Mail-Adresse muss zusaetzlich * uebereinstimmen, damit eine Bestellnummer (kryptografisch zufaellig, aber * theoretisch in URLs/E-Mails sichtbar) allein keinen Zugriff gewaehrt. */ export async function getOrderForTracking( orderNumber: string, email: string ): Promise { return prisma.order.findFirst({ where: { orderNumber, email: insensitiveEquals(email) }, include: { items: { include: { product: { select: { slug: true } } } }, shipment: true, pickup: true, invoice: true, returnRequest: true, }, }); } export async function getAddressesForCustomer(customerId: string): Promise { return prisma.address.findMany({ where: { customerId }, orderBy: [{ isDefault: "desc" }, { createdAt: "desc" }], }); } export async function getInvoiceForCustomer(invoiceNumber: string, customerId: string) { return prisma.invoice.findFirst({ where: { invoiceNumber, order: { customerId } }, include: { order: { include: { items: true, discountCode: { select: { code: true } } } } }, }); } /** Ohne Besitzpruefung — nur fuer bereits als ADMIN verifizierte Aufrufer. */ export async function getInvoiceByNumber(invoiceNumber: string) { return prisma.invoice.findUnique({ where: { invoiceNumber }, include: { order: { include: { items: true, discountCode: { select: { code: true } } } } }, }); }