340 lines
9.5 KiB
TypeScript
340 lines
9.5 KiB
TypeScript
'use server'
|
|
import { createAdminClient } from '@/lib/supabase/admin'
|
|
import { revalidatePath, unstable_noStore as noStore } from 'next/cache'
|
|
import { getLicServerConfig, getLicServerConfigSystem } from './licserver-config'
|
|
|
|
export async function getCompanies() {
|
|
noStore()
|
|
const admin = createAdminClient()
|
|
const { data, error } = await admin.from('companies').select('*')
|
|
if (error) throw error
|
|
return data
|
|
}
|
|
|
|
export async function createCompany(data: { name: string; street?: string; zip?: string; city?: string; email?: string }) {
|
|
const admin = createAdminClient()
|
|
const { data: dbData, error } = await admin.from('companies').insert({
|
|
name: data.name,
|
|
street: data.street || null,
|
|
zip: data.zip || null,
|
|
city: data.city || null,
|
|
email: data.email || null,
|
|
}).select().single()
|
|
if (error) throw error
|
|
revalidatePath('/admin/companies')
|
|
revalidatePath('/admin/users')
|
|
return dbData
|
|
}
|
|
|
|
export async function updateCompany(id: string, data: { name: string; street?: string; zip?: string; city?: string; email?: string }) {
|
|
const admin = createAdminClient()
|
|
const { data: dbData, error } = await admin.from('companies').update({
|
|
name: data.name,
|
|
street: data.street || null,
|
|
zip: data.zip || null,
|
|
city: data.city || null,
|
|
email: data.email || null,
|
|
}).eq('id', id).select().single()
|
|
if (error) throw error
|
|
revalidatePath('/admin/companies')
|
|
revalidatePath('/admin/users')
|
|
return dbData
|
|
}
|
|
|
|
export async function deleteCompany(id: string) {
|
|
const admin = createAdminClient()
|
|
const { error } = await admin.from('companies').delete().eq('id', id)
|
|
if (error) throw error
|
|
revalidatePath('/admin/companies')
|
|
revalidatePath('/admin/users')
|
|
return true
|
|
}
|
|
|
|
export async function assignCompanyToUser(userId: string, companyId: string | null) {
|
|
const admin = createAdminClient()
|
|
const { error } = await admin.from('users').update({ company_id: companyId }).eq('id', userId)
|
|
if (error) throw error
|
|
revalidatePath('/admin/users')
|
|
return true
|
|
}
|
|
|
|
export async function getEndCustomersByCompany(companyId: string) {
|
|
const admin = createAdminClient()
|
|
const { data: customers, error: customersError } = await admin
|
|
.from('end_customers')
|
|
.select('*')
|
|
.eq('partner_id', companyId)
|
|
if (customersError) throw customersError
|
|
return customers || []
|
|
}
|
|
|
|
export async function getCompanyDetails(companyId: string) {
|
|
const admin = createAdminClient()
|
|
const { data, error } = await admin.from('companies').select('*').eq('id', companyId).single()
|
|
if (error) throw error
|
|
return data
|
|
}
|
|
|
|
export async function getEndCustomersByCompanyWithPartners(companyId: string) {
|
|
const admin = createAdminClient()
|
|
|
|
const { data: customers, error: customersError } = await admin
|
|
.from('end_customers')
|
|
.select('*')
|
|
.eq('partner_id', companyId)
|
|
if (customersError) throw customersError
|
|
|
|
const { data: company } = await admin
|
|
.from('companies')
|
|
.select('name')
|
|
.eq('id', companyId)
|
|
.single()
|
|
|
|
const companyName = company?.name || 'Unbekannt'
|
|
|
|
return customers.map((c) => ({
|
|
...c,
|
|
partner_name: companyName,
|
|
}))
|
|
}
|
|
|
|
export async function getCompanyPartners(companyId: string) {
|
|
const admin = createAdminClient()
|
|
const { data: usersData, error: usersError } = await admin
|
|
.from('users')
|
|
.select('id, role')
|
|
.eq('company_id', companyId)
|
|
if (usersError) throw usersError
|
|
|
|
if (!usersData || usersData.length === 0) return []
|
|
|
|
const userIds = usersData.map(u => u.id)
|
|
|
|
const { data: profiles, error: profilesError } = await admin
|
|
.from('profiles')
|
|
.select('id, first_name, last_name')
|
|
.in('id', userIds)
|
|
if (profilesError) throw profilesError
|
|
|
|
const { data: { users }, error: authError } = await admin.auth.admin.listUsers()
|
|
const emailMap = new Map((users || []).map(u => [u.id, u.email || '']))
|
|
|
|
const profileMap = new Map((profiles || []).map(p => [p.id, p]))
|
|
|
|
return usersData.map(u => {
|
|
const prof = profileMap.get(u.id)
|
|
return {
|
|
id: u.id,
|
|
email: emailMap.get(u.id) || '',
|
|
name: prof ? `${prof.first_name || ''} ${prof.last_name || ''}`.trim() || emailMap.get(u.id) || 'Unbekannt' : emailMap.get(u.id) || 'Unbekannt',
|
|
}
|
|
})
|
|
}
|
|
|
|
export async function adminCreateEndCustomer(data: {
|
|
partner_id: string
|
|
company_name: string
|
|
vat_id?: string
|
|
first_name?: string
|
|
last_name?: string
|
|
street?: string
|
|
zip?: string
|
|
city?: string
|
|
email?: string
|
|
bank_iban?: string
|
|
bank_bic?: string
|
|
bank_name?: string
|
|
bank_owner?: string
|
|
}) {
|
|
const admin = createAdminClient()
|
|
const { data: dbData, error } = await admin
|
|
.from('end_customers')
|
|
.insert([{
|
|
partner_id: data.partner_id,
|
|
company_name: data.company_name,
|
|
vat_id: data.vat_id || null,
|
|
first_name: data.first_name || null,
|
|
last_name: data.last_name || null,
|
|
street: data.street || null,
|
|
zip: data.zip || null,
|
|
city: data.city || null,
|
|
email: data.email || null,
|
|
bank_iban: data.bank_iban || null,
|
|
bank_bic: data.bank_bic || null,
|
|
bank_name: data.bank_name || null,
|
|
bank_owner: data.bank_owner || null,
|
|
}])
|
|
.select()
|
|
.single()
|
|
if (error) throw error
|
|
return dbData
|
|
}
|
|
|
|
export async function adminUpdateEndCustomer(id: string, data: {
|
|
partner_id: string
|
|
company_name: string
|
|
vat_id?: string
|
|
first_name?: string
|
|
last_name?: string
|
|
street?: string
|
|
zip?: string
|
|
city?: string
|
|
email?: string
|
|
bank_iban?: string
|
|
bank_bic?: string
|
|
bank_name?: string
|
|
bank_owner?: string
|
|
}) {
|
|
const admin = createAdminClient()
|
|
const { data: dbData, error } = await admin
|
|
.from('end_customers')
|
|
.update({
|
|
partner_id: data.partner_id,
|
|
company_name: data.company_name,
|
|
vat_id: data.vat_id || null,
|
|
first_name: data.first_name || null,
|
|
last_name: data.last_name || null,
|
|
street: data.street || null,
|
|
zip: data.zip || null,
|
|
city: data.city || null,
|
|
email: data.email || null,
|
|
bank_iban: data.bank_iban || null,
|
|
bank_bic: data.bank_bic || null,
|
|
bank_name: data.bank_name || null,
|
|
bank_owner: data.bank_owner || null,
|
|
})
|
|
.eq('id', id)
|
|
.select()
|
|
.single()
|
|
if (error) throw error
|
|
return dbData
|
|
}
|
|
|
|
export async function adminDeleteEndCustomer(id: string) {
|
|
const admin = createAdminClient()
|
|
const { error } = await admin
|
|
.from('end_customers')
|
|
.delete()
|
|
.eq('id', id)
|
|
if (error) throw error
|
|
return true
|
|
}
|
|
|
|
export async function syncCompaniesFromLicServer() {
|
|
const admin = createAdminClient()
|
|
const cfg = await getLicServerConfigSystem()
|
|
|
|
if (!cfg.base_url || !cfg.api_key) {
|
|
throw new Error('LicServer ist nicht konfiguriert.')
|
|
}
|
|
|
|
const res = await fetch(`${cfg.base_url}/api-v1/partners?pageSize=1000`, {
|
|
headers: { 'X-Api-Key': cfg.api_key, 'Accept': 'application/json' },
|
|
signal: AbortSignal.timeout(10_000),
|
|
})
|
|
|
|
if (!res.ok) {
|
|
throw new Error(`Lizenzserver antwortete mit Fehler: HTTP ${res.status}`)
|
|
}
|
|
|
|
const result = await res.json()
|
|
const partners = result.items || []
|
|
|
|
if (partners.length === 0) {
|
|
return { success: true, count: 0 }
|
|
}
|
|
|
|
const upsertRows = partners.map((p: any) => ({
|
|
id: p.id,
|
|
name: p.name || 'Unbenannt',
|
|
email: p.email || null,
|
|
}))
|
|
|
|
const { error } = await admin
|
|
.from('companies')
|
|
.upsert(upsertRows, { onConflict: 'id' })
|
|
|
|
if (error) throw error
|
|
|
|
revalidatePath('/admin/companies')
|
|
revalidatePath('/admin/users')
|
|
|
|
return { success: true, count: partners.length }
|
|
}
|
|
|
|
export async function syncCustomersFromLicServer() {
|
|
const admin = createAdminClient()
|
|
const cfg = await getLicServerConfigSystem()
|
|
|
|
if (!cfg.base_url || !cfg.api_key) {
|
|
throw new Error('LicServer ist nicht konfiguriert.')
|
|
}
|
|
|
|
// 1. Get all local companies
|
|
const { data: companies, error: compErr } = await admin
|
|
.from('companies')
|
|
.select('id')
|
|
|
|
if (compErr) throw compErr
|
|
if (!companies || companies.length === 0) {
|
|
return { success: true, count: 0 }
|
|
}
|
|
|
|
let totalSynced = 0
|
|
const allUpsertRows: any[] = []
|
|
|
|
// 2. Fetch customers for each company
|
|
for (const company of companies) {
|
|
try {
|
|
const res = await fetch(`${cfg.base_url}/api-v1/partners/${company.id}/customers?pageSize=1000`, {
|
|
headers: { 'X-Api-Key': cfg.api_key, 'Accept': 'application/json' },
|
|
signal: AbortSignal.timeout(10_000),
|
|
})
|
|
|
|
if (res.ok) {
|
|
const result = await res.json()
|
|
const customers = result.items || []
|
|
|
|
for (const c of customers) {
|
|
const streetCombined = [c.street, c.houseNumber, c.houseNumberAddon]
|
|
.filter(Boolean)
|
|
.map(s => s.trim())
|
|
.join(' ')
|
|
|
|
allUpsertRows.push({
|
|
id: c.id,
|
|
partner_id: company.id,
|
|
company_name: c.name || 'Unbenannt',
|
|
street: streetCombined || null,
|
|
zip: c.zipCode || null,
|
|
city: c.city || null,
|
|
email: c.email || null,
|
|
is_anonymized: false,
|
|
})
|
|
}
|
|
} else {
|
|
console.warn(`[sync-customers] Skipping partner ${company.id} due to API status: ${res.status}`)
|
|
}
|
|
} catch (e: any) {
|
|
console.error(`[sync-customers] Error fetching customers for partner ${company.id}:`, e.message || e)
|
|
}
|
|
}
|
|
|
|
if (allUpsertRows.length > 0) {
|
|
const { error: upsertErr } = await admin
|
|
.from('end_customers')
|
|
.upsert(allUpsertRows, { onConflict: 'id' })
|
|
|
|
if (upsertErr) throw upsertErr
|
|
totalSynced = allUpsertRows.length
|
|
}
|
|
|
|
revalidatePath('/my-customers')
|
|
revalidatePath('/order')
|
|
revalidatePath('/admin/companies')
|
|
|
|
return { success: true, count: totalSynced }
|
|
}
|
|
|
|
|