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
transforcertransforcer 

Why the Opportunity Record Type does not change?

Hello,

I am new to an installation which has been customized with S-controls for many years. It appears that some standard functionality has stopped working, and I need tips about how to debug the situation. We are certain that this used to work.

The scenario is this: Click a recent Opportunity. It opens in "read mode". The (standard) Record-Type field is displayed near the top :  

Opportunity Record TypeChannel [Change]

 The "Change" link seems standard. The HTML for it is:

<a href="/setup/ui/recordtypeselect.jsp?id=006000000084SsJ&amp;retURL=%2F006000000084SsJ">[Change]</a>

I click "[Change]" and the expected screen appears:

Select New Record Type

Transfer this Opportunity    test
Current Record Type           Channel
*New Record Type              (a dropdown is here) 

The "Continue" and "Cancel" buttons on this screen seem standard:

  <input value="Continue"  class="btn" title="Continue" name="save" type="submit" />

  <input value="Cancel"  class="btn" title="Cancel" name="cancel" type="submit" />

and there is nothing odd about the <Form>:

  <form  action="/setup/ui/recordtypeselect.jsp" id="editPage" method="post" name="editPage"

    onsubmit="if (window.ffInAlert) { return false; }" >

 

After I select "Direct", I click "Continue". The screen redraws mostly blank, then it redraws again and it displays the same Opportunity, in Edit mode. But the Record Type is now Channel - it did not change to Direct!

 

This used to work fine.

 

1) How can I tell which S-Controls are on the Opportunity page layout? Can one of them change the Record Type while the page is loading?

2) Could Workflow rules possibly run after clicking "Continue"?

3) Could the change be failing validation? No error message displays.

4) How should I analyze and debug this situation? 

 

TIA!

 

 

Best Answer chosen by Admin (Salesforce Developers) 
sfdcfoxsfdcfox

I guess you'll have to read the record type from the URL... or you could just bypass the selection screen (it's now an option to do this when you provide your own override). Alternatively, going to a Visualforce page would pass the new value into the page. That just happens to be a limitation of S-Controls, and one of the many reasons why S-Controls were marked as outdated. They are relatively hard to use compared to Visualforce.

All Answers

sfdcfoxsfdcfox

Page overrides are denoted in Setup > Customize > Opportunities > Buttons and Links. From your description, it appears that there is an override on the Edit page, and this override is ignoring the RecordType parameter, thus causing it to be lost when redirected to the standard Edit page (probably done via {!URLFOR($Action.Opportunity.Edit,Opportunity.Id,null,true} or StandardController.edit() ).

 

If it used to work okay, but now it doesn't, most likely it has to do with a change in the name of the parameter used for Record Types, or a new record type was added that the S-Control didn't account for (bad programming practice).

 

1) Record types can be changed by S-Controls or Visualforce pages. They need only set the appropriate parameter.

2) No, workflow rules only run when a save is executed. You can't run a workflow rule after the record type selection page before saving.

3) Not likely. You'd get an error message, first of all, and secondly, validation rules only run on save actions, so unless they are providing a save=x parameter to the page, no validation rules would be running.

4) From your description, I would be nearly 100% certain that a Visualforce page or S-Control is the issue. Can you post your findings here?

transforcertransforcer

Thanks! Your hints enabled me to find the problem, I think (not tested yet).

 

I went to that Buttons&Links page. In the upper section (Standard) the line for Label=Edit, Name=Edit has "Overridden" checked. The "Display" column states: "Restrict Opportunity Edit (Custom S-Control)".

 

In the lower section (Custom), we have

 Edit* / Custom_Edit / Detail Page Button / Display in existing window with sidebar / Custom S-Control / Restrict Opportunity Edit

 

The Edit button on most Opportunity page layouts is replaced by our "Edit*" custom button, which also is the same S-Control.  

 

I am unclear why we need both of these things.

 

If I am correct, here is the solution:

After I click "Continue", the S-Control loads, because it overrides the standard Edit link. The JS function in the S-Control's <Header> section then runs , via <Body onLoad="init()"> . This would explain the repeated re-draw - first the S-Control itself loads, then when init() runs, it loads a different URL.

 

In testing, we showed that the misbehavior does occur when the Opp is not a "verified win", as per our custom field that is used in the line          StageVerified = '{!Opportunity.Stage_Verified_as_Win__c}';  

When StageVerified  is false, control drops to the "bottom" block just before the script's end:

else
{
window.parent.location.href = "/" + OpptyId +"/e?nooverride=1&retURL=%2F"+ OpptyId +'&source=edit';
}

I am guessing that using this deprecated (actually, never-supported) technique, the standard edit page for the Opp is brought up, instead of the override, and that is what we see after the second redraw completes.

 

So, I just need the correct parameter that sets the record-type in that final URL. At the start of init() it has:

var recType = '{!Opportunity.RecordTypeId}';
Based on other forum messages, it seems that it needs &RecordType=rectype . So the final block would be

{
window.parent.location.href = "/" + OpptyId +"/e?nooverride=1&retURL=%2F"+ OpptyId +'&source=edit&RecordType=' + recType;
}

Here is the whole S-Control (without the above mod):

 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script type="text/javascript" src="/js/functions.js"></script>
