Skip to content

Commit

Permalink
Apply value of transactions to the user's balance when they are applied
Browse files Browse the repository at this point in the history
- Create Entity for Avatars
- Create Entity for Category
  • Loading branch information
Macavity committed Aug 5, 2023
1 parent 3211f6f commit bb30177
Show file tree
Hide file tree
Showing 28 changed files with 770 additions and 61 deletions.
3 changes: 2 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Editor configuration, see http://editorconfig.org
root = true


[*]
charset = utf-8
indent_style = space
Expand All @@ -9,7 +10,7 @@ insert_final_newline = true
trim_trailing_whitespace = true
max_line_length = off

[*.php,*.ts]
[*.{php,ts}]
indent_size = 4

[{*.html,*.html.twig}]
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,4 @@ Thumbs.db
/.phpcs-cache
###< squizlabs/php_codesniffer ###
public/build
.fleet
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
"php:stan": [
"@putenv APP_DEBUG=true",
"@php bin/console cache:warmup --env=dev",
"@php vendor/bin/phpstan analyze src --level=2 --configuration=extension.neon",
"@php vendor/bin/phpstan analyze src --level=5 --configuration=extension.neon",
"@php bin/console cache:clear --env=dev"
],
"php:tests": [
Expand Down
9 changes: 7 additions & 2 deletions config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,10 @@ services:
- '../src/Entity/'
- '../src/Kernel.php'

# add more service definitions when explicit configuration is needed
# please note that last definitions always *replace* previous ones
App\EventListener\TransactionListener:
tags:
- { name: doctrine.event_listener, event: preUpdate }

App\EventListener\UpdateBalanceSubscriber:
tags:
- { name: doctrine.event_subscriber }
5 changes: 5 additions & 0 deletions docker/server/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ RUN a2enmod rewrite

RUN apt-get update && apt-get install -y git unzip zip

# Add Symfony CLI
RUN apk add --no-cache bash
RUN curl -1sLf 'https://dl.cloudsmith.io/public/symfony/stable/setup.alpine.sh' | sudo -E bash
RUN apk add symfony-cli

WORKDIR /var/www/html

COPY --from=mlocati/php-extension-installer /usr/bin/install-php-extensions /usr/local/bin/
Expand Down
45 changes: 45 additions & 0 deletions migrations/Version20230804194352.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?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 Version20230804194352 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('CREATE TABLE avatar (id INT AUTO_INCREMENT NOT NULL, url VARCHAR(255) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB');
$this->addSql('CREATE TABLE category (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB');
$this->addSql('ALTER TABLE transaction ADD category_id INT DEFAULT NULL, DROP type');
$this->addSql('ALTER TABLE transaction ADD CONSTRAINT FK_723705D112469DE2 FOREIGN KEY (category_id) REFERENCES category (id)');
$this->addSql('CREATE INDEX IDX_723705D112469DE2 ON transaction (category_id)');
$this->addSql('ALTER TABLE user ADD avatar_id INT DEFAULT NULL, DROP avatar');
$this->addSql('ALTER TABLE user ADD CONSTRAINT FK_8D93D64986383B10 FOREIGN KEY (avatar_id) REFERENCES avatar (id)');
$this->addSql('CREATE INDEX IDX_8D93D64986383B10 ON user (avatar_id)');
}

public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE user DROP FOREIGN KEY FK_8D93D64986383B10');
$this->addSql('ALTER TABLE transaction DROP FOREIGN KEY FK_723705D112469DE2');
$this->addSql('DROP TABLE avatar');
$this->addSql('DROP TABLE category');
$this->addSql('DROP INDEX IDX_8D93D64986383B10 ON user');
$this->addSql('ALTER TABLE user ADD avatar VARCHAR(255) DEFAULT NULL, DROP avatar_id');
$this->addSql('DROP INDEX IDX_723705D112469DE2 ON transaction');
$this->addSql('ALTER TABLE transaction ADD type SMALLINT NOT NULL, DROP category_id');
}
}
24 changes: 24 additions & 0 deletions src/Controller/Admin/AvatarCrudController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace App\Controller\Admin;

use App\Entity\Avatar;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Field\IdField;
use EasyCorp\Bundle\EasyAdminBundle\Field\UrlField;

class AvatarCrudController extends AbstractCrudController
{
public static function getEntityFqcn(): string
{
return Avatar::class;
}

public function configureFields(string $pageName): iterable
{
yield IdField::new('id')->hideOnForm();
yield UrlField::new('url');
}
}
24 changes: 24 additions & 0 deletions src/Controller/Admin/CategoryCrudController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace App\Controller\Admin;

use App\Entity\Category;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Field\IdField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;

class CategoryCrudController extends AbstractCrudController
{
public static function getEntityFqcn(): string
{
return Category::class;
}

public function configureFields(string $pageName): iterable
{
yield IdField::new('id')->hideOnForm();
yield TextField::new('name');
}
}
8 changes: 7 additions & 1 deletion src/Controller/Admin/DashboardController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
namespace App\Controller\Admin;

use _PHPStan_d55c4f2c2\Nette\Neon\Exception;
use App\Entity\Avatar;
use App\Entity\Category;
use App\Entity\Transaction;
use App\Entity\User;
use EasyCorp\Bundle\EasyAdminBundle\Config\Dashboard;
Expand Down Expand Up @@ -35,8 +37,12 @@ public function configureMenuItems(): iterable
{
yield MenuItem::linkToUrl('App', 'fas fa-home', $this->generateUrl('app_home'));
yield MenuItem::linkToDashboard('Dashboard', 'fa fa-dashboard');
yield MenuItem::section('User');
yield MenuItem::linkToCrud('User', 'fa-solid fa-user', User::class);
yield MenuItem::linkToCrud('Transaction', 'fa-solid fa-money-bill-transfer', Transaction::class);
yield MenuItem::section('General');
yield MenuItem::linkToCrud('Avatar', 'fa-solid fa-image', Avatar::class);
yield MenuItem::linkToCrud('Category', 'fa-solid fa-list', Category::class);
}

