kna / accounting-bundle
This Bundle provides event-driven accounting implementation
Installs: 1
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 2
Forks: 0
Open Issues: 0
Type:symfony-bundle
Requires
- php: ^7.2
- kna/money-bundle: ^1.0
- moneyphp/money: ^3.2
- symfony/framework-bundle: >=4.0 <5.0
- symfony/translation: >=4.0 <5.0
Requires (Dev)
- doctrine/doctrine-bundle: ^1.11
- doctrine/orm: ^2.6
Suggests
- doctrine/doctrine-bundle: For integration with Doctrine
- doctrine/orm: For integration with Doctrine ORM
This package is auto-updated.
Last update: 2024-12-17 23:11:28 UTC
README
This Bundle provides event-driven accounting implementation.
Installation
composer require kna/accounting-bundle
Configuring
Add config
// config/packages/kna_accounting.yaml kna_accounting: account: class: App\Entity\Account # default entry: class: App\Entity\Entry # default event: class: App\Entity\Event # default discriminator_type: string #default discriminator_name: type #default discriminator_length: 255 #default discriminator_map: payment: App\Entity\PaymentEvent sale: App\Entity\SaleEvent
Create base entities
Account:
<?php namespace App\Entity; use Doctrine\ORM\Mapping as ORM; use Kna\AccountingBundle\Entity\BaseAccount; class Account extends BaseAccount { /** * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") */ protected $id; }
Entry:
<?php namespace App\Entity; use Doctrine\ORM\Mapping as ORM; use Kna\AccountingBundle\Entity\BaseEntry; class Base extends BaseEntry { /** * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") */ protected $id; }
Event:
<?php namespace App\Entity; use Doctrine\ORM\Mapping as ORM; use Kna\AccountingBundle\Entity\BaseEvent; abstract class Event extends BaseEvent { /** * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") */ protected $id; }
Create events
For example:
<?php namespace App\Entity; use Doctrine\ORM\Mapping as ORM; class PaymentEvent extends Event { /** * @ORM\ManyToOne(targetEntity="Account") */ protected $account; }
and
<?php namespace App\Entity; use Doctrine\ORM\Mapping as ORM; class SaleEvent extends Event { /** * @ORM\ManyToOne(targetEntity="Order") */ protected $order; }
Create event provider
<?php namespace App\Accounting; use App\Entity\Payment; use App\Entity\Order; use App\Entity\PaymentEvent; use App\Entity\SaleEvent; use Money\Currency; use Money\Money; use Kna\AccountingBundle\Accounting\BaseEventProvider; class DefaultEventProvider extends BaseEventProvider { /** * {@inheritDoc} */ public function supports($source): bool { return $source instanceof Payment || $source instanceof Order ; } /** * {@inheritDoc} */ public function createEvents($source): \Generator { if ($source instanceof Payment) { $event = new PaymentEvent(); $event->setAmount(new Money($source->getAmount(), new Currency($source->getCurrency()))); $event->setAccount($source->getAccount()); $event->setOccurredAt(new \DateTime()); $event->setNoticedAt(new \DateTime()); yield $event; } elseif ($source instanceof Order) { $event = new SaleEvent(); $event->setAmount(new Money($source->getAmount(), new Currency($source->getCurrency()))); $event->setOrder($source); $event->setOccurredAt(new \DateTime()); $event->setNoticedAt(new \DateTime()); yield $event; } } }
Create entry provider
<?php namespace App\Accounting; use App\Entity\PaymentEvent; use App\Entity\SaleEvent; use Kna\AccountingBundle\Model\EventInterface; use Kna\AccountingBundle\Accounting\BaseEventProvider; class DefaultEntryProvider extends BaseEntryProvider { /** * {@inheritDoc} */ public function supports($source): bool { return $source instanceof PaymentEvent || $source instanceof SaleEvent ; } /** * {@inheritDoc} */ public function createEntries(EventInterface $event): \Generator { if ($event instanceof PaymentEvent) { $entry = $this->createEntry(); $entry->setAccount($event->getAccount()); $entry->setAmount($event->getAmount()); $entry->setDescription($this->translator->trans('event.payment.description', ['%event%' => (string) $event])); yield $entry; } elseif ($event instanceof SaleEvent) { $entry = $this->createEntry(); $entry->setAccount($event->getOrder()->getAccount()); $entry->setAmount($event->getAmount()->negative()); $entry->setDescription($this->translator->trans('event.sale.description', ['%event%' => (string) $event, '%order%' => $event->getOrder()->getId()])); yield $entry; } } }
Usage
Use event manager
<?php namespace App\Controller; use App\Entity\Order; use Kna\AccountingBundle\Accounting\EventManager; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; class DefaultController extends AbstractController { /** * @var EventManager */ protected $eventManager; public function __construct(EventManager $eventManager) { $this->eventManager = $eventManager; } public function index(): Response { $order = new Order(); $this->eventManager->processSource($order); } }
Use event processing command
php bin/console kna_accounting:process-events --loop