Copy what commerce order is doing and send an optional shipment notification email when shipments are completed.

CommentFileSizeAuthor
#51 interdiff_45-51.txt30.44 KBjsacksick
#51 2918482-51.patch27.17 KBjsacksick
#50 Screen Shot 2563-09-19 at 16.58.05.png30.37 KBabx
#50 Screen Shot 2563-09-19 at 16.57.43.png63.32 KBabx
#45 interdiff.2918482.28-45.txt15.92 KBlongwave
#45 2918482-45.patch27.23 KBlongwave
#41 2918482-29.patch17.44 KBAmeDSL
#28 2918482-28.patch17.37 KBmglaman
#26 2918482-26.patch17.66 KBmglaman
#21 commerce_shipping-2918482-21.patch15.5 KBsah62
#19 commerce_shipping-2918482-19.patch15.49 KBsah62
#13 2918482-13.commerce_shipping.Create-a-shipment-notification-when-shipment-is-completed.patch18.5 KBNils Loewen
#13 interdiff.2918482.12-13.patch3.18 KBNils Loewen
#12 interdiff_5-9.txt10.2 KBNils Loewen
#12 2918482-12.commerce_shipping.Create-a-shipment-notification-when-shipment-is-completed.patch15.32 KBNils Loewen
#7 commerce_shipping-add_shipment_notification-2918482-5.patch16.01 KBandyg5000
#6 interdiff.txt839 bytesandyg5000
#6 commerce_shipping-add_shipment_notification-2918482-4.patch15.79 KBandyg5000
#5 commerce_shipping-add_shipment_notification-2918482-3.patch16.11 KBandyg5000
#4 Airmail.png52.85 KBandyg5000
#4 commerce_shipping-add_shipment_notification-2918482-2.patch16.17 KBandyg5000
#2 commerce_shipping-add_shipment_notification-2918482.patch10.35 KBandyg5000
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

andyg5000 created an issue. See original summary.

andyg5000’s picture

Status: Active » Needs review
FileSize
10.35 KB

Here's a first stab at this.

2 things need to be addressed
* Send the tracking url using tracking_code formatter if available
* Add option to enable/disable this from the shipment type config

andyg5000’s picture

Status: Needs review » Needs work

Adding items above before review :)

andyg5000’s picture

Status: Needs work » Needs review
FileSize
16.17 KB
52.85 KB

Ready for review!

andyg5000’s picture

andyg5000’s picture

My tracking url (as a link) was formatted incorrectly. Can just specify {{ tracking_code }} when it's formatted as a URL object :)

andyg5000’s picture

Properties weren't defined. Last update. Promise!

andyg5000’s picture

Assigned: andyg5000 » Unassigned
p4trizio’s picture

#7 for me is working fine

bojanz’s picture

We can now significantly reduce the size of this patch thanks to #3017080: Create a service for sending emails to customers.

EDIT: Here's the change record https://www.drupal.org/node/3030431

Nils Loewen’s picture

Status: Needs review » Needs work
Nils Loewen’s picture

I have changed this patch to now use commerce mail service. It is not quite reliable for me yet.

TODO: Tests need to be written to verify final email output contents.

Nils Loewen’s picture

The interdiff contains only the new test, which will fail because the email functionality has not yet been introduced.

Status: Needs review » Needs work
Nils Loewen’s picture

Status: Needs work » Needs review

Tests are failing because of a change in commerce. You can see 2 tests fail for the interdiff but only 1 for patch 13.

The last submitted patch, 13: interdiff.2918482.12-13.patch, failed testing. View results

Status: Needs review » Needs work
sah62’s picture

Patch re-roll...

Is anyone else interested in moving this forward? I could sure use this functionality...

sah62’s picture

What actually causes the email to be sent? I've patched my installation using the patch from #19 and processed an order. I edited the shipment to include the USPS tracking number, saved it, and hit "Send shipment" when done. I went back to the order and hit "Fulfill order". I didn't see any errors, but I didn't see any email - and I checked my server log, too.

