• SFDCMatt
  • NEWBIE
  • 35 Points
  • Member since 2011
  • Sr. Manager, Sales Systems & Tools
  • Rackspace


  • Chatter
    Feed
  • 1
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 4
    Questions
  • 19
    Replies

I have a custom object called Demo Booking (DB).

I have another custom object as a related list called Demo Booking Object (DBO).

 

DBO is related to DB and to another table called Demo Object (DO). Demo objects are items that we use in our demo. They have a type and a minutes.

 

For clarity:

DBs are the BOOKINGS. DO are the OBJECTS and DBOs are the link between the two (like Opportunities, Products and Opportuntiy Products)

 

The user has to create a new Booking (DB). Once they have done that they have to select the Objects (DO) using the DBO related list. This uses the standard SFDC "Search" then "Save and New" method. The issue is that most Sales people do not really know these objects and searching for them is clunky.

 

I created a new visulaforce page on top of the DO object which displays the Objects along with their name and a checkbox.

 

The idea being that they open the new page from their new Booking and can just check the box next to the items to associate Booking#1 with Objects #1,2,3,5,6,9.

 

Finally: DBO rolls up the selected DOs' minutes to give us an approximate time for the demo.

 

If I go to the apex page this display correctly.

 

 

public class DemoObjectsShowAll{
     
        //Collection of the class/wrapper objects cObject
        public List<cObjects> objectList {get; set;}
     
        //This method uses a simple SOQL query to return a List of Objects
        public List<cObjects> getAllDemoObjects() {
            if(objectList == null) {
                objectList = new List<cObjects>();
                for(SE_Demo_Objects__c d :    [SELECT Name, Minutes_for_Demo__c, Product_Type__c FROM SE_Demo_Objects__c LIMIT 50]) {
                    // As each object is processed we create a new demo object and add it to the ObjectList
                    objectList.add(new cObjects(d));
                }
            }
            return objectList;
        }
     
     
        public PageReference processSelected() {
     
                    //We create a new list of Objects that we be populated only with Objects if they are selected
            List<SE_Demo_Objects__c> selectedObjects = new List<SE_Demo_Objects__c>();
     
            //We will cycle through our list of cObjects and will check to see if the selected property is set to true, if it is we add the Objects to the selectedObjects list
            for(cObjects cObj : getAllDemoObjects()) {
                if(cObj.selected == true) {
                    selectedObjects.add(cObj.Obj);
                }
            }
     
            // Now we have our list of selected objects
            System.debug('These are the selected Objects...');
            for(SE_Demo_Objects__c Obj : selectedObjects) {
                system.debug(Obj);
            }
            return null;
        }
     
     
        // This is our wrapper/container class. 
        public class cObjects {
            public SE_Demo_Objects__c Obj{get; set;}
            public Boolean selected {get; set;}
     
            //This is the contructor method. 
            public cObjects(SE_Demo_Objects__c d) {
                Obj = d;
                selected = false;
            }
        }
    }

 

<apex:page Controller="DemoObjectsShowAll" sidebar="false">
    <apex:form >
        <apex:pageBlock >
            <apex:pageMessages />
            <apex:pageBlockButtons >
                <apex:commandButton value="Add items to your Demo" action="{!processSelected}" rerender="table"/>
            </apex:pageBlockButtons>

            <apex:pageBlockTable value="{!allDemoObjects}" var="demo">

                <!-- This is our selected Boolean property in our wrapper class -->
                <apex:column >
                    <apex:inputCheckbox value="{!demo.selected}"/>
                </apex:column>
                <!-- This is how we access the values within our container/wrapper -->

                <apex:column value="{!demo.obj.name}"/>
                <apex:column value="{!demo.obj.Minutes_for_Demo__c}"/>
                <apex:column value="{!demo.obj.Product_Type__c}"/>
            </apex:pageBlockTable>      
        </apex:pageBlock>
    </apex:form>
</apex:page>

 

Now - I want to associate this with my related list and, of course, it doesn't associate because it is not a standard controller. How do I fix this?

 

The way I see it I have 2 issues:

#1 is that I need to write the the DBO rows from this page so I will need to associate them with the DB ID. (I have not done this as I wanted to do #2 first)

