Skip to content

Commit

Permalink
Support creating multiple past paydays in case the last call is more …
Browse files Browse the repository at this point in the history
…than one week ago
  • Loading branch information
Macavity committed Aug 7, 2023
1 parent 49bb9a3 commit 23b84f1
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 9 deletions.
31 changes: 31 additions & 0 deletions migrations/Version20230806204622.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20230806204622 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}

public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE transaction ADD pocket_money TINYINT(1) NOT NULL, ADD effective_on DATETIME DEFAULT NULL');
}

public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE transaction DROP pocket_money, DROP effective_on');
}
}
4 changes: 4 additions & 0 deletions phpcs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@

<rule ref="Squiz.Strings.ConcatenationSpacing" />

<rule ref="Squiz.Strings.ConcatenationSpacing.PaddingFound">
<severity>0</severity>
</rule>

<rule ref="SlevomatCodingStandard.TypeHints.DeclareStrictTypes">
<properties>
<property name="spacesCountAroundEqualsSign" value="0" />
Expand Down
7 changes: 5 additions & 2 deletions src/Controller/OverviewController.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,17 @@ public function getOverview(int $userId, EntityManagerInterface $entityManager):

$now = new DateTime();

if ($now >= $user->getNextPayday()) {
while ($now >= $user->getNextPayday()) {
// Update balance and nextPayday
$next = clone $user->getNextPayday();
$next->modify('+1 week');

$effectiveOn = clone $user->getNextPayday();

$user->setNextPayday($next);
$this->logger->debug('Set Next Payday to {next}', ['next' => $next]);

$pocketMoney = EarningFactory::createPocketMoney($user);
$pocketMoney = EarningFactory::createPocketMoney($user, $effectiveOn);

$entityManager->persist($pocketMoney);
$entityManager->persist($user);
Expand Down
15 changes: 15 additions & 0 deletions src/Entity/Transaction.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ class Transaction
#[ORM\Column]
private ?bool $pocketMoney = false;

#[ORM\Column(type: "datetime", nullable: true)]
private ?DateTime $effectiveOn = null;

public function getId(): ?int
{
return $this->id;
Expand Down Expand Up @@ -148,4 +151,16 @@ public function setPocketMoney(bool $pocketMoney): static

return $this;
}

public function getEffectiveOn(): ?DateTime
{
return $this->effectiveOn;
}

public function setEffectiveOn(?DateTime $effectiveOn): static
{
$this->effectiveOn = $effectiveOn;

return $this;
}
}
8 changes: 6 additions & 2 deletions src/Factory/EarningFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use App\Entity\Transaction;
use App\Entity\User;
use DateTime;
use Zenstruck\Foundry\ModelFactory;

/**
Expand All @@ -26,23 +27,25 @@ protected static function getClass(): string
return Transaction::class;
}

public static function createPocketMoney(User $user): Transaction
public static function createPocketMoney(User $user, ?DateTime $effectiveOn = null): Transaction
{
$pocketMoney = new Transaction();
$pocketMoney
->setPocketMoney(true)
->setUser($user)
->setEffectiveOn($effectiveOn)
->setTitle('Pocket Money')
->setApplied(true)
->setValue($user->getAllowance());
return $pocketMoney;
}

public function pocketMoney(User $user): self
public function pocketMoney(User $user, ?DateTime $effectiveOn): self
{
return $this->addState([
'title' => 'Pocket Money',
'pocketMoney' => true,
'effectiveOn' => $effectiveOn,
'category' => CategoryFactory::find(['name' => 'Pocket Money']),
'applied' => true,
'user' => $user,
Expand All @@ -59,6 +62,7 @@ protected function getDefaults(): array
'applied' => false,
'title' => self::faker()->realText(80),
'user' => UserFactory::random(),
'effectiveOn' => null,
'pocketMoney' => true,
'category' => CategoryFactory::find(['name' => 'Pocket Money']),
'value' => self::faker()->numberBetween(100, 1000),
Expand Down
7 changes: 7 additions & 0 deletions src/Factory/UserFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ public function nextPaydayYesterday(): self
]);
}

public function nextPaydayTwoWeeksAgo(): self
{
return $this->addState([
'nextPayday' => new DateTime('-12 days'),
]);
}

public function tracked(): self
{
return $this->addState(['tracked' => true]);
Expand Down
70 changes: 65 additions & 5 deletions tests/Api/OverviewControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,13 @@
namespace App\Tests\Api;

use ApiPlatform\Symfony\Bundle\Test\ApiTestCase;
use App\Entity\Transaction;
use App\Entity\User;
use App\Factory\UserFactory;
use App\Repository\TransactionRepository;
use App\Repository\UserRepository;
use App\Story\UserWithOutstandingPocketMoneyStory;
use DateTime;

class OverviewControllerTest extends ApiTestCase
{
Expand Down Expand Up @@ -37,10 +42,21 @@ public function setUpUser()
$this->entityManager->flush();
}

private function getUserRepository(): UserRepository
{
return $this->entityManager->getRepository(User::class);
}

private function getTransactionRepository(): TransactionRepository
{
return $this->entityManager->getRepository(Transaction::class);
}

public function testGetOverviewUpdatesNextPayDay(): void
{
UserWithOutstandingPocketMoneyStory::load();
$userRepository = $this->entityManager->getRepository(User::class);
$userRepository = $this->getUserRepository();

$users = $userRepository->findTrackedUsers();

$this->assertEquals(1, count($users));
Expand All @@ -50,22 +66,66 @@ public function testGetOverviewUpdatesNextPayDay(): void

// Use Symfony's test client to make a request to your endpoint
$client = static::createClient();
$client->request('GET', '/api/overview/'.$userId.'.json'); // Adjust this URL to your routing setup
$client->request('GET', '/api/overview/' . $userId . '.json');

// Fetch updated user from the database
$this->entityManager->clear(User::class);
$updatedUser = $this->entityManager->getRepository(User::class)->find($userId);

$updatedUser = $userRepository->find($userId);

// Assertions
$this->assertNotEquals(
expected: $user->getNextPayday(),
actual: $updatedUser->getNextPayday(),
expected: $user->getNextPayday()->format("d"),
actual: $updatedUser->getNextPayday()->format("d"),
message: "The nextPayday should have been updated."
);
$this->assertEquals(
expected: 6,
actual: $user->getNextPayday()->diff($updatedUser->getNextPayday())->days,
message: "The nextPayday should be 6 days later."
);
$this->assertEquals(1000, $updatedUser->getBalance());
}

public function testGetOverviewUpdatesMultiplePayDays(): void
{
$allowance = 1000;
UserFactory::new()
->tracked()
->withAllowance($allowance)
->nextPaydayTwoWeeksAgo()
->create();

$userRepository = $this->entityManager->getRepository(User::class);
$users = $userRepository->findTrackedUsers();
$this->assertEquals(1, count($users));

$user = $users[0];
$userId = $user->getId();

// Use Symfony's test client to make a request to your endpoint
$client = static::createClient();
$client->request('GET', '/api/overview/' . $userId . '.json');

// Fetch updated user from the database
$this->entityManager->clear(User::class);

$updatedUser = $userRepository->find($userId);

// Assertions
$this->assertNotEquals(
expected: $user->getNextPayday()->format("d"),
actual: $updatedUser->getNextPayday()->format("d"),
message: "The nextPayday should have been updated."
);
$this->assertEquals(2000, $updatedUser->getBalance());

$transactions = $this->getTransactionRepository()->findAll();
$this->assertCount(2, $transactions);

$firstPayday = (new DateTime('-12 days'))->format("d");
$this->assertEquals($firstPayday, $transactions[0]->getEffectiveOn()->format("d"));
$secondPayday = (new DateTime('-5 days'))->format("d");
$this->assertEquals($secondPayday, $transactions[1]->getEffectiveOn()->format("d"));
}
}

0 comments on commit 23b84f1

Please sign in to comment.