Looking at the patch, it creates a subscriber for the "commerce_shipment.ship.post_transition" event. I can't find any code that dispatches that event, though. Did I miss another patch that adds code to dispatch the event, or is this something that's still needed for this patch?

sah62’s picture

Minor update to the patch to properly center one of the tables in the twig template...

Can this be moved to "needs review"? I have it installed and it seems to be working fine.

99gs3’s picture

We've tested this patch.

Initially did not seem to work. But after reviewing that there's an option to turn this feature on in shipment type all seems to be working well.

Good job and thanks.

sah62’s picture

Status: Needs work » Needs review

I've deployed this patch on my site and it seems to be working fine.

3CWebDev’s picture

The patch is working perfectly for us. Thanks!

mglaman’s picture

Assigned: Unassigned » mglaman
Status: Needs review » Needs work

Quick review. Going to work on a reroll.

It looks like the test from #13 went missing.

  1. +++ b/src/EventSubscriber/ShipmentSubscriber.php
    @@ -0,0 +1,140 @@
    +  /**
    +   * The entity type manager.
    +   *
    +   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
    +   */
    +  protected $entityTypeManager;
    ...
    +    $this->entityTypeManager = $entity_type_manager;
    

    The entity type manager is not used directly outside of the constructor, we don't need it as a property.

  2. +++ b/src/EventSubscriber/ShipmentSubscriber.php
    @@ -0,0 +1,140 @@
    +  /**
    +   * The language manager.
    +   *
    +   * @var \Drupal\Core\Language\LanguageManagerInterface
    +   */
    +  protected $languageManager;
    ...
    +  /**
    +   * The renderer.
    +   *
    +   * @var \Drupal\Core\Render\Renderer
    +   */
    +  protected $renderer;
    ...
    +    $this->languageManager = $language_manager;
    ...
    +    $this->renderer = $renderer;
    

    These services aren't used, it seems.

  3. +++ b/src/EventSubscriber/ShipmentSubscriber.php
    @@ -0,0 +1,140 @@
    +    $subject = $this->t('Item(s) for Order #@number shipped!', ['@number' => $order->getOrderNumber()]);
    

    We can use formatPlural for "Item(s)"

  4. +++ b/src/EventSubscriber/ShipmentSubscriber.php
    @@ -0,0 +1,140 @@
    +      // TODO This might not be necessary.
    

    Remove the TODO, it's fine to pass as context for anyone altering the mail. We may even want to pass the shipment as a param as well.

  5. +++ b/src/Form/ShipmentTypeForm.php
    @@ -82,6 +82,21 @@ class ShipmentTypeForm extends CommerceBundleEntityFormBase {
    +      '#default_value' => ($shipment_type->isNew()) ? TRUE : $shipment_type->shouldSendConfirmation(),
    ...
    +      '#default_value' => ($shipment_type->isNew()) ? '' : $shipment_type->getConfirmationBcc(),
    

    We do not need the extra parentheses around the condition.

  6. +++ b/templates/commerce-shipment-notification.html.twig
    @@ -0,0 +1,104 @@
    +<table style="margin: 15px auto 0 auto; max-width: 768px; font-family: arial,sans-serif">
    +    <tbody>
    +    <tr>
    +        <td>
    

    Seems like the indentation is off for the file.

  7. +++ b/templates/commerce-shipment-notification.html.twig
    @@ -0,0 +1,104 @@
    +                        {{ 'Item(s) in your order #@number have been shipped!'|t({'@number': order_entity.getOrderNumber}) }}
    ...
    +                                        {{ 'Item(s) in shipment:'|t }}
    

    again, get can use formatPlural utilities

mglaman’s picture

mglaman’s picture

Status: Needs review » Needs work

Tests need updating since we added reusable profiles. And I made a syntax whoopsies

+++ b/tests/src/FunctionalJavascript/ShipmentAdminTest.php
@@ -307,7 +311,7 @@ class ShipmentAdminTest extends CommerceWebDriverTestBase {
-    list($order_item) = $this->order->getItems();
+    [$order_item] = $this->order->getItems();

Ope.

mglaman’s picture

Status: Needs work » Needs review
FileSize
17.37 KB

This should fix the test and syntax.

mglaman’s picture

Assigned: mglaman » Unassigned
Status: Needs review » Reviewed & tested by the community

There are some phpcs items to fix on commit. I think this is ready to commit.

  1. +++ b/commerce_shipping.module
    @@ -283,6 +283,14 @@ function commerce_shipping_theme() {
    +    ]
    

    needs comma

  2. +++ b/src/EventSubscriber/ShipmentSubscriber.php
    @@ -0,0 +1,119 @@
    +use Drupal\Core\Language\LanguageManagerInterface;
    ...
    +use Drupal\Core\Render\Renderer;
    

    Unused

sah62’s picture

I've tested the patch from #28 on my site. It works fine.

Fool2’s picture

Looks good so far. A few things about this feature:

  • Core commerce has a "resend receipt" action, we should be able to re-send shipping notification
  • We should extend the template to have better language when the shipment includes all order items, is the only shipment, or has only one item in it

Here's some twig code I've been playing with. I'm not sure it's the right way to go, but it's how I'm overriding the template in my site.

{% if(shipment_entity.getItems().length > 1) %}
                        {{ 'Items in your order #@number have been shipped!'|t({'@number': order_entity.getOrderNumber}) }}
                        {% else %}
                        {{ 'An item in your order #@number has been shipped!'|t({'@number': order_entity.getOrderNumber}) }}
                        {% endif %}
mglaman’s picture

Status: Reviewed & tested by the community » Needs work

31.1 good point! We should add this now versus later

32.2 we have format plural logic. That should cover the usage. Is it not for you? We're missing test coverage there as well I think.

On mobile, but worth kicking back to add the action and ensure test coverage

99gs3’s picture

Receiving the following error on the latest patch.

Drupal\Component\Plugin\Exception\PluginNotFoundException: The "commerce_shipment_type" entity type does not exist. in Drupal\Core\Entity\EntityTypeManager->getDefinition() (line 150 of /home/mysite/public_html/core/lib/Drupal/Core/Entity/EntityTypeManager.php).

Did I miss something on the patch?

99gs3’s picture

Tracked the issue down.

We had issues with updating core. We had to perform a manual update which caused commerce to be removed.
We reinstalled commerce 2.16 instead of the dev version.
Patch applied properly but is now receiving the following errors. (understandably it's likely caused by patching 2.16 instead of dev.)

Error: Call to undefined method Drupal\commerce_promotion\Plugin\Commerce\PromotionOffer\OrderPercentageOff::isDisplayInclusive() in Drupal\commerce_shipping\EventSubscriber\PromotionSubscriber->Drupal\commerce_shipping\EventSubscriber\{closure}() (line 119 of /home/mysite/public_html/modules/contrib/commerce_shipping/src/EventSubscriber/PromotionSubscriber.php)

Warning: assert(): assert($offer instanceof ShipmentPromotionOfferInterface) failed in Drupal\commerce_shipping\EventSubscriber\PromotionSubscriber->Drupal\commerce_shipping\EventSubscriber\{closure}() (line 117 of /home/mysite/public_html/modules/contrib/commerce_shipping/src/EventSubscriber/PromotionSubscriber.php)

When trying to install the dev version of commerce and commerce shipping we are now receiving dependency issues.

Problem 1
- drupal/commerce_cart 2.16.0 requires drupal/commerce 2.16.0 -> satisfiable by drupal/commerce[2.16.0] but these conflict with your requirements or minimum-stability.
- drupal/commerce_cart 2.16.0 requires drupal/commerce 2.16.0 -> satisfiable by drupal/commerce[2.16.0] but these conflict with your requirements or minimum-stability.
- drupal/commerce_cart 2.16.0 requires drupal/commerce 2.16.0 -> satisfiable by drupal/commerce[2.16.0] but these conflict with your requirements or minimum-stability.
- Installation request for drupal/commerce_cart (locked at 2.16.0) -> satisfiable by drupal/commerce_cart[2.16.0].

Is it possible to directly modify the composer.lock so we can change module and dependencies to the dev version?

Thanks

kaipipek’s picture

It seems that the email is always sent to anonymous user in English even when default site language is not English and the guest completed the order in another language. Is it the same issue than with order receipt here: https://www.drupal.org/project/commerce/issues/3031195

kaipipek’s picture

There is a bug in the provided template. Shipping item quantity is always returned as integer even when it is a decimal value. Instead of just shipping_item.getQuantity|number_format is should be something like this:

{% if shipping_item.getQuantity|number_format != shipping_item.getQuantity|round(2) %}
{{ shipping_item.getQuantity|number_format(2, '.', ',') }}
{% else %}
{{ shipping_item.getQuantity|number_format }}
{% endif %}
mglaman’s picture

Decimal value quantities are non-standard. We also use number_format in the default order receipt. Any project utilizing decimal quantities will have to override this template, just like the order receipt template and any other customizations that had to be made.

kaipipek’s picture

What do you mean decimal value quantities are non-standard? They are standard since Drupal 8. There is no need for additional modules like before.

AmeDSL’s picture

#28 works as expected! The only problem is when you place an order as anonymous user, in that case the email come in english (instead of user preferred language). To fix this you can edit /src/EventSubscriber/ShipmentSubscriber.php from line 109 like that:

'id' => 'shipment_confirmation',
      'from' => $order->getStore()->getEmail(),
      'bcc' => $shipment_type->getConfirmationBcc(),
      'order' => $order,
      'shipment' => $shipment,
    ];
    $customer = $order->getCustomer();
     if ($customer->isAuthenticated()) {
       $params['langcode'] = $customer->getPreferredLangcode();
     }
     $this->mailHandler->sendMail($to, $subject, $body, $params);
  }

}