#2 This page needs to plug into the NEW button on the DBO related list on DB but it is related to DO.

 

 

I have an Apex REST service that up until today was fully functional. It's in two sandboxes, one on Spring '13, one on Summer '13 preview, and both are throwing the same error. Now when I send in a valid request, such as:

 

<request>
<FirstName>Matthew</FirstName>
</request>

I'm nearly immediately returned the following:

 

HTTP/1.1 400 Bad Request
Date: Mon, 20 May 2013 21:20:21 GMT
Content-Type: application/xml;charset=UTF-8
Transfer-Encoding: chunked


<?xml version="1.0" encoding="UTF-8"?>
<Errors>
    <Error>
        <errorCode>XML_PARSER_ERROR</errorCode>
        <message>Unexpected parameter encountered during deserialization: FirstName</message>
    </Error>
</Errors>

 

I've tried the same with JSON, and get a similar JSON_PARSER_ERROR with the same message, "Unexpected parameter encountered during deserialization"

 

Also took a look at a debug log and it only has a handful of lines.

 

27.0 APEX_CODE,DEBUG;APEX_PROFILING,INFO;CALLOUT,INFO;DB,INFO;SYSTEM,DEBUG;VALIDATION,INFO;VISUALFORCE,INFO;WORKFLOW,INFO
17:20:21.031 (31030000)|EXECUTION_STARTED
17:20:21.031 (31075000)|CODE_UNIT_STARTED|[EXTERNAL]|01pZ00000005X08|REST_AutoRenewalService_V1.doPost
17:20:21.035 (35960000)|CODE_UNIT_FINISHED|REST_AutoRenewalService_V1.doPost
17:20:21.035 (35978000)|EXECUTION_FINISHED

 

Has anyone seen this error before or have any idea how to fix it?

In reviewing the webinar here on Apex REST API:

 

http://www.youtube.com/watch?v=uSK06phNEp4

 

At 43:40, Sandeep mentions bulkifying the Apex REST classes to accept "a list of sObjects". Does anyone have any documentation on exactly whether or not this is supported in Apex REST services? All the sample code I can find for POST or PUT operate on requests with a single record. I've also seen several posts on StackExchange where people were struggling with this.

 

Is it available at the moment? Can I build a custom Apex REST service that takes in multiple new records in a POST and create those records in bulk?

Hi all - I'm in the middle of scoping the build for a Apex REST API service layer for one of my clients. One of their team members brought up an interesting point. They've asked about how they can monitor traffic and performance of the custom services, as well as watch for issues (like failed requests, long running responses, etc) in real time for proactive support. Overall traffic of the services across 5 clients is expected to be somewhere in the range of 10K to 30K requests per day.

 

First question, does Salesforce provide any such capabilities out of the box? My strong suspicion is no, but can't hurt to ask.

 

Second question, should this type of thing be built? I certainly think the request is well intentioned, but is the overhead for this type of thing going to be too expensive? Adding additional operations to the API itself will obviously decrease response time, even if a few milliseconds.

 

Third question, assuming this is not a terrible idea, how would you build this? My thoughts initially are:

 

  • Custom object to house records for individual requests
  • Each record contains data about each request / response, including which system submitted the request, response time, incoming request, outgoing response, etc
  • Within each RestResource method, at any catch point or right before the return, call a global "LogRESTActivity()" method to log the traffic
  • A scheduled batchable process that runs nightly to flush these records after some time (time determined by a custom setting)

This data structure would allow us to drive some pretty rich reports and dashboards to monitor performance in real time.

 

Curious if others have ever tackled this type of request, and how you handled it. Or if you have thoughts about the concept I outlined above.

Hi all - I've got a custom object for which there are two basic kinds of records, parents and children. There is a same-object Lookup field on that object that looks up to the object called Object_Self_Lookup__c. I want to use this to relate the children to the parents. 

 

The object also has an external Id called External_Id_Field__c.

 

I'm generating large batches of these records in a scheduled Apex class, and maintaining two different lists, one of parents, one of children. Each record, no matter the type, is assigned a unique value to External_Id_Field__c.

 

