template-saas-frontend-v2/src/services/commissions/entries.api.ts
Adrian Flores Cortes 36ee5213c5 [SAAS-018/020] feat: Add Sales and Commissions frontend modules
Sales Frontend (Sprint 2):
- Add services: leads, opportunities, activities, pipeline, dashboard APIs
- Add hooks: useSales with React Query integration
- Add pages: SalesPage, LeadsPage, LeadDetailPage, OpportunitiesPage, OpportunityDetailPage, ActivitiesPage
- Integrate routes in main router

Commissions Frontend (Sprint 4):
- Add services: schemes, entries, periods, assignments, dashboard APIs
- Add hooks: useCommissions with React Query integration
- Add pages: CommissionsPage, SchemesPage, EntriesPage, PeriodsPage, MyEarningsPage
- Integrate routes in main router

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 22:50:11 -06:00

148 lines
4.6 KiB
TypeScript

import api from '../api';
import { CommissionScheme } from './schemes.api';
export type EntryStatus = 'pending' | 'approved' | 'rejected' | 'paid' | 'cancelled';
export interface CommissionEntry {
id: string;
tenant_id: string;
user_id: string;
scheme_id: string;
assignment_id: string | null;
reference_type: string;
reference_id: string;
base_amount: number;
rate_applied: number;
commission_amount: number;
currency: string;
status: EntryStatus;
period_id: string | null;
paid_at: string | null;
payment_reference: string | null;
notes: string | null;
metadata: Record<string, unknown>;
created_at: string;
updated_at: string;
approved_by: string | null;
approved_at: string | null;
scheme?: CommissionScheme;
user?: {
id: string;
first_name: string;
last_name: string;
email: string;
};
}
export interface CalculateCommissionDto {
user_id: string;
reference_type: string;
reference_id: string;
base_amount: number;
currency?: string;
notes?: string;
metadata?: Record<string, unknown>;
}
export interface UpdateEntryStatusDto {
status: EntryStatus;
notes?: string;
}
export interface CalculationResult {
rate_applied: number;
commission_amount: number;
scheme_id: string;
assignment_id: string | null;
}
export interface EntryFilters {
user_id?: string;
scheme_id?: string;
period_id?: string;
status?: EntryStatus;
reference_type?: string;
date_from?: string;
date_to?: string;
page?: number;
limit?: number;
sortBy?: string;
sortOrder?: 'ASC' | 'DESC';
}
export interface PaginatedEntries {
data: CommissionEntry[];
total: number;
page: number;
limit: number;
totalPages: number;
}
export const entriesApi = {
list: async (params?: EntryFilters): Promise<PaginatedEntries> => {
const response = await api.get<PaginatedEntries>('/commissions/entries', { params });
return response.data;
},
listPending: async (params?: { page?: number; limit?: number }): Promise<PaginatedEntries> => {
const response = await api.get<PaginatedEntries>('/commissions/entries/pending', { params });
return response.data;
},
get: async (id: string): Promise<CommissionEntry> => {
const response = await api.get<CommissionEntry>(`/commissions/entries/${id}`);
return response.data;
},
getByUser: async (userId: string, params?: { page?: number; limit?: number }): Promise<PaginatedEntries> => {
const response = await api.get<PaginatedEntries>(`/commissions/entries/user/${userId}`, { params });
return response.data;
},
getByPeriod: async (periodId: string, params?: { page?: number; limit?: number }): Promise<PaginatedEntries> => {
const response = await api.get<PaginatedEntries>(`/commissions/entries/period/${periodId}`, { params });
return response.data;
},
getByReference: async (type: string, refId: string): Promise<CommissionEntry | null> => {
const response = await api.get<CommissionEntry | { message: string }>(`/commissions/entries/reference/${type}/${refId}`);
if ('message' in response.data) {
return null;
}
return response.data;
},
calculate: async (data: CalculateCommissionDto): Promise<CommissionEntry> => {
const response = await api.post<CommissionEntry>('/commissions/entries/calculate', data);
return response.data;
},
simulate: async (data: CalculateCommissionDto): Promise<CalculationResult> => {
const response = await api.post<CalculationResult>('/commissions/entries/simulate', data);
return response.data;
},
updateStatus: async (id: string, data: UpdateEntryStatusDto): Promise<CommissionEntry> => {
const response = await api.patch<CommissionEntry>(`/commissions/entries/${id}/status`, data);
return response.data;
},
bulkApprove: async (entryIds: string[]): Promise<{ approved: number; failed: number }> => {
const response = await api.post<{ approved: number; failed: number }>('/commissions/entries/bulk-approve', { entry_ids: entryIds });
return response.data;
},
bulkReject: async (entryIds: string[], reason?: string): Promise<{ rejected: number; failed: number }> => {
const response = await api.post<{ rejected: number; failed: number }>('/commissions/entries/bulk-reject', { entry_ids: entryIds, reason });
return response.data;
},
cancelByReference: async (type: string, refId: string, reason?: string): Promise<CommissionEntry | null> => {
const response = await api.post<CommissionEntry | { message: string }>(`/commissions/entries/cancel/${type}/${refId}`, { reason });
if ('message' in response.data) {
return null;
}
return response.data;
},
};