Metadata-Version: 2.4
Name: iaxys-omie-utils
Version: 0.1.7
Summary: SDK Python para a API Omie — client, models e erros tipados
Project-URL: Repository, https://github.com/seu-usuario/omie-sdk
License: MIT
Keywords: api,erp,financas,omie,sdk
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27
Requires-Dist: pydantic>=2.0
Provides-Extra: dev
Requires-Dist: hatch; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: python-dotenv>=1.0; extra == 'dev'
Description-Content-Type: text/markdown

# omie-sdk

SDK Python para a API Omie — client, models Pydantic e erros tipados num único package.

## Instalação

```bash
pip install omie-sdk
```

## Uso rápido

```python
from omie.financas import OmieFinancas
from omie.financas.models import (
    ContaReceberParam,
    ContaPagarParam,
    ConsultarContaReceberParam,
    ListarContasReceberParam,
)

financas = OmieFinancas(app_key="...", app_secret="...")
```

### Contas a Receber

```python
# Incluir
financas.incluir_conta_receber(ContaReceberParam(
    codigo_lancamento_integracao="meu-sistema-123",
    codigo_cliente_fornecedor=98765,
    data_vencimento="30/06/2025",
    valor_documento=1500.00,
    codigo_categoria="1.01.02",
    data_previsao="30/06/2025",
    id_conta_corrente="12345678",
    data_emissao="01/06/2025",
    nsu="NSU-001",
    observacao="Fatura junho",
))

# Alterar
financas.alterar_conta_receber(ContaReceberParam(
    codigo_lancamento_integracao="meu-sistema-123",
    codigo_cliente_fornecedor=98765,
    data_vencimento="30/06/2025",
    valor_documento=1600.00,   # valor atualizado
    codigo_categoria="1.01.02",
    data_previsao="30/06/2025",
    id_conta_corrente="12345678",
    data_emissao="01/06/2025",
))

# Consultar
financas.consultar_conta_receber(
    ConsultarContaReceberParam(codigo_lancamento_integracao="meu-sistema-123")
)
financas.consultar_conta_receber(
    ConsultarContaReceberParam(codigo_lancamento_omie=3784804194)
)

# Listar (com defaults: pagina=1, registros_por_pagina=50)
resultado = financas.listar_contas_receber()
# resultado["conta_receber_cadastro"] → lista de lançamentos
# resultado["total_de_paginas"]       → total de páginas

# Listar com filtros
resultado = financas.listar_contas_receber(ListarContasReceberParam(
    pagina=1,
    registros_por_pagina=100,
    status_titulo="ABERTO",
    data_vencimento_de="01/06/2025",
    data_vencimento_ate="30/06/2025",
))
```

### Contas a Pagar

```python
financas.incluir_conta_pagar(ContaPagarParam(
    codigo_lancamento_integracao="fornecedor-456",
    codigo_cliente_fornecedor=11111,
    data_vencimento="15/07/2025",
    valor_documento=800.00,
    codigo_categoria="2.01.01",
    data_previsao="15/07/2025",
    id_conta_corrente="12345678",
    data_emissao="01/07/2025",
))
```

### Tratamento de erros

```python
import time
from omie.errors import OmieDuplicateError, OmieRateLimitError, OmieNotFoundError

try:
    financas.incluir_conta_receber(param)

except OmieDuplicateError as e:
    # e.omie_id → ID do lançamento existente na Omie
    conta = financas.consultar_conta_receber(
        ConsultarContaReceberParam(codigo_lancamento_omie=int(e.omie_id))
    )

except OmieRateLimitError as e:
    # e.retry_after → segundos sugeridos pela Omie
    time.sleep(e.retry_after or 60)
    raise

except OmieNotFoundError as e:
    # e.field → tag com o código não encontrado
    print(f"Campo com problema: {e.field}")
```

## Models Pydantic

Todos os models são `frozen=True` — imutáveis após criação. As validações acontecem na instanciação:

| Model | Valida |
|---|---|
| `ContaReceberParam` | datas DD/MM/YYYY, valor > 0, integracao não vazio |
| `ContaPagarParam` | idem |
| `ConsultarContaReceberParam` | ao menos um código informado |
| `ListarContasReceberParam` | pagina ≥ 1, registros ≤ 100 (limite Omie), datas DD/MM/YYYY |

## Hierarquia de erros

```
omie.errors.OmieError
├── OmieClientError          faultcode: SOAP-ENV:Client*
│   ├── OmieAuthError
│   ├── OmieValidationError      .field
│   ├── OmieDuplicateError       .omie_id
│   ├── OmieNotFoundError        .field
│   └── OmieRateLimitError       .retry_after
└── OmieServerError          faultcode: SOAP-ENV:Server*
    └── OmieUnavailableError
```

## Estrutura do package

```
omie/
├── __init__.py
├── errors/
│   └── __init__.py          exceções + parse_omie_response
├── _core/
│   └── http.py              OmieHttp (transporte, privado)
└── financas/
    ├── __init__.py          OmieFinancas
    └── models.py            ContaReceberParam, ContaPagarParam, ...
```

### Adicionando um novo contexto

```python
# omie/clientes/__init__.py
from omie._core import OmieHttp
from omie.clientes.models import ClienteParam, ListarClientesParam

class OmieClientes:
    def __init__(self, app_key: str, app_secret: str) -> None:
        self._http = OmieHttp(app_key, app_secret)

    def incluir_cliente(self, param: ClienteParam) -> dict:
        return self._http.post("geral/clientes", "IncluirCliente", [param.to_omie_dict()])

    def listar_clientes(self, param: ListarClientesParam | None = None) -> dict:
        p = param or ListarClientesParam()
        return self._http.post("geral/clientes", "ListarClientes", [p.to_omie_dict()])
```

## Publicar

```bash
uv build
uv publish --token pypi-seu-token
```

## Licença

MIT
