CaseModule
Agrupa CRUD, búsqueda y submódulos del dominio de casos.
Thread-safe: no guarda estado mutable. Los filtros son inmutables, así que un
mismo CaseFilter se puede compartir entre hilos sin copiarlo.
Submódulos disponibles:
state(), comment(), caso_type(), files(), file_typology(),
user(), primary_level(), secondary_level().
Ejemplo General
```python
page = client.caso().search(
CaseFilter.builder()
.working_sub_state_id(FilterOperator.EQ, "ws-uuid")
.build()
)
print(page.count, page.num_elements)
## Métodos
### `def __init__(config: ShoriConfig, http: HttpExecutor, repo_module: RepoModule, executor: Executor | None) -> None`
**Parámetros:**
- `config` (`ShoriConfig`) —
- `http` (`HttpExecutor`) —
- `repo_module` (`RepoModule`) —
- `executor` (`Executor | None`) —
---
### `def state() -> CaseStateModule`
Submódulo de estados y flujo de trabajo (avanzar casos, consultar estados).
**Retorna:** `CaseStateModule` — ``CaseStateModule``.
**Ejemplo de uso:**
```python
```python
client.caso().state().next({"casoId": "c1", "workingSubStatePrimaryLevelId": "ws2"})
```
def comment() -> CaseCommentModule
Submódulo de comentarios de un caso.
Retorna: CaseCommentModule — CaseCommentModule.
Ejemplo de uso:
```python
client.caso().comment().add({"casoId": "c1", "comment": "Revisado"})
```
def caso_type() -> CaseTypeModule
Submódulo de tipos de caso (productos).
Retorna: CaseTypeModule — CaseTypeModule.
Ejemplo de uso:
```python
producto = client.caso().caso_type().find_by_id_lite("tipo-uuid")
```
def files() -> CaseFilesModule
Submódulo de archivos adjuntos de un caso.
Retorna: CaseFilesModule — CaseFilesModule.
Ejemplo de uso:
```python
client.caso().files().delete("document-uuid")
```
def file_typology() -> CaseFileTypologyModule
Submódulo de tipologías y categorías de archivos.
Retorna: CaseFileTypologyModule — CaseFileTypologyModule.
Ejemplo de uso:
```python
tipologias = client.caso().file_typology().get_by_caso_type("tipo-uuid")
```
def user() -> CaseUserModule
Submódulo de asignación de usuarios a casos.
Retorna: CaseUserModule — CaseUserModule.
Ejemplo de uso:
```python
client.caso().user().assign_responsible({"userId": "u1", "casoIds": ["c1"]})
```
def primary_level() -> CasePrimaryLevelModule
Submódulo de servicios (Primary Level).
Retorna: CasePrimaryLevelModule — CasePrimaryLevelModule.
Ejemplo de uso:
```python
servicio = client.caso().primary_level().get_by_id({"primaryLevelId": "pl-uuid", "inUse": True})
```
def secondary_level() -> CaseSecondaryLevelModule
Submódulo de procesos (Secondary Level).
Retorna: CaseSecondaryLevelModule — CaseSecondaryLevelModule.
Ejemplo de uso:
```python
proceso = client.caso().secondary_level().get_by_id("sl-uuid")
```
def find_by_id(request: str) -> CasoResponse
Parámetros:
request(str) —
Retorna: CasoResponse — CasoResponse con los datos completos del caso.
Lanza:
ResourceNotFoundException— Si el caso no existe (HTTP 404).AuthenticationException— Si las credenciales no son válidas.ApiException— Ante cualquier otro error HTTP, timeout (408) o de red (0).
Ejemplo de uso:
```python
caso = client.caso().find_by_id("3f2b1c9e-0000-0000-0000-000000000000")
print(caso.caso_number, caso.caso_type_name, caso.assigned_user_name)
def find_by_id(request: FindByIdRequest) -> CasoResponse
Busca un caso utilizando uno o más criterios de búsqueda.
Parámetros:
request(FindByIdRequest) — Criterios utilizados para buscar el caso.
Retorna: CasoResponse — CasoResponse con la información del caso encontrado.
Ejemplo de uso:
>>> request = (
... FindByIdRequest.builder()
... .caso_id_int(12345)
... .build()
... )
>>> caso = client.caso().find_by_id(request)
def find_by_id(request: str | FindByIdRequest) -> CasoResponse
Parámetros:
request(str | FindByIdRequest) —
Retorna: CasoResponse —
def create(request: CasoCreateRequest | Mapping[str, Any]) -> CasoCreateResponse
Crea un caso.
El API devuelve caso (UUID) y casoId (número legible); el SDK los remapea
para que caso_id sea el UUID y caso_number el número visible.
Parámetros:
request(CasoCreateRequest | Mapping[str, Any]) —CasoCreateRequestodictequivalente (camelCase o snake_case).
Retorna: CasoCreateResponse — CasoCreateResponse con caso_id (UUID) y caso_number.
Lanza:
pydantic.ValidationError— Si el dict no cumple el modelo.ApiException— Si el API rechaza la creación.
Ejemplo de uso:
```python
req = (
CasoCreateRequest.builder()
.caso_type_id("tipo-uuid")
.form_id("form-uuid")
.priority("priority-uuid")
.submitted_data({"nombre": "Ana García"})
.build()
)
creado = client.caso().create(req)
print(creado.caso_id, creado.caso_number)
```
def update(request: CasoUpdateRequest | Mapping[str, Any]) -> None
Actualiza los datos de un caso existente.
El request recibido no se modifica (el SDK trabaja sobre una copia).
Parámetros:
request(CasoUpdateRequest | Mapping[str, Any]) —CasoUpdateRequestodictequivalente.
Lanza:
pydantic.ValidationError— Si el request no cumple el modelo.ResourceNotFoundException— Si el caso no existe.
Ejemplo de uso:
```python
client.caso().update(
CasoUpdateRequest.builder()
.id("caso-uuid")
.priority("priority-uuid")
.form_id("form-uuid")
.submitted_data({"nombre": "Ana García Pérez"})
.build()
)
```
def search(filter: CaseFilter) -> CaseSearchResult
Busca casos (una sola página).
Parámetros:
filter(CaseFilter) —CaseFilter(working_sub_state_ides obligatorio).
Retorna: CaseSearchResult — CaseSearchResult con caso_response (lista de la página), count (total que cumple el filtro), num_elements y pag.
Ejemplo de uso:
```python
page = client.caso().search(
CaseFilter.builder()
.working_sub_state_id(FilterOperator.EQ, "ws-uuid")
.page_size(50)
.build()
)
for c in page.caso_response or []:
print(c.caso_number, c.caso_type_name)
```
def count(filter: CaseFilter) -> int
Cuenta los casos que cumplen el filtro sin traer todos los datos.
Parámetros:
filter(CaseFilter) —CaseFilter.
Retorna: int — Total de casos que cumplen el filtro, tal como lo devuelve el API.
Ejemplo de uso:
```python
total = client.caso().count(
CaseFilter.builder().working_sub_state_id(FilterOperator.EQ, "ws-uuid").build()
)
```
def delete_files(document_id: str) -> Any
Borra un fichero de un caso. Equivale a client.caso().files().delete(...).
Parámetros:
document_id(str) — ID del documento adjunto.
Retorna: Any — Respuesta cruda del API.
Ejemplo de uso:
```python
client.caso().delete_files("document-uuid")
```
def create_massive(request: CreateCasoMassiveRequest | Mapping[str, Any]) -> CreateCasoMassiveResponse
Crea múltiples casos en una sola llamada.
Parámetros:
request(CreateCasoMassiveRequest | Mapping[str, Any]) —CreateCasoMassiveRequestodict.
Retorna: CreateCasoMassiveResponse — CreateCasoMassiveResponse con import_id para seguir la importación.
Lanza:
pydantic.ValidationError— Si algún caso del lote no cumple el modelo.
Ejemplo de uso:
```python
casos = [
CasoCreateRequest.builder().caso_type_id("t").form_id("f").priority("p")
.submitted_data({"nombre": n}).build()
for n in ("Ana", "Luis")
]
resp = client.caso().create_massive(
CreateCasoMassiveRequest.builder().caso_type_id("t").casos(casos).build()
)
print(resp.import_id)
```
def change_priority(caso_id: str, priority_id: str) -> bool
Cambia la urgencia (prioridad) de un caso.
Parámetros:
caso_id(str) — UUID del caso.priority_id(str) — UUID de la nueva prioridad.
Retorna: bool — Siempre True si la llamada no lanzó excepción (el API no devuelve cuerpo).
Ejemplo de uso:
```python
ok = client.caso().change_priority("caso-uuid", "priority-uuid")
```
def search_all(filter: CaseFilter) -> list[CasoSearchResponse]
Busca TODOS los casos paginando automáticamente.
Es iterativo (sin recursión): aguanta miles de páginas sin desbordar la pila.
Usa el page_size del filtro (por defecto 20, máximo 200); con 200 se
reducen las llamadas.
Parámetros:
filter(CaseFilter) —CaseFilter. El filtro original no se modifica.
Retorna: list[CasoSearchResponse] — Lista con los CasoSearchResponse de todas las páginas.
Ejemplo de uso:
```python
casos = client.caso().search_all(
CaseFilter.builder()
.working_sub_state_id(FilterOperator.EQ, "ws-uuid")
.created_at("2024-01-01", "2024-01-31", "America/Bogota")
.page_size(200)
.build()
)
print(len(casos))
```
def search_with_attachments(filter: CaseFilter) -> CaseSearchResult
Busca casos (una página) e incluye los adjuntos descargados de cada uno.
Las descargas se reparten por caso en hilos, acotadas por max_workers.
Los adjuntos quedan en caso.files y el contenido en archivo.file.
Parámetros:
filter(CaseFilter) —CaseFilter.
Retorna: CaseSearchResult — CaseSearchResult donde cada caso trae files poblado.
Ejemplo de uso:
```python
import os
os.makedirs("descargas", exist_ok=True) # save() no crea carpetas
page = client.caso().search_with_attachments(
CaseFilter.builder().working_sub_state_id(FilterOperator.EQ, "ws-uuid").page_size(10).build()
)
for caso in page.caso_response or []:
for adj in caso.files or []:
adj.file.save(f"descargas/{caso.caso_number}_{adj.file_name}")
```
def search_all_with_attachments(filter: CaseFilter) -> list[CasoSearchResponse]
Busca TODOS los casos con sus adjuntos, paginando automáticamente.
Puede descargar mucho contenido en memoria: úsalo con filtros acotados.
Parámetros:
filter(CaseFilter) —CaseFilter.
Retorna: list[CasoSearchResponse] — Lista de CasoSearchResponse con files poblado.
Ejemplo de uso:
```python
casos = client.caso().search_all_with_attachments(
CaseFilter.builder()
.working_sub_state_id(FilterOperator.EQ, "ws-uuid")
.caso_number("1001")
.build()
)
```