My goal is that I can insert the list of Parent records first, having set all their external ids, and then insert the list of children, and have the lookup to the parent record resolved by way of the external Id. I've like to avoid adding a trigger, or making a second pass to get the reference set if it's possible.

 

Is this possible? If so, what am I doing wrong here? This is simplified version of my full code, but this doesn't work either.

 

Thanks!

 

List<Custom_Object__c> parentList = new List<Custom_Object__c>();
List<Custom_Object__c> childList = new List<Custom_Object__c>();

Custom_Object__c objOne = new Custom_Object__c();
objOne.External_Id_Field__c = '1234';
parentList.add(objOne);

Custom_Object__c objTwo = new Custom_Object__c();
objTwo.Object_Self_Lookup__r = objOne;
childList.add(objTwo);

insert parentList;
insert childList;

 

I have a custom object called Demo Booking (DB).

I have another custom object as a related list called Demo Booking Object (DBO).

 

DBO is related to DB and to another table called Demo Object (DO). Demo objects are items that we use in our demo. They have a type and a minutes.

 

For clarity:

DBs are the BOOKINGS. DO are the OBJECTS and DBOs are the link between the two (like Opportunities, Products and Opportuntiy Products)

 

The user has to create a new Booking (DB). Once they have done that they have to select the Objects (DO) using the DBO related list. This uses the standard SFDC "Search" then "Save and New" method. The issue is that most Sales people do not really know these objects and searching for them is clunky.

 

I created a new visulaforce page on top of the DO object which displays the Objects along with their name and a checkbox.

 

The idea being that they open the new page from their new Booking and can just check the box next to the items to associate Booking#1 with Objects #1,2,3,5,6,9.

 

Finally: DBO rolls up the selected DOs' minutes to give us an approximate time for the demo.

 

If I go to the apex page this display correctly.

 

 

public class DemoObjectsShowAll{
     
        //Collection of the class/wrapper objects cObject
        public List<cObjects> objectList {get; set;}
     
        //This method uses a simple SOQL query to return a List of Objects
        public List<cObjects> getAllDemoObjects() {
            if(objectList == null) {
                objectList = new List<cObjects>();
                for(SE_Demo_Objects__c d :    [SELECT Name, Minutes_for_Demo__c, Product_Type__c FROM SE_Demo_Objects__c LIMIT 50]) {
                    // As each object is processed we create a new demo object and add it to the ObjectList
                    objectList.add(new cObjects(d));
                }
            }
            return objectList;
        }
     
     
        public PageReference processSelected() {
     
                    //We create a new list of Objects that we be populated only with Objects if they are selected
            List<SE_Demo_Objects__c> selectedObjects = new List<SE_Demo_Objects__c>();
     
            //We will cycle through our list of cObjects and will check to see if the selected property is set to true, if it is we add the Objects to the selectedObjects list
            for(cObjects cObj : getAllDemoObjects()) {
                if(cObj.selected == true) {
                    selectedObjects.add(cObj.Obj);
                }
            }
     
            // Now we have our list of selected objects
            System.debug('These are the selected Objects...');
            for(SE_Demo_Objects__c Obj : selectedObjects) {
                system.debug(Obj);
            }
            return null;
        }
     
     
        // This is our wrapper/container class. 
        public class cObjects {
            public SE_Demo_Objects__c Obj{get; set;}
            public Boolean selected {get; set;}
     
            //This is the contructor method. 
            public cObjects(SE_Demo_Objects__c d) {
                Obj = d;
                selected = false;
            }
        }
    }

 

<apex:page Controller="DemoObjectsShowAll" sidebar="false">
    <apex:form >
        <apex:pageBlock >
            <apex:pageMessages />
            <apex:pageBlockButtons >
                <apex:commandButton value="Add items to your Demo" action="{!processSelected}" rerender="table"/>
            </apex:pageBlockButtons>

            <apex:pageBlockTable value="{!allDemoObjects}" var="demo">

                <!-- This is our selected Boolean property in our wrapper class -->
                <apex:column >
                    <apex:inputCheckbox value="{!demo.selected}"/>
                </apex:column>
                <!-- This is how we access the values within our container/wrapper -->

                <apex:column value="{!demo.obj.name}"/>
                <apex:column value="{!demo.obj.Minutes_for_Demo__c}"/>
                <apex:column value="{!demo.obj.Product_Type__c}"/>
            </apex:pageBlockTable>      
        </apex:pageBlock>
    </apex:form>
