function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
dburnistondburniston 

Help with Button to update Custom Object records

I have a custom Object to track registrations against an Opportunity in Salesforce. I created a script so that clicking a button would change the stage of the Opportunity and then go through each Registration and change the status if it was Pending.
When I test it on an Opportunity with 3 registrations, it seems to work every time. When I use it on an Opportunity with 7 registrations, it is changing registrations that it shouldn't be.
I store the conditions back to the Registration and it looks as though it should be ignoring the record, but it gets updated.
{!REQUIRESCRIPT("/soap/ajax/19.0/connection.js")} //Required for SalesForce connection 

//Make sure not entering by mistake 
input_box = confirm ("Are you sure you want to update the workshop to Attended?") 

if (input_box==true) 

{ 
 var url = parent.location.href; //string for the URL of the current page 
 //Set up the connection and grab the current Opportunity ID 
 var conn; 
 conn = sforce.connection; 
 var opp = "{!Opportunity.Id}"; 
 var oppname= "{!Opportunity.Name}"; 

 //Get the Registration ID's for all Registrants to this Opportunity 
 var qr = conn.query("Select Registration__c.Id, Registration__c.Workshop_Cancelled__c, Registration__c.Payment_Status__c, Registration__c.Name from Registration__c where Opportunity_del__c ='" + opp + "'" ); 

 var reg = [ ]; 
 var rstat = [ ]; 
 var pstat = [ ]; 
 var paystat1 = "ignore"; // set the default action for payment status 
 var regstat1 = "ignore"; // set the default action for registration status 



 //Figure out how many Registrations there are 
 var records = qr.getArray("records"); 
 var length = records.length 

 //Build an array of registration ID's and status 
 for (var i = 0;i<length;i++) { 
 reg[i] = records[i].get("Id"); 
 rstat[i] = records[i].get("Workshop_Cancelled__c"); 
 } 

 //Build a message to display the Id's 
 //var message = "The Reg's for Opportunity " + opp + " are: "; 

 //for (var i = 0;i<length;i++) { 
 //message = message + " " + reg[i] + " " + rstat[i]; 
 //} 

 //Display the message 
 //alert(message); 

 //Update the Stage of the Opportunity to show Closed - Won 
 var _Opportunity = new sforce.SObject("Opportunity"); //create an sObject for an object - here we are using opportunity but it could be anything 
 _Opportunity.Id = opp; //id should be gathered from a query or something earlier in the script - you'll need the id of the record you want to update though 
 _Opportunity.StageName = "Closed Won"; //you can hard code a value or pass something dynamically (can be any field) - here we are hard coding an update to the opportunity stage 
 var updateOpportunity= sforce.connection.update([_Opportunity]); //actually perform the update to the record 

 //check for success 
 if (updateOpportunity[0].getBoolean("success")) { //check that the update was successful 
 alert("Updated account: "+updateOpportunity[0].id); //alert success notification 
 } else { //otherwise unsuccessful 
 alert("API error: "+updateOpportunity[0]); //alert response from update attempt 
 } 

 if (length > 0) { 
 //Update each of the registrations to update Pending to Attended and ignore the other statuses 
 var _Registration = new sforce.SObject("Registration__c"); //create an sObject for an object - here we are using opportunity but it could be anything 
 var regstat; 

 for (var i = 0;i<length;i++) {//process each registration 
 // get the values from the current registration record 
 _Registration.Id = reg[i]; // get the record id for the update 

 //regstat = rstat[i]; // get the value of Registration status for the current registration 
 _Registration.regstat__c = rstat[i]; // store the initial registration status for update to track what happened 

 regstat1 = "ignore"; // reset the default action each pass 

 //Build a message to display the Id's 
 //var message = "The values for the reg are: \n"; 
 //message = message + " " + reg[i] + " " + rstat[i] + "\n"; 
 //Display the message 
 //alert(message); 

 if (rstat[i] == "Pending"){ // If the registration status is Pending , set to process 
 regstat1 = "process"; 
 _Registration.Workshop_Cancelled__c="Attended"; 
 } 
 _Registration.regstat1__c = regstat1; // Update the holder to show value after test 

 var updateRegistration= sforce.connection.update([_Registration]); //actually perform the update to the record 
 } 

 //check for success 
 if (updateRegistration[0].getBoolean("success")) { //check that the update was successful 
 alert("Updated registration: "+updateRegistration[0].id); //alert success notification 
 } else { //otherwise unsuccessful 
 alert("API error: "+updateRegistration[0]); //alert response from update attempt 
 } 
 } 
 alert("The process has completed"); 
 parent.location.href = url; //refresh the page 
}

If the Registration status is Pending, it should be changed to Attended. There is one registration in the 7 that has a status of Cancelled. The values that get stored back show that it should be ignored, but it is being changed to Attended.

Note... the registration status field is Workshop_Cancelled__c

I also wondered if there is a way to put this in an array and then post all seven updates back at once, as I believe I am handling them one at a time... could this be part of the problem?

Thanks,

...Dave






Saurabh DhobleSaurabh Dhoble
The problem is with this block - 
if (rstat[i] == "Pending"){ // If the registration status is Pending , set to process 
 regstat1 = "process"; 
 _Registration.Workshop_Cancelled__c="Attended"; 
 }
The _Registration.Workshop_Cancelled__c property is set to "Attended" once, but is never reset again. Ideally, you should initialize a new instance of the _Registration object inside the FOR loop -

for (var i = 0;i<length;i++) {//process each registration 
   var _Registration = new sforce.SObject("Registration__c");
   _Registration.Id = reg[i]; // get the record id for the update

This will ensure that the Workshop_Cancelled__c is set to Blank everytime the loop runs.

Apart from the above, I have a serious issue with what you are trying to do here - as I understand it, you want to update the workshop cancelled status for all "child" registrations when the status for a "parent" opportunity changes. This is the perfect use case for a trigger on your Opportunity object - you don't need to do handle all this in Javascript.

Lastly, please mark this as answer if this has answered your question.

dburnistondburniston
Thanks for pointing that out.

The reason I was doing it this way rather than a trigger is as follows:

The registrations come in over a period of time and are added, up to the date that the workshop starts. During that period the status can change from Pending to another status and is manually changed by the sales rep.

When the workshop starts, they click the button to change the Opportunity Stage and have it update the registration statuses for any that are Pending and leave the rest as they are.

For our public workshops, there is a change in the stage when this is to happen. For our Onsite workshops, the Stage doesn't change (the script is basically writing the same stage as the Opportunity is already set to - they just want to update the registration status, so I didn't think a trigger would be a good solution. 

Let me test your recommended change!

Regards,

...Dave

Saurabh DhobleSaurabh Dhoble
Okay, I see. If I were you, I'd have still tried to do it via a trigger, maybe seting a special field for the "Onsite" workshops that would then update the registrations. But that's okay, I just have more preference to do stuff in Apex while I can.

BTW, please mark this as answer if the solution works for you. Can't hurt to get some points on my profile :)
dburnistondburniston
Thanks. it appears to be working correctly now. I will definitely look at a trigger to see if it can do the job. I really appreciate the help!