# Licitações — Views e UX

> Views CMS: `v6/resources/views/prefecture/**` (AdminLTE 1.22).
> Views Portal: `v6/resources/views/portal/**` (Bootstrap 4), com variantes de layout
> `modelo1`..`modelo6`, `newsbit` e `default`.

---

## 1. CMS — Licitações (`prefecture/biddings/`)

| Arquivo | Função |
|---|---|
| `v6/resources/views/prefecture/biddings/index.blade.php` | Listagem em DataTable (`#tabela_licitacao`), colunas ID/Número/Valor/Modalidade/Data de publicação/Tipo/Situação/Ações; botão “Cadastrar Licitação” (`licitacao.create`) e botão de exclusão em lote (`ajax.bidding.deleteByLote`). |
| `v6/resources/views/prefecture/biddings/create.blade.php` | Formulário de cadastro (`Form::open(['route' => ['licitacao.index'], 'files' => true])`), botão com `desabilitaBotao()` (spinner `loading.gif`). |
| `v6/resources/views/prefecture/biddings/edit.blade.php` | Formulário de edição + script `deleteArchive(archive_id)` que faz `POST` em `route('ajax.delete.files-licitacoes')` com `_token`, `licitacao` e `archive_id`. |
| `v6/resources/views/prefecture/biddings/form.blade.php` | Formulário compartilhado (create/edit). |
| `v6/resources/views/prefecture/biddings/show.blade.php` | **Template genérico “Funcionalidade”**, com `$functionality->name` — não é usado por este módulo (o controller não tem `show()`). |

### 1.1 Campos do formulário (`form.blade.php`)

| Campo | Controle | Obrigatório (UI) | Máscara |
|---|---|---|---|
| `is_show` | checkbox | não | rótulo herdado **“Show Artístico”** |
| `statuses_id` | select | sim | `Status::where('status_category_id', 2)` |
| `number` | input, `maxlen=15` | sim | — |
| `management_units_id` | select | sim | `ManagementUnit::get(['name','id'])` |
| `bidding_types_id` | select | sim | `BiddingType::get(['name','id'])` |
| `bidding_modalities_id` | select | sim | `BiddingModality::orderBy('name','ASC')->get()` |
| `local` | input, `maxlen=80` | não | — |
| `jurisdicionado[]` | select multiple | sim | conteúdos da categoria `slug = 'secretarias'` |
| `publication_edital_date` | date | não | `br-data` |
| `competition_date` | date+hora | não | `br-data-tempo` |
| `process_number` | input | não | — |
| `object` | textarea | sim | summernote |
| `homologation_date` | date | não | `br-data` |
| `show_value` | radio Sim/Não | sim | — |
| `value` | input | sim | `money` (máscara JS `000.000.000.000,00`) |
| `archive[][0]` + `archive[][description]` | file + texto | não | linhas clonadas por JS |

### 1.2 JavaScript embutido no formulário

- `verificaModalidades(modalidade)`: esconde `#dt_certame` e `#dt_edital` para as
  modalidades `1, 6, 7, 8`. **Esses `id`s não existem** no formulário (os campos
  são `competition_date` e `publication_edital_date`) — o efeito pretendido
  (esconder as datas para dispensas) não acontece.
- Clonagem de linhas de arquivo: o botão `#btn-adicionar` clona o bloco
  `.data-itens` com `<input type="file" name="archive[][]">` e
  `<input type="text" name="archive[][description]">`; `.js-remove-itens` remove
  a linha.
- Carregamento de `summernote.min.js`, `summernote-pt-BR.js`,
  `assets/js/custom/utilities/richtext/summernote.js` e
  `bootstrap3-wysihtml5.all.min.js`.

## 2. CMS — Tipos e Modalidades

