/** * Account Service - API calls for account management */ import api from './api'; import type { Account, AccountFormInput, TransferFormInput, ApiResponse } from '../types'; /** * Get all accounts */ export async function getAccounts(): Promise { const response = await api.get>('/accounts'); return response.data || []; } /** * Get a single account by ID */ export async function getAccount(id: number): Promise { const response = await api.get>(`/accounts/${id}`); if (!response.data) { throw new Error('Account not found'); } return response.data; } /** * Create a new account */ export async function createAccount(data: AccountFormInput): Promise { // Convert camelCase to snake_case for backend const payload = { name: data.name, type: data.type, balance: data.balance, currency: data.currency, icon: data.icon, billing_date: data.billingDate, payment_date: data.paymentDate, }; const response = await api.post>('/accounts', payload); if (!response.data) { throw new Error(response.error || 'Failed to create account'); } return response.data; } /** * Update an existing account */ export async function updateAccount(id: number, data: Partial): Promise { // Convert camelCase to snake_case for backend const payload: Record = {}; if (data.name !== undefined) payload.name = data.name; if (data.type !== undefined) payload.type = data.type; if (data.balance !== undefined) payload.balance = data.balance; if (data.currency !== undefined) payload.currency = data.currency; if (data.icon !== undefined) payload.icon = data.icon; if (data.billingDate !== undefined) payload.billing_date = data.billingDate; if (data.paymentDate !== undefined) payload.payment_date = data.paymentDate; const response = await api.put>(`/accounts/${id}`, payload); if (!response.data) { throw new Error(response.error || 'Failed to update account'); } return response.data; } /** * Delete an account */ export async function deleteAccount(id: number): Promise { await api.delete>(`/accounts/${id}`); } /** * Transfer between accounts */ export async function transferBetweenAccounts(data: TransferFormInput): Promise { // Convert camelCase to snake_case for backend const payload = { from_account_id: data.fromAccountId, to_account_id: data.toAccountId, amount: data.amount, note: data.note, }; const response = await api.post>('/accounts/transfer', payload); if (!response.success && response.error) { throw new Error(response.error); } } /** * Get accounts grouped by type */ export function groupAccountsByType(accounts: Account[] | undefined): Record { if (!accounts || !Array.isArray(accounts)) { return {}; } return accounts.reduce( (groups, account) => { const type = account.type; if (!groups[type]) { groups[type] = []; } groups[type].push(account); return groups; }, {} as Record ); } /** * Calculate total balance for accounts */ export function calculateTotalBalance(accounts: Account[] | undefined): number { if (!accounts || !Array.isArray(accounts)) { return 0; } return accounts.reduce((total, account) => total + account.balance, 0); } /** * Calculate total assets (positive balances) */ export function calculateTotalAssets(accounts: Account[] | undefined): number { if (!accounts || !Array.isArray(accounts)) { return 0; } return accounts .filter((account) => account.balance > 0) .reduce((total, account) => total + account.balance, 0); } /** * Calculate total liabilities (negative balances) */ export function calculateTotalLiabilities(accounts: Account[] | undefined): number { if (!accounts || !Array.isArray(accounts)) { return 0; } return accounts .filter((account) => account.balance < 0) .reduce((total, account) => total + Math.abs(account.balance), 0); } export default { getAccounts, getAccount, createAccount, updateAccount, deleteAccount, transferBetweenAccounts, groupAccountsByType, calculateTotalBalance, calculateTotalAssets, calculateTotalLiabilities, };