Skip to content

Instantly share code, notes, and snippets.

@mirahtadi
Created March 18, 2016 06:47
Show Gist options
  • Save mirahtadi/b0c532d5d381f690bf61 to your computer and use it in GitHub Desktop.
Save mirahtadi/b0c532d5d381f690bf61 to your computer and use it in GitHub Desktop.
Transaction History
<?php
namespace App\Bundle\TransactionBundle\Subscriber;
use App\Bundle\TransactionBundle\Entity\TransactionHistory;
use App\Bundle\TransactionBundle\Event\TransactionHistoryEvent;
use App\Bundle\TransactionBundle\Manager\TransactionHistoryManager;
use App\Bundle\TransactionBundle\TransactionHistoryEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class TransactionHistorySubscriber implements EventSubscriberInterface
{
#----------------------------------------------------------------------------------------------
# Private Constants
#----------------------------------------------------------------------------------------------
const TRANSACTION_CREATE = 'Create';
const TRANSACTION_UPDATE = 'Update';
const TRANSACTION_DELETE = 'Delete';
#-------------------------------------------------------------------------------------------------------------------
# Properties
#-------------------------------------------------------------------------------------------------------------------
/**
* @var TransactionHistoryManager
*/
private $transactionHistoryManager;
#-------------------------------------------------------------------------------------------------------------------
# Public methods
#-------------------------------------------------------------------------------------------------------------------
/**
* @inheritdoc
*/
public static function getSubscribedEvents()
{
return [
TransactionHistoryEvents::DELETED => 'addHistoryDelete',
TransactionHistoryEvents::UPDATED => 'addHistoryUpdate',
TransactionHistoryEvents::CREATED => 'addHistoryCreate'
];
}
/**
* Creates new history
* @param TransactionHistoryEvent $event
*/
public function addHistoryUpdate(TransactionHistoryEvent $event, TransactionHistory $transactionHistory)
{
$transactionHistory->setMessage('User updated data')
->setType(TransactionHistorySubscriber::TRANSACTION_UPDATE)
->setUser($event->getUser())
->setTransaction($event->getTransaction());
$this->transactionHistoryManager->save($transactionHistory);
}
}
<?php
namespace App\Bundle\TransactionBundle\Manager;
use App\Bundle\ProductBundle\Filter\ProductCategoryFilter;
use App\Bundle\ProductBundle\Repository\ProductCategoryRepository;
use App\Bundle\ProductBundle\Repository\ProductRepository;
use App\Bundle\ReportBundle\Filter\ReportFilter;
use App\Bundle\TransactionBundle\Entity\PaymentType;
use App\Bundle\TransactionBundle\Event\TransactionHistoryEvent;
use App\Bundle\TransactionBundle\Filter\TransactionFilter;
use App\Bundle\TransactionBundle\Repository\PaymentNoteRepository;
use App\Bundle\TransactionBundle\Repository\PaymentTypeRepository;
use App\Bundle\TransactionBundle\Repository\TransactionPaymentRepository;
use App\Bundle\TransactionBundle\Repository\TransactionRepository;
use App\Bundle\MainBundle\Exception\ValidationFailedException;
use App\Bundle\TransactionBundle\Entity\Transaction;
use App\Bundle\TransactionBundle\TransactionHistoryEvents;
use Symfony\Component\Validator\Validator\ValidatorInterface;
class TransactionManager
{
#----------------------------------------------------------------------------------------------
# Properties
#----------------------------------------------------------------------------------------------
/**
* @var TransactionRepository
*/
private $repository;
/**
* @var ValidatorInterface
*/
private $validator;
/**
* @var TransactionProductManager
*/
private $transactionProductManager;
/**
* @var ProductCategoryRepository
*/
private $productCategoryRepository;
/**
* @var ProductRepository
*/
private $productRepository;
/**
* @var PaymentTypeRepository
*/
private $paymentTypeRepository;
/**
* @var TransactionPaymentManager
*/
private $transactionPaymentManager;
/**
* @var PaymentNoteManager
*/
private $paymentNoteManager;
/**
* @var PaymentNoteRepository
*/
private $paymentNoteRepository;
/**
* @var TransactionPaymentRepository
*/
private $transactionPaymentRepository;
/**
* @var EventDispatcherInterface
*/
private $eventDispatcher;
#----------------------------------------------------------------------------------------------
# Magic methods
#----------------------------------------------------------------------------------------------
/**
* @param TransactionRepository $repository
* @param ValidatorInterface $validator
* @param TransactionProductManager $transactionProductManager
* @param ProductCategoryRepository $productCategoryRepository
* @param ProductRepository $productRepository
* @param PaymentTypeRepository $paymentTypeRepository
* @param PaymentNoteRepository $paymentNoteRepository
* @param TransactionPaymentManager $transactionPaymentManager
* @param PaymentNoteManager $paymentNoteManager
* @param EventDispatcherInterface $eventDispatcher
*/
public function __construct(
TransactionRepository $repository,
ValidatorInterface $validator,
TransactionProductManager $transactionProductManager,
ProductCategoryRepository $productCategoryRepository,
ProductRepository $productRepository,
PaymentTypeRepository $paymentTypeRepository,
PaymentNoteRepository $paymentNoteRepository,
TransactionPaymentManager $transactionPaymentManager,
PaymentNoteManager $paymentNoteManager,
TransactionPaymentRepository $transactionPaymentRepository,
EventDispatcherInterface $eventDispatcher
) {
$this->repository = $repository;
$this->validator = $validator;
$this->transactionProductManager = $transactionProductManager;
$this->productCategoryRepository = $productCategoryRepository;
$this->productRepository = $productRepository;
$this->paymentTypeRepository = $paymentTypeRepository;
$this->transactionPaymentManager = $transactionPaymentManager;
$this->paymentNoteManager = $paymentNoteManager;
$this->paymentNoteRepository = $paymentNoteRepository;
$this->transactionPaymentRepository = $transactionPaymentRepository;
$this->eventDispatcher = $eventDispatcher;
}
#----------------------------------------------------------------------------------------------
# Public methods
#----------------------------------------------------------------------------------------------
/**
* @param Transaction $transaction
* @throws ValidationFailedException
*/
public function save(Transaction $transaction)
{
if ($transaction->isDeleted() === null) {
$transaction->setDeleted(false);
}
$total = 0;
foreach ($transaction->getTransactionProducts() as $transactionProduct) {
$transactionProduct->setTransaction($transaction);
if ($transactionProduct->getDateTime() === null) {
$transactionProduct->setDateTime(new \Datetime());
}
$total += $transactionProduct->getTotal();
}
$totalPayment = 0;
foreach ($transaction->getTransactionPayments() as $transactionPayment) {
$transactionPayment->setTransaction($transaction);
$totalPayment += $transactionPayment->getAmount();
if ($transaction->getId() !== null && $transactionPayment->getId() === null) {
$transactionPayment->setPaymentOnly(true);
}
}
if ($totalPayment < $total) {
$transaction->setFullyPaid(false);
} else {
$transaction->setFullyPaid(true);
}
foreach ($transaction->getPaymentNotes() as $paymentNote) {
$paymentNote->setTransaction($transaction);
}
$transaction->setTotal($total);
if ($transaction->getAgent() !== null) {
$transaction->setCommission($transaction->getAgent()->getCommission());
}
$errors = $this->validator->validate($transaction);
if ($errors->count() > 0) {
throw new ValidationFailedException($errors);
}
$this->repository->save($transaction);
foreach ($transaction->getTransactionProducts() as $transactionProduct) {
$this->transactionProductManager->save($transactionProduct);
}
foreach ($transaction->getTransactionPayments() as $transactionPayment) {
$this->transactionPaymentManager->save($transactionPayment);
}
foreach ($transaction->getPaymentNotes() as $paymentNote) {
$this->paymentNoteManager->save($paymentNote);
}
$this->eventDispatcher
->dispatch(TransactionHistoryEvents::UPDATED,
new TransactionHistoryEvent($transaction));
}
/**
* @param Transaction $transaction
*/
public function softDelete(Transaction $transaction)
{
$transaction->setDeleted(true);
$this->save($transaction);
$this->eventDispatcher
->dispatch(TransactionHistoryEvents::DELETED,
new TransactionHistoryEvent($transaction));
}
/**
* @param ReportFilter $reportFilter
* @return array
*/
public function getRevenueReportByFilter(ReportFilter $reportFilter)
{
/** @var PaymentType[] $paymentTypes */
$paymentTypes = $this->paymentTypeRepository->findAll();
$productCategoryReport = $this->productCategoryRepository->getReportByFilter($reportFilter);
$categories = $this->productCategoryRepository->findAllByFilter(new ProductCategoryFilter());
$transactionFilter = new TransactionFilter();
$transactionFilter->setStartDate($reportFilter->getStartDate());
$transactionFilter->setEndDate($reportFilter->getEndDate());
$transactionFilter->setOutlet($reportFilter->getOutlet());
$i = 0;
// For each product category, get transactions and payment type summary
foreach ($productCategoryReport as &$productCategory) {
$transactionFilter->setProductCategory($categories[$i]);
$productCategory['transactions'] = $this->repository->findAllByFilter($transactionFilter);
foreach ($paymentTypes as $paymentType) {
$transactionFilter->setPaymentType($paymentType);
// Get payment type sum for each product category
$productCategory['payment_type'][$paymentType->getName()]
= $this->repository->getPaymentTypeSumByFilter($transactionFilter);
}
$i++;
}
$revenueReport['payment_only'] = $this->transactionPaymentRepository
->getPaymentOnlyReportByFilter($reportFilter);
$revenueReport['product_categories'] = $productCategoryReport;
$revenueReport['payment_types'] = $this->paymentTypeRepository->getReportTotalByFilter($reportFilter);
$revenueReport['payment_notes'] = $this->paymentNoteRepository->getReportTotalByFilter($reportFilter);
$revenueReport['products'] = $this->productRepository->getReportByFilter($reportFilter);
$revenueReport['products_total'] = $this->productRepository->getReportTotalByFilter($reportFilter);
return $revenueReport;
}
}
<?php
namespace App\Bundle\TransactionBundle\Tests\Unit\Manager;
use App\Bundle\TransactionBundle\Entity\Transaction;
use App\Bundle\TransactionBundle\Entity\TransactionProduct;
use App\Bundle\TransactionBundle\Manager\PaymentNoteManager;
use App\Bundle\TransactionBundle\Manager\TransactionManager;
use App\Bundle\TransactionBundle\Manager\TransactionPaymentManager;
use App\Bundle\TransactionBundle\Repository\PaymentNoteRepository;
use App\Bundle\TransactionBundle\Repository\TransactionPaymentRepository;
use App\Bundle\TransactionBundle\Repository\TransactionRepository;
use App\Bundle\TransactionBundle\TransactionHistoryEvents;
use Prophecy\Argument;
use Prophecy\Prophecy\ObjectProphecy;
use Prophecy\Prophecy\MethodProphecy;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Validator\ConstraintViolationListInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use App\Bundle\TransactionBundle\Manager\TransactionProductManager;
use App\Bundle\ProductBundle\Repository\ProductCategoryRepository;
use App\Bundle\ProductBundle\Repository\ProductRepository;
use App\Bundle\TransactionBundle\Repository\PaymentTypeRepository;
class TransactionManagerTest extends \PHPUnit_Framework_TestCase
{
#----------------------------------------------------------------------------------------------
# Properties
#----------------------------------------------------------------------------------------------
/**
* @var TransactionManager
*/
private $manager;
/**
* @var ObjectProphecy|TransactionRepository
*/
private $repository;
/**
* @var ObjectProphecy|ValidatorInterface
*/
private $validator;
/**
* @var MethodProphecy|EventDispatcherInterface
*/
private $eventDispatcher;
/**
* @var ObjectProphecy|TransactionProductManager
*/
private $transactionProductManager;
/**
* @var ObjectProphecy|PaymentNoteManager
*/
private $paymentNoteManager;
/**
* @var ObjectProphecy|TransactionPaymentManager
*/
private $transactionPaymentManager;
/**
* @var ObjectProphecy|ProductCategoryRepository
*/
private $productCategoryRepository;
/**
* @var ObjectProphecy|ProductRepository
*/
private $productRepository;
/**
* @var ObjectProphecy|PaymentTypeRepository
*/
private $paymentTypeRepository;
/**
* @var ObjectProphecy|PaymentNoteRepository
*/
private $paymentNoteRepository;
/**
* @var ObjectProphecy|Transaction
*/
private $transaction;
/**
* @var ObjectProphecy|TransactionProduct
*/
private $transactionProduct;
/**
* @var ObjectProphecy|ConstraintViolationListInterface
*/
private $violationList;
/**
* @var TransactionPaymentRepository
*/
private $transactionPaymentRepository;
#----------------------------------------------------------------------------------------------
# Public methods
#----------------------------------------------------------------------------------------------
/**
* @group unit
*/
public function testSave()
{
$this->violationList->count()->shouldBeCalledTimes(1)->willReturn(0);
$this->transaction->isDeleted()->shouldBeCalledTimes(1)->willReturn(null);
$this->transaction->setDeleted(false)->shouldBeCalledTimes(1);
$this->transaction->setFullyPaid(true)->shouldBeCalledTimes(1);
$this->transaction->getTransactionProducts()->shouldBeCalledTimes(2)
->willReturn($this->transactionProduct->setTransaction($this->transactionProduct->reveal()));
$this->transaction->getTransactionPayments()->shouldBeCalledTimes(2)
->willReturn($this->prophesize(array()));
$this->transaction->getPaymentNotes()->shouldBeCalledTimes(2)
->willReturn($this->prophesize(array()));
$this->transaction->setTotal(0)->shouldBeCalledTimes(1);
$this->transaction->getAgent()->shouldBeCalledTimes(1);
$this->validator->validate($this->transaction->reveal())
->shouldBeCalledTimes(1)->willReturn($this->violationList->reveal());
$this->repository->save($this->transaction->reveal())
->shouldBeCalledTimes(1);
$this->manager->save($this->transaction->reveal());
}
/**
* @group unit
*/
public function testSoftDelete()
{
$this->transaction->setDeleted(true)->shouldBeCalledTimes(1);
$this->transaction->setDeleted(false)->shouldNotBeCalled();
$this->transaction->isDeleted()->shouldBeCalledTimes(1)->willReturn(false);
$this->transaction->setFullyPaid(true)->shouldBeCalledTimes(1);
$this->transaction->getTransactionProducts()->shouldBeCalledTimes(2)
->willReturn($this->transactionProduct->setTransaction($this->transactionProduct->reveal()));
$this->transaction->getTransactionPayments()->shouldBeCalledTimes(2)
->willReturn($this->prophesize(array()));
$this->transaction->getPaymentNotes()->shouldBeCalledTimes(2)
->willReturn($this->prophesize(array()));
$this->transaction->setTotal(0)->shouldBeCalledTimes(1);
$this->transaction->getAgent()->shouldBeCalledTimes(1);
$this->validator->validate($this->transaction->reveal())
->shouldBeCalledTimes(1)->willReturn($this->violationList->reveal());
$this->repository->save($this->transaction->reveal())
->shouldBeCalledTimes(1);
$this->manager->softDelete($this->transaction->reveal());
}
#----------------------------------------------------------------------------------------------
# Protected methods
#----------------------------------------------------------------------------------------------
/**
* {@inheritdoc}
*/
protected function setUp()
{
$this->repository = $this->prophesize(TransactionRepository::class);
$this->validator = $this->prophesize(ValidatorInterface::class);
$this->transactionProductManager = $this->prophesize(TransactionProductManager::class);
$this->productCategoryRepository = $this->prophesize(ProductCategoryRepository::class);
$this->productRepository = $this->prophesize(ProductRepository::class);
$this->paymentTypeRepository = $this->prophesize(PaymentTypeRepository::class);
$this->paymentNoteRepository = $this->prophesize(PaymentNoteRepository::class);
$this->paymentNoteManager = $this->prophesize(PaymentNoteManager::class);
$this->transactionPaymentManager = $this->prophesize(TransactionPaymentManager::class);
$this->transactionPaymentRepository = $this->prophesize(TransactionPaymentRepository::class);
$this->eventDispatcher = $this->prophesize(EventDispatcherInterface::class);
$this->transaction = $this->prophesize(Transaction::class);
$this->transactionProduct = $this->prophesize(TransactionProduct::class);
$this->violationList = $this->prophesize(ConstraintViolationListInterface::class);
$this->manager = new TransactionManager(
$this->repository->reveal(), $this->validator->reveal(),
$this->transactionProductManager->reveal(),
$this->productCategoryRepository->reveal(),
$this->productRepository->reveal(),
$this->paymentTypeRepository->reveal(),
$this->paymentNoteRepository->reveal(),
$this->transactionPaymentManager->reveal(),
$this->paymentNoteManager->reveal(),
$this->transactionPaymentRepository->reveal(),
$this->eventDispatcher->getListeners(TransactionHistoryEvents::DELETED,
TransactionHistoryEvents::CREATED,
TransactionHistoryEvents::UPDATED)
);
}
}
@gusdecool
Copy link

change

#TransactionManagerTest.php:212
$this->eventDispatcher->getListeners(TransactionHistoryEvents::DELETED,
                TransactionHistoryEvents::CREATED,
                TransactionHistoryEvents::UPDATED)

#change to
$this->eventDispatcher->reveal();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment