View source
<?php
namespace Drupal\uc_ups\Plugin\Ubercart\ShippingQuote;
use Drupal\Core\Form\FormStateInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\uc_order\OrderInterface;
use Drupal\uc_quote\ShippingQuotePluginBase;
use Drupal\node\Entity\Node;
abstract class UPSRateBase extends ShippingQuotePluginBase {
public function defaultConfiguration() {
return [
'base_rate' => 0,
'product_rate' => 0,
'field' => '',
];
}
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;
}
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');
}
public function getDescription() {
return $this
->t('UPS');
}
public function getDisplayLabel($label) {
$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',
],
],
];
$build['label'] = [
'#plain_text' => $this
->t('@service Rate', [
'@service' => $label,
]),
];
$build['packages'] = [
'#plain_text' => ' (' . \Drupal::translation()
->formatPlural(count($packages), '1 package', '@count packages') . ')',
];
return $build;
}
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,
];
}
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) {
$packages[$last_key] = [
0 => $this
->newPackage(),
];
foreach ($products as $product) {
if ($product->nid->value) {
$key = NULL;
$address = uc_quote_get_default_shipping_address($product->nid->value);
foreach ($addresses as $index => $value) {
if ($address
->isSamePhysicalLocation($value)) {
$key = $index;
break;
}
}
if (!isset($key)) {
$addresses[++$last_key] = $address;
$key = $last_key;
$packages[$key] = [
0 => $this
->newPackage(),
];
}
}
$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[$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 {
foreach ($products as $product) {
if ($product->nid) {
$address = uc_quote_get_default_shipping_address($product->nid);
if (in_array($address, $addresses)) {
foreach ($addresses as $index => $value) {
if ($address == $value) {
$key = $index;
break;
}
}
}
else {
$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':
$weight = $weight * G_TO_KG;
case 'kg':
$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;
}
$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':
$weight = $weight * G_TO_KG;
case 'kg':
$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;
}
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;
}
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;
}
}
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;
}
}
}