[Channel][PriceHistory] Extract config

This commit is contained in:
Jan Goralski 2023-03-29 11:42:20 +02:00
parent cade56ccc6
commit 77addfe312
No known key found for this signature in database
GPG key ID: 95D91BA380F31EDD
10 changed files with 130 additions and 144 deletions

View file

@ -111,20 +111,5 @@
<group>admin:channel:read</group>
<group>admin:channel:create</group>
</attribute>
<attribute name="lowestPriceForDiscountedProductsVisible">
<group>admin:channel:read</group>
<group>admin:channel:create</group>
<group>admin:channel:update</group>
</attribute>
<attribute name="lowestPriceForDiscountedProductsCheckingPeriod">
<group>admin:channel:read</group>
<group>admin:channel:create</group>
<group>admin:channel:update</group>
</attribute>
<attribute name="taxonsExcludedFromShowingLowestPrice">
<group>admin:channel:read</group>
<group>admin:channel:create</group>
<group>admin:channel:update</group>
</attribute>
</class>
</serializer>

View file

@ -0,0 +1,66 @@
<?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\Bundle\CoreBundle\Migrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
final class Version20230329093932 extends AbstractMigration
{
public function getDescription(): string
{
return 'Add ChannelPriceHistoryConfig';
}
public function up(Schema $schema): void
{
$this->addSql('CREATE TABLE sylius_channel_price_history_config (id INT AUTO_INCREMENT NOT NULL, lowest_price_for_discounted_products_checking_period INT DEFAULT 30 NOT NULL, lowest_price_for_discounted_products_visible TINYINT(1) DEFAULT 1 NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
$this->addSql('CREATE TABLE sylius_channel_price_history_config_excluded_taxons (channel_id INT NOT NULL, taxon_id INT NOT NULL, INDEX IDX_77FD02A72F5A1AA (channel_id), INDEX IDX_77FD02ADE13F470 (taxon_id), PRIMARY KEY(channel_id, taxon_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
$this->addSql('ALTER TABLE sylius_channel_price_history_config_excluded_taxons ADD CONSTRAINT FK_77FD02A72F5A1AA FOREIGN KEY (channel_id) REFERENCES sylius_channel_price_history_config (id) ON DELETE CASCADE');
$this->addSql('ALTER TABLE sylius_channel_price_history_config_excluded_taxons ADD CONSTRAINT FK_77FD02ADE13F470 FOREIGN KEY (taxon_id) REFERENCES sylius_taxon (id) ON DELETE CASCADE');
$this->addSql('ALTER TABLE sylius_channel_excluded_taxons DROP FOREIGN KEY FK_3574E1E972F5A1AA');
$this->addSql('ALTER TABLE sylius_channel_excluded_taxons DROP FOREIGN KEY FK_3574E1E9DE13F470');
$this->addSql('DROP TABLE sylius_channel_excluded_taxons');
$this->addSql('ALTER TABLE sylius_channel ADD channel_price_history_config_id INT DEFAULT NULL, DROP lowest_price_for_discounted_products_checking_period, DROP lowest_price_for_discounted_products_visible');
$this->addSql('ALTER TABLE sylius_channel ADD CONSTRAINT FK_16C8119E75F20EAE FOREIGN KEY (channel_price_history_config_id) REFERENCES sylius_channel_price_history_config (id) ON DELETE CASCADE');
$this->addSql('CREATE UNIQUE INDEX UNIQ_16C8119E75F20EAE ON sylius_channel (channel_price_history_config_id)');
}
public function postUp(Schema $schema): void
{
$channelsIds = $this->connection->executeQuery('SELECT id from sylius_channel')->fetchAllAssociative();
foreach ($channelsIds as $channelId) {
$this->connection->executeQuery('INSERT INTO sylius_channel_price_history_config (lowest_price_for_discounted_products_checking_period, lowest_price_for_discounted_products_visible) VALUES (30, true)');
$this->connection->executeQuery('UPDATE sylius_channel SET channel_price_history_config_id = :priceHistoryConfig WHERE id = :channel', [
'channel' => $channelId['id'],
'priceHistoryConfig' => $this->connection->lastInsertId(),
]);
}
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE sylius_channel DROP FOREIGN KEY FK_16C8119E75F20EAE');
$this->addSql('CREATE TABLE sylius_channel_excluded_taxons (channel_id INT NOT NULL, taxon_id INT NOT NULL, INDEX IDX_3574E1E972F5A1AA (channel_id), INDEX IDX_3574E1E9DE13F470 (taxon_id), PRIMARY KEY(channel_id, taxon_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB COMMENT = \'\' ');
$this->addSql('ALTER TABLE sylius_channel_excluded_taxons ADD CONSTRAINT FK_3574E1E972F5A1AA FOREIGN KEY (channel_id) REFERENCES sylius_channel (id) ON UPDATE NO ACTION ON DELETE CASCADE');
$this->addSql('ALTER TABLE sylius_channel_excluded_taxons ADD CONSTRAINT FK_3574E1E9DE13F470 FOREIGN KEY (taxon_id) REFERENCES sylius_taxon (id) ON UPDATE NO ACTION ON DELETE CASCADE');
$this->addSql('ALTER TABLE sylius_channel_price_history_config_excluded_taxons DROP FOREIGN KEY FK_77FD02A72F5A1AA');
$this->addSql('ALTER TABLE sylius_channel_price_history_config_excluded_taxons DROP FOREIGN KEY FK_77FD02ADE13F470');
$this->addSql('DROP TABLE sylius_channel_price_history_config');
$this->addSql('DROP TABLE sylius_channel_price_history_config_excluded_taxons');
$this->addSql('DROP INDEX UNIQ_16C8119E75F20EAE ON sylius_channel');
$this->addSql('ALTER TABLE sylius_channel ADD lowest_price_for_discounted_products_checking_period INT DEFAULT 30 NOT NULL, ADD lowest_price_for_discounted_products_visible TINYINT(1) DEFAULT 1 NOT NULL, DROP channel_price_history_config_id');
}
}

View file

@ -29,30 +29,6 @@
<option name="default">0</option>
</options>
</field>
<field
name="lowestPriceForDiscountedProductsCheckingPeriod"
column="lowest_price_for_discounted_products_checking_period"
type="integer"
>
<options>
<option name="default">30</option>
</options>
</field>
<field name="lowestPriceForDiscountedProductsVisible" column="lowest_price_for_discounted_products_visible" type="boolean">
<options>
<option name="default">1</option>
</options>
</field>
<many-to-many field="taxonsExcludedFromShowingLowestPrice" target-entity="Sylius\Component\Taxonomy\Model\TaxonInterface">
<join-table name="sylius_channel_excluded_taxons">
<join-columns>
<join-column name="channel_id" nullable="false" on-delete="CASCADE" />
</join-columns>
<inverse-join-columns>
<join-column name="taxon_id" nullable="false" on-delete="CASCADE" />
</inverse-join-columns>
</join-table>
</many-to-many>
<many-to-one field="defaultLocale" target-entity="Sylius\Component\Locale\Model\LocaleInterface" fetch="EAGER">
<join-column name="default_locale_id" referenced-column-name="id" nullable="false" />
</many-to-one>
@ -106,5 +82,12 @@
<cascade-all />
</cascade>
</one-to-one>
<one-to-one field="channelPriceHistoryConfig" target-entity="Sylius\Component\Core\Model\ChannelPriceHistoryConfigInterface">
<join-column name="channel_price_history_config_id" on-delete="CASCADE"/>
<cascade>
<cascade-all />
</cascade>
</one-to-one>
</mapped-superclass>
</doctrine-mapping>

View file

@ -157,6 +157,7 @@
<service id="sylius.custom_factory.channel" class="Sylius\Component\Core\Factory\ChannelFactory" decorates="sylius.factory.channel" decoration-priority="256" public="false">
<argument type="service" id="sylius.custom_factory.channel.inner" />
<argument type="service" id="sylius.factory.channel_price_history_config" />
<argument>order_items_based</argument>
</service>

View file

@ -54,32 +54,5 @@
</option>
</constraint>
</property>
<getter property="lowestPriceForDiscountedProductsCheckingPeriod">
<constraint name="NotNull">
<option name="groups">
<value>sylius</value>
</option>
</constraint>
<constraint name="Type">
<option name="value">int</option>
<option name="groups">
<value>sylius</value>
</option>
</constraint>
<constraint name="LessThan">
<option name="value">2147483647</option>
<option name="groups">
<value>sylius</value>
</option>
<option name="message">sylius.channel.lowest_price_for_discounted_products_checking_period.less_than</option>
</constraint>
<constraint name="GreaterThan">
<option name="value">0</option>
<option name="groups">
<value>sylius</value>
</option>
<option name="message">sylius.channel.lowest_price_for_discounted_products_checking_period.greater_than</option>
</constraint>
</getter>
</class>
</constraint-mapping>

View file

@ -16,13 +16,17 @@ namespace Sylius\Component\Core\Factory;
use Sylius\Component\Channel\Factory\ChannelFactoryInterface;
use Sylius\Component\Channel\Model\ChannelInterface;
use Sylius\Component\Core\Model\ChannelInterface as CoreChannelInterface;
use Sylius\Component\Core\Model\ChannelPriceHistoryConfigInterface;
use Sylius\Component\Resource\Factory\FactoryInterface;
use Webmozart\Assert\Assert;
final class ChannelFactory implements ChannelFactoryInterface
{
public function __construct(private FactoryInterface $decoratedFactory, private string $defaultCalculationStrategy)
{
public function __construct(
private FactoryInterface $decoratedFactory,
private FactoryInterface $channelPriceHistoryConfigFactory,
private string $defaultCalculationStrategy,
) {
}
/**
@ -34,6 +38,10 @@ final class ChannelFactory implements ChannelFactoryInterface
$channel = $this->decoratedFactory->createNew();
$channel->setTaxCalculationStrategy($this->defaultCalculationStrategy);
/** @var ChannelPriceHistoryConfigInterface $channelPriceHistoryConfig */
$channelPriceHistoryConfig = $this->channelPriceHistoryConfigFactory->createNew();
$channel->setChannelPriceHistoryConfig($channelPriceHistoryConfig);
return $channel;
}

View file

@ -83,16 +83,7 @@ class Channel extends BaseChannel implements ChannelInterface
/** @var TaxonInterface|null */
protected $menuTaxon;
/**
* @var Collection|TaxonInterface[]
*
* @psalm-var Collection<array-key, TaxonInterface>
*/
protected Collection $taxonsExcludedFromShowingLowestPrice;
protected int $lowestPriceForDiscountedProductsCheckingPeriod = 30;
protected bool $lowestPriceForDiscountedProductsVisible = true;
protected ?ChannelPriceHistoryConfigInterface $channelPriceHistoryConfig = null;
public function __construct()
{
@ -104,8 +95,6 @@ class Channel extends BaseChannel implements ChannelInterface
$this->locales = new ArrayCollection();
/** @var ArrayCollection<array-key, CountryInterface> $this->countries */
$this->countries = new ArrayCollection();
// /** @var ArrayCollection<array-key, TaxonInterface> $this->taxonsExcludedFromShowingLowestPrice */
$this->taxonsExcludedFromShowingLowestPrice = new ArrayCollection();
}
public function getBaseCurrency(): ?CurrencyInterface
@ -310,52 +299,13 @@ class Channel extends BaseChannel implements ChannelInterface
$this->menuTaxon = $menuTaxon;
}
public function getLowestPriceForDiscountedProductsCheckingPeriod(): int
public function getChannelPriceHistoryConfig(): ?ChannelPriceHistoryConfigInterface
{
return $this->lowestPriceForDiscountedProductsCheckingPeriod;
return $this->channelPriceHistoryConfig;
}
public function setLowestPriceForDiscountedProductsCheckingPeriod(int $periodInDays): void
public function setChannelPriceHistoryConfig(ChannelPriceHistoryConfigInterface $channelPriceHistoryConfig): void
{
$this->lowestPriceForDiscountedProductsCheckingPeriod = $periodInDays;
}
public function isLowestPriceForDiscountedProductsVisible(): bool
{
return $this->lowestPriceForDiscountedProductsVisible;
}
public function setLowestPriceForDiscountedProductsVisible(bool $visible = true): void
{
$this->lowestPriceForDiscountedProductsVisible = $visible;
}
public function getTaxonsExcludedFromShowingLowestPrice(): Collection
{
return $this->taxonsExcludedFromShowingLowestPrice;
}
public function hasTaxonExcludedFromShowingLowestPrice(TaxonInterface $taxon): bool
{
return $this->taxonsExcludedFromShowingLowestPrice->contains($taxon);
}
public function addTaxonExcludedFromShowingLowestPrice(TaxonInterface $taxon): void
{
if (!$this->hasTaxonExcludedFromShowingLowestPrice($taxon)) {
$this->taxonsExcludedFromShowingLowestPrice->add($taxon);
}
}
public function removeTaxonExcludedFromShowingLowestPrice(TaxonInterface $taxon): void
{
if ($this->hasTaxonExcludedFromShowingLowestPrice($taxon)) {
$this->taxonsExcludedFromShowingLowestPrice->removeElement($taxon);
}
}
public function clearTaxonsExcludedFromShowingLowestPrice(): void
{
$this->taxonsExcludedFromShowingLowestPrice->clear();
$this->channelPriceHistoryConfig = $channelPriceHistoryConfig;
}
}

View file

@ -93,21 +93,7 @@ interface ChannelInterface extends
public function hasCountry(CountryInterface $country): bool;
public function getLowestPriceForDiscountedProductsCheckingPeriod(): int;
public function setChannelPriceHistoryConfig(ChannelPriceHistoryConfigInterface $channelPriceHistoryConfig): void;
public function setLowestPriceForDiscountedProductsCheckingPeriod(int $periodInDays): void;
public function isLowestPriceForDiscountedProductsVisible(): bool;
public function setLowestPriceForDiscountedProductsVisible(bool $visible = true): void;
public function getTaxonsExcludedFromShowingLowestPrice(): Collection;
public function hasTaxonExcludedFromShowingLowestPrice(TaxonInterface $taxon): bool;
public function addTaxonExcludedFromShowingLowestPrice(TaxonInterface $taxon): void;
public function removeTaxonExcludedFromShowingLowestPrice(TaxonInterface $taxon): void;
public function clearTaxonsExcludedFromShowingLowestPrice(): void;
public function getChannelPriceHistoryConfig(): ?ChannelPriceHistoryConfigInterface;
}

