97 lines
3.0 KiB
TypeScript
97 lines
3.0 KiB
TypeScript
import apiClient from '../../../shared/services/apiClient';
|
|
|
|
export type ExceptionType =
|
|
| 'missing_invoice'
|
|
| 'missing_payment'
|
|
| 'amount_mismatch'
|
|
| 'duplicate_payment'
|
|
| 'orphaned_payment'
|
|
| 'date_mismatch';
|
|
|
|
export type ExceptionStatus = 'open' | 'assigned' | 'in_review' | 'resolved' | 'closed';
|
|
|
|
export interface ReconciliationException {
|
|
id: number;
|
|
exception_type: ExceptionType;
|
|
status: ExceptionStatus;
|
|
severity: 'low' | 'medium' | 'high' | 'critical';
|
|
payment_id?: number;
|
|
invoice_id?: number;
|
|
booking_id?: number;
|
|
description: string;
|
|
expected_amount?: number;
|
|
actual_amount?: number;
|
|
difference?: number;
|
|
assigned_to?: number;
|
|
assigned_at?: string;
|
|
resolved_by?: number;
|
|
resolved_at?: string;
|
|
resolution_notes?: string;
|
|
comments?: Array<{
|
|
user_id: number;
|
|
comment: string;
|
|
created_at: string;
|
|
}>;
|
|
created_at: string;
|
|
updated_at: string;
|
|
}
|
|
|
|
export interface ExceptionStats {
|
|
total: number;
|
|
by_status: Record<ExceptionStatus, number>;
|
|
by_type: Record<ExceptionType, number>;
|
|
by_severity: Record<string, number>;
|
|
}
|
|
|
|
class ReconciliationService {
|
|
async runReconciliation(params?: {
|
|
start_date?: string;
|
|
end_date?: string;
|
|
}): Promise<{ status: string; data: { exceptions_created: number; exceptions: ReconciliationException[] } }> {
|
|
const response = await apiClient.post('/financial/reconciliation/run', null, { params });
|
|
return response.data;
|
|
}
|
|
|
|
async getExceptions(params?: {
|
|
status?: ExceptionStatus;
|
|
exception_type?: ExceptionType;
|
|
assigned_to?: number;
|
|
severity?: string;
|
|
page?: number;
|
|
limit?: number;
|
|
}): Promise<{ status: string; data: { exceptions: ReconciliationException[]; pagination: { total: number; page: number; limit: number; totalPages: number } } }> {
|
|
const response = await apiClient.get('/financial/reconciliation/exceptions', { params });
|
|
return response.data;
|
|
}
|
|
|
|
async assignException(exceptionId: number, assignedTo: number): Promise<{ status: string; data: ReconciliationException }> {
|
|
const response = await apiClient.post(`/financial/reconciliation/exceptions/${exceptionId}/assign`, {
|
|
assigned_to: assignedTo
|
|
});
|
|
return response.data;
|
|
}
|
|
|
|
async resolveException(exceptionId: number, notes: string): Promise<{ status: string; data: ReconciliationException }> {
|
|
const response = await apiClient.post(`/financial/reconciliation/exceptions/${exceptionId}/resolve`, {
|
|
notes
|
|
});
|
|
return response.data;
|
|
}
|
|
|
|
async addComment(exceptionId: number, comment: string): Promise<{ status: string; data: ReconciliationException }> {
|
|
const response = await apiClient.post(`/financial/reconciliation/exceptions/${exceptionId}/comment`, {
|
|
comment
|
|
});
|
|
return response.data;
|
|
}
|
|
|
|
async getExceptionStats(): Promise<{ status: string; data: ExceptionStats }> {
|
|
const response = await apiClient.get('/financial/reconciliation/exceptions/stats');
|
|
return response.data;
|
|
}
|
|
}
|
|
|
|
const reconciliationService = new ReconciliationService();
|
|
export default reconciliationService;
|
|
|