# Requerimento de Diárias — Rotas e Controllers

## 1. Rotas do CMS (`v6/routes/basepro.php`)

O grupo `/cms` é aberto em `v6/routes/basepro.php:35`
(`Route::group(['prefix' => 'cms', 'before' => 'csrf'], ...)`) e fechado em
`v6/routes/basepro.php:513`. Tudo dentro dele herda o prefixo `/cms` e a
proteção CSRF (`before => csrf`).

### 1.1 Resource do CRUD

| Método | URI | Nome da rota | Controller@action | Middleware |
|---|---|---|---|---|
| GET | `/cms/requerimento-diarias` | `requerimento-diarias.index` | `Prefecture\RequerimentoDiariasController@index` | `check.route.permission` (construtor do controller) |
| GET | `/cms/requerimento-diarias/create` | `requerimento-diarias.create` | `...@create` | idem |
| POST | `/cms/requerimento-diarias` | `requerimento-diarias.store` | `...@store` | idem |
| GET | `/cms/requerimento-diarias/{id}` | `requerimento-diarias.show` | `...@show` | idem |
| GET | `/cms/requerimento-diarias/{id}/edit` | `requerimento-diarias.edit` | `...@edit` | idem |
| PUT/PATCH | `/cms/requerimento-diarias/{id}` | `requerimento-diarias.update` | `...@update` | idem |
| DELETE | `/cms/requerimento-diarias/{id}` | `requerimento-diarias.destroy` | `...@destroy` | idem |

Declaração: `v6/routes/basepro.php:205`

```php
Route::resource("requerimento-diarias", "Prefecture\RequerimentoDiariasController");
```

### 1.2 Exclusão em lote

| Método | URI | Nome | Controller@action | Middleware |
|---|---|---|---|---|
| POST | `/cms/requerimento-diarias/destroyAll` | `requerimento-diarias.destroyAll` | `Prefecture\RequerimentoDiariasController@destroyAll` | `check.route.permission` |

Declaração: `v6/routes/basepro.php:248`

```php
Route::post("requerimento-diarias/destroyAll", "Prefecture\RequerimentoDiariasController@destroyAll")->name('requerimento-diarias.destroyAll');
```

O corpo esperado é `toDelete[]` (array de ids) — enviado por
`v6/public/assets/js/custom/utilities/deleteAll.js`.

### 1.3 DataTable (JSON)

| Método | URI | Nome | Controller@action | Middleware |
|---|---|---|---|---|
| GET | `/cms/datatable/requerimento_diarias` | `datatable.requerimento_diarias` | `Prefecture\DatatableController@get_requerimentos_diarias` | `check.route.permission` (herdado de `Prefecture\Controller`) |

Declaração: `v6/routes/basepro.php:434`, dentro do grupo
`Route::group(['prefix' => 'datatable', 'as' => 'datatable.'], ...)`
(`v6/routes/basepro.php:396`), que herda o prefixo `/cms`.

> O nome literal declarado é `->name('requerimento_diarias')`; o prefixo
> `datatable.` do grupo produz o nome final `datatable.requerimento_diarias`.

### 1.4 Configurações de Requerimento

Estas rotas ficam **fora** do grupo `/cms` (declaradas após o fechamento em
`v6/routes/basepro.php:513`), portanto o prefixo é a raiz da aplicação.

| Método | URI | Nome | Controller@action | Middleware |
|---|---|---|---|---|
| GET | `/requerimento-diarias/configuracoes` | `requerimento-diarias-config.index` | `Prefecture\RequerimentoDiariasController@get_configuration` | `check.route.permission` (construtor) |
| PUT | `/requerimento-diarias/configuracoes/update` | `requerimento-diarias-config.update` | `...@update_configuration` | idem |
| GET | `/deletar-arquivo-padrao` | `deletar-arquivo-padrao` | `...@destroy_archive` | idem |
| GET | `/deletar-arquivo/{id}` | `deletar-arquivo` | `...@delete_archives` | idem |

Declarações: `v6/routes/basepro.php:526-530`

```php
/*Configurações de Requerimento*/
Route::get('requerimento-diarias/configuracoes', 'Prefecture\RequerimentoDiariasController@get_configuration')->name('requerimento-diarias-config.index');
Route::put('requerimento-diarias/configuracoes/update', 'Prefecture\RequerimentoDiariasController@update_configuration')->name('requerimento-diarias-config.update');
Route::get('/deletar-arquivo-padrao', 'Prefecture\RequerimentoDiariasController@destroy_archive')->name('deletar-arquivo-padrao');
Route::get('/deletar-arquivo/{id}', 'Prefecture\RequerimentoDiariasController@delete_archives')->name('deletar-arquivo');
```

> **Riscos estruturais:** (a) as duas rotas de exclusão usam **GET** para
> efeito destrutivo; (b) por estarem fora do grupo `/cms`, não há prefixo de
> instalação; (c) o middleware `check.route.permission` continua aplicado
> porque está no construtor do controller — mas o `hasAccess()` do middleware
> deriva a permissão do **nome** da rota (`deletar-arquivo-padrao`,
> `deletar-arquivo`), slugs que **não** existem na tabela `resources`.

