-
ChatterFeed
-
0Best Answers
-
0Likes Received
-
0Likes Given
-
7Questions
-
10Replies
Why am I getting the Error: Syntax error. Missing ')' when trying to save email template
I would assume the code below should work but I seem to have my syntax wrong. I guess I need to ask is this legal. Trying to implement an If/else if logic.
<apex:image width="180" height="40" id="theImage3" value="{!IF(LEFT(relatedTo.rstk__Buyer_Contact__c,3)='Lee',
"https://geometricsinc123456--rspilot--c.cs97.content.force.com/servlet/servlet.FileDownload?file=0150U00000052qp","{!IF(LEFT(relatedTo.rstk__Buyer_Contact__c,3)='barb',"https://geometricsinc123456--rspilot--c.cs97.content.force.com/servlet/servlet.FileDownload?file=0150U00000050cW",""))}}"></apex:image>
<apex:image width="180" height="40" id="theImage3" value="{!IF(LEFT(relatedTo.rstk__Buyer_Contact__c,3)='Lee',
"https://geometricsinc123456--rspilot--c.cs97.content.force.com/servlet/servlet.FileDownload?file=0150U00000052qp","{!IF(LEFT(relatedTo.rstk__Buyer_Contact__c,3)='barb',"https://geometricsinc123456--rspilot--c.cs97.content.force.com/servlet/servlet.FileDownload?file=0150U00000050cW",""))}}"></apex:image>
- Don Pierce
- June 21, 2018
- Like
- 0
table alignment problem using deader and footer divs
I have setup an email template to handle headers and footers. The problem I have is the content inbetween will not align properly. I get an error when I try to use a div around the middle content and this appears to be due to the use of the apex:repeat code. I think it has to do with the css settings but have not been able to resolve. Here is the code and I have attached the PDF rendered. I have a few extra lines in there as I have been testing. <messaging:emailTemplate subject="Sales Order Invoice Geo" recipientType="User" relatedToType="rstk__FSOINVH__c"> <messaging:htmlEmailBody > <html> <head> <style> @page { size:a4; margin-left: 1.3cm; margin-right: 0.4cm; margin-top: 8.0cm; margin-bottom: 4.5cm; @top-left { content: element(header); } @bottom-left { content: element(footer); } } div.header { display: block; padding: 1px; position: running(header); padding-top: 1.0cm; } div.footer { display: block; padding: 1px; position: running(footer); } body, table, th, td, div { font:normal normal 95%/1.0 arial, times new roman, verdana; } body { counter-reset: pg -1; } table { cell-padding: 0; cell-spacing: 0; } #main { width:690px; background:#ffffff; } #cont { display:block; } .headerSect { width:700px; } .logoDiv { height:56px; width:220px; } .logoDiv img { display: block; height: 100%; } .cmpLogo { max-height:66px; max-width:250px; } .header2 { width:400px; border: 1px solid; padding: 1px; } .formTitle { float:left; font-weight: bold; font-size: 140%; padding-left:4px; } .pageNumSect { float:right; counter-increment: pg; } div.pageNumSect:before { content: "Page " counter(pg) " of " ; } .headerInfo { margin-top:24px; padding: 2px; } .hdrInfoLbl { font-weight: bold; } .hdrInfoData { font-weight: normal; } td { padding: 2px; } .addressSect { background-color: #000000; width:700px; margin-top:6px; margin-right:2px; } .addressSect th { text-align:center; font-weight: bold; background-color:#000000; color:#ffffff; padding: 2px; } .addressSect td { background-color:#ffffff; } .termsSect { width:700px; margin-top:6px; border: 1px solid; } .termsSect td { vertical-align:top; } .termsSect td:nth-child(1) { width: 17%; font-weight: bold; } .termsSect td:nth-child(2) { width: 33%; } .termsSect td:nth-child(3) { width: 15%; font-weight: bold; } .termsSect td:nth-child(4) { width: 35%; } table.lines { width:700px; table-layout:fixed; background-color: #ffffff; margin-top:6px; border-top: 1px solid; border-bottom: 1px solid; border-right: 1px solid; margin-left: auto; margin-right:auto; } table.lines td { background-color:#ffffff; vertical-align:top; padding: 1px; border-left: 1px solid black; } table.lines th { background-color:#000000; color:#ffffff; padding: 0px 0px 0px 0px; text-align:center; font-weight:bold; } table.footerSect { width:700px; margin-top:6px; margin-right:2px; border-top: 1px solid; border-bottom: 1px solid; border-right: 1px solid; } table.footerSect td { margin-top: 6px; border-left: 1px solid black; } table.footerSect td td { border: none; } //230 .totalLabel { font-weight: bold; width: 90px; } .totalAmt { text-align:right; width: 140px; } .totalSect td { border: 0; } .shippingComments { font-weight:bold; } table.lines tr.lines_content_row td.col_description { text-align:left; font-weight:bold; text-overflow:ellipsis; padding-left: 1em; white-space: wrap; font-size:8pt; color:blue; } table.lines tr.lines_content_row td.col_comment { text-align:left; font-style:italic; padding-left: 1em; text-overflow:ellipsis; } table.lines tr.lines_content_row td.col_empty { text-align:left; color: #ffffff; } table.lines tr.lines_content_row td.col_serial { text-align:left; padding-left: 1em; text-overflow:ellipsis; } table.lines tr.lines_content_row td.col_component { text-align:left; padding-left:1em; text-overflow:ellipsis; } table.lines tr.lines_content_row td.col_product{ text-align:left; text-overflow:ellipsis; } table.lines tr.lines_content_row td.col_uom { text-align:center; font-size:8pt; } table.lines tr.lines_content_row td.col_shipper { text-align:center; } table.lines tr.lines_content_row td.col_tax { text-align:center; } table.lines tr.lines_content_row td { text-align:right; overflow:hidden; text-overflow:clip; white-space:nowrap; } table.lines { padding-bottom: {!38 - relatedTo.rstk__numLines__c}em; } .wrapper{position:relative;} .right,.left{width:50%; position:absolute;} .right{right:0;} .left{left:0;} </style> </head> <body> <div id="main"> <!--apex:repeat value="{pages}" var="page"--> <div class="header"> <div class="headerSect"> <table cellspacing="0" cellpadding="0" border="1"> <tr><td valign="middle" width="300px"> <div class="logoDiv"> <!-- <apex:image height="48px" width="204px" value="{!relatedTo.rstk__companylogo__c}" rendered="{!!ISBLANK(relatedTo.rstk__companylogo__c)}"/>--> <apex:image styleClass=".cmpLogo" value="{!relatedTo.rstk__companylogo__c}" rendered="{!!ISBLANK(relatedTo.rstk__companylogo__c)}"/> </div> </td><td width="400px"> <!-- <div class="header2">--> <div class="formTitle">Sales Invoice</div> <div class="pageNumSect">{!relatedTo.rstk__pages__c}</div> <apex:panelGrid styleClass="headerInfo" columnClasses="hdrInfoLbl,hdrInfoData" columns="2" width="100%"> <apex:outputText value="Invoice Number"/> <apex:outputText value="{!relatedTo.rstk__invoiceno__c}"/> <apex:outputText value="Invoice Date"/> <apex:outputText value="{0,date,short}"> <apex:param value="{!relatedTo.rstk__invdate__c}"/> </apex:outputText> <apex:outputText value="Sales Order Number"/> <apex:outputText value="{!relatedTo.rstk__order__c}"/> <apex:outputText value="Customer PO Number"/> <apex:outputText value="{!relatedTo.rstk__custpo__c}"/> </apex:panelGrid> <!-- </div> --> </td></tr></table> </div> <table border="0" cellspacing="0" cellpadding="0" class="lines" style="float:left"> <tr class="lines_header_row"> <th width="4%" >Line</th> <th width="44%">Product</th> <th width="4%" >UOM</th> <th width="12%">Shipper</th> <th width="7%" >Quantity</th> <th width="9%" >Unit Price</th> <th width="7%" >Discount</th> <th width="10%">Extension</th> <th width="3%" >Tax</th> </tr></table> </div> <div class="footer"> <table class="footerSect" cellpadding="5" cellspacing="0" border="1"> <tr><td> <apex:outputText value="These items are controlled by the U.S. Government and authorized for export only to the country of ultimate destination for use by the ultimate consignee or end-user(s) herein identified. They may not be resold, transferred, or otherwise disposed of, to any other country or to any person other than the authorized ultimate consignee or end-user(s), either in their original form or after being incorporated into other items, without first obtaining approval from the U. S. government or as otherwise authorized by the U. S. law and regulations."/> </td></tr> </table> </div> <table border="0" cellspacing="0" cellpadding="0" class="lines" style="float:left"> <tr> <th width="4%" >Line</th> <th width="44%">Product</th> <th width="4%" >UOM</th> <th width="12%">Shipper</th> <th width="7%" >Quantity</th> <th width="9%" >Unit Price</th> <th width="7%" >Discount</th> <th width="10%">Extension</th> <th width="3%" >Tax</th> </tr> <apex:repeat var="l" value="{!relatedTo.rstk__lines__r}"> <tr class="lines_content_row"> <apex:variable var="isSpanRow" value="{!l.rstk__linetype__c='Description'}" /> <!-- Description Panel - Spans Across Table --> <apex:outputPanel layout="none" rendered="{! isSpanRow }"> <!-- Blank Line Number Column --> <td></td> <!-- Description Column --> <td class="col_description" colspan="8" >{!l.rstk__comment__c}</td> </apex:outputPanel> <!-- Standard Panel - No Spans --> <apex:outputPanel layout="none" rendered="{! !isSpanRow }"> <!-- Line Number Column --> <td class="col_lineno">{!l.rstk__invline__c}</td> <!-- Product Column --> <apex:variable var="productClass" value="{! 'col_product' + IF(l.rstk__linetype__c='Empty',' col_empty','') + IF(l.rstk__linetype__c='Detail', '', '') + IF(l.rstk__linetype__c='Prepayment','','') + IF(l.rstk__linetype__c='PrepaymentApplied','','') + IF(l.rstk__linetype__c='Comment',' col_comment', '') + IF(l.rstk__linetype__c='Serial', ' col_serial', '') + IF(l.rstk__linetype__c='Component', ' col_component', '') }"/> <apex:variable var="productDisplayVal" value="{! '' + IF(l.rstk__linetype__c='Empty', 'X', '') + IF(l.rstk__linetype__c='Detail', l.rstk__prod__c, '') + IF(OR(l.rstk__linetype__c='Prepayment', l.rstk__linetype__c='PrepaymentApplied', l.rstk__linetype__c='Comment', l.rstk__linetype__c='Serial'), l.rstk__comment__c, '') + IF(l.rstk__linetype__c='Component', l.rstk__component__c , '') }"/> <td class="{!productClass}"> {!productDisplayVal} </td> <!-- Unit Of Measure Column --> <td class="col_uom">{!l.rstk__uom__c}</td> <!-- Shipper Column --> <td class="col_shipper">{!l.rstk__shipper__c}</td> <!-- Quantity Column --> <td class="col_qty"> <apex:outputText value="{0,Number,###,###,###,##0.00}" rendered="{!OR(l.rstk__linetype__c='Detail',l.rstk__linetype__c='Prepayment')}"> <apex:param value="{!l.rstk__qty__c}"/> </apex:outputText> </td> <!-- Unit Price Column --> <td class="col_unitprice"> <apex:outputText value="{0,Number,###,###,###,##0.00}" rendered="{!l.rstk__linetype__c='Detail'}"> <apex:param value="{!l.rstk__price__c}"/> </apex:outputText> <apex:outputText value="{0,Number,###,###,###,##0.00}" rendered="{!l.rstk__linetype__c='Component'}"> <apex:param value="{!l.rstk__unitprice__c}"/> </apex:outputText> </td> <!-- Discount Column --> <td class="col_discount"> <apex:outputText value="{0,Number,###,###,###,##0.00}%" rendered="{!!ISBLANK(l.rstk__discpct__c)}"> <apex:param value="{!l.rstk__discpct__c}"/> </apex:outputText> </td> <!-- Extension Column --> <td class="col_extension"> <apex:variable var="isPrepaymentApplied" value="{! l.rstk__linetype__c='PrepaymentApplied' }"/> <apex:variable var="extensionAmount" value="{! IF(isPrepaymentApplied, (l.rstk__price__c - l.rstk__discamt__c) * l.rstk__qty__c , (l.rstk__price__c - l.rstk__discamt__c) * l.rstk__qty__c )}"/> <apex:outputText value="{0,Number,###,###,###,##0.00}"> <apex:param value="{!extensionAmount}"/> </apex:outputText> </td> <!-- Tax Column --> <td class="col_tax"> <apex:outputText value="{!IF(OR(relatedTo.rstk__taxexempt__c, l.rstk__taxexempt__c),'','Y')}" rendered="{!!ISBLANK(l.rstk__invline__c)}"/> </td> </apex:outputPanel> </tr> </apex:repeat> </table> <!--/apex:repeat--> <table cellpadding="0" cellspacing="0" border="1" width="100%" style="float:left"> <tr><td width="460px" valign="top"> <div style="overflow:hidden;max-height:85px;"><apex:outputText escape="false" value="{!relatedTo.rstk__extcomment__c}"/></div> </td> <td width="240px"> <apex:panelGrid styleClass="totalSect" columnClasses="totalLabel,totalAmt" columns="2" width="240px" > <apex:outputText value="SubTotal"/> <apex:outputText value="{0,Number,###,###,###,###,##0.00}"> <apex:param value="{!relatedTo.rstk__total__c}"/> </apex:outputText> <apex:outputText value="Discount" rendered="{!AND(!ISNULL(relatedTo.rstk__discamt__c), relatedTo.rstk__discamt__c>0)}"/> <apex:outputText value="({0,Number,###,###,###,###,##0.00})" rendered="{!AND(!ISNULL(relatedTo.rstk__discamt__c), relatedTo.rstk__discamt__c>0)}"> <apex:param value="{!relatedTo.rstk__discamt__c}"/> </apex:outputText> <apex:outputText value="Shipping"/> <apex:outputText value="{0,Number,###,###,###,###,##0.00}"> <apex:param value="{!relatedTo.rstk__freightamt__c+relatedTo.rstk__handlingamt__c+relatedTo.rstk__packageamt__c}"/> </apex:outputText> <apex:outputText value="Tax"/> <apex:outputText value="{0,Number,###,###,###,###,##0.00}"> <apex:param value="{!relatedTo.rstk__taxamt__c}"/> </apex:outputText> <apex:outputText value="Prepayment"/> <apex:outputText value="({0,Number,###,###,###,###,##0.00})"> <apex:param value="{!relatedTo.rstk__totalppya__c}"/> </apex:outputText> <apex:outputText value="Invoice Total"/> <apex:outputText value="{0,Number,###,###,###,###,##0.00}"> <apex:param value="{!relatedTo.rstk__grandtotal__c - relatedTo.rstk__totalppya__c}"/> </apex:outputText> </apex:panelGrid> </td></tr> </table> </div> </body> </html> </messaging:htmlEmailBody> </messaging:emailTemplate>
- Don Pierce
- May 31, 2018
- Like
- 0
Problem displaying list from Apex Class in emailtemplate
I created a simple Apex Class and VFC to display my query results in an email template.
The only thing it displays is the correct size of the list and a blank POId . No List results.
*********************Apex Code
global class POComponent
{
global string POId
{
get;
set;
}
global integer leng
{
get;
set;
}
global List<rstk__poline__c> RSNPOLine2
{
get;
set;
}
public POComponent()
{
POComponentCore();
}
public List<rstk__poline__c> POComponentCore()
{
POId = ApexPages.currentPage().getParameters().get('id');
List<rstk__poline__c> RSNPOLine2 = new List<rstk__poline__c>();
RSNPOLine2 = [SELECT rstk__poline_lne__c,rstk__poline_item__c, rstk__poline_descr__c FROM rstk__poline__c where rstk__poline_ordno__c = :POId];
leng = RSNPOLine2.size();
return RSNPOLine2;
}
}
*************************VFC code:
<apex:component controller="POComponent" access="global">
<apex:attribute name="configproducts" description="DCPId" type="String" assignTo="{!POId}"/>
<table>
<apex:repeat var="arr" value="{!RSNPOLine2}">
<tr>
<td style="width: 010mm; height: 004mm;">Just a test inside VFC</td>
<td style="width: 025mm; height: 004mm;">
<div style="width: 100%; max-width:100%; white-space: nowrap; overflow: hidden;">{!arr.rstk__poline_descr__c}</div>
</td>
<td style="width: 067mm; height: 004mm; ">
<div style="width: 100%; max-width:100%; white-space: nowrap; overflow: hidden;">{!arr.rstk__poline_item__c}</div>
</td>
<td style="width: 010mm; height: 004mm;">
<div style="width: 100%; max-width:100%; white-space: nowrap; overflow: hidden; text-align: right;">{!arr.rstk__poline_lne__c}</div>
</td>
<td style="width: 010mm; height: 004mm; ">
<div style="width: 100%; max-width:100%; white-space: nowrap; overflow: hidden; text-align: left; margin-left: 1mm;">CCCCC</div>
</td>
<td style="width: 025mm; height: 004mm;">
<div style="width: 100%; max-width:100%; white-space: nowrap; overflow: hidden; text-align: right;">1111.99</div>
</td>
</tr>
</apex:repeat>
</table>
<table>
<tr><td>This is outside the repeat loop, list size = {!leng} and POId is {!POId}</td></tr></table>
</apex:component>
******************Email Template code:
<messaging:emailTemplate subject="Purchase Order" recipientType="User" relatedToType="rstk__PO_Print_Header__c">
<messaging:htmlEmailBody >
<html>
<head>
<style type="text/css" media="print">
@page {
size:A4;
margin-left: 0.8cm;
margin-right: 0.8cm;
margin-top: 12.0cm;
margin-bottom: 4.5cm;
@top-center {
content: element(header);
}
@bottom-left {
content: element(footer);
}
}
</style>
</head>
<body>
<c:POComponent configproducts="{!relatedTo.Id}"/>
</body>
</html>
</messaging:htmlEmailBody>
</messaging:emailTemplate>
The only thing it displays is the correct size of the list and a blank POId . No List results.
*********************Apex Code
global class POComponent
{
global string POId
{
get;
set;
}
global integer leng
{
get;
set;
}
global List<rstk__poline__c> RSNPOLine2
{
get;
set;
}
public POComponent()
{
POComponentCore();
}
public List<rstk__poline__c> POComponentCore()
{
POId = ApexPages.currentPage().getParameters().get('id');
List<rstk__poline__c> RSNPOLine2 = new List<rstk__poline__c>();
RSNPOLine2 = [SELECT rstk__poline_lne__c,rstk__poline_item__c, rstk__poline_descr__c FROM rstk__poline__c where rstk__poline_ordno__c = :POId];
leng = RSNPOLine2.size();
return RSNPOLine2;
}
}
*************************VFC code:
<apex:component controller="POComponent" access="global">
<apex:attribute name="configproducts" description="DCPId" type="String" assignTo="{!POId}"/>
<table>
<apex:repeat var="arr" value="{!RSNPOLine2}">
<tr>
<td style="width: 010mm; height: 004mm;">Just a test inside VFC</td>
<td style="width: 025mm; height: 004mm;">
<div style="width: 100%; max-width:100%; white-space: nowrap; overflow: hidden;">{!arr.rstk__poline_descr__c}</div>
</td>
<td style="width: 067mm; height: 004mm; ">
<div style="width: 100%; max-width:100%; white-space: nowrap; overflow: hidden;">{!arr.rstk__poline_item__c}</div>
</td>
<td style="width: 010mm; height: 004mm;">
<div style="width: 100%; max-width:100%; white-space: nowrap; overflow: hidden; text-align: right;">{!arr.rstk__poline_lne__c}</div>
</td>
<td style="width: 010mm; height: 004mm; ">
<div style="width: 100%; max-width:100%; white-space: nowrap; overflow: hidden; text-align: left; margin-left: 1mm;">CCCCC</div>
</td>
<td style="width: 025mm; height: 004mm;">
<div style="width: 100%; max-width:100%; white-space: nowrap; overflow: hidden; text-align: right;">1111.99</div>
</td>
</tr>
</apex:repeat>
</table>
<table>
<tr><td>This is outside the repeat loop, list size = {!leng} and POId is {!POId}</td></tr></table>
</apex:component>
******************Email Template code:
<messaging:emailTemplate subject="Purchase Order" recipientType="User" relatedToType="rstk__PO_Print_Header__c">
<messaging:htmlEmailBody >
<html>
<head>
<style type="text/css" media="print">
@page {
size:A4;
margin-left: 0.8cm;
margin-right: 0.8cm;
margin-top: 12.0cm;
margin-bottom: 4.5cm;
@top-center {
content: element(header);
}
@bottom-left {
content: element(footer);
}
}
</style>
</head>
<body>
<c:POComponent configproducts="{!relatedTo.Id}"/>
</body>
</html>
</messaging:htmlEmailBody>
</messaging:emailTemplate>
- Don Pierce
- May 27, 2018
- Like
- 0
Concatenating text and textarea fails in javascript
I am trying to concatenate two fields and insert into a Note.
It works fine when I use text but fails when I try to use a textarea
InstrumentName__c is a text(255) field and IntrumentProblem_c is textarea(255)
The following works fine:
var repnew3 = new sforce.SObject('Note');
repnew3.ParentId = qr.records.Id;
repnew3.Title = '{!Case.Subject}';
// combine
repnew3.Body = '{!Case.InstrumentName__c}';
result3 = sforce.connection.create([repnew3]);
This will not work:
var repnew3 = new sforce.SObject('Note');
repnew3.ParentId = qr.records.Id;
repnew3.Title = '{!Case.Subject}';
// combine
repnew3.Body = '{!Case.InstrumentProblem__c}';
result3 = sforce.connection.create([repnew3]);
Is there a conversion process require or does the Note.Body field not accept textarea?
Ultimately I want to concatenate the two as follows:
var repnew3 = new sforce.SObject('Note');
repnew3.ParentId = qr.records.Id;
repnew3.Title = '{!Case.Subject}';
// combine
repnew3.Body = 'Problem: ' + '{!Case.InstrumentProblem__c}' + ' Name: ' + '{!Case.InstrumentName__c}';
result3 = sforce.connection.create([repnew3]);
This is being used as a button action on the Case layout.
It works fine when I use text but fails when I try to use a textarea
InstrumentName__c is a text(255) field and IntrumentProblem_c is textarea(255)
The following works fine:
var repnew3 = new sforce.SObject('Note');
repnew3.ParentId = qr.records.Id;
repnew3.Title = '{!Case.Subject}';
// combine
repnew3.Body = '{!Case.InstrumentName__c}';
result3 = sforce.connection.create([repnew3]);
This will not work:
var repnew3 = new sforce.SObject('Note');
repnew3.ParentId = qr.records.Id;
repnew3.Title = '{!Case.Subject}';
// combine
repnew3.Body = '{!Case.InstrumentProblem__c}';
result3 = sforce.connection.create([repnew3]);
Is there a conversion process require or does the Note.Body field not accept textarea?
Ultimately I want to concatenate the two as follows:
var repnew3 = new sforce.SObject('Note');
repnew3.ParentId = qr.records.Id;
repnew3.Title = '{!Case.Subject}';
// combine
repnew3.Body = 'Problem: ' + '{!Case.InstrumentProblem__c}' + ' Name: ' + '{!Case.InstrumentName__c}';
result3 = sforce.connection.create([repnew3]);
This is being used as a button action on the Case layout.
- Don Pierce
- September 04, 2017
- Like
- 0
Trigger error when attempting to delete a quote item
The error returned upon a delete of a Quote Line Item is:
There were custom validation error(s) encountered while saving the affected record(s). The first validation error encountered was "Apex trigger QuoteLineItemTrigger caused an unexpected exception, contact your administrator: QuoteLineItemTrigger: execution of AfterDelete caused by: System.NullPointerException: Attempt to de-reference a null object: Trigger.QuoteLineItemTrigger: line 12, column 1".
This is the code, I tried after delete and before delete. It works fine for after insert and after update.
trigger QuoteLineItemTrigger on QuoteLineItem (after insert, after update, after delete){
// prevent recursion
if (!QuoteLineItemUtility.TriggerIsRunning){
QuoteLineItemUtility.TriggerIsRunning = true;
Set<Id> QuoteIds = new Set<Id>();
List<QuoteLineItem> lineItemsForUpdate = new List<QuoteLineItem>();
// gather IDs first of quotes
for (QuoteLineItem ql : trigger.new) { // line 12
QuoteIds.add(ql.QuoteId);
}
if (!QuoteIds.isEmpty()) {
// get all line items for all of the above quotes in bulk so that we don't hit governor limits
Id prevQuoteId;
Double lastLineNumber;
// we can query all and these triggered records in an after trigger, nothing missing
for (QuoteLineItem ql : [Select Id, Item_Numbering__c,QuoteId,SortOrder
From QuoteLineItem
Where QuoteId in :QuoteIds
// Order By ProductName__c NULLS LAST]) {
// Order By Item_Numbering__c NULLS LAST]) {
Order By SortOrder ASC NULLS LAST]) {
// These are coming in already grouped by the same quote
// and are sorted by the line number within that group
if (prevQuoteId == null || prevQuoteId != ql.QuoteId) {
// start fresh because this is the first iteration OR we made it to
// another group of line items
prevQuoteId = ql.QuoteId;
lastLineNumber = 0.0; //back to default
}
// Set the new line numbers as needed
// if(ql.Item_Numbering__c == null || ql.Item_Numbering__c <= lastLineNumber ) {
// if(ql.Item_Numbering__c == null || ql.Item_Numbering__c == 0) {
ql.Item_Numbering__c = lastLineNumber + 1;
// Need to create a "new" in memory line item to break reference to the
// trigger reference, otherwise you will get an error like "cannot update in an After trigger"
// lineItemsForUpdate.add(new QuoteLineItem(id = ql.id, Item_Numbering__c = ql.SortOrder));
lineItemsForUpdate.add(new QuoteLineItem(id = ql.id, Item_Numbering__c = ql.Item_Numbering__c));
// }
lastLineNumber = ql.Item_Numbering__c;
} // end for
}
if (!lineItemsForUpdate.isEmpty())
update lineItemsForUpdate; // DML only the changed line items
QuoteLineItemUtility.TriggerIsRunning = false;
}
}
There were custom validation error(s) encountered while saving the affected record(s). The first validation error encountered was "Apex trigger QuoteLineItemTrigger caused an unexpected exception, contact your administrator: QuoteLineItemTrigger: execution of AfterDelete caused by: System.NullPointerException: Attempt to de-reference a null object: Trigger.QuoteLineItemTrigger: line 12, column 1".
This is the code, I tried after delete and before delete. It works fine for after insert and after update.
trigger QuoteLineItemTrigger on QuoteLineItem (after insert, after update, after delete){
// prevent recursion
if (!QuoteLineItemUtility.TriggerIsRunning){
QuoteLineItemUtility.TriggerIsRunning = true;
Set<Id> QuoteIds = new Set<Id>();
List<QuoteLineItem> lineItemsForUpdate = new List<QuoteLineItem>();
// gather IDs first of quotes
for (QuoteLineItem ql : trigger.new) { // line 12
QuoteIds.add(ql.QuoteId);
}
if (!QuoteIds.isEmpty()) {
// get all line items for all of the above quotes in bulk so that we don't hit governor limits
Id prevQuoteId;
Double lastLineNumber;
// we can query all and these triggered records in an after trigger, nothing missing
for (QuoteLineItem ql : [Select Id, Item_Numbering__c,QuoteId,SortOrder
From QuoteLineItem
Where QuoteId in :QuoteIds
// Order By ProductName__c NULLS LAST]) {
// Order By Item_Numbering__c NULLS LAST]) {
Order By SortOrder ASC NULLS LAST]) {
// These are coming in already grouped by the same quote
// and are sorted by the line number within that group
if (prevQuoteId == null || prevQuoteId != ql.QuoteId) {
// start fresh because this is the first iteration OR we made it to
// another group of line items
prevQuoteId = ql.QuoteId;
lastLineNumber = 0.0; //back to default
}
// Set the new line numbers as needed
// if(ql.Item_Numbering__c == null || ql.Item_Numbering__c <= lastLineNumber ) {
// if(ql.Item_Numbering__c == null || ql.Item_Numbering__c == 0) {
ql.Item_Numbering__c = lastLineNumber + 1;
// Need to create a "new" in memory line item to break reference to the
// trigger reference, otherwise you will get an error like "cannot update in an After trigger"
// lineItemsForUpdate.add(new QuoteLineItem(id = ql.id, Item_Numbering__c = ql.SortOrder));
lineItemsForUpdate.add(new QuoteLineItem(id = ql.id, Item_Numbering__c = ql.Item_Numbering__c));
// }
lastLineNumber = ql.Item_Numbering__c;
} // end for
}
if (!lineItemsForUpdate.isEmpty())
update lineItemsForUpdate; // DML only the changed line items
QuoteLineItemUtility.TriggerIsRunning = false;
}
}
- Don Pierce
- August 05, 2017
- Like
- 0
I do not understand why this error occurs : SObject row was retrieved via SOQL without querying the requested field
This is the error:
Apex trigger QuoteLineItemTrigger caused an unexpected exception, contact your administrator: QuoteLineItemTrigger: execution of AfterUpdate caused by: System.SObjectException: SObject row was retrieved via SOQL without querying the requested field: QuoteLineItem.QuoteId: Trigger.QuoteLineItemTrigger: line 34, column 1
Here is my code:
trigger QuoteLineItemTrigger on QuoteLineItem (after insert, after update){
// prevent recursion
if (!QuoteLineItemUtility.TriggerIsRunning){
QuoteLineItemUtility.TriggerIsRunning = true;
Set<Id> QuoteIds = new Set<Id>();
List<QuoteLineItem> lineItemsForUpdate = new List<QuoteLineItem>();
// gather IDs first of quotes
for (QuoteLineItem ql : trigger.new) {
QuoteIds.add(ql.QuoteId);
}
if (!QuoteIds.isEmpty()) {
// get all line items for all of the above quotes in bulk so that we don't hit governor limits
Id prevQuoteId;
Double lastLineNumber;
// we can query all and these triggered records in an after trigger, nothing missing
for (QuoteLineItem ql : [Select Id, Item_Numbering__c
From QuoteLineItem
Where QuoteId in :QuoteIds
Order By QuoteId, Item_Numbering__c NULLS LAST]) {
// These are coming in already grouped by the same quote
// and are sorted by the line number within that group
if (prevQuoteId == null || prevQuoteId != ql.QuoteId) {
// start fresh because this is the first iteration OR we made it to
// another group of line items
prevQuoteId = ql.QuoteId;
lastLineNumber = 0.0; //back to default
}
// Set the new line numbers as needed
if(ql.Item_Numbering__c == null || ql.Item_Numbering__c == 0) {
ql.Item_Numbering__c = lastLineNumber + 1;
// Need to create a "new" in memory line item to break reference to the
// trigger reference, otherwise you will get an error like "cannot update in an After trigger"
lineItemsForUpdate.add(new QuoteLineItem(id = ql.id, Item_Numbering__c = ql.Item_Numbering__c));
}
lastLineNumber = ql.Item_Numbering__c;
} // end for
}
if (!lineItemsForUpdate.isEmpty())
update lineItemsForUpdate; // DML only the changed line items
QuoteLineItemUtility.TriggerIsRunning = false;
}
}
Apex trigger QuoteLineItemTrigger caused an unexpected exception, contact your administrator: QuoteLineItemTrigger: execution of AfterUpdate caused by: System.SObjectException: SObject row was retrieved via SOQL without querying the requested field: QuoteLineItem.QuoteId: Trigger.QuoteLineItemTrigger: line 34, column 1
Here is my code:
trigger QuoteLineItemTrigger on QuoteLineItem (after insert, after update){
// prevent recursion
if (!QuoteLineItemUtility.TriggerIsRunning){
QuoteLineItemUtility.TriggerIsRunning = true;
Set<Id> QuoteIds = new Set<Id>();
List<QuoteLineItem> lineItemsForUpdate = new List<QuoteLineItem>();
// gather IDs first of quotes
for (QuoteLineItem ql : trigger.new) {
QuoteIds.add(ql.QuoteId);
}
if (!QuoteIds.isEmpty()) {
// get all line items for all of the above quotes in bulk so that we don't hit governor limits
Id prevQuoteId;
Double lastLineNumber;
// we can query all and these triggered records in an after trigger, nothing missing
for (QuoteLineItem ql : [Select Id, Item_Numbering__c
From QuoteLineItem
Where QuoteId in :QuoteIds
Order By QuoteId, Item_Numbering__c NULLS LAST]) {
// These are coming in already grouped by the same quote
// and are sorted by the line number within that group
if (prevQuoteId == null || prevQuoteId != ql.QuoteId) {
// start fresh because this is the first iteration OR we made it to
// another group of line items
prevQuoteId = ql.QuoteId;
lastLineNumber = 0.0; //back to default
}
// Set the new line numbers as needed
if(ql.Item_Numbering__c == null || ql.Item_Numbering__c == 0) {
ql.Item_Numbering__c = lastLineNumber + 1;
// Need to create a "new" in memory line item to break reference to the
// trigger reference, otherwise you will get an error like "cannot update in an After trigger"
lineItemsForUpdate.add(new QuoteLineItem(id = ql.id, Item_Numbering__c = ql.Item_Numbering__c));
}
lastLineNumber = ql.Item_Numbering__c;
} // end for
}
if (!lineItemsForUpdate.isEmpty())
update lineItemsForUpdate; // DML only the changed line items
QuoteLineItemUtility.TriggerIsRunning = false;
}
}
- Don Pierce
- August 04, 2017
- Like
- 0
Trying to define a trigger to number the quote line items within each quote
Here is the code but I am getting this error:
Error: Compile Error: unexpected syntax: 'missing EOF at '}'' at line 61 column 1
Of course line 61 is the closing curly brace before the Plublic Class declaration
trigger QuoteLineItemTrigger on QuoteLineItem (after insert, after update){
// prevent recursion
if (!QuoteLineItemUtility.TriggerIsRunning){
QuoteLineItemUtility.TriggerIsRunning = true;
Set<Id> QuoteIds = new Set<Id>();
List<QuoteLineItem> lineItemsForUpdate = new List<QuoteLineItem>();
// gather IDs first of quotes
for (QuoteLineItem ql : trigger.new) {
QuoteIds.add(ql.QuoteId);
}
}
if (!QuoteIds.isEmpty()) {
// get all line items for all of the above quotes in bulk so that we don't hit governor limits
Id prevQuoteId;
Integer lastLineNumber;
// we can query all and these triggered records in an after trigger, nothing missing
for (QuoteLineItem ql : [Select Id, Item_Numbering__c
From QuoteLineItem
Where QuoteId in :QuoteIds
Order By QuoteId, Item_Numbering__c NULLS LAST]) {
// These are coming in already grouped by the same quote
// and are sorted by the line number within that group
if (prevQuoteId == null || prevQuoteId != ql.QuoteId) {
// start fresh because this is the first iteration OR we made it to
// another group of line items
prevQuoteId = ql.QuoteId;
lastLineNumber = 0; //back to default
}
// Set the new line numbers as needed
if(ql.Item_Numbering__c == null || ql.Item_Numbering__c == 0) {
ql.Item_Numbering__c = lastLineNumber + 1;
// Need to create a "new" in memory line item to break reference to the
// trigger reference, otherwise you will get an error like "cannot update in an After trigger"
lineItemsForUpdate.add(new QuoteLineItem(id = ql.id, Item_Numbering__c = ql.Item_Numbering__c));
}
lastLineNumber = ql.Item_Numbering__c;
} // end for
}
if (!lineItemsForUpdate.isEmpty())
update lineItemsForUpdate; // DML only the changed line items
QuoteLineItemUtility.TriggerIsRunning = false;
}
}
public class QuoteLineItemUtility(){
public static TriggerIsRunning = false;
}
Error: Compile Error: unexpected syntax: 'missing EOF at '}'' at line 61 column 1
Of course line 61 is the closing curly brace before the Plublic Class declaration
trigger QuoteLineItemTrigger on QuoteLineItem (after insert, after update){
// prevent recursion
if (!QuoteLineItemUtility.TriggerIsRunning){
QuoteLineItemUtility.TriggerIsRunning = true;
Set<Id> QuoteIds = new Set<Id>();
List<QuoteLineItem> lineItemsForUpdate = new List<QuoteLineItem>();
// gather IDs first of quotes
for (QuoteLineItem ql : trigger.new) {
QuoteIds.add(ql.QuoteId);
}
}
if (!QuoteIds.isEmpty()) {
// get all line items for all of the above quotes in bulk so that we don't hit governor limits
Id prevQuoteId;
Integer lastLineNumber;
// we can query all and these triggered records in an after trigger, nothing missing
for (QuoteLineItem ql : [Select Id, Item_Numbering__c
From QuoteLineItem
Where QuoteId in :QuoteIds
Order By QuoteId, Item_Numbering__c NULLS LAST]) {
// These are coming in already grouped by the same quote
// and are sorted by the line number within that group
if (prevQuoteId == null || prevQuoteId != ql.QuoteId) {
// start fresh because this is the first iteration OR we made it to
// another group of line items
prevQuoteId = ql.QuoteId;
lastLineNumber = 0; //back to default
}
// Set the new line numbers as needed
if(ql.Item_Numbering__c == null || ql.Item_Numbering__c == 0) {
ql.Item_Numbering__c = lastLineNumber + 1;
// Need to create a "new" in memory line item to break reference to the
// trigger reference, otherwise you will get an error like "cannot update in an After trigger"
lineItemsForUpdate.add(new QuoteLineItem(id = ql.id, Item_Numbering__c = ql.Item_Numbering__c));
}
lastLineNumber = ql.Item_Numbering__c;
} // end for
}
if (!lineItemsForUpdate.isEmpty())
update lineItemsForUpdate; // DML only the changed line items
QuoteLineItemUtility.TriggerIsRunning = false;
}
}
public class QuoteLineItemUtility(){
public static TriggerIsRunning = false;
}
- Don Pierce
- August 03, 2017
- Like
- 0
Why am I getting the Error: Syntax error. Missing ')' when trying to save email template
I would assume the code below should work but I seem to have my syntax wrong. I guess I need to ask is this legal. Trying to implement an If/else if logic.
<apex:image width="180" height="40" id="theImage3" value="{!IF(LEFT(relatedTo.rstk__Buyer_Contact__c,3)='Lee',
"https://geometricsinc123456--rspilot--c.cs97.content.force.com/servlet/servlet.FileDownload?file=0150U00000052qp","{!IF(LEFT(relatedTo.rstk__Buyer_Contact__c,3)='barb',"https://geometricsinc123456--rspilot--c.cs97.content.force.com/servlet/servlet.FileDownload?file=0150U00000050cW",""))}}"></apex:image>
<apex:image width="180" height="40" id="theImage3" value="{!IF(LEFT(relatedTo.rstk__Buyer_Contact__c,3)='Lee',
"https://geometricsinc123456--rspilot--c.cs97.content.force.com/servlet/servlet.FileDownload?file=0150U00000052qp","{!IF(LEFT(relatedTo.rstk__Buyer_Contact__c,3)='barb',"https://geometricsinc123456--rspilot--c.cs97.content.force.com/servlet/servlet.FileDownload?file=0150U00000050cW",""))}}"></apex:image>
- Don Pierce
- June 21, 2018
- Like
- 0
table alignment problem using deader and footer divs
I have setup an email template to handle headers and footers. The problem I have is the content inbetween will not align properly. I get an error when I try to use a div around the middle content and this appears to be due to the use of the apex:repeat code. I think it has to do with the css settings but have not been able to resolve. Here is the code and I have attached the PDF rendered. I have a few extra lines in there as I have been testing. <messaging:emailTemplate subject="Sales Order Invoice Geo" recipientType="User" relatedToType="rstk__FSOINVH__c"> <messaging:htmlEmailBody > <html> <head> <style> @page { size:a4; margin-left: 1.3cm; margin-right: 0.4cm; margin-top: 8.0cm; margin-bottom: 4.5cm; @top-left { content: element(header); } @bottom-left { content: element(footer); } } div.header { display: block; padding: 1px; position: running(header); padding-top: 1.0cm; } div.footer { display: block; padding: 1px; position: running(footer); } body, table, th, td, div { font:normal normal 95%/1.0 arial, times new roman, verdana; } body { counter-reset: pg -1; } table { cell-padding: 0; cell-spacing: 0; } #main { width:690px; background:#ffffff; } #cont { display:block; } .headerSect { width:700px; } .logoDiv { height:56px; width:220px; } .logoDiv img { display: block; height: 100%; } .cmpLogo { max-height:66px; max-width:250px; } .header2 { width:400px; border: 1px solid; padding: 1px; } .formTitle { float:left; font-weight: bold; font-size: 140%; padding-left:4px; } .pageNumSect { float:right; counter-increment: pg; } div.pageNumSect:before { content: "Page " counter(pg) " of " ; } .headerInfo { margin-top:24px; padding: 2px; } .hdrInfoLbl { font-weight: bold; } .hdrInfoData { font-weight: normal; } td { padding: 2px; } .addressSect { background-color: #000000; width:700px; margin-top:6px; margin-right:2px; } .addressSect th { text-align:center; font-weight: bold; background-color:#000000; color:#ffffff; padding: 2px; } .addressSect td { background-color:#ffffff; } .termsSect { width:700px; margin-top:6px; border: 1px solid; } .termsSect td { vertical-align:top; } .termsSect td:nth-child(1) { width: 17%; font-weight: bold; } .termsSect td:nth-child(2) { width: 33%; } .termsSect td:nth-child(3) { width: 15%; font-weight: bold; } .termsSect td:nth-child(4) { width: 35%; } table.lines { width:700px; table-layout:fixed; background-color: #ffffff; margin-top:6px; border-top: 1px solid; border-bottom: 1px solid; border-right: 1px solid; margin-left: auto; margin-right:auto; } table.lines td { background-color:#ffffff; vertical-align:top; padding: 1px; border-left: 1px solid black; } table.lines th { background-color:#000000; color:#ffffff; padding: 0px 0px 0px 0px; text-align:center; font-weight:bold; } table.footerSect { width:700px; margin-top:6px; margin-right:2px; border-top: 1px solid; border-bottom: 1px solid; border-right: 1px solid; } table.footerSect td { margin-top: 6px; border-left: 1px solid black; } table.footerSect td td { border: none; } //230 .totalLabel { font-weight: bold; width: 90px; } .totalAmt { text-align:right; width: 140px; } .totalSect td { border: 0; } .shippingComments { font-weight:bold; } table.lines tr.lines_content_row td.col_description { text-align:left; font-weight:bold; text-overflow:ellipsis; padding-left: 1em; white-space: wrap; font-size:8pt; color:blue; } table.lines tr.lines_content_row td.col_comment { text-align:left; font-style:italic; padding-left: 1em; text-overflow:ellipsis; } table.lines tr.lines_content_row td.col_empty { text-align:left; color: #ffffff; } table.lines tr.lines_content_row td.col_serial { text-align:left; padding-left: 1em; text-overflow:ellipsis; } table.lines tr.lines_content_row td.col_component { text-align:left; padding-left:1em; text-overflow:ellipsis; } table.lines tr.lines_content_row td.col_product{ text-align:left; text-overflow:ellipsis; } table.lines tr.lines_content_row td.col_uom { text-align:center; font-size:8pt; } table.lines tr.lines_content_row td.col_shipper { text-align:center; } table.lines tr.lines_content_row td.col_tax { text-align:center; } table.lines tr.lines_content_row td { text-align:right; overflow:hidden; text-overflow:clip; white-space:nowrap; } table.lines { padding-bottom: {!38 - relatedTo.rstk__numLines__c}em; } .wrapper{position:relative;} .right,.left{width:50%; position:absolute;} .right{right:0;} .left{left:0;} </style> </head> <body> <div id="main"> <!--apex:repeat value="{pages}" var="page"--> <div class="header"> <div class="headerSect"> <table cellspacing="0" cellpadding="0" border="1"> <tr><td valign="middle" width="300px"> <div class="logoDiv"> <!-- <apex:image height="48px" width="204px" value="{!relatedTo.rstk__companylogo__c}" rendered="{!!ISBLANK(relatedTo.rstk__companylogo__c)}"/>--> <apex:image styleClass=".cmpLogo" value="{!relatedTo.rstk__companylogo__c}" rendered="{!!ISBLANK(relatedTo.rstk__companylogo__c)}"/> </div> </td><td width="400px"> <!-- <div class="header2">--> <div class="formTitle">Sales Invoice</div> <div class="pageNumSect">{!relatedTo.rstk__pages__c}</div> <apex:panelGrid styleClass="headerInfo" columnClasses="hdrInfoLbl,hdrInfoData" columns="2" width="100%"> <apex:outputText value="Invoice Number"/> <apex:outputText value="{!relatedTo.rstk__invoiceno__c}"/> <apex:outputText value="Invoice Date"/> <apex:outputText value="{0,date,short}"> <apex:param value="{!relatedTo.rstk__invdate__c}"/> </apex:outputText> <apex:outputText value="Sales Order Number"/> <apex:outputText value="{!relatedTo.rstk__order__c}"/> <apex:outputText value="Customer PO Number"/> <apex:outputText value="{!relatedTo.rstk__custpo__c}"/> </apex:panelGrid> <!-- </div> --> </td></tr></table> </div> <table border="0" cellspacing="0" cellpadding="0" class="lines" style="float:left"> <tr class="lines_header_row"> <th width="4%" >Line</th> <th width="44%">Product</th> <th width="4%" >UOM</th> <th width="12%">Shipper</th> <th width="7%" >Quantity</th> <th width="9%" >Unit Price</th> <th width="7%" >Discount</th> <th width="10%">Extension</th> <th width="3%" >Tax</th> </tr></table> </div> <div class="footer"> <table class="footerSect" cellpadding="5" cellspacing="0" border="1"> <tr><td> <apex:outputText value="These items are controlled by the U.S. Government and authorized for export only to the country of ultimate destination for use by the ultimate consignee or end-user(s) herein identified. They may not be resold, transferred, or otherwise disposed of, to any other country or to any person other than the authorized ultimate consignee or end-user(s), either in their original form or after being incorporated into other items, without first obtaining approval from the U. S. government or as otherwise authorized by the U. S. law and regulations."/> </td></tr> </table> </div> <table border="0" cellspacing="0" cellpadding="0" class="lines" style="float:left"> <tr> <th width="4%" >Line</th> <th width="44%">Product</th> <th width="4%" >UOM</th> <th width="12%">Shipper</th> <th width="7%" >Quantity</th> <th width="9%" >Unit Price</th> <th width="7%" >Discount</th> <th width="10%">Extension</th> <th width="3%" >Tax</th> </tr> <apex:repeat var="l" value="{!relatedTo.rstk__lines__r}"> <tr class="lines_content_row"> <apex:variable var="isSpanRow" value="{!l.rstk__linetype__c='Description'}" /> <!-- Description Panel - Spans Across Table --> <apex:outputPanel layout="none" rendered="{! isSpanRow }"> <!-- Blank Line Number Column --> <td></td> <!-- Description Column --> <td class="col_description" colspan="8" >{!l.rstk__comment__c}</td> </apex:outputPanel> <!-- Standard Panel - No Spans --> <apex:outputPanel layout="none" rendered="{! !isSpanRow }"> <!-- Line Number Column --> <td class="col_lineno">{!l.rstk__invline__c}</td> <!-- Product Column --> <apex:variable var="productClass" value="{! 'col_product' + IF(l.rstk__linetype__c='Empty',' col_empty','') + IF(l.rstk__linetype__c='Detail', '', '') + IF(l.rstk__linetype__c='Prepayment','','') + IF(l.rstk__linetype__c='PrepaymentApplied','','') + IF(l.rstk__linetype__c='Comment',' col_comment', '') + IF(l.rstk__linetype__c='Serial', ' col_serial', '') + IF(l.rstk__linetype__c='Component', ' col_component', '') }"/> <apex:variable var="productDisplayVal" value="{! '' + IF(l.rstk__linetype__c='Empty', 'X', '') + IF(l.rstk__linetype__c='Detail', l.rstk__prod__c, '') + IF(OR(l.rstk__linetype__c='Prepayment', l.rstk__linetype__c='PrepaymentApplied', l.rstk__linetype__c='Comment', l.rstk__linetype__c='Serial'), l.rstk__comment__c, '') + IF(l.rstk__linetype__c='Component', l.rstk__component__c , '') }"/> <td class="{!productClass}"> {!productDisplayVal} </td> <!-- Unit Of Measure Column --> <td class="col_uom">{!l.rstk__uom__c}</td> <!-- Shipper Column --> <td class="col_shipper">{!l.rstk__shipper__c}</td> <!-- Quantity Column --> <td class="col_qty"> <apex:outputText value="{0,Number,###,###,###,##0.00}" rendered="{!OR(l.rstk__linetype__c='Detail',l.rstk__linetype__c='Prepayment')}"> <apex:param value="{!l.rstk__qty__c}"/> </apex:outputText> </td> <!-- Unit Price Column --> <td class="col_unitprice"> <apex:outputText value="{0,Number,###,###,###,##0.00}" rendered="{!l.rstk__linetype__c='Detail'}"> <apex:param value="{!l.rstk__price__c}"/> </apex:outputText> <apex:outputText value="{0,Number,###,###,###,##0.00}" rendered="{!l.rstk__linetype__c='Component'}"> <apex:param value="{!l.rstk__unitprice__c}"/> </apex:outputText> </td> <!-- Discount Column --> <td class="col_discount"> <apex:outputText value="{0,Number,###,###,###,##0.00}%" rendered="{!!ISBLANK(l.rstk__discpct__c)}"> <apex:param value="{!l.rstk__discpct__c}"/> </apex:outputText> </td> <!-- Extension Column --> <td class="col_extension"> <apex:variable var="isPrepaymentApplied" value="{! l.rstk__linetype__c='PrepaymentApplied' }"/> <apex:variable var="extensionAmount" value="{! IF(isPrepaymentApplied, (l.rstk__price__c - l.rstk__discamt__c) * l.rstk__qty__c , (l.rstk__price__c - l.rstk__discamt__c) * l.rstk__qty__c )}"/> <apex:outputText value="{0,Number,###,###,###,##0.00}"> <apex:param value="{!extensionAmount}"/> </apex:outputText> </td> <!-- Tax Column --> <td class="col_tax"> <apex:outputText value="{!IF(OR(relatedTo.rstk__taxexempt__c, l.rstk__taxexempt__c),'','Y')}" rendered="{!!ISBLANK(l.rstk__invline__c)}"/> </td> </apex:outputPanel> </tr> </apex:repeat> </table> <!--/apex:repeat--> <table cellpadding="0" cellspacing="0" border="1" width="100%" style="float:left"> <tr><td width="460px" valign="top"> <div style="overflow:hidden;max-height:85px;"><apex:outputText escape="false" value="{!relatedTo.rstk__extcomment__c}"/></div> </td> <td width="240px"> <apex:panelGrid styleClass="totalSect" columnClasses="totalLabel,totalAmt" columns="2" width="240px" > <apex:outputText value="SubTotal"/> <apex:outputText value="{0,Number,###,###,###,###,##0.00}"> <apex:param value="{!relatedTo.rstk__total__c}"/> </apex:outputText> <apex:outputText value="Discount" rendered="{!AND(!ISNULL(relatedTo.rstk__discamt__c), relatedTo.rstk__discamt__c>0)}"/> <apex:outputText value="({0,Number,###,###,###,###,##0.00})" rendered="{!AND(!ISNULL(relatedTo.rstk__discamt__c), relatedTo.rstk__discamt__c>0)}"> <apex:param value="{!relatedTo.rstk__discamt__c}"/> </apex:outputText> <apex:outputText value="Shipping"/> <apex:outputText value="{0,Number,###,###,###,###,##0.00}"> <apex:param value="{!relatedTo.rstk__freightamt__c+relatedTo.rstk__handlingamt__c+relatedTo.rstk__packageamt__c}"/> </apex:outputText> <apex:outputText value="Tax"/> <apex:outputText value="{0,Number,###,###,###,###,##0.00}"> <apex:param value="{!relatedTo.rstk__taxamt__c}"/> </apex:outputText> <apex:outputText value="Prepayment"/> <apex:outputText value="({0,Number,###,###,###,###,##0.00})"> <apex:param value="{!relatedTo.rstk__totalppya__c}"/> </apex:outputText> <apex:outputText value="Invoice Total"/> <apex:outputText value="{0,Number,###,###,###,###,##0.00}"> <apex:param value="{!relatedTo.rstk__grandtotal__c - relatedTo.rstk__totalppya__c}"/> </apex:outputText> </apex:panelGrid> </td></tr> </table> </div> </body> </html> </messaging:htmlEmailBody> </messaging:emailTemplate>
- Don Pierce
- May 31, 2018
- Like
- 0
Problem displaying list from Apex Class in emailtemplate
I created a simple Apex Class and VFC to display my query results in an email template.
The only thing it displays is the correct size of the list and a blank POId . No List results.
*********************Apex Code
global class POComponent
{
global string POId
{
get;
set;
}
global integer leng
{
get;
set;
}
global List<rstk__poline__c> RSNPOLine2
{
get;
set;
}
public POComponent()
{
POComponentCore();
}
public List<rstk__poline__c> POComponentCore()
{
POId = ApexPages.currentPage().getParameters().get('id');
List<rstk__poline__c> RSNPOLine2 = new List<rstk__poline__c>();
RSNPOLine2 = [SELECT rstk__poline_lne__c,rstk__poline_item__c, rstk__poline_descr__c FROM rstk__poline__c where rstk__poline_ordno__c = :POId];
leng = RSNPOLine2.size();
return RSNPOLine2;
}
}
*************************VFC code:
<apex:component controller="POComponent" access="global">
<apex:attribute name="configproducts" description="DCPId" type="String" assignTo="{!POId}"/>
<table>
<apex:repeat var="arr" value="{!RSNPOLine2}">
<tr>
<td style="width: 010mm; height: 004mm;">Just a test inside VFC</td>
<td style="width: 025mm; height: 004mm;">
<div style="width: 100%; max-width:100%; white-space: nowrap; overflow: hidden;">{!arr.rstk__poline_descr__c}</div>
</td>
<td style="width: 067mm; height: 004mm; ">
<div style="width: 100%; max-width:100%; white-space: nowrap; overflow: hidden;">{!arr.rstk__poline_item__c}</div>
</td>
<td style="width: 010mm; height: 004mm;">
<div style="width: 100%; max-width:100%; white-space: nowrap; overflow: hidden; text-align: right;">{!arr.rstk__poline_lne__c}</div>
</td>
<td style="width: 010mm; height: 004mm; ">
<div style="width: 100%; max-width:100%; white-space: nowrap; overflow: hidden; text-align: left; margin-left: 1mm;">CCCCC</div>
</td>
<td style="width: 025mm; height: 004mm;">
<div style="width: 100%; max-width:100%; white-space: nowrap; overflow: hidden; text-align: right;">1111.99</div>
</td>
</tr>
</apex:repeat>
</table>
<table>
<tr><td>This is outside the repeat loop, list size = {!leng} and POId is {!POId}</td></tr></table>
</apex:component>
******************Email Template code:
<messaging:emailTemplate subject="Purchase Order" recipientType="User" relatedToType="rstk__PO_Print_Header__c">
<messaging:htmlEmailBody >
<html>
<head>
<style type="text/css" media="print">
@page {
size:A4;
margin-left: 0.8cm;
margin-right: 0.8cm;
margin-top: 12.0cm;
margin-bottom: 4.5cm;
@top-center {
content: element(header);
}
@bottom-left {
content: element(footer);
}
}
</style>
</head>
<body>
<c:POComponent configproducts="{!relatedTo.Id}"/>
</body>
</html>
</messaging:htmlEmailBody>
</messaging:emailTemplate>
The only thing it displays is the correct size of the list and a blank POId . No List results.
*********************Apex Code
global class POComponent
{
global string POId
{
get;
set;
}
global integer leng
{
get;
set;
}
global List<rstk__poline__c> RSNPOLine2
{
get;
set;
}
public POComponent()
{
POComponentCore();
}
public List<rstk__poline__c> POComponentCore()
{
POId = ApexPages.currentPage().getParameters().get('id');
List<rstk__poline__c> RSNPOLine2 = new List<rstk__poline__c>();
RSNPOLine2 = [SELECT rstk__poline_lne__c,rstk__poline_item__c, rstk__poline_descr__c FROM rstk__poline__c where rstk__poline_ordno__c = :POId];
leng = RSNPOLine2.size();
return RSNPOLine2;
}
}
*************************VFC code:
<apex:component controller="POComponent" access="global">
<apex:attribute name="configproducts" description="DCPId" type="String" assignTo="{!POId}"/>
<table>
<apex:repeat var="arr" value="{!RSNPOLine2}">
<tr>
<td style="width: 010mm; height: 004mm;">Just a test inside VFC</td>
<td style="width: 025mm; height: 004mm;">
<div style="width: 100%; max-width:100%; white-space: nowrap; overflow: hidden;">{!arr.rstk__poline_descr__c}</div>
</td>
<td style="width: 067mm; height: 004mm; ">
<div style="width: 100%; max-width:100%; white-space: nowrap; overflow: hidden;">{!arr.rstk__poline_item__c}</div>
</td>
<td style="width: 010mm; height: 004mm;">
<div style="width: 100%; max-width:100%; white-space: nowrap; overflow: hidden; text-align: right;">{!arr.rstk__poline_lne__c}</div>
</td>
<td style="width: 010mm; height: 004mm; ">
<div style="width: 100%; max-width:100%; white-space: nowrap; overflow: hidden; text-align: left; margin-left: 1mm;">CCCCC</div>
</td>
<td style="width: 025mm; height: 004mm;">
<div style="width: 100%; max-width:100%; white-space: nowrap; overflow: hidden; text-align: right;">1111.99</div>
</td>
</tr>
</apex:repeat>
</table>
<table>
<tr><td>This is outside the repeat loop, list size = {!leng} and POId is {!POId}</td></tr></table>
</apex:component>
******************Email Template code:
<messaging:emailTemplate subject="Purchase Order" recipientType="User" relatedToType="rstk__PO_Print_Header__c">
<messaging:htmlEmailBody >
<html>
<head>
<style type="text/css" media="print">
@page {
size:A4;
margin-left: 0.8cm;
margin-right: 0.8cm;
margin-top: 12.0cm;
margin-bottom: 4.5cm;
@top-center {
content: element(header);
}
@bottom-left {
content: element(footer);
}
}
</style>
</head>
<body>
<c:POComponent configproducts="{!relatedTo.Id}"/>
</body>
</html>
</messaging:htmlEmailBody>
</messaging:emailTemplate>
- Don Pierce
- May 27, 2018
- Like
- 0
Concatenating text and textarea fails in javascript
I am trying to concatenate two fields and insert into a Note.
It works fine when I use text but fails when I try to use a textarea
InstrumentName__c is a text(255) field and IntrumentProblem_c is textarea(255)
The following works fine:
var repnew3 = new sforce.SObject('Note');
repnew3.ParentId = qr.records.Id;
repnew3.Title = '{!Case.Subject}';
// combine
repnew3.Body = '{!Case.InstrumentName__c}';
result3 = sforce.connection.create([repnew3]);
This will not work:
var repnew3 = new sforce.SObject('Note');
repnew3.ParentId = qr.records.Id;
repnew3.Title = '{!Case.Subject}';
// combine
repnew3.Body = '{!Case.InstrumentProblem__c}';
result3 = sforce.connection.create([repnew3]);
Is there a conversion process require or does the Note.Body field not accept textarea?
Ultimately I want to concatenate the two as follows:
var repnew3 = new sforce.SObject('Note');
repnew3.ParentId = qr.records.Id;
repnew3.Title = '{!Case.Subject}';
// combine
repnew3.Body = 'Problem: ' + '{!Case.InstrumentProblem__c}' + ' Name: ' + '{!Case.InstrumentName__c}';
result3 = sforce.connection.create([repnew3]);
This is being used as a button action on the Case layout.
It works fine when I use text but fails when I try to use a textarea
InstrumentName__c is a text(255) field and IntrumentProblem_c is textarea(255)
The following works fine:
var repnew3 = new sforce.SObject('Note');
repnew3.ParentId = qr.records.Id;
repnew3.Title = '{!Case.Subject}';
// combine
repnew3.Body = '{!Case.InstrumentName__c}';
result3 = sforce.connection.create([repnew3]);
This will not work:
var repnew3 = new sforce.SObject('Note');
repnew3.ParentId = qr.records.Id;
repnew3.Title = '{!Case.Subject}';
// combine
repnew3.Body = '{!Case.InstrumentProblem__c}';
result3 = sforce.connection.create([repnew3]);
Is there a conversion process require or does the Note.Body field not accept textarea?
Ultimately I want to concatenate the two as follows:
var repnew3 = new sforce.SObject('Note');
repnew3.ParentId = qr.records.Id;
repnew3.Title = '{!Case.Subject}';
// combine
repnew3.Body = 'Problem: ' + '{!Case.InstrumentProblem__c}' + ' Name: ' + '{!Case.InstrumentName__c}';
result3 = sforce.connection.create([repnew3]);
This is being used as a button action on the Case layout.
- Don Pierce
- September 04, 2017
- Like
- 0
Trigger error when attempting to delete a quote item
The error returned upon a delete of a Quote Line Item is:
There were custom validation error(s) encountered while saving the affected record(s). The first validation error encountered was "Apex trigger QuoteLineItemTrigger caused an unexpected exception, contact your administrator: QuoteLineItemTrigger: execution of AfterDelete caused by: System.NullPointerException: Attempt to de-reference a null object: Trigger.QuoteLineItemTrigger: line 12, column 1".
This is the code, I tried after delete and before delete. It works fine for after insert and after update.
trigger QuoteLineItemTrigger on QuoteLineItem (after insert, after update, after delete){
// prevent recursion
if (!QuoteLineItemUtility.TriggerIsRunning){
QuoteLineItemUtility.TriggerIsRunning = true;
Set<Id> QuoteIds = new Set<Id>();
List<QuoteLineItem> lineItemsForUpdate = new List<QuoteLineItem>();
// gather IDs first of quotes
for (QuoteLineItem ql : trigger.new) { // line 12
QuoteIds.add(ql.QuoteId);
}
if (!QuoteIds.isEmpty()) {
// get all line items for all of the above quotes in bulk so that we don't hit governor limits
Id prevQuoteId;
Double lastLineNumber;
// we can query all and these triggered records in an after trigger, nothing missing
for (QuoteLineItem ql : [Select Id, Item_Numbering__c,QuoteId,SortOrder
From QuoteLineItem
Where QuoteId in :QuoteIds
// Order By ProductName__c NULLS LAST]) {
// Order By Item_Numbering__c NULLS LAST]) {
Order By SortOrder ASC NULLS LAST]) {
// These are coming in already grouped by the same quote
// and are sorted by the line number within that group
if (prevQuoteId == null || prevQuoteId != ql.QuoteId) {
// start fresh because this is the first iteration OR we made it to
// another group of line items
prevQuoteId = ql.QuoteId;
lastLineNumber = 0.0; //back to default
}
// Set the new line numbers as needed
// if(ql.Item_Numbering__c == null || ql.Item_Numbering__c <= lastLineNumber ) {
// if(ql.Item_Numbering__c == null || ql.Item_Numbering__c == 0) {
ql.Item_Numbering__c = lastLineNumber + 1;
// Need to create a "new" in memory line item to break reference to the
// trigger reference, otherwise you will get an error like "cannot update in an After trigger"
// lineItemsForUpdate.add(new QuoteLineItem(id = ql.id, Item_Numbering__c = ql.SortOrder));
lineItemsForUpdate.add(new QuoteLineItem(id = ql.id, Item_Numbering__c = ql.Item_Numbering__c));
// }
lastLineNumber = ql.Item_Numbering__c;
} // end for
}
if (!lineItemsForUpdate.isEmpty())
update lineItemsForUpdate; // DML only the changed line items
QuoteLineItemUtility.TriggerIsRunning = false;
}
}
There were custom validation error(s) encountered while saving the affected record(s). The first validation error encountered was "Apex trigger QuoteLineItemTrigger caused an unexpected exception, contact your administrator: QuoteLineItemTrigger: execution of AfterDelete caused by: System.NullPointerException: Attempt to de-reference a null object: Trigger.QuoteLineItemTrigger: line 12, column 1".
This is the code, I tried after delete and before delete. It works fine for after insert and after update.
trigger QuoteLineItemTrigger on QuoteLineItem (after insert, after update, after delete){
// prevent recursion
if (!QuoteLineItemUtility.TriggerIsRunning){
QuoteLineItemUtility.TriggerIsRunning = true;
Set<Id> QuoteIds = new Set<Id>();
List<QuoteLineItem> lineItemsForUpdate = new List<QuoteLineItem>();
// gather IDs first of quotes
for (QuoteLineItem ql : trigger.new) { // line 12
QuoteIds.add(ql.QuoteId);
}
if (!QuoteIds.isEmpty()) {
// get all line items for all of the above quotes in bulk so that we don't hit governor limits
Id prevQuoteId;
Double lastLineNumber;
// we can query all and these triggered records in an after trigger, nothing missing
for (QuoteLineItem ql : [Select Id, Item_Numbering__c,QuoteId,SortOrder
From QuoteLineItem
Where QuoteId in :QuoteIds
// Order By ProductName__c NULLS LAST]) {
// Order By Item_Numbering__c NULLS LAST]) {
Order By SortOrder ASC NULLS LAST]) {
// These are coming in already grouped by the same quote
// and are sorted by the line number within that group
if (prevQuoteId == null || prevQuoteId != ql.QuoteId) {
// start fresh because this is the first iteration OR we made it to
// another group of line items
prevQuoteId = ql.QuoteId;
lastLineNumber = 0.0; //back to default
}
// Set the new line numbers as needed
// if(ql.Item_Numbering__c == null || ql.Item_Numbering__c <= lastLineNumber ) {
// if(ql.Item_Numbering__c == null || ql.Item_Numbering__c == 0) {
ql.Item_Numbering__c = lastLineNumber + 1;
// Need to create a "new" in memory line item to break reference to the
// trigger reference, otherwise you will get an error like "cannot update in an After trigger"
// lineItemsForUpdate.add(new QuoteLineItem(id = ql.id, Item_Numbering__c = ql.SortOrder));
lineItemsForUpdate.add(new QuoteLineItem(id = ql.id, Item_Numbering__c = ql.Item_Numbering__c));
// }
lastLineNumber = ql.Item_Numbering__c;
} // end for
}
if (!lineItemsForUpdate.isEmpty())
update lineItemsForUpdate; // DML only the changed line items
QuoteLineItemUtility.TriggerIsRunning = false;
}
}
- Don Pierce
- August 05, 2017
- Like
- 0
I do not understand why this error occurs : SObject row was retrieved via SOQL without querying the requested field
This is the error:
Apex trigger QuoteLineItemTrigger caused an unexpected exception, contact your administrator: QuoteLineItemTrigger: execution of AfterUpdate caused by: System.SObjectException: SObject row was retrieved via SOQL without querying the requested field: QuoteLineItem.QuoteId: Trigger.QuoteLineItemTrigger: line 34, column 1
Here is my code:
trigger QuoteLineItemTrigger on QuoteLineItem (after insert, after update){
// prevent recursion
if (!QuoteLineItemUtility.TriggerIsRunning){
QuoteLineItemUtility.TriggerIsRunning = true;
Set<Id> QuoteIds = new Set<Id>();
List<QuoteLineItem> lineItemsForUpdate = new List<QuoteLineItem>();
// gather IDs first of quotes
for (QuoteLineItem ql : trigger.new) {
QuoteIds.add(ql.QuoteId);
}
if (!QuoteIds.isEmpty()) {
// get all line items for all of the above quotes in bulk so that we don't hit governor limits
Id prevQuoteId;
Double lastLineNumber;
// we can query all and these triggered records in an after trigger, nothing missing
for (QuoteLineItem ql : [Select Id, Item_Numbering__c
From QuoteLineItem
Where QuoteId in :QuoteIds
Order By QuoteId, Item_Numbering__c NULLS LAST]) {
// These are coming in already grouped by the same quote
// and are sorted by the line number within that group
if (prevQuoteId == null || prevQuoteId != ql.QuoteId) {
// start fresh because this is the first iteration OR we made it to
// another group of line items
prevQuoteId = ql.QuoteId;
lastLineNumber = 0.0; //back to default
}
// Set the new line numbers as needed
if(ql.Item_Numbering__c == null || ql.Item_Numbering__c == 0) {
ql.Item_Numbering__c = lastLineNumber + 1;
// Need to create a "new" in memory line item to break reference to the
// trigger reference, otherwise you will get an error like "cannot update in an After trigger"
lineItemsForUpdate.add(new QuoteLineItem(id = ql.id, Item_Numbering__c = ql.Item_Numbering__c));
}
lastLineNumber = ql.Item_Numbering__c;
} // end for
}
if (!lineItemsForUpdate.isEmpty())
update lineItemsForUpdate; // DML only the changed line items
QuoteLineItemUtility.TriggerIsRunning = false;
}
}
Apex trigger QuoteLineItemTrigger caused an unexpected exception, contact your administrator: QuoteLineItemTrigger: execution of AfterUpdate caused by: System.SObjectException: SObject row was retrieved via SOQL without querying the requested field: QuoteLineItem.QuoteId: Trigger.QuoteLineItemTrigger: line 34, column 1
Here is my code:
trigger QuoteLineItemTrigger on QuoteLineItem (after insert, after update){
// prevent recursion
if (!QuoteLineItemUtility.TriggerIsRunning){
QuoteLineItemUtility.TriggerIsRunning = true;
Set<Id> QuoteIds = new Set<Id>();
List<QuoteLineItem> lineItemsForUpdate = new List<QuoteLineItem>();
// gather IDs first of quotes
for (QuoteLineItem ql : trigger.new) {
QuoteIds.add(ql.QuoteId);
}
if (!QuoteIds.isEmpty()) {
// get all line items for all of the above quotes in bulk so that we don't hit governor limits
Id prevQuoteId;
Double lastLineNumber;
// we can query all and these triggered records in an after trigger, nothing missing
for (QuoteLineItem ql : [Select Id, Item_Numbering__c
From QuoteLineItem
Where QuoteId in :QuoteIds
Order By QuoteId, Item_Numbering__c NULLS LAST]) {
// These are coming in already grouped by the same quote
// and are sorted by the line number within that group
if (prevQuoteId == null || prevQuoteId != ql.QuoteId) {
// start fresh because this is the first iteration OR we made it to
// another group of line items
prevQuoteId = ql.QuoteId;
lastLineNumber = 0.0; //back to default
}
// Set the new line numbers as needed
if(ql.Item_Numbering__c == null || ql.Item_Numbering__c == 0) {
ql.Item_Numbering__c = lastLineNumber + 1;
// Need to create a "new" in memory line item to break reference to the
// trigger reference, otherwise you will get an error like "cannot update in an After trigger"
lineItemsForUpdate.add(new QuoteLineItem(id = ql.id, Item_Numbering__c = ql.Item_Numbering__c));
}
lastLineNumber = ql.Item_Numbering__c;
} // end for
}
if (!lineItemsForUpdate.isEmpty())
update lineItemsForUpdate; // DML only the changed line items
QuoteLineItemUtility.TriggerIsRunning = false;
}
}
- Don Pierce
- August 04, 2017
- Like
- 0
Trying to define a trigger to number the quote line items within each quote
Here is the code but I am getting this error:
Error: Compile Error: unexpected syntax: 'missing EOF at '}'' at line 61 column 1
Of course line 61 is the closing curly brace before the Plublic Class declaration
trigger QuoteLineItemTrigger on QuoteLineItem (after insert, after update){
// prevent recursion
if (!QuoteLineItemUtility.TriggerIsRunning){
QuoteLineItemUtility.TriggerIsRunning = true;
Set<Id> QuoteIds = new Set<Id>();
List<QuoteLineItem> lineItemsForUpdate = new List<QuoteLineItem>();
// gather IDs first of quotes
for (QuoteLineItem ql : trigger.new) {
QuoteIds.add(ql.QuoteId);
}
}
if (!QuoteIds.isEmpty()) {
// get all line items for all of the above quotes in bulk so that we don't hit governor limits
Id prevQuoteId;
Integer lastLineNumber;
// we can query all and these triggered records in an after trigger, nothing missing
for (QuoteLineItem ql : [Select Id, Item_Numbering__c
From QuoteLineItem
Where QuoteId in :QuoteIds
Order By QuoteId, Item_Numbering__c NULLS LAST]) {
// These are coming in already grouped by the same quote
// and are sorted by the line number within that group
if (prevQuoteId == null || prevQuoteId != ql.QuoteId) {
// start fresh because this is the first iteration OR we made it to
// another group of line items
prevQuoteId = ql.QuoteId;
lastLineNumber = 0; //back to default
}
// Set the new line numbers as needed
if(ql.Item_Numbering__c == null || ql.Item_Numbering__c == 0) {
ql.Item_Numbering__c = lastLineNumber + 1;
// Need to create a "new" in memory line item to break reference to the
// trigger reference, otherwise you will get an error like "cannot update in an After trigger"
lineItemsForUpdate.add(new QuoteLineItem(id = ql.id, Item_Numbering__c = ql.Item_Numbering__c));
}
lastLineNumber = ql.Item_Numbering__c;
} // end for
}
if (!lineItemsForUpdate.isEmpty())
update lineItemsForUpdate; // DML only the changed line items
QuoteLineItemUtility.TriggerIsRunning = false;
}
}
public class QuoteLineItemUtility(){
public static TriggerIsRunning = false;
}
Error: Compile Error: unexpected syntax: 'missing EOF at '}'' at line 61 column 1
Of course line 61 is the closing curly brace before the Plublic Class declaration
trigger QuoteLineItemTrigger on QuoteLineItem (after insert, after update){
// prevent recursion
if (!QuoteLineItemUtility.TriggerIsRunning){
QuoteLineItemUtility.TriggerIsRunning = true;
Set<Id> QuoteIds = new Set<Id>();
List<QuoteLineItem> lineItemsForUpdate = new List<QuoteLineItem>();
// gather IDs first of quotes
for (QuoteLineItem ql : trigger.new) {
QuoteIds.add(ql.QuoteId);
}
}
if (!QuoteIds.isEmpty()) {
// get all line items for all of the above quotes in bulk so that we don't hit governor limits
Id prevQuoteId;
Integer lastLineNumber;
// we can query all and these triggered records in an after trigger, nothing missing
for (QuoteLineItem ql : [Select Id, Item_Numbering__c
From QuoteLineItem
Where QuoteId in :QuoteIds
Order By QuoteId, Item_Numbering__c NULLS LAST]) {
// These are coming in already grouped by the same quote
// and are sorted by the line number within that group
if (prevQuoteId == null || prevQuoteId != ql.QuoteId) {
// start fresh because this is the first iteration OR we made it to
// another group of line items
prevQuoteId = ql.QuoteId;
lastLineNumber = 0; //back to default
}
// Set the new line numbers as needed
if(ql.Item_Numbering__c == null || ql.Item_Numbering__c == 0) {
ql.Item_Numbering__c = lastLineNumber + 1;
// Need to create a "new" in memory line item to break reference to the
// trigger reference, otherwise you will get an error like "cannot update in an After trigger"
lineItemsForUpdate.add(new QuoteLineItem(id = ql.id, Item_Numbering__c = ql.Item_Numbering__c));
}
lastLineNumber = ql.Item_Numbering__c;
} // end for
}
if (!lineItemsForUpdate.isEmpty())
update lineItemsForUpdate; // DML only the changed line items
QuoteLineItemUtility.TriggerIsRunning = false;
}
}
public class QuoteLineItemUtility(){
public static TriggerIsRunning = false;
}
- Don Pierce
- August 03, 2017
- Like
- 0