import { apiFetch, type PaginatedResponse } from './api'; export interface ContactPersonResponse { id: string; contact_id: string; name: string; function?: string; phone?: string; email?: string; created_at?: string; } export interface ContactResponse { id: string; company_name: string; legal_form?: string; address_street?: string; address_zip?: string; address_city?: string; address_country: string; vat_id?: string; phone?: string; email?: string; website?: string; role: string; vat_id_status: string; is_private: boolean; created_at?: string; updated_at?: string; deleted_at?: string | null; contact_persons: ContactPersonResponse[]; } export interface ContactCreateData { company_name: string; legal_form?: string; address_street?: string; address_zip?: string; address_city?: string; address_country: string; vat_id?: string; phone?: string; email?: string; website?: string; role: string; is_private?: boolean; contact_persons?: ContactPersonCreateData[]; } export interface ContactUpdateData { company_name?: string; legal_form?: string; address_street?: string; address_zip?: string; address_city?: string; address_country?: string; vat_id?: string; phone?: string; email?: string; website?: string; role?: string; is_private?: boolean; } export interface ContactPersonCreateData { name: string; function?: string; phone?: string; email?: string; } export interface ContactListParams { page?: number; page_size?: number; search?: string; role?: string; is_eu?: boolean; is_private?: boolean; sort?: string; } export async function listContacts(params: ContactListParams = {}): Promise> { const query = new URLSearchParams(); if (params.page) query.set('page', String(params.page)); if (params.page_size) query.set('page_size', String(params.page_size)); if (params.search) query.set('search', params.search); if (params.role) query.set('role', params.role); if (params.is_eu !== undefined) query.set('is_eu', String(params.is_eu)); if (params.is_private !== undefined) query.set('is_private', String(params.is_private)); if (params.sort) query.set('sort', params.sort); const qs = query.toString(); return apiFetch>(`/contacts/${qs ? `?${qs}` : ''}`); } export async function getContact(id: string): Promise { return apiFetch(`/contacts/${id}`); } export async function createContact(data: ContactCreateData): Promise { return apiFetch('/contacts/', { method: 'POST', body: JSON.stringify(data), }); } export async function updateContact(id: string, data: ContactUpdateData): Promise { return apiFetch(`/contacts/${id}`, { method: 'PUT', body: JSON.stringify(data), }); } export async function deleteContact(id: string): Promise { return apiFetch(`/contacts/${id}`, { method: 'DELETE' }); } export async function addContactPerson(contactId: string, data: ContactPersonCreateData): Promise { return apiFetch(`/contacts/${contactId}/persons`, { method: 'POST', body: JSON.stringify(data), }); } export async function removeContactPerson(contactId: string, personId: string): Promise { await apiFetch(`/contacts/${contactId}/persons/${personId}`, { method: 'DELETE' }); } /** * Validate VAT ID format on the frontend (mirrors backend ust_validation.py). * Returns error message or null if valid. */ export function validateVatIdFormat(vatId: string, countryCode: string): string | null { if (!vatId) return null; const normalized = vatId.trim().toUpperCase().replace(/\s+/g, ''); const patterns: Record = { DE: /^DE\d{9}$/, AT: /^ATU\d{8}$/, FR: /^FR[A-Za-z0-9]{2}\d{9}$/, NL: /^NL\d{9}B\d{2}$/, PL: /^PL\d{10}$/, CZ: /^CZ\d{8,10}$/, IT: /^IT\d{11}$/, ES: /^ES[A-Za-z0-9]\d{7}[A-Za-z0-9]$/, BE: /^BE\d{10}$/, DK: /^DK\d{8}$/, SE: /^SE\d{10}$/, }; const euCountries = new Set([ 'AT', 'BE', 'BG', 'CY', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FI', 'FR', 'GR', 'HR', 'HU', 'IE', 'IT', 'LT', 'LU', 'LV', 'MT', 'NL', 'PL', 'PT', 'RO', 'SE', 'SI', 'SK', ]); const cc = normalized.substring(0, 2); if (!cc.match(/^[A-Z]{2}$/)) return 'Invalid country code'; const pattern = patterns[cc]; if (pattern) { return pattern.test(normalized) ? null : `Invalid VAT ID format for ${cc}`; } if (euCountries.has(cc)) { return /^[A-Z]{2}[A-Za-z0-9]{5,15}$/.test(normalized) ? null : `Invalid VAT ID format for ${cc}`; } return `VAT ID validation not supported for country ${cc}`; }