Last active
June 3, 2022 09:14
Revisions
-
WengerK revised this gist
Jun 3, 2022 . 3 changed files with 228 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,113 @@ <?php namespace Drupal\my_custom_commerce_range_condition\Plugin\Commerce\Condition; use Drupal\commerce\Plugin\Commerce\Condition\ConditionBase; use Drupal\commerce_price\Price; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Form\FormStateInterface; /** * Provides the total price range condition for orders. * * To be used when willing to trigger condition when the order total falls * within a range of price (including adjustments) * e.g. $100 => order total <= $200. * * @CommerceCondition( * id="order_total_price_range", * label=@Translation("Total price range"), * display_label=@Translation("Current order total within a range"), * category=@Translation("Order", context="Commerce"), * entity_type="commerce_order", * ) */ class OrderTotalPriceRange extends ConditionBase { /** * {@inheritdoc} */ public function defaultConfiguration() { return [ 'amount_from' => NULL, 'amount_to' => NULL, ] + parent::defaultConfiguration(); } /** * {@inheritdoc} */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { $form = parent::buildConfigurationForm($form, $form_state); $amount_from = $this->configuration['amount_from']; $amount_to = $this->configuration['amount_to']; // An #ajax bug can cause $amount_from to be incomplete. if (isset($amount_from) && !isset($amount_from['number'], $amount_from['currency_code'])) { $amount_from = NULL; } // An #ajax bug can cause $amount_to to be incomplete. if (isset($amount_to) && !isset($amount_to['number'], $amount_to['currency_code'])) { $amount_to = NULL; } $form['amount_from'] = [ '#type' => 'commerce_price', '#title' => $this->t('Amount from'), '#default_value' => $amount_from, '#required' => TRUE, ]; $form['amount_to'] = [ '#type' => 'commerce_price', '#title' => $this->t('Amount to'), '#default_value' => $amount_to, '#required' => TRUE, ]; return $form; } /** * {@inheritdoc} */ public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { parent::submitConfigurationForm($form, $form_state); $values = $form_state->getValue($form['#parents']); $this->configuration['amount_from'] = $values['amount_from']; $this->configuration['amount_to'] = $values['amount_to']; } /** * {@inheritdoc} */ public function evaluate(EntityInterface $entity) { $this->assertEntity($entity); /** @var \Drupal\commerce_order\Entity\OrderInterface $order */ $order = $entity; $total_price = $order->getTotalPrice(); if (!$total_price) { return FALSE; } $condition_price_from = Price::fromArray($this->configuration['amount_from']); if ($total_price->getCurrencyCode() !== $condition_price_from->getCurrencyCode()) { return FALSE; } $condition_price_to = Price::fromArray($this->configuration['amount_to']); if ($total_price->getCurrencyCode() !== $condition_price_to->getCurrencyCode()) { return FALSE; } return $total_price->greaterThanOrEqual($condition_price_from) && $total_price->lessThanOrEqual($condition_price_to); } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,106 @@ <?php namespace Drupal\Tests\my_custom_commerce_range_condition\Unit\Plugin\Commerce\Condition; use Drupal\commerce_order\Entity\OrderInterface; use Drupal\commerce_price\Price; use Drupal\my_custom_commerce_range_condition\Plugin\Commerce\Condition\OrderTotalPriceRange; use Drupal\Tests\UnitTestCase; /** * @coversDefaultClass \Drupal\my_custom_commerce_range_condition\Plugin\Commerce\Condition\OrderTotalPriceRange * @group commerce * * @internal */ final class OrderTotalPriceRangeRangeTest extends UnitTestCase { /** * ::covers evaluate. */ public function testEmptyOrder() { $condition = new OrderTotalPriceRange([ 'amount_from' => [ 'number' => '10.00', 'currency_code' => 'EUR', ], 'amount_to' => [ 'number' => '25.00', 'currency_code' => 'EUR', ], ], 'order_total_price', ['entity_type' => 'commerce_order']); $order = $this->prophesize(OrderInterface::class); $order->getEntityTypeId()->willReturn('commerce_order'); $order->getTotalPrice()->willReturn(NULL); $order = $order->reveal(); self::assertFalse($condition->evaluate($order)); } /** * ::covers evaluate. */ public function testMismatchedCurrencies() { $condition = new OrderTotalPriceRange([ 'amount_from' => [ 'number' => '10.00', 'currency_code' => 'EUR', ], 'amount_to' => [ 'number' => '25.00', 'currency_code' => 'EUR', ], ], 'order_total_price', ['entity_type' => 'commerce_order']); $order = $this->prophesize(OrderInterface::class); $order->getEntityTypeId()->willReturn('commerce_order'); $order->getTotalPrice()->willReturn(new Price('10.00', 'USD')); $order = $order->reveal(); self::assertFalse($condition->evaluate($order)); } /** * ::covers evaluate. * * @dataProvider totalPriceProvider */ public function testEvaluate($amount_from, $amount_to, $given_total_price, $result) { $condition = new OrderTotalPriceRange([ 'amount_from' => [ 'number' => $amount_from, 'currency_code' => 'USD', ], 'amount_to' => [ 'number' => $amount_to, 'currency_code' => 'USD', ], ], 'order_total_price', ['entity_type' => 'commerce_order']); $order = $this->prophesize(OrderInterface::class); $order->getEntityTypeId()->willReturn('commerce_order'); $order->getTotalPrice()->willReturn(new Price($given_total_price, 'USD')); $order = $order->reveal(); self::assertEquals($result, $condition->evaluate($order)); } /** * Data provider for ::testEvaluate. * * @return array * A list of testEvaluate function arguments. */ public function totalPriceProvider() { return [ [10, 25, 5, FALSE], [10, 25, 9, FALSE], [10, 25, 10, TRUE], [10, 25, 11, TRUE], [10, 25, 20, TRUE], [10, 25, 24, TRUE], [10, 25, 25, TRUE], [10, 25, 26, FALSE], [10, 25, 100, FALSE], ]; } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,9 @@ name: My Custom Commerce Range Condition type: module description: Module used to handle Commerce Range Condition core_version_requirement: ^9.1 package: Commerce dependencies: - commerce:commerce - commerce:commerce_order - commerce:commerce_product -
WengerK created this gist
Jun 3, 2022 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,7 @@ # Article Ressources - How to setup a Drupal Commerce Order total range condition This is the Gist repository for my article **Drupal Commerce Order total range condition**. Be aware that this article has been wrote for the Blog of [Antistatique](https://antistatique.net) — Web Agency in Lausanne, Switzerland. A place where I work as Full Stack Web Developer. Feel free to read it the full article on [Medium](https://medium.com/@WengerK) or check it out on [Antistatique](https://antistatique.net).