</apex:page>

 

Now - I want to associate this with my related list and, of course, it doesn't associate because it is not a standard controller. How do I fix this?

 

The way I see it I have 2 issues:

#1 is that I need to write the the DBO rows from this page so I will need to associate them with the DB ID. (I have not done this as I wanted to do #2 first)

#2 This page needs to plug into the NEW button on the DBO related list on DB but it is related to DO.

 

 

I'm attempting to lookup existing case numbers for live agents if a customer provides a case number. I'm doing this in my code, but it doesn't appear to work. Is there something else I have to do? I've placed the code below and bolded the line where I believe this should be working?

 

<apex:page showHeader="false">
<!-- This script takes the endpoint URL parameter passed from the deployment page and makes
it the action for the form -->
<script type="text/javascript">
(function() { function handlePageLoad() {
var endpointMatcher = new RegExp("[\\?\\&]endpoint=([^&#]*)");
document.getElementById('prechatForm').setAttribute('action',
decodeURIComponent(endpointMatcher.exec(document.location.search)[1]));
} if (window.addEventListener) {
window.addEventListener('load', handlePageLoad, false);
} else { window.attachEvent('onload', handlePageLoad, false);
}})();
</script>

<h1>Pre-chat Form</h1>
<form method='post' id='prechatForm'>
    Last Name: <input type='text' name='liveagent.prechat.name' id='prechat_field' /><br />
    Email Address: <input type='text' name='liveagent.prechat:Email' /><br />
    Previous Case Number (if applicable): <input type='text' name='liveagent.prechat:CaseNumber' /><br />
    Product: <select name="liveagent.prechat.buttons">
        <option value="573C0000000Gmli">TestProduct</option>
    </select><br />

<!-- Creates an auto-query for a matching Contact record’s Email field based on the value of the liveagent.prechat:Email field -->
<input type="hidden" name="liveagent.prechat.query:Email" value="Contact,Contact.Email"/>
<input type="hidden" name="liveagent.prechat.query:CaseNumber" value="Case,Case.CaseNumber"/>
<input type="hidden" name="liveagent.prechat.save:Email" value="Email__c" />
<input type='submit' value='Request Chat' id='prechat_submit'/>
<style type="text/css"> p {font-weight: bolder } </style>
</form>
</apex:page>

 

I'm facing a problem trying to search for Content. We are basically trying to return search results using SOSL on the ContentVersion object. We're expecting full-text search results (words within the PDF or DOC), but results are returned only on ContentVersion.Title.

 

List<List<SObject>> contentresults1 = [FIND :SearchVal IN ALL FIELDS RETURNING ContentVersion (id, Title, Description)];

I am implementing a method that receives an authentication token from a user. Based on that token, how can I get the ID of the user that owns the token? The method is being called by an iPhone application. Here is the method declarartion:

 

@future(callout=true)
global static void getItems(String authToken)

 

 

Thanks

Hi all - I've got a custom object for which there are two basic kinds of records, parents and children. There is a same-object Lookup field on that object that looks up to the object called Object_Self_Lookup__c. I want to use this to relate the children to the parents. 

 

The object also has an external Id called External_Id_Field__c.

 

I'm generating large batches of these records in a scheduled Apex class, and maintaining two different lists, one of parents, one of children. Each record, no matter the type, is assigned a unique value to External_Id_Field__c.

 

My goal is that I can insert the list of Parent records first, having set all their external ids, and then insert the list of children, and have the lookup to the parent record resolved by way of the external Id. I've like to avoid adding a trigger, or making a second pass to get the reference set if it's possible.

 

Is this possible? If so, what am I doing wrong here? This is simplified version of my full code, but this doesn't work either.

 

Thanks!

 

List<Custom_Object__c> parentList = new List<Custom_Object__c>();
List<Custom_Object__c> childList = new List<Custom_Object__c>();

