1

I'm updating a custom field within a product to contain a discount code. The code is generated and the custom field updated using the onBeforeOrderComplete event. All works well, apart from the order email:

  1. The order email doesn't contain the discount code (the field is just blank).
  2. Checking the product immediately after in the backend, the code is in the field.
  3. Switching the order status back to processing sends the email with the code in it.

Which makes me think the email is going out before onBeforeOrderComplete is triggered. Is this right?

Here is how I set the custom field:

public function updateProductWithDiscountCode($productId, $discountCode) 
{

    // GET THE PRODUCT, UPDATE IT AND SAVE
    $product = craft()->commerce_products->getProductById($productId);
    $product->setContentFromPost(array('discountCode' => $discountCode ));
    if (craft()->commerce_products->saveProduct($product)) {
        GiftVouchersPlugin::log("Product #$product->id updated with coupon code $discountCode", LogLevel::Info);
    }
    return TRUE;

}

The plugin work in progress is here: https://github.com/cliveportman/giftVouchers

What should be happening:

  1. gift voucher product is created and added to the cart
  2. payment takes place
  3. when onBeforeOrderComplete is called, if the order contains a gift voucher product, we create a promo and add the discount code to a field within the product
  4. the order email is sent, containing the discount code

What I think is happening:

  1. gift voucher product is created and added to the cart
  2. payment takes place
  3. the order email is sent, without the discount code
  4. when onBeforeOrderComplete is called, if the order contains a gift voucher product, we create a promo and add the discount code to a field within the product

Here is a sample of the email template:

  {% for item in order.lineItems %}
    {% if item.purchasable | length %}
      {% set product = item.purchasable.product %}
        <div class="cartitem">
            <p><strong>{{ item.price | currency(order.currency) }} {{ product.title }}</strong>
              <br>

              // THIS IS POPULATED WHEN THE PRODUCT IS CREATED SO DISPLAYS FINE
              {% if product.recipientName | length %}for {{ product.recipientName }}<br>{% endif %}

              // THIS IS EMPTY WHEN THE ORDER EMAIL IS SENT OUT THE FIRST TIME
              // BUT IS POPULATED IF SENT OUT THROUGH A LATER STATUS CHANGE
              {% if product.discountCode | length %}code {{ product.discountCode }}<br>{% else %}

                // THIS IS EMPTY AS WELL
                {{ product.content.discountCode }}

              // THIS IS MY FALLBACK AT THE MOMENT - SENDING PEOPLE TO THE VIEW ORDER PAGE WHERE I CAN SHOW THEM THE DISCOUNT CODE USING {{ product.discountCode }}
              {#<a href="{{ siteUrl }}orders/{{ order.number }}">Click here to view your gift voucher code</a>#}<br>{% endif %}

            </p>
        </div>
    {% endif %}
  {% endfor %}
Clive Portman
  • 2,908
  • 17
  • 36
  • How are you setting the custom field value in the onBeforeOrderComplete ? – Luke Holder May 09 '17 at 17:58
  • Also, the email is being sent after the onBeforeOrderComplete. – Luke Holder May 09 '17 at 18:02
  • Hi Luke. I've added some code showing how the custom field is populated. – Clive Portman May 09 '17 at 18:58
  • Is it possible this is similar to the issue I mention at the bottom of this answer - https://craftcms.stackexchange.com/questions/14970/order-confirmation-email-in-craft-commerce/14975#14975 - perhaps you need to use the same trick i.e. product.content.etc in this case? Just guessing! – Jeremy Daalder May 10 '17 at 23:45
  • Thanks Jeremy. Like you, I'm finding the email is being sent before the OnBeforeOrderComplete function has finished. What I'm after in my email is some information from a product within the order that isn't updated until the OnBeforeOrderComplete is called - it's not information within the order itself so I don't think your order.content... is going to help. What I don't understand is why the email is being sent before my product has been updated, when according to my digging around and Luke's comment it shouldn't be doing so. – Clive Portman May 11 '17 at 08:17
  • I did actually mean product.content.whatevs specifically - I think this is a way of addressing the products content (that may have changed) before it is saved back to the db. Should only take a few seconds to try it anyway! – Jeremy Daalder May 11 '17 at 09:23
  • Oh okay. I'll try this. – Clive Portman May 11 '17 at 11:16
  • Curious - did it work? – Jeremy Daalder May 17 '17 at 04:22
  • Hi Jeremy. I'm expecting to use {{ product.discountCode }} which is the custom field, but have just tried {{ product.content.discountCode }} as I think you're suggesting. It returned nothing again. I have understood you correctly, right? – Clive Portman May 18 '17 at 09:25
  • I've added some of the order email template to the question. Am currently thinking of creating the discount earlier in the process to get around this but that way I'll have a load of unused discount codes in the backen. – Clive Portman May 18 '17 at 09:44
  • Yeah you understood - was just a guess. It works with the orders fields...I'll think further! – Jeremy Daalder May 18 '17 at 23:56

0 Answers0