## 2. Rotas do Portal (`v6/routes/web.php`)

Todo o `web.php` está dentro de
`Route::middleware(['check.site.manutention'])->group(...)`
(`v6/routes/web.php:7`).

| Método | URI | Nome | Controller@action | Middleware |
|---|---|---|---|---|
| ANY | `/requerimento-de-diarias` | `requerimento-de-diarias-portal.index` | `Portal\BuscaDiariasController@index` | `check.site.manutention` |
| GET | `/requerimento-de-diarias/{id}` | `requerimento-de-diarias-portal.show` | `Portal\BuscaDiariasController@show` | `check.site.manutention` |

Declarações: `v6/routes/web.php:210-212`

```php
###Requerimento de diárias########################################################
Route::any('/requerimento-de-diarias', 'Portal\BuscaDiariasController@index')->name('requerimento-de-diarias-portal.index');
Route::get('/requerimento-de-diarias/{id}', 'Portal\BuscaDiariasController@show')->name('requerimento-de-diarias-portal.show');
```

O `Route::any` existe porque o formulário de filtro do Portal usa
`method="POST"` (ver `v6/resources/views/portal/layouts/busca-diarias/show.blade.php:34`).

> **Não confundir:** `v6/routes/web.php:44-46` define
> `/requerimentos`, `/requerimentos/{slug}`, `/requerimentos/{slug1}/{slug2}`
> (`Portal\RequerimentoController`) — módulo **Publicações/Requérimentos**
> (`category_contents.slug = 'requerimentos'`, módulo 41). Não tem relação com
> as diárias.

## 3. Breadcrumbs (`v6/routes/breadcrumbs.php:323-327`)

```php
// Home > Diario
Breadcrumbs::register('requerimento-diarias', function ($breadcrumbs) {
    $breadcrumbs->parent('home');
    $breadcrumbs->push("Requerimento Diárias", route('requerimento-diarias.index'));
});
```

O nome do breadcrumb é `requerimento-diarias` (sem sufixo), usado tanto pela
view do Portal (`Breadcrumbs::view("portal.layouts.$model.layout.breadcrumb", 'requerimento-diarias', 'Requerimento Diárias')`)
quanto pela rota CMS `requerimento-diarias.index`.

## 4. Controllers — responsabilidades

### 4.1 `Prefecture\RequerimentoDiariasController`

Arquivo: `v6/app/Http/Controllers/Prefecture/RequerimentoDiariasController.php`

| Propriedade / método | Conteúdo |
|---|---|
| `__construct(IRequerimentoRepository $config_repository)` | Chama `menuClicks('requerimento-diarias')` (incrementa `menu_orders.clicks`), instancia `new RequerimentoRepository()`, resolve `RequerimentoDiarias`, `Servidor`, `State` via `app()`, aplica `$this->middleware('check.route.permission')` |
| `index()` | View `prefecture.contents.requerimento-diarias.index` |
| `create()` | Carrega `RequerimentoDiariasConfig` (id 1), sugere `max(codigo_diarias)+1`, lista `servidores` e `estados` |
| `store(RequerimentosRequest)` | `upInsert` + criação do `Archive` (lei padrão ou upload) |
| `edit($id)` | Carrega `archives` do requerimento, `RequerimentoDiarias` da tabela e a configuração |
| `update(Request, $id)` | `upInsert` + criação/atualização do `Archive` |
| `destroy($id)` | `$this->table->destroy($id)` (soft delete) → JSON |
| `destroyAll(Request)` | `$this->repository->destroyAll($request->toDelete)` → JSON |
| `show($id)` | `$this->repository->generatePDF($id)` (PDF sem máscara) |
| `get_configuration()` | View `prefecture.contents.requerimento-diarias.configuracoes.create` |
| `update_configuration(Request)` | Grava/atualiza a config (id 1) e sobe o arquivo da lei |
| `destroy_archive()` | `RequerimentoDiariasConfig::query()->update(['archive' => null, 'path' => null])` |
| `delete_archives($id)` | Remove `archives` do requerimento e marca `padrao_arquivo_config = false` |

### 4.2 `Portal\BuscaDiariasController`

Arquivo: `v6/app/Http/Controllers/Portal/BuscaDiariasController.php`

| Propriedade / método | Conteúdo |
|---|---|
| `__construct()` | `new RequerimentoRepository()` |
| `use GetInformationsPrefectureTrait` | Fornece `getTemplateActived()` |
| `index(DiariasRequest)` | Query Eloquent + filtros; view `portal.layouts.busca-diarias.show`; `paginate(10)` |
| `show($id)` | `$this->repository->generatePDF($id, true)` (PDF mascarado) |

> A classe estende `App\Http\Controllers\Admin\Controller`
> (`v6/app/Http/Controllers/Portal/BuscaDiariasController.php:13`) — herança
> fora do namespace esperado para um controller de Portal.

### 4.3 `Prefecture\DatatableController@get_requerimentos_diarias`

Arquivo: `v6/app/Http/Controllers/Prefecture/DatatableController.php:179-183`

