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