| Arquivo | Função |
|---|---|
| `v6/resources/views/prefecture/biddings-types/index.blade.php` | Tabela HTML simples (sem DataTable) com ID, Nome e ações; botão “Cadastrar Tipo de Licitação”. |
| `v6/resources/views/prefecture/biddings-types/create.blade.php` | Formulário de tipo de licitação. |
| `v6/resources/views/prefecture/biddings-types/edit.blade.php` | Formulário de edição do tipo. |
| `v6/resources/views/prefecture/biddings-types/form.blade.php` | Campo `name`. |
| `v6/resources/views/prefecture/biddings-modalities/index.blade.php` | Tabela HTML simples com ID, Nome e ações. |
| `v6/resources/views/prefecture/biddings-modalities/create.blade.php` | Formulário de modalidade. |
| `v6/resources/views/prefecture/biddings-modalities/edit.blade.php` | Formulário de edição da modalidade. |
| `v6/resources/views/prefecture/biddings-modalities/form.blade.php` | Campo `name`. |

> Bug: em `biddings-types/index.blade.php` o botão de editar aponta para
> `route('licitacao-anterior', $biddingsType->id)` — **rota inexistente**
> (`licitacao-anterior` é *slug de recurso*, não nome de rota). O mesmo ocorre
> no link “Voltar” de `biddings-types/create.blade.php`
> (`route('licitacao-anterior')`). O acesso a essas telas gera
> `RouteNotFoundException`.

## 3. Portal — Listagem de licitações

| Arquivo | Função |
|---|---|
| `v6/resources/views/portal/layouts/modelo1/licitacao/index.blade.php` | Página `/licitacoes`: título, link “Ir para licitações até 2018” (condicional), filtros, botões de exportação, tabela e paginação. |
| `v6/resources/views/portal/layouts/modelo1/licitacao/filtro.blade.php` | Formulário de filtros (`#form-filter`, action `licitacoes`). |
| `v6/resources/views/portal/components/licitacoes/tabela.blade.php` | Tabela da listagem (componente compartilhado por todos os layouts). |

O mesmo conjunto existe em `modelo2`, `modelo3`, `modelo4`, `modelo5`, `modelo6`
e `newsbit` — ex.: `v6/resources/views/portal/layouts/modelo6/licitacao/index.blade.php`,
`v6/resources/views/portal/layouts/newsbit/licitacao/index.blade.php`.
O layout `default` **não** possui a pasta `licitacao/`.

### 3.1 Filtros disponíveis (`filtro.blade.php`)

| Campo | Tipo | Aplicado no filtro? |
|---|---|---|
| `dt_inicial` / `dt_final` | date | sim (`publication_edital_date` >= / <=) |
| `number` | texto | sim (`ilike %...%`) |
| `process_number` | texto | sim (`ilike %...%`) |
| `bidding_modalities_id` | select | sim |
| `statuses_id` | select | sim |
| `show` | checkbox | sim (`where('is_show', 1)`) — rótulo “Apenas Shows” |
| `local` | select (locais distintos) | sim (comparação exata) |
| `contents_id` | select (secretarias) | **não** — o `FilterBiddings` não trata `contents_id` |
| `value` | slider jQuery UI | sim (`whereBetween`) |
| `bidding_types_id` | select | sim |
| `proponent` | select (participantes) | sim (`whereHas proposals.proponents`) |
| `object` | texto | sim, com `translate/ilike` + `transliterator_transliterate` |

O filtro de objeto usa SQL bruto:

```php
$result->when(($request->object), function ($data) {
    return $data->whereRaw("translate(lower(object), ' ''àáâãäéèëêíìïîóòõöôúùüûçÇ', '--aaaaaeeeeiiiiooooouuuucc') ilike ?", '%' . transliterator_transliterate('Any-Latin; Latin-ASCII', request('object')) . '%');
});
```

### 3.2 Tabela (`portal/components/licitacoes/tabela.blade.php`)

Colunas: Órgão (unidade gestora), Licitação Nº, Processo Nº, Modalidade, Local,
Valor Estimado (“Indisponível” quando `show_value` é falso), Data da Publicação,
Data da Realização, Data da Homologação, Situação (cor por
`$res->present()->getStyleColorTd`), Edital (lupa) e Objeto.