To be more clear:

'id' => 'shipment_confirmation',
      'from' => $order->getStore()->getEmail(),
      'bcc' => $shipment_type->getConfirmationBcc(),
-    'langcode' => $order->getCustomer()->getPreferredLangcode(),
      'order' => $order,
      'shipment' => $shipment,
     ];
+    $customer = $order->getCustomer();
+    if ($customer->isAuthenticated()) {
+      $params['langcode'] = $customer->getPreferredLangcode();
+    }
     $this->mailHandler->sendMail($to, $subject, $body, $params);
   }
 
AmeDSL’s picture

Patch #28 work on last RC1 release and PHP 7.3. Also work my fix for anonymous user (language) in /src/EventSubscriber/ShipmentSubscriber.php from line 109

'id' => 'shipment_confirmation',
      'from' => $order->getStore()->getEmail(),
      'bcc' => $shipment_type->getConfirmationBcc(),
-    'langcode' => $order->getCustomer()->getPreferredLangcode(),
      'order' => $order,
      'shipment' => $shipment,
     ];
+    $customer = $order->getCustomer();
+    if ($customer->isAuthenticated()) {
+      $params['langcode'] = $customer->getPreferredLangcode();
+    }
     $this->mailHandler->sendMail($to, $subject, $body, $params);
}
AmeDSL’s picture

