• thunksalot
  • NEWBIE
  • 200 Points
  • Member since 2009

  • Chatter
    Feed
  • 7
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 26
    Questions
  • 52
    Replies
I'm working with a client that is requiring shopping cart integration with salesforce. Does anyone know of an open source shopping cart that has the ability to integrate with salesforce? Thanks in advance.
  • October 14, 2009
  • Like
  • 0
Hi everyone,
 
Since I was not able to find any solution to this issue and there might be something out there, so if there is please direct me to the community blog.
 
I have been trying to mass update contacts or mass update tasks and when I click on Updated Selected Cells (after I have all of my ID's populated and everything else I need ) this is the error message I am getting and I have no idea how to fix it.
 
==================================================
Set qr = sfApi.Retrieve("*", entityType, idlist, False)
Set DoFullGet = ProcessQueryResults(qr)
End Function
 
passing a limited sels list keeps this a fast routine.
Public Function Retrieve(sels As String, idlist() As String, entityType As String) As Object
    ' make sure id list has no blanks
    Dim i%: For i = 0 To UBound(idlist)
      Debug.Assert idlist(i) <> "" ' bad things ...
    Next i
    Set Retrieve = sfApi.Retrieve(sels, entityType, idlist, False)
End Function
 
' load it up in a dictionary of object by id
' NOTE, the query result may be more than 2000 long, in which case
' we probably would miss something, ouch...
' TODO find out if this is happening ?
'
Public Function ProcessQueryResults(ByVal qr As QueryResultSet3) As Object
    Dim s As SObject3
 
==========================================
Then when I want to close the Excel spreadsheet I am getting the following message:
 
Microsoft Visual Basic -  This command will stop the debugger.
==============================================
The only way to exit Excel is by saying Ok to this message and when you do that the following message comes up: Application-defined or object-defined error.
 
 
Did anybody ever encounter this message before? Any ideas will be more than appreciated. Thank you so much!
 
Blanka
 
  • November 14, 2008
  • Like
  • 0

It appears that I have code that works perfectly in both a production and a sandbox environment, but does not work when called from a unit test that performs the same operations that work just fine using the GUI.

 

I've modified the CampaignCallDownController to have filters and a search box.  The below test adds one Contact and one Lead to a Campaign, then invokes the CampaignCallDown VF page and controller.  When I do those steps using the GUI in production or the sandbox, the call list shows two records, one Contact and one Lead.  But when I run this unit test, it says there are zero records in the call list.  I've tracked the problem down to this query in the CampaignCallDownController...

 

members = [select Id, ContactId, LeadId, Status, CampaignId, Level_of_Interest__c, 

                    Last_Action__c, Next_Action__c, Campaign.Name,

                    Lead.Id, Lead.Salutation, Lead.Title, Lead.Name, Lead.Company, Lead.Phone, 

                    Lead.Street, Lead.State, Lead.Email,

                    Contact.ID, Contact.AccountId, Contact.Salutation, Contact.Title, Contact.Name

                    Contact.Phone, Contact.MailingState, Contact.Email, Contact.Account.name

                    from CampaignMember where CampaignId = :camp AND Next_Action__c LIKE :desiredNA AND 

                    (NOT Next_Action__c LIKE :excludedNA) AND Level_of_Interest__c LIKE :desiredLI AND 

                    (NOT Level_of_Interest__c LIKE :excludedLI) AND

                    (Contact.Account.Name LIKE :searchFilter OR Contact.Name LIKE :searchFilter

ORContact.Email LIKE :searchFilter 

                    OR Contact.Title LIKE :searchFilter OR Contact.MailingState LIKE :searchFilter OR 

                    Lead.Name LIKE :searchFilter OR Lead.Company LIKE :searchFilter  OR 

                    Lead.Email LIKE :searchFilter OR Lead.Title LIKE :searchFilter OR Lead.State LIKE :searchFilter

                    ORDER BY Contact.Account.name LIMIT :recordsPerPage OFFSET :offset ];

 

I've highlighted the part of the query that performs the search function because that's where the problem is.  When that query gets called from the GUI, it will return all Leads *and* Contacts that match the searchFilter criteria.  But when called from the test, it will only return an empty list, not matter what search or filter criteria are input.  I've stripped the query criteria down to just the red and blue parts and found that if I remove one or the other (the Contact field matching or the Lead field matching criteria) it will return records when called from the below test.  In other words, if I remove the red part it will return 1 Lead in the test below.  Or, if I leave in the red part and remove the blue part, it will return 1 Contact in the test below.  But, if I leave both in, it will return zero leads and zero contacts.  When the same operations are performed in the GUI, it returns two records - both the Lead and the Contact.

 

Anybody know what's going  on?  Have I hit a bug in the way tests are executed by SFDC?  I'm about to pull my hair out - or write a unit test that is really a non-test!! :(

 

 

@isTest
private class CampaignCallDownControllerTest {

     static testMethod void testNormalFlow(){
     	
     	//get campaign member record type ID
     	RecordType rt = [select id,Name from RecordType where SobjectType='CampaignMember' and Name='Email Campaign Member' Limit 1];
     	
        //campaign
        Campaign testCampaign       = new Campaign();
        testCampaign.name           = 'TestCampaign';
        testCampaign.CampaignMemberRecordTypeId = rt.ID;
        insert testCampaign;
        
        Account testAccount		= new Account();
        testAccount.name		= 'TestAccount';
        insert testAccount;  
                
        //Lead
        Lead testLead1          = new Lead();
        testLead1.FirstName     = 'LeadFirstName1';
        testLead1.LastName      = 'LeadLastName1';
        testLead1.Company       = 'Test1';
        insert testLead1;
        
        //Contact
        Contact testContact1         = new Contact();
        testContact1.FirstName       = 'ContactFirstName';
        testContact1.LastName        ='ContactLastName';
        testContact1.Email           = 'Adress1@Adress.com';
        testContact1.Title           = 'ContactTitle';
        testContact1.AccountID 		 = testAccount.ID;
        insert testContact1;
        
        //make campaign members
        CampaignMember testCM1       = new CampaignMember();
        testCM1.leadID               = testLead1.Id;
        testCM1.contactID			 = null;
        testCM1.campaignID           = testCampaign.Id;
        testCM1.Status               = 'Sent';
        testCM1.Level_of_Interest__c = 'Interested';
        testCM1.Next_Action__c 		 = 'contact now';
        insert testCM1;
        
        CampaignMember testCM3      = new CampaignMember();
        testCM3.ContactId           = testContact1.Id;
        testCM3.LeadID			 	= null;
        testCM3.CampaignId          = testCampaign.Id;
        testCM3.Status              = 'Sent';
        testCM3.Level_of_Interest__c= 'Interested';        
        testCM3.Next_Action__c 		= 'contact now';
        insert testCM3;
        
		// Check to make sure the contacts and leads made it into the campaign        
        testCampaign = [SELECT ID, NumberofContacts, NumberOfLeads FROM Campaign WHERE ID = :testCampaign.ID];       
        System.assertEquals(1,testCampaign.NumberofContacts);
        System.assertEquals(1,testCampaign.NumberofLeads);
                
        //begin tests
 		// instantiate page
 		PageReference pageRef = Page.CampaignCallDown;
 		Test.setCurrentPage(pageRef);
 		ApexPages.currentPage().getParameters().put('camp',testCampaign.Id);

        CampaignCallDownController ccdc1 = new CampaignCallDownController();
	System.assert(ccdc1.getHasCampaignID() == TRUE);
	System.assertequals(2, ccdc1.getLeadPlusTasks().size()); // FAILS HERE
		 		
 	}

 

I'm having a really bizarre experience with the OFFSET clause.  Sometimes when I save the class in Eclipse with the below SOQL query in it, it saves to my sandbox org with no error.  Other times, I get an error saying "expecting right square bracket, found 'OFFSET'".  There doesn't seem to be any rhyme or reason for when it does and doesn't throw the error.  And, more bizarrely, it appears to be successfully saving to my sandbox org in spite of the error.

 

The apex class is using the 27.0 API and I have had SF support enable the OFFSET soql functionality to my production and sandbox orgs.  I'm using the latest version of Eclipse 3.5.2.  Any ideas?

 

members = [select Id, ContactId, LeadId, Status, CampaignId, Level_of_Interest__c, 

                    Last_Action__c, Next_Action__c, Campaign.Name,

                    Lead.Id, Lead.Salutation, Lead.Title, Lead.Name, Lead.Company, Lead.Phone, 

                    Lead.Street, Lead.State, Lead.Email,

                    Contact.ID, Contact.AccountId, Contact.Salutation, Contact.Title, Contact.Name

                    Contact.Phone, Contact.MailingState, Contact.Email, Contact.Account.name

                    from CampaignMember where CampaignId = :camp AND Next_Action__c LIKE :desiredNA AND 

                    (NOT Next_Action__c LIKE :excludedNA) AND Level_of_Interest__c LIKE :desiredLI AND 

                    (NOT Level_of_Interest__c LIKE :excludedLI) AND

                    (NOT Contact.Account.name LIKE 'Remove from SF'

                    AND (Contact.Account.Name LIKE :searchFilter OR Contact.Name LIKE :searchFilter

                    OR Lead.Name LIKE :searchFilter OR Lead.Company LIKE :searchFilter OR 

                    Lead.Email LIKE :searchFilter OR Contact.Email LIKE :searchFilter OR

                    Contact.Title LIKE :searchFilter OR Lead.Title LIKE :searchFilter 

                    OR Contact.MailingState LIKE :searchFilter OR Lead.State LIKE :searchFilter) 

                    ORDER BY Contact.Account.name LIMIT 200 OFFSET 200];

I want to concatenate two object IDs in order to make a hash value for a map, but this doesn't work:

 

conversionMap.put(entry.Pricebook2Id + entry.Product2Id), entry);

If I could convert the IDs to strings first, then I should be able to concatenate them in this way.  But, while there is a function to convert a string to an ID, I can't find any way to convert an ID to a string.  Anybody know how to do that?  Or, a better way to do what I'm trying to do?

 

I'm working with a VF page and Apex controller and I want to be able to do SOQL queries that are limited to 200 results but that start the results at different places in the total query results.  In other words have queries that would get me the first 200 results, the second 200 results and so on...  BUT, I want to be able to jump around so that the user could jump straight from the 1st page of results (records 1-200) to the 5th page of results (query for results 1,000 to 1,200).  Is that possible?  I cannot query *all* the records and then just return 200 to the page at a time because the query returns too much data.  So, I'd want to run the query again each time but getting a specific subset.   Kind of like a row limit but starting at a certain record count.  

 

Totally crazy?

I deployed a class *successfully* on 1/14/2012.  Seven days later, I discovered that when I try to deploy anything at all, even a class that only has whitespace changes, the deployment fails with the message that the test for the class that I deployed successfully on 1/14 has "Too many script statements: 200001".  How can that be?  How can it have passed the test successfully while deploy successfully 10 days ago and now I can't deploy anything because it is failing, when I haven't changed it in any way?!

The worst part is that aside from keeping me from being able to deploy anything, which I discovered on Friday, one of my users discovered yesterday that using the button that calls this class is now resulting in the "Too many script statements: 200001" error message.  So, I now do have business processes being interrupted.  Which is really, really strange because right after I *successfully* deployed that class on 1/14, I used that button to *successfully* process far more records (180) than my users are processing when they use it (1-2).  

 

Anybody have any idea what could have changed between when it was deploying and working fine and now?  I'm totally at a loss to explain what could have changed.  I have all the info about how to deal with this error, in general, such as using @future and reducing for loops, but I want to know how the code could have become broken *after* deploying successfully and running correctly under much greater stress than it is failing under now.  That is the most disconcerting thing to me.

Thanks for any clues!

 

I'm trying to increment the Invoice Count on the Opportunity each time a new invoice is issued for the Opportunity.  The Invoice is a Visualforce Component that is called either by an VF Page or an VF Email Template (since the invoices can be downloaded as PDF or emailed as an attachment).

 

I see on this page of the VF documentation that is *not* a good practice to try and increment a variable within a Setter method.  But, the documentation doesn't suggest any alternative.  How can I accomplish this?  Note that since this is a PDF invoice, I can't use any Action methods.

 

Below is what I have now and here's the error I'm getting:

 

common.apex.runtime.impl.DmlExecutionException: Update failed. First exception on row 0 with id 006J00000039ZoeIAE; first error: UNABLE_TO_LOCK_ROW, unable to obtain exclusive access to this record: [] 

Here's my component's opening where the parameter is passed, kicking off the Set function below:

<apex:component access="global" controller="IAR_Controller" allowDML="TRUE" >
<!--  pass the Opportunity to the controller's opportunity object -->
<apex:attribute name="opportunityID" description="" type="ID" assignTo="{!opportunityID}"/>

 

Here's my controller set function:

    public Id opportunityID { 
        get; 
        set{
            //  When the OpportunityID is set by the component parameter tag, 
            //  it is now possible to query all the opportunity, transaction and lineitem info
            opportunityID = value;
            opportunity = [select Id, Invoice_Count__c from Opportunity WHERE Id = :this.opportunityID];
            transactions = [select Id from ChargentSFA__Transaction__c WHERE ChargentSFA__Transaction__C.ChargentSFA__Opportunity__c = :opportunity.ID];
            opportunitylineitems = [select Id from OpportunityLineItem where opportunityId = :opportunity.ID];

            // In case the Invoice Count has not defaulted to 1 for some reason and is therefore null,
            // set it to 1.
            if(opportunity.Invoice_Count__c == null){ opportunity.Invoice_Count__c = 1;}
           
            // Since this is really the initialization, increment the the Invoice Count now so that 
            // this Invoice will have one higher count than the previous one
            if(docType == 'invoice' && opportunity.Invoice_Count__C != null){
                opportunity.Invoice_Count__c = opportunity.Invoice_Count__c + 1;
                update opportunity;
            }
        }
    }

 

For over a year now, my org has been generating and sending invoices and receipts using VF Components that are rendered as PDFs and attached to VF Email Templates.  The invoices and receipts each use CSS styles defined within a <style> tag in the header.  I just discovered that after the Summer '12 release, those styles are no longer being rendered.  As a result, the CSS style definitions are being printed at the top of the PDFs and the invoices and receipts have no styling.

 

Is anyone else having this problem?  I'm on na7.  I don't see it in the Known Issues but have submitted a support case.

 

I'm going to try moving the style definitions into a CSS stylesheet, loading that as a static resource and then referencing it with the <apex:stylesheet> tag.  Hopefully, that will work.  If not, I'm not sure what to try next.

 

So far, I've only been able to figure out how to generate PDF email attachments that my users can send from an object by embedding the Visualforce code for the PDF within the <messaging:attachment> tag for a Visualforce Email Template.  The downside to this is that the message body of the email is not editable by the user.  This means my generated attachments always get sent with the same impersonal boilerplate message body.

 

I didn't know it was possible to do any better until I got my AppExchange newsletter today and saw the demo of Steel Brick's QuoteQuickly app.  I was surprised to see at the 1:30 mark of the video's second part that they claim they are using Force.com's built-in Send Email functionality to send quotes - and then they show the Send Email form load with an editable message body AND with their generated PDF already attached.  

 

How are they doing that?  Anybody know or have a guess?  

 

Unfortunately, QuoteQuickly doesn't meet my needs, so I need to figure out how to replicate that functionality.

 

Much thanks in advance for any assistance!

I'm trying to debug a single test method but my log file is coming out with tens of thousands of lines.  I tried filtering using the debug log filter instructions here.  That did improve the situation by reducing the log size.  But, even if I set *all* the filter levels to NONE, I still get a log file that is 7k lines long.  I can't get it down any further than that, which I want to do because it seems like there is still a ton of stuff being thrown in there that is extraneous for my purposes.  

 

What's really odd is that no matter what I set the log filter levels to, the log file still begins with "20.0 APEX_CODE,FINE;APEX_PROFILING,FINE;DB,INFO;VALIDATION,INFO;WORKFLOW,FINEST".  Which is odd because I can tell by the variation in log file sizes that the filter levels I'm assiging are having an effect.

 

Doesn't it seem like I should get a zero line log file if I set all the debug levels to zero?

For each Account, I need to know the ID of the Opportunity related to it that has the newest renewal date.  I was thinking that I could query Opportunity records for their ID with a GROUP BY on AccountID and a MAX(Renewal_Date__c), like this:

 

AggregateResult[] groupedResults
= [SELECT ID, AccountID, MAX(Renewal_Date__c)
FROM Opportunity
WHERE AccountID in :acctIDs AND RecordTypeID = '012A0000000qpET'
GROUP BY AccountID];

That results in a query failed error message:

 

MALFORMED_QUERY: Field must be grouped or aggregated: Id

I get why an aggregate query won't allow me to return the Opportunity ID, given that I could have several aggregate functions like AVG() and MIN() in the same query, each returning a value that corresponds to a different Opportunity ID.  But, I don't know what else to do.  

 

What is the correct way to populate the AccountID-OppID relationship map that I need in this scenario?

Short version:  I'm trying to create/maintain a date field on my Campaigns that will indicate the close date of the most recently won opportunity related to that campaign.  Any suggestions?

 

Full version:  I'd like to create a widget for a dashboard that shows a number of Campaign statistics for every campaign that has had at least one opportunity won in relation to that campaign in a given time period.  In order to do this in a Campaigns report, I think I need a Date Last Opp Won field.  I've tried creating it as a MAX roll-up summary field, but Opportunities are not available in Campaign roll-up summaries.  I've also tried creating a workflow rule that would fire when the Num Opps Won changes, but then discovered that while roll-up summary fields in general can trigger workflow rules, the built-in campaign Num Opps Won roll-up summary field cannot.  I also tried making an Opportunity workflow rule that would update it's related Campaign on Close/Won, but that isn't possible

 

I'm out of ideas, short of writing an Opportunity Trigger that fires on Close/Won.  Before I mess with that, wanted to see if I'm missing something obvious. 

I have a VF page that uses a standard controller.  Now, I have to turn it into a custom component in order to be able to use it in a VF email template.  Since custom components cannot use standard controllers, does that mean that I have to write a custom controller that does everything the standard controller was already doing for me?  Or, can I extend the standard controller somehow using the apex:component tag?  (All the examples of controller extensions I see are related to pages that use the extensions parameter.  I haven't seen any related to a component, other than this thread that ended unsolved.)  

In particular, I'd *really* like to not have to recreate the handling of opportunity line items that comes for free with the Opportunity standard controller.

I have noticed that when I use a custom button to call a visualforce page that does some work via a custom controller class before returning the user to the original page (the one on which they clicked the button), that I end up with an accumulation of development mode footers.  See screenshot here  Do I need to do something special when the pageref is returned at the end of my custom controller work such that the development mode footer closes?

 

In the screenshot linked above, I've navigated to four different Opportunities and clicked my custom button, thus resulting in 4 development mode footers all piled up.  It doesn't seem to matter what I go on to do after I click the custom button, the development footer doesn't go away.  The only way that I've found to get rid of the footers when so many have accumulated that it's bothersome is to close the tab completely and start with a fresh tab.  Something tells me there has to be a better way.

I would like to create a validation rule that fires if a formula field on our Opportunities has a certain value.  I already have the formula field, which is useful for other things besides this validation function.  So, I'd like it if I could just write a validation rule that checks the value of the formula field, but I'm not sure if it is *always* the case that on save the formula field would get updated *before* the validation rule runs. 

 

I realize I can copy the part of the formula field's logic that is relevant to the validation rule into the validation rule's formula, but if I can avoid duplicating logic that then has to be maintained separately, I'd like to do that.

SHORT PROBLEM STATEMENT:  If someone has good guidance for the best way to go about splitting the below pdf-rendered visualforce page into a component(s) that will render identically when included in an Apex Page AND when pulled into a VF email template, I would be most grateful!  Obviously, my goal is to use (as much as possible) the same VF code and Apex controller code for the PDF both when it is rendered as an email attachment and when it is rendered from a VF page in a browser.

 

MORE DETAILS:

I created a Visualforce page (pasted below) to produce PDF invoices for our Opportunities.  I created a custom link to it so our staff can generate a PDF invoice for any given Opportunity with a click of their mouse.  It works beautifully.  Then, I wanted to attach the VisualForce page to VisualForce email templates we use for automating our renewal invoicing.  From the documentation, it appears that I have to convert it from a Page it into a Component in order to do that.  So, I tried turning it into a component that can be reference both by the Visualforce page that my custom link calls AND that can be pulled into my Visualforce email templates within <messaging:attachment> tag.  Sounds simple, right? 

 

Unfortunately, I'm pulling my hair out right now because my VF page uses the standard Opportunity controller, which I extended - whereas components cannot use standard controllers at all!  Does that mean I have to write a controller now that mimics everything that my VF page gets from the Opportunity controller?  Is there any easy way to create a controller that mimics everything a standard controller does? 

 

Obviously, my goal is to use (as much as possible) the same VF code and Apex controller code for both the PDF rendered as an email attachment and the PDF when rendered from a browser.  If someone has general guidance for the best way to go about splitting the below pdf-rendered visualforce page into a component(s) that will render identically when included in an Apex Page AND when pulled into a VF email template, I would be most grateful!  

 

BTW - you may notice that my styles include data from the controller.  That's because putting data in a PDF header or footer requires putting it in the "content" attributes of the @page styles.  This has proven to be a problem in my experiments with componentizing this page.  Advice on how to handle the styles, given that they need access to Opportunity data, would be a big help, too.

 

THANK YOU ALL IN ADVANCE!!!!!!!

 

<apex:page standardController="Opportunity" showHeader="FALSE" standardStylesheets="false" renderas="pdf">
<head>
<style type="text/css">
@page{
    size: letter;
    margin: 10%;
    @top-center {
        content: "Invoice Date: {!MONTH(TODAY())}/{!DAY(TODAY())}/{!YEAR(TODAY())}";
            font-family: Helvetica, Arial, sans-serif;
            font-size: 12px;
            font-weight: bolder;
    }
    @top-right {
        content: "Invoice #: {!opportunity.ID_for_invoices__c}";
        font-family: Helvetica, Arial, sans-serif;
        font-size: 12px;
        font-weight: bolder;
    }
    @top-left {
        content: "INVOICE";
        font-family: Helvetica, Arial, sans-serif;
        font-size: 12px;
        font-weight: bolder;
    }
    @bottom-left {
        content: "";
        font-family: Helvetica, Arial, sans-serif;
        font-size: 10px;
    }
    @bottom-right {
        content: "Page " counter(page) " of " counter(pages);
        font-family: Helvetica, Arial, sans-serif;
        font-size: 10px;
    }
}
body {
    font-family: Helvetica, Arial, sans-serif;
    font-size: 11px;
}
table {
    font-family: Helvetica, Arial, sans-serif;  
}
td {
    border: 1px solid #000000;  
}
.tablelabel {
    background: #000000;
    color: #FFFFFF;
    padding: 5px;
    font-weight: bolder;
}
.tableheader {
    font-weight: bolder;
}
.invisiblecell {
    border-left: 0;
    border-bottom: 0;
    border-top: 0;
}
span#warningtext{
    font-size: 80%;
    background: #FFF000;
    float: left;
    padding: 3px;
    margin-right: 8px;
    width: 90px;
    align: middle;
    text-align: right;
}

</style>
</head>

<p><strong>Billed To:</strong></p>
<p>{!opportunity.Account.Name}<br/>
<apex:outputText value="{! IF(ISBLANK(opportunity.Account.BillingStreet),"", opportunity.Account.BillingStreet &"<br/>")}" escape="false"/>
{!opportunity.Account.BillingCity}, {!opportunity.Account.BillingState} {!opportunity.Account.BillingPostalCode}<br/>
{!opportunity.Account.BillingCountry}
</p>

<!-- OUTPUT INVOICE COMMENT, IF ANY  -->
<apex:outputpanel rendered="{! NOT(ISBLANK(opportunity.invoice_comment__c))}">
<p><strong>Comment:</strong> {!opportunity.Invoice_Comment__c}</p>
</apex:outputpanel>

<!-- OUTPUT PROMOTION DESCRIPTION, IF PROMOTION APPLIED -->
<apex:outputpanel rendered="{! NOT(ISBLANK(opportunity.promotion_code__c))}">
<p><strong>Promotion:</strong> {!opportunity.Promotion_Code__c}</p>
</apex:outputpanel>

<!-- OUTPUT ORDERED ITEMS TABLE -->
<table class="tables" cellpadding="6" cellspacing="0" width="100%">
<tr><td colspan="5" class="tablelabel">Order</td></tr>
<tr class="tableheader"><td>Item Description</td><td align="right">List Price</td><td align="right">Sale Price</td><td align="center">Quantity</td><td align="right">Amount</td></tr>
<tr>
</tr>

<apex:repeat var="lineitem" value="{!opportunity.OpportunityLineItems}">
<tr>
<td align="left" width="50%">{!lineitem.PricebookEntry.Product2.Name}</td>
<td align="right"><apex:outputfield value="{!lineitem.ListPrice}" /></td>
<td align="right"><apex:outputfield value="{!lineitem.UnitPrice}" /></td>
<td align="center">{!lineitem.Quantity}</td>
<td align="right"><apex:outputfield value="{!lineitem.TotalPrice}" /></td>
</tr>
</apex:repeat>
<tr><td class="invisiblecell"></td><td colspan="3" class="tablelabel">Order Total</td><td class="tablelabel" align="right"><apex:outputfield value="{!opportunity.Amount}" /></td></tr>
</table>

<p>&nbsp;</p>
<p><strong>To Pay by Credit Card</strong><br/>
We are available to take credit card payments over the phone between 8am and 5pm ET at XXX-XXX-XXXX.</p>

<p>
<strong>To Pay by Check</strong> <br/>
Make checks payable to “XXXXX”, include a memo that the amount is for "XXXXX" and mail to:</p>


<p><span id="warningtext">Please note our<br />new address<br />for payments</span>AASHE<br />
PO Box XXXXXXX<br />
Philadelphia, PA XXXXXX 
</p>

<p><strong><em>Thank you!</em></strong>
</p>

</apex:page>

 

I'm using the online Visualforce documentation to try to learn how to render a visualforce component as a PDF attachment on a visualforce email.  But, when I try creating a component exactly like the one in the documentation I get an error.  Am I missing something or is there a mistake in the documentation??

 

Here's the code I can't get to work (gray box below).  When I copy and paste it into a new visualforce component, it won't save and gives me this error message: Error: Unknown property 'account'

 

Defining a Custom Component as an Attachment

By creating a custom component and using it on the Visualforce email form and to render the PDF for the email, users can see a preview of the content they are trying to send.

The following markup defines a custom component namedattachmentthat represents the attachment for the email:
<apex:component access="global">
  <h1>Account Details</h1>
  
  <apex:panelGrid columns="2">

      <apex:outputLabel for="Name" value="Name"/>
      <apex:outputText id="Name" value="{!account.Name}"/>
      
      <apex:outputLabel for="Owner" value="Account Owner"/>
      <apex:outputText id="Owner" value="{!account.Owner.Name}"/>
      
      <apex:outputLabel for="AnnualRevenue" value="Annual Revenue"/>
      <apex:outputText id="AnnualRevenue" value="{0,number,currency}">
          <apex:param value="{!account.AnnualRevenue}"/>
      </apex:outputText>
      
      <apex:outputLabel for="NumberOfEmployees" value="Employees"/>
      <apex:outputText id="NumberOfEmployees" value="{!account.NumberOfEmployees}"/>
      
  </apex:panelGrid>
</apex:component>
Replace yourattachmentPDFpage like this:

I have a need that I think is pretty common.  I'm handed a big contact list and told to load them into a Campaign - but to leave out anyone that is associated with an Account that is already a customer.  So, I use PeopleImport to carefully load the Contacts (all as Contacts) and assign the updated/inserted Contacts to a Campaign.  Then, I go looking for some way to see which, if any, of the Contacts in the Campaign are related to customer Accounts.  It seems like it should be pretty simple, but a custom report that went Campaign >> Contact >> Account didn't work (the Account fields were available in the report editor but when I run the report they are all blank).  I've tried a couple other things, but simply haven't been able to figure out a way to do a simple pairing of Campaign Members (all Contacts) with details from their Account records. 

 

Please help!  Thanks so much!

We use Google Apps for our mail server.  I have a support address that forwards to a SF email-to-case address.  Recently, we've gotten several strange rejections.  When Google reports the delivery failure it says it is getting a 582 error message from SF saying that "This message violates our email policy."  Any idea what is going on?  The sender's email looks pretty innocuous.

 

---------- Forwarded message ----------
From: Mail Delivery Subsystem <mailer-daemon@googlemail.com>
Date: Thu, Feb 10, 2011 at 12:05 PM
Subject: Delivery Status Notification (Failure)
To: person@ourdomain.org


Delivery to the following recipient failed permanently:

support@ourdomain.org

Technical details of permanent failure:
Google tried to deliver your message, but it was rejected by the recipient
domain. We recommend contacting the other email provider for further
information about the cause of this error. The error that the other server
returned was: 582 582 This message violates our email policy. (state 18).

I'm trying to use a formula to see if an email address contained in one field is contained in a serialized list of email addresses contained in another field.  The problem I'm running into is that using CONTAINS() results in false matches when the search email address is found within a part of a whole email address in the list.  E.g. guy@hotmail.com is found to be "contained" in the serialized list when awesomeguy@hotmail.com is in the list.  I thought maybe I could use a REGEX to limit the match to the whole email address (guy@hotmail.com) surrounded by white space or a comma but couldn't figure out how to do that.

 

Right now my formula is:

CONTAINS( Obsolete_Emails__c , Email )

 

Any advice?  I suppose I could do what I'm trying to do with a trigger, but I'm so close to having it working this way.  Thanks for your help.

I'm about to pull my hair out, so would really appreciate it if someone could help me see the simple mistake I must be making here.  I have a trigger that works perfectly when I perform manually the same steps I have written into the unit test.  I thought maybe it was that my trigger is a before update trigger, so I added some extraneous updates after the update in this test, but that didn't help.  And, when I do the updates manually exactly as in this unit test, it works, without extraneous follow-on updates.

 

Here's the trigger:

 

 

trigger searchZipCode on Account (before update) {

    // For each Account in the Trigger.new list of Accounts
    for (Account a : Trigger.new) {
        // check if the BillingPostalCode field is contained in the list of zips
        try {
            if (a.BillingPostalCode != NULL){
                if (a.ZipSearchList__c.contains(a.BillingPostalCode.substring(0,5)))
                {
                    a.ZipFound__c = TRUE;
                } else a.ZipFound__c = FALSE;
            }
        } catch (System.NullPointerException e) {
            system.debug(e.getMessage());
            a.ZipFound__c = FALSE;        
        } finally {
            // do nothing     
        }           
 }
}

 

 

 

Here's the unit test:

 

 

@isTest
private class searchZipCodeTest {

    static testMethod void testsearchZipCode() {
        String ziplist = '12345, 67890';
        String successZip = '12345';
        String failZip = '66666';
        
        Account successAccount = new Account(
            Name = 'Success University',
            // RecordType = '012A00000004OUY',
            Type = 'Graduate Institution',
            BillingPostalCode = successZip,
            ZipFound__c = FALSE
        );
        
        Account failAccount = new Account(
            Name= 'Fail University',
            // RecordType = '012A00000004OUY',
            Type = 'Graduate Institution',
            BillingPostalCode = failZip,
            ZipFound__c = FALSE
         );
        insert new Account[] { successAccount, failAccount };
 
        successAccount.ZipSearchList__c = ziplist;
        failAccount.ZipSearchList__c = ziplist;
        update successAccount;
        update failAccount;
        
        Test.StartTest();
        System.assertEquals('12345', successAccount.BillingPostalCode);
        System.assertEquals('12345, 67890', successAccount.ZipSearchList__c);
// This is the assert that fails:
System.assertEquals(TRUE, successAccount.ZipFound__c); System.assertEquals(FALSE, failAccount.ZipFound__c); Test.StopTest(); } }

 

 

 

Here's the error message:

 

It appears that I have code that works perfectly in both a production and a sandbox environment, but does not work when called from a unit test that performs the same operations that work just fine using the GUI.

 

I've modified the CampaignCallDownController to have filters and a search box.  The below test adds one Contact and one Lead to a Campaign, then invokes the CampaignCallDown VF page and controller.  When I do those steps using the GUI in production or the sandbox, the call list shows two records, one Contact and one Lead.  But when I run this unit test, it says there are zero records in the call list.  I've tracked the problem down to this query in the CampaignCallDownController...

 

members = [select Id, ContactId, LeadId, Status, CampaignId, Level_of_Interest__c, 

                    Last_Action__c, Next_Action__c, Campaign.Name,

                    Lead.Id, Lead.Salutation, Lead.Title, Lead.Name, Lead.Company, Lead.Phone, 

                    Lead.Street, Lead.State, Lead.Email,

                    Contact.ID, Contact.AccountId, Contact.Salutation, Contact.Title, Contact.Name

                    Contact.Phone, Contact.MailingState, Contact.Email, Contact.Account.name

                    from CampaignMember where CampaignId = :camp AND Next_Action__c LIKE :desiredNA AND 

                    (NOT Next_Action__c LIKE :excludedNA) AND Level_of_Interest__c LIKE :desiredLI AND 

                    (NOT Level_of_Interest__c LIKE :excludedLI) AND

                    (Contact.Account.Name LIKE :searchFilter OR Contact.Name LIKE :searchFilter

ORContact.Email LIKE :searchFilter 

                    OR Contact.Title LIKE :searchFilter OR Contact.MailingState LIKE :searchFilter OR 

                    Lead.Name LIKE :searchFilter OR Lead.Company LIKE :searchFilter  OR 

                    Lead.Email LIKE :searchFilter OR Lead.Title LIKE :searchFilter OR Lead.State LIKE :searchFilter

                    ORDER BY Contact.Account.name LIMIT :recordsPerPage OFFSET :offset ];

 

I've highlighted the part of the query that performs the search function because that's where the problem is.  When that query gets called from the GUI, it will return all Leads *and* Contacts that match the searchFilter criteria.  But when called from the test, it will only return an empty list, not matter what search or filter criteria are input.  I've stripped the query criteria down to just the red and blue parts and found that if I remove one or the other (the Contact field matching or the Lead field matching criteria) it will return records when called from the below test.  In other words, if I remove the red part it will return 1 Lead in the test below.  Or, if I leave in the red part and remove the blue part, it will return 1 Contact in the test below.  But, if I leave both in, it will return zero leads and zero contacts.  When the same operations are performed in the GUI, it returns two records - both the Lead and the Contact.

 

Anybody know what's going  on?  Have I hit a bug in the way tests are executed by SFDC?  I'm about to pull my hair out - or write a unit test that is really a non-test!! :(

 

 

@isTest
private class CampaignCallDownControllerTest {

     static testMethod void testNormalFlow(){
     	
     	//get campaign member record type ID
     	RecordType rt = [select id,Name from RecordType where SobjectType='CampaignMember' and Name='Email Campaign Member' Limit 1];
     	
        //campaign
        Campaign testCampaign       = new Campaign();
        testCampaign.name           = 'TestCampaign';
        testCampaign.CampaignMemberRecordTypeId = rt.ID;
        insert testCampaign;
        
        Account testAccount		= new Account();
        testAccount.name		= 'TestAccount';
        insert testAccount;  
                
        //Lead
        Lead testLead1          = new Lead();
        testLead1.FirstName     = 'LeadFirstName1';
        testLead1.LastName      = 'LeadLastName1';
        testLead1.Company       = 'Test1';
        insert testLead1;
        
        //Contact
        Contact testContact1         = new Contact();
        testContact1.FirstName       = 'ContactFirstName';
        testContact1.LastName        ='ContactLastName';
        testContact1.Email           = 'Adress1@Adress.com';
        testContact1.Title           = 'ContactTitle';
        testContact1.AccountID 		 = testAccount.ID;
        insert testContact1;
        
        //make campaign members
        CampaignMember testCM1       = new CampaignMember();
        testCM1.leadID               = testLead1.Id;
        testCM1.contactID			 = null;
        testCM1.campaignID           = testCampaign.Id;
        testCM1.Status               = 'Sent';
        testCM1.Level_of_Interest__c = 'Interested';
        testCM1.Next_Action__c 		 = 'contact now';
        insert testCM1;
        
        CampaignMember testCM3      = new CampaignMember();
        testCM3.ContactId           = testContact1.Id;
        testCM3.LeadID			 	= null;
        testCM3.CampaignId          = testCampaign.Id;
        testCM3.Status              = 'Sent';
        testCM3.Level_of_Interest__c= 'Interested';        
        testCM3.Next_Action__c 		= 'contact now';
        insert testCM3;
        
		// Check to make sure the contacts and leads made it into the campaign        
        testCampaign = [SELECT ID, NumberofContacts, NumberOfLeads FROM Campaign WHERE ID = :testCampaign.ID];       
        System.assertEquals(1,testCampaign.NumberofContacts);
        System.assertEquals(1,testCampaign.NumberofLeads);
                
        //begin tests
 		// instantiate page
 		PageReference pageRef = Page.CampaignCallDown;
 		Test.setCurrentPage(pageRef);
 		ApexPages.currentPage().getParameters().put('camp',testCampaign.Id);

        CampaignCallDownController ccdc1 = new CampaignCallDownController();
	System.assert(ccdc1.getHasCampaignID() == TRUE);
	System.assertequals(2, ccdc1.getLeadPlusTasks().size()); // FAILS HERE
		 		
 	}

 

I want to concatenate two object IDs in order to make a hash value for a map, but this doesn't work:

 

conversionMap.put(entry.Pricebook2Id + entry.Product2Id), entry);

If I could convert the IDs to strings first, then I should be able to concatenate them in this way.  But, while there is a function to convert a string to an ID, I can't find any way to convert an ID to a string.  Anybody know how to do that?  Or, a better way to do what I'm trying to do?

 

I'm working with a VF page and Apex controller and I want to be able to do SOQL queries that are limited to 200 results but that start the results at different places in the total query results.  In other words have queries that would get me the first 200 results, the second 200 results and so on...  BUT, I want to be able to jump around so that the user could jump straight from the 1st page of results (records 1-200) to the 5th page of results (query for results 1,000 to 1,200).  Is that possible?  I cannot query *all* the records and then just return 200 to the page at a time because the query returns too much data.  So, I'd want to run the query again each time but getting a specific subset.   Kind of like a row limit but starting at a certain record count.  

 

Totally crazy?

I deployed a class *successfully* on 1/14/2012.  Seven days later, I discovered that when I try to deploy anything at all, even a class that only has whitespace changes, the deployment fails with the message that the test for the class that I deployed successfully on 1/14 has "Too many script statements: 200001".  How can that be?  How can it have passed the test successfully while deploy successfully 10 days ago and now I can't deploy anything because it is failing, when I haven't changed it in any way?!

The worst part is that aside from keeping me from being able to deploy anything, which I discovered on Friday, one of my users discovered yesterday that using the button that calls this class is now resulting in the "Too many script statements: 200001" error message.  So, I now do have business processes being interrupted.  Which is really, really strange because right after I *successfully* deployed that class on 1/14, I used that button to *successfully* process far more records (180) than my users are processing when they use it (1-2).  

 

Anybody have any idea what could have changed between when it was deploying and working fine and now?  I'm totally at a loss to explain what could have changed.  I have all the info about how to deal with this error, in general, such as using @future and reducing for loops, but I want to know how the code could have become broken *after* deploying successfully and running correctly under much greater stress than it is failing under now.  That is the most disconcerting thing to me.

Thanks for any clues!

 

For over a year now, my org has been generating and sending invoices and receipts using VF Components that are rendered as PDFs and attached to VF Email Templates.  The invoices and receipts each use CSS styles defined within a <style> tag in the header.  I just discovered that after the Summer '12 release, those styles are no longer being rendered.  As a result, the CSS style definitions are being printed at the top of the PDFs and the invoices and receipts have no styling.

 

Is anyone else having this problem?  I'm on na7.  I don't see it in the Known Issues but have submitted a support case.

 

I'm going to try moving the style definitions into a CSS stylesheet, loading that as a static resource and then referencing it with the <apex:stylesheet> tag.  Hopefully, that will work.  If not, I'm not sure what to try next.

 

So far, I've only been able to figure out how to generate PDF email attachments that my users can send from an object by embedding the Visualforce code for the PDF within the <messaging:attachment> tag for a Visualforce Email Template.  The downside to this is that the message body of the email is not editable by the user.  This means my generated attachments always get sent with the same impersonal boilerplate message body.

 

I didn't know it was possible to do any better until I got my AppExchange newsletter today and saw the demo of Steel Brick's QuoteQuickly app.  I was surprised to see at the 1:30 mark of the video's second part that they claim they are using Force.com's built-in Send Email functionality to send quotes - and then they show the Send Email form load with an editable message body AND with their generated PDF already attached.  

 

How are they doing that?  Anybody know or have a guess?  

 

Unfortunately, QuoteQuickly doesn't meet my needs, so I need to figure out how to replicate that functionality.

 

Much thanks in advance for any assistance!

For each Account, I need to know the ID of the Opportunity related to it that has the newest renewal date.  I was thinking that I could query Opportunity records for their ID with a GROUP BY on AccountID and a MAX(Renewal_Date__c), like this:

 

AggregateResult[] groupedResults
= [SELECT ID, AccountID, MAX(Renewal_Date__c)
FROM Opportunity
WHERE AccountID in :acctIDs AND RecordTypeID = '012A0000000qpET'
GROUP BY AccountID];

That results in a query failed error message:

 

MALFORMED_QUERY: Field must be grouped or aggregated: Id

I get why an aggregate query won't allow me to return the Opportunity ID, given that I could have several aggregate functions like AVG() and MIN() in the same query, each returning a value that corresponds to a different Opportunity ID.  But, I don't know what else to do.  

 

What is the correct way to populate the AccountID-OppID relationship map that I need in this scenario?

I have noticed that when I use a custom button to call a visualforce page that does some work via a custom controller class before returning the user to the original page (the one on which they clicked the button), that I end up with an accumulation of development mode footers.  See screenshot here  Do I need to do something special when the pageref is returned at the end of my custom controller work such that the development mode footer closes?

 

In the screenshot linked above, I've navigated to four different Opportunities and clicked my custom button, thus resulting in 4 development mode footers all piled up.  It doesn't seem to matter what I go on to do after I click the custom button, the development footer doesn't go away.  The only way that I've found to get rid of the footers when so many have accumulated that it's bothersome is to close the tab completely and start with a fresh tab.  Something tells me there has to be a better way.

SHORT PROBLEM STATEMENT:  If someone has good guidance for the best way to go about splitting the below pdf-rendered visualforce page into a component(s) that will render identically when included in an Apex Page AND when pulled into a VF email template, I would be most grateful!  Obviously, my goal is to use (as much as possible) the same VF code and Apex controller code for the PDF both when it is rendered as an email attachment and when it is rendered from a VF page in a browser.

 

MORE DETAILS:

I created a Visualforce page (pasted below) to produce PDF invoices for our Opportunities.  I created a custom link to it so our staff can generate a PDF invoice for any given Opportunity with a click of their mouse.  It works beautifully.  Then, I wanted to attach the VisualForce page to VisualForce email templates we use for automating our renewal invoicing.  From the documentation, it appears that I have to convert it from a Page it into a Component in order to do that.  So, I tried turning it into a component that can be reference both by the Visualforce page that my custom link calls AND that can be pulled into my Visualforce email templates within <messaging:attachment> tag.  Sounds simple, right? 

 

Unfortunately, I'm pulling my hair out right now because my VF page uses the standard Opportunity controller, which I extended - whereas components cannot use standard controllers at all!  Does that mean I have to write a controller now that mimics everything that my VF page gets from the Opportunity controller?  Is there any easy way to create a controller that mimics everything a standard controller does? 

 

Obviously, my goal is to use (as much as possible) the same VF code and Apex controller code for both the PDF rendered as an email attachment and the PDF when rendered from a browser.  If someone has general guidance for the best way to go about splitting the below pdf-rendered visualforce page into a component(s) that will render identically when included in an Apex Page AND when pulled into a VF email template, I would be most grateful!  

 

BTW - you may notice that my styles include data from the controller.  That's because putting data in a PDF header or footer requires putting it in the "content" attributes of the @page styles.  This has proven to be a problem in my experiments with componentizing this page.  Advice on how to handle the styles, given that they need access to Opportunity data, would be a big help, too.

 

THANK YOU ALL IN ADVANCE!!!!!!!

 

<apex:page standardController="Opportunity" showHeader="FALSE" standardStylesheets="false" renderas="pdf">
<head>
<style type="text/css">
@page{
    size: letter;
    margin: 10%;
    @top-center {
        content: "Invoice Date: {!MONTH(TODAY())}/{!DAY(TODAY())}/{!YEAR(TODAY())}";
            font-family: Helvetica, Arial, sans-serif;
            font-size: 12px;
            font-weight: bolder;
    }
    @top-right {
        content: "Invoice #: {!opportunity.ID_for_invoices__c}";
        font-family: Helvetica, Arial, sans-serif;
        font-size: 12px;
        font-weight: bolder;
    }
    @top-left {
        content: "INVOICE";
        font-family: Helvetica, Arial, sans-serif;
        font-size: 12px;
        font-weight: bolder;
    }
    @bottom-left {
        content: "";
        font-family: Helvetica, Arial, sans-serif;
        font-size: 10px;
    }
    @bottom-right {
        content: "Page " counter(page) " of " counter(pages);
        font-family: Helvetica, Arial, sans-serif;
        font-size: 10px;
    }
}
body {
    font-family: Helvetica, Arial, sans-serif;
    font-size: 11px;
}
table {
    font-family: Helvetica, Arial, sans-serif;  
}
td {
    border: 1px solid #000000;  
}
.tablelabel {
    background: #000000;
    color: #FFFFFF;
    padding: 5px;
    font-weight: bolder;
}
.tableheader {
    font-weight: bolder;
}
.invisiblecell {
    border-left: 0;
    border-bottom: 0;
    border-top: 0;
}
span#warningtext{
    font-size: 80%;
    background: #FFF000;
    float: left;
    padding: 3px;
    margin-right: 8px;
    width: 90px;
    align: middle;
    text-align: right;
}

</style>
</head>

<p><strong>Billed To:</strong></p>
<p>{!opportunity.Account.Name}<br/>
<apex:outputText value="{! IF(ISBLANK(opportunity.Account.BillingStreet),"", opportunity.Account.BillingStreet &"<br/>")}" escape="false"/>
{!opportunity.Account.BillingCity}, {!opportunity.Account.BillingState} {!opportunity.Account.BillingPostalCode}<br/>
{!opportunity.Account.BillingCountry}
</p>

<!-- OUTPUT INVOICE COMMENT, IF ANY  -->
<apex:outputpanel rendered="{! NOT(ISBLANK(opportunity.invoice_comment__c))}">
<p><strong>Comment:</strong> {!opportunity.Invoice_Comment__c}</p>
</apex:outputpanel>

<!-- OUTPUT PROMOTION DESCRIPTION, IF PROMOTION APPLIED -->
<apex:outputpanel rendered="{! NOT(ISBLANK(opportunity.promotion_code__c))}">
<p><strong>Promotion:</strong> {!opportunity.Promotion_Code__c}</p>
</apex:outputpanel>

<!-- OUTPUT ORDERED ITEMS TABLE -->
<table class="tables" cellpadding="6" cellspacing="0" width="100%">
<tr><td colspan="5" class="tablelabel">Order</td></tr>
<tr class="tableheader"><td>Item Description</td><td align="right">List Price</td><td align="right">Sale Price</td><td align="center">Quantity</td><td align="right">Amount</td></tr>
<tr>
</tr>

<apex:repeat var="lineitem" value="{!opportunity.OpportunityLineItems}">
<tr>
<td align="left" width="50%">{!lineitem.PricebookEntry.Product2.Name}</td>
<td align="right"><apex:outputfield value="{!lineitem.ListPrice}" /></td>
<td align="right"><apex:outputfield value="{!lineitem.UnitPrice}" /></td>
<td align="center">{!lineitem.Quantity}</td>
<td align="right"><apex:outputfield value="{!lineitem.TotalPrice}" /></td>
</tr>
</apex:repeat>
<tr><td class="invisiblecell"></td><td colspan="3" class="tablelabel">Order Total</td><td class="tablelabel" align="right"><apex:outputfield value="{!opportunity.Amount}" /></td></tr>
</table>

<p>&nbsp;</p>
<p><strong>To Pay by Credit Card</strong><br/>
We are available to take credit card payments over the phone between 8am and 5pm ET at XXX-XXX-XXXX.</p>

<p>
<strong>To Pay by Check</strong> <br/>
Make checks payable to “XXXXX”, include a memo that the amount is for "XXXXX" and mail to:</p>


<p><span id="warningtext">Please note our<br />new address<br />for payments</span>AASHE<br />
PO Box XXXXXXX<br />
Philadelphia, PA XXXXXX 
</p>

<p><strong><em>Thank you!</em></strong>
</p>

</apex:page>

 

I'm using the online Visualforce documentation to try to learn how to render a visualforce component as a PDF attachment on a visualforce email.  But, when I try creating a component exactly like the one in the documentation I get an error.  Am I missing something or is there a mistake in the documentation??

 

Here's the code I can't get to work (gray box below).  When I copy and paste it into a new visualforce component, it won't save and gives me this error message: Error: Unknown property 'account'

 

Defining a Custom Component as an Attachment

By creating a custom component and using it on the Visualforce email form and to render the PDF for the email, users can see a preview of the content they are trying to send.

The following markup defines a custom component namedattachmentthat represents the attachment for the email:
<apex:component access="global">
  <h1>Account Details</h1>
  
  <apex:panelGrid columns="2">

      <apex:outputLabel for="Name" value="Name"/>
      <apex:outputText id="Name" value="{!account.Name}"/>
      
      <apex:outputLabel for="Owner" value="Account Owner"/>
      <apex:outputText id="Owner" value="{!account.Owner.Name}"/>
      
      <apex:outputLabel for="AnnualRevenue" value="Annual Revenue"/>
      <apex:outputText id="AnnualRevenue" value="{0,number,currency}">
          <apex:param value="{!account.AnnualRevenue}"/>
      </apex:outputText>
      
      <apex:outputLabel for="NumberOfEmployees" value="Employees"/>
      <apex:outputText id="NumberOfEmployees" value="{!account.NumberOfEmployees}"/>
      
  </apex:panelGrid>
</apex:component>
Replace yourattachmentPDFpage like this:

I have a visualforce pdf page that list outs the order (custom object) details.

I am getting this error while loading the pdf page.

 

UNABLE_TO_LOCK_ROW, unable to obtain exclusive access to this record: []

 

the code is performing an update to this object every time, but there is no other trigger on this object.

can't figure out the reason for this error

 

Also, the error comes only in the production environment not in the sandbox.

 

Please help.

Hello. I want to use the Description field in the CampaignMember object for user data entry. However, when I place it on a page layout, it's automatically set to read-only and I can't change it. Is there a way around this? What's the reason for this field to be read-only?