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
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ no [contrato de saída](docs/guia/contrato-de-saida.md).

## [Unreleased]

### Fixed

- **`financeiro alteracoes` não paginava.** A API aceita `pagina` e
`tamanho_pagina` (iguais às outras listagens financeiras), mas o comando
não expunha `--pagina`/`--tamanho-pagina` e o cliente nem mandava os
parâmetros. Passa a enviar os dois, com o mesmo default do restante do
CLI (`1` / `50`).

### Changed

- **Requisito mínimo de PHP subiu de 8.4 para 8.4.1.** O código do CLI não
Expand Down
12 changes: 11 additions & 1 deletion docs/_data/commands/financeiro.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ sections:
- 'financeiro alteracoes'
status: verified
endpoints:
'financeiro alteracoes': 'ISO 8601 **sem timezone**'
'financeiro alteracoes': 'GET /v1/financeiro/eventos-financeiros/alteracoes'
params:
data-inicio:
label: '`--data-inicio`'
Expand All @@ -17,6 +17,16 @@ sections:
required: não¹
default: 'fim do mês corrente'
description: 'ISO 8601 **sem timezone**'
pagina:
label: '`--pagina`'
required: não
default: '`1`'
description: 'Número da página'
tamanho-pagina:
label: '`--tamanho-pagina`'
required: não
default: '`50`'
description: 'Itens por página'
body: |
Feed de alterações no período — o caminho para reconciliar escritas que terminaram em `ambiguous`.

Expand Down
16 changes: 15 additions & 1 deletion docs/commands.json
Original file line number Diff line number Diff line change
Expand Up @@ -744,7 +744,7 @@
{
"arguments": [],
"description": "Lista alterações de eventos financeiros num intervalo (útil para reconciliação)",
"endpoint": "ISO 8601 **sem timezone**",
"endpoint": "GET /v1/financeiro/eventos-financeiros/alteracoes",
"group": "financeiro",
"name": "financeiro alteracoes",
"options": [
Expand All @@ -761,6 +761,20 @@
"multiple": false,
"name": "--data-fim",
"takes_value": true
},
{
"default": 1,
"description": "Número da página",
"multiple": false,
"name": "--pagina",
"takes_value": true
},
{
"default": 50,
"description": "Itens por página",
"multiple": false,
"name": "--tamanho-pagina",
"takes_value": true
}
],
"verified": true
Expand Down
2 changes: 1 addition & 1 deletion docs/financial-apis-openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ paths:
/v1/financeiro/eventos-financeiros/{id_evento}/parcelas:
get: { summary: "Parcelas de um evento financeiro (sem comando no CLI)" }
/v1/financeiro/eventos-financeiros/alteracoes:
get: { summary: "Feed de alterações; params data_inicio e data_fim em ISO 8601 SEM timezone" }
get: { summary: "Feed de alterações; params data_inicio e data_fim em ISO 8601 SEM timezone, pagina e tamanho_pagina" }
/v1/financeiro/eventos-financeiros/saldo-inicial:
get: { summary: "Saldo inicial no período; params data_inicio e data_fim em ISO 8601 SEM timezone" }
/v1/protocolo/{id}:
Expand Down
4 changes: 3 additions & 1 deletion docs/llms-full.txt
Original file line number Diff line number Diff line change
Expand Up @@ -559,12 +559,14 @@ uma baixa: não existe "estornar".**

## `financeiro alteracoes` ✅ { #financeiro-alteracoes }

`ISO 8601 **sem timezone**`
`GET /v1/financeiro/eventos-financeiros/alteracoes`

| Parâmetro | Obrig. | Padrão | Descrição |
|---|---|---|---|
| `--data-inicio` | não¹ | início do mês corrente | ISO 8601 **sem timezone** |
| `--data-fim` | não¹ | fim do mês corrente | ISO 8601 **sem timezone** |
| `--pagina` | não | `1` | Número da página |
| `--tamanho-pagina` | não | `50` | Itens por página |

Feed de alterações no período — o caminho para reconciliar escritas que terminaram em `ambiguous`.

Expand Down
4 changes: 3 additions & 1 deletion docs/referencia/financeiro.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@

## `financeiro alteracoes` ✅ { #financeiro-alteracoes }