dhruva2’s picture

Does this patch works with latest commerce 2.19?

sah62’s picture

Does this patch works with latest commerce 2.19?

I'm using the patch from #28 with Drupal Commerce 8.x-2.20 and Commerce Shipping 8.x-2.0-rc1. It works fine.

longwave’s picture

Status: Needs work » Needs review
FileSize
27.23 KB
15.92 KB

Thanks to everyone who's contributed to this issue, this is a super useful feature.

I have implemented the "Resend notification" button in the operations dropdown on the shipments page, as this was helpful when creating and testing a custom shipment notification email template.

I have also refactored the notification mail into its own ShipmentNotificationMail service, based on the OrderReceiptMail service.

The patch also includes the language changes from #39-41 but the interdiff is from #28.

sah62’s picture

The patch in #45 seems to be working for my normal workflow. The only unexpected thing I noticed was that the "Resend notification" button in the operations dropdown (thanks, this is a nice feature!) is available even when I haven't sent the shipment notification for the first time. I haven't tried to resend a notification yet.

dhruva2’s picture

@Sah it works perfectly for re-sending the notification.

99gs3’s picture

Patch 45 with Resend notification works perfectly.
However, is it possible to also send a copy to the email addresses that were configured to receive a copy as well?

Thanks

Edit: Looking over the patch, it looks like the BCC email address were included for the new Resend notification feature. However, our tests so far does not receive any email notifications that were resent to customers.

