A custom field formatter may be added that would display the customised price next to the original base price. It could also provide the option to display an explanation on what is the reason for the customised price.

Comments

krystalcode created an issue. See original summary.

sorabh.v6’s picture

Assigned: Unassigned » sorabh.v6
sorabh.v6’s picture

StatusFileSize
new2.23 KB

Patchfile uploaded for field formatter. This formatter shows customised price i.e. it shows striked default price and next to it shows new price. I tried to show 'reason for the customised price' as required in the issue summary but I think for 'reason for the customised price' we will need a new field in price rule entity. @krystalcode What do you suggest?

sorabh.v6’s picture

Assigned: sorabh.v6 » Unassigned
Status: Active » Needs review
subhojit777’s picture

Status: Needs review » Needs work
  1. +++ b/src/Plugin/Field/FieldFormatter/PriceRuleFormatter.php
    @@ -0,0 +1,55 @@
    +      $purchasable_entity = $items->getEntity();
    

    I think it should be $item->getEntity()

  2. +++ b/src/Plugin/Field/FieldFormatter/PriceRuleFormatter.php
    @@ -0,0 +1,55 @@
    +      $number = $resolved_price->getNumber();
    

    Can we mention the data type here.

  3. +++ b/src/Plugin/Field/FieldFormatter/PriceRuleFormatter.php
    @@ -0,0 +1,55 @@
    +      $currency = $this->currencyStorage->load($resolved_price->getCurrencyCode());
    

    Can we mention the data type here as well.

  4. +++ b/src/Plugin/Field/FieldFormatter/PriceRuleFormatter.php
    @@ -0,0 +1,55 @@
    +        '#markup' => '<del>' . $default_price . '</del>&nbsp;' . $new_price,
    

    It is recommended to use #plain_text here, or Xss::filterAdmin()

sorabh.v6’s picture

@subhojit777 I referred this code from the price module`s PriceCalculatedFormatter. These things are there as it is. But if you still think that this patch needs your mentioned changes then I will do it.

subhojit777’s picture

subhojit777’s picture

I think it should be $item->getEntity()

I am quite sure about this one. Rest of them are code improvements, and writing more secure code.

sorabh.v6’s picture

+++ b/src/Plugin/Field/FieldFormatter/PriceRuleFormatter.php
@@ -0,0 +1,55 @@
+  public function viewElements(FieldItemListInterface $items, $langcode) {
+    $context = new Context($this->currentUser, $this->currentStore->getStore());
+    $elements = [];
+    /** @var \Drupal\commerce_price\Plugin\Field\FieldType\PriceItem $item */
+    foreach ($items as $delta => $item) {
+      /** @var \Drupal\commerce\PurchasableEntityInterface $purchasable_entity */
+      $purchasable_entity = $items->getEntity();

See its $items provided in viewElements() method as argument. Therefore, I will need to change that argument to $item is I make change suggested by you. Its same as in PriceCalculatedFormatter.

subhojit777’s picture

I am talking about the $item in the loop foreach ($items as $delta => $item)

sorabh.v6’s picture

Status: Needs work » Needs review
StatusFileSize
new1.62 KB
new2.22 KB

As per discussion with @subhojit777 over the chat -

+      /** @var \Drupal\commerce\PurchasableEntityInterface $purchasable_entity */
+      $purchasable_entity = $items->getEntity();
+      $resolved_price = $this->chainPriceResolver->resolve($purchasable_entity, 1, $context);
+      $number = $resolved_price->getNumber();
+      $currency = $this->currencyStorage->load($resolved_price->getCurrencyCode());
+      $default_price = $this->numberFormatter->formatCurrency($item->number, $currency);
+      $new_price = $this->numberFormatter->formatCurrency($number, $currency);

This hunk of code should be outside of the loop.

New patch contains above changes. Please review.

subhojit777’s picture

Status: Needs review » Needs work
+++ b/src/Plugin/Field/FieldFormatter/PriceRuleFormatter.php
@@ -0,0 +1,55 @@
+        '#cache' => [
+          'tags' => $purchasable_entity->getCacheTags(),
+          'contexts' => Cache::mergeContexts($purchasable_entity->getCacheContexts(), [
+            'languages:' . LanguageInterface::TYPE_INTERFACE,
+            'country',
+          ]),
+        ],

Since cache tag only dependes on $purchasable_entity, therefore it can be created as an array variable outside the loop. We can then just use the variable in #cache

sorabh.v6’s picture

Status: Needs work » Needs review
StatusFileSize
new1.34 KB
new2.22 KB

Patch updated with changes mentioned in #12. Please review.

subhojit777’s picture

Patch looks good to me.

mrpauldriver’s picture

This looks interesting. Can it be used yet?

jwwj’s picture

Old thread, so probably not valid anymore. But just thought I'd mention the patch in #13 does not work for me. Failed with

Error: Call to a member function load() on null in Drupal\commerce_price_rule\Plugin\Field\FieldFormatter\PriceRuleFormatter->viewElements() (line 35 of modules/contrib/commerce_price_rule/src/Plugin/Field/FieldFormatter/PriceRuleFormatter.php).

This against the 1.0@alpha version. I did a quick check and the PriceCalculatedFormatter class that this patch extends does not have a field called currencyStorage, so that's probably why the null pointer exception. Seems the base repository has moved on since this patch was created...

daniel korte’s picture

#16 should be fixed. Also, the last patch did not check if there was a new price or not so it was possible for the formatter to show $10 $10. This new patch will use the parent formatter (“Calculated”) when there isn’t a cheaper price.