has('type')) { $query->where('type', $request->type); } if ($request->has('is_active')) { $query->where('is_active', $request->boolean('is_active')); } $accounts = $query->orderBy('name')->get(); return response()->json([ 'success' => true, 'data' => $accounts, 'types' => Account::TYPES, ]); } /** * Criar nova conta */ public function store(Request $request): JsonResponse { $validated = $request->validate([ 'name' => 'required|string|max:100', 'type' => ['required', Rule::in(array_keys(Account::TYPES))], 'bank_name' => 'nullable|string|max:100', 'account_number' => 'nullable|string|max:50', 'initial_balance' => 'nullable|numeric', 'credit_limit' => 'nullable|numeric', 'currency' => 'nullable|string|size:3', 'color' => 'nullable|string|max:7', 'icon' => 'nullable|string|max:50', 'description' => 'nullable|string', 'is_active' => 'nullable|boolean', 'include_in_total' => 'nullable|boolean', ]); $validated['user_id'] = Auth::id(); $validated['current_balance'] = $validated['initial_balance'] ?? 0; $account = Account::create($validated); return response()->json([ 'success' => true, 'message' => 'Conta criada com sucesso', 'data' => $account, ], 201); } /** * Exibir uma conta específica */ public function show(int $id): JsonResponse { $account = Account::where('user_id', Auth::id())->findOrFail($id); return response()->json([ 'success' => true, 'data' => $account, ]); } /** * Atualizar uma conta */ public function update(Request $request, int $id): JsonResponse { $account = Account::where('user_id', Auth::id())->findOrFail($id); $validated = $request->validate([ 'name' => 'sometimes|required|string|max:100', 'type' => ['sometimes', 'required', Rule::in(array_keys(Account::TYPES))], 'bank_name' => 'nullable|string|max:100', 'account_number' => 'nullable|string|max:50', 'initial_balance' => 'nullable|numeric', 'credit_limit' => 'nullable|numeric', 'currency' => 'nullable|string|size:3', 'color' => 'nullable|string|max:7', 'icon' => 'nullable|string|max:50', 'description' => 'nullable|string', 'is_active' => 'nullable|boolean', 'include_in_total' => 'nullable|boolean', ]); $account->update($validated); return response()->json([ 'success' => true, 'message' => 'Conta atualizada com sucesso', 'data' => $account->fresh(), ]); } /** * Deletar uma conta (soft delete) */ public function destroy(int $id): JsonResponse { $account = Account::where('user_id', Auth::id())->findOrFail($id); $account->delete(); return response()->json([ 'success' => true, 'message' => 'Conta excluída com sucesso', ]); } /** * Retorna o saldo total de todas as contas */ public function totalBalance(): JsonResponse { $accounts = Account::where('user_id', Auth::id()) ->active() ->includeInTotal() ->get(); $total = 0; foreach ($accounts as $account) { // Para passivos e cartões de crédito, o saldo é negativo if ($account->isCreditAccount()) { $total += (float) $account->current_balance; // já é negativo } else { $total += (float) $account->current_balance; } } return response()->json([ 'success' => true, 'data' => [ 'total_balance' => $total, 'accounts_count' => $accounts->count(), ], ]); } /** * Recalcular saldos de todas as contas do usuário */ public function recalculateBalances(): JsonResponse { $accounts = Account::where('user_id', Auth::id())->get(); $results = []; foreach ($accounts as $account) { $oldBalance = (float) $account->current_balance; $newBalance = $account->recalculateBalance(); $results[] = [ 'id' => $account->id, 'name' => $account->name, 'old_balance' => $oldBalance, 'new_balance' => $newBalance, 'difference' => $newBalance - $oldBalance, ]; } return response()->json([ 'success' => true, 'message' => 'Saldos recalculados com sucesso', 'data' => $results, ]); } /** * Recalcular saldo de uma conta específica */ public function recalculateBalance(int $id): JsonResponse { $account = Account::where('user_id', Auth::id())->findOrFail($id); $oldBalance = (float) $account->current_balance; $newBalance = $account->recalculateBalance(); return response()->json([ 'success' => true, 'message' => 'Saldo recalculado com sucesso', 'data' => [ 'id' => $account->id, 'name' => $account->name, 'old_balance' => $oldBalance, 'new_balance' => $newBalance, 'difference' => $newBalance - $oldBalance, ], ]); } /** * Ajustar saldo de uma conta definindo o saldo real atual * Calcula e atualiza o initial_balance para que: initial_balance + créditos - débitos = saldo_desejado */ public function adjustBalance(Request $request, int $id): JsonResponse { $validated = $request->validate([ 'target_balance' => 'required|numeric', ]); $account = Account::where('user_id', Auth::id())->findOrFail($id); $targetBalance = (float) $validated['target_balance']; $oldInitialBalance = (float) $account->initial_balance; $oldCurrentBalance = (float) $account->current_balance; // Calcular soma de transações $credits = (float) $account->transactions() ->where('type', 'credit') ->where('status', 'completed') ->sum('amount'); $debits = (float) $account->transactions() ->where('type', 'debit') ->where('status', 'completed') ->sum('amount'); // Calcular novo initial_balance: target = initial + credits - debits // initial = target - credits + debits $newInitialBalance = $targetBalance - $credits + $debits; // Atualizar conta $account->update([ 'initial_balance' => $newInitialBalance, 'current_balance' => $targetBalance, ]); return response()->json([ 'success' => true, 'message' => 'Saldo ajustado com sucesso', 'data' => [ 'id' => $account->id, 'name' => $account->name, 'old_initial_balance' => $oldInitialBalance, 'new_initial_balance' => $newInitialBalance, 'old_current_balance' => $oldCurrentBalance, 'new_current_balance' => $targetBalance, 'credits_sum' => $credits, 'debits_sum' => $debits, ], ]); } }