- Issue created by @bakerrac12
there isn't the ability to set percentages (at least for drupal 10.4.4)
setting a number for the tip in increments of 1 cents isn't very useful so I suggest the tip inline form gets changed to the following (apologies I don't think I can commit code to this project?)
<?php
namespace Drupal\commerce_tip\Plugin\Commerce\InlineForm;
use CommerceGuys\Intl\Formatter\CurrencyFormatterInterface;
use Drupal\commerce\Plugin\Commerce\InlineForm\InlineFormBase;
use Drupal\commerce_order\Adjustment;
use Drupal\commerce_order\Entity\OrderInterface;
use Drupal\commerce_price\Price;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides an inline form for Tip.
*
* @CommerceInlineForm(
* id = "commerce_tip_inline_form",
* label = @Translation("Tip InlineForm"),
* )
*/
class TipInlineForm extends InlineFormBase {
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected EntityTypeManagerInterface $entityTypeManager;
/**
* The currency formatter.
*
* @var \CommerceGuys\Intl\Formatter\CurrencyFormatterInterface
*/
protected CurrencyFormatterInterface $currencyFormatter;
/**
* Constructs a new TipInlineForm object.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \CommerceGuys\Intl\Formatter\CurrencyFormatterInterface $currency_formatter
* The currency formatter.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, CurrencyFormatterInterface $currency_formatter) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->entityTypeManager = $entity_type_manager;
$this->currencyFormatter = $currency_formatter;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('entity_type.manager'),
$container->get('commerce_price.currency_formatter')
);
}
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
return [
// The order_id is passed via configuration to avoid serializing the
// order, which is loaded from scratch in the submit handler to minimize
// chances of a conflicting save.
'order_id' => '',
'tip_description' => [
'value' => '',
'format' => 'plain_text',
],
];
}
/**
* {@inheritdoc}
*/
protected function requiredConfiguration() {
return ['order_id'];
}
/**
* {@inheritdoc}
*/
public function buildInlineForm(array $inline_form, FormStateInterface $form_state) {
$inline_form = parent::buildInlineForm($inline_form, $form_state);
/** @var \Drupal\commerce_order\Entity\Order $order */
$order = $this->entityTypeManager->getStorage('commerce_order')->load($this->configuration['order_id']);
if (!$order) {
throw new \RuntimeException('Invalid order_id given to the coupon_redemption inline form.');
}
assert($order instanceof OrderInterface);
$form_state->set('inline_configuration', $this->getConfiguration());
$inline_form = [
'#tree' => TRUE,
] + $inline_form;
if ($this->configuration['tip_description'] && $this->configuration['tip_description']['value'] && $this->configuration['tip_description']['format']) {
$inline_form['tip_description'] = [
'#type' => 'container',
'#attributes' => [
'class' => ['tip-description-container'],
],
];
$inline_form['tip_description']['description'] = [
'#type' => 'processed_text',
'#text' => $this->configuration['tip_description']['value'],
'#format' => $this->configuration['tip_description']['format'],
];
}
$inline_form['tip_info'] = [
'#type' => 'container',
'#attributes' => [
'class' => ['tip-info-container'],
],
];
$inline_form['tip_info']['tip'] = [
'#type' => 'select',
'#options' => [10=>'10%',15=> '15%', 18=> '18%', 20=>'20%'],
];
$inline_form['tip_info']['add_tip'] = [
'#type' => 'submit',
'#value' => t('Add'),
'#name' => 'add_tip',
'#limit_validation_errors' => [
$inline_form['#parents'],
],
'#submit' => [[get_called_class(), 'addTip']],
'#ajax' => [
'callback' => [get_called_class(), 'ajaxRefreshForm'],
'element' => $inline_form['#parents'],
],
];
$adjustments = $order->getAdjustments();
$hide_tip = FALSE;
foreach ($adjustments as $index => $adjustment) {
$type = $adjustment->getType();
$label = $adjustment->getLabel();
$sourceId = $adjustment->getSourceId();
if ($type == 'custom' && $sourceId == 'custom' && $label == 'Tip') {
$hide_tip = TRUE;
/** @var \Drupal\commerce_price\Price $amount */
$amount = $adjustment->getAmount();
$tip_value_formatter = $this->currencyFormatter->format($amount->getNumber(), $amount->getCurrencyCode());
$inline_form[$index] = [
'#type' => 'container',
'#attributes' => [
'class' => ['tip-index--container'],
],
];
$inline_form[$index]['tip_value'] = [
'#type' => 'label',
'#title' => $tip_value_formatter,
'#title_display' => 'hidden',
];
$inline_form[$index]['remove_tip'] = [
'#type' => 'submit',
'#value' => t('Remove'),
'#name' => 'remove_tip_' . $index,
'#ajax' => [
'callback' => [get_called_class(), 'ajaxRefreshForm'],
'element' => $inline_form['#parents'],
],
'#weight' => 50,
'#limit_validation_errors' => [
$inline_form['#parents'],
],
'#adjustment_index' => $index,
'#submit' => [[get_called_class(), 'removeTip']],
// Simplify ajaxRefresh() by having all triggering elements
// on the same level.
'#parents' => array_merge($inline_form['#parents'], ['remove_tip_' . $index]),
];
}
}
if ($hide_tip) {
// Don't allow additional tip to be added.
$inline_form['tip_info']['tip']['#access'] = FALSE;
$inline_form['tip_info']['add_tip']['#access'] = FALSE;
}
return $inline_form;
}
/**
* Submit callback for the "Add Tip" button.
*/
public static function addTip(array $form, FormStateInterface $form_state) {
$triggering_element = $form_state->getTriggeringElement();
$parents = array_slice($triggering_element['#parents'], 0, -1);
$values = $form_state->getValue($parents);
if (!empty($values['tip'])) {
$inline_configuration = $form_state->get('inline_configuration');
$order = \Drupal::entityTypeManager()->getStorage('commerce_order')->load($inline_configuration['order_id']);
$total_price = $order->getTotalPrice();
$tip=(int)$values['tip'];
$adj=$total_price->getNumber()*$tip/100;
$order->addAdjustment(new Adjustment([
'type' => 'custom',
'label' => 'Tip',
'amount' => new Price($adj, $total_price->getCurrencyCode()),
'locked' => TRUE,
'source_id' => 'custom',
'percentage' => NULL,
'included' => FALSE,
]))->save();
}
$form_state->setRebuild();
}
/**
* Submit callback for the "Remove tip" button.
*/
public static function removeTip(array $form, FormStateInterface $form_state) {
$triggering_element = $form_state->getTriggeringElement();
$inline_configuration = $form_state->get('inline_configuration');
/** @var \Drupal\commerce_order\Entity\Order $order */
$order = \Drupal::entityTypeManager()->getStorage('commerce_order')->load($inline_configuration['order_id']);
$adjustment_index = $triggering_element['#adjustment_index'];
$order->get('adjustments')->removeItem($adjustment_index);
$order->save();
$form_state->setRebuild();
}
}
Needs review
1.0
Code