# Manual tecnico-operacional - CIOT eFrete na Operacao

Este manual descreve como a integracao eFrete funciona na tela `gt_operacao`, quais dados alimentam o JSON, quais validacoes bloqueiam o envio e como cada acao da aba Acerto > CIOT se comporta.

## 1. Onde fica a operacao

Tela principal:

- `gt_operacao/cad.php`
- Aba: `Acerto > CIOT`
- Servico central: `include/services/ciot_operacao_service.php`
- Cliente HTTP eFrete: `include/services/efrete_pef_service.php`
- Helpers compartilhados de payload: `include/services/ciot_docto_service.php`
- Configuracao da integradora: `sis_filial/cad.php`, aba de CIOT da filial

Endpoints usados pela tela:

| Acao na tela | Arquivo | Metodo e funcao |
| --- | --- | --- |
| Listar integradoras | `gt_operacao/listar_integradores_ciot.php` | `ciot_operacao_listar_integradores_disponiveis` |
| Gerar JSON | `gt_operacao/preview_ciot_json.php` | `ciot_preview_operacao` |
| Emitir CIOT | `gt_operacao/emitir_ciot.php` | `ciot_emitir_operacao` |
| Consultar ultimo retorno | `gt_operacao/consultar_ultimo_retorno_ciot.php` | `ciot_consultar_ultimo_operacao` |
| Cancelar CIOT | `gt_operacao/cancelar_ciot.php` | `ciot_cancelar_operacao` |
| Encerrar CIOT | `gt_operacao/encerrar_ciot.php` | `ciot_encerrar_operacao` |
| PDF CIOT | `gt_operacao/baixar_ciot_pdf.php` | `ciot_obter_pdf_operacao` |
| Retificar CIOT | `gt_operacao/retificar_ciot.php` | `ciot_retificar_operacao` |
| Adicionar viagem | `gt_operacao/adicionar_viagem_ciot.php` | `ciot_operacao_adicionar_viagem` |
| Adicionar pagamento | `gt_operacao/adicionar_pagamento_ciot.php` | `ciot_operacao_adicionar_pagamento` |
| Cancelar pagamento | `gt_operacao/cancelar_pagamento_ciot.php` | `ciot_operacao_cancelar_pagamento` |
| Liberar/alterar pagamento | `gt_operacao/alterar_liberacao_pagamento_ciot.php` | `ciot_operacao_alterar_data_liberacao_pagamento` |
| Registrar desembarque | `gt_operacao/registrar_desembarque_ciot.php` | `ciot_operacao_registrar_desembarque` |
| Abonar quebra | `gt_operacao/abonar_quebra_ciot.php` | `ciot_operacao_abonar_quebra` |
| Alterar entrega de documentacao | `gt_operacao/alterar_entrega_documentacao_ciot.php` | `ciot_operacao_alterar_entrega_documentacao` |
| Consultar transacoes | `gt_operacao/consultar_transacoes_ciot.php` | `ciot_operacao_obter_transacoes` |
| Consultar tipos de carga | `gt_operacao/consultar_tipo_carga_ciot.php` | `ciot_operacao_consultar_tipo_carga` |

## 2. Configuracao da integradora

A integradora e escolhida pela filial da operacao (`gt_operacao.idfilial`).

Tabela:

- `sis_filial_ciot_integrador`

Campos principais:

| Campo | Uso |
| --- | --- |
| `provider` | Deve ser `efrete` para esta integracao. A mesma estrutura tambem suporta `ndd`, mas este manual foca eFrete. |
| `ambiente` | Define qual URL usar: `producao` usa `base_url`; homologacao usa `base_url_homologacao`. |
| `base_url` | Base URL de producao. |
| `base_url_homologacao` | Base URL de homologacao. |
| `integrador` | Nome/identificador do integrador. Para eFrete, se o campo `hash` estiver preenchido, o envio usa o `hash` como `Integrador`; se nao estiver, usa `integrador`. |
| `usuario`, `senha` | Usados no login quando `usar_login = 1`. |
| `hash` | Usado como token quando o login nao retorna token ou quando `usar_login` nao estiver ativo. |
| `versao`, `timeout_segundos` | Configuracao tecnica da chamada. As versoes por endpoint tambem sao fixadas em `EFretePefService::resolveVersao`. |
| `tipo_embalagem`, `entrega_documentacao`, `codigo_tipo_carga`, `quantidade_saques`, `quantidade_transferencias`, `bloquear_nao_equiparado` | Parametros enviados no payload de emissao/encerramento. |

