# Fixtures — Importador de Dados (RH & Folha)

Arquivos de apoio para os casos de teste IMP-09 a IMP-14.  
Escopo: tabelas do módulo RH/Folha de Pagamento (mix de tabela existente `pessoa` + novas tabelas).

> **Use os arquivos `10-` e `11-` para o teste principal (CSV único, multi-tabela).**  
> Os arquivos `01-` a `05-` são versões granulares por tabela, úteis para testes isolados depois.

---

## Pré-requisito: criar as tabelas novas

Execute **uma única vez** no banco `minierp`:

```bash
sqlite3 /var/www/html/madbuilder/testes_fw5/web/mad-framework/app/database/sqlite/minierp.db \
  < docs/testes/fixtures/00-criar-tabelas-rh.sql
```

---

## Ordem de execução dos templates

Os templates devem ser criados e executados **nesta ordem** (dependência de FK):

```
1. rh-cargos          →  tabela rh_cargo
2. rh-departamentos   →  tabela rh_departamento   (responsavel_id → pessoa)
3. rh-funcionarios    →  tabela rh_funcionario     (→ pessoa, rh_cargo, rh_departamento)
4. rh-folha           →  tabela rh_folha_lancamento (→ rh_funcionario)
```

---

## Descrição dos arquivos

---

## Planilhas flat (multi-tabela) — use estas primeiro

### `10-rh-flat-partial.csv`
- **Modo:** partial
- **Delimitador:** `;`
- **Linhas:** 10 — todas válidas
- **Tabelas alimentadas por linha:** `rh_cargo` + `rh_departamento` + `rh_funcionario`
- **Como funciona:** cada coluna do CSV é mapeada para o campo destino de uma das 3 tabelas. A coluna `cargo_id` mapeia simultaneamente para `rh_cargo.id` e `rh_funcionario.cargo_id`; `depto_id` mapeia para `rh_departamento.id` e `rh_funcionario.departamento_id`. O REPLACE garante que cargos/deptos repetidos (ex.: cargo 1 em 2 linhas) sejam atualizados sem erro.
- **Mapeamento a configurar no formulário:**

| Coluna CSV | Tabela destino | Campo destino |
|---|---|---|
| `cargo_id` | `rh_cargo` | `id` |
| `cargo_nome` | `rh_cargo` | `nome` |
| `cargo_nivel` | `rh_cargo` | `nivel` |
| `cargo_salario_base` | `rh_cargo` | `salario_base` |
| `cargo_horas` | `rh_cargo` | `carga_horaria_mensal` |
| `depto_id` | `rh_departamento` | `id` |
| `depto_nome` | `rh_departamento` | `nome` |
| `depto_sigla` | `rh_departamento` | `sigla` |
| `depto_custo` | `rh_departamento` | `centro_custo` |
| `pessoa_id` | `rh_funcionario` | `pessoa_id` |
| `cargo_id` | `rh_funcionario` | `cargo_id` |
| `depto_id` | `rh_funcionario` | `departamento_id` |
| `matricula` | `rh_funcionario` | `matricula` |
| `data_admissao` | `rh_funcionario` | `data_admissao` |
| `func_salario` | `rh_funcionario` | `salario` |
| `regime` | `rh_funcionario` | `regime` |
| `status` | `rh_funcionario` | `status` |

- **Comportamento esperado:** 10 inserções em `rh_funcionario`; cargos e deptos repetidos fazem REPLACE silencioso; `success_rows = 10`.

### `11-rh-flat-atomic.csv`
- **Modo:** atomic
- **Delimitador:** `;`
- **Linhas:** 10
- **Armadilha:** linha 8 — `depto_id = 99` com sigla `XXX` (não existe; a própria linha tenta inserir o depto, mas se houver constraint de UNIQUE na sigla pode conflitar dependendo do estado do banco)
- **Comportamento esperado:** rollback total — `aborted = true`, `success_rows = 0`; NENHUMA das 10 linhas persiste (nem cargos, nem deptos, nem funcionários)

