Files
Novault-Frontend-web/copy/src/services/accountService.ts

159 lines
4.3 KiB
TypeScript

/**
* 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<Account[]> {
const response = await api.get<ApiResponse<Account[]>>('/accounts');
return response.data || [];
}
/**
* Get a single account by ID
*/
export async function getAccount(id: number): Promise<Account> {
const response = await api.get<ApiResponse<Account>>(`/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<Account> {
// 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<ApiResponse<Account>>('/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<AccountFormInput>): Promise<Account> {
// Convert camelCase to snake_case for backend
const payload: Record<string, unknown> = {};
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<ApiResponse<Account>>(`/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<void> {
await api.delete<ApiResponse<void>>(`/accounts/${id}`);
}
/**
* Transfer between accounts
*/
export async function transferBetweenAccounts(data: TransferFormInput): Promise<void> {
// 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<ApiResponse<void>>('/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<string, Account[]> {
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<string, Account[]>
);
}
/**
* 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,
};