Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/doctrine/ChannelPricingLogEntry.orm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

<field name="price" column="price" type="integer" />
<field name="originalPrice" column="original_price" type="integer" nullable="true" />
<field name="visible" column="visible" type="boolean" />
<field name="loggedAt" column="logged_at" type="datetime" />

<many-to-one field="channelPricing" target-entity="Sylius\Component\Core\Model\ChannelPricing">
Expand Down
3 changes: 3 additions & 0 deletions config/serialization/ChannelPricingLogEntry.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
<attribute name="originalPrice">
<group>admin:channel_pricing_log_entry:read</group>
</attribute>
<attribute name="visible">
<group>admin:channel-pricing-log-entry:read</group>
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OFC should be admin:channel_pricing_log_entry:read

</attribute>
<attribute name="loggedAt">
<group>admin:channel_pricing_log_entry:read</group>
</attribute>
Expand Down
24 changes: 24 additions & 0 deletions config/services/checkers.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>

<!--

This file is part of the Sylius package.

(c) Paweł Jędrzejewski

For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.

-->

<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"
>
<services>
<service
id="Sylius\PriceHistoryPlugin\Checker\ProductVariantVisibilityCheckerInterface"
class="Sylius\PriceHistoryPlugin\Checker\ProductVariantVisibilityChecker"
/>
</services>
</container>
7 changes: 7 additions & 0 deletions config/services/filters.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,12 @@
</argument>
<tag name="api_platform.filter" />
</service>

<service id="sylius_price_history.api.visible_filter" parent="api_platform.doctrine.orm.boolean_filter" public="true">
<argument type="collection">
<argument key="visible" />
</argument>
<tag name="api_platform.filter" />
</service>
</services>
</container>
2 changes: 2 additions & 0 deletions config/services/listeners.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
>
<services>
<service id="sylius_price_history.listener.channel_pricing_change" class="Sylius\PriceHistoryPlugin\EventListener\ChannelPricingChangeListener">
<argument type="service" id="Sylius\PriceHistoryPlugin\Checker\ProductVariantVisibilityCheckerInterface" />
<argument type="service" id="sylius.repository.channel" />
<tag name="doctrine.event_listener" event="onFlush" lazy="true" />
</service>
</services>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,38 @@ Feature: Seeing the correct catalog price history after creating a product varia
Then I should see 2 log entries in the catalog price history
And there should be a log entry on the 1st position with the "$10.00" selling price, "$20.00" original price and datetime of the price change
And there should be a log entry on the 2nd position with the "$20.00" selling price, no original price and datetime of the price change

@todo
Scenario: Seeing historical product variant prices visible in the catalog only, after the product variant has been created but disabled
Given the store has a "Wyborowa Vodka" configurable product
When I want to create a new variant of this product
And I specify its code as "WYBOROWA_VODKA"
And I set its price to "$20.00" for "United States" channel
And I set its original price to "$25.00" for "United States" channel
#And I disable it # It's not possible to disable a product variant in the current API state
And I add it
And I go to the "Wyborowa Vodka" product variant price history
Then I should not see any log entries in the catalog price history

@api
Scenario: Seeing historical product variant prices visible in the catalog only, after the product variant has been created within the disabled product
Given the store has a "Wyborowa Vodka" configurable product
And this product has been disabled
When I want to create a new variant of this product
And I specify its code as "WYBOROWA_VODKA"
And I set its price to "$20.00" for "United States" channel
And I set its original price to "$25.00" for "United States" channel
And I add it
And I go to the "Wyborowa Vodka" product variant price history
Then I should not see any log entries in the catalog price history

@api
Scenario: Seeing historical product variant prices visible in the catalog only, after the product variant has been created with no channel enabled
Given the store has a "Wyborowa Vodka" configurable product with no channel enabled
When I want to create a new variant of this product
And I specify its code as "WYBOROWA_VODKA"
And I set its price to "$20.00" for "United States" channel
And I set its original price to "$25.00" for "United States" channel
And I add it
And I go to the "Wyborowa Vodka" product variant price history
Then I should not see any log entries in the catalog price history
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Feature: Seeing the correct catalog price history after editing a product varian
Background:
Given the store operates on a single channel in "United States"
And the store has a product "Wyborowa Vodka" priced at "$40.00" in "United States" channel
And the store has a product "Orange Juice" priced at "$10.00" in "United States" channel
And I am logged in as an administrator