Custom_Object__c objOne = new Custom_Object__c();
objOne.External_Id_Field__c = '1234';
parentList.add(objOne);

Custom_Object__c objTwo = new Custom_Object__c();
objTwo.Object_Self_Lookup__r = objOne;
childList.add(objTwo);

insert parentList;
insert childList;

 

Looking to display a list of records within an unrelated object. We are making an employee review object, and would like to display all the accounts that user owns on the review object. We will be able to grab the user's ID on that review object - they aren't the owner, but are in a lookup field. I'm invisioning a bit of Visualforce, but I'm not sure how to get there. Any help is appreciated!

Salesforce announced PermissionSet feature in its recent release, and I'm loving it. 

 

The Winter ‘12 Salesforce release has introduced Permission Sets as a new way to manage security within the application. Each user continues to have a Profile, but Permission Sets can now be given to individual users to extend their permissions beyond what is described in their Profile. One of the current limitations is that there is no way to manage assignments of Permission Sets for more than one user at a time, which makes administration tedious.

 

So I'm trying to build visualforce page for a System Administrator to manage (assign and remove) Permission Sets for more than one user at a time i.e., Develop a tool  to assign or remove one or more permission sets to or from one or more users.

 

However, I'm caught with error "Save error: DML not allowed on PermissionSetAssignment" when trying to make INSERT DML call on PermissionSetAssignment object. API version of my apex class is 23.0 and Docs too says that this object is Createable. 

 

What is that I'm missing or is it something not released yet?

Hello,

 

I'm writing a small app, that will bulk merge contacts, using partner WSDL.

Here is code that i'm using:

 

private SObject createSObject(String ID,String type)
    {   
        SObject result = new SObject();
        result.setType(type);
        result.setId(ID);
        return result;
    }
    

private void merge(String MasterID,String type, String ChildID)
    {
        connection = Auth.getConnection();
        MergeRequest mReq = new MergeRequest();
        mReq.setMasterRecord(createSObject(MasterID, type));
        mReq.setRecordToMergeIds(new String[] { ChildID });
        MergeRequest[] mergeBatch = new MergeRequest[1];
        mergeBatch[0] = mReq;
        MergeResult[] mRes = connection.merge(mergeBatch)
    }

When i'm trying to merge two contacts, and child has a donation, i get an error:

"Contacts tied to Donations cannot be deleted."

Isn't it suppose to remap donations also? 

 

Thanks

  • November 21, 2011
  • Like
  • 0

I have an old application that uses Web-To-Lead. I'm updating it to use the REST API. We have a bunch of assignment rules set up for Leads. When we create a lead through Web-To-Lead, the Lead is assigned according to our assignment rules. However, when we create a Lead through the REST API, the assignment rules are completely ignored, and the Lead is assigned to the account whose credentials we used to authenticate through OAuth. This has slowed our sales team to a crawl, because now they have to assign leads by hand.

 

Any ideas how to fix this?

Right now I have a custom email button that calls and specific email template. Is there any way to use the same button but call a different template from either a a custom object on the users record?

Baiscally if User's showroom = this, then template = this

This is the code for the custom email button I currently have:

https://cs3.salesforce.com/_ui/core/email/author/EmailAuthor? 
&p3_lkid={!Opportunity.Id} 
&p3={!Opportunity.Name} 
&rtype=003 
& 
IF(AND({!ISPICKVAL( $User.Showroom__c , "Houston")}) , template_id = 00X30000001ARUA), 
IF(AND({!ISPICKVAL( $User.Showroom__c , "Lake Forest")}), template_id = 00X30000001AGI9), 
&p26={!$User.Email} 
&p24={!Opportunity.Renters_Email__c} 
&retURL=/{!Opportunity.Id} 
&saveURL=/{!Opportunity.Id}

  • August 15, 2011
  • Like
  • 0

