// ============================================================ // CRM – API-Funktionen (nutzt bestehenden Axios-Client) // ============================================================ import api from '../api/client'; import type { Contact, CreateContactPayload, UpdateContactPayload, ContactsQueryParams, Deal, CreateDealPayload, UpdateDealPayload, DealsQueryParams, Pipeline, CreatePipelinePayload, UpdatePipelinePayload, CreateStagePayload, UpdateStagePayload, PipelineStage, Activity, CreateActivityPayload, UpdateActivityPayload, ActivitiesQueryParams, Company, CreateCompanyPayload, UpdateCompanyPayload, CompaniesQueryParams, Industry, CreateIndustryPayload, UpdateIndustryPayload, AccountType, CreateAccountTypePayload, UpdateAccountTypePayload, RelationshipType, CreateRelationshipTypePayload, UpdateRelationshipTypePayload, CompanyRelationship, CreateCompanyRelationshipPayload, TenantUser, LexwareContact, LexwareContactSearchParams, LexwareVoucher, LexwareVouchersQueryParams, DealVoucher, TradeEvent, CreateTradeEventPayload, UpdateTradeEventPayload, EntityOwner, AddOwnerPayload, CustomFieldDef, CustomFieldEntityType, CreateCustomFieldDefPayload, UpdateCustomFieldDefPayload, CustomFieldValue, SetCustomFieldValuesPayload, ForecastResponse, ForecastPeriod, ImportPreviewResponse, ImportEntityType, ImportExecuteRequest, ImportExecuteResponse, EnrichmentResponse, EnrichmentConfig, PaginatedResponse, SingleResponse, } from './types'; // --- Contacts --- export const contactsApi = { list: (params: ContactsQueryParams) => api .get>('/crm/contacts', { params }) .then((r) => r.data), getById: (id: string) => api .get>(`/crm/contacts/${id}`) .then((r) => r.data), create: (data: CreateContactPayload) => api .post>('/crm/contacts', data) .then((r) => r.data), update: (id: string, data: UpdateContactPayload) => api .patch>(`/crm/contacts/${id}`, data) .then((r) => r.data), delete: (id: string) => api .delete>(`/crm/contacts/${id}`) .then((r) => r.data), }; // --- Deals --- export const dealsApi = { list: (params: DealsQueryParams) => api .get>('/crm/deals', { params }) .then((r) => r.data), getById: (id: string) => api .get>(`/crm/deals/${id}`) .then((r) => r.data), create: (data: CreateDealPayload) => api .post>('/crm/deals', data) .then((r) => r.data), update: (id: string, data: UpdateDealPayload) => api .patch>(`/crm/deals/${id}`, data) .then((r) => r.data), delete: (id: string) => api .delete>(`/crm/deals/${id}`) .then((r) => r.data), }; // --- Forecast --- export const forecastApi = { get: (pipelineId?: string, period?: ForecastPeriod) => api .get<{ success: boolean; data: ForecastResponse; meta: { timestamp: string } }>( '/crm/deals/forecast', { params: { pipelineId, period } }, ) .then((r) => r.data), }; // --- Pipelines --- export const pipelinesApi = { list: () => api .get<{ success: boolean; data: Pipeline[]; meta: { timestamp: string } }>( '/crm/pipelines', ) .then((r) => r.data), getById: (id: string) => api .get>(`/crm/pipelines/${id}`) .then((r) => r.data), create: (data: CreatePipelinePayload) => api .post>('/crm/pipelines', data) .then((r) => r.data), update: (id: string, data: UpdatePipelinePayload) => api .patch>(`/crm/pipelines/${id}`, data) .then((r) => r.data), delete: (id: string) => api .delete>(`/crm/pipelines/${id}`) .then((r) => r.data), addStage: (pipelineId: string, data: CreateStagePayload) => api .post>( `/crm/pipelines/${pipelineId}/stages`, data, ) .then((r) => r.data), updateStage: (pipelineId: string, stageId: string, data: UpdateStagePayload) => api .patch>( `/crm/pipelines/${pipelineId}/stages/${stageId}`, data, ) .then((r) => r.data), removeStage: (pipelineId: string, stageId: string) => api .delete>( `/crm/pipelines/${pipelineId}/stages/${stageId}`, ) .then((r) => r.data), }; // --- Activities --- export const activitiesApi = { list: (params: ActivitiesQueryParams) => api .get>('/crm/activities', { params }) .then((r) => r.data), getById: (id: string) => api .get>(`/crm/activities/${id}`) .then((r) => r.data), create: (data: CreateActivityPayload) => api .post>('/crm/activities', data) .then((r) => r.data), update: (id: string, data: UpdateActivityPayload) => api .patch>(`/crm/activities/${id}`, data) .then((r) => r.data), delete: (id: string) => api .delete>(`/crm/activities/${id}`) .then((r) => r.data), }; // --- Companies --- export const companiesApi = { list: (params: CompaniesQueryParams) => api .get>('/crm/companies', { params }) .then((r) => r.data), getById: (id: string) => api .get>(`/crm/companies/${id}`) .then((r) => r.data), create: (data: CreateCompanyPayload) => api .post>('/crm/companies', data) .then((r) => r.data), update: (id: string, data: UpdateCompanyPayload) => api .patch>(`/crm/companies/${id}`, data) .then((r) => r.data), delete: (id: string) => api .delete>(`/crm/companies/${id}`) .then((r) => r.data), }; // --- Owners (Contact, Company, Deal) --- export const ownersApi = { addContactOwner: (contactId: string, data: AddOwnerPayload) => api .post>(`/crm/contacts/${contactId}/owners`, data) .then((r) => r.data), removeContactOwner: (contactId: string, userId: string) => api .delete>(`/crm/contacts/${contactId}/owners/${userId}`) .then((r) => r.data), addCompanyOwner: (companyId: string, data: AddOwnerPayload) => api .post>(`/crm/companies/${companyId}/owners`, data) .then((r) => r.data), removeCompanyOwner: (companyId: string, userId: string) => api .delete>(`/crm/companies/${companyId}/owners/${userId}`) .then((r) => r.data), addDealOwner: (dealId: string, data: AddOwnerPayload) => api .post>(`/crm/deals/${dealId}/owners`, data) .then((r) => r.data), removeDealOwner: (dealId: string, userId: string) => api .delete>(`/crm/deals/${dealId}/owners/${userId}`) .then((r) => r.data), }; // --- Industries --- export const industriesApi = { list: () => api .get<{ success: boolean; data: Industry[]; meta: { timestamp: string } }>( '/crm/industries', ) .then((r) => r.data), create: (data: CreateIndustryPayload) => api .post>('/crm/industries', data) .then((r) => r.data), update: (id: string, data: UpdateIndustryPayload) => api .patch>(`/crm/industries/${id}`, data) .then((r) => r.data), delete: (id: string) => api .delete>(`/crm/industries/${id}`) .then((r) => r.data), }; // --- Account Types --- export const accountTypesApi = { list: () => api .get<{ success: boolean; data: AccountType[]; meta: { timestamp: string } }>( '/crm/account-types', ) .then((r) => r.data), create: (data: CreateAccountTypePayload) => api .post>('/crm/account-types', data) .then((r) => r.data), update: (id: string, data: UpdateAccountTypePayload) => api .patch>(`/crm/account-types/${id}`, data) .then((r) => r.data), delete: (id: string) => api .delete>(`/crm/account-types/${id}`) .then((r) => r.data), }; // --- Relationship Types --- export const relationshipTypesApi = { list: () => api .get<{ success: boolean; data: RelationshipType[]; meta: { timestamp: string } }>( '/crm/relationship-types', ) .then((r) => r.data), create: (data: CreateRelationshipTypePayload) => api .post>('/crm/relationship-types', data) .then((r) => r.data), update: (id: string, data: UpdateRelationshipTypePayload) => api .patch>( `/crm/relationship-types/${id}`, data, ) .then((r) => r.data), delete: (id: string) => api .delete>( `/crm/relationship-types/${id}`, ) .then((r) => r.data), }; // --- Company Relationships --- export const companyRelationshipsApi = { list: (companyId: string) => api .get<{ success: boolean; data: CompanyRelationship[]; meta: { timestamp: string } }>( `/crm/companies/${companyId}/relationships`, ) .then((r) => r.data), create: (companyId: string, data: CreateCompanyRelationshipPayload) => api .post>( `/crm/companies/${companyId}/relationships`, data, ) .then((r) => r.data), delete: (companyId: string, relationshipId: string) => api .delete>( `/crm/companies/${companyId}/relationships/${relationshipId}`, ) .then((r) => r.data), }; // --- Tenant Users --- export const usersApi = { list: () => api .get<{ success: boolean; data: TenantUser[]; meta: { timestamp: string } }>( '/crm/users', ) .then((r) => r.data), }; // --- Lexware Office: Contacts --- export const lexwareContactsApi = { search: (params: LexwareContactSearchParams) => api .get>('/crm/lexware/contacts/search', { params, }) .then((r) => r.data), linkCompany: (data: { lexwareContactId: string; companyId: string }) => api .post>('/crm/lexware/contacts/link-company', data) .then((r) => r.data), linkContact: (data: { lexwareContactId: string; contactId: string }) => api .post>('/crm/lexware/contacts/link-contact', data) .then((r) => r.data), unlinkCompany: (companyId: string) => api .delete>( `/crm/lexware/contacts/unlink-company/${companyId}`, ) .then((r) => r.data), unlinkContact: (contactId: string) => api .delete>( `/crm/lexware/contacts/unlink-contact/${contactId}`, ) .then((r) => r.data), importCompany: (data: { lexwareContactId: string }) => api .post>( '/crm/lexware/contacts/import-company', data, ) .then((r) => r.data), importContact: (data: { lexwareContactId: string }) => api .post>( '/crm/lexware/contacts/import-contact', data, ) .then((r) => r.data), push: (entityType: 'company' | 'contact', entityId: string) => api .post>( `/crm/lexware/contacts/push/${entityType}/${entityId}`, ) .then((r) => r.data), sync: (entityType: 'company' | 'contact', entityId: string) => api .post>( `/crm/lexware/contacts/sync/${entityType}/${entityId}`, ) .then((r) => r.data), }; // --- Lexware Office: Vouchers --- export const lexwareVouchersApi = { getForCompany: (companyId: string, params?: LexwareVouchersQueryParams) => api .get>( `/crm/lexware/vouchers/company/${companyId}`, { params }, ) .then((r) => r.data), getForContact: (contactId: string, params?: LexwareVouchersQueryParams) => api .get>( `/crm/lexware/vouchers/contact/${contactId}`, { params }, ) .then((r) => r.data), getForDeal: (dealId: string) => api .get<{ success: boolean; data: DealVoucher[]; meta: { timestamp: string } }>( `/crm/lexware/vouchers/deal/${dealId}`, ) .then((r) => r.data), linkToDeal: (dealId: string, voucherId: string) => api .post>( `/crm/lexware/vouchers/deal/${dealId}/link`, { voucherId }, ) .then((r) => r.data), unlinkFromDeal: (dealId: string, voucherId: string) => api .delete>( `/crm/lexware/vouchers/deal/${dealId}/unlink/${voucherId}`, ) .then((r) => r.data), refreshCompany: (companyId: string) => api .post>( `/crm/lexware/vouchers/refresh/company/${companyId}`, ) .then((r) => r.data), refreshContact: (contactId: string) => api .post>( `/crm/lexware/vouchers/refresh/contact/${contactId}`, ) .then((r) => r.data), }; // --- Trade Events (Messe-Timer) --- export const tradeEventsApi = { list: () => api .get<{ data: TradeEvent[] }>('/crm/trade-events') .then((r) => r.data), listActive: () => api .get<{ data: TradeEvent[] }>('/crm/trade-events/active') .then((r) => r.data), getById: (id: string) => api .get>(`/crm/trade-events/${id}`) .then((r) => r.data), create: (data: CreateTradeEventPayload) => api .post>('/crm/trade-events', data) .then((r) => r.data), update: (id: string, data: UpdateTradeEventPayload) => api .patch>(`/crm/trade-events/${id}`, data) .then((r) => r.data), delete: (id: string) => api .delete>(`/crm/trade-events/${id}`) .then((r) => r.data), }; // --- Custom Fields (Phase 2.1) --- export const customFieldsApi = { /** Feld-Definitionen auflisten (optional nach Entity-Typ gefiltert) */ listDefs: (entityType?: CustomFieldEntityType) => api .get<{ success: boolean; data: CustomFieldDef[]; meta: { timestamp: string } }>( '/crm/custom-fields', { params: entityType ? { entityType } : {} }, ) .then((r) => r.data), /** Einzelne Feld-Definition abrufen */ getDef: (id: string) => api .get>(`/crm/custom-fields/${id}`) .then((r) => r.data), /** Feld-Definition erstellen */ createDef: (data: CreateCustomFieldDefPayload) => api .post>('/crm/custom-fields', data) .then((r) => r.data), /** Feld-Definition aktualisieren */ updateDef: (id: string, data: UpdateCustomFieldDefPayload) => api .patch>(`/crm/custom-fields/${id}`, data) .then((r) => r.data), /** Feld-Definition loeschen (CASCADE auf alle Werte!) */ deleteDef: (id: string) => api .delete>(`/crm/custom-fields/${id}`) .then((r) => r.data), /** Custom-Field-Werte fuer eine Entity lesen */ getValues: (entityId: string) => api .get<{ success: boolean; data: CustomFieldValue[]; meta: { timestamp: string } }>( `/crm/custom-fields/${entityId}/values`, ) .then((r) => r.data), /** Custom-Field-Werte fuer eine Entity setzen (Bulk-Upsert) */ setValues: (entityId: string, data: SetCustomFieldValuesPayload) => api .put<{ success: boolean; data: CustomFieldValue[]; meta: { timestamp: string } }>( `/crm/custom-fields/${entityId}/values`, data, ) .then((r) => r.data), }; // --- Import --- /** Backend erwartet lowercase entity-type-Bezeichner */ const toImportEntityType = (t: ImportEntityType): string => t === 'PERSON' ? 'contact' : t === 'COMPANY' ? 'company' : 'deal'; export const importApi = { preview: (file: File, entityType: ImportEntityType) => { const form = new FormData(); form.append('file', file); form.append('entityType', toImportEntityType(entityType)); return api .post<{ success: boolean; data: ImportPreviewResponse; meta: { timestamp: string } }>( '/crm/import/preview', form, { headers: { 'Content-Type': 'multipart/form-data' } }, ) .then((r) => r.data); }, execute: (data: ImportExecuteRequest) => { // Backend erwartet mapping als Array [{sourceColumn, targetField}] const mappingArray = Object.entries(data.mapping) .filter(([, target]) => target) .map(([sourceColumn, targetField]) => ({ sourceColumn, targetField })); return api .post<{ success: boolean; data: ImportExecuteResponse; meta: { timestamp: string } }>( '/crm/import/execute', { ...data, entityType: toImportEntityType(data.entityType), mapping: mappingArray, }, ) .then((r) => r.data); }, }; // --- Enrichment --- export const enrichmentApi = { enrich: (companyId: string) => api .post<{ success: boolean; data: EnrichmentResponse; meta: { timestamp: string } }>( `/crm/companies/${companyId}/enrich`, ) .then((r) => r.data), getConfig: () => api .get<{ success: boolean; data: EnrichmentConfig; meta: { timestamp: string } }>( '/crm/settings/integrations/north-data', ) .then((r) => r.data), setConfig: (apiKey: string) => api .put<{ success: boolean; data: EnrichmentConfig; meta: { timestamp: string } }>( '/crm/settings/integrations/north-data', { apiKey }, ) .then((r) => r.data), };