longwave’s picture

The BCC mail is only sent on the original notification, not the resend. This is the same as the order receipt functionality in Commerce Order, the BCC mail is never resent there either.

abx’s picture

Status: Needs review » Reviewed & tested by the community
FileSize
63.32 KB
30.37 KB

Just tested it with current dev and it works great. After patched, I need to go into Shipment Type setting to enable " Send customer an email confirmation when shipped" so that the email will automatically send to customer when we click on send button.

Then, we can resend the same email to customer using "Resend notification" button in the Operations.

jsacksick’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
27.17 KB
30.44 KB

I've been reviewing this today in preparation for the next RC release and made minor adjustments:

  1. I fixed several phpcs violations and small issues with the comments (Wrong class name in constructor).
  2. I renamed "notification" to "confirmation" everywhere for consistency. Shipment notification is too generic, and the shipping module might deliver additional notifications in the future. So now we have "resend confirmation", the template is now commerce-shipment-confirmation instead of commerce-shipment-notification for example.

  • jsacksick committed 0b23a18 on 8.x-2.x
    Issue #2918482 by andyg5000, mglaman, longwave, jsacksick, AmeDSL, abx:...
jsacksick’s picture

Status: Needs review » Fixed

Thanks everyone!! This is now committed!!

tonytheferg’s picture

Does this support urls for tracking links to different shipping companies tracking pages like usps, ups, and FedEx?

sah62’s picture

Does this support urls for tracking links to different shipping companies tracking pages like usps, ups, and FedEx?

No, it doesn't. The tracking code is included in the email, but the code isn't wrapped with an HTML tag to turn it into a hyperlink - and you can't just add the tag to the twig template. To make it work, you need to know which shipping company is being used so that the URL references the right service.

longwave’s picture

However, if your shipping method plugin implements SupportsTrackingInterface and you write the getTrackingUrl() method then the linked URL should be passed through to the shipping confirmation email.

sah62’s picture

The USPS plugin appears to do both of those things, but I don't see a hyperlink in my shipment notifications. There's just the tracking code. Here's the code for the getTrackingUrl function:

  public function getTrackingUrl(ShipmentInterface $shipment) {
    $code = $shipment->getTrackingCode();
    if (!empty($code)) {
      // If the tracking code token exists, replace it with the code.
      if (strstr($this->configuration['options']['tracking_url'], '[tracking_code]')) {
        $url = str_replace('[tracking_code]', $code, $this->configuration['options']['tracking_url']);
      }
      else {
        // Otherwise, append the tracking code to the end of the URL.
        $url = $this->configuration['options']['tracking_url'] . $code;
      }

      return Url::fromUri($url);
    }
    return FALSE;
  }

Status: Fixed » Closed (fixed)

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

frederico’s picture

Thanks sah62, I'll check out your solution. I appreciate you letting us know what worked for you!