/**
Expand All @@ -48,6 +54,6 @@ public function configureUserMenu(UserInterface $user): UserMenu
throw new Exception('Invalid User Entity');
}

return parent::configureUserMenu($user)->setAvatarUrl($user->getAvatar());
return parent::configureUserMenu($user)->setAvatarUrl($user->getAvatar()->getUrl());
}
}
6 changes: 5 additions & 1 deletion src/Controller/Admin/TransactionCrudController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use App\Entity\Transaction;
use App\Enum\TransactionType;
use App\Trait\HasCurrencyFormatter;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
use EasyCorp\Bundle\EasyAdminBundle\Field\BooleanField;
Expand All @@ -16,6 +17,8 @@

class TransactionCrudController extends AbstractCrudController
{
use HasCurrencyFormatter;

public static function getEntityFqcn(): string
{
return Transaction::class;
Expand All @@ -26,6 +29,7 @@ public function configureFields(string $pageName): iterable
yield IdField::new('id')->hideOnForm();
yield TextField::new('title');
yield AssociationField::new('user');
yield AssociationField::new('category');
yield ChoiceField::new('type')
->setChoices([
'+' => TransactionType::EARNING,
Expand All @@ -37,7 +41,7 @@ public function configureFields(string $pageName): iterable
]);
yield BooleanField::new('applied');
yield NumberField::new('value')->formatValue(function ($value) {
return (intval($value)/100).'';
return $this->formatCurrency($value);
});
}
}
13 changes: 12 additions & 1 deletion src/Controller/Admin/UserCrudController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,21 @@
namespace App\Controller\Admin;

use App\Entity\User;
use App\Trait\HasCurrencyFormatter;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Field\ArrayField;
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
use EasyCorp\Bundle\EasyAdminBundle\Field\AvatarField;
use EasyCorp\Bundle\EasyAdminBundle\Field\BooleanField;
use EasyCorp\Bundle\EasyAdminBundle\Field\EmailField;
use EasyCorp\Bundle\EasyAdminBundle\Field\IdField;
use EasyCorp\Bundle\EasyAdminBundle\Field\NumberField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;

class UserCrudController extends AbstractCrudController
{
use HasCurrencyFormatter;

public static function getEntityFqcn(): string
{
return User::class;
Expand All @@ -24,9 +29,15 @@ public function configureFields(string $pageName): iterable
{
yield IdField::new('id')->hideOnForm();
yield TextField::new('name');
yield AvatarField::new('avatar');
yield AvatarField::new('avatarUrl')->hideOnForm();
yield AssociationField::new('avatar')->hideOnIndex();
yield EmailField::new('email');
yield ArrayField::new('roles');
yield BooleanField::new('tracked');
yield NumberField::new('balance')
->hideOnForm()
->formatValue(function ($value) {
return $this->formatCurrency($value);
});
}
}
78 changes: 68 additions & 10 deletions src/DataFixtures/AppFixtures.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,90 @@

namespace App\DataFixtures;

use App\Factory\TransactionFactory;
use App\Entity\Avatar;
use App\Entity\Category;
use App\Factory\AvatarFactory;
use App\Factory\CategoryFactory;
use App\Factory\EarningFactory;
use App\Factory\ExpenseFactory;
use App\Factory\UserFactory;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
use Zenstruck\Foundry\Proxy;

class AppFixtures extends Fixture
{
private Category|Proxy $catSpent;
private Category|Proxy $catEarn;
private Proxy|Avatar $avatarMale;
private Proxy|Avatar $avatarFemale;

public function __construct()
{
}

public function load(ObjectManager $manager): void
{
$this->loadAvatars();
$this->loadCategories();
$this->loadUsers();
$this->loadAdmin($manager);
}

public function loadAvatars(): void
{
$this->avatarFemale = AvatarFactory::createOne([
'url' => '/assets/images/avatar_female.png',
]);
$this->avatarMale = AvatarFactory::createOne([
'url' => '/assets/images/avatar_male.png',
]);
}

UserFactory::createMany(2);
public function loadCategories(): void
{
$this->catEarn = CategoryFactory::createOne([
'name' => 'Pocket Money',
]);
$this->catSpent = CategoryFactory::createOne([
'name' => 'Expense',
]);
}

TransactionFactory::createMany(
10,
function () {
return [
'user' => UserFactory::random(),
];
},
public function loadUsers(): void
{
$this->loadUserWithTransactions($this->avatarMale);
$this->loadUserWithTransactions($this->avatarFemale);
}

/**
* @param Proxy<Avatar>|Avatar $avatar
* @return void
*/
public function loadUserWithTransactions(Proxy|Avatar $avatar): void
{
$user = UserFactory::createOne([
'avatar' => $avatar,
'tracked' => true
]);

EarningFactory::createOne([
'user' => $user,
'category' => $this->catEarn,
'value' => 3000,
]);

ExpenseFactory::createMany(
5,
[
'user' => $user,
'category' => $this->catSpent,
]
);
}

// Create admin afterwards, so it doesn't get transactions
public function loadAdmin(ObjectManager $manager): void
{
$admin = UserFactory::new()->admin($_ENV['ADMIN_PASSWORD'])->create()
->setEmail($_ENV['ADMIN_MAIL'])
->setName('Admin');
Expand Down
Loading

0 comments on commit bb30177

Please sign in to comment.