public function ShipmentForm::form in Commerce Shipping 8.2
Gets the actual form array to be built.
Overrides ContentEntityForm::form
See also
\Drupal\Core\Entity\EntityForm::processForm()
\Drupal\Core\Entity\EntityForm::afterBuild()
File
- src/
Form/ ShipmentForm.php, line 64
Class
- ShipmentForm
- Defines the shipment add/edit form.
Namespace
Drupal\commerce_shipping\FormCode
public function form(array $form, FormStateInterface $form_state) {
/** @var \Drupal\commerce_shipping\Entity\ShipmentInterface $shipment */
$shipment = $this->entity;
$order_id = $shipment
->get('order_id')->target_id;
if (!$order_id) {
$order_id = $this
->getRouteMatch()
->getRawParameter('commerce_order');
$shipment
->set('order_id', $order_id);
}
/** @var \Drupal\commerce_order\Entity\OrderInterface $order */
$order = $shipment
->getOrder();
/** @var \Drupal\profile\Entity\ProfileInterface $shipping_profile */
$shipping_profile = $shipment
->getShippingProfile();
if (!$shipping_profile) {
/** @var \Drupal\commerce_shipping\Entity\ShipmentTypeInterface $shipment_type */
$shipment_type = $this->entityTypeManager
->getStorage('commerce_shipment_type')
->load($shipment
->bundle());
/** @var \Drupal\profile\Entity\ProfileInterface $shipping_profile */
$shipping_profile = $this->entityTypeManager
->getStorage('profile')
->create([
'type' => $shipment_type
->getProfileTypeId(),
'uid' => 0,
]);
$address = [
'#type' => 'address',
'#default_value' => [],
];
$shipping_profile
->set('address', $address);
$shipment
->setShippingProfile($shipping_profile);
}
// Store the original amount for ShipmentForm::save().
$form_state
->set('original_amount', $shipment
->getAmount());
$form = parent::form($form, $form_state);
// The ShippingProfileWidget doesn't output a fieldset because that makes
// sense in a checkout context, but on the admin form it is clearer for
// profile fields to be visually grouped.
$form['shipping_profile']['widget'][0]['#type'] = 'fieldset';
// Fixes illegal choice has been detected message upon AJAX reload.
if (empty($form['shipping_method']['widget'][0]['#options'])) {
$form['shipping_method']['#access'] = FALSE;
}
// Prepare the form for ajax.
// Not using Html::getUniqueId() on the wrapper ID to avoid #2675688.
$form['#wrapper_id'] = 'shipping-information-wrapper';
$form['#prefix'] = '<div id="' . $form['#wrapper_id'] . '">';
$form['#suffix'] = '</div>';
$package_types = $this->packageTypeManager
->getDefinitions();
$package_type_options = [];
foreach ($package_types as $package_type) {
$unit = ' ' . array_pop($package_type['dimensions']);
$dimensions = ' (' . implode(' x ', $package_type['dimensions']) . $unit . ')';
$package_type_options[$package_type['id']] = $package_type['label'] . $dimensions;
}
$package_type = $shipment
->getPackageType();
$form['package_type'] = [
'#type' => 'select',
'#title' => $this
->t('Package Type'),
'#options' => $package_type_options,
'#default_value' => $package_type ? $package_type
->getId() : '',
'#access' => count($package_types) > 1,
];
$order_items = $order
->getItems();
/** @var \Drupal\commerce_shipping\ShipmentStorageInterface $shipment_storage */
$shipment_storage = $this->entityTypeManager
->getStorage('commerce_shipment');
// Get all of the shipments for the current order.
$order_shipments = $shipment_storage
->loadMultipleByOrder($order);
// Store order_items that are already tied to shipments on this order.
$already_on_shipment = [];
foreach ($order_shipments as $order_shipment) {
if ($order_shipment
->id() != $shipment
->id()) {
$shipment_items = $order_shipment
->getItems();
foreach ($shipment_items as $shipment_item) {
$order_item_id = $shipment_item
->getOrderItemId();
$already_on_shipment[$order_item_id] = $order_item_id;
}
}
}
$shipment_item_options = [];
// Populates the default values by looking at the items already in this
// shipment.
$shipment_item_defaults = [];
$shipment_items = $shipment
->getItems();
/** @var \Drupal\commerce_shipping\ShipmentItem $shipment_item */
foreach ($shipment_items as $shipment_item) {
$shipment_item_id = $shipment_item
->getOrderItemId();
$shipment_item_defaults[$shipment_item_id] = $shipment_item_id;
$shipment_item_options[$shipment_item_id] = $shipment_item
->getTitle();
}
/** @var \Drupal\commerce_order\Entity\OrderItemInterface $order_item */
foreach ($order_items as $order_item) {
// Skip shipment items that are already on this shipment.
if (isset($shipment_item_options[$order_item
->id()]) || !$order_item
->hasField('purchased_entity') || in_array($order_item
->id(), $already_on_shipment, TRUE)) {
continue;
}
// Only allow items that aren't already on a shipment
// have a purchasable entity and implement the shippable trait.
$purchasable_entity = $order_item
->getPurchasedEntity();
if (!empty($purchasable_entity) && $purchasable_entity
->hasField('weight')) {
$shipment_item_options[$order_item
->id()] = $order_item
->label();
}
}
$form['shipment_items'] = [
'#type' => 'checkboxes',
'#title' => $this
->t('Shipment items'),
'#options' => $shipment_item_options,
'#default_value' => $shipment_item_defaults,
'#required' => TRUE,
'#weight' => 48,
];
$form['recalculate_shipping'] = [
'#type' => 'button',
'#value' => $this
->t('Recalculate shipping'),
'#recalculate' => TRUE,
'#ajax' => [
'callback' => [
get_class($this),
'ajaxRefresh',
],
'wrapper' => $form['#wrapper_id'],
],
// The calculation process only needs a valid shipping profile.
'#limit_validation_errors' => [
array_merge($form['#parents'], [
'shipping_profile',
]),
],
'#weight' => 49,
'#after_build' => [
[
static::class,
'clearValues',
],
],
];
return $form;
}