webmoney/backend/app/Http/Controllers/Api/AccountController.php
marco 54cccdd095 refactor: migração para desenvolvimento direto no servidor
- Removido README.md padrão do Laravel (backend)
- Removidos scripts de deploy (não mais necessários)
- Atualizado copilot-instructions.md para novo fluxo
- Adicionada documentação de auditoria do servidor
- Sincronizado código de produção com repositório

Novo workflow:
- Trabalhamos diretamente em /root/webmoney (symlink para /var/www/webmoney)
- Mudanças PHP são instantâneas
- Mudanças React requerem 'npm run build'
- Commit após validação funcional
2025-12-19 11:45:32 +01:00

262 lines
8.1 KiB
PHP
Executable File

<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\Account;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\Rule;
class AccountController extends Controller
{
/**
* Listar todas as contas do usuário
*/
public function index(Request $request): JsonResponse
{
$query = Account::where('user_id', Auth::id());
// Filtros opcionais
if ($request->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,
],
]);
}
}