Skip to content

Commit

Permalink
[UI] added display of product variant original price on product page
Browse files Browse the repository at this point in the history
  • Loading branch information
JulienLoison committed May 22, 2020
1 parent a00d41e commit c8f7e40
Show file tree
Hide file tree
Showing 11 changed files with 100 additions and 9 deletions.
@@ -0,0 +1,25 @@
@viewing_products
Feature: Viewing different discounted price for different product variants
In order to see product variant discounted price
As a Visitor
I want to be able to see a proper discounted price for each product variant

Background:
Given the store operates on a single channel in "United States"
And the store has a "Wyborowa Vodka" configurable product
And the product "Wyborowa Vodka" has "Wyborowa Vodka Exquisite" variant priced at "$40.00"
And the product "Wyborowa Vodka" has "Wyborowa Apple" variant priced at "$12.55"
And the "Wyborowa Apple" product variant has original price at "$20.00"

@ui
Scenario: Viewing a detailed page with default variant's price without discount
When I view product "Wyborowa Vodka"
Then the product price should be "$40.00"
And I should not see any original price

@ui @javascript
Scenario: Viewing a detailed page with product's discount price for different variant
When I view product "Wyborowa Vodka"
And I select "Wyborowa Apple" variant
Then the product price should be "$12.55"
And the product original price should be "$20.00"
12 changes: 12 additions & 0 deletions src/Sylius/Behat/Context/Setup/ProductContext.php
Expand Up @@ -878,6 +878,18 @@ public function productHasVariant(ProductInterface $product, string $productVari
$this->createProductVariant($product, $productVariantName, $priceValue, $code, $channel, null, true, $currentStock);
}

/**
* @Given /^the ("[^"]+" product variant) has original price at ("[^"]+")$/
*/
public function productVariantHasOriginalPrice(ProductVariantInterface $productVariant, int $price)
{
/** @var ChannelInterface $channel */
$channel = $this->sharedStorage->get('channel');

$productVariant->getChannelPricingForChannel($channel)->setOriginalPrice($price);
$this->objectManager->flush();
}

/**
* @Given the store has a product :productName in channel :channel
* @Given the store also has a product :productName in channel :channel
Expand Down
9 changes: 9 additions & 0 deletions src/Sylius/Behat/Context/Ui/Shop/ProductContext.php
Expand Up @@ -306,9 +306,18 @@ public function iShouldSeeTheProductPrice($price)
*/
public function iShouldSeeTheProductOriginalPrice($price)
{
Assert::true($this->showPage->isOriginalPriceVisible());
Assert::same($this->showPage->getOriginalPrice(), $price);
}

/**
* @Then I should not see any original price
*/
public function iShouldNotSeeTheProductOriginalPrice()
{
Assert::false($this->showPage->isOriginalPriceVisible());
}

/**
* @When I set its :optionName to :optionValue
*/
Expand Down
9 changes: 9 additions & 0 deletions src/Sylius/Behat/Page/Shop/Product/ShowPage.php
Expand Up @@ -133,6 +133,15 @@ public function getOriginalPrice(): string
return $this->getElement('product_original_price')->getText();
}

public function isOriginalPriceVisible(): bool
{
try {
return null !== $this->getElement('product_original_price')->find('css','del');
} catch (ElementNotFoundException $elementNotFoundException) {
return false;
}
}

