Créer une méthode de livraison avec Drupal commerce 2

Camion de livraison

Drupal commerce fournit en standard plusieurs méthodes de livraison que nous pouvons conditionner selon différents critères (montant de la commande, profil client, type de commande, Poids de la commande, Type de produit, etc.). Pour des besoins spécifiques, nous pouvons ajouter une méthode de livraison sur mesure qui peut alors se charger d'effectuer les calculs nécessaires à la détermination du coût de la livraison.

Pour ce faire il suffit de créer un Plugin Commerce de type CommerceShippingMethod fournie par le module Commerce shipping. Prenons un exemple, en créant une nouvelle méthode de livraison qui va calculer le coût de la livraison en fonction du poids de la commande.

Créons le fichier RateParWeight.php et plaçons le dans un module custom My Module dans le répertoire src/Plugin/Commerce/ShippingMethod.


namespace Drupal\my_module\Plugin\Commerce\ShippingMethod;

use Drupal\commerce_price\Price;
use Drupal\commerce_shipping\Entity\ShipmentInterface;
use Drupal\commerce_shipping\PackageTypeManagerInterface;
use Drupal\commerce_shipping\Plugin\Commerce\ShippingMethod\ShippingMethodBase;
use Drupal\commerce_shipping\ShippingRate;
use Drupal\commerce_shipping\ShippingService;
use Drupal\physical\Weight;
use Drupal\physical\WeightUnit;
use Drupal\state_machine\WorkflowManagerInterface;

/**
 * Provides the Rate per weight shipping method.
 *
 * @CommerceShippingMethod(
 *   id = "rate_per_weight",
 *   label = @Translation("Rate per weight"),
 * )
 */
class RatePerWeight extends ShippingMethodBase {

  private $rounder;

  /**
   * Constructs a new FlatRate 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\commerce_shipping\PackageTypeManagerInterface $package_type_manager
   *   The package type manager.
   * @param \Drupal\state_machine\WorkflowManagerInterface $workflow_manager
   *   The workflow manager.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, PackageTypeManagerInterface $package_type_manager, WorkflowManagerInterface $workflow_manager) {
    parent::__construct($configuration, $plugin_id, $plugin_definition, $package_type_manager, $workflow_manager);
    $this->services['default'] = new ShippingService('default', $this->t('Home delivery'));
    $this->rounder = \Drupal::service('commerce_price.rounder');
  }

  /**
   * {@inheritdoc}
   */
  public function calculateRates(ShipmentInterface $shipment) {
    // Index 0 is for Weight 0 to 5kg.
    // Index 1 is for Weight 5 to 10kg.
    // Index 2 is for Weight over 10kg.
    $amounts = [10, 20, 30];

    // Default value is for shipping where weight is superior to 10kg.
    $weight_rate = 2;
    $total_weight = $shipment->getWeight();
    if (!$total_weight) {
      $total_weight = new Weight('0', WeightUnit::KILOGRAM);
    }
    $total_weight = $total_weight->convert(WeightUnit::KILOGRAM);
    $five_kg_weight = new Weight('5', WeightUnit::KILOGRAM);
    $ten_kg_weight = new Weight('10', WeightUnit::KILOGRAM);
    if ($total_weight->lessThan($five_kg_weight)) {
      $weight_rate = 0;
    }
    elseif ($total_weight->greaterThanOrEqual($five_kg_weight) &&
      $total_weight->lessThan($ten_kg_weight)) {
      $weight_rate = 1;
    }
    
    $shipping_amount = $amounts[$weight_rate];
    $amount = new Price((string) $shipping_amount, $shipment->getOrder()->getTotalPrice()->getCurrencyCode());
    $amount = $this->rounder->round($amount);

    $rates = [];
    $rates[] = new ShippingRate([
      'shipping_method_id' => $this->parentEntity->id(),
      'service' => $this->services['default'],
      'amount' => $amount,
    ]);
    return $rates;
  }

}


Cette méthode de livraison basique va alors calculer le montant de la livraison selon le tableau ($amounts) fourni en paramètre en dur dans le plugin. Cet exemple pour permet alors de sélectionner ce plugin de livraison lors de la création d'une méthode de livraison disponible dans le tunnel d'achat.

Sélection du plugin rate per weight

 

A noter qu'il serait possible d'utiliser les méthodes de livraison standard fournies par Commerce Shipping, et de conditionner chaque méthode de livraison en fonction du poids de la commande. Ce type de méthode de livraison sur mesure peut être plus simple à maintenir, ou encore peut embarquer une logique plus complexe dans la détermination du coût de livraison pour une commande.

 

Ajouter un commentaire