diff --git a/commerce_shipping.links.task.yml b/commerce_shipping.links.task.yml index 1785922..6d14982 100644 --- a/commerce_shipping.links.task.yml +++ b/commerce_shipping.links.task.yml @@ -1,3 +1,13 @@ +entity.commerce_shipment.collection: + route_name: entity.commerce_shipment.collection + base_route: entity.commerce_order.canonical + title: Shipments + +entity.commerce_shipment.edit_form: + route_name: entity.commerce_shipment.edit_form + base_route: entity.commerce_shipment.edit_form + title: Edit + entity.commerce_package_type.edit_form: route_name: entity.commerce_package_type.edit_form base_route: entity.commerce_package_type.edit_form diff --git a/commerce_shipping.module b/commerce_shipping.module index efbef6c..d4acea8 100644 --- a/commerce_shipping.module +++ b/commerce_shipping.module @@ -8,9 +8,11 @@ use Drupal\commerce\BundleFieldDefinition; use Drupal\commerce\PurchasableEntityInterface; use Drupal\commerce_order\Entity\OrderInterface; +use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Field\BaseFieldDefinition; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Url; /** * Implements hook_commerce_entity_trait_info_alter(). @@ -62,6 +64,30 @@ function commerce_shipping_field_widget_form_alter(&$element, FormStateInterface } } +/** + * Implements hook_entity_operation(). + */ +function commerce_shipping_entity_operation(EntityInterface $entity) { + if ($entity->getEntityTypeId() !== 'commerce_order') { + return; + } + + if (\Drupal::currentUser()->hasPermission('administer commerce_shipment')) { + return; + } + + $operations = []; + $operations['shipments'] = [ + 'title' => t('Shipments'), + 'url' => Url::fromRoute('entity.commerce_shipment.collection', [ + 'commerce_order' => $entity->id(), + ]), + 'weight' => 50, + ]; + + return $operations; +} + /** * Implements hook_ENTITY_TYPE_delete(). */ diff --git a/commerce_shipping.routing.yml b/commerce_shipping.routing.yml index 0815bc4..78f5b06 100644 --- a/commerce_shipping.routing.yml +++ b/commerce_shipping.routing.yml @@ -29,3 +29,15 @@ entity.commerce_shipment_type.collection: _title: 'Shipment types' requirements: _permission: 'administer commerce_shipment_type' + +entity.commerce_shipment.collection: + path: '/admin/commerce/orders/{commerce_order}/shipments' + defaults: + _entity_list: 'commerce_shipment' + _title: 'Shipments' + options: + parameters: + commerce_order: + type: 'entity:commerce_order' + requirements: + _permission: 'administer commerce_shipment' diff --git a/src/Entity/Shipment.php b/src/Entity/Shipment.php index ff3e73e..d63db1c 100644 --- a/src/Entity/Shipment.php +++ b/src/Entity/Shipment.php @@ -29,9 +29,17 @@ use Drupal\profile\Entity\ProfileInterface; * ), * bundle_label = @Translation("Shipment type"), * handlers = { + * "access" = "Drupal\commerce_shipping\ShipmentAccessControlHandler", * "storage" = "Drupal\commerce_shipping\ShipmentStorage", * "access" = "Drupal\Core\Entity\EntityAccessControlHandler", - * "views_data" = "Drupal\views\EntityViewsData" + * "views_data" = "Drupal\views\EntityViewsData", + * "list_builder" = "Drupal\commerce_shipping\ShipmentListBuilder", + * "route_provider" = { + * "default" = "Drupal\Core\Entity\Routing\AdminHtmlRouteProvider", + * }, + * "form" = { + * "default" = "Drupal\Core\Entity\ContentEntityForm", + * }, * }, * base_table = "commerce_shipment", * admin_permission = "administer commerce_shipment", @@ -42,6 +50,10 @@ use Drupal\profile\Entity\ProfileInterface; * "label" = "title", * "uuid" = "uuid", * }, + * links = { + * "collection" = "/admin/commerce/orders/{commerce_order}/shipments", + * "edit-form" = "/admin/commerce/orders/{commerce_order}/shipment/{commerce_shipment}/edit", + * }, * bundle_entity_type = "commerce_shipment_type", * field_ui_base_route = "entity.commerce_shipment_type.edit_form", * ) @@ -498,6 +510,10 @@ class Shipment extends ContentEntityBase implements ShipmentInterface { ->setDescription(t('The shipment tracking code.')) ->setDefaultValue('') ->setSetting('max_length', 255) + ->setDisplayOptions('form', [ + 'type' => 'string_textfield', + 'weight' => 20, + ]) ->setDisplayConfigurable('form', TRUE) ->setDisplayConfigurable('view', TRUE); diff --git a/src/Plugin/Commerce/CheckoutPane/ShippingInformation.php b/src/Plugin/Commerce/CheckoutPane/ShippingInformation.php index 71f1880..3fe4183 100644 --- a/src/Plugin/Commerce/CheckoutPane/ShippingInformation.php +++ b/src/Plugin/Commerce/CheckoutPane/ShippingInformation.php @@ -234,6 +234,7 @@ class ShippingInformation extends CheckoutPaneBase implements ContainerFactoryPl $form_display = EntityFormDisplay::collectRenderDisplay($shipment, 'default'); $form_display->removeComponent('shipping_profile'); $form_display->removeComponent('title'); + $form_display->removeComponent('tracking_code'); $form_display->buildForm($shipment, $pane_form['shipments'][$index], $form_state); $pane_form['shipments'][$index]['#shipment'] = $shipment; } diff --git a/src/ShipmentAccessControlHandler.php b/src/ShipmentAccessControlHandler.php new file mode 100644 index 0000000..593d116 --- /dev/null +++ b/src/ShipmentAccessControlHandler.php @@ -0,0 +1,30 @@ +getOrder(); + $access = AccessResult::allowedIfHasPermission($account, $this->entityType->getAdminPermission()) + ->andIf(AccessResult::allowedIf($order && $order->access('view', $account, TRUE))) + ->addCacheableDependency($entity); + + return $access; + } + +} diff --git a/src/ShipmentListBuilder.php b/src/ShipmentListBuilder.php new file mode 100644 index 0000000..d0d36b1 --- /dev/null +++ b/src/ShipmentListBuilder.php @@ -0,0 +1,127 @@ +routeMatch = $route_match; + $this->dateFormatter = $date_formatter; + } + + /** + * {@inheritdoc} + */ + public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) { + return new static( + $entity_type, + $container->get('entity.manager')->getStorage($entity_type->id()), + $container->get('current_route_match'), + $container->get('date.formatter') + ); + } + + /** + * {@inheritdoc} + */ + public function load() { + $order = $this->routeMatch->getParameter('commerce_order'); + return $this->storage->loadMultipleByOrder($order); + } + + /** + * {@inheritdoc} + */ + public function getOperations(EntityInterface $entity) { + /** @var \Drupal\commerce_shipping\Entity\Shipment $entity */ + $operations = parent::getOperations($entity); + + if (!isset($operations['edit'])) { + return $operations; + } + + $url = $entity->toUrl('edit-form')->setRouteParameter( + 'commerce_order', + $entity->getOrderId() + ); + $operations['edit'] = [ + 'title' => $this->t('Edit'), + 'weight' => 30, + 'url' => $url, + ]; + + return $operations; + } + + /** + * {@inheritdoc} + */ + public function buildHeader() { + $header['label'] = $this->t('Shipment'); + $header['state'] = $this->t('State'); + $header['items'] = $this->t('Items'); + $header['tracking_code'] = $this->t('Tracking Code'); + $header['last_updated'] = $this->t('Last Updated'); + return $header + parent::buildHeader(); + } + + /** + * {@inheritdoc} + */ + public function buildRow(EntityInterface $entity) { + /** @var \Drupal\commerce_shipping\Entity\ShipmentInterface $entity */ + $items = []; + + foreach ($entity->getItems() as $item) { + $items[] = $item->getTitle(); + } + + $row['label'] = $entity->getTitle(); + $row['state'] = $entity->getState()->getLabel(); + $row['items'] = implode(",\n", $items); + $row['tracking_code'] = $entity->getTrackingCode() ?: ''; + $row['last_updated'] = $this->dateFormatter->format($entity->getChangedTime(), 'short'); + + return $row + parent::buildRow($entity); + } + +}