diff --git a/VERSION.md b/VERSION.md index d4a4663..969152c 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1,3 +1,8 @@ +4.7.0 + +## Added +- Add invoice ZIP request methods: `createZipRequest()`, `listZipRequests()`, `retrieveZipRequest()`, and `downloadZipRequest()`. + 4.6.0 ## Added diff --git a/src/Resources/Invoices.php b/src/Resources/Invoices.php index 21fbf06..d2b6b8e 100644 --- a/src/Resources/Invoices.php +++ b/src/Resources/Invoices.php @@ -122,6 +122,66 @@ public function download_zip( $id ): string { return $this->downloadZip( $id ); } + /** + * Creates or retrieves an invoice ZIP request + * + * @param array $body ZIP request payload. + * @return mixed JSON-decoded response. + * @throws FacturapiException + */ + public function createZipRequest( $body ): mixed { + try { + return json_decode( $this->executeJsonPostRequest( $this->getRequestUrl( "zip-requests" ), $body ) ); + } catch ( FacturapiException $e ) { + throw $e; + } + } + + /** + * Lists invoice ZIP requests + * + * @param array|null $query Query parameters. + * @return mixed JSON-decoded response. + * @throws FacturapiException + */ + public function listZipRequests( $query = null ): mixed { + try { + return json_decode( $this->executeGetRequest( $this->getRequestUrl( "zip-requests", $query ) ) ); + } catch ( FacturapiException $e ) { + throw $e; + } + } + + /** + * Retrieves an invoice ZIP request by ID + * + * @param string $id ZIP request ID. + * @return mixed JSON-decoded response. + * @throws FacturapiException + */ + public function retrieveZipRequest( $id ): mixed { + try { + return json_decode( $this->executeGetRequest( $this->getRequestUrl( "zip-requests/" . $id ) ) ); + } catch ( FacturapiException $e ) { + throw $e; + } + } + + /** + * Downloads a completed invoice ZIP request + * + * @param string $id ZIP request ID. + * @return string ZIP file contents. + * @throws FacturapiException + */ + public function downloadZipRequest( $id ): string { + try { + return $this->executeGetRequest( $this->getRequestUrl( "zip-requests/" . $id . "/zip" ) ); + } catch ( FacturapiException $e ) { + throw $e; + } + } + /** * Downloads the specified invoice in a PDF file * diff --git a/tests/Resources/InvoicesTest.php b/tests/Resources/InvoicesTest.php index 1132150..817ff0e 100644 --- a/tests/Resources/InvoicesTest.php +++ b/tests/Resources/InvoicesTest.php @@ -72,4 +72,73 @@ public function testAllUrlEncodesScalarQueryValues(): void (string) $request->getUri() ); } + + public function testCreateZipRequestUsesExpectedPathAndJsonBody(): void + { + $httpClient = new FakeHttpClient(new Response(200, [], '{"id":"zip_123"}')); + $invoices = new Invoices('sk_test_abc123', ['httpClient' => $httpClient]); + $payload = [ + 'year' => 2025, + 'month' => 3, + 'issuer_type' => 'issuing', + 'invoice_types' => ['I', 'E'], + ]; + + $result = $invoices->createZipRequest($payload); + + self::assertSame('zip_123', $result->id); + $request = $httpClient->requests()[0]; + self::assertSame('POST', $request->getMethod()); + self::assertSame('https://www.facturapi.io/v2/invoices/zip-requests', (string) $request->getUri()); + self::assertSame('application/json', $request->getHeaderLine('Content-Type')); + self::assertSame($payload, json_decode((string) $request->getBody(), true)); + } + + public function testListZipRequestsUsesExpectedPathAndQuery(): void + { + $httpClient = new FakeHttpClient(new Response(200, [], '{"data":[]}')); + $invoices = new Invoices('sk_test_abc123', ['httpClient' => $httpClient]); + + $result = $invoices->listZipRequests([ + 'year' => 2025, + 'month' => 3, + 'status' => 'finished', + 'limit' => 20, + 'page' => 1, + ]); + + self::assertSame([], $result->data); + $request = $httpClient->requests()[0]; + self::assertSame('GET', $request->getMethod()); + self::assertSame( + 'https://www.facturapi.io/v2/invoices/zip-requests?year=2025&month=3&status=finished&limit=20&page=1', + (string) $request->getUri() + ); + } + + public function testRetrieveZipRequestUsesExpectedPath(): void + { + $httpClient = new FakeHttpClient(new Response(200, [], '{"id":"zip_123"}')); + $invoices = new Invoices('sk_test_abc123', ['httpClient' => $httpClient]); + + $result = $invoices->retrieveZipRequest('zip_123'); + + self::assertSame('zip_123', $result->id); + $request = $httpClient->requests()[0]; + self::assertSame('GET', $request->getMethod()); + self::assertSame('https://www.facturapi.io/v2/invoices/zip-requests/zip_123', (string) $request->getUri()); + } + + public function testDownloadZipRequestReturnsBinaryContentsFromExpectedPath(): void + { + $httpClient = new FakeHttpClient(new Response(200, [], 'ZIP_BINARY_CONTENT')); + $invoices = new Invoices('sk_test_abc123', ['httpClient' => $httpClient]); + + $result = $invoices->downloadZipRequest('zip_123'); + + self::assertSame('ZIP_BINARY_CONTENT', $result); + $request = $httpClient->requests()[0]; + self::assertSame('GET', $request->getMethod()); + self::assertSame('https://www.facturapi.io/v2/invoices/zip-requests/zip_123/zip', (string) $request->getUri()); + } }