```php
public function get_requerimentos_diarias()
{
    $requerimentos_diarias = DB::table('req_diarias')->get();
    return DataTables::of($this->struct_views($requerimentos_diarias, 'requerimento-diarias'))->make(true);
}
```

`struct_views()` (linha 504) injeta `edit`, `delete`, `active` e `inactivate`
conforme `has_access()`, que o JS consome para montar os botões.

## 5. Form Requests e validação

### `RequerimentosRequest` — `v6/app/Http/Requests/RequerimentosRequest.php`

| Campo | Regra | Mensagem |
|---|---|---|
| `codigo_diarias` | `required` | "O código do Requerimento de Diárias é obrigatório." |
| `id_servidor` | `[new SelectRule, 'required']` | "O Servidor é obrigatório." |
| `dados_objetivo` | `required` | "O dados de objetivo da viagem são obrigatórios." |
| `cidade_destino` | `required` | "A cidade de destino é obrigatório." |
| `estado_destino` | `[new SelectRule, 'required']` | "O estado de destino é obrigatório." |
| `placa_transporte` | `required` | "A placa do veiculo de transporte é obrigatória." |
| `data_saida` | `required` | "A data de saída é obrigatória." |
| `data_entrada` | `required` | "A data de entrada é obrigatória." |
| `duracao_viagem` | `required` | "A duração da viagem é obrigatória." |
| `fundamentos_legais` | `required` | "O campo de Fundamentos Legais é obrigatório." |
| `valor_diarias` | `required` | "O campo de valor das diárias é obrigatório." |
| `numero_diarias` | `required` | "O campo de quantidade das diárias é obrigatório." |
| `archive.*.0` | `mimes:doc,docx,pdf` | "O arquivo selecionado não é um arquivo válido." |

`SelectRule` (`v6/app/Rules/SelectRule.php`) apenas rejeita o valor `'0'`.
`authorize()` retorna `true` — **não há autorização no Form Request**; a
autorização depende exclusivamente do middleware.

### `DiariasRequest` — `v6/app/Http/Requests/DiariasRequest.php`

| Campo | Regra | Mensagem |
|---|---|---|
| `cpf` | `nullable|min:14` | "Digite o CPF completo." |

Os demais filtros (`req_name`, `num_diaria`, `data_saida`, `data_retorno`) **não
são validados**.

### `RequerimentosConfigsRequest` — `v6/app/Http/Requests/RequerimentosConfigsRequest.php`

| Campo | Regra |
|---|---|
| `lei_padrao` | `required` |
| `archive` | `required|file|mimes:pdf,doc,docx` |

**Classe órfã:** `update_configuration()` recebe `Illuminate\Http\Request` cru,
não este Form Request. As regras nunca são aplicadas.

## 6. API Resources / Presenters

**Não existem** API Resources nem Presenters para este módulo. As saídas são:

| Endpoint | Formato |
|---|---|
| `/cms/datatable/requerimento_diarias` | JSON do Yajra DataTables (sem `Resource`) |
| `/cms/requerimento-diarias/{id}` (destroy/destroyAll) | JSON manual `{"success": ...}` / `{"erro": ...}` |
| `/cms/requerimento-diarias/{id}` (show) | PDF (stream DomPDF) |
| `/requerimento-de-diarias` | HTML (Blade) |
| `/requerimento-de-diarias/{id}` | PDF (stream DomPDF) |

## 7. Permissões e guard

| Recurso | Verificação |
|---|---|
| Todas as ações do controller CMS | `check.route.permission` (`v6/app/Http/Controllers/Prefecture/RequerimentoDiariasController.php:35`) |
| `super-admin` | Passa por todas as rotas sem checagem de acesso (`v6/app/Http/Middleware/CheckRoutePermission.php:24-32`) |
| Não logado | Redirecionado para `login` (`CheckRoutePermission.php:32-33`) |
| Rotas do Portal | Sem autenticação; apenas `check.site.manutention` |

O `hasAccess()` do middleware (`v6/app/Http/Middleware/CheckRoutePermission.php:41-95`)
deduz a permissão a partir do **nome da rota** e do segmento da URL. Para o
resource do CMS, os nomes `requerimento-diarias.index|create|store|show|edit|update|destroy`
coincidem com o padrão `<resource-slug>.<permissão>`.

## 8. Mapa de Permissões x Tela

| Elemento de UI | Permissão | Arquivo |
|---|---|---|
| Botão "Configurações" | `requerimento-diarias.create` | `v6/resources/views/prefecture/contents/requerimento-diarias/index.blade.php` |
| Botão "Cadastrar Requerimento Diárias" | `requerimento-diarias.create` | idem |
| Botão de exclusão em lote | `requerimento-diarias.delete` | idem |
| Checkbox master da tabela | `requerimento-diarias.delete` | idem |
| Botão Editar | `requerimento-diarias.edit` (via `struct_views`) | `v6/app/Http/Controllers/Prefecture/DatatableController.php:507` |
| Botão Excluir | `requerimento-diarias.delete` (via `struct_views`) | idem |
