Has anyone had success adding product images into ...
# suitescript
h
Has anyone had success adding product images into quote emails? I have been trying to replicate the following logic we have for item fulfillment emails but with our default quote fields. However, no images have populated even when I try to manually assign the item.item value in the source to a known item id.
Copy code
<td>
    <#if (itemimages[item.item])?has_content>
    <img class="item-image" src="${itemimages[item.item]}" alt="" />
    </#if>
</td>
e
What's in
itemimages
?
h
Im not quite sure, currently the following template is what we use for our sitebuilder fulfillment emails:
Copy code
<!DOCTYPE html>
<html>
<head>
</head>
<body style="color: #4d5256; font-family: Open Sans, Verdana, Arial, Helvetica, sans-serif; font-size: 14px; margin: auto; padding: 27px 0 13px 0; width: 600px;">
<div>
<div>
<table style="font-family: Open Sans, Verdana, Arial, Helvetica, sans-serif;" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td style="vertical-align: bottom;">
<span style="color: #4d5256; font-size: 18px; font-weight: 600; line-height: 24px;">Order Shipped</span>
</td>
</tr>
<tr>
<td style="vertical-align: top;">
<span style="color: #4d5256; font-size: 12px; line-height: 16px;">Order number ${salesorder.memo}</span>
</td>
</tr>
</table>
</div>
<div style="margin-top: 30px; width: 100%;">
<div>
<div style="font-size: 14px; font-weight: 600;">
Dear <#if customer.isPerson == "T" && ( (customer.firstName)?has_content || (customer.lastName)?has_content )>${customer.firstName} ${customer.lastName}<#elseif customer.isPerson == "F" && (customer.companyName)?has_content>${customer.companyName}<#else>${preferences.naming_customer}</#if>,
</div>
<div>
Thank you for shopping at <#if (website.url)?has_content><a href="${website.url}" style="color: #087ca6; font-weight: 600; text-decoration: none;">${website.displayName}</a><#else><span style="font-weight: 600;">${website.displayName}</span></#if>. Your order has been shipped and will be delivered soon to:
</div>
<div>
<#if (itemfulfillment.shipAddress)?has_content>
<div style="margin-top: 16px;">
<div style="font-family: Open Sans, Verdana, Arial, Helvetica, sans-serif; font-size: 12px; font-weight: 600;">
${itemfulfillment.shipAddress}
</div>
</div>
</#if>
</div>
</div>
<div>
<div style="margin: 16px 0;">
<span style="font-weight: 600">Delivery method:</span> ${itemfulfillment.shipMethod}
</div>
<#if (salesorder.trackingLink)?has_content>
<div style="margin: 16px 0 32px 0; width: auto;">
<div style="background-color: #ebf5f7; padding: 16px; width: auto;">Tracking information: <a href="${salesorder.trackingLink}" style="color: #087ca6; text-decoration: none;">${salesorder.linkedtrackingnumbers}</a></div>
</div>
</#if>
<div style="font-weight: 600; line-height: 24px; padding-bottom: 10px;">
Shipped Items
</div>
<table style="font-family: Open Sans, Verdana, Arial, Helvetica, sans-serif; line-height: 16px; vertical-align: top; width: 100%;" cellspacing="0" cellpadding="5" border="0">
<#list itemfulfillment.item as itemline>
<tr style="margin: 4px 0;">
<td>
<#if (itemimages[itemline.itemkey])?has_content>
<img src="${itemimages[itemline.itemkey]}" style="display: block; margin-left: auto; margin-right: auto; max-height: 64px; max-width: 64px;" alt=""/>
</#if>
</td>
<td style="vertical-align: top;">
<div>
<#if (itemurls[itemline.itemkey])?has_content>
<a href="${itemurls[itemline.itemkey]}" style="color: #087ca6; font-size: 14px; line-height: 16px; text-decoration: none;">${itemline.item}</a>
<#else>
<span style="font-size: 14px; line-height: 16px;">${itemline.item}</span>
</#if>
</div>
<#if (itemline.options)?has_content>
<#assign br = "<br />">
<#list (itemline.options)?split(br) as option>
<#assign label=option?substring(0,option?index_of(":")) value=(option?substring(option?index_of(":")+1))?trim>
<div style="font-size: 12px;">
<span style="color: #81878c; text-align: left;">${label}:</span><span style="padding-left: 5px;">${value}</span>
</div>
</#list>
</#if>
<div>
<span style="color: #81878c; font-size: 12px; text-align: left;">Quantity:</span><span style="font-size: 12px; padding-left: 5px;">${itemline.quantity}</span>
</div>
</td>
</tr>
</#list>
</table>
</div>
</div>
<hr style="color:#d7f1fa;" color="#d7f1fa">
<div>
<#if (website.customerCenterUrl)?has_content>
<div style="margin-top: 8px; text-align: center;">
<span style="font-family: Open Sans, Verdana, Arial, Helvetica, sans-serif; font-size: 12px;">If you are a registered customer, you can <a href="${website.customerCenterUrl}" style="color: #087ca6; font-weight: 600; text-decoration: none;">log in</a> to see your order status</span>
</div>
</#if>
</div>
</div>
</body>
</html>
e
Well my guess is that
itemimages
doesn't exist or doesn't contain what you think it does on quotes. You'll need to figure out where it comes from on your fulfillments and replicate it for quotes.
b
@Hunter Jacobs Hi!
So I am using this:
Copy code
<#if (itemimages[itemline.item.internalId])?has_content>
  <img style="display: block; margin-left: auto; margin-right: auto; max-height: 64px; max-width: 64px;" src="${itemimages[itemline.item.internalId]?replace(' ', '%20')}" alt="" /></#if>