I was hoping one of you bright people could answer a question regarding SOSL and Content.  In the standard Document object, there is a field called IsBodySearchable that allows SOSL to search within the file contents of an uploaded file.  I also know that in the latest release, the ContentVersion object is now searchable with SOSL, and I know that feature was implemented due to this idea in the IdeaExchange which specifically asks for searching file content.  However, I don't see that same field on the ContentVersion object and cannot find any documentation that specifically states that Content file contents can be searched.  I don't want to promise to a client that we can do this programmatically without seeing it in documentation or getting an "official" verification from someone internal to SFDC. Thanks community!

I am getting a ‘Regex too complicated’ error below when loading data into our org using the following process:

 

1) an email service to receive the CSV data,

2) an APEX class to split and validate the CSV data, and then

3) a set of @future calls to upsert the data.

 

The same data works in smaller volumes, but not beyond a certain threshold. This applies whether we reduce the number of rows, or reduce the width of certain columns of data by truncating them to 3000 characters (a small number of columns have 10,000 characters of text included). When we do either or both of these steps in any combination to reduce the file size, we don't get this problem. It’s not a problem with a specific badly formatted row either, because reducing the number of rows in various combinations always causes the problem to go away.

 

So we don’t believe it is actually a regex problem, because the regular expression is just finding commas to split up a comma separated file/string - i.e. it's very simple.

 

This is why we think there's an undocumented storage or capacity limit somewhere within the APEX processing that is being exceeded - but one that doesn't have a governor limit associated with it, or indeed an accurate error message. We think it is an erroneous error message - i.e. it's not to do with complicated regex – and that this error message is a symptom of another issue.

 

This error has occurred in code that has been stable to date, but has appeared since the filesize we're uploading has increased to beyond about 4600-4800KB, which seems to be the threshold beyond which this problem occurs. There seem to be some undocumented limits in the volume of data than can be processed using the solution architecture we've designed.

 

We want to be able to code around this problem, but unless we know exactly what the error is, any changes we make to our code may not actually fix the problem and result in wasted effort. So I don't want to start changing this until I know exactly which part of the solution needs to be changed!

 

I’ve raised this with Salesforce as a potential bug or to see if they could clarify any undocumented limits on processing large volume datasets using the process we’ve designed, but they seem to have decided it’s a developer issue so won’t help.

 

The error message is below:

 

Apex script unhandled exception by user/organization: 

Failed to invoke future method 'public static void PrepareCSV(String, String, String, Integer, Boolean)'

caused by: System.Exception: Regex too complicated

Class.futureClassToProcess.GetList: line 98, column 17
Class.futureClassToProcess.parseCSV: line 53, column 38
Class.futureClassToProcess.PrepareCSV: line 35, column 20 External entry point

 The relevant code snippet is below:

 

 

 

public static list<List<String>> GetList(String Content)
        {
        Content = Content.replaceAll(',"""',',"DBLQT').replaceall('""",','DBLQT",');
            Content = Content.replaceAll('""','DBLQT');
            List<List<String>> lstCSV = new List<List<String>>();
            Boolean Cont = true;
            while (Cont == true){
                List<String> lstS = Content.Split('\r\n',500);
                if(lstS.size() == 500){
                    Content =lstS[499];
                    lstS.remove(499);
                }else{
                    Cont = false;
                }
                lstCSV.add(lstS);
            }
            return lstCSV;
        }

 

Any suggestions gratefully received as to whether we're missing something obvious, whether 4MB+ files just can't be processed this way, or whether this might actually be a SFDC APEX bug.

 

 

 

public static list<List<String>> GetList(String Content)
        {
            //Sanjeeb
            Log('GetList started.');
            Content = Content.replaceAll(',"""',',"DBLQT').replaceall('""",','DBLQT",');
            Log('Replaing DBLQT.');
            Content = Content.replaceAll('""','DBLQT');
            Log('Replaing DBLQT.');
            List<List<String>> lstCSV = new List<List<String>>();
            Boolean Cont = true;
            while (Cont == true){
                List<String> lstS = Content.Split('\r\n',500);
                Log('Split upto 500 Rows.');
                //List<String> lstS = Content.Split('\r\n',1000);
                if(lstS.size() == 500){
                    Content =lstS[499];
                    lstS.remove(499);
                }else{
                    Cont = false;
                }
                lstCSV.add(lstS);
            }
            Log('GetList ends.');
            return lstCSV;
        }