`ISO 8601 **sem timezone**`
`GET /v1/financeiro/eventos-financeiros/alteracoes`

| Parâmetro | Obrig. | Padrão | Descrição |
|---|---|---|---|
| `--data-inicio` | não¹ | início do mês corrente | ISO 8601 **sem timezone** |
| `--data-fim` | não¹ | fim do mês corrente | ISO 8601 **sem timezone** |
| `--pagina` | não | `1` | Número da página |
| `--tamanho-pagina` | não | `50` | Itens por página |

Feed de alterações no período — o caminho para reconciliar escritas que terminaram em `ambiguous`.

Expand Down
2 changes: 1 addition & 1 deletion docs/referencia/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ Cada endpoint traz uma marca de confiança:
| [`baixa get`](baixa.md#baixa-get) | `GET /v1/financeiro/eventos-financeiros/parcelas/baixa/{id}` | ✅ |
| [`baixa update`](baixa.md#baixa-update) | `PATCH /v1/financeiro/eventos-financeiros/parcelas/baixa/{id}` | ✅ |
| [`baixa delete`](baixa.md#baixa-delete) | `DELETE /v1/financeiro/eventos-financeiros/parcelas/baixa/{id}` | ✅ |
| [`financeiro alteracoes`](financeiro.md#financeiro-alteracoes) | `ISO 8601 **sem timezone**` | ✅ |
| [`financeiro alteracoes`](financeiro.md#financeiro-alteracoes) | `GET /v1/financeiro/eventos-financeiros/alteracoes` | ✅ |
| [`financeiro saldo-inicial`](financeiro.md#financeiro-saldo-inicial) | `GET /v1/financeiro/eventos-financeiros/saldo-inicial` | ✅ |
| [`protocolo get`](protocolo.md#protocolo-get) | `GET /v1/protocolo/{id}` | ✅ |
| [`contrato list`](contrato.md#contrato-list) | `GET /v1/contratos` | ✅ |
Expand Down
22 changes: 12 additions & 10 deletions src/Api/FinanceiroClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -425,22 +425,24 @@ public function createCentroDeCusto(array $payload): array {
* As datas vão em ISO 8601 **sem timezone** (`2026-08-01T00:00:00`). Com
* sufixo `Z` ou offset a API responde 400.
*
* @param array<string, mixed> $filters
*
* @return array<mixed>
*/
public function getAlteracoes(string $dataInicio, string $dataFim, array $filters = []): array {
public function getAlteracoes(
string $dataInicio,
string $dataFim,
int $pagina = 1,
int $tamanhoPagina = 50,
): array {
return $this->support->request(
'GET',
'/v1/financeiro/eventos-financeiros/alteracoes',
[
'query' => array_merge(
[
'data_fim' => $dataFim,
'data_inicio' => $dataInicio,
],
$filters,
),
'query' => [
'data_fim' => $dataFim,
'data_inicio' => $dataInicio,
'pagina' => $pagina,
'tamanho_pagina' => $tamanhoPagina,
],
],
);
}
Expand Down
15 changes: 13 additions & 2 deletions src/Command/Financeiro/AlteracoesCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
namespace ContaAzulCli\Command\Financeiro;

use ContaAzulCli\Api\FinanceiroClient;
use ContaAzulCli\Api\PaginationValidator;
use ContaAzulCli\Command\Support\CommandExecutor;
use ContaAzulCli\Command\Support\PaginationOptions;
use ContaAzulCli\Command\Support\PeriodoPadrao;
use ContaAzulCli\Output\ErrorEnvelope;
use ContaAzulCli\Output\ResponseRenderer;
Expand All @@ -28,6 +30,7 @@ public function __construct(
private readonly FinanceiroClient $client,
private readonly ErrorEnvelope $errorEnvelope,
private readonly ResponseRenderer $responseRenderer,
private readonly PaginationValidator $paginationValidator,
private readonly WarningEnvelope $warningEnvelope,
private readonly PeriodoPadrao $periodoPadrao,
CommandExecutor|null $commandExecutor = null,
Expand All @@ -49,9 +52,13 @@ public function __invoke(
description: 'Fim em ISO 8601 sem timezone (ex: 2026-08-31T23:59:59). Padrão: fim do mês corrente',
)]
string|null $dataFim = null,
#[Option(description: 'Número da página')]
int $pagina = 1,
#[Option(name: 'tamanho-pagina', description: 'Itens por página')]
int $tamanhoPagina = 50,
): int {
return $this->commandExecutor->execute(
function () use ($dataInicio, $dataFim): void {
function () use ($dataInicio, $dataFim, $pagina, $tamanhoPagina): void {
$inicio = $dataInicio !== null && $dataInicio !== '' ? $dataInicio : $this->periodoPadrao->primeiroInstante();
$fim = $dataFim !== null && $dataFim !== '' ? $dataFim : $this->periodoPadrao->ultimoInstante();

Expand All @@ -62,7 +69,11 @@ function () use ($dataInicio, $dataFim): void {
);
}

$this->responseRenderer->render($this->client->getAlteracoes($inicio, $fim));
$pagination = PaginationOptions::fromValues($pagina, $tamanhoPagina, $this->paginationValidator);

$this->responseRenderer->render(
$this->client->getAlteracoes($inicio, $fim, $pagination->page(), $pagination->pageSize()),
);
},
);
}
Expand Down
1 change: 1 addition & 0 deletions src/Command/Module/FinanceiroCommandModule.php
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ public function commands(): array {
$this->client,
$this->errorEnvelope,
$this->responseRenderer,
$this->paginationValidator,
$this->warningEnvelope,
$this->periodoPadrao,
),
Expand Down
91 changes: 91 additions & 0 deletions tests/Integration/Command/Financeiro/AlteracoesCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace ContaAzulCli\Tests\Integration\Command\Financeiro;

use ContaAzulCli\Api\PaginationValidator;
use ContaAzulCli\Command\Financeiro\AlteracoesCommand;
use ContaAzulCli\Command\Support\PeriodoPadrao;
use ContaAzulCli\Output\ErrorEnvelope;
Expand All @@ -13,6 +14,11 @@
use DateTimeImmutable;
use Symfony\Component\Console\Command\Command;

use function parse_str;
use function parse_url;

use const PHP_URL_QUERY;

final class AlteracoesCommandTest extends CommandTestCase
{
public function testListsChangesWithExplicitIntervalAndNoWarning(): void {
Expand All @@ -21,6 +27,7 @@ public function testListsChangesWithExplicitIntervalAndNoWarning(): void {
$this->financeiroClient([$this->jsonResponse(['itens' => []])]),
new ErrorEnvelope($output),
new ResponseRenderer($output),
new PaginationValidator(),
new WarningEnvelope($output),
new PeriodoPadrao(),
);
Expand All @@ -41,6 +48,7 @@ public function testMissingIntervalFallsBackToCurrentMonthWithAWarning(): void {
$this->financeiroClient([$this->jsonResponse(['itens' => []])]),
new ErrorEnvelope($output),
new ResponseRenderer($output),
new PaginationValidator(),
new WarningEnvelope($output),
new PeriodoPadrao(new DateTimeImmutable('2026-08-16')),
);
Expand All @@ -51,6 +59,89 @@ public function testMissingIntervalFallsBackToCurrentMonthWithAWarning(): void {

$warning = self::decodeEnvelope($output->stderr());
self::assertSame('warning', $warning['kind']);
self::assertIsString($warning['message']);
self::assertStringContainsString('2026-08-01T00:00:00', $warning['message']);
}

public function testForwardsPaginationOptionsAsQueryParameters(): void {
$captured = null;
$output = $this->newOutput();
$command = new AlteracoesCommand(
$this->financeiroClientRecording($captured),
new ErrorEnvelope($output),
new ResponseRenderer($output),
new PaginationValidator(),
new WarningEnvelope($output),
new PeriodoPadrao(),
);

$tester = $this->runCommand(
$command,
[
'--data-fim' => '2026-08-31T23:59:59',
'--data-inicio' => '2026-08-01T00:00:00',
'--pagina' => '3',
'--tamanho-pagina' => '10',
],
);

self::assertSame(Command::SUCCESS, $tester->getStatusCode());
self::assertNotNull($captured);
parse_str((string) parse_url($captured['url'], PHP_URL_QUERY), $query);
self::assertSame('2026-08-01T00:00:00', $query['data_inicio'] ?? null);
self::assertSame('2026-08-31T23:59:59', $query['data_fim'] ?? null);
self::assertSame('3', $query['pagina'] ?? null);
self::assertSame('10', $query['tamanho_pagina'] ?? null);
}

public function testSendsDefaultPaginationWhenTheFlagsAreOmitted(): void {
$captured = null;
$output = $this->newOutput();
$command = new AlteracoesCommand(
$this->financeiroClientRecording($captured),
new ErrorEnvelope($output),
new ResponseRenderer($output),
new PaginationValidator(),
new WarningEnvelope($output),
new PeriodoPadrao(),
);

$this->runCommand(
$command,
['--data-inicio' => '2026-08-01T00:00:00', '--data-fim' => '2026-08-31T23:59:59'],
);

self::assertNotNull($captured);
parse_str((string) parse_url($captured['url'], PHP_URL_QUERY), $query);
self::assertSame('1', $query['pagina'] ?? null);
self::assertSame('50', $query['tamanho_pagina'] ?? null);
}

public function testUnsupportedPageSizeFailsBeforeCallingTheApi(): void {
$captured = null;
$output = $this->newOutput();
$command = new AlteracoesCommand(
$this->financeiroClientRecording($captured),
new ErrorEnvelope($output),
new ResponseRenderer($output),
new PaginationValidator(),
new WarningEnvelope($output),
new PeriodoPadrao(),
);

$tester = $this->runCommand(
$command,
[
'--data-fim' => '2026-08-31T23:59:59',
'--data-inicio' => '2026-08-01T00:00:00',
'--tamanho-pagina' => '15',
],
);

self::assertSame(Command::FAILURE, $tester->getStatusCode());
self::assertNull($captured);

$envelope = self::decodeEnvelope($output->stderr());
self::assertSame('client_error', $envelope['kind']);
}
}
8 changes: 5 additions & 3 deletions tests/Integration/ContaAzulApplicationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,12 @@ public function testApplicationCommandsExposeFormatButNotRaw(): void {
/** Registering the shared --format option must not crowd out an invokable command's own #[Option] attributes. */
public function testInvokableOptionsSurviveFormatRegistration(): void {
$application = new ContaAzulApplication();
$definition = $application->get('categoria list')->getDefinition();

self::assertTrue($definition->hasOption('pagina'));
self::assertTrue($definition->hasOption('tamanho-pagina'));
foreach (['categoria list', 'financeiro alteracoes', 'financeiro saldo-inicial'] as $name) {
$definition = $application->get($name)->getDefinition();
self::assertTrue($definition->hasOption('pagina'), $name);
self::assertTrue($definition->hasOption('tamanho-pagina'), $name);
}
}

/** The removed JSON alias is rejected on project commands before any API request. */
Expand Down
15 changes: 15 additions & 0 deletions tests/Unit/Api/FinanceiroClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -393,9 +393,24 @@ public function testAlteracoesSendsDataInicioAndDataFim(): void {
parse_str((string) parse_url($captured['url'], PHP_URL_QUERY), $query);
self::assertSame('2026-08-01T00:00:00', $query['data_inicio'] ?? null);
self::assertSame('2026-08-31T23:59:59', $query['data_fim'] ?? null);
self::assertSame('1', $query['pagina'] ?? null);
self::assertSame('50', $query['tamanho_pagina'] ?? null);
self::assertArrayNotHasKey('desde', $query);
}

/** Paginação vai na query, iguais às outras listagens financeiras. */
public function testAlteracoesSendsPagination(): void {
$captured = null;
$client = $this->clientRecording($captured);

$client->getAlteracoes('2026-08-01T00:00:00', '2026-08-31T23:59:59', 2, 25);

self::assertNotNull($captured);
parse_str((string) parse_url($captured['url'], PHP_URL_QUERY), $query);
self::assertSame('2', $query['pagina'] ?? null);
self::assertSame('25', $query['tamanho_pagina'] ?? null);
}

/** Assim como `getAlteracoes`, o instante ISO 8601 vai sem timezone. */
public function testListSaldoInicialSendsDataInicioDataFimAndPagination(): void {
$captured = null;
Expand Down
Loading