Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Commerce shippping pane that automatically chooses a shipping method without providing a UI for the cutomer
<?php
namespace Drupal\MODULE\Plugin\Commerce\CheckoutPane;
use Drupal\commerce_shipping\Entity\ShipmentInterface;
use Drupal\commerce_shipping\Entity\ShippingMethod;
use Drupal\commerce_shipping\Plugin\Commerce\CheckoutPane\ShippingInformation;
use Drupal\Core\Entity\Entity\EntityFormDisplay;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Render\Element;
/**
* Provides the shipping information pane.
*
* Collects the shipping profile, then the information for each shipment.
* Assumes that all shipments share the same shipping profile.
*
* @CommerceCheckoutPane(
* id = "MODULE_shipping_information",
* label = @Translation("Shipping information"),
* wrapper_element = "fieldset",
* )
*/
class CustomShippingInformation extends ShippingInformation implements ContainerFactoryPluginInterface {
protected $eu_countries = [
"AT",
"BE",
"BG",
"CY",
"CZ",
"DE",
"DK",
"EE",
"ES",
"FI",
"FR",
"GB",
"GR",
"HR",
"HU",
"IE",
"IT",
"LT",
"LU",
"LV",
"MT",
"NL",
"PL",
"PT",
"RO",
"SE",
"SI",
"SK"
];
/**
* {@inheritdoc}
*/
public function buildPaneForm(array $pane_form, FormStateInterface $form_state, array &$complete_form) {
$pane_form = parent::buildPaneForm($pane_form, $form_state, $complete_form);
$pane_form['recalculate_shipping']['#access'] = FALSE;
$pane_form['shipments']['#access'] = FALSE;
return $pane_form;
}
/**
* {@inheritdoc}
*/
public function validatePaneForm(array &$pane_form, FormStateInterface $form_state, array &$complete_form) {
$shipment_indexes = Element::children($pane_form['shipments']);
foreach ($shipment_indexes as $index) {
$shipment = clone $pane_form['shipments'][$index]['#shipment'];
$form_display = EntityFormDisplay::collectRenderDisplay($shipment, 'default');
$form_display->removeComponent('shipping_profile');
$form_display->removeComponent('title');
$form_display->extractFormValues($shipment, $pane_form['shipments'][$index], $form_state);
$form_display->validateFormValues($shipment, $pane_form['shipments'][$index], $form_state);
}
}
/**
* {@inheritdoc}
*/
public function submitPaneForm(array &$pane_form, FormStateInterface $form_state, array &$complete_form) {
// Save the modified shipments.
$shipments = [];
foreach (Element::children($pane_form['shipments']) as $index) {
/** @var \Drupal\commerce_shipping\Entity\ShipmentInterface $shipment */
$shipment = clone $pane_form['shipments'][$index]['#shipment'];
$form_display = EntityFormDisplay::collectRenderDisplay($shipment, 'default');
$form_display->removeComponent('shipping_profile');
$form_display->removeComponent('title');
$form_display->extractFormValues($shipment, $pane_form['shipments'][$index], $form_state);
$shipment->setShippingProfile($pane_form['shipping_profile']['#profile']);
$this->setShippingMethodByShippingAddressCountry($shipment);
$shipment->save();
$shipments[] = $shipment;
}
$this->order->shipments = $shipments;
// Delete shipments that are no longer in use.
$removed_shipment_ids = $pane_form['removed_shipments']['#value'];
if (!empty($removed_shipment_ids)) {
$shipment_storage = $this->entityTypeManager->getStorage('commerce_shipment');
$removed_shipments = $shipment_storage->loadMultiple($removed_shipment_ids);
$shipment_storage->delete($removed_shipments);
}
}
public function setShippingMethodByShippingAddressCountry(ShipmentInterface &$shipment) {
/** @var \Drupal\commerce_shipping\Entity\ShipmentInterface $shipment */
$shipping_profile = $shipment->getShippingProfile();
$address = $shipping_profile->get('address');
$country = $address->country_code;
$shipping_method_id = 3;
if ($country == 'CH') {
$shipping_method_id = 1;
}
else {
if (in_array($country, $this->eu_countries)) {
$shipping_method_id = 2;
}
}
$shipping_method = ShippingMethod::load($shipping_method_id);
$shipment->setShippingMethod($shipping_method);
$shipping_method_plugin = $shipping_method->getPlugin();
$rates = $shipping_method_plugin->calculateRates($shipment);
$shipment->setAmount($rates[0]->getAmount());
return $shipping_method;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment