/** * Report Service * Handles API calls for statistical reports and analysis */ import api from './api'; import type { CurrencyCode } from '../types'; const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:2612/api/v1'; // Report API Response Types export interface CurrencySummary { currency: CurrencyCode; total_income: number; total_expense: number; balance: number; count: number; } export interface UnifiedSummary { target_currency: CurrencyCode; total_income: number; total_expense: number; balance: number; conversion_date: string; } export interface TransactionSummaryResponse { by_currency: CurrencySummary[]; unified?: UnifiedSummary; } export interface CategorySummaryItem { category_id: number; category_name: string; currency?: CurrencyCode; total_amount: number; count: number; percentage: number; } export interface CategorySummaryResponse { by_currency: CategorySummaryItem[]; unified?: CategorySummaryItem[]; } export interface TrendDataPoint { Date: string; TotalIncome: number; TotalExpense: number; Balance: number; Count: number; } export interface TrendDataResponse { period: 'day' | 'week' | 'month' | 'year'; currency?: CurrencyCode; data_points: TrendDataPoint[]; } export interface SummaryParams { start_date: string; end_date: string; target_currency?: CurrencyCode; conversion_date?: string; } export interface CategoryParams { start_date: string; end_date: string; type: 'income' | 'expense'; target_currency?: CurrencyCode; conversion_date?: string; } export interface TrendParams { start_date: string; end_date: string; period: 'day' | 'week' | 'month' | 'year'; currency?: CurrencyCode; } export interface ExportParams { start_date: string; end_date: string; format: 'pdf' | 'excel'; target_currency?: CurrencyCode; } /** * Get transaction summary for a date range */ export const getTransactionSummary = async ( params: SummaryParams ): Promise => { const response = await api.get<{ success: boolean; data: TransactionSummaryResponse }>( '/reports/summary', params as unknown as Record ); if (!response.data) { throw new Error('Failed to get transaction summary'); } return response.data; }; /** * Get category summary for a date range */ export const getCategorySummary = async ( params: CategoryParams ): Promise => { const response = await api.get<{ success: boolean; data: CategorySummaryResponse }>( '/reports/category', params as unknown as Record ); if (!response.data) { throw new Error('Failed to get category summary'); } return response.data; }; /** * Get trend data for a date range */ export const getTrendData = async ( params: TrendParams ): Promise => { const response = await api.get<{ success: boolean; data: TrendDataResponse }>( '/reports/trend', params as unknown as Record ); if (!response.data) { throw new Error('Failed to get trend data'); } return response.data; }; /** * Export report as PDF or Excel * Downloads the file directly to the user's device */ export const exportReport = async (params: ExportParams): Promise => { // Use fetch directly for blob response const response = await fetch(`${API_BASE_URL}/reports/export`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(params), }); if (!response.ok) { const errorData = await response.json().catch(() => ({})); throw new Error(errorData.message || `Export failed with status: ${response.status}`); } // Get the blob from response const blob = await response.blob(); // Create a temporary URL for the blob const url = window.URL.createObjectURL(blob); // Create a temporary anchor element and trigger download const link = document.createElement('a'); link.href = url; // Generate filename based on date range and format const filename = `report_${params.start_date.replace(/-/g, '')}_to_${params.end_date.replace(/-/g, '')}.${params.format === 'pdf' ? 'pdf' : 'xlsx'}`; link.download = filename; // Trigger the download document.body.appendChild(link); link.click(); // Clean up document.body.removeChild(link); window.URL.revokeObjectURL(url); }; export default { getTransactionSummary, getCategorySummary, getTrendData, exportReport, };