diff --git a/app/Http/Controllers/Relatorio/Sistema/AuditoriaController.php b/app/Http/Controllers/Relatorio/Sistema/AuditoriaController.php new file mode 100644 index 00000000..20284f56 --- /dev/null +++ b/app/Http/Controllers/Relatorio/Sistema/AuditoriaController.php @@ -0,0 +1,88 @@ +middleware('permission:relatorio_sistema_auditoria', ['only' => ['index', 'show']]); + } + + /** + * Display a listing of the audit records. + */ + public function index(Request $request) + { + $auditorias = Audit::query(); + $auditorias->with('user'); + + // Filtro por modelo + if ($request->filled('auditable_type')) { + $auditorias->where('auditable_type', $request->auditable_type); + } + + // Filtro por tipo de evento + if ($request->filled('event')) { + $auditorias->where('event', $request->event); + } + + // Filtro por usuário + if ($request->filled('user_id')) { + $auditorias->where('user_id', $request->user_id); + } + + // Filtro por ID do registro auditado + if ($request->filled('auditable_id')) { + $auditorias->where('auditable_id', $request->auditable_id); + } + + // Filtro por data + if ($request->filled('data_inicio')) { + $auditorias->whereDate('created_at', '>=', $request->data_inicio); + } + + if ($request->filled('data_fim')) { + $auditorias->whereDate('created_at', '<=', $request->data_fim); + } + + // Ordenação padrão + $auditorias = $auditorias->latest('created_at')->paginate(50); + + // Obter lista de modelos auditados para o filtro + $modelos = Audit::select('auditable_type') + ->distinct() + ->orderBy('auditable_type') + ->pluck('auditable_type') + ->toArray(); + + $modelos = collect($modelos) + ->mapWithKeys(fn ($type) => [$type => class_basename($type)]) + ->all(); + + // Obter lista de usuários + $usuarios = \App\Models\User::orderBy('name')->pluck('name', 'id'); + + return view('relatorio.sistema.auditoria.index', [ + 'auditorias' => $auditorias, + 'request' => $request, + 'modelos' => $modelos, + 'usuarios' => $usuarios, + ]); + } + + /** + * Display the specified audit record. + */ + public function show(Audit $auditoria) + { + return view('relatorio.sistema.auditoria.show', [ + 'auditoria' => $auditoria, + ]); + } +} diff --git a/app/Models/Checklist/Checklist.php b/app/Models/Checklist/Checklist.php index 2ced28b8..97e6e6a9 100644 --- a/app/Models/Checklist/Checklist.php +++ b/app/Models/Checklist/Checklist.php @@ -7,10 +7,12 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use OwenIt\Auditing\Contracts\Auditable; -class Checklist extends Model +class Checklist extends Model implements Auditable { use HasFactory; + use \OwenIt\Auditing\Auditable; public function categoria(): BelongsTo { diff --git a/app/Models/Cliente/Cliente.php b/app/Models/Cliente/Cliente.php index b169d2e8..404237ae 100644 --- a/app/Models/Cliente/Cliente.php +++ b/app/Models/Cliente/Cliente.php @@ -9,10 +9,12 @@ use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; +use OwenIt\Auditing\Contracts\Auditable; -class Cliente extends Model +class Cliente extends Model implements Auditable { use HasFactory; + use \OwenIt\Auditing\Auditable; /** * The attributes that should be cast. diff --git a/app/Models/Configuracao/Garantia/Garantia.php b/app/Models/Configuracao/Garantia/Garantia.php index 764b51d6..6cf08bd7 100644 --- a/app/Models/Configuracao/Garantia/Garantia.php +++ b/app/Models/Configuracao/Garantia/Garantia.php @@ -5,10 +5,12 @@ use App\Models\User; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use OwenIt\Auditing\Contracts\Auditable; -class Garantia extends Model +class Garantia extends Model implements Auditable { use HasFactory; + use \OwenIt\Auditing\Auditable; /** * Retorna o nome do usuário. diff --git a/app/Models/Configuracao/Parametro/Categoria.php b/app/Models/Configuracao/Parametro/Categoria.php index 3d02b4ff..02dfa4d8 100644 --- a/app/Models/Configuracao/Parametro/Categoria.php +++ b/app/Models/Configuracao/Parametro/Categoria.php @@ -7,10 +7,12 @@ use App\Models\Configuracao\Garantia\Garantia; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use OwenIt\Auditing\Contracts\Auditable; -class Categoria extends Model +class Categoria extends Model implements Auditable { use HasFactory; + use \OwenIt\Auditing\Auditable; /** * Os atributos que são atribuíveis em massa. diff --git a/app/Models/Configuracao/Parametro/Status.php b/app/Models/Configuracao/Parametro/Status.php index 2fd02829..05f798c1 100644 --- a/app/Models/Configuracao/Parametro/Status.php +++ b/app/Models/Configuracao/Parametro/Status.php @@ -8,10 +8,12 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasMany; +use OwenIt\Auditing\Contracts\Auditable; -class Status extends Model +class Status extends Model implements Auditable { use HasFactory; + use \OwenIt\Auditing\Auditable; protected $table = 'status'; diff --git a/app/Models/Configuracao/Sistema/SistemaConfig.php b/app/Models/Configuracao/Sistema/SistemaConfig.php index 9d579748..275100cb 100644 --- a/app/Models/Configuracao/Sistema/SistemaConfig.php +++ b/app/Models/Configuracao/Sistema/SistemaConfig.php @@ -4,10 +4,12 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use OwenIt\Auditing\Contracts\Auditable; -class SistemaConfig extends Model +class SistemaConfig extends Model implements Auditable { use HasFactory; + use \OwenIt\Auditing\Auditable; protected $fillable = [ 'key', diff --git a/app/Models/Financeiro/Contas.php b/app/Models/Financeiro/Contas.php index d20d8ac8..89f8490c 100644 --- a/app/Models/Financeiro/Contas.php +++ b/app/Models/Financeiro/Contas.php @@ -9,10 +9,12 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Http\Request; +use OwenIt\Auditing\Contracts\Auditable; -class Contas extends Model +class Contas extends Model implements Auditable { use HasFactory; + use \OwenIt\Auditing\Auditable; protected $fillable = [ 'tipo', @@ -172,7 +174,7 @@ public static function RelatorioContasAbertas(Request $request): ?object $query->selectRaw(' contas.id, contas.tipo, - contas.name, + contas.name, contas.os_id, contas.venda_id, clientes.name as cliente, diff --git a/app/Models/Financeiro/MetaContabil.php b/app/Models/Financeiro/MetaContabil.php index 1634576e..b9d27552 100644 --- a/app/Models/Financeiro/MetaContabil.php +++ b/app/Models/Financeiro/MetaContabil.php @@ -7,9 +7,12 @@ use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Model; use Illuminate\Http\Request; +use OwenIt\Auditing\Contracts\Auditable; -class MetaContabil extends Model +class MetaContabil extends Model implements Auditable { + use \OwenIt\Auditing\Auditable; + /** * Relacionamento com o Centro de Custo. */ diff --git a/app/Models/Financeiro/Pagamentos.php b/app/Models/Financeiro/Pagamentos.php index 4d7a00ca..bfa6c02d 100644 --- a/app/Models/Financeiro/Pagamentos.php +++ b/app/Models/Financeiro/Pagamentos.php @@ -8,10 +8,12 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Http\Request; +use OwenIt\Auditing\Contracts\Auditable; -class Pagamentos extends Model +class Pagamentos extends Model implements Auditable { use HasFactory; + use \OwenIt\Auditing\Auditable; protected $table = 'contas_pagamentos'; diff --git a/app/Models/Os/Os.php b/app/Models/Os/Os.php index f6e131c5..3ab6e45e 100644 --- a/app/Models/Os/Os.php +++ b/app/Models/Os/Os.php @@ -16,10 +16,12 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Support\Facades\DB; +use OwenIt\Auditing\Contracts\Auditable; -class Os extends Model +class Os extends Model implements Auditable { use HasFactory; + use \OwenIt\Auditing\Auditable; protected $casts = [ 'data_entrada' => 'date', diff --git a/app/Models/Os/OsChecklist.php b/app/Models/Os/OsChecklist.php index 9bae9a3d..7d3b5d32 100644 --- a/app/Models/Os/OsChecklist.php +++ b/app/Models/Os/OsChecklist.php @@ -4,10 +4,12 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use OwenIt\Auditing\Contracts\Auditable; -class OsChecklist extends Model +class OsChecklist extends Model implements Auditable { use HasFactory; + use \OwenIt\Auditing\Auditable; protected $fillable = [ 'name', diff --git a/app/Models/Os/OsInformacao.php b/app/Models/Os/OsInformacao.php index 711797a4..e90c1bca 100644 --- a/app/Models/Os/OsInformacao.php +++ b/app/Models/Os/OsInformacao.php @@ -4,10 +4,12 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use OwenIt\Auditing\Contracts\Auditable; -class OsInformacao extends Model +class OsInformacao extends Model implements Auditable { use HasFactory; + use \OwenIt\Auditing\Auditable; protected $fillable = [ 'user_id', diff --git a/app/Models/Os/OsProduto.php b/app/Models/Os/OsProduto.php index 53b9922d..1786c226 100644 --- a/app/Models/Os/OsProduto.php +++ b/app/Models/Os/OsProduto.php @@ -7,10 +7,12 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use OwenIt\Auditing\Contracts\Auditable; -class OsProduto extends Model +class OsProduto extends Model implements Auditable { use HasFactory; + use \OwenIt\Auditing\Auditable; protected $fillable = [ 'valor_custo', diff --git a/app/Models/Os/OsServico.php b/app/Models/Os/OsServico.php index c3fa5a74..44b245da 100644 --- a/app/Models/Os/OsServico.php +++ b/app/Models/Os/OsServico.php @@ -6,10 +6,12 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use OwenIt\Auditing\Contracts\Auditable; -class OsServico extends Model +class OsServico extends Model implements Auditable { use HasFactory; + use \OwenIt\Auditing\Auditable; protected $fillable = [ 'servico_id', diff --git a/app/Models/Produto/Produto.php b/app/Models/Produto/Produto.php index 95a3bfb5..0608a4f8 100644 --- a/app/Models/Produto/Produto.php +++ b/app/Models/Produto/Produto.php @@ -10,10 +10,12 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Http\Request; +use OwenIt\Auditing\Contracts\Auditable; -class Produto extends Model +class Produto extends Model implements Auditable { use HasFactory; + use \OwenIt\Auditing\Auditable; /** * Retornar as movimentações dos Produtos. diff --git a/app/Models/Servico/Servico.php b/app/Models/Servico/Servico.php index e4dd0ad8..2bd09bce 100644 --- a/app/Models/Servico/Servico.php +++ b/app/Models/Servico/Servico.php @@ -7,10 +7,12 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasMany; +use OwenIt\Auditing\Contracts\Auditable; -class Servico extends Model +class Servico extends Model implements Auditable { use HasFactory; + use \OwenIt\Auditing\Auditable; /** * Retornar as Os dos Produtos. diff --git a/app/Models/Venda/Venda.php b/app/Models/Venda/Venda.php index 1d206405..16f7b2bb 100644 --- a/app/Models/Venda/Venda.php +++ b/app/Models/Venda/Venda.php @@ -11,10 +11,12 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Support\Facades\DB; +use OwenIt\Auditing\Contracts\Auditable; -class Venda extends Model +class Venda extends Model implements Auditable { use HasFactory; + use \OwenIt\Auditing\Auditable; protected $casts = [ 'data_saida' => 'date', diff --git a/app/Models/Venda/VendaProduto.php b/app/Models/Venda/VendaProduto.php index 400bbb4a..bdc27580 100644 --- a/app/Models/Venda/VendaProduto.php +++ b/app/Models/Venda/VendaProduto.php @@ -6,10 +6,12 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use OwenIt\Auditing\Contracts\Auditable; -class VendaProduto extends Model +class VendaProduto extends Model implements Auditable { use HasFactory; + use \OwenIt\Auditing\Auditable; protected $fillable = [ 'valor_custo', diff --git a/app/Models/Wiki/File.php b/app/Models/Wiki/File.php index 10b3ae72..fa68e1ae 100644 --- a/app/Models/Wiki/File.php +++ b/app/Models/Wiki/File.php @@ -4,10 +4,12 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use OwenIt\Auditing\Contracts\Auditable; -class File extends Model +class File extends Model implements Auditable { use HasFactory; + use \OwenIt\Auditing\Auditable; protected $table = 'wiki_files'; diff --git a/app/Models/Wiki/Link.php b/app/Models/Wiki/Link.php index c98e3e7c..a953d48d 100644 --- a/app/Models/Wiki/Link.php +++ b/app/Models/Wiki/Link.php @@ -4,10 +4,12 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use OwenIt\Auditing\Contracts\Auditable; -class Link extends Model +class Link extends Model implements Auditable { use HasFactory; + use \OwenIt\Auditing\Auditable; protected $table = 'wiki_links'; diff --git a/app/Models/Wiki/Wiki.php b/app/Models/Wiki/Wiki.php index 522c8636..3e533b7b 100644 --- a/app/Models/Wiki/Wiki.php +++ b/app/Models/Wiki/Wiki.php @@ -11,10 +11,12 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Http\Request; +use OwenIt\Auditing\Contracts\Auditable; -class Wiki extends Model +class Wiki extends Model implements Auditable { use HasFactory; + use \OwenIt\Auditing\Auditable; public function fabricante() { diff --git a/composer.json b/composer.json index a284687a..c0c07587 100644 --- a/composer.json +++ b/composer.json @@ -18,6 +18,7 @@ "laravellegends/pt-br-validator": "^12.0", "livewire/livewire": "^3.4", "opcodesio/log-viewer": "^3.15", + "owen-it/laravel-auditing": "^14.0", "php-flasher/flasher-laravel": "^2.1", "spatie/laravel-backup": "^9.3", "spatie/laravel-html": "^3.2", diff --git a/composer.lock b/composer.lock index e1c4b9e7..762ecf78 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5efba3922bd708193b1eb76e212ddc09", + "content-hash": "29e63f39c1e1243226548d2036c44e74", "packages": [ { "name": "almasaeed2010/adminlte", @@ -3957,6 +3957,90 @@ }, "time": "2023-11-19T08:47:43+00:00" }, + { + "name": "owen-it/laravel-auditing", + "version": "v14.0.3", + "source": { + "type": "git", + "url": "https://github.com/owen-it/laravel-auditing.git", + "reference": "34e8a21890082a7a353894a4acdeb2d301dbe0d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/owen-it/laravel-auditing/zipball/34e8a21890082a7a353894a4acdeb2d301dbe0d4", + "reference": "34e8a21890082a7a353894a4acdeb2d301dbe0d4", + "shasum": "" + }, + "require": { + "ext-json": "*", + "illuminate/console": "^11.0|^12.0|^13.0", + "illuminate/database": "^11.0|^12.0|^13.0", + "illuminate/filesystem": "^11.0|^12.0|^13.0", + "php": "^8.2" + }, + "require-dev": { + "mockery/mockery": "^1.5.1", + "orchestra/testbench": "^9.0|^10.0|^11.0", + "phpunit/phpunit": "^11.0|^12.5.12" + }, + "type": "package", + "extra": { + "laravel": { + "providers": [ + "OwenIt\\Auditing\\AuditingServiceProvider" + ] + }, + "branch-alias": { + "dev-master": "v14-dev" + } + }, + "autoload": { + "psr-4": { + "OwenIt\\Auditing\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Antério Vieira", + "email": "anteriovieira@gmail.com" + }, + { + "name": "Raphael França", + "email": "raphaelfrancabsb@gmail.com" + }, + { + "name": "Morten D. Hansen", + "email": "morten@visia.dk" + } + ], + "description": "Audit changes of your Eloquent models in Laravel", + "homepage": "https://laravel-auditing.com", + "keywords": [ + "Accountability", + "Audit", + "auditing", + "changes", + "eloquent", + "history", + "laravel", + "log", + "logging", + "lumen", + "observer", + "record", + "revision", + "tracking" + ], + "support": { + "issues": "https://github.com/owen-it/laravel-auditing/issues", + "source": "https://github.com/owen-it/laravel-auditing" + }, + "time": "2026-03-27T13:27:17+00:00" + }, { "name": "paragonie/constant_time_encoding", "version": "v3.0.0", @@ -12158,5 +12242,5 @@ "php": "^8.2" }, "platform-dev": {}, - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.9.0" } diff --git a/config/adminlte.php b/config/adminlte.php index 6e6676bd..ab8dff92 100644 --- a/config/adminlte.php +++ b/config/adminlte.php @@ -450,7 +450,7 @@ 'icon' => 'fa-regular fa-file-lines', 'can' => [ 'relatorio_financeiro_balancete', 'relatorio_financeiro_receita_despesa', 'relatorio_financeiro_conta_aberta', - 'relatorio_sistema_log', + 'relatorio_sistema_log', 'relatorio_sistema_auditoria', ], 'submenu' => [ [ @@ -488,6 +488,7 @@ 'icon' => 'fa-solid fa-sitemap', 'can' => [ 'relatorio_sistema_log', + 'relatorio_sistema_auditoria', ], 'submenu' => [ [ @@ -497,6 +498,13 @@ 'target' => '_blank', 'can' => 'relatorio_sistema_log', ], + [ + 'text' => 'Auditoria', + 'icon' => 'fas fa-history', + 'route' => 'relatorio.sistema.auditoria.index', + 'active' => ['relatorio/sistema/auditoria*'], + 'can' => 'relatorio_sistema_auditoria', + ], ], ], ], diff --git a/config/app.php b/config/app.php index 327fb5e4..ef9fade5 100644 --- a/config/app.php +++ b/config/app.php @@ -176,6 +176,9 @@ // Image Intervention.io // Intervention\Image\ImageServiceProvider::class, + // Laravel Auditing + OwenIt\Auditing\AuditingServiceProvider::class, + ])->toArray(), /* diff --git a/config/audit.php b/config/audit.php new file mode 100644 index 00000000..9c94d549 --- /dev/null +++ b/config/audit.php @@ -0,0 +1,198 @@ + env('AUDITING_ENABLED', true), + + /* + |-------------------------------------------------------------------------- + | Audit Implementation + |-------------------------------------------------------------------------- + | + | Define which Audit model implementation should be used. + | + */ + + 'implementation' => OwenIt\Auditing\Models\Audit::class, + + /* + |-------------------------------------------------------------------------- + | User Morph prefix & Guards + |-------------------------------------------------------------------------- + | + | Define the morph prefix and authentication guards for the User resolver. + | + */ + + 'user' => [ + 'morph_prefix' => 'user', + 'guards' => [ + 'web', + 'api', + ], + 'resolver' => OwenIt\Auditing\Resolvers\UserResolver::class, + ], + + /* + |-------------------------------------------------------------------------- + | Audit Resolvers + |-------------------------------------------------------------------------- + | + | Define the IP Address, User Agent and URL resolver implementations. + | + */ + 'resolvers' => [ + 'ip_address' => OwenIt\Auditing\Resolvers\IpAddressResolver::class, + 'user_agent' => OwenIt\Auditing\Resolvers\UserAgentResolver::class, + 'url' => OwenIt\Auditing\Resolvers\UrlResolver::class, + ], + + /* + |-------------------------------------------------------------------------- + | Audit Events + |-------------------------------------------------------------------------- + | + | The Eloquent events that trigger an Audit. + | + */ + + 'events' => [ + 'created', + 'updated', + 'deleted', + 'restored', + ], + + /* + |-------------------------------------------------------------------------- + | Strict Mode + |-------------------------------------------------------------------------- + | + | Enable the strict mode when auditing? + | + */ + + 'strict' => false, + + /* + |-------------------------------------------------------------------------- + | Global exclude + |-------------------------------------------------------------------------- + | + | Have something you always want to exclude by default? - add it here. + | Note that this is overwritten (not merged) with local exclude + | + */ + + 'exclude' => [], + + /* + |-------------------------------------------------------------------------- + | Empty Values + |-------------------------------------------------------------------------- + | + | Should Audit records be stored when the recorded old_values & new_values + | are both empty? + | + | Some events may be empty on purpose. Use allowed_empty_values to exclude + | those from the empty values check. For example when auditing + | model retrieved events which will never have new and old values. + | + | + */ + + 'empty_values' => true, + 'allowed_empty_values' => [ + 'retrieved', + ], + + /* + |-------------------------------------------------------------------------- + | Allowed Array Values + |-------------------------------------------------------------------------- + | + | Should the array values be audited? + | + | By default, array values are not allowed. This is to prevent performance + | issues when storing large amounts of data. You can override this by + | setting allow_array_values to true. + */ + 'allowed_array_values' => false, + + /* + |-------------------------------------------------------------------------- + | Audit Timestamps + |-------------------------------------------------------------------------- + | + | Should the created_at, updated_at and deleted_at timestamps be audited? + | + */ + + 'timestamps' => false, + + /* + |-------------------------------------------------------------------------- + | Audit Threshold + |-------------------------------------------------------------------------- + | + | Specify a threshold for the amount of Audit records a model can have. + | Zero means no limit. + | + */ + + 'threshold' => 0, + + /* + |-------------------------------------------------------------------------- + | Audit Driver + |-------------------------------------------------------------------------- + | + | The default audit driver used to keep track of changes. + | + */ + + 'driver' => 'database', + + /* + |-------------------------------------------------------------------------- + | Audit Driver Configurations + |-------------------------------------------------------------------------- + | + | Available audit drivers and respective configurations. + | + */ + + 'drivers' => [ + 'database' => [ + 'table' => 'audits', + 'connection' => null, + ], + ], + + /* + |-------------------------------------------------------------------------- + | Audit Queue Configurations + |-------------------------------------------------------------------------- + | + | Available audit queue configurations. + | + */ + + 'queue' => [ + 'enable' => false, + 'connection' => 'sync', + 'queue' => 'default', + 'delay' => 0, + ], + + /* + |-------------------------------------------------------------------------- + | Audit Console + |-------------------------------------------------------------------------- + | + | Whether console events should be audited (eg. php artisan db:seed). + | + */ + + 'console' => false, +]; diff --git a/database/migrations/2026_05_05_085235_create_audits_table.php b/database/migrations/2026_05_05_085235_create_audits_table.php new file mode 100644 index 00000000..f639a3e4 --- /dev/null +++ b/database/migrations/2026_05_05_085235_create_audits_table.php @@ -0,0 +1,47 @@ +create($table, function (Blueprint $table) { + $morphPrefix = config('audit.user.morph_prefix', 'user'); + + $table->bigIncrements('id'); + $table->string($morphPrefix.'_type')->nullable(); + $table->unsignedBigInteger($morphPrefix.'_id')->nullable(); + $table->string('event'); + $table->morphs('auditable'); + $table->text('old_values')->nullable(); + $table->text('new_values')->nullable(); + $table->text('url')->nullable(); + $table->ipAddress('ip_address')->nullable(); + $table->string('user_agent', 1023)->nullable(); + $table->string('tags')->nullable(); + $table->timestamps(); + + $table->index([$morphPrefix.'_id', $morphPrefix.'_type']); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + $connection = config('audit.drivers.database.connection', config('database.default')); + $table = config('audit.drivers.database.table', 'audits'); + + Schema::connection($connection)->drop($table); + } +}; diff --git a/database/seeders/DefaultsConfigPermissionsRelatorio.php b/database/seeders/DefaultsConfigPermissionsRelatorio.php index 36c52075..5ed5f2f1 100644 --- a/database/seeders/DefaultsConfigPermissionsRelatorio.php +++ b/database/seeders/DefaultsConfigPermissionsRelatorio.php @@ -38,6 +38,12 @@ public function run(): void 'guard_name' => 'web', 'group_id' => 2, ], + [ + 'description' => 'Acesso ao Relatório de Auditoria do Sistema', + 'name' => 'relatorio_sistema_auditoria', + 'guard_name' => 'web', + 'group_id' => 2, + ], ]; foreach ($insert as $key => $value) { diff --git a/resources/views/checklist/show.blade.php b/resources/views/checklist/show.blade.php index b22404b3..db84b58a 100644 --- a/resources/views/checklist/show.blade.php +++ b/resources/views/checklist/show.blade.php @@ -19,6 +19,14 @@ Voltar + @can('relatorio_sistema_auditoria') + + + + @endcan diff --git a/resources/views/cliente/show.blade.php b/resources/views/cliente/show.blade.php index 5bd9bdda..660271c6 100644 --- a/resources/views/cliente/show.blade.php +++ b/resources/views/cliente/show.blade.php @@ -7,6 +7,14 @@ @stop @section('content') +
+ @can('relatorio_sistema_auditoria') + + + Auditoria + + @endcan +
@livewire('cliente.show-cliente', ['cliente' => $cliente], key('detalhes-tab')) @stop diff --git a/resources/views/financeiro/despesa/show.blade.php b/resources/views/financeiro/despesa/show.blade.php index 2c79c49d..45e1216a 100644 --- a/resources/views/financeiro/despesa/show.blade.php +++ b/resources/views/financeiro/despesa/show.blade.php @@ -19,6 +19,14 @@ Voltar + @can('relatorio_sistema_auditoria') + + + + @endcan @can('financeiro_despesa_edit') + @can('relatorio_sistema_auditoria') + + + + @endcan diff --git a/resources/views/financeiro/receita/show.blade.php b/resources/views/financeiro/receita/show.blade.php index 52a05ba2..efaeb3fd 100644 --- a/resources/views/financeiro/receita/show.blade.php +++ b/resources/views/financeiro/receita/show.blade.php @@ -19,6 +19,14 @@ Voltar + @can('relatorio_sistema_auditoria') + + + + @endcan @can('financeiro_receita_edit') + @can('relatorio_sistema_auditoria') + + + + @endcan @can('os_edit') + @can('relatorio_sistema_auditoria') + + + + @endcan @can('produto_edit') + + @if (Request::all()) + + + + @endif + + @if (count($request->all()) > 0) + + + + @endif + + +
+
+ {{ App\Models\Configuracao\Sistema\Emitente::getHtmlEmitente(1) }} +
+ + @include('adminlte::partials.form-alert') + +
+
+
+ + {!! html()->number('auditable_id', $request->auditable_id)->class('form-control')->placeholder('ID do Registro') !!} +
+
+
+
+ + {!! html()->date('data_inicio', ($request->data_inicio == true) ? $request->data_inicio : null)->class('form-control')->placeholder('Data Início') !!} +
+
+ +
+
+ + {!! html()->date('data_fim', ($request->data_fim == true) ? $request->data_fim : null)->class('form-control')->placeholder('Data Fim') !!} +
+
+
+
+ + {!! html()->select('auditable_type', ['' => '-- Selecione --'] + $modelos, $request->auditable_type)->class('form-control')->placeholder('Modelo') !!} +
+
+
+
+ + {!! html()->select('event', ['' => '-- Selecione --', 'created' => 'Criado', 'updated' => 'Atualizado', 'deleted' => 'Deletado'], $request->event)->class('form-control') !!} +
+
+ +
+
+ + {!! html()->select('user_id', ['' => '-- Selecione --'] + $usuarios->toArray(), $request->user_id)->class('form-control') !!} +
+
+
+
+ + + + + + + + + + + + + @forelse($auditorias as $auditoria) + + + + + + + + + @empty + + + + @endforelse + +
#ModeloUsuárioEventoData/Hora
{{ $auditoria->auditable_id }} + + {{ class_basename($auditoria->auditable_type) }} + + + @if($auditoria->user) + {{ $auditoria->user->name }} + @else + Sistema + @endif + + @if($auditoria->event === 'created') + {{ ucfirst($auditoria->event) }} + @elseif($auditoria->event === 'updated') + {{ ucfirst($auditoria->event) }} + @elseif($auditoria->event === 'deleted') + {{ ucfirst($auditoria->event) }} + @else + {{ ucfirst($auditoria->event) }} + @endif + + + {{ $auditoria->created_at->format('d/m/Y H:i:s') }} + + + + + +
+ Nenhum registro de auditoria encontrado. +
+
+ + @if($auditorias->count() > 0) +
+
+ {{ $auditorias->appends(request()->query())->links() }} +
+
+ @endif +
+ {!! html()->form()->close() !!} + +@stop diff --git a/resources/views/relatorio/sistema/auditoria/show.blade.php b/resources/views/relatorio/sistema/auditoria/show.blade.php new file mode 100644 index 00000000..c2c2fd3d --- /dev/null +++ b/resources/views/relatorio/sistema/auditoria/show.blade.php @@ -0,0 +1,254 @@ +@extends('adminlte::page') + +@section('title', 'Detalhes da Auditoria') + +@section('content_header') +

Detalhes da Auditoria

+@stop + +@section('content') +
+
+ + + + + + +
+ +
+
+ {{ App\Models\Configuracao\Sistema\Emitente::getHtmlEmitente(1) }} +
+ +
+
+
+ +

{{ $auditoria->created_at->format('d/m/Y H:i:s') }}

+
+
+
+ +
+
+
+ +

+ @if($auditoria->user) + {{ $auditoria->user->name }} + @else + Sistema + @endif +

+
+
+ +
+
+ +

+ @if($auditoria->event === 'created') + {{ ucfirst($auditoria->event) }} + @elseif($auditoria->event === 'updated') + {{ ucfirst($auditoria->event) }} + @elseif($auditoria->event === 'deleted') + {{ ucfirst($auditoria->event) }} + @else + {{ ucfirst($auditoria->event) }} + @endif +

+
+
+
+ +
+
+
+ +

+ + {{ class_basename($auditoria->auditable_type) }} + +

+
+
+ +
+
+ +

{{ $auditoria->auditable_id }}

+
+
+
+ +
+ +
+
+

Valores Alterados

+
+
+ + @if($auditoria->event === 'created') + +
+ + + + + + + + + @forelse($auditoria->new_values as $field => $value) + + + + + @empty + + + + @endforelse + +
CampoValor
{{ $field }} + @if(is_array($value)) +
{{ json_encode($value, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) }}
+ @else + {{ $value }} + @endif +
Sem alterações registradas
+
+ @elseif($auditoria->event === 'deleted') + +
+ + + + + + + + + @forelse($auditoria->old_values as $field => $value) + + + + + @empty + + + + @endforelse + +
CampoValor Deletado
{{ $field }} + @if(is_array($value)) +
{{ json_encode($value, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) }}
+ @else + {{ $value }} + @endif +
Sem dados deletados
+
+ @else + + + @if(count($auditoria->old_values) > 0 || count($auditoria->new_values) > 0) +
+
+
Valores Anteriores
+
+ + + + + + + + + @forelse($auditoria->old_values as $field => $value) + + + + + @empty + + + + @endforelse + +
CampoValor Anterior
{{ $field }} + @if(is_array($value)) +
{{ json_encode($value, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) }}
+ @else + {{ $value }} + @endif +
Nenhum
+
+
+ +
+
Novos Valores
+
+ + + + + + + + + @forelse($auditoria->new_values as $field => $value) + + + + + @empty + + + + @endforelse + +
CampoNovo Valor
{{ $field }} + @if(is_array($value)) +
{{ json_encode($value, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) }}
+ @else + {{ $value }} + @endif +
Nenhum
+
+
+
+ @else + + @endif + @endif + +
+ +
+
+

+ IP: {{ $auditoria->ip_address }}
+ User Agent: {{ $auditoria->user_agent }} +

+
+
+
+
+@stop diff --git a/resources/views/servico/show.blade.php b/resources/views/servico/show.blade.php index 5bb15cd4..6c3ff263 100644 --- a/resources/views/servico/show.blade.php +++ b/resources/views/servico/show.blade.php @@ -19,6 +19,14 @@ Voltar + @can('relatorio_sistema_auditoria') + + + + @endcan diff --git a/resources/views/venda/show.blade.php b/resources/views/venda/show.blade.php index edcce0f2..a48e45af 100644 --- a/resources/views/venda/show.blade.php +++ b/resources/views/venda/show.blade.php @@ -16,6 +16,14 @@ Voltar + @can('relatorio_sistema_auditoria') + + + + @endcan @can('os_edit') + + @endcan + @can('wiki_edit') + {{-- + + --}} + - --}} - - - @endcan + + @endcan +
diff --git a/routes/breadcrumbs.php b/routes/breadcrumbs.php index e9dbd7d0..90ad000c 100644 --- a/routes/breadcrumbs.php +++ b/routes/breadcrumbs.php @@ -27,6 +27,7 @@ use App\Models\Wiki\Wiki; use Diglactic\Breadcrumbs\Breadcrumbs; use Diglactic\Breadcrumbs\Generator as BreadcrumbTrail; +use OwenIt\Auditing\Models\Audit; use Spatie\Permission\Models\Permission; // This import is also not required, and you could replace `BreadcrumbTrail $trail` // with `$trail`. This is nice for IDE type checking and completion. @@ -707,18 +708,40 @@ Breadcrumbs::for('relatorio.financeiro.balancete.index', function (BreadcrumbTrail $trail) { $trail->parent('home'); $trail->push('Relatórios'); + $trail->push('Financeiro'); $trail->push('Balancete', route('relatorio.financeiro.balancete.index')); }); // Financeiro Despesa Breadcrumbs::for('relatorio.financeiro.despesa.index', function (BreadcrumbTrail $trail) { $trail->parent('home'); $trail->push('Relatórios'); + $trail->push('Financeiro'); $trail->push('Despesa', route('relatorio.financeiro.despesa.index')); }); // Financeiro Contas em Aberto Breadcrumbs::for('relatorio.financeiro.conta_aberta.index', function (BreadcrumbTrail $trail) { $trail->parent('home'); $trail->push('Relatórios'); + $trail->push('Financeiro'); $trail->push('Contas em Aberto', route('relatorio.financeiro.conta_aberta.index')); }); +Breadcrumbs::for('relatorio.sistema.auditoria.index', function (BreadcrumbTrail $trail) { + $trail->parent('home'); + $trail->push('Relatórios'); + $trail->push('Sistema'); + $trail->push('Auditoria', route('relatorio.sistema.auditoria.index')); +}); + +Breadcrumbs::for('relatorio.sistema.auditoria.show', function (BreadcrumbTrail $trail, Audit $item) { + $trail->parent('home'); + $trail->push('Relatórios'); + $trail->push('Sistema'); + $trail->push(Str::limit($item->id), route('relatorio.sistema.auditoria.show', $item)); +}); + +// // Sistema > [Visualização de Sistema] +// Breadcrumbs::for('configuracao.sistema.show', function (BreadcrumbTrail $trail, SistemaConfig $item) { +// $trail->parent('configuracao.sistema.index'); +// $trail->push(Str::limit($item->name, 20), route('configuracao.sistema.show', $item)); +// }); // Relatório diff --git a/routes/web.php b/routes/web.php index 3fe41f6c..f59ed921 100644 --- a/routes/web.php +++ b/routes/web.php @@ -30,6 +30,7 @@ use App\Http\Controllers\Relatorio\Financeiro\BalanceteController; use App\Http\Controllers\Relatorio\Financeiro\ContaAbertaController; use App\Http\Controllers\Relatorio\Financeiro\ReceitaDespesaController; +use App\Http\Controllers\Relatorio\Sistema\AuditoriaController; use App\Http\Controllers\Servico\ServicoController; use App\Http\Controllers\TestController; use App\Http\Controllers\Venda\VendaController; @@ -134,6 +135,12 @@ Route::get('/conta_aberta', [ContaAbertaController::class, 'index'])->name('conta_aberta.index'); }); + // Sistema + Route::name('sistema.')->prefix('sistema')->group(function () { + Route::get('/auditoria', [AuditoriaController::class, 'index'])->name('auditoria.index'); + Route::get('/auditoria/{auditoria}', [AuditoriaController::class, 'show'])->name('auditoria.show'); + }); + // // OS // Route::name('os.')->prefix('os')->group( function () {