290 lines
8.9 KiB
PHP
290 lines
8.9 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\CostCenter;
|
|
use App\Models\CostCenterKeyword;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class CostCenterController extends Controller
|
|
{
|
|
/**
|
|
* Listar todos os centros de custo do usuário
|
|
*/
|
|
public function index(Request $request): JsonResponse
|
|
{
|
|
$userId = Auth::id();
|
|
|
|
// Verificar se o usuário tem um centro de custo do sistema
|
|
// Se não tiver, criar automaticamente o "Geral"
|
|
$hasSystemCostCenter = CostCenter::where('user_id', $userId)
|
|
->where('is_system', true)
|
|
->exists();
|
|
|
|
if (!$hasSystemCostCenter) {
|
|
CostCenter::create([
|
|
'user_id' => $userId,
|
|
'name' => 'Geral',
|
|
'code' => 'GERAL',
|
|
'description' => 'Centro de custo padrão para transações não categorizadas',
|
|
'color' => '#6c757d',
|
|
'icon' => 'FaFolder',
|
|
'is_active' => true,
|
|
'is_system' => true,
|
|
]);
|
|
}
|
|
|
|
$query = CostCenter::where('user_id', $userId)
|
|
->with('keywords');
|
|
|
|
if ($request->has('is_active')) {
|
|
$query->where('is_active', $request->boolean('is_active'));
|
|
}
|
|
|
|
// Ordenar com centro de custo do sistema primeiro, depois por nome
|
|
$costCenters = $query->orderByDesc('is_system')->orderBy('name')->get();
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => $costCenters,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Criar novo centro de custo
|
|
*/
|
|
public function store(Request $request): JsonResponse
|
|
{
|
|
$validated = $request->validate([
|
|
'name' => 'required|string|max:100',
|
|
'code' => 'nullable|string|max:20|unique:cost_centers,code,NULL,id,user_id,' . Auth::id(),
|
|
'description' => 'nullable|string',
|
|
'color' => 'nullable|string|max:7',
|
|
'icon' => 'nullable|string|max:50',
|
|
'is_active' => 'nullable|boolean',
|
|
'keywords' => 'nullable|array',
|
|
'keywords.*' => 'string|max:100',
|
|
]);
|
|
|
|
$keywords = $validated['keywords'] ?? [];
|
|
unset($validated['keywords']);
|
|
|
|
$validated['user_id'] = Auth::id();
|
|
|
|
DB::beginTransaction();
|
|
try {
|
|
$costCenter = CostCenter::create($validated);
|
|
|
|
// Adicionar palavras-chave
|
|
foreach ($keywords as $keyword) {
|
|
$costCenter->keywords()->create([
|
|
'keyword' => trim($keyword),
|
|
'is_case_sensitive' => false,
|
|
'is_active' => true,
|
|
]);
|
|
}
|
|
|
|
DB::commit();
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => 'Centro de custo criado com sucesso',
|
|
'data' => $costCenter->load('keywords'),
|
|
], 201);
|
|
|
|
} catch (\Exception $e) {
|
|
DB::rollBack();
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Erro ao criar centro de custo: ' . $e->getMessage(),
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Exibir um centro de custo específico
|
|
*/
|
|
public function show(int $id): JsonResponse
|
|
{
|
|
$costCenter = CostCenter::where('user_id', Auth::id())
|
|
->with('keywords')
|
|
->findOrFail($id);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => $costCenter,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Atualizar um centro de custo
|
|
*/
|
|
public function update(Request $request, int $id): JsonResponse
|
|
{
|
|
$costCenter = CostCenter::where('user_id', Auth::id())->findOrFail($id);
|
|
|
|
// Impedir edição de centro de custo do sistema
|
|
if ($costCenter->is_system) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'O centro de custo do sistema não pode ser editado',
|
|
], 403);
|
|
}
|
|
|
|
$validated = $request->validate([
|
|
'name' => 'sometimes|required|string|max:100',
|
|
'code' => 'nullable|string|max:20|unique:cost_centers,code,' . $id . ',id,user_id,' . Auth::id(),
|
|
'description' => 'nullable|string',
|
|
'color' => 'nullable|string|max:7',
|
|
'icon' => 'nullable|string|max:50',
|
|
'is_active' => 'nullable|boolean',
|
|
'keywords' => 'nullable|array',
|
|
'keywords.*' => 'string|max:100',
|
|
]);
|
|
|
|
$keywords = $validated['keywords'] ?? null;
|
|
unset($validated['keywords']);
|
|
|
|
DB::beginTransaction();
|
|
try {
|
|
$costCenter->update($validated);
|
|
|
|
// Se keywords foram fornecidas, sincronizar
|
|
if ($keywords !== null) {
|
|
// Remover antigas
|
|
$costCenter->keywords()->delete();
|
|
|
|
// Adicionar novas
|
|
foreach ($keywords as $keyword) {
|
|
$costCenter->keywords()->create([
|
|
'keyword' => trim($keyword),
|
|
'is_case_sensitive' => false,
|
|
'is_active' => true,
|
|
]);
|
|
}
|
|
}
|
|
|
|
DB::commit();
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => 'Centro de custo atualizado com sucesso',
|
|
'data' => $costCenter->fresh()->load('keywords'),
|
|
]);
|
|
|
|
} catch (\Exception $e) {
|
|
DB::rollBack();
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Erro ao atualizar centro de custo: ' . $e->getMessage(),
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Deletar um centro de custo (soft delete)
|
|
*/
|
|
public function destroy(int $id): JsonResponse
|
|
{
|
|
$costCenter = CostCenter::where('user_id', Auth::id())->findOrFail($id);
|
|
|
|
// Impedir exclusão de centro de custo do sistema
|
|
if ($costCenter->is_system) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'O centro de custo do sistema não pode ser excluído',
|
|
], 403);
|
|
}
|
|
|
|
$costCenter->keywords()->delete();
|
|
$costCenter->delete();
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => 'Centro de custo excluído com sucesso',
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Adicionar palavra-chave a um centro de custo
|
|
*/
|
|
public function addKeyword(Request $request, int $id): JsonResponse
|
|
{
|
|
$costCenter = CostCenter::where('user_id', Auth::id())->findOrFail($id);
|
|
|
|
$validated = $request->validate([
|
|
'keyword' => 'required|string|max:100',
|
|
'is_case_sensitive' => 'nullable|boolean',
|
|
]);
|
|
|
|
$keyword = $costCenter->keywords()->create([
|
|
'keyword' => trim($validated['keyword']),
|
|
'is_case_sensitive' => $validated['is_case_sensitive'] ?? false,
|
|
'is_active' => true,
|
|
]);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => 'Palavra-chave adicionada com sucesso',
|
|
'data' => $keyword,
|
|
], 201);
|
|
}
|
|
|
|
/**
|
|
* Remover palavra-chave de um centro de custo
|
|
*/
|
|
public function removeKeyword(int $id, int $keywordId): JsonResponse
|
|
{
|
|
$costCenter = CostCenter::where('user_id', Auth::id())->findOrFail($id);
|
|
$keyword = $costCenter->keywords()->findOrFail($keywordId);
|
|
$keyword->delete();
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => 'Palavra-chave removida com sucesso',
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Encontrar centro de custo por texto (usando palavras-chave)
|
|
*/
|
|
public function matchByText(Request $request): JsonResponse
|
|
{
|
|
$validated = $request->validate([
|
|
'text' => 'required|string',
|
|
]);
|
|
|
|
$text = $validated['text'];
|
|
$textLower = strtolower($text);
|
|
|
|
$keywords = CostCenterKeyword::whereHas('costCenter', function ($query) {
|
|
$query->where('user_id', Auth::id())->where('is_active', true);
|
|
})
|
|
->where('is_active', true)
|
|
->with('costCenter')
|
|
->get();
|
|
|
|
$matches = [];
|
|
foreach ($keywords as $keyword) {
|
|
$searchText = $keyword->is_case_sensitive ? $text : $textLower;
|
|
$searchKeyword = $keyword->is_case_sensitive ? $keyword->keyword : strtolower($keyword->keyword);
|
|
|
|
if (str_contains($searchText, $searchKeyword)) {
|
|
$matches[] = [
|
|
'cost_center' => $keyword->costCenter,
|
|
'matched_keyword' => $keyword->keyword,
|
|
];
|
|
}
|
|
}
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => $matches,
|
|
]);
|
|
}
|
|
}
|