Let me know if that worked! 🙂
h
@Berenice Domínguez Are you using this from quote records? I'm not finding internalID at all on my quote record. When using your logic I return <img data-imagetype="Empty" data-imageerror="SrcNullOrEmpty" alt="" style="display:block; margin-left:auto; margin-right:auto; max-height:64px; max-width:64px">'
b
Oh I am using that in Sales Orders.
h
Okay, scrapped that first approach as it was not working. Now I am running into an issue where netsuite will not serve unique photos. When I generate this email the photos show but it is always 3 photos of one product. When if I remove that "one" product from the quote, a new product will populate an image on each row
Copy code
<p>Dear ${transaction.entity},</p>
<p>Your quote (Quote ID: ${transaction.tranid}) is set to expire in 7 days.</p>
<p>Quote Summary:</p>
<table class="quote-details">
        <thead>
            <tr>
                <th>Image</th>
                <th>Item</th>
                <th>Quantity</th>
                <th>Description</th>
                <th>Price</th>
            </tr>
        </thead>
        <tbody>
            <#assign itemCount = transaction.item?size>
            <#if itemCount gt 0>
                <#list 0 .. itemCount-1 as index>
                    <#assign currentItem = transaction.item[index]>
                    <#assign imageUrl = currentItem.item.storedisplaythumbnail?has_content?then(currentItem.item.storedisplaythumbnail, "default_image_url")>
                    <tr>
                        <td>
                            <!-- Debug: Output the image URL for each item -->
                            <!-- Remove or comment out the line below in the final template -->
                            <div>Debug Image URL: ${imageUrl}</div>
                            
                            <img src="${imageUrl}" class="item-image" />
                        </td>
                        <td>${currentItem.item}</td>
                        <td>${currentItem.quantity}</td>
                        <td>${currentItem.description}</td>
                        <td>${currentItem.rate}</td>
                    </tr>
                </#list>
            <#else>
                <tr>
                    <td colspan="5">No items found</td>
                </tr>
            </#if>
            <tr>
                <td style="text-align: right;" colspan="4"><strong>Total:</strong></td>
                <td><strong>$${transaction.total?string("#,##0.00")}</strong></td>
            </tr>
        </tbody>
    </table>
c
Copy code
<p>Dear ${transaction.entity},</p>
<p>Your quote (Quote ID: ${transaction.tranid}) is set to expire in 7 days.</p>
<p>Quote Summary:</p>
<table class="quote-details">
    <#list transaction.item as item>
        
        <#if item_index ===0>
            <thead>
                <tr>
                    <th>Image</th>
                    <th>Item</th>
                    <th>Quantity</th>
                    <th>Description</th>
                    <th>Price</th>
                </tr>
            </thead>
        </#if>

        <tr>
            <td>
                <#if item.storedisplaythumbnail?has_content>
                    <img src="${item.storedisplaythumbnail}" class="item-image" />
                </#if>
            </td>
            <td>${item.item}</td>
            <td>${item.quantity}</td>
            <td>${item.description}</td>
            <td>${item.rate}</td>
        </tr>
            
    </#list>
    <tr>
        <td style="text-align: right;" colspan="4"><strong>Total:</strong></td>
        <td><strong>$${transaction.total?string("#,##0.00")}</strong></td>
    </tr>
</table>
You should be able to access the list of items using transaction.item as item and not have to deal with indexes other than the initial header row. You can't create a quote (or transactions) without items (99% but could be wrong?) so there's no reason to check item count. I would just get the images displaying without any logic first like above and then you can add an else to display a default image.
h
@creece That is what i tried at first, this is more or less the Frankensteined Chatgpt code
a
You can't access item fields directly without exposing them at the transaction line level, they will only work for the first line item and repeat the same value for all lines, this is a known bug/limitation. • ${item.item} = (Transaction Item Sublist/Transaction Line Field) -> This works because item is a transaction line field. • ${item.custom_or_native_item_field} -> This does not work because you can't reach the Item field not exposed as a custom transaction line field.