Email template placeholders broken since last updates

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Unreal51North
    Junior Member
    • Apr 2025
    • 7

    #1

    Email template placeholders broken since last updates

    Hello,

    We updated Espo to Version 9.1.7, Sales Pack to 3.0.2 and Advanced Pack to 3.10.2 last night. We are not using any other extensions.

    Since the updates, our e-mail templates are not properly showing the data behind Opportunity Placeholders when sending quotes. For example: {Opportunity.name} stays {Opportunity.name} and is not being replaced by the name of the Opportunity. Same with {Opportunity.accountName}, {Opportunity.closeDate}, {Opportunity.cChannelInformation}. It is able to pickup the information from the quote it's being sent from, but not from the related Opportunity like before.

    I see the release notes are mentioning something about email templates. Is there something that changed in the way placeholders are working?

    We cleared the cache and rebuild the backend and browser cache to make sure it wasn't cache related.

    Thank you
    Last edited by Unreal51North; Yesterday, 02:54 PM. Reason: Fixed typos
  • lazovic
    Super Moderator
    • Jan 2022
    • 1083

    #2
    Hi Unreal51North,

    Please tell me which version of EspoCRM did you upgrade from?

    Comment

    • Unreal51North
      Junior Member
      • Apr 2025
      • 7

      #3
      Originally posted by lazovic
      Hi Unreal51North,

      Please tell me which version of EspoCRM did you upgrade from?
      9.1.5 if I'm not mistaken. We are pulling from Docker Hub.
      Last edited by Unreal51North; Yesterday, 03:12 PM.

      Comment

      • yuri
        Member
        • Mar 2014
        • 9117

        #4
        It's not clear how it was working before for you. Maybe the parent was selected as the Opportunity, not as the Quote. Anyway, for the next release, I haved add the logic that Quotes, Sales Orders, Invoices will be available in the Email Template.
        If you find EspoCRM good, we would greatly appreciate if you could give the project a star on GitHub. We believe our work truly deserves more recognition. Thanks.

        Comment

        • Unreal51North
          Junior Member
          • Apr 2025
          • 7

          #5
          Originally posted by yuri
          It's not clear how it was working before for you. Maybe the parent was selected as the Opportunity, not as the Quote. Anyway, for the next release, I haved add the logic that Quotes, Sales Orders, Invoices will be available in the Email Template.
          Yuri, here is the detailed template we were using. We were sending the email right from the Quote.

          Code:
          <meta charset="UTF-8">
          <meta http-equiv="X-UA-Compatible" content="IE=edge">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>Distributor Pricing Agreement</title>
          
          <div class="container" style="font-family: Arial, sans-serif; max-width: 800px; margin: auto; padding: 20px;">
              <h2 style="background-color: #2a3f5f; color: white; padding: 15px; border-radius: 10px; text-align: center;">
                  Distributor Pricing Agreement – <strong>{Opportunity.name}</strong>
              </h2>
          
              <p>Hello,</p>
          
              <p>
                  Please find below the distributor pricing agreement prepared for <strong>{Opportunity.accountName}</strong>,
                  for the project <strong>{Opportunity.name}</strong>.
              </p>
          
          <div style="background-color: #f5f9ff; border-left: 4px solid #2a3f5f; padding: 10px 15px; margin: 20px 0;">
              <p style="margin: 0 0 8px 0; font-weight: bold; color: #2a3f5f;">
                  This pricing is for your internal use only and should be used to prepare a quote to be submitted to the following contact:
              </p>
              <p style="margin: 0;">
                  <strong>{Opportunity.contactName}</strong><br>
                  <a href="mailto:{Opportunity.contact.emailAddress}" style="color: #2a3f5f;">{Opportunity.contact.emailAddress}</a>
              </p>
          </div>
          
          
              <p><strong>Pricing Agreement Valid Until:</strong>&nbsp;{Quote.cQuoteValidUntil}</p>
          
              <br>
          
              <p><strong>Quote Items:</strong></p>
          
              {{#each itemList}}
              <table style="width: 100%; border-collapse: collapse; background-color: #ffffff; border-radius: 10px; margin: 20px 0;">
                  <thead>
                      <tr style="background-color: #f5f5f5; color: #2a3f5f; font-size: 0.9em;">
                          <th style="padding: 8px; text-align: left;">#</th>
                          <th style="padding: 8px; text-align: left;">Item</th>
                          <th style="padding: 8px; text-align: left;">Brand</th>
                          <th style="padding: 8px; text-align: center;">Qty</th>
                          <th style="padding: 8px; text-align: right;">List</th>
                          <th style="padding: 8px; text-align: right;">Discount</th>
                          <th style="padding: 8px; text-align: right;">Unit</th>
                          <th style="padding: 8px; text-align: right;">Total</th>
                          <th style="padding: 8px; text-align: right;">Currency</th>
                      </tr>
                  </thead>
                  <tbody style="font-size: 0.9em;">
                      <tr>
                          <td style="padding: 8px;">{{order}}</td>
                          <td style="padding: 8px;">{{name}}</td>
                          <td style="padding: 8px;">{{cOriginalBrand}}</td>
                          <td style="padding: 8px; text-align: center;">{{quantity}}</td>
                          <td style="padding: 8px; text-align: right;">{{listPrice}}</td>
                          <td style="padding: 8px; text-align: right;">{{discount}}%</td>
                          <td style="padding: 8px; text-align: right;">{{unitPrice}}</td>
                          <td style="padding: 8px; text-align: right;">{{amount}}</td>
                          <td style="padding: 8px; text-align: right;">{{cOriginalCurrency}}</td>
                      </tr>
                      <tr>
                          <td colspan="9" style="padding: 10px; color: #666;">{{{description}}}</td>
                      </tr>
                  </tbody>
              </table>
              {{/each}}
          
              {{#if description}}
              <div style="background-color: #fff9e5; border: 1px solid #f1c40f; border-radius: 10px; padding: 20px; margin-top: 20px;">
                  <p style="margin: 0; color: #2a3f5f; font-weight: bold;">Additional Notes</p>
                  <p style="margin-top: 8px;">{Quote.description}</p>
              </div>
              {{/if}}
          
              <br>
          
              <p style="font-size: 0.8em; color: #999; text-align: center;">
                  This pricing agreement has been provided to facilitate distributor quoting for the end purchaser listed above. It is confidential and intended solely for authorized distribution partners. Pricing is based on information available at the time of issue and may change without notice. REDACTED is not liable for discrepancies or procurement errors. Technical validation is the responsibility of the purchaser and/or integrator.
              </p>
          
              <p style="font-size: 0.8em; color: #999; text-align: center;">
                  <a href="https://REDACTED/#Quote/view/{Quote.id}" style="color: #999; text-decoration: underline;">
                      Access this quote (internal use)
                  </a>
              </p>
          </div>
          Last edited by Unreal51North; Yesterday, 04:08 PM.

          Comment

          • yuri
            Member
            • Mar 2014
            • 9117

            #6
            I don't understand how it worked before as it mixes {Quote.*} and {Opportunity.*} placeholders. Only one could work, depending on the email parent.

            Now, the Quote record is selected as as a parent of the email. Before, in some cases, Opportunity could be preselected as the parent.

            You need to use {Quote.*} placeholders.

            You can access records related to the quote: {Quote.billingContact.emailAddress}, {Quote.opportunity.name}.
            If you find EspoCRM good, we would greatly appreciate if you could give the project a star on GitHub. We believe our work truly deserves more recognition. Thanks.

            Comment

            • yuri
              Member
              • Mar 2014
              • 9117

              #7
              You might need to add Quote to the Email parent list.

              Administration > Entity Manager > Email > Fields > Parent. Add the Quote entity type to the list.
              If you find EspoCRM good, we would greatly appreciate if you could give the project a star on GitHub. We believe our work truly deserves more recognition. Thanks.

              Comment

              Working...