public function hasAddToCartButton(): bool
{
if (!$this->hasElement('add_to_cart_button')) {
Expand Down
2 changes: 2 additions & 0 deletions src/Sylius/Behat/Page/Shop/Product/ShowPageInterface.php
Expand Up @@ -56,6 +56,8 @@ public function getPrice(): string;

public function getOriginalPrice(): string;

public function isOriginalPriceVisible(): bool;

public function hasAddToCartButton(): bool;

public function hasAssociation(string $productAssociationName): bool;
Expand Down
Expand Up @@ -20,10 +20,17 @@ const handleProductOptionsChange = function handleProductOptionsChange() {
});

const price = $('#sylius-variants-pricing').find(selector).attr('data-value');
const originalPrice = $('#sylius-variants-pricing').find(selector).attr('data-original-price');

if (price !== undefined) {
$('#product-price').text(price);
$('button[type=submit]').removeAttr('disabled');

if (originalPrice !== undefined) {
$('#product-original-price').css('display', 'inline').html(`<del>${originalPrice}</del>`);
} else {
$('#product-original-price').css('display', 'none');
}
} else {
$('#product-price').text($('#sylius-variants-pricing').attr('data-unavailable-text'));
$('button[type=submit]').attr('disabled', 'disabled');
Expand All @@ -33,8 +40,16 @@ const handleProductOptionsChange = function handleProductOptionsChange() {

const handleProductVariantsChange = function handleProductVariantsChange() {
$('[name="sylius_add_to_cart[cartItem][variant]"]').on('change', (event) => {
const price = $(event.currentTarget).parents('tr').find('.sylius-product-variant-price').text();
const priceRow = $(event.currentTarget).parents('tr').find('.sylius-product-variant-price');
const price = priceRow.text();
const originalPrice = priceRow.attr('data-original-price');
$('#product-price').text(price);

if (originalPrice !== undefined) {
$('#product-original-price').css('display', 'inline').html(`<del>${originalPrice}</del>`);
} else {
$('#product-original-price').css('display', 'none');
}
});
};

Expand Down
Expand Up @@ -3,11 +3,11 @@
{% set variant = product|sylius_resolve_variant %}
{% set hasDiscount = variant|sylius_has_discount({'channel': sylius.channel}) %}

{% if hasDiscount %}
<span class="ui small header" id="product-original-price" {{ sylius_test_html_attribute('product-original-price', money.calculateOriginalPrice(variant)) }}>
<span class="ui small header" id="product-original-price" {{ sylius_test_html_attribute('product-original-price', money.calculateOriginalPrice(variant)) }}>
{% if hasDiscount %}
<del>{{ money.calculateOriginalPrice(variant) }}</del>
</span>
{% endif %}
{% endif %}
</span>

<span class="ui huge header" id="product-price" {{ sylius_test_html_attribute('product-price', money.calculatePrice(variant)) }}>
{{ money.calculatePrice(variant) }}
Expand Down
Expand Up @@ -23,7 +23,9 @@
</div>
{% endif %}
</td>
<td class="sylius-product-variant-price">{{ money.calculatePrice(variant) }}</td>
<td class="sylius-product-variant-price" {% if variant|sylius_has_discount({'channel': sylius.channel}) %}data-original-price="{{ money.calculateOriginalPrice(variant) }}"{% endif %}>
{{ money.calculatePrice(variant) }}
</td>
<td class="right aligned">
{{ form_widget(form.cartItem.variant[key], {'label': false}) }}
</td>
Expand Down
Expand Up @@ -2,6 +2,6 @@

<div id="sylius-variants-pricing" data-unavailable-text="{{ 'sylius.ui.unavailable'|trans }}">
{% for price in pricing %}
<div {% for option, value in price %}data-{{ option }}="{% if option == 'value' %}{{ money.convertAndFormat(value) }}{% else %}{{ value|replace({'\"': '\''}) }}{% endif %}" {{ sylius_test_html_attribute('variant-price') }}{% endfor %}></div>
<div {% for option, value in price %}data-{{ option }}="{% if option == 'value' or option == 'original-price' %}{{ money.convertAndFormat(value) }}{% else %}{{ value|replace({'\"': '\''}) }}{% endif %}" {{ sylius_test_html_attribute('variant-price') }}{% endfor %}></div>
{% endfor %}
</div>
Expand Up @@ -14,10 +14,12 @@
namespace Sylius\Component\Core\Provider;

use Sylius\Component\Core\Calculator\ProductVariantPriceCalculatorInterface;
use Sylius\Component\Core\Calculator\ProductVariantPricesCalculatorInterface;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Core\Model\ProductVariantInterface;
use Sylius\Component\Product\Model\ProductOptionValueInterface;
use Webmozart\Assert\Assert;

final class ProductVariantsPricesProvider implements ProductVariantsPricesProviderInterface
{
Expand Down Expand Up @@ -53,7 +55,15 @@ private function constructOptionsMap(ProductVariantInterface $variant, ChannelIn
$optionMap[$option->getOptionCode()] = $option->getCode();
}

$optionMap['value'] = $this->productVariantPriceCalculator->calculate($variant, ['channel' => $channel]);
$price = $this->productVariantPriceCalculator->calculate($variant, ['channel' => $channel]);
$optionMap['value'] = $price;

Assert::isInstanceOf($this->productVariantPriceCalculator, ProductVariantPricesCalculatorInterface::class);
$originalPrice = $this->productVariantPriceCalculator->calculateOriginal($variant, ['channel' => $channel]);

if ($originalPrice > $price) {
$optionMap['original-price'] = $originalPrice;
}

return $optionMap;
}
Expand Down
Expand Up @@ -16,6 +16,7 @@
use Doctrine\Common\Collections\ArrayCollection;
use PhpSpec\ObjectBehavior;
use Sylius\Component\Core\Calculator\ProductVariantPriceCalculatorInterface;
use Sylius\Component\Core\Calculator\ProductVariantPricesCalculatorInterface;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Core\Model\ProductVariantInterface;
Expand Down Expand Up @@ -45,7 +46,7 @@ function it_provides_array_containing_product_variant_options_map_with_correspon
ProductVariantInterface $blackSmallTShirt,
ProductVariantInterface $whiteLargeTShirt,
ProductVariantInterface $whiteSmallTShirt,
ProductVariantPriceCalculatorInterface $productVariantPriceCalculator
ProductVariantPricesCalculatorInterface $productVariantPriceCalculator
): void {
$tShirt->getVariants()->willReturn(new ArrayCollection([
$blackSmallTShirt->getWrappedObject(),
Expand All @@ -68,9 +69,13 @@ function it_provides_array_containing_product_variant_options_map_with_correspon
);

$productVariantPriceCalculator->calculate($blackSmallTShirt, ['channel' => $channel])->willReturn(1000);
$productVariantPriceCalculator->calculateOriginal($blackSmallTShirt, ['channel' => $channel])->willReturn(1000);
$productVariantPriceCalculator->calculate($whiteSmallTShirt, ['channel' => $channel])->willReturn(1500);
$productVariantPriceCalculator->calculateOriginal($whiteSmallTShirt, ['channel' => $channel])->willReturn(2000);
$productVariantPriceCalculator->calculate($blackLargeTShirt, ['channel' => $channel])->willReturn(2000);
$productVariantPriceCalculator->calculateOriginal($blackLargeTShirt, ['channel' => $channel])->willReturn(2000);
$productVariantPriceCalculator->calculate($whiteLargeTShirt, ['channel' => $channel])->willReturn(2500);
$productVariantPriceCalculator->calculateOriginal($whiteLargeTShirt, ['channel' => $channel])->willReturn(3000);

$black->getOptionCode()->willReturn('t_shirt_color');
$white->getOptionCode()->willReturn('t_shirt_color');
Expand All @@ -92,6 +97,7 @@ function it_provides_array_containing_product_variant_options_map_with_correspon
't_shirt_color' => 'white',
't_shirt_size' => 'small',
'value' => 1500,
'original-price' => 2000,
],
[
't_shirt_color' => 'black',
Expand All @@ -102,6 +108,7 @@ function it_provides_array_containing_product_variant_options_map_with_correspon
't_shirt_color' => 'white',
't_shirt_size' => 'large',
'value' => 2500,
'original-price' => 3000,
],
]);
}
Expand Down

0 comments on commit c8f7e40

Please sign in to comment.