- Microdata `schema.org` (`itemtype="https://turmalina.tcepb.tc.br/documentation/Bidding"`).
- Botão “+” → `getDetailShow(id)`: apenas **mostra/oculta** (jQuery) a linha de
  propostas do mesmo `<tbody>` — **não é uma chamada AJAX**.
- Botão lupa → `url('licitacao', $res->id)`.
- Corpo secundário `<tbody class="detail-proposal" id="proposal-dt-{{ $res->id }}">`
  com participante, CPF/CNPJ, valor da proposta e situação (vencedor/perdedor).

### 3.3 Exportação

No `index.blade.php` há quatro botões: `xls`, `pdf`, `csv`, `txt`.

```js
function exportar(type) {
    var valores = $('#form-filter').serialize();
    valores = valores + '&type=' + type;
    window.location.href = 'exportacao?' + valores;
}
```

O controller detecta o tipo pela **nome da rota**:

```php
if (Route::currentRouteName() == 'exportacao') {
    return $this->export($result, $request->type);
}
```

| `type` | Implementação | Arquivo |
|---|---|---|
| `xls` | `Excel::download(new BiddingsExport($licitacoes), 'licitacoes.xlsx')` | `v6/app/Exports/BiddingsExport.php` |
| `csv` | `Excel::download(new BiddingsExport($licitacoes), 'licitacoes.csv')` | idem |
| `pdf` | `PDF::loadView('exports.biddings', compact('licitacoes','pdf'))->download('licitacoes.pdf')` | `v6/resources/views/exports/biddings.blade.php` |
| `txt` (default) | `exportTxt()` → resposta `text/plain` montada à mão | `Portal\BiddingsController@gerarTxt` / `@exportTxt` |

O botão **“pdf”** da tela, porém, **não** usa a exportação do servidor: ele chama
`gerarPdf()` de `v6/public/assets/js/modulos/jspdf/gerar-pdf-licitacoes.js`,
que monta a tabela no navegador com jsPDF + AutoTable a partir do JSON
embutido na view (`const licitacoes = <?= json_encode($licitacoes) ?>`).
Esse JSON traz **todas** as licitações filtradas — sem paginação — o que torna a
página pesada em bases grandes.

A view `v6/resources/views/exports/biddings.blade.php` (usada no xls/csv/pdf
server-side) mostra: Órgão + secretarias, Licitação nº, Modalidade, Valor
Estimado (“Indisponível” se `show_value != 1`), Data de Publicação, Data de
Realização, Data de Homologação, Situação e Objeto (limitado a 150 caracteres);
abaixo, uma tabela de participantes por licitação.

## 4. Portal — Detalhe da licitação

| Arquivo | Função |
|---|---|
| `v6/resources/views/portal/layouts/modelo1/licitacao/show.blade.php` | Tabela com Situação, Número, Unidade gestora, Tipo de objeto, Secretarias/Órgãos, Modalidade, Data de publicação, Objeto, Data/hora do certame, Número do processo, Valor R$ e Data de Homologação (condicional). |
| `v6/resources/views/portal/layouts/modelo1/licitacao/arquivos.blade.php` | Lista de arquivos (edital/anexos) com link de download. |
| `v6/resources/views/portal/layouts/modelo1/licitacao/propostas.blade.php` | Propostas com participante, CPF/CNPJ, valor e situação. |
| `v6/resources/views/portal/layouts/modelo1/licitacao/contratos.blade.php` | Contratos vinculados às propostas. |
| `v6/resources/views/portal/layouts/contratos/contratos-sem-proposta.blade.php` | Contratos vinculados **diretamente** à licitação (`bidding_id`). |

Regras de exibição:

- Cor da situação: `statuses_id == 5` → `text-success`; `6` ou `7` → `text-danger`;
  demais → `text-secondary`.
- Valor: `{{ $bidding->show_value ? $bidding->value : 'Indisponível' }}`.
- Arquivos: `$bidding->archives` (pivot) unido a `Archive::where('biddings_id', $id)`.
- Se a licitação não existir: `view("admin.errors.conteudo-nao-encontrado")`.

## 5. Portal — Contratos

