Redone
This commit is contained in:
@@ -1,43 +1,67 @@
|
||||
// 🔧 Hilfsfunktionen
|
||||
import {FastifyInstance} from "fastify";
|
||||
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('@')
|
||||
const parts = email.split("@")
|
||||
return parts.length === 2 ? parts[1].toLowerCase() : null
|
||||
}
|
||||
|
||||
export async function findCustomerOrContactByEmailOrDomain(server:FastifyInstance, fromMail: string, tenantId: number) {
|
||||
// -------------------------------------------------------------
|
||||
// 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
|
||||
const { data: contactMatch } = await server.supabase
|
||||
.from('contacts')
|
||||
.select('id, customer')
|
||||
.eq('email', sender)
|
||||
.eq('tenant', tenantId)
|
||||
.maybeSingle()
|
||||
// 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?.customer) {
|
||||
return { customer: contactMatch.customer, contact: contactMatch.id }
|
||||
if (contactMatch.length && contactMatch[0].customer) {
|
||||
return {
|
||||
customer: contactMatch[0].customer,
|
||||
contact: contactMatch[0].id,
|
||||
}
|
||||
}
|
||||
|
||||
// 2️⃣ Kunden nach Domain oder Rechnungs-E-Mail durchsuchen
|
||||
const { data: customers, error } = await server.supabase
|
||||
.from('customers')
|
||||
.select('id, infoData')
|
||||
.eq('tenant', tenantId)
|
||||
// 2️⃣ Kunden anhand Domain vergleichen
|
||||
const allCustomers = await server.db
|
||||
.select({
|
||||
id: customers.id,
|
||||
infoData: customers.infoData,
|
||||
})
|
||||
.from(customers)
|
||||
.where(eq(customers.tenant, tenantId))
|
||||
|
||||
if (error) {
|
||||
server.log.error(`[Helpdesk] Fehler beim Laden der Kunden: ${error.message}`)
|
||||
return null
|
||||
}
|
||||
|
||||
for (const c of customers || []) {
|
||||
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)
|
||||
@@ -55,18 +79,28 @@ export async function findCustomerOrContactByEmailOrDomain(server:FastifyInstanc
|
||||
return null
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// getNestedValue (für Sortierung & Suche im Backend)
|
||||
// -------------------------------------------------------------
|
||||
export function getNestedValue(obj: any, path: string): any {
|
||||
return path.split('.').reduce((acc, part) => acc?.[part], obj);
|
||||
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;
|
||||
if (a === b) return 0
|
||||
if (a == null) return 1
|
||||
if (b == null) return -1
|
||||
|
||||
if (typeof a === 'string' && typeof b === 'string') {
|
||||
return a.localeCompare(b);
|
||||
// String Compare
|
||||
if (typeof a === "string" && typeof b === "string") {
|
||||
return a.localeCompare(b)
|
||||
}
|
||||
|
||||
return a < b ? -1 : 1;
|
||||
}
|
||||
// Numerisch
|
||||
return a < b ? -1 : 1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user