abstract class UPSRateBase in Ubercart 8.4
Common functionality for UPS shipping quotes plugins.
Hierarchy
- class \Drupal\Component\Plugin\PluginBase implements DerivativeInspectionInterface, PluginInspectionInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
- class \Drupal\uc_quote\ShippingQuotePluginBase implements ShippingQuotePluginInterface
- class \Drupal\uc_ups\Plugin\Ubercart\ShippingQuote\UPSRateBase
- class \Drupal\uc_quote\ShippingQuotePluginBase implements ShippingQuotePluginInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
Expanded class hierarchy of UPSRateBase
File
- shipping/
uc_ups/ src/ Plugin/ Ubercart/ ShippingQuote/ UPSRateBase.php, line 14
Namespace
Drupal\uc_ups\Plugin\Ubercart\ShippingQuoteView source
abstract class UPSRateBase extends ShippingQuotePluginBase {
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
return [
'base_rate' => 0,
'product_rate' => 0,
'field' => '',
];
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$fields = [
'' => $this
->t('- None -'),
];
$result = \Drupal::entityQuery('field_config')
->condition('field_type', 'number')
->execute();
foreach (FieldConfig::loadMultiple($result) as $field) {
$fields[$field
->getName()] = $field
->label();
}
$form['base_rate'] = [
'#type' => 'uc_price',
'#title' => $this
->t('Base price'),
'#description' => $this
->t('The starting price for shipping costs.'),
'#default_value' => $this->configuration['base_rate'],
'#required' => TRUE,
];
$form['product_rate'] = [
'#type' => 'number',
'#title' => $this
->t('Default product shipping rate'),
'#min' => 0,
'#step' => 'any',
'#description' => $this
->t('The percentage of the item price to add to the shipping cost for an item.'),
'#default_value' => $this->configuration['product_rate'],
'#field_suffix' => $this
->t('% (percent)'),
'#required' => TRUE,
];
$form['field'] = [
'#type' => 'select',
'#title' => $this
->t('Product shipping rate override field'),
'#description' => $this
->t('Overrides the default shipping rate per product for this percentage rate shipping method, when the field is attached to a product content type and has a value.'),
'#options' => $fields,
'#default_value' => $this->configuration['field'],
];
return $form;
}
/**
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
$this->configuration['base_rate'] = $form_state
->getValue('base_rate');
$this->configuration['product_rate'] = $form_state
->getValue('product_rate');
$this->configuration['field'] = $form_state
->getValue('field');
}
/**
* {@inheritdoc}
*/
public function getDescription() {
return $this
->t('UPS');
}
/**
* {@inheritdoc}
*/
public function getDisplayLabel($label) {
// Start with logo as required by the UPS terms of service.
$build['image'] = [
'#theme' => 'image',
'#uri' => drupal_get_path('module', 'uc_ups') . '/images/uc_ups_logo.jpg',
'#alt' => $this
->t('UPS logo'),
'#attributes' => [
'class' => [
'ups-logo',
],
],
];
// Add the UPS service name.
$build['label'] = [
'#plain_text' => $this
->t('@service Rate', [
'@service' => $label,
]),
];
// Add package information.
$build['packages'] = [
'#plain_text' => ' (' . \Drupal::translation()
->formatPlural(count($packages), '1 package', '@count packages') . ')',
];
return $build;
}
/**
* {@inheritdoc}
*/
public function getQuotes(OrderInterface $order) {
$rate = $this->configuration['base_rate'];
$field = $this->configuration['field'];
foreach ($order->products as $product) {
if (isset($product->nid->entity->{$field}->value)) {
$product_rate = $product->nid->entity->{$field}->value * $product->qty->value;
}
else {
$product_rate = $this->configuration['product_rate'] * $product->qty->value;
}
$rate += $product->price->value * floatval($product_rate) / 100;
}
return [
$rate,
];
}
/**
* Organizes products into packages for shipment.
*
* @param OrderProduct[] $products
* An array of product objects as they are represented in the cart or order.
* @param Address[] $addresses
* Reference to an array of addresses which are the pickup locations of each
* package. They are determined from the shipping addresses of their
* component products.
*
* @return array
* Packaged products. Packages are separated by shipping address and weight
* or quantity limits imposed by the shipping method or the products.
*/
protected function packageProducts(array $products, array $addresses) {
$last_key = 0;
$packages = [];
$ups_config = \Drupal::config('uc_ups.settings');
if ($ups_config
->get('all_in_one') && count($products) > 1) {
// "All in one" packaging strategy.
// Only need to do this if more than one product line item in order.
$packages[$last_key] = [
0 => $this
->newPackage(),
];
foreach ($products as $product) {
if ($product->nid->value) {
// Packages are grouped by the address from which they will be
// shipped. We will keep track of the different addresses in an array
// and use their keys for the array of packages.
$key = NULL;
$address = uc_quote_get_default_shipping_address($product->nid->value);
foreach ($addresses as $index => $value) {
if ($address
->isSamePhysicalLocation($value)) {
// This is an existing address.
$key = $index;
break;
}
}
if (!isset($key)) {
// This is a new address. Increment the address counter $last_key
// instead of using [] so that it can be used in $packages and
// $addresses.
$addresses[++$last_key] = $address;
$key = $last_key;
$packages[$key] = [
0 => $this
->newPackage(),
];
}
}
// Grab some product properties directly from the (cached) product
// data. They are not normally available here because the $product
// object is being read out of the $order object rather than from
// the database, and the $order object only carries around a limited
// number of product properties.
$temp = Node::load($product->nid->value);
$product->length = $temp->length->value;
$product->width = $temp->width->value;
$product->height = $temp->height->value;
$product->length_units = $temp->length_units;
$product->ups['container'] = isset($temp->ups['container']) ? $temp->ups['container'] : 'VARIABLE';
$packages[$key][0]->price += $product->price * $product->qty;
$packages[$key][0]->weight += $product->weight * $product->qty * uc_weight_conversion($product->weight_units, 'lb');
}
foreach ($packages as $key => $package) {
$packages[$key][0]->pounds = floor($package[0]->weight);
$packages[$key][0]->ounces = LB_TO_OZ * ($package[0]->weight - $packages[$key][0]->pounds);
$packages[$key][0]->container = 'VARIABLE';
$packages[$key][0]->size = 'REGULAR';
// Packages are "machinable" if heavier than 6oz. and less than 35lbs.
$packages[$key][0]->machinable = ($packages[$key][0]->pounds == 0 ? $packages[$key][0]->ounces >= 6 : TRUE) && $packages[$key][0]->pounds <= 35 && ($packages[$key][0]->pounds == 35 ? $packages[$key][0]->ounces == 0 : TRUE);
$packages[$key][0]->qty = 1;
}
}
else {
// !$ups_config->get('all_in_one') || count($products) = 1
// This is the "Each in own" packaging strategy, or
// there is only one product line item in order.
foreach ($products as $product) {
if ($product->nid) {
$address = uc_quote_get_default_shipping_address($product->nid);
if (in_array($address, $addresses)) {
// This is an existing address.
foreach ($addresses as $index => $value) {
if ($address == $value) {
$key = $index;
break;
}
}
}
else {
// This is a new address.
$addresses[++$last_key] = $address;
$key = $last_key;
}
}
if (!isset($product->pkg_qty) || !$product->pkg_qty) {
$product->pkg_qty = 1;
}
$num_of_pkgs = (int) ($product->qty / $product->pkg_qty);
if ($num_of_pkgs) {
$package = clone $product;
$package->description = $product->model;
$weight = $product->weight * $product->pkg_qty;
switch ($product->weight_units) {
case 'g':
// Convert to kg and fall through.
$weight = $weight * G_TO_KG;
case 'kg':
// Convert to lb and fall through.
$weight = $weight * KG_TO_LB;
case 'lb':
$package->pounds = floor($weight);
$package->ounces = LB_TO_OZ * ($weight - $package->pounds);
break;
case 'oz':
$package->pounds = floor($weight * OZ_TO_LB);
$package->ounces = $weight - $package->pounds * LB_TO_OZ;
break;
}
// Grab some product properties directly from the (cached) product
// data. They are not normally available here because the $product
// object is being read out of the $order object rather than from
// the database, and the $order object only carries around a limited
// number of product properties.
$temp = Node::load($product->nid);
$product->length = $temp->length;
$product->width = $temp->width;
$product->height = $temp->height;
$product->length_units = $temp->length_units;
$product->ups['container'] = isset($temp->ups['container']) ? $temp->ups['container'] : 'VARIABLE';
$package->container = $product->ups['container'];
$length_conversion = uc_length_conversion($product->length_units, 'in');
$package->length = max($product->length, $product->width) * $length_conversion;
$package->width = min($product->length, $product->width) * $length_conversion;
$package->height = $product->height * $length_conversion;
if ($package->length < $package->height) {
list($package->length, $package->height) = [
$package->height,
$package->length,
];
}
$package->girth = 2 * $package->width + 2 * $package->height;
$package->size = $package->length <= 12 ? 'REGULAR' : 'LARGE';
$package->machinable = $package->length >= 6 && $package->length <= 34 && $package->width >= 0.25 && $package->width <= 17 && $package->height >= 3.5 && $package->height <= 17 && ($package->pounds == 0 ? $package->ounces >= 6 : TRUE) && $package->pounds <= 35 && ($package->pounds == 35 ? $package->ounces == 0 : TRUE);
$package->price = $product->price * $product->pkg_qty;
$package->qty = $num_of_pkgs;
$packages[$key][] = $package;
}
$remaining_qty = $product->qty % $product->pkg_qty;
if ($remaining_qty) {
$package = clone $product;
$package->description = $product->model;
$weight = $product->weight * $remaining_qty;
switch ($product->weight_units) {
case 'g':
// Convert to kg and fall through.
$weight = $weight * G_TO_KG;
case 'kg':
// Convert to lb and fall through.
$weight = $weight * KG_TO_LB;
case 'lb':
$package->pounds = floor($weight);
$package->ounces = LB_TO_OZ * ($weight - $package->pounds);
break;
case 'oz':
$package->pounds = floor($weight * OZ_TO_LB);
$package->ounces = $weight - $package->pounds * LB_TO_OZ;
break;
}
$package->container = $product->ups['container'];
$length_conversion = uc_length_conversion($product->length_units, 'in');
$package->length = max($product->length, $product->width) * $length_conversion;
$package->width = min($product->length, $product->width) * $length_conversion;
$package->height = $product->height * $length_conversion;
if ($package->length < $package->height) {
list($package->length, $package->height) = [
$package->height,
$package->length,
];
}
$package->girth = 2 * $package->width + 2 * $package->height;
$package->size = $package->length <= 12 ? 'REGULAR' : 'LARGE';
$package->machinable = $package->length >= 6 && $package->length <= 34 && $package->width >= 0.25 && $package->width <= 17 && $package->height >= 3.5 && $package->height <= 17 && ($package->pounds == 0 ? $package->ounces >= 6 : TRUE) && $package->pounds <= 35 && ($package->pounds == 35 ? $package->ounces == 0 : TRUE);
$package->price = $product->price * $remaining_qty;
$package->qty = 1;
$packages[$key][] = $package;
}
}
}
return $packages;
}
/**
* Pseudo-constructor to set default values of a package.
*/
protected function newPackage() {
$package = new \stdClass();
$package->price = 0;
$package->qty = 1;
$package->pkg_type = '02';
$package->weight = 0;
$package->weight_units = 'lb';
$package->length = 0;
$package->width = 0;
$package->height = 0;
$package->length_units = 'in';
return $package;
}
/**
* Modifies the rate received from UPS before displaying to the customer.
*
* @param float $rate
* Shipping rate without any rate markup.
*
* @return float
* Shipping rate after markup.
*/
protected function rateMarkup($rate) {
$ups_config = \Drupal::config('uc_ups.settings');
$markup = trim($ups_config
->get('rate_markup'));
$type = $ups_config
->get('rate_markup_type');
if (is_numeric($markup)) {
switch ($type) {
case 'percentage':
return $rate + $rate * floatval($markup) / 100;
case 'multiplier':
return $rate * floatval($markup);
case 'currency':
return $rate + floatval($markup);
}
}
else {
return $rate;
}
}
/**
* Modifies the weight of shipment before sending to UPS for a quote.
*
* @param float $weight
* Shipping weight without any weight markup.
*
* @return float
* Shipping weight after markup.
*/
protected function weightMarkup($weight) {
$ups_config = \Drupal::config('uc_ups.settings');
$markup = trim($ups_config
->get('weight_markup'));
$type = $ups_config
->get('weight_markup_type');
if (is_numeric($markup)) {
switch ($type) {
case 'percentage':
return $weight + $weight * floatval($markup) / 100;
case 'multiplier':
return $weight * floatval($markup);
case 'mass':
return $weight + floatval($markup);
}
}
else {
return $weight;
}
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
DependencySerializationTrait:: |
protected | property | An array of entity type IDs keyed by the property name of their storages. | |
DependencySerializationTrait:: |
protected | property | An array of service IDs keyed by property name used for serialization. | |
DependencySerializationTrait:: |
public | function | 1 | |
DependencySerializationTrait:: |
public | function | 2 | |
MessengerTrait:: |
protected | property | The messenger. | 29 |
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
MessengerTrait:: |
public | function | Sets the messenger. | |
PluginBase:: |
protected | property | Configuration information passed into the plugin. | 1 |
PluginBase:: |
protected | property | The plugin implementation definition. | 1 |
PluginBase:: |
protected | property | The plugin_id. | |
PluginBase:: |
constant | A string which is used to separate base plugin IDs from the derivative ID. | ||
PluginBase:: |
public | function |
Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the definition of the plugin implementation. Overrides PluginInspectionInterface:: |
3 |
PluginBase:: |
public | function |
Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface:: |
|
PluginBase:: |
public | function | Determines if the plugin is configurable. | |
ShippingQuotePluginBase:: |
public | function |
Gets this plugin's configuration. Overrides ConfigurableInterface:: |
|
ShippingQuotePluginBase:: |
public | function |
Sets the configuration for this plugin instance. Overrides ConfigurableInterface:: |
|
ShippingQuotePluginBase:: |
public | function |
Form validation handler. Overrides PluginFormInterface:: |
|
ShippingQuotePluginBase:: |
public | function |
Constructs a \Drupal\Component\Plugin\PluginBase object. Overrides PluginBase:: |
|
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. | |
UPSRateBase:: |
public | function |
Form constructor. Overrides PluginFormInterface:: |
|
UPSRateBase:: |
public | function |
Gets default configuration for this plugin. Overrides ShippingQuotePluginBase:: |
|
UPSRateBase:: |
public | function |
Returns a description of this shipping quote. Overrides ShippingQuotePluginInterface:: |
|
UPSRateBase:: |
public | function |
Returns the shipping quote method label with logo. Overrides ShippingQuotePluginBase:: |
|
UPSRateBase:: |
public | function |
Retrieves shipping quotes for this method. Overrides ShippingQuotePluginInterface:: |
|
UPSRateBase:: |
protected | function | Pseudo-constructor to set default values of a package. | |
UPSRateBase:: |
protected | function | Organizes products into packages for shipment. | |
UPSRateBase:: |
protected | function | Modifies the rate received from UPS before displaying to the customer. | |
UPSRateBase:: |
public | function |
Form submission handler. Overrides PluginFormInterface:: |
|
UPSRateBase:: |
protected | function | Modifies the weight of shipment before sending to UPS for a quote. |