View file

@ -16,13 +16,16 @@ namespace spec\Sylius\Component\Core\Factory;
use PhpSpec\ObjectBehavior;
use Sylius\Component\Channel\Factory\ChannelFactoryInterface;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\ChannelPriceHistoryConfigInterface;
use Sylius\Component\Resource\Factory\FactoryInterface;
final class ChannelFactorySpec extends ObjectBehavior
{
function let(FactoryInterface $decoratedFactory): void
{
$this->beConstructedWith($decoratedFactory, 'order_items_based');
function let(
FactoryInterface $decoratedFactory,
FactoryInterface $channelPriceHistoryConfigFactory,
): void {
$this->beConstructedWith($decoratedFactory, $channelPriceHistoryConfigFactory, 'order_items_based');
}
function it_implements_channel_factory_interface(): void
@ -35,11 +38,35 @@ final class ChannelFactorySpec extends ObjectBehavior
$this->shouldImplement(FactoryInterface::class);
}
function it_creates_a_new_channel(FactoryInterface $decoratedFactory, ChannelInterface $channel): void
{
function it_creates_a_new_channel(
FactoryInterface $decoratedFactory,
FactoryInterface $channelPriceHistoryConfigFactory,
ChannelInterface $channel,
ChannelPriceHistoryConfigInterface $channelPriceHistoryConfig,
): void {
$decoratedFactory->createNew()->willReturn($channel);
$channel->setTaxCalculationStrategy('order_items_based')->shouldBeCalled();
$channelPriceHistoryConfigFactory->createNew()->willReturn($channelPriceHistoryConfig);
$channel->setChannelPriceHistoryConfig($channelPriceHistoryConfig)->shouldBeCalled();
$this->createNew()->shouldReturn($channel);
}
function it_creates_a_new_named_channel(
FactoryInterface $decoratedFactory,
FactoryInterface $channelPriceHistoryConfigFactory,
ChannelInterface $channel,
ChannelPriceHistoryConfigInterface $channelPriceHistoryConfig,
): void {
$decoratedFactory->createNew()->willReturn($channel);
$channel->setTaxCalculationStrategy('order_items_based')->shouldBeCalled();
$channelPriceHistoryConfigFactory->createNew()->willReturn($channelPriceHistoryConfig);
$channel->setChannelPriceHistoryConfig($channelPriceHistoryConfig)->shouldBeCalled();
$channel->setName('Web')->shouldBeCalled();
$this->createNamed('Web')->shouldReturn($channel);
}
}

View file

@ -18,6 +18,7 @@ use PhpSpec\ObjectBehavior;
use Sylius\Component\Addressing\Model\ZoneInterface;
use Sylius\Component\Channel\Model\Channel as BaseChannel;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\ChannelPriceHistoryConfigInterface;
use Sylius\Component\Core\Model\TaxonInterface;
use Sylius\Component\Currency\Model\CurrencyInterface;
use Sylius\Component\Locale\Model\LocaleInterface;
@ -188,4 +189,10 @@ final class ChannelSpec extends ObjectBehavior
$this->setMenuTaxon($taxon);
$this->getMenuTaxon()->shouldReturn($taxon);
}
function its_price_history_config_is_mutable(ChannelPriceHistoryConfigInterface $config): void
{
$this->setChannelPriceHistoryConfig($config);
$this->getChannelPriceHistoryConfig()->shouldReturn($config);
}
}