Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Contribuir

## Compilación

La compilación usa JDK 25 por defecto y genera bytecode Java 17.

```bash
./gradlew clean build
```

Para compilar y ejecutar los tests con otro JDK instalado:

```bash
./gradlew clean build -PjavaVersion=17
./gradlew clean build -PjavaVersion=21
```

El wrapper incluye Gradle 9.8.1 y verifica el SHA-256 de su distribución. Los
tests usan un servidor HTTP local con puerto efímero; no necesitan la API en
producción ni un servicio en `localhost:8080`.

## Formato y análisis estático

- [Spotless](https://plugins.gradle.org/plugin/com.diffplug.spotless) aplica
[Palantir Java Format](https://github.com/palantir/palantir-java-format) a
todas las fuentes Java, incluidos los tests, y formatea los archivos Gradle con
Groovy Eclipse.
- [PMD](https://pmd.github.io/) analiza producción y tests con las reglas de
[config/pmd/ruleset.xml](config/pmd/ruleset.xml): errores de igualdad,
excepciones, recursos, código sin uso y operaciones redundantes.
- El compilador activa `-Xlint:all` y trata las advertencias como errores.

```bash
./gradlew spotlessApply # Aplicar el formato
./gradlew spotlessCheck # Comprobar el formato
./gradlew pmdMain pmdTest # Analizar producción y tests
./gradlew check # Formato, análisis y tests
```

`build` incluye todas estas comprobaciones. Funcionan con los tres JDK admitidos;
puedes añadir `-PjavaVersion=17` o `-PjavaVersion=21` a los comandos anteriores.
Las herramientas de calidad son dependencias del build y no se publican como
dependencias del cliente.

## Integración continua

CI ejecuta `./gradlew clean build` con Java 17, 21 y 25 y falla si alguna
comprobación detecta un problema.

## Dependencias

Retrofit se declara como dependencia `api` porque los métodos públicos devuelven
`retrofit2.Call`. El BOM de OkHttp también se expone para alinear sus tipos
transitivos entre la compilación del consumidor y la ejecución. La conversión
JSON usa el módulo oficial `fastjson2-extension`, que incluye el
[conversor para Retrofit](https://github.com/alibaba/fastjson2/blob/2.0.65/extension/src/main/java/com/alibaba/fastjson2/support/retrofit/Retrofit2ConverterFactory.java).

Registra los cambios de cada versión en [CHANGELOG.md](CHANGELOG.md).
168 changes: 80 additions & 88 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,53 +1,17 @@
# Tu RUC Java Client

Cliente Java para consultar y buscar contribuyentes en la API de Tu RUC.
Cliente Java para consultar y buscar contribuyentes en la API de
[Tu RUC](https://turuc.com.py/).

## Requisitos y compilación
## Requisitos

La biblioteca funciona en Java 17, 21 y 25. La compilación usa JDK 25 por defecto
y genera bytecode Java 17; los consumidores no necesitan JDK 25.
Java 17 o superior.

```bash
./gradlew clean build
```

Para compilar y ejecutar los tests con otro JDK instalado:

```bash
./gradlew clean build -PjavaVersion=17
./gradlew clean build -PjavaVersion=21
```

El wrapper incluye Gradle 9.8.1 y verifica el SHA-256 de su distribución. Los
tests usan un servidor HTTP local con puerto efímero y no necesitan la API en
producción ni un servicio en `localhost:8080`. CI verifica Java 17, 21 y 25.

## Formato y análisis estático

[Spotless 8.10.4](https://plugins.gradle.org/plugin/com.diffplug.spotless/8.10.4)
aplica [Palantir Java Format 2.102.0](https://github.com/palantir/palantir-java-format)
a todas las fuentes Java, incluidos los tests, y formatea los archivos Gradle con
Groovy Eclipse. [PMD 7.28.0](https://pmd.github.io/2026/09/25/PMD-7.28.0/)
analiza producción y tests con las reglas de [config/pmd/ruleset.xml](config/pmd/ruleset.xml):
errores de igualdad, excepciones, recursos, código sin uso y operaciones redundantes.
El compilador también activa `-Xlint:all` y trata las advertencias como errores.

```bash
./gradlew spotlessApply # Aplicar el formato
./gradlew spotlessCheck # Comprobar el formato
./gradlew pmdMain pmdTest # Analizar producción y tests
./gradlew check # Formato, análisis y tests
```

`build` incluye todas estas comprobaciones. Funcionan con los tres JDK admitidos;
se puede añadir `-PjavaVersion=17` o `-PjavaVersion=21` a los comandos anteriores.
CI ejecuta las mismas comprobaciones y falla si detecta un problema. Las herramientas
de calidad son dependencias del build y no se publican como dependencias del cliente.
## Instalación

## Uso desde otro proyecto Gradle

La versión de trabajo es `0.1.0`. Para consumir el checkout local, agrega a
`settings.gradle` del proyecto consumidor:
La biblioteca todavía no se publica en un repositorio Maven. Para usarla desde
otro proyecto Gradle, clona este repositorio junto a tu proyecto y agrega a su
`settings.gradle`:

```groovy
includeBuild("../tu-ruc-java-client")
Expand All @@ -65,17 +29,19 @@ dependencies {
}
```

Gradle resuelve la biblioteca local y sus dependencias. El JAR generado en
`build/libs/` no incluye las dependencias dentro del archivo.
Este ejemplo con `includeBuild` compila el checkout y requiere JDK 25 instalado
con la configuración por defecto. Consumir el JAR ya compilado requiere Java 17
o superior.
Gradle compila la biblioteca y resuelve sus dependencias desde Maven Central.
Para compilarla así necesitas JDK 25 instalado, aunque el resultado funciona
desde Java 17. Si usas el JAR de `build/libs/`, agrega tú sus dependencias:
el JAR no las incluye.

## Uso

```java
import org.ith.client.TuRuc;
import org.ith.client.TuRucClient;

TuRucClient client = new TuRuc("https://turuc.com.py/").getClient();

var response = client.getContribuyente("80024191-6").execute();

if (response.isSuccessful()) {
Expand All @@ -89,52 +55,78 @@ if (response.isSuccessful()) {
var page = client.searchContribuyentes("NUÑEZ", 0).execute();
```

`execute()` puede lanzar `IOException` ante un fallo de transporte o un error
al convertir el JSON de la respuesta. Los errores HTTP se consultan mediante
`Response.isSuccessful()`, `code()` y `errorBody()`.
Las páginas comienzan en cero y la URL base debe terminar en `/`.
- La URL base debe terminar en `/`.
- Las páginas de búsqueda empiezan en 0.
- Los métodos devuelven `retrofit2.Call`: usa `execute()` para una llamada
síncrona o `enqueue()` para una asíncrona.
- Crea el cliente una vez y reutilízalo; cada llamada a `getClient()` crea un
cliente HTTP nuevo.
- El cliente registra cada petición y respuesta completas, con su cuerpo, en el
log de OkHttp.

### Respuestas

`getContribuyente()` devuelve un `Contribuyente` dentro de `getData()`.
`searchContribuyentes()` devuelve un `SearchResponse` con `getContribuyentes()`
y `getPaginas()`.

| Campo de `Contribuyente` | Tipo | Descripción |
| ------------------------ | --------- | ------------------------------------------- |
| `getDoc()` | `Integer` | Número de documento (CI) |
| `getRazonSocial()` | `String` | Nombre o razón social |
| `getDv()` | `Integer` | Dígito verificador del RUC |
| `getRuc()` | `String` | RUC completo, con el dígito verificador |
| `getEstado()` | `String` | Estado del contribuyente; puede ser `null` |
| `getEsPersonaJuridica()` | `Boolean` | Indica si es persona jurídica |
| `getEsEntidadPublica()` | `Boolean` | Indica si es entidad pública |

### Errores

- **Errores HTTP:** consúltalos con `response.isSuccessful()`, `code()` y
`errorBody()`. No lanzan excepciones.
- **Fallos de red o JSON inválido:** `execute()` lanza `IOException`. Si el JSON
no se puede convertir, la causa original viene en `getCause()`.

### Timeouts

Por defecto, todos los timeouts son de 60 segundos, incluido el de la llamada
completa. Para cambiarlos, indica los valores en segundos:

```java
// callTimeout, writeTimeout, readTimeout, connectTimeout
TuRucClient client = new TuRuc("https://turuc.com.py/", 30, 10, 10, 5).getClient();
```

## Migración desde 0.0.1-beta

`0.1.0` cambia la API pública de `Contribuyente` para reflejar la respuesta actual
del servidor. Es necesario recompilar y adaptar a los consumidores:
La versión 0.1.0 cambia el modelo `Contribuyente` para reflejar la respuesta
actual de la API. Recompila tu proyecto y adapta estos usos:

| Antes | Ahora |
| --- | --- |
| `Integer getRuc()` | `String getRuc()` devuelve el RUC completo con DV |
| `setRuc(Integer)` | `setRuc(String)` recibe el RUC completo |
| Número de documento en `ruc` | `Integer getDoc()` y `setDoc(Integer)` |
| Constructor de tres argumentos | Constructor con los siete campos de la respuesta |
| Antes | Ahora |
| ------------------------------ | --------------------------------------------------------- |
| `Integer getRuc()` | `String getRuc()`, con el dígito verificador |
| `setRuc(Integer)` | `setRuc(String)`, con el RUC completo |
| Número de documento en `ruc` | `Integer getDoc()` y `setDoc(Integer)` |
| Constructor de tres argumentos | Constructor con los siete campos, en el orden de la tabla |

```java
var contribuyente = new org.ith.model.Contribuyente(
80024191, "MINISTERIO DE PRUEBA", 6, "80024191-6", "ACTIVO", false, true);
```

También se exponen `estado`, `esPersonaJuridica` y `esEntidadPublica` mediante
getters y setters. `equals()` y `hashCode()` incluyen todos los campos del modelo.
`estado` puede ser `null`, tal como permite la API. El modelo usa `doc` y `ruc`
recibidos del servidor; no reconstruye uno a partir del otro.

La conversión JSON utiliza Fastjson2 en lugar de Gson. Los métodos públicos
siguen devolviendo `retrofit2.Call` con los mismos modelos. El conversor oficial
de Fastjson2 propaga los errores de conversión como `IOException`, con la causa
original; si capturabas excepciones específicas de Gson, adapta esas capturas.

## Dependencias

Retrofit usa 3.0.0; OkHttp y su interceptor de logs se alinean con el BOM 5.5.0.
La conversión JSON usa el módulo oficial `fastjson2-extension` 2.0.65, que incluye
el conversor para Retrofit y depende de `fastjson2` de la misma versión. Gson y
`converter-gson` dejan de formar parte de las dependencias de ejecución.
Los tests usan JUnit 6.1.3. Retrofit se declara como dependencia de API porque
los métodos públicos devuelven `retrofit2.Call`.
El BOM de OkHttp también se expone para alinear sus tipos transitivos entre la
compilación del consumidor y la ejecución.

El cliente procesa las respuestas JSON de texto de TuRuc mediante el conversor
[oficial de Fastjson2](https://github.com/alibaba/fastjson2/blob/2.0.65/extension/src/main/java/com/alibaba/fastjson2/support/retrofit/Retrofit2ConverterFactory.java).
La migración verifica compatibilidad funcional; no implica una mejora medida
del tiempo total de las consultas.

Consulta [CHANGELOG.md](CHANGELOG.md) para los cambios de esta versión.
`equals()` y `hashCode()` ahora comparan los siete campos.

El JSON se convierte con Fastjson2 en lugar de Gson. Si capturabas excepciones
de Gson, captura `IOException`. La biblioteca ya no trae Gson como dependencia;
si tu proyecto lo usa, decláralo por tu cuenta.

Las dependencias transitivas pasan a Retrofit 3.0.0 y OkHttp 5.5.0.

## Cambios

Consulta [CHANGELOG.md](CHANGELOG.md) para conocer los cambios de cada versión.

## Contribuciones

Para compilar, ejecutar las pruebas y conocer las comprobaciones de calidad,
consulta [CONTRIBUTING.md](CONTRIBUTING.md).
Loading