diff --git a/CHANGELOG.md b/CHANGELOG.md index ba72fd2..7393d3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.4.0] - 2026-08-12 + +### Added + +- Add `invoices.createZipRequest(Map data)` for `POST /invoices/zip-requests`. +- Add `invoices.listZipRequests(Map params)` for `GET /invoices/zip-requests`. +- Add `invoices.retrieveZipRequest(String id)` for `GET /invoices/zip-requests/{id}`. +- Add `invoices.downloadZipRequest(String id)` for streaming `GET /invoices/zip-requests/{id}/zip`. + ## [1.3.0] - 2026-06-07 ### Added diff --git a/pom.xml b/pom.xml index 4235f4a..ed8e67d 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.facturapi facturapi-java - 1.3.0 + 1.4.0 facturapi-java Official Java SDK for Facturapi https://github.com/facturapi/facturapi-java diff --git a/src/main/java/io/facturapi/resources/InvoicesResource.java b/src/main/java/io/facturapi/resources/InvoicesResource.java index f0d2911..a0313bb 100644 --- a/src/main/java/io/facturapi/resources/InvoicesResource.java +++ b/src/main/java/io/facturapi/resources/InvoicesResource.java @@ -142,6 +142,63 @@ public InputStream downloadZipStream(String id) { return client.getStream("/invoices/" + id + "/zip"); } + /** + * Creates a ZIP request or returns the existing request for the same criteria. + * + * @param data ZIP request criteria. + * @return ZIP request data. + * @see API reference + */ + public Map createZipRequest(Map data) { + return post( + "/invoices/zip-requests", + data, + null, + new TypeReference>() {} + ); + } + + /** + * Gets a paginated list of ZIP requests. + * + * @param params Search and pagination parameters. + * @return Paginated ZIP request result. + * @see API reference + */ + public SearchResult> listZipRequests(Map params) { + return get( + "/invoices/zip-requests", + params, + new TypeReference>>() {} + ); + } + + /** + * Gets a ZIP request by id. + * + * @param id ZIP request id. + * @return ZIP request data. + * @see API reference + */ + public Map retrieveZipRequest(String id) { + return get( + "/invoices/zip-requests/" + id, + null, + new TypeReference>() {} + ); + } + + /** + * Downloads the ZIP generated for a request. + * + * @param id ZIP request id. + * @return ZIP stream. Caller owns closing it. + * @see API reference + */ + public InputStream downloadZipRequest(String id) { + return client.getStream("/invoices/zip-requests/" + id + "/zip"); + } + /** * Downloads the cancellation receipt XML file. * diff --git a/src/test/java/io/facturapi/FacturapiResourcesTest.java b/src/test/java/io/facturapi/FacturapiResourcesTest.java index b523184..1223ef8 100644 --- a/src/test/java/io/facturapi/FacturapiResourcesTest.java +++ b/src/test/java/io/facturapi/FacturapiResourcesTest.java @@ -112,6 +112,98 @@ void invoicePdfCanBeStreamed() throws Exception { assertEquals("/v2/invoices/inv_1/pdf", request.uri().getPath()); } + @Test + void invoiceZipRequestCanBeCreated() { + StubHttpClient httpClient = new StubHttpClient(); + httpClient.enqueueJson(200, "{\"id\":\"zip_1\",\"status\":\"pending\"}"); + + Facturapi sdk = new Facturapi( + FacturapiConfig.builder("sk_test") + .httpClient(httpClient.client()) + .build() + ); + + var response = sdk.invoices().createZipRequest( + Map.of( + "year", 2025, + "month", 3, + "issuer_type", "issuing", + "invoice_types", java.util.List.of("I", "E") + ) + ); + + assertEquals("zip_1", response.get("id")); + var request = httpClient.requests().get(0); + assertEquals("POST", request.method()); + assertEquals("/v2/invoices/zip-requests", request.uri().getPath()); + assertTrue(request.bodyUtf8().contains("\"issuer_type\":\"issuing\"")); + } + + @Test + void invoiceZipRequestsCanBeListed() { + StubHttpClient httpClient = new StubHttpClient(); + httpClient.enqueueJson( + 200, + "{\"page\":1,\"total_pages\":1,\"total_results\":1,\"data\":[{\"id\":\"zip_1\"}]}" + ); + + Facturapi sdk = new Facturapi( + FacturapiConfig.builder("sk_test") + .httpClient(httpClient.client()) + .build() + ); + + var response = sdk.invoices().listZipRequests( + Map.of("year", 2025, "month", 3, "status", "finished", "limit", 20, "page", 1) + ); + + assertEquals("zip_1", response.getData().get(0).get("id")); + var request = httpClient.requests().get(0); + assertEquals("GET", request.method()); + assertEquals("/v2/invoices/zip-requests", request.uri().getPath()); + assertTrue(request.uri().getQuery().contains("year=2025")); + assertTrue(request.uri().getQuery().contains("status=finished")); + } + + @Test + void invoiceZipRequestCanBeRetrieved() { + StubHttpClient httpClient = new StubHttpClient(); + httpClient.enqueueJson(200, "{\"id\":\"zip_1\",\"status\":\"finished\"}"); + + Facturapi sdk = new Facturapi( + FacturapiConfig.builder("sk_test") + .httpClient(httpClient.client()) + .build() + ); + + var response = sdk.invoices().retrieveZipRequest("zip_1"); + + assertEquals("finished", response.get("status")); + var request = httpClient.requests().get(0); + assertEquals("GET", request.method()); + assertEquals("/v2/invoices/zip-requests/zip_1", request.uri().getPath()); + } + + @Test + void invoiceZipRequestCanBeDownloaded() throws Exception { + StubHttpClient httpClient = new StubHttpClient(); + httpClient.enqueueBinary(200, "ZIP-CONTENT".getBytes(StandardCharsets.UTF_8), "application/zip"); + + Facturapi sdk = new Facturapi( + FacturapiConfig.builder("sk_test") + .httpClient(httpClient.client()) + .build() + ); + + try (InputStream stream = sdk.invoices().downloadZipRequest("zip_1")) { + assertEquals("ZIP-CONTENT", new String(stream.readAllBytes(), StandardCharsets.UTF_8)); + } + + var request = httpClient.requests().get(0); + assertEquals("GET", request.method()); + assertEquals("/v2/invoices/zip-requests/zip_1/zip", request.uri().getPath()); + } + @Test void organizationUploadsAcceptBytes() { StubHttpClient httpClient = new StubHttpClient();