Regra de selecao:

- Se nao existir integradora ativa para a filial, a emissao bloqueia.
- Se existir mais de uma integradora ativa, a tela exige selecao.
- Se a operacao ja tiver CIOT ativo, retificacao e acoes posteriores usam a mesma integradora da emissao original.

## 3. Fluxo de emissao

1. A tela valida se a operacao ja esta salva e se a negociacao do acerto nao foi alterada sem salvar.
2. A tela chama `listar_integradores_ciot.php`.
3. O usuario escolhe a integradora ou o sistema usa a primeira quando ha somente uma.
4. A tela chama `emitir_ciot.php` com `id` da operacao e `idintegrador`.
5. O backend executa `ciot_operacao_preparar_envio`.
6. O backend carrega o contexto da operacao.
7. O backend resolve a integradora da filial.
8. O backend calcula `TipoViagem` e `TipoPagamento` pela negociacao da aba Acerto.
9. O backend valida dados obrigatorios.
10. O backend monta o JSON e valida os pagamentos.
11. Antes de enviar a operacao, o backend sincroniza cadastros na eFrete: proprietario, motorista e veiculo.
12. O backend envia `AdicionarOperacaoTransporte`.
13. Se o retorno nao trouxer o codigo do CIOT, o backend tenta consultar por `IdOperacaoCliente`.
14. O retorno e salvo em `gt_operacao_ciot` e o evento em `gt_operacao_ciot_evento`.
15. Os CT-es vinculados sao sincronizados em `gt_operacao_ciot_docto`.

## 4. Bases de dados usadas para montar o contexto

A funcao `ciot_operacao_carregar_contexto` concentra as consultas.

| Dado | Origem |
| --- | --- |
| Operacao | `gt_operacao op` |
| Produto predominante | `dim_produtoservicos p` via `op.idproduto` |
| Filial/contratante | `sis_filial sf` via `op.idfilial` |
| CNPJ matriz | Busca outra `sis_filial` com mesma raiz de CNPJ da filial; se nao encontrar, usa CNPJ da filial. |
| Cliente/tomador | `dim_participante` via `op.idcliente` |
| Remetente | `dim_participante` via `op.idremetente` |
| Expedidor | `dim_participante` via `op.idexpedidor` |
| Destinatario | `dim_participante` via `op.iddestinatario` |
| Recebedor/consignatario | `dim_participante` via `op.idrecebedor` |
| Subcontratante | `dim_participante` via `op.idfornecedortransportador`, somente se tiver endereco minimo. |
| Veiculo principal | `dim_veiculostelemetria` via `op.idveiculo` |
| Carretas | `dim_veiculostelemetria` via `op.idcarreta1` e `op.idcarreta2` |
| Motorista | `dim_motorista` via `op.idmotorista` |
| Proprietario | `dim_participante` via `veiculo.idproprietario`; se veiculo proprio e sem proprietario, usa dados da filial. |
| NF-es | `gt_operacao_nf` + `gt_notafiscal` + NCM de `gt_notafiscal_itens` |
| CT-es | `gt_operacao_docto` + `gt_doctotransporte` |
| Financeiro | `gt_operacao_financeiro` + `fin_lancamento` |
| Conta do motorista | `dim_motorista_contabancaria`, principal mais recente, quando a tabela existir. |

## 5. Regras de negociacao

Tipo de viagem:

| Campo na operacao | Regra | Valor enviado |
| --- | --- | --- |
| `gt_operacao.acertotipocontratacao = 1` | Agregado | `TAC_Agregado` |
| Qualquer outro valor | Proprio ou terceiro/autonomo | `Padrao` |

Tipo de pagamento:

| Campo na operacao | Normalizacao |
| --- | --- |
| `eFRETE` ou `pix` | `eFRETE` |
| `TransferenciaBancaria` | `TransferenciaBancaria` |
| `DepositoAgendado` | `DepositoAgendado` |

Emissao gratuita:

- No payload eFrete, `EmissaoGratuita = true` quando `TipoPagamento` nao for `eFRETE`.
- Quando `TipoPagamento = eFRETE`, `EmissaoGratuita = false`.

## 6. Identificadores gerados