| Arquivo | Função |
|---|---|
| `v6/resources/views/portal/layouts/modelo1/licitacao/contratos/index.blade.php` | Listagem de contratos. |
| `v6/resources/views/portal/layouts/modelo1/licitacao/contratos/filtro.blade.php` | Filtros de contrato (número, licitação, processo, período, valor). |
| `v6/resources/views/portal/layouts/modelo1/licitacao/contratos/list.blade.php` | Linhas da listagem + botões de exportação (`xls`, `pdf`, `csv`, `txt`). |
| `v6/resources/views/portal/layouts/modelo1/licitacao/contratos/show.blade.php` | Detalhe do contrato. |

O botão “pdf” da listagem de contratos chama `exportar('pdf')`, que redireciona
para `/exportacao?...&type=pdf` — mas `/exportacao` é servido por
`Portal\BiddingsController@index`, que gera **o PDF de licitações**, não de
contratos. A exportação de contratos usa `ContractsExportView`
(`v6/app/Exports/ContractsExportView.php`), acionado por outro fluxo.

## 6. Assets JavaScript

| Arquivo | Papel |
|---|---|
| `v6/public/assets/js/custom/contents/licitacoes/licitacao/datatable.js` | Colunas do DataTable do CMS (`numero`, `valor`, `modalidade`, `data_publicacao`, `tipo`, `situacao`) e a coluna de ações (`createBTN(data.id, 'licitacao/{id}/edit', ...)`). |
| `v6/public/assets/js/custom/utilities/table.js` | `runDatatables(url, columns, ...)`: monta o AJAX em `/cms/datatable/${url}` e os botões de exportação Excel/PDF/CSV do próprio DataTable. `createBTN()` gera os botões editar/excluir. |
| `v6/public/assets/js/custom/utilities/deleteAll.js` | `submitDeleteAll(routeDelete)`: serializa os `input[name="toDeleteAll[]"]` marcados e envia `POST` com `toDelete[]`. |
| `v6/public/assets/js/modulos/jspdf/gerar-pdf-licitacoes.js` | Geração do PDF no navegador (jsPDF + AutoTable). |
| `v6/public/assets/js/custom/utilities/richtext/summernote.js` | Configuração do editor do campo `object`. |

## 7. Endpoints Ajax consumidos pelas telas

| Endpoint | Consumido por | Payload / resposta |
|---|---|---|
| `GET /cms/datatable/licitacao` | `datatable.js` | JSON (yajra/datatables) com as colunas da view `licitacao` + `edit`/`delete`/`active`/`inactivate` |
| `POST /cms/ajax/ajax-delete-files-licitacoes` | `prefecture/biddings/edit.blade.php` | `{_token, licitacao, archive_id}` → `[true]` / `[false]` (HTTP 500) |
| `POST /cms/ajax/licitacao/delete-por-lote` | `deleteAll.js` via `prefecture.components.deleteByLoteSubmitButton` | `{_token, toDelete[]}` → `{success: ...}` / `{erro: ...}` |
| `GET /licitacoes` (ajax) | `Portal\BiddingsController@index` | JSON com a coleção Eloquent completa |
| `GET /exportacao?...&type=` | `filtro.blade.php` | arquivo xls/xlsx/csv/pdf/txt |

## 8. O que o usuário final vê vs. o que o operador vê

| | Cidadão | Operador (CMS) |
|---|---|---|
| Entrada | `/licitacoes` | `/cms/licitacao` |
| Filtros | 12 filtros (período, número, processo, modalidade, situação, show, local, órgão, valor, tipo, participante, objeto) | nenhum filtro; DataTable com ordenação |
| Valor estimado | oculto se `show_value = false` | sempre visível e editável |
| Arquivos | download/view | upload com descrição, download, delete |
| Propostas | expande na própria linha | não exibidas no CMS de licitações (módulo de propostas) |
| Contratos | listados na tela de detalhe e em `/contratos` | CRUD em `/cms/contrato` |
| Exportação | xls, pdf (navegador), csv, txt | Excel/PDF/CSV do próprio DataTable |
