Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
use Drupal\commerce\Plugin\Commerce\EntityTrait\EntityTraitBase;
use Drupal\commerce_fedex\Plugin\Commerce\ShippingMethod\FedEx;
use Drupal\entity\BundleFieldDefinition;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use NicholasCreativeMedia\FedExPHP\Enums\DangerousGoodsAccessibilityType;
use NicholasCreativeMedia\FedExPHP\Enums\HazardousCommodityOptionType;

/**
* Provides the "fedex_dangerous" trait.
Expand All @@ -25,13 +27,23 @@ public function buildFieldDefinitions() {
$id = $this->getPluginId();

$fields[$id . '_accessibility'] = BundleFieldDefinition::create('list_string')
->setLabel($this->t('Require Dangerous Goods/Hazardous Materials Shipping'))
->setLabel($this->t('Require Dangerous Goods Shipping'))
->setCardinality(1)
->setSetting('allowed_values', [0 => "None"] + FedEx::enumToList(DangerousGoodsAccessibilityType::getValidValues()))
->setDisplayOptions('form', [
'type' => 'options_select',
'weight' => 95,
]);

$fields[$id . '_options'] = BundleFieldDefinition::create('list_string')
->setLabel($this->t('Dangerous Goods Options'))
->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED)
->setSetting('allowed_values', FedEx::enumToList(HazardousCommodityOptionType::getValidValues()))
->setDisplayOptions('form', [
'type' => 'options_select',
'weight' => 96,
]);

return $fields;
}

Expand Down
140 changes: 122 additions & 18 deletions modules/dangerous/src/Plugin/Commerce/FedEx/DangerousGoodsPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,19 @@
use Drupal\commerce_shipping\Entity\ShipmentInterface;
use Drupal\commerce_shipping\ShipmentItem;
use Drupal\Core\Form\FormStateInterface;
use NicholasCreativeMedia\FedExPHP\Enums\HazardousCommodityOptionType;
use NicholasCreativeMedia\FedExPHP\Enums\HazardousCommodityPackingGroupType;
use NicholasCreativeMedia\FedExPHP\Enums\HazardousCommodityQuantityType;
use NicholasCreativeMedia\FedExPHP\Enums\HazardousContainerPackingType;
use NicholasCreativeMedia\FedExPHP\Enums\PackageSpecialServiceType;
use NicholasCreativeMedia\FedExPHP\Enums\RadioactiveContainerClassType;
use NicholasCreativeMedia\FedExPHP\Structs\DangerousGoodsContainer;
use NicholasCreativeMedia\FedExPHP\Structs\DangerousGoodsDetail;
use NicholasCreativeMedia\FedExPHP\Structs\HazardousCommodityContent;
use NicholasCreativeMedia\FedExPHP\Structs\HazardousCommodityDescription;
use NicholasCreativeMedia\FedExPHP\Structs\HazardousCommodityInnerReceptacleDetail;
use NicholasCreativeMedia\FedExPHP\Structs\HazardousCommodityPackingDetail;
use NicholasCreativeMedia\FedExPHP\Structs\HazardousCommodityQuantityDetail;
use NicholasCreativeMedia\FedExPHP\Structs\PackageSpecialServicesRequested;
use NicholasCreativeMedia\FedExPHP\Structs\RequestedPackageLineItem;

Expand Down Expand Up @@ -58,37 +69,79 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s
* {@inheritdoc}
*/
public function adjustPackage(RequestedPackageLineItem $package, array $shipment_items, ShipmentInterface $shipment) {
$status = $this->getDangerousStatus(reset($shipment_items));
$dangerous_goods = $this->getDangerousGoodsItems($shipment_items);
if (!empty($dangerous_goods)) {
/** @var ShipmentItem $item */
$item = reset($dangerous_goods);
$status = $this->getDangerousStatus($item);
$special_services_requested = $package->getSpecialServicesRequested();
if (empty($special_services_requested)) {
$special_services_requested = new PackageSpecialServicesRequested();
}
$special_services_requested->addToSpecialServiceTypes(PackageSpecialServiceType::VALUE_DANGEROUS_GOODS);
$dangerous_goods_detail = $special_services_requested->getDangerousGoodsDetail();
if (empty($dangerous_goods_detail)) {
$dangerous_goods_detail = new DangerousGoodsDetail();
}
$dangerous_goods_detail->setOptions($this->getDangerousOptions($dangerous_goods));
if ($this->isHazardous($dangerous_goods)) {
$commodity = new HazardousCommodityContent();

if ($status === static::NOT_DANGEROUS) {
return $package;
}
$description = new HazardousCommodityDescription();
$description->setLabelText($item->getTitle());
$description->setId((string) $item->getOrderItemId());
$description->setSequenceNumber(1);
$description->setPackingGroup(HazardousCommodityPackingGroupType::VALUE_DEFAULT);
$description->setPackingDetails(new HazardousCommodityPackingDetail(FALSE));
$commodity->setDescription($description);

$special_services_requested = $package->getSpecialServicesRequested();
if (empty($special_services_requested)) {
$special_services_requested = new PackageSpecialServicesRequested();
}
$special_services_requested->addToSpecialServiceTypes(PackageSpecialServiceType::VALUE_DANGEROUS_GOODS);
$dangerous_goods_detail = $special_services_requested->getDangerousGoodsDetail();
if (empty($dangerous_goods_detail)) {
$dangerous_goods_detail = new DangerousGoodsDetail();
$container = new DangerousGoodsContainer();
$container->addToHazardousCommodities($commodity);
$container->setNumberOfContainers(1);
$container->setPackingType(HazardousContainerPackingType::VALUE_ALL_PACKED_IN_ONE);
$dangerous_goods_detail->addToContainers($container);
} else {
$dangerous_goods_detail->setAccessibility($status);
}
$special_services_requested->setDangerousGoodsDetail($dangerous_goods_detail);
$package->setSpecialServicesRequested($special_services_requested);
}
$dangerous_goods_detail->setAccessibility($status);
$special_services_requested->setDangerousGoodsDetail($dangerous_goods_detail);
$package->setSpecialServicesRequested($special_services_requested);

return $package;
}

/**
* Determines if the shipment items contain hazardous materials.
*
* @param array $shipment_items
* The shipment items to check.
*
* @return bool
* TRUE if hazardous, FALSE otherwise.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
*/
protected function isHazardous(array $shipment_items) {
$options = $this->getDangerousOptions($shipment_items);
return array_search(HazardousCommodityOptionType::VALUE_HAZARDOUS_MATERIALS, $options) !== FALSE;
}

/**
* {@inheritdoc}
*/
public function splitPackage(array $shipment_items, ShipmentInterface $shipment) {
$packages = [];
$main_package = [];
foreach ($shipment_items as $shipment_item) {
$packages[$this->getDangerousStatus($shipment_item)][] = $shipment_item;
if ($this->getDangerousStatus($shipment_item) === self::NOT_DANGEROUS) {
$main_package[] = $shipment_item;
} else {
$packages[][] = $shipment_item;
}
}
if (!empty($main_package)) {
$packages = [$main_package] + $packages;
}
return array_values($packages);
return $packages;
}

/**
Expand All @@ -99,6 +152,8 @@ public function splitPackage(array $shipment_items, ShipmentInterface $shipment)
*
* @return mixed
* The DG status.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
*/
protected function getDangerousStatus(ShipmentItem $shipment_item) {
$storage = \Drupal::entityTypeManager()->getStorage('commerce_order_item');
Expand All @@ -111,4 +166,53 @@ protected function getDangerousStatus(ShipmentItem $shipment_item) {
return $purchased_entity->get('fedex_dangerous_accessibility')->value;
}

/**
* Gets only the dangerous goods items from a list of shipment items.
*
* @param array $shipment_items
* All of the shipment items.
*
* @return array
* The dangerous goods items from the shipment items list.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
*/
protected function getDangerousGoodsItems(array $shipment_items) {
$dangerous_items = [];
foreach ($shipment_items as $shipment_item) {
if ($this->getDangerousStatus($shipment_item) !== self::NOT_DANGEROUS) {
$dangerous_items[] = $shipment_item;
}
}
return $dangerous_items;
}

/**
* Gets the type of this dangerous goods item.
*
* @param ShipmentItem[] $shipment_items
* The item to check.
*
* @return mixed
* 'dangerous', 'hazardous', or FALSE.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
*/
protected function getDangerousOptions(array $shipment_items) {
$storage = \Drupal::entityTypeManager()->getStorage('commerce_order_item');
$options = [];
$field = 'fedex_dangerous_options';
foreach ($shipment_items as $shipment_item) {
/** @var \Drupal\commerce_order\Entity\OrderItemInterface $order_item */
$order_item = $storage->load($shipment_item->getOrderItemId());
$purchased_entity = $order_item->getPurchasedEntity();
if ($purchased_entity->hasField($field) && !$purchased_entity->get($field)->isEmpty()) {
foreach ($purchased_entity->get($field)->getValue() as $item) {
$options[] = $item['value'];
}
}
}

return array_unique($options);
}
}
2 changes: 1 addition & 1 deletion src/Plugin/Commerce/ShippingMethod/FedEx.php
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ public function calculateRates(ShipmentInterface $shipment) {
}
}

if (in_array($highest_severity, $allowed_severities)) {
if (in_array($highest_severity, $allowed_severities) && is_array($response->getRateReplyDetails())) {
$multiplier = (!empty($this->configuration['options']['rate_multiplier']))
? $this->configuration['options']['rate_multiplier']
: 1.0;
Expand Down