Populate the title for new shipments

Created on 14 February 2022, almost 3 years ago
Updated 13 January 2024, 12 months ago

Problem/Motivation

When an order is created the DefaultPacker.php sets the title of the first shipment to Shipment #1:

    $proposed_shipments = [];
    if (!empty($items)) {
      $proposed_shipments[] = new ProposedShipment([
        'type' => $this->getShipmentType($order),
        'order_id' => $order->id(),
        'title' => $this->t('Shipment #1'),
        'items' => $items,
        'shipping_profile' => $shipping_profile,
      ]);
    }

Proposed resolution

When creating new shipments, it would be nice if a user had a default value already in the title field. We could prepopulate the titles of new shipments with an incremented numerical value. Get the number of shipments already on the order, and set the shipment title by +1

✨ Feature request
Status

Fixed

Version

2.0

Component

Code

Created by

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡ΊπŸ‡ΈUnited States rhovland Oregon

    Here is a patch that adds a default value to the title field based on how many existing shipments there are in the order.

    Why is this a form override?
    I made a function to generate the title

    /**
    * Returns a default title for the shipment based on the number of shipments currently in the order.
    * 
    * @param \Drupal\commerce_order\Entity\OrderInterface $order
    *   The shipment.
    * 
    * @return string
    *   The shipment title.
    */
    public static function generateShipmentTitle(OrderInterface $order) {
      $existing_shipments = count($order->get('shipments')->referencedEntities());
      return 'Shipment #' . ($existing_shipments + 1);
    }
    

    I tried setting the default value in the base field definition using a callback function

    ->setDefaultValueCallback('Drupal\commerce_shipping\Entity\Shipment::generateShipmentTitle')
    

    But there is no state at this point so it can't count shipments on the order.

    Why not in ShipmentForm.php ?
    I cannot set just the default value for the title here, I had to define the entire title form field. This broke the form completely and I couldn't save the shipment or use shipping calculation.

    $form['title'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Title'),
      '#default_value' => ShipmentForm::generateShipmentTitle($order),
      '#maxlength' => 255,
    ];
    
  • πŸ‡ΊπŸ‡ΈUnited States ericchew

    What if you have multiple shipment types? Should probably use hook_BASE_FORM_ID_alter instead.

  • πŸ‡ΊπŸ‡ΈUnited States rhovland Oregon

    @ericchew Where is it in ShipmentForm? I don't see it?

    I attempted to change just the default value but the whole title field went poof instead
    Eg:

    $form['title'] = [
      '#default_value' => ShipmentForm::generateShipmentTitle($order),
    ];
    
  • πŸ‡ΊπŸ‡ΈUnited States ericchew

    It's an entity form so its being built by the form display widgets when it calls $form = parent::form($form, $form_state);. Your code in #4 would break it because you're overriding the entire form element array for the title field.

    Try $form['title']['widget'][0]['value']['#default_value'] = ShipmentForm::generateShipmentTitle($order); instead which just overrides the default value key (just like you did in your form alter). This line would have to go AFTER the form is being built (see the link I put in #3 for where it is being built.

  • You'll want to make it translatable too. Something like this:

    $form['title']['widget'][0]['value']['#default_value'] = t('Shipment #@number', [
          '@number' => ($existing_shipments + 1),
        ]);
  • πŸ‡ΊπŸ‡ΈUnited States rhovland Oregon

    Here's a patch taking into account feedback. Thanks for your help!

  • πŸ‡ΊπŸ‡ΈUnited States rhovland Oregon

    So it seems this latest patch is overwriting the title value when you go to edit a shipment. I'm at a loss for how... it's setting the #default_value not #value

    The older patch works fine

  • if (empty($shipment->getTitle())) { etc...

  • Status changed to Needs review almost 2 years ago
  • Here is a patch with my approach mentioned.

  • Status changed to Fixed 12 months ago
  • πŸ‡ΊπŸ‡ΈUnited States rszrama

    Thanks. I don't even really like showing this title field, but defaulting it like this is a good starting point!

  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024