---

## Planilhas individuais por tabela (granulares)

### `01-rh-cargos.csv`
- **Modo:** partial  
- **Delimitador:** `;`  
- **Linhas:** 8 — todas válidas  
- **Objetivo:** aquecimento; estabelece os IDs de cargo para uso nos próximos templates  
- **Comportamento esperado:** 8 inserções com sucesso, nenhum erro

### `02-rh-departamentos.csv`
- **Modo:** partial  
- **Delimitador:** `;`  
- **Linhas:** 6  
- **Armadilhas:**
  - Linha 6: `responsavel_id = 999` — FK inválida (pessoa não existe); `ativo` em branco  
- **Comportamento esperado (partial):** 5 linhas OK, 1 com erro registrado em `errors_json`

### `03-rh-funcionarios-partial.csv`
- **Modo:** partial  
- **Delimitador:** `;`  
- **Linhas:** 18  
- **Armadilhas:**
  - Linha 9: `salario = 1412,50` — decimal PT-BR (deve ser convertido para `1412.50`)
  - Linha 10: `cargo_id = 99` — FK inválida
  - Linha 11: `departamento_id = 999` — FK inválida
  - Linha 12: vazia (ignorada pelo parser)
  - Linha 13: `data_admissao = 15/04/2023` — formato brasileiro (pode falhar dependendo do driver)
  - Linha 14: `matricula = F-0001` — duplicata da linha 1 (REPLACE deve atualizar ou erro de constraint)
- **Comportamento esperado:** ≥12 linhas OK; 3–4 com erro; nenhum rollback global

### `04-rh-funcionarios-atomic.csv`
- **Modo:** atomic  
- **Delimitador:** `;`  
- **Linhas:** 15  
- **Armadilha:** linha 8: `cargo_id = 99` — FK inválida  
- **Comportamento esperado:** rollback total — `successRows = 0`, `aborted = true`; NENHUMA linha persiste no banco

### `05-rh-folha-lancamentos.csv`
- **Modo:** partial  
- **Delimitador:** `;`  
- **Linhas:** 30  
- **Armadilhas:**
  - Decimais PT-BR com ponto de milhar: `3.500,00`, `7.800,00`, `12.000,00`, `2.106,45` — parser faz trim de `,` mas **não** remove ponto de milhar; observar se converte corretamente
  - Linha 25: duplicata de `funcionario_id=1 / competencia=2026-05 / tipo=PROVENTO / descricao=Salário Base` — testa comportamento do REPLACE
  - Linha 26: `funcionario_id = 999` — FK inválida; linha isolada deve falhar sem afetar as demais
  - `referencia` em branco em vários lançamentos — campo nullable, deve aceitar NULL
- **Comportamento esperado:** ≥27 linhas OK; 1 com FK inválida; duplicata substitui registro anterior (REPLACE)

---

## Como verificar os resultados

### Via SQLite direto

```bash
DB=/var/www/html/madbuilder/testes_fw5/web/mad-framework/app/database/sqlite/minierp.db

# Contar registros importados
sqlite3 $DB "SELECT COUNT(*) FROM rh_cargo;"
sqlite3 $DB "SELECT COUNT(*) FROM rh_departamento;"
sqlite3 $DB "SELECT COUNT(*) FROM rh_funcionario;"
sqlite3 $DB "SELECT COUNT(*) FROM rh_folha_lancamento;"

# Ver log de erros da última importação
sqlite3 $DB "SELECT id, template_id, total_rows, success_rows, error_rows, errors_json FROM system_import_log ORDER BY id DESC LIMIT 5;"

# Verificar rollback atômico (deve ser 0 após atomic com erro)
sqlite3 $DB "SELECT COUNT(*) FROM rh_funcionario WHERE matricula LIKE 'F-01%';"
```