| Campo | Regra |
| --- | --- |
| `IdOperacaoCliente` | Se houver valor preferencial de registro anterior, reutiliza. Senao gera `EMP{empresa}OP{idOperacao}{AAAAMMDDHHMMSS}`, limitado a 60 caracteres. |
| `DocumentoViagem` | Se houver CT-e vinculado, usa `CTE-{numero}-{serie}` do primeiro CT-e. Senao usa `OPERACAO-{numero}` ou `OPERACAO-{id}`. |
| Pagamento de adiantamento | `OP{idOperacao}-FIN{idFinanceiro}` quando vem de titulo financeiro. |
| Pagamento de quitacao | `OP{idOperacao}-QUITACAO`. |
| Pagamento manual posterior | `OP{idOperacao}-PG{AAAAMMDDHHMMSS}` se o usuario nao informar um ID. |

## 7. Payload principal da eFrete

A funcao `ciot_operacao_build_payload_efrete` retorna um envelope interno com:

```json
{
  "idoperacaocliente": "...",
  "documentoviagem": "...",
  "payload": {}
}
```

Somente o objeto `payload` e enviado para `AdicionarOperacaoTransporte`.

### 7.1 Cabecalho da operacao

| Campo no JSON | Origem/regra |
| --- | --- |
| `TipoViagem` | `acertotipocontratacao`: agregado vira `TAC_Agregado`; demais viram `Padrao`. |
| `EmissaoGratuita` | `TipoPagamento != eFRETE`. |
| `TipoPagamento` | `gt_operacao.acertotipopagamentociot`, normalizado. |
| `BloquearNaoEquiparado` | Configuracao da integradora da filial. |
| `MatrizCNPJ` | CNPJ matriz localizado pela raiz do CNPJ da filial. |
| `FilialCNPJ` | `sis_filial.cnpj`. |
| `IdOperacaoCliente` | Identificador gerado/reutilizado. |
| `DataInicioViagem` | `gt_operacao.dtprevcoleta`; se vazio, `gt_operacao.dtoperacao`; se vazio, data atual. |
| `DataFimViagem` | `gt_operacao.dtpreventaentrega`; se vazio, `DataInicioViagem + 1 dia`. |
| `CodigoNCMNaturezaCarga` | NCM do produto predominante; se vazio, NCM da primeira NF-e com NCM. Usa a raiz normalizada de ate 4 digitos. |
| `PesoCarga` | Soma de `gt_notafiscal.pesototal` ou `pesobruto`; se nao houver peso nas NF-es, usa `gt_operacao.pesoestimado`. |
| `TipoEmbalagem` | Configuracao da integradora, padrao `Pallet`. |
| `EntregaDocumentacao` | Configuracao da integradora, padrao `Cliente`. |
| `QuantidadeSaques`, `QuantidadeTransferencias` | Configuracao da integradora. |
| `CodigoTipoCarga` | Configuracao da integradora. Quando vazio/zero, envia `NENHUM`. |
| `AltoDesempenho` | Fixo `false`. |
| `DestinacaoComercial` | Fixo `true`. |
| `FreteRetorno` | Fixo `false`. |
| `CepRetorno` | Fixo vazio. |
| `DistanciaRetorno` | Fixo `1`. |

Para `TAC_Agregado`, a emissao inicial remove os campos de viagem/carga/pagamento que nao sao obrigatorios nesse tipo:

- `DataInicioViagem`
- `DataFimViagem`
- `CodigoNCMNaturezaCarga`
- `PesoCarga`
- `TipoEmbalagem`
- `Viagens`
- `Pagamentos`
- `Destinatario`
- `TomadorServico`
- `CodigoTipoCarga`
- `AltoDesempenho`
- `DestinacaoComercial`
- `FreteRetorno`
- `CepRetorno`
- `DistanciaRetorno`

### 7.2 Viagens

Para CIOT `Padrao`, o payload inclui uma viagem.

| Campo no JSON | Origem/regra |
| --- | --- |
| `DocumentoViagem` | Primeiro CT-e vinculado ou identificador da operacao. |
| `CodigoMunicipioOrigem` | `expedidor.cidade_ibge`; se vazio, `remetente.cidade_ibge`. |
| `CodigoMunicipioDestino` | `recebedor.cidade_ibge`; se vazio, `destinatario.cidade_ibge`. |
| `CepOrigem` | CEP do expedidor; se vazio, CEP do remetente. |
| `CepDestino` | CEP do recebedor; se vazio, CEP do destinatario. |
| `DistanciaPercorrida` | `gt_operacao.distanciaestimada`, minimo zero. |
| `TipoPagamento` | Mesmo tipo de pagamento da operacao. |
| `NotasFiscais` | Lista montada pelas NF-es vinculadas. |

### 7.3 Valores da viagem

Os valores saem principalmente da aba Acerto da operacao.

