Skip to content

Commit

Permalink
fix: frequency get remaining iterations method logic fixed for first …
Browse files Browse the repository at this point in the history
…date inclusive (#18)

* first date inclusion logic added

* dates fixed

* test corrected

* RecurringCashFlowServiceTest.php added
  • Loading branch information
chinmaypurav authored Jan 11, 2025
1 parent 96fe200 commit 8e864dc
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 7 deletions.
4 changes: 3 additions & 1 deletion app/Enums/Frequency.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@ public function getRemainingIterations(Carbon $start, Carbon $end, int $iteratio
self::MONTHLY->value => $start->diffInMonths($end, true),
self::QUARTERLY->value => $start->diffInQuarters($end),
self::YEARLY->value => $start->diffInYears($end),
default => 1,
self::ONCE->value => 0,
};

$diff = floor($diff);

$diff = $diff + 1; // the first date is inclusive

return min($iterationsLeft, $diff);
}
}
62 changes: 62 additions & 0 deletions tests/Feature/RecurringCashFlowServiceTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

use App\Enums\Frequency;
use App\Models\Account;
use App\Models\RecurringExpense;
use App\Models\RecurringIncome;
use App\Models\User;
use App\Services\RecurringCashFlowService;
use Illuminate\Foundation\Testing\RefreshDatabase;

use function PHPUnit\Framework\assertEquals;

uses(RefreshDatabase::class);

beforeEach(function () {
$this->user = User::factory()->create();
$this->actingAs($this->user);
});

test('it returns recurring incomes total', function () {
$account = Account::factory()->create();

RecurringIncome::factory()
->for($this->user)
->for($account)
->create([
'amount' => 1000,
'frequency' => Frequency::MONTHLY,
'remaining_recurrences' => 12,
'next_transaction_at' => today()->addDay(),
]);

$total = RecurringCashFlowService::processRecurringIncomes(
$this->user,
today(),
today()->addYear()
);

assertEquals(12000, $total);
});

test('it returns recurring expenses total', function () {
$account = Account::factory()->create();

RecurringExpense::factory()
->for($this->user)
->for($account)
->create([
'amount' => 1000,
'frequency' => Frequency::MONTHLY,
'remaining_recurrences' => 12,
'next_transaction_at' => today()->addDay(),
]);

$total = RecurringCashFlowService::processRecurringExpenses(
$this->user,
today(),
today()->addYear()
);

assertEquals(12000, $total);
});
12 changes: 6 additions & 6 deletions tests/Unit/Enums/FrequencyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@

it('returns correct remaining occurrences for monthly frequency', function () {
$start = Carbon::create(2023, 1, 1);
$end = Carbon::create(2023, 6, 1); // 5 months
$end = Carbon::create(2023, 6, 1); // 6 months
$iterationsLeft = 10;

$remainingOccurrences = Frequency::MONTHLY->getRemainingIterations($start, $end, $iterationsLeft);

expect($remainingOccurrences)->toEqual(5);
expect($remainingOccurrences)->toEqual(6);
});

it('returns correct remaining occurrences for quarterly frequency', function () {
Expand Down Expand Up @@ -63,12 +63,12 @@
expect($remainingOccurrences)->toEqual(1);
});

it('returns the minimum of iterations left or the differences', function () {
it('returns the iterations within the duration when the iteration is above the date range', function () {
$start = Carbon::create(2023, 1, 1);
$end = Carbon::create(2023, 1, 5); // 4 days
$iterationsLeft = 2;
$end = Carbon::create(2023, 1, 5); // 5 days
$iterationsLeft = 10;

$remainingOccurrences = Frequency::DAILY->getRemainingIterations($start, $end, $iterationsLeft);

expect($remainingOccurrences)->toEqual(2);
expect($remainingOccurrences)->toEqual(5);
});

0 comments on commit 8e864dc

Please sign in to comment.