// 🔧 Hilfsfunktionen import { FastifyInstance } from "fastify" import { eq, ilike, and } from "drizzle-orm" import { contacts, customers } from "../../db/schema" // ------------------------------------------------------------- // Extract Domain // ------------------------------------------------------------- export function extractDomain(email: string) { if (!email) return null const parts = email.split("@") return parts.length === 2 ? parts[1].toLowerCase() : null } // ------------------------------------------------------------- // Kunde oder Kontakt anhand E-Mail oder Domain finden // ------------------------------------------------------------- export async function findCustomerOrContactByEmailOrDomain( server: FastifyInstance, fromMail: string, tenantId: number ) { const sender = fromMail.toLowerCase() const senderDomain = extractDomain(sender) if (!senderDomain) return null // 1️⃣ Direkter Match über Contacts (email) const contactMatch = await server.db .select({ id: contacts.id, customer: contacts.customer, }) .from(contacts) .where( and( eq(contacts.email, sender), eq(contacts.tenant, tenantId) ) ) .limit(1) if (contactMatch.length && contactMatch[0].customer) { return { customer: contactMatch[0].customer, contact: contactMatch[0].id, } } // 2️⃣ Kunden anhand Domain vergleichen const allCustomers = await server.db .select({ id: customers.id, infoData: customers.infoData, }) .from(customers) .where(eq(customers.tenant, tenantId)) for (const c of allCustomers) { const info = c.infoData || {} // @ts-ignore const email = info.email?.toLowerCase() //@ts-ignore const invoiceEmail = info.invoiceEmail?.toLowerCase() const emailDomain = extractDomain(email) const invoiceDomain = extractDomain(invoiceEmail) if ( sender === email || sender === invoiceEmail || senderDomain === emailDomain || senderDomain === invoiceDomain ) { return { customer: c.id, contact: null } } } return null } // ------------------------------------------------------------- // getNestedValue (für Sortierung & Suche im Backend) // ------------------------------------------------------------- export function getNestedValue(obj: any, path: string): any { return path .split(".") .reduce((acc, part) => (acc && acc[part] !== undefined ? acc[part] : undefined), obj) } // ------------------------------------------------------------- // compareValues (Sortierung für paginated) // ------------------------------------------------------------- export function compareValues(a: any, b: any): number { if (a === b) return 0 if (a == null) return 1 if (b == null) return -1 // String Compare if (typeof a === "string" && typeof b === "string") { return a.localeCompare(b) } // Numerisch return a < b ? -1 : 1 }