| Campo no JSON | Origem/regra |
| --- | --- |
| `TotalOperacao` | `base_impostos`, calculada a partir de `acertobaseimpostos`; se vazio, usa `acertovalorpremiacao`. |
| `TotalViagem` | Mesmo valor de `base_impostos`. |
| `TotalDeAdiantamento` | Soma dos titulos financeiros de adiantamento; se nao houver titulos, usa `gt_operacao.acertoadiantamento`. |
| `TotalDeQuitacao` | Soma dos titulos financeiros que nao sao adiantamento; se nao houver titulos, usa `gt_operacao.acertovalorliquido`. |
| `Pedagio` | `gt_operacao.vlrpedagio`. |
| `Seguro` | `gt_operacao.vlrsegurofrete`. |
| `OutrosCreditos` | Diferenca positiva entre `acertovalorpremiacao` e valor calculado sem premiacao. |
| `JustificativaOutrosCreditos` | `Premiacao do acerto da operacao.` quando houver outros creditos. |
| `OutrosDebitos` | Diferenca calculada entre base, adiantamento, impostos e quitacao; se houver financeiro marcado como `descontarmotorista`, usa a soma desses titulos. |
| `JustificativaOutrosDebitos` | Texto fixo quando houver debitos. |
| `Combustivel` | Fixo `0`. |

Calculo financeiro interno:

- `base_impostos = acertobaseimpostos`; se zero, `acertovalorpremiacao`.
- `valor_pagar = base_impostos / (1 + acertopercpremiacao / 100)`.
- `total_impostos = acertototalimpostos`; se vazio, soma INSS + SEST + SENAT + IRRF.
- Titulos vinculados prevalecem sobre os valores diretos de adiantamento/saldo.

### 7.4 Notas fiscais

Cada NF-e vinculada em `gt_operacao_nf` gera um item em `NotasFiscais`.

| Campo no JSON | Origem/regra |
| --- | --- |
| `Numero` | `gt_notafiscal.numeronf`. |
| `Serie` | `gt_notafiscal.serienf`. |
| `Data` | `gt_notafiscal.dataemissao`; se vazio, data de inicio da viagem. |
| `ValorTotal` | `gt_notafiscal.valortotal`. |
| `CodigoNCMNaturezaCarga` | NCM do item da NF-e; se vazio, NCM predominante. |
| `DescricaoDaMercadoria` | `dim_produtoservicos.descricao`; se vazio, `Carga geral`. |
| `QuantidadeDaMercadoriaNoEmbarque` | Peso da NF-e (`pesototal` ou `pesobruto`). Se vazio, distribui o peso total pela quantidade de NF-es. |
| `ValorDoFretePorUnidadeDeMercadoria` | `base_impostos / pesoNota`. |
| `UnidadeDeMedidaDaMercadoria` | Fixo `Kg`. |
| `TipoDeCalculo` | Fixo `SemQuebra`. |
| `ValorDaMercadoriaPorUnidade` | Fixo `0`. |
| `ToleranciaDePerdaDeMercadoria` | Fixo `Tipo = Nenhum`, `Valor = 0`. |
| `DiferencaDeFrete` | Fixo sem diferenca, base `QuantidadeDesembarque`. |

### 7.5 Impostos

| Campo no JSON | Origem/regra |
| --- | --- |
| `IRRF` | `gt_operacao.acertovalorirrf`. |
| `SestSenat` | `acertovalorsest + acertovalorsenat`. |
| `INSS` | `gt_operacao.acertovalorinss`. |
| `ISSQN` | Fixo `0`. |
| `OutrosImpostos` | Fixo `0`. |
| `DescricaoOutrosImpostos` | Fixo vazio. |

### 7.6 Participantes

Formato base usado para participantes:

```json
{
  "NomeOuRazaoSocial": "",
  "CpfOuCnpj": "",
  "Endereco": {
    "Bairro": "",
    "Rua": "",
    "Numero": "SN",
    "CEP": "",
    "Complemento": "",
    "CodigoMunicipio": 0
  },
  "EMail": "",
  "Telefones": {
    "Celular": { "DDD": 0, "Numero": 0 },
    "Fixo": { "DDD": 0, "Numero": 0 }
  },
  "ResponsavelPeloPagamento": false
}
```

Regras:

- CPF/CNPJ, CEP e telefones sao enviados somente com numeros.
- Se numero do endereco estiver vazio, o sistema envia `SN`.
- Telefone com menos de 10 digitos vira DDD `0` e Numero `0`.

