feature #11529 [RFC] Using tabs for channel pricing (mamazu)

This PR was merged into the 1.8-dev branch.

Discussion
----------

| Q               | A
| --------------- | -----
| Branch?         | master
| Bug fix?        | no
| New feature?    | yes
| BC breaks?      | no
| Deprecations?   | no
| Related tickets | -
| License         | MIT

## Proposal
Channel prices in a simple product get displayed on the product page under the list of channels. So I propose that they will be made into a tabbed view so that they are more easy to manage. If you have a lot of channels (where the product is not active for example) you have a lot of values to scroll through.

### Before
![screenshot_before](https://user-images.githubusercontent.com/14860264/83183765-afe4e980-a128-11ea-9f98-705d2650572c.png)

### After
![screenshot_after](https://user-images.githubusercontent.com/14860264/83183770-b1161680-a128-11ea-948b-0f9ee5475d9f.png)


Commits
-------

79a5074dd5 Using tabs for channel pricing
d4511ea2de Extracting channel_pricings out to its own template
80661a5771 Fixing tests
4de3ba117d Adding label back in to fix behat tests
fc34aca7ce Adding a transformer for channels
a5e37128b7 Update src/Sylius/Behat/Context/Ui/Admin/ManagingProductVariantsContext.php
0df50ab725 Fixing the tests
This commit is contained in:
Łukasz Chruściel 2020-06-16 10:34:32 +02:00 committed by GitHub
commit 929a23588d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 148 additions and 96 deletions

View file

@ -3,7 +3,7 @@ Feature: Removing a product's price after channel deletion
In order to have product's prices specified only for existing channels
As an Administrator
I want to have product's price removed after corresponding channel deletion
Background:
Given the store has currency "USD"
And the store operates on a channel named "Web-US" in "USD" currency

View file

@ -22,6 +22,7 @@ use Sylius\Behat\Page\Admin\ProductVariant\UpdatePageInterface;
use Sylius\Behat\Service\NotificationCheckerInterface;
use Sylius\Behat\Service\Resolver\CurrentPageResolverInterface;
use Sylius\Behat\Service\SharedStorageInterface;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Core\Model\ProductVariantInterface;
use Webmozart\Assert\Assert;
@ -126,20 +127,20 @@ final class ManagingProductVariantsContext implements Context
}
/**
* @When /^I set its(?:| default) price to "(?:€|£|\$)([^"]+)" for "([^"]+)" channel$/
* @When /^I set its(?:| default) price to "(?:€|£|\$)([^"]+)" for ("([^"]+)" channel)$/
* @When I do not set its price
*/
public function iSetItsPriceTo(?string $price = null, $channelName = null)
public function iSetItsPriceTo(?string $price = null, ?ChannelInterface $channel = null)
{
$this->createPage->specifyPrice($price ?? '', $channelName ?? (string) $this->sharedStorage->get('channel'));
$this->createPage->specifyPrice($price ?? '', $channel ?? $this->sharedStorage->get('channel'));
}
/**
* @When /^I set its original price to "(?:€|£|\$)([^"]+)" for "([^"]+)" channel$/
* @When /^I set its original price to "(?:€|£|\$)([^"]+)" for ("([^"]+)" channel)$/
*/
public function iSetItsOriginalPriceTo($originalPrice, $channelName)
public function iSetItsOriginalPriceTo($originalPrice, ChannelInterface $channel)
{
$this->createPage->specifyOriginalPrice($originalPrice, $channelName);
$this->createPage->specifyOriginalPrice($originalPrice, $channel);
}
/**
@ -215,13 +216,13 @@ final class ManagingProductVariantsContext implements Context
}
/**
* @Then /^the (variant with code "[^"]+") should be priced at (?:€|£|\$)([^"]+) for channel "([^"]+)"$/
* @Then /^the (variant with code "[^"]+") should be priced at (?:€|£|\$)([^"]+) for (channel "([^"]+)")$/
*/
public function theVariantWithCodeShouldBePricedAtForChannel(ProductVariantInterface $productVariant, string $price, $channelName)
public function theVariantWithCodeShouldBePricedAtForChannel(ProductVariantInterface $productVariant, string $price, ChannelInterface $channel)
{
$this->updatePage->open(['id' => $productVariant->getId(), 'productId' => $productVariant->getProduct()->getId()]);
Assert::same($this->updatePage->getPriceForChannel($channelName), $price);
Assert::same($this->updatePage->getPriceForChannel($channel), $price);
}
/**
@ -235,14 +236,14 @@ final class ManagingProductVariantsContext implements Context
}
/**
* @Then /^the (variant with code "[^"]+") should have an original price of (?:€|£|\$)([^"]+) for channel "([^"]+)"$/
* @Then /^the (variant with code "[^"]+") should have an original price of (?:€|£|\$)([^"]+) for (channel "([^"]+)")$/
*/
public function theVariantWithCodeShouldHaveAnOriginalPriceOfForChannel(ProductVariantInterface $productVariant, $originalPrice, $channelName)
public function theVariantWithCodeShouldHaveAnOriginalPriceOfForChannel(ProductVariantInterface $productVariant, $originalPrice, ChannelInterface $channel)
{
$this->updatePage->open(['id' => $productVariant->getId(), 'productId' => $productVariant->getProduct()->getId()]);
Assert::same(
$this->updatePage->getOriginalPriceForChannel($channelName),
$this->updatePage->getOriginalPriceForChannel($channel),
$originalPrice
);
}
@ -441,12 +442,12 @@ final class ManagingProductVariantsContext implements Context
}
/**
* @When /^I specify that the (\d)(?:st|nd|rd|th) variant is identified by "([^"]+)" code and costs "(?:|£|\$)([^"]+)" in ("[^"]+") channel$/
* @When /^I specify that the (\d)(?:st|nd|rd|th) variant is identified by "([^"]+)" code and costs "(?:|£|\$)([^"]+)" in (("[^"]+") channel)$/
*/
public function iSpecifyThereAreVariantsIdentifiedByCodeWithCost($nthVariant, $code, int $price, $channelName)
public function iSpecifyThereAreVariantsIdentifiedByCodeWithCost($nthVariant, $code, int $price, ChannelInterface $channel)
{
$this->generatePage->specifyCode($nthVariant - 1, $code);
$this->generatePage->specifyPrice($nthVariant - 1, $price, $channelName);
$this->generatePage->specifyPrice($nthVariant - 1, $price, $channel);
}
/**
@ -458,11 +459,11 @@ final class ManagingProductVariantsContext implements Context
}
/**
* @When /^I specify that the (\d)(?:st|nd|rd|th) variant costs "(?:€|£|\$)([^"]+)" in ("[^"]+") channel$/
* @When /^I specify that the (\d)(?:st|nd|rd|th) variant costs "(?:€|£|\$)([^"]+)" in (("[^"]+") channel)$/
*/
public function iSpecifyThereAreVariantsWithCost($nthVariant, int $price, $channelName)
public function iSpecifyThereAreVariantsWithCost($nthVariant, int $price, ChannelInterface $channel)
{
$this->generatePage->specifyPrice($nthVariant - 1, $price, $channelName);
$this->generatePage->specifyPrice($nthVariant - 1, $price, $channel);
}
/**

View file

@ -14,7 +14,6 @@ declare(strict_types=1);
namespace Sylius\Behat\Context\Ui\Admin;
use Behat\Behat\Context\Context;
use Behat\Mink\Exception\ElementNotFoundException;
use Sylius\Behat\NotificationType;
use Sylius\Behat\Page\Admin\Crud\CreatePageInterface;
use Sylius\Behat\Page\Admin\Crud\UpdatePageInterface;
@ -178,19 +177,19 @@ final class ManagingProductsContext implements Context
}
/**
* @When /^I set its(?:| default) price to "(?:€|£|\$)([^"]+)" for "([^"]+)" channel$/
* @When /^I set its(?:| default) price to "(?:€|£|\$)([^"]+)" for ("([^"]+)" channel)$/
*/
public function iSetItsPriceTo(string $price, string $channelName)
public function iSetItsPriceTo(string $price, ChannelInterface $channel)
{
$this->createSimpleProductPage->specifyPrice($channelName, $price);
$this->createSimpleProductPage->specifyPrice($channel, $price);
}
/**
* @When /^I set its original price to "(?:€|£|\$)([^"]+)" for "([^"]+)" channel$/
* @When /^I set its original price to "(?:€|£|\$)([^"]+)" for ("([^"]+)" channel)$/
*/
public function iSetItsOriginalPriceTo(int $originalPrice, $channelName)
public function iSetItsOriginalPriceTo(int $originalPrice, ChannelInterface $channel)
{
$this->createSimpleProductPage->specifyOriginalPrice($channelName, $originalPrice);
$this->createSimpleProductPage->specifyOriginalPrice($channel, $originalPrice);
}
/**
@ -487,19 +486,19 @@ final class ManagingProductsContext implements Context
}
/**
* @When /^I change its price to (?:|£|\$)([^"]+) for "([^"]+)" channel$/
* @When /^I change its price to (?:|£|\$)([^"]+) for ("([^"]+)" channel)$/
*/
public function iChangeItsPriceTo(string $price, $channelName)
public function iChangeItsPriceTo(string $price, ChannelInterface $channel)
{
$this->updateSimpleProductPage->specifyPrice($channelName, $price);
$this->updateSimpleProductPage->specifyPrice($channel, $price);
}
/**
* @When /^I change its original price to "(?:€|£|\$)([^"]+)" for "([^"]+)" channel$/
* @When /^I change its original price to "(?:€|£|\$)([^"]+)" for ("([^"]+)" channel)$/
*/
public function iChangeItsOriginalPriceTo(string $price, $channelName)
public function iChangeItsOriginalPriceTo(string $price, ChannelInterface $channel)
{
$this->updateSimpleProductPage->specifyOriginalPrice($channelName, $price);
$this->updateSimpleProductPage->specifyOriginalPrice($channel, $price);
}
/**
@ -885,7 +884,10 @@ final class ManagingProductsContext implements Context
*/
public function iShouldBeNotifiedThatPriceMustBeDefinedForEveryChannel()
{
$this->assertValidationMessage('channel_pricings', 'You must define price for every channel.');
Assert::same(
$this->createSimpleProductPage->getChannelPricingValidationMessage(),
'You must define price for every channel.'
);
}
/**
@ -929,25 +931,25 @@ final class ManagingProductsContext implements Context
}
/**
* @Then /^(it|this product) should be priced at (?:|£|\$)([^"]+) for channel "([^"]+)"$/
* @Then /^(product "[^"]+") should be priced at (?:€|£|\$)([^"]+) for channel "([^"]+)"$/
* @Then /^(it|this product) should be priced at (?:|£|\$)([^"]+) for (channel "([^"]+)")$/
* @Then /^(product "[^"]+") should be priced at (?:€|£|\$)([^"]+) for (channel "([^"]+)")$/
*/
public function itShouldBePricedAtForChannel(ProductInterface $product, string $price, $channelName)
public function itShouldBePricedAtForChannel(ProductInterface $product, string $price, ChannelInterface $channel)
{
$this->updateSimpleProductPage->open(['id' => $product->getId()]);
Assert::same($this->updateSimpleProductPage->getPriceForChannel($channelName), $price);
Assert::same($this->updateSimpleProductPage->getPriceForChannel($channel), $price);
}
/**
* @Then /^(its|this products) original price should be "(?:€|£|\$)([^"]+)" for channel "([^"]+)"$/
* @Then /^(its|this products) original price should be "(?:€|£|\$)([^"]+)" for (channel "([^"]+)")$/
*/
public function itsOriginalPriceForChannel(ProductInterface $product, $originalPrice, $channelName)
public function itsOriginalPriceForChannel(ProductInterface $product, string $originalPrice, ChannelInterface $channel)
{
$this->updateSimpleProductPage->open(['id' => $product->getId()]);
Assert::same(
$this->updateSimpleProductPage->getOriginalPriceForChannel($channelName),
$this->updateSimpleProductPage->getOriginalPriceForChannel($channel),
$originalPrice
);
}
@ -959,13 +961,8 @@ final class ManagingProductsContext implements Context
{
$this->updateSimpleProductPage->open(['id' => $product->getId()]);
try {
$this->updateSimpleProductPage->getPriceForChannel($channelName);
} catch (ElementNotFoundException $exception) {
return;
}
throw new \Exception(
Assert::true(
$this->updateSimpleProductPage->hasNoPriceForChannel($channelName),
sprintf('Product "%s" should not have price defined for channel "%s".', $product->getName(), $channelName)
);
}

View file

@ -20,6 +20,7 @@ use Sylius\Behat\Behaviour\SpecifiesItsCode;
use Sylius\Behat\Page\Admin\Crud\CreatePage as BaseCreatePage;
use Sylius\Behat\Service\AutocompleteHelper;
use Sylius\Behat\Service\SlugGenerationHelper;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\TaxonInterface;
use Sylius\Component\Product\Model\ProductAssociationTypeInterface;
use WebDriver\Exception;
@ -55,14 +56,14 @@ class CreateSimpleProductPage extends BaseCreatePage implements CreateSimpleProd
$this->getElement('slug', ['%locale%' => $locale])->setValue($slug);
}
public function specifyPrice(string $channelName, string $price): void
public function specifyPrice(ChannelInterface $channel, string $price): void
{
$this->getElement('price', ['%channelName%' => $channelName])->setValue($price);
$this->getElement('price', ['%channelCode%' => $channel->getCode()])->setValue($price);
}
public function specifyOriginalPrice(string $channelName, int $originalPrice): void
public function specifyOriginalPrice(ChannelInterface $channel, int $originalPrice): void
{
$this->getElement('original_price', ['%channelName%' => $channelName])->setValue($originalPrice);
$this->getElement('original_price', ['%channelCode%' => $channel->getCode()])->setValue($originalPrice);
}
public function addAttribute(string $attributeName, string $value, string $localeCode): void
@ -208,6 +209,11 @@ class CreateSimpleProductPage extends BaseCreatePage implements CreateSimpleProd
$this->getElement('shipping_required')->uncheck();
}
public function getChannelPricingValidationMessage(): string
{
return $this->getElement('prices_validation_message')->getText();
}
protected function getElement(string $name, array $parameters = []): NodeElement
{
if (!isset($parameters['%locale%'])) {
@ -228,7 +234,6 @@ class CreateSimpleProductPage extends BaseCreatePage implements CreateSimpleProd
'attribute_value' => '.tab[data-tab="%localeCode%"] .attribute .label:contains("%attributeName%") ~ input',
'attributes_choice' => '#sylius_product_attribute_choice',
'channel_checkbox' => '.checkbox:contains("%channelName%") input',
'channel_pricings' => '#sylius_product_variant_channelPricings',
'code' => '#sylius_product_code',
'form' => 'form[name="sylius_product"]',
'images' => '#sylius_product_images',
@ -236,8 +241,9 @@ class CreateSimpleProductPage extends BaseCreatePage implements CreateSimpleProd
'locale_tab' => '#attributesContainer .menu [data-tab="%localeCode%"]',
'main_taxon' => '#sylius_product_mainTaxon',
'name' => '#sylius_product_translations_%locale%_name',
'price' => '#sylius_product_variant_channelPricings > .field:contains("%channelName%") input[name$="[price]"]',
'original_price' => '#sylius_product_variant_channelPricings > .field:contains("%channelName%") input[name$="[originalPrice]"]',
'original_price' => '#sylius_product_variant_channelPricings input[name$="[originalPrice]"][id*="%channelCode%"]',
'price' => '#sylius_product_variant_channelPricings input[id*="%channelCode%"]',
'prices_validation_message' => '#sylius_product_variant_channelPricings ~ .sylius-validation-error, #sylius_product_variant_channelPricings .sylius-validation-error',
'price_calculator' => '#sylius_product_variant_pricingCalculator',
'shipping_category' => '#sylius_product_variant_shippingCategory',
'shipping_required' => '#sylius_product_variant_shippingRequired',

View file

@ -14,14 +14,15 @@ declare(strict_types=1);
namespace Sylius\Behat\Page\Admin\Product;
use Sylius\Behat\Page\Admin\Crud\CreatePageInterface as BaseCreatePageInterface;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\TaxonInterface;
use Sylius\Component\Product\Model\ProductAssociationTypeInterface;
interface CreateSimpleProductPageInterface extends BaseCreatePageInterface
{
public function specifyPrice(string $channelName, string $price): void;
public function specifyPrice(ChannelInterface $channel, string $price): void;
public function specifyOriginalPrice(string $channelName, int $originalPrice): void;
public function specifyOriginalPrice(ChannelInterface $channel, int $originalPrice): void;
public function choosePricingCalculator(string $name): void;
@ -57,4 +58,6 @@ interface CreateSimpleProductPageInterface extends BaseCreatePageInterface
public function selectShippingCategory(string $shippingCategoryName): void;
public function setShippingRequired(bool $isShippingRequired): void;
public function getChannelPricingValidationMessage(): string;
}

View file

@ -46,14 +46,14 @@ class UpdateSimpleProductPage extends BaseUpdatePage implements UpdateSimpleProd
}
}
public function specifyPrice(string $channelName, string $price): void
public function specifyPrice(ChannelInterface $channel, string $price): void
{
$this->getElement('price', ['%channelName%' => $channelName])->setValue($price);
$this->getElement('price', ['%channelCode%' => $channel->getCode()])->setValue($price);
}
public function specifyOriginalPrice(string $channelName, string $originalPrice): void
public function specifyOriginalPrice(ChannelInterface $channel, string $originalPrice): void
{
$this->getElement('original_price', ['%channelName%' => $channelName])->setValue($originalPrice);
$this->getElement('original_price', ['%channelCode%' => $channel->getCode()])->setValue($originalPrice);
}
public function addSelectedAttributes(): void
@ -318,14 +318,14 @@ class UpdateSimpleProductPage extends BaseUpdatePage implements UpdateSimpleProd
}
}
public function getPriceForChannel(string $channelName): string
public function getPriceForChannel(ChannelInterface $channel): string
{
return $this->getElement('price', ['%channelName%' => $channelName])->getValue();
return $this->getElement('price', ['%channelCode%' => $channel->getCode()])->getValue();
}
public function getOriginalPriceForChannel(string $channelName): string
public function getOriginalPriceForChannel(ChannelInterface $channel): string
{
return $this->getElement('original_price', ['%channelName%' => $channelName])->getValue();
return $this->getElement('original_price', ['%channelCode%' => $channel->getCode()])->getValue();
}
public function isShippingRequired(): bool
@ -383,6 +383,11 @@ class UpdateSimpleProductPage extends BaseUpdatePage implements UpdateSimpleProd
$this->getElement('enabled')->check();
}
public function hasNoPriceForChannel(string $channelName): bool
{
return strpos($this->getElement('prices')->getHtml(), $channelName) === false;
}
protected function getCodeElement(): NodeElement
{
return $this->getElement('code');
@ -411,8 +416,9 @@ class UpdateSimpleProductPage extends BaseUpdatePage implements UpdateSimpleProd
'language_tab' => '[data-locale="%locale%"] .title',
'locale_tab' => '#attributesContainer .menu [data-tab="%localeCode%"]',
'name' => '#sylius_product_translations_%locale%_name',
'original_price' => '#sylius_product_variant_channelPricings > .field:contains("%channelName%") input[name$="[originalPrice]"]',
'price' => '#sylius_product_variant_channelPricings > .field:contains("%channelName%") input[name$="[price]"]',
'prices' => '#sylius_product_variant_channelPricings',
'original_price' => '#sylius_product_variant_channelPricings input[name$="[originalPrice]"][id*="%channelCode%"]',
'price' => '#sylius_product_variant_channelPricings input[id*="%channelCode%"]',
'pricing_configuration' => '#sylius_calculator_container',
'main_taxon' => '#sylius_product_mainTaxon',
'shipping_required' => '#sylius_product_variant_shippingRequired',

View file

@ -25,9 +25,9 @@ interface UpdateSimpleProductPageInterface extends BaseUpdatePageInterface
public function isSlugReadonlyIn(string $locale): bool;
public function specifyPrice(string $channelName, string $price): void;
public function specifyPrice(ChannelInterface $channel, string $price): void;
public function specifyOriginalPrice(string $channelName, string $originalPrice): void;
public function specifyOriginalPrice(ChannelInterface $channel, string $originalPrice): void;
public function nameItIn(string $name, string $localeCode): void;
@ -89,9 +89,9 @@ interface UpdateSimpleProductPageInterface extends BaseUpdatePageInterface
public function specifySlugIn(string $slug, string $locale): void;
public function getPriceForChannel(string $channelName): string;
public function getPriceForChannel(ChannelInterface $channel): string;
public function getOriginalPriceForChannel(string $channelName): string;
public function getOriginalPriceForChannel(ChannelInterface $channel): string;
public function isShippingRequired(): bool;
@ -114,4 +114,6 @@ interface UpdateSimpleProductPageInterface extends BaseUpdatePageInterface
public function isEnabled(): bool;
public function enable(): void;
public function hasNoPriceForChannel(string $channelName): bool;
}

