• sgkmills
  • NEWBIE
  • 100 Points
  • Member since 2007

  • Chatter
    Feed
  • 3
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 21
    Questions
  • 29
    Replies

All,

 

I have written a controller extension which is extending the standard controller of an object, say abc__c.  Within the controller extension, I have declared the class with the keyword 'without sharing'.  In the abc__c object, there is a field that only Admins can update, call it PRM__c.  Within the controller extension, I write to the the PRM__c field and then try to update the abc__c record. 

 

To test the code, I login as a standard user and click the button that kicks off the controller extension class.  When the update abc__c code executes, I get a validation error stating that the update failed.  The validation rule checks the PRM__c field == True and $Profile.Name <> "System Administrator".  When I look in the debug logs, I see that the $Profile.Name is the value of the standard user 'SU' (who I am currently logged in as), but I was expecting it to be 'System Administrator' since the APEX code should be running in System Mode. An excerpt from my log is below:

 

 

|VALIDATION_FORMULA|PRM__c = True && 
$Profile.Name <> "System Administrator"|Primary__c=1 , $Profile.Name=SU
17:59:06.150 (150752000)|VALIDATION_FAIL
17:59:06.150 (150803000)|CODE_UNIT_FINISHED|Validation:abc:a0l50000009lmGk
17:59:06.152 (152315000)|FATAL_ERROR|System.DmlException: Update failed. First exception on row 0 with id a0l50000009lmGk; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION,....

 

I also looked in the the Visual Force Developer's Guide and on Pg. 11 it states the below:

 

Because standard controllers execute in user mode, in which the permissions, field-level security, and sharing rules of the
current user are enforced, extending a standard controller allows you to build a Visualforce page that respects user permissions.
Although the extension class executes in system mode, the standard controller executes in user mode. As with custom
controllers, you can specify whether a user can execute methods in a controller extension based on the user's profile.
Note: Although custom controllers and controller extension classes execute in system mode and thereby ignore
profile-based permissions and field-level security, you can choose whether they respect a user's organization-wide
defaults, role hierarchy, and sharing rules by using the with sharing keywords in the class definition. For information,
see “Using the with sharing or without sharing Keywords” in the Force.com Apex Code Developer's Guide

 

So is the problem that even though my controller extension is set up with 'without sharing', the standard controller, abc__c, runs in user mode?  Consequently, the field PRM__c is read_only for the standard user profile (SU), therefore the update in the controller extension to the PRM__c field in the abc__c object fails!

 

If this is the case, how can I allow the controller extension to update the PRM__c field?  If it isn't, has anyone come across this situation and has a solution?

 

Thanks in advance.

I need some clarification as to why the the two scenarios below give different results. I am retrieving a record (IO Campaign, with all its children from Inventory Reservation). These are both custom objects in our organization. There are actually 561 inventory Reservations associated with the IO Campaign I am retrieving, so that is the value I am expecting in the list, invresItems.

1. The first scenario, I use one query to get data from a parent child relationship.:

public IO_Campaign__c io_campaign { get; private set;}
public List<Inventory_Reservation__c> invresItems { get; private set; }

io_campaign = [SELECT Id, Name,
(SELECT Id, Name FROM Inventory_Reservations__r ORDER BY Name) FROM IO_Campaign__c
where id = :id limit 1];
invresItems = io_campaign.Inventory_Reservations__r;
System.debug('invresItems.size()=' + invresItems.size());

 

When I debug this, the output for invresItems.size() is 499


2. The second scenario:

public IO_Campaign__c io_campaign { get; private set;}
public List<Inventory_Reservation__c> invresItems { get; private set; }

io_campaign = [SELECT Id, Name FROM IO_Campaign__c where id = :id limit 1];
invresItems = [SELECT Id, Name FROM Inventory_Reservation__c ORDER BY Name where IO_Campaign__r.Id = :io_campaign.Id];
System.debug('invresItems.size()=' + invresItems.size());

 

When I debug this, the output for invresItems.size() is 561. This is the expected output.

Why is the first scenario truncating the list at 499? I believe it has to do with the way Salesforce returns data in the API where you have to use the querymore function to retrieve the rest of the rows. I don't believe I can use that in Apex, so what is the correct approach. Am I missing something?


 

Also, I found an article What does the Invalid Query Locator error mean? and it explained that APEX might create a query locator when you use an inner query and the query locator will be used with a querymore when you try to retrieve the inner query data.

 

I tried to change the code to the below and it still only gave me the 499 records.

 

public IO_Campaign__c io_campaign { get; private set;}
public List<IO_Campaign__c > lst_io_campaign { get; private set;}
public List<Inventory_Reservation__c> invresItems { get; private set; }

invresItems = new List<Inventory_Reservation__c>();


lst_io_campaign = [SELECT Id, Name,
(SELECT Id, Name FROM Inventory_Reservations__r ORDER BY Name) FROM IO_Campaign__c
where id = :id limit 1];

for(IO_Campaign__c io : lst_io_campaign) // queryMore() will be used to retrieve child cases
invresItems.addAll(io.Inventory_Reservations__r);


io_campaign = lst_io_campaign[0];
System.debug('invresItems.size()=' + invresItems.size());


 

When I debug this, the output for invresItems.size() is 499


So it seems as if the inner query is only retrieving the 500 (the one IO Campaign record and the 499 Inventory Reservation records), but the For Loop should add the rest by using the query locator and the querymore function.  This isn't happening.

 

Any help will be greatly appreciated.

 

I have written a custom controller extension on a custom object and am trying to retrieve the current record/id by using the getRecord and getId methods of the StandardController class but both are coming back null. How is that possible?

part of the controller extension is below. The custom object is called SC__c:

public SC_Controller_Ext (ApexPages.StandardController stdController) {
// this will kickoff you main page
controller = stdController;
system.debug('stdController=' + stdController + ', stdController.getRecord()=' + stdController.getRecord() + ', stdController.getId()=' + stdController.getId());

 

The system.debug shows the getRecord and the getId are null.  The controller extension gets kicked off from an overwritten button on a Standard Page.  The button that is overwritten is the 'new' button of the custom object.  

 

I don't understand how the standardcontroller object can be null because I am viewing the record and then just clicking the edit button, of the custom object.  This button is not overwitten, it is using the default Salesforce action.  Then I click the 'Save and New' button from the 'edit' screen and the controller isn't initialized.

 

Any info/ideas will be greatly appreciated.

Good Day All, I have written a class in Apex that has a bunch of methods, some are used to do Callouts to a 3rd party RESTful Web service and some are used to parse the XML data that is returned by the RESTful Web service. The Callout is instantiated by a user clicking a button on a Visual Force Page. The button resides on a page layout of a custom object, 'IOC'. A string is composed of data from the 'IOC' object and its children, 'IR' object. This string is passed to the callout, which processes it and returns XML data. The Callout works fine, I am able to parse the XML data returned with the methods I wrote and am able to update fields in a custom object after the XML data is parsed. The issue is that the Callout can take anywhere from 30-120 seconds when the 'IOC' object has more than 50 'IR' objects. This is too long for a user to be waiting for the data to be returned. So I wrote an Asynchronous Callout to alleviate the problem which sends the data over to the 3rd party RESTful Web service service in batches. The issue is that the Asynchronous Callout doesn't have a return value and is marked as 'static' and my methods that are parsing the XML data are marked as 'public virtual'. This seems to not allow me to call the parsing methods from within the Asynchronous Callout Method. Am I able to use the methods I created to parse the XML data from withing the Asynchronous Callout Method? If not, what is the best approach to process the XML data using an Asynchronous Callout method. BTW, the Asynchronous Callout method does make the Callout to the 3rd party RESTful Web service. I tested it with an 'IOC' object of 200 'IR' objects and the Asynchronous Callout method ran 4 separate times because it makes a callout in batches of 50 'IR' objects. I went into the monitoring area of Salesforce and saw each Asynchronous Callout method had a status value of 'Success' and looked at the log file and saw that the Callout was made successful and the XML data was returned by the Web service. Now I just need to be able to use the parsing methods I created to parse the data. So close!!!! Any information would be greatly appreciated, links, sample code, etc.... Thanks in advance

I have an excel app I wrote with the excel connector, that allows users to login and do some inserts/deletes for some custom objects.  I would like to write some validation rules that detect when the user is logged in via this APP which will allow them to edit certain fields.  If they are logged in via the browser, they shouldn't be able to edit those same fields.

 

Is there a field/flag that allows me to detect that the login came from the API as opposed to the Web Browser?

 

Thanks in advance

I created a visualforce page and a button that calls the visual force page to do some behind the scenes processing.  The processing basically clones a custom object record and its children, doing some other unique things.  The button is displayed on the standard detail record screen of the custom object and when clicked it will call the visual force page below, call it 'CLONE':

 

 

 

<apex:page standardController="custom_object__c" action="{!autoRun_Version}" extensions="custom_Controller_Ext" title="Cloning Custom object record"> <apex:sectionHeader title="Cloning of Custom object record"/> <apex:messages /> <apex:outputPanel > Click <apex:outputLink value="/{!$CurrentPage.parameters.id}"> Here </apex:outputLink> to return to the Custom object record </apex:outputPanel> </apex:page>

 

The code in the controller does all the processing and it works fine.  The issue is I want to display any error messages on the page where the button is clicked, but this is a standard page created by Salesforce and the company doesn't want to change it.  So I currently display the messages in the Visual force page, 'CLONE' above.  I would prefer to display the errors on the standard page where the button is clicked, if possible.  But, if it isn't, I want to display them on a Generic Error Page.  The error page will have the errors and then a link to go back to the standard detail page where the button is on.

 

The main part of the controller code is displayed, I didn't include everything because it would just complicate the matter:

 

 

public with sharing class custom_Controller_Ext { *** all the stuff such as constructors and private variables set above *** public PageReference autoRun_Version() { .... // *** all the stuff in autoRun_Version that wasn't pertinent has been left out *** .... if (Campaign_Inactive__c != true) { vIO(); vInv(); } else { System.debug('SKM-IO Campaign is Inactive'); PageReference pageRef = Page.ErrorPg; pageRef.getParameters().put('id', custom_object__c.id); System.debug('SKM- (INACTIVE) Page Reference =' + pageRef); pageRef.setRedirect(true); ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.ERROR, 'ERROR: \'INACTIVE\' '); ApexPages.addMessage(myMsg); return pageRef; } } }

 

Lastly, the  visualforce page, ErrorPg, is attached.  This is my generic error page. As you see below, I have the <apex:messages /> code in the visual force page, but the message I added above int the controller doesn't get displayed.   I believe it has to do with the fact that the button exists on a standard detail page, which calls a visualforce page and then gets redirected to another visualforce page to display the message.  Is this permissable

 

BTW, I can see the error messages if I change the 'return pageRef' to 'return null'.  This basically shows the errors in the 'CLONE' visualforce page, not the generic error visualforce page.

 

 

<apex:page standardController="custom_object__c"> <apex:sectionHeader title="Generic Error Page"/> <apex:messages /> <apex:outputPanel > Click <apex:outputLink value="/{!$CurrentPage.parameters.id}"> Here </apex:outputLink> to return to the Campaign </apex:outputPanel> </apex:page>

 

 Any help will be appreciated.

 

Thanks

 

 

 

I am trying to use the method EncodingUtil.urlEncode as shown below to encode a string passed into my method 'checkProduct'.  For example, if I call checkProduct('Jelly Beans'), I am expecting that the econdedURL would equal https://somewhere.com/something/Jelly%20Beans.  I am not getting that.  I am getting https://somewhere.com/something/Jelly++Beans.

 

What I need is for any of the spaces to be converted to %20.  I thought this is what the urlEncode method would do?  Any help would be appreciated.

 

public String checkProduct(String target) { String URL = 'https://somewhere.com/something/'; String encodedURL; System.debug('URL= ' + URL); encodedURL = URL + EncodingUtil.urlEncode(target, 'UTF-8'); System.debug('encodedURL= ' + encodedURL); )

 

I am trying to do a callout that logon's to a webservice and then returns an xml file.  I am trying to set the response header's content-type to be application-xml, but only see a setHeader method on the HttpRequest object.  

 

I am having a problem setting the Content-Type header with the below code.  When I check the Content-Type of the HttpResponse object, the value isn't 'application/xml' as I expected. 

 

Is this the correct approach?

 

 

Http http = new Http(); HttpRequest req = new HttpRequest(); req.setMethod('GET'); req.setHeader('Content-Type', 'application/xml'); req.setEndpoint('https://something./rest/clientauth/authenticate?account=xxx&password=xxx&source=xxx'); try { //Execute web service call here HTTPResponse res = http.send(req); //Helpful debug messages System.debug(res.toString()); System.debug('STATUS:'+res.getStatus()); System.debug('STATUS_CODE:'+res.getStatusCode()); System.debug('Content-Type:'+ res.getHeader('Content-Type')); } catch (System.CalloutException e) { system.debug('SKM-CalloutException occurred'); }

 

 

 

 

I have a trigger that calls a asynchronous method and it hits the 'Too Many DML rows' exception.  Basically the trigger creates a bunch of records in a child table which is used to do statistics.  Is there any way that I can create these records at a later date, for instance schedule a job, or write a class to do the creation after the trigger completes.

 

I had a solution, but it entails in making numerous calls to the asynchrounous method.  When I do that, I hit the barrier of 'Too many Future Calls'

 

So my main question is how can I break the process up so I can load the DML rows into the child table.  BTW, the code is already batching the records and I have optimized the code for bulk operation.

 

Any ideas/help will be appreciated.

 

Thanks

I have a trigger on the opportunity object that gets called on the 'After Insert' event.  The code in this trigger creates a record in a custom s-object that I created, call it "SC__c".

 

trigger CreateSCTrigger on Opportunity (after insert) {
if (Trigger.isInsert) {
for (Opportunity o : Trigger.new) {
//Code to create new SC
temp_SC = new SC__c(Opportunity__c=o.Id, Sales_Rep__c=o.OwnerID, CPct__c=100);
insert temp_SC;
}
}

}

 

I also have a trigger on  "SC__c" that gets called on the 'Before Insert' event.  The code for this trigger just changes a field value

trigger UpdateSCTrigger on SC__c (before insert) {
if (Trigger.isInsert) {
if (Trigger.new.size() >=1) {
for (SC__c sc : Trigger.new) {
sc.Sales_Goal__c = sc.SalesGoalID__c;
}
}
}

}

 

So the 'insert temp_SC' line in the CreateSCTrigger, causes the UpdateSCTrigger to fire.

 

This used to work fine, but with the Spring09 changes to the behavior of workflow rules and roll-up summary field evaluations, the 2nd trigger is causing a 'INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY, insufficient access rights on cross-reference id:' error.

 

Why would this be?  Any help will be greatly appreciated.

 

Thanks in advance.

Hi,

 

I have 2 custom objects, once is called 'res' and the other called 'res_mt', which has a lookup relationship to 'res'.  I have a trigger on the 'res' object that creates 48 'res_mt' records upon 'afterinsert'.  This trigger works fine.

 

I then added a new object called 'res_d', which has a lookup relationship to 'res_mt'.  I created a trigger on the 'res_mt' object that would create 31 'res_d' records upon 'afterinsert'.

 

I try to add a 'res' record and get a Too Many DML Rows error.  When looking in the 'System Log', I see the trigger on 'res' gets fired and the 48 records are created.  But, the 2nd trigger that creates the 31 'res_d' records, doesn't get fired for each of the 48 records!  I thought that for each of the 48 'res_mt' records, I would see the 2nd trigger fire in between, like a nested trigger.  That doesn't seem to be the case, it seems that the first trigger must complete before the 2nd starts.  

 

Does anyone have any suggestions for me?

 

 

When looking at the System Log, I see that 

What happens in the following scenario:

I have a custom object, call it MDP, that is associated with an opportunity.  There can be many MDP records for each opportunity.  I have written a trigger that updates fields in the Opportunity when certain fields in a MDP record is modified.

The problem is that the data loader does not seem to be updating the same opportunity if two MDP records associated to the same Opportunity is updated.  What I would need is each time the MDP record is updated, the Opportunity is updated.  Regardless if it is the same opportunity in a batch update via dataloader.  Is it possible?
I currently have written a bunch of triggers, but if an error occurs I am the only person getting the emails.

Is there a way to send the email for an 'unhandled trigger exception' to another admin in Salesforce?
Is it possible to write TestCode to check if an OpportunityShare was created?

I have the below code in  a trigger:

Code:
  temp_opp_share = new OpportunityShare(OpportunityAccessLevel='Edit', UserOrGroupId=o.Channel_Specialist__c, OpportunityId=o.Id);
            insert temp_opp_share;

 
Now I need to write test code to see if the OpportunityShare does indeed get created.

How would I do this?
Is there a global variable for the salesforce server you are connecting to.

Currently, I have the following code:
Code:
 var saveURL ="https://tapp0.salesforce.com/"+ newOppId; 


But, I don't want to hardcode the URL, so how can I get the salesforce server name that I am currently connected to.

I was trying to use the URLFOR function, but I still need a target value and didn't know what I could put.

Thanks in advance

I have written a C# application that forces territory rules to run on a scheduled time period by running the salesforce generated URL.  So I am trying to write a trigger that runs the territory rules when an Opportunity is either created or updated!  The problem is that I don't see a way to force the territory rules to run! 

Does any one have a practical solution?  BTW, I tried to update the account associated with the opportunity.  If I do it via Salesforce, the account page layout forces the territory rules to run.  This is due to the checkbox 'Run territory Assignment Rules on save by default' on the account page layout.  But, it seems this doesn't work via the API.

Any information on this matter would be greatly appreciated!
I have the following trigger on a user object, but I am not getting any debugging information within the sandobx environment.  I have selected my 'Log Category' to be 'Apex Code' and 'Log Level' to be 'Debug'.

Nothing is being displayed?  Is there another setting or area where I must view the debug information for the trigger?

Code:
trigger NewUserTrigger on User(before insert, before update, after insert, after update) {

 Account temp_acc;
 String TestAcct = 'New User Trigger - do not delete or modify'; //Test Account
  System.Debug('Starting NewUserTrigger');

 try {
     System.Debug('SKM-NewUserTrigger');
  
  if (Trigger.isBefore) {     
     for (User u : Trigger.new) {
        System.Debug('Update--SKM-isBefore: ' + u.Full_Name__c );
     }
  } else if (Trigger.isAfter) {
        for (User u : Trigger.new) {
            System.Debug('Update--SKM-isAfter ' + u.Full_Name__c );
        }
  }
 }
 finally
 {
 }
}

 

I have written some apex code to basically do an update of account records where all the children of a master account will be updated with certain information.  We have a custom field called "Parent_Account_Name" and this field should be updated with the master account's new name. 

I create an array of accounts and try to access the Name field, but I get a null value.  The problem is I can reference the name field by displaying accts[0].Name, (where accts is my array of accounts returned from a SOQL query) but not reference it by doing the 'for (Account a1 : accts)' and then displaying a1.Name.  a1.Name shows as Null.

Below is the code for the trigger:

Code:
if (Trigger.isAfter) {
      /* Once the insert/update trigger is completed, the cascading phase is as follows:
    1.  Get the Acct Id of the record that was just inserted/updated
    2.  Do a search to see which records have their ParentId the same as the Acct Id found in 1.
    3.  Update the new Parent Name for all those records in 2.
    */
        for (Account a : Trigger.new) {
         System.Debug('isAfter-a: ' + a);
         Account[] accts = [select id, ParentId, Name from Account where ParentId = :a.Id];
         System.Debug('SKM-Acct.Size: ' + accts.size());
         if (accts.size() > 0) {
             System.Debug('accts[0]: ' + accts[0].Name);
             for (Account a1 : accts) {
                a1.Name = a.Parent_Account_Name__c;
                System.Debug('a1= ' + a1 + ', acct.Name= ' + a1.Name + ', a.Parent_Account.Name= ' + a.Parent_Account_Name__c);
            }
         }
        }

 
I have viewed the code in debug mode and see some wierd behavior.

Partial print of the debug code is below
:
Code:
20080219162042.523:Trigger.ParentNameUpdateTrigger: line 6, column 3: Starting ParentNameUpdate
20080219162042.523:Trigger.ParentNameUpdateTrigger: line 51, column 10: isAfter-a: Account:{SystemModstamp=Tue Feb 19 16:20:42 GMT 2008, Type=Master Customer, Parent_ID_Confirm__c=1, RecordTypeId=0125000000097vkAAA, OwnerId=00550000000s4qAAAQ, IsExcludedFromRealign=false, IsLocked=false, LastModifiedById=00550000000s4qAAAQ, MayEdit=false, IsDeleted=false, Master_Customer_Level__c=SKM-Tes1a, CreatedDate=Tue Feb 19 16:20:38 GMT 2008, LastModifiedDate=Tue Feb 19 16:20:42 GMT 2008, Account_ID_Display__c=001S0000002f8AY, Name=SKM-Tes1a, Id=001S0000002f8AYIAY, CreatedById=00550000000s4qAAAQ}
20080219162042.523:Trigger.ParentNameUpdateTrigger: line 53, column 10: SKM-Acct.Size: 2
20080219162042.523:Trigger.ParentNameUpdateTrigger: line 55, column 13: accts[0]: SKM-Test2
20080219162042.523:Trigger.ParentNameUpdateTrigger: line 58, column 17: a1= Account:{ParentId=001S0000002f8AYIAY, Name=null, Id=001S0000002f8AZIAY}, acct.Name= null, a.Parent_Account.Name= null
20080219162042.523:Trigger.ParentNameUpdateTrigger: line 58, column 17: a1= Account:{ParentId=001S0000002f8AYIAY, Name=null, Id=001S0000002f8AaIAI}, acct.Name= null, a.Parent_Account.Name= null

 
The debug statement at line 53 shows 2 accounts that are children of my master account.  If I traverse the accts array that I created, I see that 'accts[0].Name' does show the correct name of 'SKM-Test-2'.  Then I use a for loop to go through the accts array, 'for (Account a1 : accts)', and try to print out the values, but the 'Name' field is now Null!  So how is it that I can reference the name field by dowing accts[0].Name, but not reference it by doing the 'For loop'?

I have been reading these forums and keep seeig this request for a way to set fields on a page when using S-Controls.

I took the liberty to show my solution, which actually sets fields defined as read-only and editable fields on a specific page layout.

Below, I create a variable called "options".  This variable holds all the fieldnames and values I want to set within the field.  For example, opp7 is the fieldname for amount and the fields starting with "00N" are custom fields.  BTW, you can find the fieldname of the custom field by going to the Setup | Customize area in Salesforce and then going into the Fields area for the object that you are setting values in.  In my case it was Opportunity.

The next step, I created a "newURL" variable, which uses the URLFOR function to build the URL that I will redirect the browser to.  As you see, I append the "options" variable to the end of the created URL.

Then I just use the window.parent.location.replace function to redirect the browser to the newly created URL.

As I stated above, some of these fields are not editable on the layout, but still get changed and then they are viewed as read-only. 

Code:
 var options = "&opp7=0&opp11=Development&00N5000000xxxxx=0&00N3000000xxxxx=0&00N5000000xxxxx=" +
"&RecordType=012300000000xxxxxx&opp5;

var newURL = "{!URLFOR( $Action.Opportunity.Edit, Opportunity.Id,
      [retURL=$Request.retURL] ,true)}"+options;

window.parent.location.replace(newURL);

 

Problem:  I have overwriten the "Clone" button for the opportunity object.  I pass parameters to the newly created opportunity via the URL.  If validation rules fail when the user clicks "Save", then salesforce redirects the page to https://na3.salesforce.com/006/e.  this is the edit page for the newly created opportunity, but doesn't have my variables.  The reason this is a problem is because one of my varialbes is  "cloneli=1"  This allows me to clone the line items of the opportunity.  When Salesforce redirects me to https://na3.salesforce.com/006/e, the "Save" button becomes "Save & Add Deliverables", which means it isn't cloning the Opportunity LineItems anymore.

BTW, Deliverables, is our name for Opportunity LineItems.

The code below works fine if validation is passed on all fields when the user clicks "Save".  The Opportunity Line Items are also cloned.  As stated, the problem is if the user makes an error or doesn't put in a required field on the cloned opportunity and then they try to save it, then Salesfoce redirects them to the following URL https://na3.salesforce.com/006/e.  All my variables that I added to the URL are stripped!

How can I get the same variables I passed when I clicked the "Clone" button to show up if validation fails when the user clicks the "Save" button in the newly created cloned opportunity?


Note: The "options" variable below are the parameters I pass to the URL and the newURL variable is the actual URL that gets called.

Code:
     var options = "&opp7=0&opp11=&00N50000001TsuZ=0&00N300000018Fd8=0&00N50000001gfzh=&00N50000001TsuZ=0&00N50000001QPD1=0&00N50000001hD8t=0&00N50000001hD8Z=0&retURL=/" +  "{!Opportunity.Id}" ;

var newURL ="https://na3.salesforce.com/"+ "{!Opportunity.Id}" + "/e—clone=1" + options + "&nooverride=1&cloneli=1";

window.parent.location.replace(newURL);

 

All,

 

I have written a controller extension which is extending the standard controller of an object, say abc__c.  Within the controller extension, I have declared the class with the keyword 'without sharing'.  In the abc__c object, there is a field that only Admins can update, call it PRM__c.  Within the controller extension, I write to the the PRM__c field and then try to update the abc__c record. 

 

To test the code, I login as a standard user and click the button that kicks off the controller extension class.  When the update abc__c code executes, I get a validation error stating that the update failed.  The validation rule checks the PRM__c field == True and $Profile.Name <> "System Administrator".  When I look in the debug logs, I see that the $Profile.Name is the value of the standard user 'SU' (who I am currently logged in as), but I was expecting it to be 'System Administrator' since the APEX code should be running in System Mode. An excerpt from my log is below:

 

 

|VALIDATION_FORMULA|PRM__c = True && 
$Profile.Name <> "System Administrator"|Primary__c=1 , $Profile.Name=SU
17:59:06.150 (150752000)|VALIDATION_FAIL
17:59:06.150 (150803000)|CODE_UNIT_FINISHED|Validation:abc:a0l50000009lmGk
17:59:06.152 (152315000)|FATAL_ERROR|System.DmlException: Update failed. First exception on row 0 with id a0l50000009lmGk; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION,....

 

I also looked in the the Visual Force Developer's Guide and on Pg. 11 it states the below:

 

Because standard controllers execute in user mode, in which the permissions, field-level security, and sharing rules of the
current user are enforced, extending a standard controller allows you to build a Visualforce page that respects user permissions.
Although the extension class executes in system mode, the standard controller executes in user mode. As with custom
controllers, you can specify whether a user can execute methods in a controller extension based on the user's profile.
Note: Although custom controllers and controller extension classes execute in system mode and thereby ignore
profile-based permissions and field-level security, you can choose whether they respect a user's organization-wide
defaults, role hierarchy, and sharing rules by using the with sharing keywords in the class definition. For information,
see “Using the with sharing or without sharing Keywords” in the Force.com Apex Code Developer's Guide

 

So is the problem that even though my controller extension is set up with 'without sharing', the standard controller, abc__c, runs in user mode?  Consequently, the field PRM__c is read_only for the standard user profile (SU), therefore the update in the controller extension to the PRM__c field in the abc__c object fails!

 

If this is the case, how can I allow the controller extension to update the PRM__c field?  If it isn't, has anyone come across this situation and has a solution?

 

Thanks in advance.

I need some clarification as to why the the two scenarios below give different results. I am retrieving a record (IO Campaign, with all its children from Inventory Reservation). These are both custom objects in our organization. There are actually 561 inventory Reservations associated with the IO Campaign I am retrieving, so that is the value I am expecting in the list, invresItems.

1. The first scenario, I use one query to get data from a parent child relationship.:

public IO_Campaign__c io_campaign { get; private set;}
public List<Inventory_Reservation__c> invresItems { get; private set; }

io_campaign = [SELECT Id, Name,
(SELECT Id, Name FROM Inventory_Reservations__r ORDER BY Name) FROM IO_Campaign__c
where id = :id limit 1];
invresItems = io_campaign.Inventory_Reservations__r;
System.debug('invresItems.size()=' + invresItems.size());

 

When I debug this, the output for invresItems.size() is 499


2. The second scenario:

public IO_Campaign__c io_campaign { get; private set;}
public List<Inventory_Reservation__c> invresItems { get; private set; }

io_campaign = [SELECT Id, Name FROM IO_Campaign__c where id = :id limit 1];
invresItems = [SELECT Id, Name FROM Inventory_Reservation__c ORDER BY Name where IO_Campaign__r.Id = :io_campaign.Id];
System.debug('invresItems.size()=' + invresItems.size());

 

When I debug this, the output for invresItems.size() is 561. This is the expected output.

Why is the first scenario truncating the list at 499? I believe it has to do with the way Salesforce returns data in the API where you have to use the querymore function to retrieve the rest of the rows. I don't believe I can use that in Apex, so what is the correct approach. Am I missing something?


 

Also, I found an article What does the Invalid Query Locator error mean? and it explained that APEX might create a query locator when you use an inner query and the query locator will be used with a querymore when you try to retrieve the inner query data.

 

I tried to change the code to the below and it still only gave me the 499 records.

 

public IO_Campaign__c io_campaign { get; private set;}
public List<IO_Campaign__c > lst_io_campaign { get; private set;}
public List<Inventory_Reservation__c> invresItems { get; private set; }

invresItems = new List<Inventory_Reservation__c>();


lst_io_campaign = [SELECT Id, Name,
(SELECT Id, Name FROM Inventory_Reservations__r ORDER BY Name) FROM IO_Campaign__c
where id = :id limit 1];

for(IO_Campaign__c io : lst_io_campaign) // queryMore() will be used to retrieve child cases
invresItems.addAll(io.Inventory_Reservations__r);


io_campaign = lst_io_campaign[0];
System.debug('invresItems.size()=' + invresItems.size());


 

When I debug this, the output for invresItems.size() is 499


So it seems as if the inner query is only retrieving the 500 (the one IO Campaign record and the 499 Inventory Reservation records), but the For Loop should add the rest by using the query locator and the querymore function.  This isn't happening.

 

Any help will be greatly appreciated.

 

I have written a custom controller extension on a custom object and am trying to retrieve the current record/id by using the getRecord and getId methods of the StandardController class but both are coming back null. How is that possible?

part of the controller extension is below. The custom object is called SC__c:

public SC_Controller_Ext (ApexPages.StandardController stdController) {
// this will kickoff you main page
controller = stdController;
system.debug('stdController=' + stdController + ', stdController.getRecord()=' + stdController.getRecord() + ', stdController.getId()=' + stdController.getId());

 

The system.debug shows the getRecord and the getId are null.  The controller extension gets kicked off from an overwritten button on a Standard Page.  The button that is overwritten is the 'new' button of the custom object.  

 

I don't understand how the standardcontroller object can be null because I am viewing the record and then just clicking the edit button, of the custom object.  This button is not overwitten, it is using the default Salesforce action.  Then I click the 'Save and New' button from the 'edit' screen and the controller isn't initialized.

 

Any info/ideas will be greatly appreciated.

Hi All,

 

I have a custom object (XYZ__c) under Opportunities as a related list (master-detail).

 

I had to pre-populate few fields in XYZ record when user clicks on 'NEW XYZ' button under the opportunity.

 

So, I used a custom button and replaced the standard NEW XYZ button in the page layout (of opportunity) passing values in the URL.

 

.........&Name=Auto+Number&RecordType=****************&saveURL=/{!XYZ__c.Id}&retURL=/{!XYZ__c.Id}

 

Everything is fine. But when users click on Save and New, these values are not prepolating, instead it re-directs user to record type selection page !!!!!!!! Becoz, after save its going to the standard NEW button in the XYZ object, which I haven't overriden.  I just replaced the new button in the pagelayout (of opportunity). 

 

I cannot over-write the standard NEW button of XYZ object with URL. I dont have any VF pages. I just need couple of fields to be pre-populated hence i am using URL to override. 

 

Any help would be highly appreciated!

 

Please help.

Winter '11 was supposed to include the much-improved system log, and we got an email blast saying that with Winter '11, the Help & Training minisite was getting an overhaul.  We've had Winter '11 implemented already, but these features are missing.

I created a visualforce page and a button that calls the visual force page to do some behind the scenes processing.  The processing basically clones a custom object record and its children, doing some other unique things.  The button is displayed on the standard detail record screen of the custom object and when clicked it will call the visual force page below, call it 'CLONE':

 

 

 

<apex:page standardController="custom_object__c" action="{!autoRun_Version}" extensions="custom_Controller_Ext" title="Cloning Custom object record"> <apex:sectionHeader title="Cloning of Custom object record"/> <apex:messages /> <apex:outputPanel > Click <apex:outputLink value="/{!$CurrentPage.parameters.id}"> Here </apex:outputLink> to return to the Custom object record </apex:outputPanel> </apex:page>

 

The code in the controller does all the processing and it works fine.  The issue is I want to display any error messages on the page where the button is clicked, but this is a standard page created by Salesforce and the company doesn't want to change it.  So I currently display the messages in the Visual force page, 'CLONE' above.  I would prefer to display the errors on the standard page where the button is clicked, if possible.  But, if it isn't, I want to display them on a Generic Error Page.  The error page will have the errors and then a link to go back to the standard detail page where the button is on.

 

The main part of the controller code is displayed, I didn't include everything because it would just complicate the matter:

 

 

public with sharing class custom_Controller_Ext { *** all the stuff such as constructors and private variables set above *** public PageReference autoRun_Version() { .... // *** all the stuff in autoRun_Version that wasn't pertinent has been left out *** .... if (Campaign_Inactive__c != true) { vIO(); vInv(); } else { System.debug('SKM-IO Campaign is Inactive'); PageReference pageRef = Page.ErrorPg; pageRef.getParameters().put('id', custom_object__c.id); System.debug('SKM- (INACTIVE) Page Reference =' + pageRef); pageRef.setRedirect(true); ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.ERROR, 'ERROR: \'INACTIVE\' '); ApexPages.addMessage(myMsg); return pageRef; } } }

 

Lastly, the  visualforce page, ErrorPg, is attached.  This is my generic error page. As you see below, I have the <apex:messages /> code in the visual force page, but the message I added above int the controller doesn't get displayed.   I believe it has to do with the fact that the button exists on a standard detail page, which calls a visualforce page and then gets redirected to another visualforce page to display the message.  Is this permissable

 

BTW, I can see the error messages if I change the 'return pageRef' to 'return null'.  This basically shows the errors in the 'CLONE' visualforce page, not the generic error visualforce page.

 

 

<apex:page standardController="custom_object__c"> <apex:sectionHeader title="Generic Error Page"/> <apex:messages /> <apex:outputPanel > Click <apex:outputLink value="/{!$CurrentPage.parameters.id}"> Here </apex:outputLink> to return to the Campaign </apex:outputPanel> </apex:page>

 

 Any help will be appreciated.

 

Thanks

 

 

 

When developing a Visualforce page for overiding view page for any object, one problem that creeps up is to display the History details of a record. The standard related list Component doesn't works for History.

 

With the help of some code from Community ( I now can't find the link to it :( ), I wrote my own code  then to display the history of an object. It mimics the standard list as far as possible.  

 

Heres the code. It is for the Case object but it can be used for any other object.

 1.Component Code

 

<apex:component controller="CaseHistoriesComponentController">
<!-- Attribute Definition -->
<apex:attribute name="CaseId" description="Salesforce Id of the Case whose Case History needs to be rendered" type="Id" required="true" assignTo="{!caseId}" />

<!-- Case History Related List -->
<apex:pageBlock title="Case History">
<apex:pageBlockTable value="{!histories}" var="History" >
<apex:column headerValue="Date" value="{!History.thedate}"/>
<apex:column headerValue="User"> <apex:outputLink value="/{!History.userId}"> {!History.who} </apex:outputLink></apex:column>
<apex:column headerValue="Action"><apex:outputText escape="false" value="{!History.action}"/></apex:column>
</apex:pageBlockTable>
</apex:pageBlock>
</apex:component>

 

 

 

 

2. Apex Code

 

public class CaseHistoriesComponentController {

public Id caseId {get; set;}
public cHistories[] histories;

// Variables
public Static final Map<String, Schema.SObjectField> CaseFieldmap = Schema.SObjectType.Case.fields.getMap();
public Static final List<Schema.PicklistEntry> fieldPicklistValues = CaseHistory.Field.getDescribe().getPicklistValues();

public List<cHistories> getHistories()
{
list<cHistories> histories = new list<cHistories>();
String prevDate = '';
for(CaseHistory cHistory : [Select CreatedDate, CreatedBy.Name, CreatedBy.Id, Field, NewValue, OldValue from CaseHistory where CaseId = :caseId order by CreatedDate desc])
{
if((cHistory.newValue == null && cHistory.oldValue == null)
|| (cHistory.newValue != null && !(string.valueOf(cHistory.newValue).startsWith('005') || string.valueOf(cHistory.newValue).startsWith('00G')))
|| (cHistory.oldValue != null && !(string.valueOf(cHistory.oldValue).startsWith('005') || string.valueOf(cHistory.oldValue).startsWith('00G'))))
{
cHistories tempHistory = new cHistories();
// Set the Date and who performed the action
if(String.valueOf(cHistory.CreatedDate) != prevDate)
{
tempHistory.theDate = String.valueOf(cHistory.CreatedDate);
tempHistory.who = cHistory.CreatedBy.Name;
tempHistory.userId = cHistory.CreatedBy.Id;
}
else
{
tempHistory.theDate = '';
tempHistory.who = '';
tempHistory.userId = cHistory.CreatedBy.Id;
}
prevDate = String.valueOf(cHistory.CreatedDate);

// Get the field label
String fieldLabel = CaseHistoriesComponentController.returnFieldLabel(String.valueOf(cHistory.Field));

// Set the Action value
if (String.valueOf(cHistory.Field) == 'created') { // on Creation
tempHistory.action = 'Created.';
}
else if(cHistory.OldValue != null && cHistory.NewValue == null){ // when deleting a value from a field
// Format the Date and if there's an error, catch it and re
try {
tempHistory.action = 'Deleted ' + Date.valueOf(cHistory.OldValue).format() + ' in <b>' + fieldLabel + '</b>.';
} catch (Exception e){
tempHistory.action = 'Deleted ' + String.valueOf(cHistory.OldValue) + ' in <b>' + fieldLabel + '</b>.';
}
}
else{ // all other scenarios
String fromText = '';
if (cHistory.OldValue != null) {
try {
fromText = ' from ' + Date.valueOf(cHistory.OldValue).format();
} catch (Exception e) {
fromText = ' from ' + String.valueOf(cHistory.OldValue);
}
}

String toText = '';
if (cHistory.OldValue != null) {
try {
toText = Date.valueOf(cHistory.NewValue).format();
} catch (Exception e) {
toText = String.valueOf(cHistory.NewValue);
}
}
if(toText != '')
tempHistory.action = 'Changed <b>' + fieldLabel + '</b>' + fromText + ' to <b>' + toText + '</b>.';
else
tempHistory.action = 'Changed <b>' + fieldLabel;
}

// Add to the list
histories.add(tempHistory);
}
}

return histories;
}

// Function to return Field Label of a Case field given a Field API name
public Static String returnFieldLabel(String fieldName)
{
if(CaseHistoriesComponentController.CaseFieldmap.containsKey(fieldName))
return CaseHistoriesComponentController.CaseFieldmap.get(fieldName).getDescribe().getLabel();
else
{
for(Schema.PicklistEntry pickList : fieldPicklistValues)
{
if(pickList.getValue() == fieldName)
{
if(pickList.getLabel() != null)
return pickList.getLabel();
else
return pickList.getValue();
}
}
}
return '';
}
// Inner Class to store the detail of the case histories
public class cHistories {

public String theDate {get; set;}
public String who {get; set;}
public Id userId {get; set;}
public String action {get; set;}
}
}

  Let me know your views on the code or if you have any questions

 

I am trying to use the method EncodingUtil.urlEncode as shown below to encode a string passed into my method 'checkProduct'.  For example, if I call checkProduct('Jelly Beans'), I am expecting that the econdedURL would equal https://somewhere.com/something/Jelly%20Beans.  I am not getting that.  I am getting https://somewhere.com/something/Jelly++Beans.

 

What I need is for any of the spaces to be converted to %20.  I thought this is what the urlEncode method would do?  Any help would be appreciated.

 

public String checkProduct(String target) { String URL = 'https://somewhere.com/something/'; String encodedURL; System.debug('URL= ' + URL); encodedURL = URL + EncodingUtil.urlEncode(target, 'UTF-8'); System.debug('encodedURL= ' + encodedURL); )

 

I am trying to do a callout that logon's to a webservice and then returns an xml file.  I am trying to set the response header's content-type to be application-xml, but only see a setHeader method on the HttpRequest object.  

 

I am having a problem setting the Content-Type header with the below code.  When I check the Content-Type of the HttpResponse object, the value isn't 'application/xml' as I expected. 

 

Is this the correct approach?

 

 

Http http = new Http(); HttpRequest req = new HttpRequest(); req.setMethod('GET'); req.setHeader('Content-Type', 'application/xml'); req.setEndpoint('https://something./rest/clientauth/authenticate?account=xxx&password=xxx&source=xxx'); try { //Execute web service call here HTTPResponse res = http.send(req); //Helpful debug messages System.debug(res.toString()); System.debug('STATUS:'+res.getStatus()); System.debug('STATUS_CODE:'+res.getStatusCode()); System.debug('Content-Type:'+ res.getHeader('Content-Type')); } catch (System.CalloutException e) { system.debug('SKM-CalloutException occurred'); }

 

 

 

 

I have a trigger that calls a asynchronous method and it hits the 'Too Many DML rows' exception.  Basically the trigger creates a bunch of records in a child table which is used to do statistics.  Is there any way that I can create these records at a later date, for instance schedule a job, or write a class to do the creation after the trigger completes.

 

I had a solution, but it entails in making numerous calls to the asynchrounous method.  When I do that, I hit the barrier of 'Too many Future Calls'

 

So my main question is how can I break the process up so I can load the DML rows into the child table.  BTW, the code is already batching the records and I have optimized the code for bulk operation.

 

Any ideas/help will be appreciated.

 

Thanks

I have written a C# application that forces territory rules to run on a scheduled time period by running the salesforce generated URL.  So I am trying to write a trigger that runs the territory rules when an Opportunity is either created or updated!  The problem is that I don't see a way to force the territory rules to run! 

Does any one have a practical solution?  BTW, I tried to update the account associated with the opportunity.  If I do it via Salesforce, the account page layout forces the territory rules to run.  This is due to the checkbox 'Run territory Assignment Rules on save by default' on the account page layout.  But, it seems this doesn't work via the API.

Any information on this matter would be greatly appreciated!
I have the following trigger on a user object, but I am not getting any debugging information within the sandobx environment.  I have selected my 'Log Category' to be 'Apex Code' and 'Log Level' to be 'Debug'.

Nothing is being displayed?  Is there another setting or area where I must view the debug information for the trigger?

Code:
trigger NewUserTrigger on User(before insert, before update, after insert, after update) {

 Account temp_acc;
 String TestAcct = 'New User Trigger - do not delete or modify'; //Test Account
  System.Debug('Starting NewUserTrigger');

 try {
     System.Debug('SKM-NewUserTrigger');
  
  if (Trigger.isBefore) {     
     for (User u : Trigger.new) {
        System.Debug('Update--SKM-isBefore: ' + u.Full_Name__c );
     }
  } else if (Trigger.isAfter) {
        for (User u : Trigger.new) {
            System.Debug('Update--SKM-isAfter ' + u.Full_Name__c );
        }
  }
 }
 finally
 {
 }
}