Mapeamento:

| Campo no JSON | Origem |
| --- | --- |
| `Contratado.CpfOuCnpj` | CPF/CNPJ do proprietario do veiculo. |
| `Contratado.RNTRC` | `veiculo.antt`; se vazio, RNTRC da filial. |
| `Motorista.CpfOuCnpj` | `dim_motorista.cpf`. |
| `Motorista.CNH` | `dim_motorista.cnh`. |
| `Motorista.Celular` | `dim_motorista.telefone`. |
| `Destinatario` | `op.iddestinatario`. |
| `Contratante` | Filial da operacao, com RNTRC e responsavel pelo pagamento. |
| `Consignatario` | Recebedor; se vazio, destinatario. |
| `TomadorServico` | Cliente; se vazio, destinatario. Marcado como responsavel pelo pagamento. |
| `Remetente` | `op.idremetente`. |
| `ProprietarioCarga` | Cliente; se vazio, remetente. |
| `Subcontratante` | Transportador/fornecedor da operacao, somente se tiver endereco preenchido. |

### 7.7 Veiculos

No payload da operacao, `Veiculos` contem as placas:

- Veiculo principal: `op.idveiculo`.
- Carreta 1: `op.idcarreta1`.
- Carreta 2: `op.idcarreta2`.

Antes da emissao, o veiculo principal tambem e sincronizado no cadastro da eFrete com:

| Campo enviado no cadastro | Origem/regra |
| --- | --- |
| `Placa` | `dim_veiculostelemetria.placa_veiculo`. |
| `Renavam` | `dim_veiculostelemetria.renavam`. |
| `Chassi` | `dim_veiculostelemetria.chassi`. |
| `RNTRC` | `dim_veiculostelemetria.antt`; se vazio, RNTRC da filial. |
| `NumeroDeEixos` | `layouteixo`, minimo `2`. |
| `CodigoMunicipio` | Codigo IBGE da cidade da filial. |
| `Marca`, `Modelo` | Cadastro do veiculo. |
| `AnoFabricacao`, `AnoModelo` | `anomodelo_veiculo`; se vazio, ano atual. |
| `Cor` | Fixo `Branco`. |
| `Tara`, `CapacidadeM3` | Fixo `0`. |
| `CapacidadeKg` | `capacidade * 1000`. |
| `TipoRodado`, `TipoCarroceria` | Mapeados por helpers de CIOT. |

### 7.8 Pagamentos

Os pagamentos da emissao `Padrao` sao gerados por `ciot_operacao_build_pagamentos_efrete`.

Origem preferencial:

- Titulos vinculados em `gt_operacao_financeiro` + `fin_lancamento`.
- Titulos com `descontarmotorista = 1` entram como debito e nao viram pagamento.
- Titulos com `fin_lancamento.adiantamento = 1` viram pagamento categoria `Adiantamento`.
- Titulos sem adiantamento sao somados em um unico pagamento categoria `Quitacao`.

Fallback quando nao existem titulos:

- `gt_operacao.acertoadiantamento` gera `OP{id}-ADIANTAMENTO`.
- `gt_operacao.acertovalorliquido` gera `OP{id}-QUITACAO`.

Formato do pagamento:

| Campo no JSON | Origem/regra |
| --- | --- |
| `IdPagamentoCliente` | Regra de identificador do titulo ou quitacao. |
| `DataDeLiberacao` | `fin_lancamento.dtvencimento`; se vazio, data da operacao. |
| `Valor` | `fin_lancamento.valortotal`; se vazio, `valor`. |
| `TipoPagamento` | Tipo de pagamento da operacao. |
| `Categoria` | `Adiantamento`, `Quitacao`, `Estadia` ou `SemCategoria`, conforme contexto. |
| `Documento` | Documento viagem do CIOT. |
| `InformacoesBancarias` | Enviado para `TransferenciaBancaria` ou `DepositoAgendado`. |
| `InformacaoAdicional` | Para eFRETE com PIX, envia `Chave:{chave}`. |

Dados bancarios:

| Campo eFrete | Origem |
| --- | --- |
| `InstituicaoBancaria` | `dim_motorista_contabancaria.banco`. |
| `Agencia` | `agencia + digitoagencia`, somente numeros. |
| `Conta` | `conta + digitoconta`, somente numeros. |
| `TipoConta` | `tipoconta`: 1 conta corrente, 2 poupanca, 3 conta pagamento. |

PIX:

- Exige `formapagamento = pix`.
- Exige `chavepix`.
- Exige `tipochavepix`.
- Tipo 1 ou 2 vira CPF/CNPJ.
- Tipo 3 vira Email.
- Tipo 4 vira TelefoneCelular.
- Tipo 5 vira ChaveAleatoria.

## 8. Validacoes antes da emissao

A funcao `ciot_operacao_validar_contexto` bloqueia a emissao quando encontra erro.

### 8.1 Validacoes gerais

- Filial deve ter CNPJ valido com 14 digitos.
- Filial deve ter RNTRC.
- Operacao deve ter remetente.
- Operacao deve ter destinatario.
- Operacao deve ter veiculo principal.
- Operacao deve ter motorista.
- Veiculo deve ter proprietario; se for veiculo proprio, o sistema tenta usar a filial como proprietario.
- Veiculo deve ter RNTRC/ANTT.
- Veiculo deve ter Renavam.
- Veiculo deve ter chassi.
- Motorista deve ter CPF valido.
- Motorista deve ter CNH.
- Motorista deve ter nome da mae.
- Motorista deve ter data de nascimento.
- Motorista deve ter endereco, bairro, CEP e cidade com codigo IBGE.
- Proprietario deve ter CPF/CNPJ.
- Proprietario deve ter endereco e CEP.

### 8.2 Validacoes especificas de CIOT Padrao

- Deve existir ao menos uma NF-e vinculada.
- Deve existir NCM no produto predominante ou na NF-e.
- Deve existir ao menos um CT-e vinculado.
- Total de viagem deve ser maior que zero.
- Deve existir ao menos adiantamento ou saldo a pagar.
- Distancia estimada deve ser maior que zero.
- Data de inicio/previsao de coleta e obrigatoria.
- Data de inicio nao pode ser anterior a data atual do servidor.

### 8.3 Validacoes de pagamento

Para `TransferenciaBancaria` ou `DepositoAgendado`:

- Conta bancaria do motorista deve ter banco, agencia e conta.

Para `eFRETE` com conta do motorista marcada como PIX:

- Deve existir chave PIX e tipo de chave.

Depois de montar o payload, o sistema valida novamente:

- Cada pagamento deve ter `IdPagamentoCliente`.
- Cada pagamento deve ter valor maior que zero.
- Cada pagamento deve ter `Documento`.
- Cada pagamento deve ter dados bancarios ou informacao PIX quando aplicavel.
- A lista de pagamentos nao pode ficar vazia para CIOT Padrao.

## 9. Sincronizacao de cadastros antes da emissao

Antes de chamar `AdicionarOperacaoTransporte`, o sistema chama:

1. `/services/proprietarios/gravar`
2. `/services/motoristas/gravar`
3. `/services/veiculos/gravar`

Se qualquer um desses tres cadastros falhar, a emissao e bloqueada com a mensagem:

`Falha ao sincronizar proprietario, motorista ou veiculo na eFrete.`

## 10. Endpoints eFrete chamados

| Acao | Endpoint eFrete |
| --- | --- |
| Login | `/services/Logon/Login` |
| Gravar proprietario | `/services/proprietarios/gravar` |
| Gravar motorista | `/services/motoristas/gravar` |
| Gravar veiculo | `/services/veiculos/gravar` |
| Emitir CIOT | `/services/Pef/AdicionarOperacaoTransporte` |
| Retificar CIOT | `/services/Pef/RetificarOperacaoTransporte` |
| Cancelar CIOT | `/services/Pef/CancelarOperacaoTransporte` |
| Adicionar pagamento | `/services/Pef/AdicionarPagamento` |
| Cancelar pagamento | `/services/Pef/CancelarPagamento` |
| Adicionar viagem | `/services/Pef/AdicionarViagem` |
| Encerrar CIOT | `/services/Pef/EncerrarOperacaoTransporte` |
| Abonar quebra | `/services/Pef/AbonarQuebraDeFrete` |
| Obter codigo por IdOperacaoCliente | `/services/Pef/ObterCodigoIdentificacaoOperacaoTransportePorIdOperacaoCliente` |
| PDF | `/services/Pef/ObterOperacaoTransportePdf` |
| Transacoes | `/services/Pef/ObterTransacoes` |
| Alterar liberacao de pagamento | `/services/Pef/AlterarDataLiberacaoPagamento` |
| Registrar desembarque | `/services/Pef/RegistrarQuantidadeDaMercadoriaNoDesembarque` |
| Alterar entrega documentacao | `/services/Pef/AlterarEntregaDocumentacao` |
| Tipos de carga | `/services/Pef/ConsultarTipoCarga` |

