I have a store setup with 2 products. Public and private tours. Public tours are 10 for each unit.
Private tours on the other hand are only meant to collect a deposit. I need the total to be $50 no matter the quantity selected and the rest is paid on site.
I tried creating a custom PromotionOffer as seen below. I can create the promotion but it doesn’t seem to apply while in the cart/checkout. I even tried making it a coupon and when I apply the coupon it says its not valid, may have expired or been used. I have one condition set and that is they have a private tour in their cart.
<?php namespace Drupaltour_reservationPluginCommercePromotionOffer; use Drupalcommerce_orderAdjustment; use Drupalcommerce_pricePrice; use Drupalcommerce_promotionEntityPromotionInterface; use Drupalcommerce_promotionPluginCommercePromotionOfferPromotionOfferBase; use DrupalCoreEntityEntityInterface; use DrupalCoreFormFormStateInterface; /** * Discounts a cart to a fixed amount. * * @CommercePromotionOffer( * id = "tour_reservation_discount_to_fixed", * label = @Translation("Sets cart total to a fixed amount"), * entity_type = "commerce_order_item", * ) */ class OrderFixedPrice extends PromotionOfferBase { /** * {@inheritdoc} */ public function defaultConfiguration() { return [ 'amount' => NULL, ] + parent::defaultConfiguration(); } /** * {@inheritdoc} */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { $form += parent::buildConfigurationForm($form, $form_state); $amount = $this->configuration['amount']; // A bug in the plugin_select form element causes $amount to be incomplete. if (isset($amount) && !isset($amount['number'], $amount['currency_code'])) { $amount = NULL; } $form['amount'] = [ '#type' => 'commerce_price', '#title' => $this->t('Amount'), '#default_value' => $amount, '#required' => TRUE, '#description' => $this->t('Set cart price. Format: 9.99'), ]; return $form; } /** * {@inheritdoc} */ public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { $values = $form_state->getValue($form['#parents']); if ($values['amount']['number'] < 0) { $form_state->setError($form, $this->t('Amount cannot be negative.')); } } /** * {@inheritdoc} */ public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { parent::submitConfigurationForm($form, $form_state); $values = $form_state->getValue($form['#parents']); $this->configuration['amount'] = $values['amount']; } /** * {@inheritdoc} */ public function apply(EntityInterface $entity, PromotionInterface $promotion) { $this->assertEntity($entity); /** @var Drupalcommerce_orderEntityOrderItemInterface $order_item */ $order_item = $entity; $target_amount = $this->getAmount(); $order_item->addAdjustment(new Adjustment([ 'type' => 'promotion', 'label' => t('Discount'), 'amount' => $target_amount, 'source_id' => $promotion->id(), ])); } /** * Gets the offer amount. * * @return Drupalcommerce_pricePrice|null * The amount, or NULL if unknown. */ protected function getAmount() { if (!empty($this->configuration['amount'])) { $amount = $this->configuration['amount']; return new Price($amount['number'], $amount['currency_code']); } } }
Ideally, I dont want to use promotions and rather just adjust the price in the cart. Any ideas?