@api
Expand All @@ -18,3 +19,29 @@ Feature: Seeing the correct catalog price history after editing a product varian
Then I should see 2 log entries in the catalog price history
And there should be a log entry on the 1st position with the "$42.00" selling price, no original price and datetime of the price change
And there should be a log entry on the 2nd position with the "$40.00" selling price, no original price and datetime of the price change

@api
Scenario: Seeing historical product variant prices after the product variant has been edited but the product disabled
Given the "Orange Juice" product is disabled
When I want to modify the "Orange Juice" product variant
And I change its price to "$15.00" for "United States" channel
And I save my changes
And I go to the "Orange Juice" product variant price history
Then I should see a single log entry in the catalog price history
And there should be a log entry with the "$10.00" selling price, no original price and datetime of the price change

@api
Scenario: Seeing historical product variant prices after the product variant has been edited while it has been disabled
Given the "Orange Juice" product is disabled with a new price "$15.00"
When I go to the "Orange Juice" product variant price history
Then I should see a single log entry in the catalog price history
And there should be a log entry with the "$10.00" selling price, no original price and datetime of the price change

@api
Scenario: Seeing historical product variant prices after the product variant has been edited while it has been disabled and then enabled
Given the "Orange Juice" product is disabled with a new price "$15.00"
And the "Orange Juice" product is enabled
When I go to the "Orange Juice" product variant price history
Then I should see 2 log entries in the catalog price history
And there should be a log entry on the 1st position with the "$15.00" selling price, no original price and datetime of the price change
And there should be a log entry on the 2nd position with the "$10.00" selling price, no original price and datetime of the price change
84 changes: 84 additions & 0 deletions spec/Checker/ProductVariantVisibilityCheckerSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php

/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace spec\Sylius\PriceHistoryPlugin\Checker;

use PhpSpec\ObjectBehavior;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Core\Model\ProductVariantInterface;
use Sylius\PriceHistoryPlugin\Checker\ProductVariantVisibilityCheckerInterface;

class ProductVariantVisibilityCheckerSpec extends ObjectBehavior
{
function it_implements_product_visibility_checker_interface(): void
{
$this->shouldHaveType(ProductVariantVisibilityCheckerInterface::class);
}

function it_returns_true_if_product_variant_is_visible(
ProductVariantInterface $productVariant,
ChannelInterface $channel,
ProductInterface $product,
): void {
$productVariant->getProduct()->willReturn($product);

$productVariant->isEnabled()->willReturn(true);
$product->isEnabled()->willReturn(true);
$product->hasChannel($channel)->willReturn(true);

$this->isVisibleInChannel($productVariant, $channel)->shouldReturn(true);
}

function it_returns_false_if_product_is_disabled(
ProductVariantInterface $productVariant,
ChannelInterface $channel,
ProductInterface $product,
): void {
$productVariant->getProduct()->willReturn($product);

$productVariant->isEnabled()->willReturn(true);
$product->isEnabled()->willReturn(false);
$product->hasChannel($channel)->willReturn(true);

$this->isVisibleInChannel($productVariant, $channel)->shouldReturn(false);
}

function it_returns_false_if_product_is_disabled_for_a_given_channel(
ProductVariantInterface $productVariant,
ChannelInterface $channel,
ProductInterface $product,
): void {
$productVariant->getProduct()->willReturn($product);

$productVariant->isEnabled()->willReturn(true);
$product->isEnabled()->willReturn(true);
$product->hasChannel($channel)->willReturn(false);

$this->isVisibleInChannel($productVariant, $channel)->shouldReturn(false);
}

function it_returns_false_if_product_variant_is_disabled(
ProductVariantInterface $productVariant,
ChannelInterface $channel,
ProductInterface $product,
): void {
$productVariant->getProduct()->willReturn($product);

$productVariant->isEnabled()->willReturn(false);
$product->isEnabled()->willReturn(true);
$product->hasChannel($channel)->willReturn(true);

$this->isVisibleInChannel($productVariant, $channel)->shouldReturn(false);
}
}
16 changes: 14 additions & 2 deletions spec/Model/ChannelPricingLogEntrySpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class ChannelPricingLogEntrySpec extends ObjectBehavior
{
function let(ChannelPricingInterface $channelPricing): void
{
$this->beConstructedWith($channelPricing, 1000, 2000);
$this->beConstructedWith($channelPricing, 1000, 2000, true);
}

function it_implements_channel_pricing_log_entry_interface(): void
Expand All @@ -31,7 +31,7 @@ function it_implements_channel_pricing_log_entry_interface(): void

function it_initialize_with_no_original_price(ChannelPricingInterface $channelPricing): void
{
$this->beConstructedWith($channelPricing, 1000, null);
$this->beConstructedWith($channelPricing, 1000, null, true);
$this->getOriginalPrice()->shouldReturn(null);
}

Expand All @@ -54,4 +54,16 @@ function it_gets_a_logged_at(): void
{
$this->getLoggedAt()->shouldReturnAnInstanceOf(\DateTimeImmutable::class);
}

function it_can_be_visible(): void
{
$this->isVisible()->shouldReturn(true);
}

function it_can_be_invisible(ChannelPricingInterface $channelPricing): void
{
$this->beConstructedWith($channelPricing, 1000, 2000, false);

$this->isVisible()->shouldReturn(false);
}
}
29 changes: 29 additions & 0 deletions src/Checker/ProductVariantVisibilityChecker.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Sylius\PriceHistoryPlugin\Checker;

use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\ProductVariantInterface;
use Webmozart\Assert\Assert;

class ProductVariantVisibilityChecker implements ProductVariantVisibilityCheckerInterface
{
public function isVisibleInChannel(ProductVariantInterface $productVariant, ChannelInterface $channel): bool
{
$product = $productVariant->getProduct();
Assert::notNull($product);

return $productVariant->isEnabled() && $product->isEnabled() && $product->hasChannel($channel);
}
}
22 changes: 22 additions & 0 deletions src/Checker/ProductVariantVisibilityCheckerInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Sylius\PriceHistoryPlugin\Checker;

use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\ProductVariantInterface;

interface ProductVariantVisibilityCheckerInterface
{
public function isVisibleInChannel(ProductVariantInterface $productVariant, ChannelInterface $channel): bool;
}
15 changes: 14 additions & 1 deletion src/EventListener/ChannelPricingChangeListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,23 @@
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Event\OnFlushEventArgs;
use Doctrine\ORM\UnitOfWork;
use Sylius\Component\Channel\Repository\ChannelRepositoryInterface;
use Sylius\Component\Core\Model\ChannelPricingInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Sylius\PriceHistoryPlugin\Checker\ProductVariantVisibilityCheckerInterface;
use Sylius\PriceHistoryPlugin\Model\ChannelPricingLogEntry;
use Webmozart\Assert\Assert;

final class ChannelPricingChangeListener
{
private const SUPPORTED_FIELDS = ['price', 'originalPrice'];

public function __construct(
private ProductVariantVisibilityCheckerInterface $productVariantVisibilityChecker,
private ChannelRepositoryInterface $channelRepository,
) {
}

public function onFlush(OnFlushEventArgs $eventArgs): void
{
$entityManager = $eventArgs->getObjectManager();
Expand Down Expand Up @@ -65,7 +74,11 @@ private function createLogEntry(ChannelPricingInterface $model): ChannelPricingL
{
Assert::notNull($price = $model->getPrice());

return new ChannelPricingLogEntry($model, $price, $model->getOriginalPrice());
$channel = $this->channelRepository->findOneByCode($model->getChannelCode());
dd($channel);
$isChangeVisible = $this->productVariantVisibilityChecker->isVisibleInChannel($model->getProductVariant(), $channel);

return new ChannelPricingLogEntry($model, $price, $model->getOriginalPrice(), $isChangeVisible);
}

private function isPriceChanged(UnitOfWork $unitOfWork, ChannelPricingInterface $channelPricing): bool
Expand Down
31 changes: 31 additions & 0 deletions src/Migrations/Version20230202130642.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace Sylius\PriceHistoryPlugin\Migrations;

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

/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20230202130642 extends AbstractMigration
{
public function getDescription(): string
{
return 'Add `visible` field to the ChannelPricingLogEntry';
}

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

public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE sylius_price_history_channel_pricing_log_entry DROP visible');
}
}
Loading