<p>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 <code>onBeforeOrderComplete</code> event. All works well, apart from the order email:</p>

<ol>
<li>The order email <em>doesn't</em> contain the discount code (the field is just blank).</li>
<li>Checking the product immediately after in the backend, the code is in the field.</li>
<li>Switching the order status back to <code>processing</code> sends the email with the code in it.</li>
</ol>

<p>Which makes me think the email is going out before <code>onBeforeOrderComplete</code> is triggered. Is this right?</p>

<p>Here is how I set the custom field:</p>

<pre><code>public function updateProductWithDiscountCode($productId, $discountCode) 
{

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

}
</code></pre>

<p>The plugin work in progress is here: <a href="https://github.com/cliveportman/giftVouchers" rel="nofollow noreferrer">https://github.com/cliveportman/giftVouchers</a></p>

<p>What should be happening:</p>

<ol>
<li>gift voucher product is created and added to the cart</li>
<li>payment takes place</li>
<li>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</li>
<li>the order email is sent, containing the discount code</li>
</ol>

<p>What I think is happening:</p>

<ol>
<li>gift voucher product is created and added to the cart</li>
<li>payment takes place</li>
<li>the order email is sent, without the discount code</li>
<li>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</li>
</ol>

<p>Here is a sample of the email template:</p>

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

              // THIS IS POPULATED WHEN THE PRODUCT IS CREATED SO DISPLAYS FINE
              {% if product.recipientName | length %}for {{ product.recipientName }}&lt;br&gt;{% 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 }}&lt;br&gt;{% 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 }}
              {#&lt;a href="{{ siteUrl }}orders/{{ order.number }}"&gt;Click here to view your gift voucher code&lt;/a&gt;#}&lt;br&gt;{% endif %}

            &lt;/p&gt;
        &lt;/div&gt;
    {% endif %}
  {% endfor %}
</code></pre>

CC BY-SA 3.0
2017-05-09T17:58:40.997Z
How are you setting the custom field value in the `onBeforeOrderComplete` ?
Luke Holder
CC BY-SA 3.0
2017-05-09T18:02:13.997Z
Also, the email is being sent after the `onBeforeOrderComplete`.
Luke Holder
CC BY-SA 3.0
2017-05-09T18:58:03.243Z
Hi Luke. I've added some code showing how the custom field is populated.
Clive Portman
CC BY-SA 3.0
2017-05-10T23:45:04.453Z
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
CC BY-SA 3.0
2017-05-11T08:17:37.010Z
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
CC BY-SA 3.0
2017-05-11T09:23:53.943Z
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
CC BY-SA 3.0
2017-05-11T11:16:53.660Z
Oh okay. I'll try this.
Clive Portman
CC BY-SA 3.0
2017-05-17T04:22:16.643Z
Curious - did it work?
Jeremy Daalder
CC BY-SA 3.0
2017-05-18T09:25:02.653Z
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
CC BY-SA 3.0
2017-05-18T09:44:18.240Z
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
CC BY-SA 3.0
2017-05-18T23:56:46.723Z
Yeah you understood - was just a guess.  It works with the orders fields...I'll think further!
Jeremy Daalder
<plugin-craftcommerce>
When is the order email sent out in Craft Commerce?
# When is the order email sent out in Craft Commerce?

(Asked by: username_0 on 2017-05-09)

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:

The order email doesn't contain the discount code (the field is just blank).
Checking the product immediately after in the backend, the code is in the field.
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:

gift voucher product is created and added to the cart
payment takes place
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
the order email is sent, containing the discount code

What I think is happening:

gift voucher product is created and added to the cart
payment takes place
the order email is sent, without the discount code
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 %}
        
            {{ item.price | currency(order.currency) }} {{ product.title }}
              

              // THIS IS POPULATED WHEN THE PRODUCT IS CREATED SO DISPLAYS FINE
              {% if product.recipientName | length %}for {{ product.recipientName }}{% 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 }}{% 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 }}
              {#Click here to view your gift voucher code#}{% endif %}

            
        
    {% endif %}
  {% endfor %}

**Tags:** plugin-craftcommerce
> **Comments:**
> **username_1**: How are you setting the custom field value in the `onBeforeOrderComplete` ?  
> **username_1**: Also, the email is being sent after the `onBeforeOrderComplete`.  
> **username_0**: Hi Luke. I've added some code showing how the custom field is populated.  
> **username_2**: 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!  
> **username_0**: 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.  
> **username_2**: 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!  
> **username_0**: Oh okay. I'll try this.  
> **username_2**: Curious - did it work?  
> **username_0**: 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?  
> **username_0**: 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.  
> **username_2**: Yeah you understood - was just a guess.  It works with the orders fields...I'll think further!  

---

## 0 answers