View file

@ -16,19 +16,20 @@ namespace Sylius\Behat\Page\Admin\ProductVariant;
use Behat\Mink\Exception\ElementNotFoundException;
use Sylius\Behat\Behaviour\SpecifiesItsCode;
use Sylius\Behat\Page\Admin\Crud\CreatePage as BaseCreatePage;
use Sylius\Component\Core\Model\ChannelInterface;
class CreatePage extends BaseCreatePage implements CreatePageInterface
{
use SpecifiesItsCode;
public function specifyPrice(string $price, string $channelName): void
public function specifyPrice(string $price, ChannelInterface $channel): void
{
$this->getElement('price', ['%channelName%' => $channelName])->setValue($price);
$this->getElement('price', ['%channelCode%' => $channel->getCode()])->setValue($price);
}
public function specifyOriginalPrice(string $originalPrice, string $channelName): void
public function specifyOriginalPrice(string $originalPrice, ChannelInterface $channel): void
{
$this->getElement('original_price', ['%channelName%' => $channelName])->setValue($originalPrice);
$this->getElement('original_price', ['%channelCode%' => $channel->getCode()])->setValue($originalPrice);
}
public function specifyCurrentStock(string $currentStock): void
@ -110,8 +111,8 @@ class CreatePage extends BaseCreatePage implements CreatePageInterface
'price_calculator' => '#sylius_product_variant_pricingCalculator',
'shipping_category' => '#sylius_product_variant_shippingCategory',
'shipping_required' => '#sylius_product_variant_shippingRequired',
'original_price' => '#sylius_product_variant_channelPricings > .field:contains("%channelName%") input[name$="[originalPrice]"]',
'price' => '#sylius_product_variant_channelPricings > .field:contains("%channelName%") input[name$="[price]"]',
'original_price' => '#sylius_product_variant_channelPricings input[name$="[originalPrice]"][id*="%channelCode%"]',
'price' => '#sylius_product_variant_channelPricings input[id*="%channelCode%"]',
'prices_validation_message' => '#sylius_product_variant_channelPricings ~ .sylius-validation-error, #sylius_product_variant_channelPricings .sylius-validation-error',
'weight' => '#sylius_product_variant_weight',
'width' => '#sylius_product_variant_width',

View file

@ -14,12 +14,13 @@ declare(strict_types=1);
namespace Sylius\Behat\Page\Admin\ProductVariant;
use Sylius\Behat\Page\Admin\Crud\CreatePageInterface as BaseCreatePageInterface;
use Sylius\Component\Core\Model\ChannelInterface;
interface CreatePageInterface extends BaseCreatePageInterface
{
public function specifyPrice(string $price, string $channelName): void;
public function specifyPrice(string $price, ChannelInterface $channelName): void;
public function specifyOriginalPrice(string $originalPrice, string $channelName): void;
public function specifyOriginalPrice(string $originalPrice, ChannelInterface $channelName): void;
public function specifyHeightWidthDepthAndWeight(string $height, string $width, string $depth, string $weight): void;

View file

@ -16,6 +16,7 @@ namespace Sylius\Behat\Page\Admin\ProductVariant;
use Behat\Mink\Element\NodeElement;
use Behat\Mink\Exception\ElementNotFoundException;
use FriendsOfBehat\PageObjectExtension\Page\SymfonyPage;
use Sylius\Component\Core\Model\ChannelInterface;
class GeneratePage extends SymfonyPage implements GeneratePageInterface
{
@ -24,9 +25,9 @@ class GeneratePage extends SymfonyPage implements GeneratePageInterface
$this->getDocument()->pressButton('Generate');
}
public function specifyPrice(int $nth, int $price, string $channelName): void
public function specifyPrice(int $nth, int $price, ChannelInterface $channel): void
{
$this->getElement('price', ['%position%' => $nth, '%channelName%' => $channelName])->setValue($price);
$this->getElement('price', ['%position%' => $nth, '%channelCode%' => $channel->getCode()])->setValue($price);
}
public function specifyCode(int $nth, string $code): void
@ -66,7 +67,7 @@ class GeneratePage extends SymfonyPage implements GeneratePageInterface
{
return array_merge(parent::getDefinedElements(), [
'code' => '#sylius_product_generate_variants_variants_%position%_code',
'price' => '#sylius_product_generate_variants_variants_%position%_channelPricings > .field:contains("%channelName%") input',
'price' => '#sylius_product_generate_variants_variants_%position%_channelPricings input[id*="%channelCode%"]',
'prices_validation_message' => '#sylius_product_generate_variants_variants_%position%_channelPricings ~ .sylius-validation-error',
]);
}

View file

@ -14,12 +14,13 @@ declare(strict_types=1);
namespace Sylius\Behat\Page\Admin\ProductVariant;
use FriendsOfBehat\PageObjectExtension\Page\SymfonyPageInterface;
use Sylius\Component\Core\Model\ChannelInterface;
interface GeneratePageInterface extends SymfonyPageInterface
{
public function generate(): void;
public function specifyPrice(int $nth, int $price, string $channelName): void;
public function specifyPrice(int $nth, int $price, ChannelInterface $channel): void;
public function specifyCode(int $nth, string $code): void;

View file

@ -55,14 +55,14 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
return $priceElement->find('css', 'input')->getValue();
}
public function getPriceForChannel(string $channelName): string
public function getPriceForChannel(ChannelInterface $channel): string
{
return $this->getElement('price', ['%channelName%' => $channelName])->getValue();
return $this->getElement('price', ['%channelCode%' => $channel->getCode()])->getValue();
}
public function getOriginalPriceForChannel(string $channelName): string
public function getOriginalPriceForChannel(ChannelInterface $channel): string
{
return $this->getElement('original_price', ['%channelName%' => $channelName])->getValue();
return $this->getElement('original_price', ['%channelCode%' => $channel->getCode()])->getValue();
}
public function getNameInLanguage(string $language): string
@ -112,8 +112,8 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
'name' => '#sylius_product_variant_translations_%language%_name',
'on_hand' => '#sylius_product_variant_onHand',
'option_values' => '#sylius_product_variant_optionValues_%optionName%',
'original_price' => '#sylius_product_variant_channelPricings > .field:contains("%channelName%") input[name$="[originalPrice]"]',
'price' => '#sylius_product_variant_channelPricings > .field:contains("%channelName%") input[name$="[price]"]',
'original_price' => '#sylius_product_variant_channelPricings input[name$="[originalPrice]"][id*="%channelCode%"]',
'price' => '#sylius_product_variant_channelPricings input[id*="%channelCode%"]',
'pricing_configuration' => '#sylius_calculator_container',
'shipping_required' => '#sylius_product_variant_shippingRequired',
'show_product_dropdown' => '.scrolling.menu',

View file

@ -33,9 +33,9 @@ interface UpdatePageInterface extends BaseUpdatePageInterface
public function getPricingConfigurationForChannelAndCurrencyCalculator(ChannelInterface $channel, CurrencyInterface $currency): string;
public function getPriceForChannel(string $channelName): string;
public function getPriceForChannel(ChannelInterface $channel): string;
public function getOriginalPriceForChannel(string $channelName): string;
public function getOriginalPriceForChannel(ChannelInterface $channel): string;
public function getNameInLanguage(string $language): string;

View file

@ -44,6 +44,8 @@ sylius:
header: Sales
orders: Orders
ui:
product:
product_not_active_in_channel: The product is not yet activated in this channel.
gateway:
no_sca_support_notice: The chosen payment gateway does not support SCA.
sales_summary: Sales summary

View file

@ -29,13 +29,16 @@
</div>
<div class="column">
{{ form_row(form.channels) }}
{% if product.simple %}
<h4 class="ui dividing header">{{ 'sylius.ui.pricing'|trans }}</h4>
{{ form_row(form.variant.channelPricings, {'label': false}) }}
{% endif %}
</div>
</div>
{% if product.simple %}
<div class="ui one column stackable grid">
<div class="column">
<h4 class="ui dividing header">{{ 'sylius.ui.pricing'|trans }}</h4>
{% include "@SyliusAdmin/Product/_channel_pricing.html.twig" with { product: product, variantForm: form.variant } only %}
</div>
</div>
{% endif %}
<div class="ui hidden divider"></div>
{{ translationFormWithSlug(form.translations, '@SyliusAdmin/Product/_slugField.html.twig', product) }}
{% if product.simple %}

View file

@ -0,0 +1,27 @@
<div id="sylius_product_variant_channelPricings">
{{ form_errors(variantForm.channelPricings) }}
<div class="ui top attached tabular menu">
{% for channelCode, channelPricing in variantForm.channelPricings %}
{% if loop.index0 == 0 %}
<a class="item active" data-tab="{{ channelCode }}">{{ channelPricing.vars.label }}</a>
{% else %}
<a class="item" data-tab="{{ channelCode }}">{{ channelPricing.vars.label }}</a>
{% endif %}
{% endfor %}
</div>
{% for channelCode, channelPricing in variantForm.channelPricings %}
{% if loop.index0 == 0 %}
<div class="ui bottom attached active tab segment" data-tab="{{ channelCode }}">
{% else %}
<div class="ui bottom attached tab segment" data-tab="{{ channelCode }}">
{% endif %}
{% if channelCode not in product.channels|map(channel => channel.code) %}
<div class="ui info message">
{{ 'sylius.ui.product.product_not_active_in_channel'|trans }}
</div>
{% endif %}
{{ form_row(channelPricing, {'label': false}) }}
</div>
{% endfor %}
</div>

View file

@ -12,7 +12,8 @@
<div class="two fields">
{{ form_row(form.shippingCategory) }}
</div>
{{ form_row(form.channelPricings) }}
{{form_label(form.channelPricings)}}
{% include "@SyliusAdmin/Product/_channel_pricing.html.twig" with { product: product_variant.product, variantForm: form } only %}
</div>
<div class="ui segment">
<div class="one field">