O token e resolvido assim:

1. Se ja existe token em cache, usa o cache.
2. Se `usar_login = 1` e ha usuario/senha, faz login e tenta extrair `Token` ou `Hash`.
3. Se login nao fornecer token e `hash` estiver preenchido, usa `hash`.
4. Se nada disso existir, retorna erro de configuracao.

## 11. Acoes apos emissao

### 11.1 Retificar CIOT

Disponivel somente com CIOT ativo e nao encerrado.

Payload enviado:

- `CodigoIdentificacaoOperacao`
- `Veiculos`
- `QuantidadeSaques`
- `QuantidadeTransferencias`
- `ValorSaques = 0`
- `ValorTransferencias = 0`

Bloqueia se nao houver veiculo para retificar.

### 11.2 Cancelar CIOT

Exige CIOT ativo com `CodigoIdentificacaoOperacao`.

Payload enviado:

- `CodigoIdentificacaoOperacao`
- `Motivo`

Quando cancelado com sucesso, grava novo registro com `status_ciot = 2`.

### 11.3 Encerrar CIOT

Exige CIOT ativo, com codigo e ainda nao encerrado.

Payload enviado:

- `CodigoIdentificacaoOperacao`
- `PesoCarga`
- `Impostos`
- `QuantidadeSaques`
- `QuantidadeTransferencias`
- `ValorSaques = 0`
- `ValorTransferencias = 0`

O `PesoCarga` vem do payload salvo na emissao. Se nao existir, o sistema remonta o payload e usa o peso recalculado.

Quando encerrado com sucesso, grava novo registro com `status_ciot = 5`.

### 11.4 PDF

Exige CIOT ativo com codigo.

Tenta obter PDF com:

1. GET com `CodigoIdentificacaoOperacao` e `DocumentoViagem`.
2. POST com os mesmos campos.
3. GET somente com `CodigoIdentificacaoOperacao`.
4. POST somente com `CodigoIdentificacaoOperacao`.

Aceita PDF bruto ou base64 retornado pela eFrete.

### 11.5 Liberar ou alterar pagamento

Acionado pelo botao `Liberar eFrete` na lista de titulos financeiros.

Payload:

- `CodigoIdentificacaoOperacao`
- `IdPagamentoCliente`
- `DataLiberacao` no formato `YYYY-MM-DD`
- `Motivo`

Bloqueia se o CIOT estiver encerrado.

### 11.6 Adicionar pagamento

Disponivel somente com CIOT ativo e nao encerrado.

Regras:

- Categoria permitida: `Estadia` ou `SemCategoria`.
- `Adiantamento` e `Quitacao` devem ser enviados na emissao, nao por esta acao.
- Para `TAC_Agregado`, categoria `Estadia` nao e permitida.
- Valor deve ser maior que zero.
- Data deve estar em `YYYY-MM-DD`.

Payload:

- `CodigoIdentificacaoOperacao`
- `Pagamentos` com um item gerado por `ciot_pagamento_payload`.

### 11.7 Cancelar pagamento

Disponivel somente com CIOT ativo e nao encerrado.

Payload:

- `CodigoIdentificacaoOperacao`
- `IdPagamentoCliente`
- `Motivo`

### 11.8 Registrar desembarque

Disponivel somente com CIOT ativo e nao encerrado.

Entrada da tela:

- Uma NF por linha no formato `numero;serie;quantidade_desembarque`.

Payload:

- `CodigoIdentificacaoOperacao`
- `NotasFiscais[]` com `Numero`, `Serie` e `QuantidadeDaMercadoriaNoDesembarque`.

Exige ao menos uma nota com numero e quantidade maior que zero.

### 11.9 Abonar quebra

Disponivel somente com CIOT ativo e nao encerrado.

Tipos permitidos:

- `Nenhum`
- `Porcentagem`
- `ValorAbsoluto`
- `Peso`

Regras:

- Pode aplicar em todas as notas.
- Se nao aplicar em todas, deve informar uma ou mais notas.

Payload:

- `CodigoIdentificacaoOperacao`
- `DocumentoViagem`
- `AplicarEmTodasAsNotasFiscais`
- `NotasFiscais`
- `AbonoDeQuebra`

### 11.10 Alterar entrega de documentacao

Disponivel somente com CIOT ativo e nao encerrado.

Valores permitidos:

- `Cliente`
- `RedeCredenciada`

Payload:

