Skip to content

Commit

Permalink
Merge pull request #4 from Zales0123/refunding-single-unit
Browse files Browse the repository at this point in the history
Refunding single unit
  • Loading branch information
GSadee authored Jul 10, 2018
2 parents 10d5734 + 66f2ec0 commit 2ea3c76
Show file tree
Hide file tree
Showing 57 changed files with 1,534 additions and 88 deletions.
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@
composer require sylius/refund-plugin
```

2. Add plugin class to your `AppKernel`:
2. Add plugin class and other required bundles to your `AppKernel`:

```php
$bundles = [
new \Sylius\RefundPlugin\SyliusRefundPlugin(),
new Prooph\Bundle\ServiceBus\ProophServiceBusBundle(),
new \Sylius\RefundPlugin\SyliusRefundPlugin(),
];
```

Expand All @@ -30,12 +31,11 @@
imports:
- { resource: "@SyliusRefundPlugin/Resources/config/app/config.yml" }
```
4. Import routing:
````yaml
sylius_refund:
resource: "@SyliusRefundPlugin/Resources/config/app/routing.yml"
resource: "@SyliusRefundPlugin/Resources/config/routing.yml"
````
5. Clear cache:
Expand All @@ -44,3 +44,5 @@
bin/console cache:clear
```
6. Copy migrations from `vendor/sylius/refund-plugin/migrations/`
to your migrations directory and run `bin/console doctrine:migrations:migrate`
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"php": "^7.2",

"sylius/sylius": "^1.2",
"symfony/symfony": "^3.4|^4.1"
"symfony/symfony": "^3.4|^4.1",
"prooph/service-bus-symfony-bundle": "^0.7.0"
},
"require-dev": {
"behat/behat": "^3.4",
Expand Down
2 changes: 2 additions & 0 deletions easy-coding-standard.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
imports:
- { resource: 'vendor/sylius-labs/coding-standard/easy-coding-standard.yml' }
16 changes: 11 additions & 5 deletions features/refunding_single_order_unit.feature
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,17 @@ Feature: Refunding a single order unit
When I want to refund some units of order "#00000022"
Then I should be able to refund 2 "Mr. Meeseeks T-Shirt" products

@ui @todo
@ui @application
Scenario: Refunding one of the order unit
When I want to refund some units of order "#00000022"
And I decide to refund 1st "Mr. Meeseeks T-Shirt" product
Then I should be notified that order unit has been successfully refunded
And refunded total should be "$10"
And I should not be able to refund 1st "Mr. Meeseeks T-Shirt" product
But I should still be able to refund 2nd "Mr. Meeseeks T-Shirt" product
Then I should be notified that selected order units have been successfully refunded
And this order refunded total should be "$10.00"
And I should not be able to refund 1st unit with product "Mr. Meeseeks T-Shirt"
But I should still be able to refund 2nd unit with product "Mr. Meeseeks T-Shirt"

@ui
Scenario: Not being able to refund 0 units
When I want to refund some units of order "#00000022"
And I refund zero items
Then I should be notified that at least one unit should be selected to refund
27 changes: 27 additions & 0 deletions migrations/Version20180704112314.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace Application\Migrations;

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

final class Version20180704112314 extends AbstractMigration
{
public function up(Schema $schema) : void
{
// this up() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'sqlite', 'Migration can only be executed safely on \'mysql\'.');

$this->addSql('CREATE TABLE sylius_refund_refund (id INTEGER NOT NULL, orderNumber VARCHAR(255) NOT NULL, amount INTEGER NOT NULL, refundedItemId INTEGER DEFAULT NULL, PRIMARY KEY(id))');
}

public function down(Schema $schema) : void
{
// this down() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'sqlite', 'Migration can only be executed safely on \'mysql\'.');

$this->addSql('DROP TABLE sylius_refund_refund');
}
}
6 changes: 3 additions & 3 deletions phpspec.yml.dist
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
suites:
main:
namespace: Acme\SyliusExamplePlugin
psr4_prefix: Acme\SyliusExamplePlugin
sylius_refund:
namespace: Sylius\RefundPlugin
psr4_prefix: Sylius\RefundPlugin
39 changes: 39 additions & 0 deletions spec/Checker/UnitRefundingAvailabilityCheckerSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

declare(strict_types=1);

namespace spec\Sylius\RefundPlugin\Checker;

use PhpSpec\ObjectBehavior;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Sylius\RefundPlugin\Checker\UnitRefundingAvailabilityCheckerInterface;
use Sylius\RefundPlugin\Entity\RefundInterface;

final class UnitRefundingAvailabilityCheckerSpec extends ObjectBehavior
{
function let(RepositoryInterface $refundRepository): void
{
$this->beConstructedWith($refundRepository);
}

function it_implements_unit_refunding_availability_checker_interface(): void
{
$this->shouldImplement(UnitRefundingAvailabilityCheckerInterface::class);
}

function it_returns_true_if_refund_for_given_unit_does_not_already_exist(RepositoryInterface $refundRepository): void
{
$refundRepository->findOneBy(['refundedUnitId' => 1])->willReturn(null);

$this->__invoke(1)->shouldReturn(true);
}

function it_returns_false_if_refund_for_given_unit_does_not_already_exist(
RepositoryInterface $refundRepository,
RefundInterface $refund
): void {
$refundRepository->findOneBy(['refundedUnitId' => 1])->willReturn($refund);

$this->__invoke(1)->shouldReturn(false);
}
}
18 changes: 18 additions & 0 deletions spec/Command/RefundUnitsSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace spec\Sylius\RefundPlugin\Command;

use PhpSpec\ObjectBehavior;

final class RefundUnitsSpec extends ObjectBehavior
{
function it_represents_an_intention_to_refund_specific_order_units(): void
{
$this->beConstructedWith('000222', [1, 3, 5]);

$this->orderNumber()->shouldReturn('000222');
$this->refundedUnitIds()->shouldReturn([1, 3, 5]);
}
}
46 changes: 46 additions & 0 deletions spec/CommandHandler/RefundUnitsHandlerSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace spec\Sylius\RefundPlugin\CommandHandler;

use PhpSpec\ObjectBehavior;
use Prooph\ServiceBus\EventBus;
use Prophecy\Argument;
use Sylius\RefundPlugin\Command\RefundUnits;
use Sylius\RefundPlugin\Creator\RefundCreatorInterface;
use Sylius\RefundPlugin\Event\UnitsRefunded;
use Sylius\RefundPlugin\Provider\RefundedUnitTotalProviderInterface;

final class RefundUnitsHandlerSpec extends ObjectBehavior
{
function let(
RefundCreatorInterface $refundCreator,
RefundedUnitTotalProviderInterface $refundedUnitTotalProvider,
EventBus $eventBus
): void {
$this->beConstructedWith($refundCreator, $refundedUnitTotalProvider, $eventBus);
}

function it_handles_command_and_create_refund_for_each_refunded_unit(
RefundCreatorInterface $refundCreator,
RefundedUnitTotalProviderInterface $refundedUnitTotalProvider,
EventBus $eventBus
): void {
$refundedUnitTotalProvider->getTotalOfUnitWithId(1)->willReturn(1000);
$refundedUnitTotalProvider->getTotalOfUnitWithId(3)->willReturn(500);

$refundCreator->__invoke('000222', 1, 1000)->shouldBeCalled();
$refundCreator->__invoke('000222', 3, 500)->shouldBeCalled();

$eventBus->dispatch(Argument::that(function (UnitsRefunded $event): bool {
return
$event->orderNumber() === '000222' &&
$event->unitIds() === [1, 3] &&
$event->amount() === 1500
;
}))->shouldBeCalled();

$this(new RefundUnits('000222', [1, 3]));
}
}
74 changes: 74 additions & 0 deletions spec/Creator/RefundCreatorSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

declare(strict_types=1);

namespace spec\Sylius\RefundPlugin\Creator;

use Doctrine\Common\Persistence\ObjectManager;
use PhpSpec\ObjectBehavior;
use Prooph\ServiceBus\EventBus;
use Prophecy\Argument;
use Sylius\RefundPlugin\Checker\UnitRefundingAvailabilityCheckerInterface;
use Sylius\RefundPlugin\Creator\RefundCreatorInterface;
use Sylius\RefundPlugin\Entity\RefundInterface;
use Sylius\RefundPlugin\Event\UnitRefunded;
use Sylius\RefundPlugin\Exception\UnitAlreadyRefundedException;
use Sylius\RefundPlugin\Factory\RefundFactoryInterface;

final class RefundCreatorSpec extends ObjectBehavior
{
function let(
RefundFactoryInterface $refundFactory,
UnitRefundingAvailabilityCheckerInterface $unitRefundingAvailabilityChecker,
ObjectManager $refundEntityManager,
EventBus $eventBus
): void {
$this->beConstructedWith(
$refundFactory,
$unitRefundingAvailabilityChecker,
$refundEntityManager,
$eventBus
);
}

function it_implements_refund_creator_interface(): void
{
$this->shouldImplement(RefundCreatorInterface::class);
}

function it_creates_refund_with_given_data_and_save_it_in_database(
RefundFactoryInterface $refundFactory,
UnitRefundingAvailabilityCheckerInterface $unitRefundingAvailabilityChecker,
ObjectManager $refundEntityManager,
EventBus $eventBus,
RefundInterface $refund
): void {
$unitRefundingAvailabilityChecker->__invoke(1)->willReturn(true);

$refundFactory->createWithData('000222', 1, 1000)->willReturn($refund);

$refundEntityManager->persist($refund)->shouldBeCalled();
$refundEntityManager->flush()->shouldBeCalled();

$eventBus->dispatch(Argument::that(function (UnitRefunded $event): bool {
return
$event->orderNumber() === '000222' &&
$event->unitId() === 1 &&
$event->amount() === 1000
;
}))->shouldBeCalled();

$this('000222', 1, 1000);
}

function it_throws_exception_if_unit_has_already_been_refunded(
UnitRefundingAvailabilityCheckerInterface $unitRefundingAvailabilityChecker
): void {
$unitRefundingAvailabilityChecker->__invoke(1)->willReturn(false);

$this
->shouldThrow(UnitAlreadyRefundedException::class)
->during('__invoke', ['000222', 1, 1000])
;
}
}
34 changes: 34 additions & 0 deletions spec/Entity/RefundSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace spec\Sylius\RefundPlugin\Entity;

use PhpSpec\ObjectBehavior;
use Sylius\RefundPlugin\Entity\RefundInterface;

final class RefundSpec extends ObjectBehavior
{
function it_implements_refund_interface(): void
{
$this->shouldImplement(RefundInterface::class);
}

function it_has_order_number(): void
{
$this->setOrderNumber('000666');
$this->getOrderNumber()->shouldReturn('000666');
}

function it_has_amount(): void
{
$this->setAmount(1000);
$this->getAmount()->shouldReturn(1000);
}

function it_has_refunded_unit_id(): void
{
$this->setRefundedUnitId(3);
$this->getRefundedUnitId()->shouldReturn(3);
}
}
19 changes: 19 additions & 0 deletions spec/Event/UnitRefundedSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace spec\Sylius\RefundPlugin\Event;

use PhpSpec\ObjectBehavior;

final class UnitRefundedSpec extends ObjectBehavior
{
function it_represents_an_immutable_fact_that_unit_has_been_refunded(): void
{
$this->beConstructedWith('000222', 1, 1000);

$this->orderNumber()->shouldReturn('000222');
$this->unitId()->shouldReturn(1);
$this->amount()->shouldReturn(1000);
}
}
19 changes: 19 additions & 0 deletions spec/Event/UnitsRefundedSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace spec\Sylius\RefundPlugin\Event;

use PhpSpec\ObjectBehavior;

final class UnitsRefundedSpec extends ObjectBehavior
{
function it_represents_an_immutable_fact_that_units_has_been_refunded(): void
{
$this->beConstructedWith('000222', [1, 2, 3], 5000);

$this->orderNumber()->shouldReturn('000222');
$this->unitIds()->shouldReturn([1, 2, 3]);
$this->amount()->shouldReturn(5000);
}
}
27 changes: 27 additions & 0 deletions spec/Factory/RefundFactorySpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace spec\Sylius\RefundPlugin\Factory;

use PhpSpec\ObjectBehavior;
use Sylius\RefundPlugin\Entity\Refund;
use Sylius\RefundPlugin\Factory\RefundFactoryInterface;

final class RefundFactorySpec extends ObjectBehavior
{
function it_implements_refund_factory_interface(): void
{
$this->shouldImplement(RefundFactoryInterface::class);
}

function it_allows_to_create_refund_with_given_data(): void
{
$refund = new Refund();
$refund->setOrderNumber('0001');
$refund->setRefundedUnitId(1);
$refund->setAmount(1000);

$this->createWithData('0001', 1, 1000)->shouldBeLike($refund);
}
}
Loading

0 comments on commit 2ea3c76

Please sign in to comment.