<script src="/soap/ajax/12.0/connection.js"></script>
<script type="text/javascript" src="/static/102207/js/functions.js"></script>
<script src="/dJS/en/1208068638000/library.js" type="text/javascript"></script>
<script type="text/javascript" src="/static/102207/desktop/desktopAjax.js"></script>
<script type="text/javascript">
function init()
{
var recordType = '{!Opportunity.RecordTypeId}';
var StageVerified = '{!Opportunity.Stage_Verified_as_Win__c}';
var UserProfile = '{!User.ProfileId}';
var OpptyId = '{!Opportunity.Id}';

if(StageVerified == 1)
{
if(UserProfile == '00e00000006omJE' || UserProfile == '00e00000006zBLd' || UserProfile == '00e80000001BIFf' || UserProfile == '00e80000000leRp' || UserProfile == '00e00000006xOca')
{
if(recordType == '01200000000CcfJ' || recordType == '01280000000AuPC' || recordType == '01280000000At6B' || recordType == '01200000000CcfE' || recordType == '01200000000Ccf9' || recordType == '01200000000CcfP' || recordType == '01200000000Ccep')
{
window.parent.location.href = "/" + OpptyId +"/e?nooverride=1&retURL=%2F"+ OpptyId +'&source=edit';
}
else
{
alert('The opportunity cannot be edited. It has been booked and therefore locked.');
window.parent.location.href = "/" + OpptyId;
}
}
else
{
//window.parent.location.href = "/" + OpptyId +"/e?nooverride=1&retURL=%2F"+ OpptyId +'&source=edit';
alert('The opportunity cannot be edited. It has been booked and therefore locked.');
window.parent.location.href = "/" + OpptyId;

}
}
else
{
window.parent.location.href = "/" + OpptyId +"/e?nooverride=1&retURL=%2F"+ OpptyId +'&source=edit';
}
}
</script>
</head>
<body onload="init();">
</body>
</html>

 

transforcertransforcer

I implemented this idea but it does not work. The problem is, when it gets the Opp's record-type in the line

         var recordType = '{!Opportunity.RecordTypeId}';

it gets the unchanged value , not the value that was selected in the select-new-record-type screen. So, when you add that recordtype to the URL, you are just setting it to the way it already was.

 

The select-new-record-type screen is displayed by the URL

        ....../setup/ui/recordtypeselect.jsp

and i see no way to override that screen.

 

This all used to work. It seems that in earlier releases the select-new-record-type screen modified the Opportunity's recordtype, but now,  it does not. 

sfdcfoxsfdcfox

I guess you'll have to read the record type from the URL... or you could just bypass the selection screen (it's now an option to do this when you provide your own override). Alternatively, going to a Visualforce page would pass the new value into the page. That just happens to be a limitation of S-Controls, and one of the many reasons why S-Controls were marked as outdated. They are relatively hard to use compared to Visualforce.

This was selected as the best answer
transforcertransforcer

I wish I had read your reply before I worked out the same conclusion! TYVM.

 

I ask myself: why did this work at all in the past? I surmise that the "Set New Record Type" jsp used to save changes to the stored Opportunity when one clicked "Continue", but now, it merely passes the changes to the Edit Opportunity page (or its override) in the URL.

 

Regardless, the point that you make is the one to take away. Restating it from the viewpoint of those sites where the new skills are not yet in use: if old S-controls that do "URL-hacking" start "forgetting" data, check whether that data is now passed to them in their URL, and whether they are passing it on in the URLs they build.

 

Here is the modified, working code.

 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script type="text/javascript" src="/js/functions.js"></script>
<script src="/soap/ajax/12.0/connection.js"></script>
<script type="text/javascript" src="/static/102207/js/functions.js"></script>
<script src="/dJS/en/1208068638000/library.js" type="text/javascript"></script>
<script type="text/javascript" src="/static/102207/desktop/desktopAjax.js"></script>
<script type="text/javascript">
function init()
{
var recordType = '{!Opportunity.RecordTypeId}';
var StageVerified = '{!Opportunity.Stage_Verified_as_Win__c}';
var UserProfile = '{!User.ProfileId}';
var OpptyId = '{!Opportunity.Id}';
var rteq = 'recordtype=';
var URLin = window.parent.location.href;
var LenID = recordType.length;
var newTypID = '';

// Point to the &recordtype= clause in the current page's URL
var Where = URLin.toLowerCase().lastIndexOf(rteq);

// Incoming URL will contain &RecordType=nnnnnn if we are coming from the "Select New Record Type" screen
// or any other that specifies a record-type in the URL
if( Where != -1)
{
// Point past the clause to the value that follows the equal sign
Where = Where + rteq.length;
// Extract the ID that was passed in the URL. Assume that all IDs are the same length.
newTypID = URLin.substring( Where, Where + LenID );
newTypID = '&RecordType=' + newTypID;
}

if(StageVerified == 1)
{
if(UserProfile == '00e00000006omJE' || UserProfile == '00e00000006zBLd' || UserProfile == '00e80000001BIFf' || UserProfile == '00e80000000leRp' || UserProfile == '00e00000006xOca')
{
if(recordType == '01200000000CcfJ' || recordType == '01280000000AuPC' || recordType == '01280000000At6B' || recordType == '01200000000CcfE' || recordType == '01200000000Ccf9' || recordType == '01200000000CcfP' || recordType == '01200000000Ccep')
{
window.parent.location.href = "/" + OpptyId +"/e?nooverride=1&retURL=%2F"+ OpptyId +'&source=edit' + newTypID ;
}
else
{
alert('The opportunity cannot be edited. It has been booked and therefore locked.');
window.parent.location.href = "/" + OpptyId;
}
}
else
{
alert('The opportunity cannot be edited. It has been booked and therefore locked.');
window.parent.location.href = "/" + OpptyId;
}
}
else
{
window.parent.location.href = "/" + OpptyId +"/e?nooverride=1&retURL=%2F"+ OpptyId +'&source=edit' + newTypID ;
}
}
</script>
</head>
<body onload="init();">
</body>
</html>

 

The main point of our S-Control is to prevent editing of certain opportunities, by certain people, once the custom field "Stage Verified As Win" has been set. There are easier ways to do this today, but way back when, this technique was coded by SFDC's own personnel.