- `CodigoIdentificacaoOperacao`
- `EntregaDocumentacao`

### 11.11 Adicionar viagem

Permitido somente para CIOT `TAC_Agregado` ativo e nao encerrado.

Fluxo:

1. Localiza CT-es vinculados que ainda nao foram adicionados como viagem.
2. Envia somente o primeiro CT-e pendente por chamada.
3. Carrega o contexto do CT-e pelo fluxo antigo de documento.
4. Monta uma viagem no formato eFrete.
5. Envia `AdicionarViagem`.
6. Grava a viagem em `gt_operacao_ciot_viagem`.

Validacoes:

- CIOT deve ser `TAC_Agregado`.
- Deve existir CT-e pendente.
- Se o tipo de pagamento for bancario, a conta do motorista deve estar completa.
- O CT-e deve passar nas validacoes de viagem.

### 11.12 Consultar transacoes

Payload:

- `MatrizCNPJ`
- `CIOTs`
- `DataInicial`
- `DataFinal`

Regras:

- Datas em `YYYY-MM-DD`.
- Data final nao pode ser menor que data inicial.
- Intervalo maximo de 3 dias.

### 11.13 Consultar tipos de carga

Pode ser executado antes ou depois de emitir, desde que exista integradora eFrete resolvida para a filial.

Payload vazio.

## 12. Persistencia e status

Tabela principal:

- `gt_operacao_ciot`

Campos importantes:

| Campo | Uso |
| --- | --- |
| `provider` | `efrete` ou outro provider. |
| `idintegradorfilial` | Integrador da filial usado na emissao. |
| `descricao_integrador` | Nome amigavel salvo no momento da emissao. |
| `idoperacaocliente` | ID usado para identificar a operacao na eFrete. |
| `codigoidentificacaooperacao` | Codigo/CIOT retornado ou recuperado da eFrete. |
| `documentoviagem` | Documento usado no payload. |
| `status_ciot` | Status interno. |
| `tipo_viagem` | `Padrao` ou `TAC_Agregado`. |
| `tipo_pagamento` | Tipo enviado para a eFrete. |
| `payload` | JSON enviado, incluindo cadastros quando aplicavel. |
| `retorno` | Retorno tecnico da eFrete. |

Status internos:

| Status | Significado |
| --- | --- |
| `0` | Pendente |
| `1` | Emitido |
| `2` | Cancelado |
| `3` | Erro |
| `4` | Retificado |
| `5` | Encerrado |

Tabelas auxiliares:

- `gt_operacao_ciot_evento`: log de cada acao enviada.
- `gt_operacao_ciot_docto`: vinculo entre CIOT e CT-es da operacao.
- `gt_operacao_ciot_viagem`: viagens adicionadas posteriormente em CIOT `TAC_Agregado`.

## 13. Como diagnosticar erros

1. Use `Gerar JSON` antes de emitir para conferir o payload sem enviar para a eFrete.
2. Se a validacao falhar, a tela mostra a lista de erros retornada por `ciot_operacao_validar_contexto`.
3. Se a sincronizacao falhar, confira o retorno tecnico de proprietario, motorista e veiculo.
4. Se a emissao falhar, use `Consultar Retorno`.
5. Confira `gt_operacao_ciot_evento.payload` e `gt_operacao_ciot_evento.retorno` para ver exatamente o que foi enviado e recebido.
6. Quando a eFrete disser que a operacao ja existe, o sistema tenta recuperar o codigo por `IdOperacaoCliente`. Se nao recuperar, confira se a mesma operacao foi enviada com outro ID ou outra filial.

## 14. Checklist antes da emissao

- Filial da operacao possui integradora eFrete ativa.
- Ambiente da integradora aponta para a URL correta.
- Filial tem CNPJ, RNTRC, endereco, cidade e UF.
- Motorista tem CPF valido, CNH, nome da mae, nascimento, endereco, CEP e cidade IBGE.
- Conta bancaria/PIX do motorista esta completa conforme o tipo de pagamento.
- Veiculo tem placa, proprietario, ANTT/RNTRC, Renavam e chassi.
- Proprietario tem CPF/CNPJ, endereco e CEP.
- Operacao tem remetente, destinatario, veiculo e motorista.
- Para CIOT Padrao, operacao tem NF-e, CT-e, NCM, distancia, data de inicio e valor de viagem.
- Aba Acerto foi salva depois de alterar tipo de contratacao ou tipo de pagamento.
- Titulos financeiros de adiantamento/quitacao foram gerados ou valores de fallback estao preenchidos.

