• FGNY
  • NEWBIE
  • 0 Points
  • Member since 2007

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 7
    Questions
  • 11
    Replies

Hello,

Despite creating S-Controls for our organization for several years we just started to create our first Apex Triggers and immediatly run into the "Test Classes"-problem. We created the following simple trigger which is working in the Sandbox but cannot transfer it to Production Environment without a Test Class.

 

When a user tries to set the Opportunity Stage to "Won", the trigger checks if there is a quotation file among opportunity attachments and if not, prevents saving the record with an error message. Here is the code:

 

trigger CheckOppAttachments on Opportunity (before update) 
{
    if (trigger.new[0].StageName == 'Closed Won')
    {
        Boolean pdf = false;
        Boolean pdfloop = false;
    
        Opportunity opp = trigger.new[0];
        Attachment[] atts = [SELECT Name FROM Attachment WHERE ParentId =: opp.Id];
        for (Integer i = 0; i < atts.size(); i++) 
        {
            pdfloop = atts[i].Name.contains(opp.Quotation_No__c);
            if (pdfloop)
            {
            pdf=true;
	    }
        }
		
	if (pdf)
	{}
	else
	{
	     opp.addError('The Stage can not be set to "Won" as long Quotation is not attached');
	}
    }
}   

 

Any example of a test class for such a trigger would be appreciated.

 

 

 

 

  • July 29, 2012
  • Like
  • 0
Salesforce Function "View Hierarchy" in the Account layout is very useful for displaying Account/ParentAccount relationship tree but sadly the displayed account field columns are not configurable. We built the following function which mimick the Salesforce hierarchy view performing "No. of hierarchy levels" +1 queries to retrieve the necessary data:

Code:
<script src="/soap/ajax/10.0/connection.js"></script>
<script type="text/javascript">

var level=1;
var space='        ';
var ac;
var accname="'" + "{!Account.Id}" + "'";

function first()//Retrieves data of highest level account
{
var ergo = sforce.connection.query("SELECT Account.Id, Account.Name, Account.Site, Account.Line_Name__c FROM Account WHERE Id =" + accname);  
rec = ergo.getArray("records");
document.write('<tr class="dataRow even"><th class="dataCell" scope="row"><a nowrap="nowrap" href="/' + rec[0].Id + '">' + rec[0].Name + '<\/a>
<\/th><td class="dataCell">' + rec[0].Site + '<\/td><td class="dataCell">' + rec[0].Line_Name__c + '<\/td><\/td><\/tr>'); function rekursiv(accid)//Runs once for each hierarchy level { var erg = sforce.connection.query("SELECT Account.Id, Account.Name, Account.Site, Account.Line_Name__c FROM Account WHERE ParentId IN (" + accid + ")"); records = erg.getArray("records"); ac=''; for (var j=0; j<level; j++) { space=space.concat(' '); } for(var i=0; i<records.length; i++) { var acc = records[i]; ac = ac.concat(",'" + acc.Id + "'"); document.write('<tr class="dataRow even"><th class="dataCell" scope="row">' + space + '<a nowrap="nowrap" href="/' + acc.Id + '">' + acc.Name + '<\/a>
<\/th><td class="dataCell">' + acc.Site + '<\/td><td class="dataCell">' + acc.Line_Name__c + '<\/td><\/tr>'); } if(ac!='')//If lower level Accounts found { level++; rekursiv(ac.slice(1)); } } rekursiv(accname); } </script>

 
However this function builds the following view


While it should be



It shows accounts grouped by their hierarchy level not by  their parent accounts and we have no idea how to correct it.
Is there a way to change the function to work properly?

Possibly it is necessary to pull an array of all Accounts in the hierarchy first, then sort them from each parent node down, and only afterwards generate output. But we failed to build a recursive function which sorts an array of accounts by their parent.



Message Edited by FGNY on 08-27-2008 02:32 AM
  • August 27, 2008
  • Like
  • 0
We use hierarchies in our SF organization with accounts related to higher level accounts by ParentAcccount relationship. But we need informations of all objects from child accounty of any level which are under a selected Account

For example: This query provides all opportunities of an Account:
Code:
sforce.connection.query("SELECT Id, Name, Amount FROM Oportunity 
WHERE Account.Id = " + '{!Account.Id}');

When I want all opportunities from direct child accounts of a defined parent account i can retrieve it this way:
Code:
sforce.connection.query("SELECT Id, Name, Amount FROM Oportunity 
WHERE Account.ParentId = " + '{!Account.Id}');

 However I need a query which retrieves all opportunities from an account + all opportunities of child acconts, regardless if direct  childs or "childs of childs". Is it a way to accomplish it



  • August 13, 2008
  • Like
  • 0
Hello, I have the following problem: I made an S-Control which is triggered by a button in custom object "Repair" and redirects to "new opportunity" edit screen with some values prepopulated from the Repair. However we use record types in opportunities and each time I have to select the record type first before the edit page appears (despite all opportunities created from Repairs should have the same record type). Is it possible to pass the record type in the URL, so the manual record type selection will be skipped? Here is the code:


Code:
var newUrl = "{!URLFOR($Action.Opportunity.New,null,[saveURL=URLFOR($SControl.Update_Repair, Repair__c.Id), retURL = $Request.retURL] ,true)}";

newUrl = newUrl + "&opp3=" + "Repair for " + {!Repair__c.Name} + "&00N200000003EQc=" + 'Repair' + "&opp4=" + "{!Repair__c.Account__c}";
window.parent.location.replace(newUrl);

 

  • August 11, 2008
  • Like
  • 0
Is there a possibility to update changed Saleforce objects at once? I wrote the following code which updates a field in a number of accounts, however the process takes much time, since each account is individually updated to salesforce after the change. Is there a possibility to change the objects first and then update them to salesforce at once.
Code:
var accounts = sforce.connection.query("SELECT Id, Name, Prospecting_Opps__c FROM Account WHERE Prospecting_Opps__c=true");
var rec = accounts.getArray("records");
alert(accs.size);
var j =0;
while (j<accs.size)
{
checkbox(rec[j].Id);
j++;
}

function checkbox(Accid)
{
var Acc = new sforce.SObject("Account");
Acc ["Id"] = Accid;
Acc ["Prospecting_Opps__c"] = "true";
sforce.connection.update([Acc]);
}

 
new.sforce.sObject returns an array and sforce.connection.update updates it to salesforce. Therefore those arrays need to be wrapped up in a structure like an "array of arrays". C++ for example knows two dimensional arrays caled matrix, but  as far I know Javascript don't know such element.
  • December 10, 2007
  • Like
  • 0
I want to create an S-Control which retrieves project milestones (dates) from an asset and compares these dates with today's date or "Today - x days". But the following code does not work.
Code:
var ident= sforce.connection.query("SELECT Id, PurchaseDate , Delivery_Date__c, InstallDate, Acceptance_Date__c, Warranty_End_Date__c, ProjectState FROM Asset WHERE Type__c IN ('SIS' , 'WIS') AND Asset_Autostatus__c NOT IN ('Out of Operation' , 'Out of Warranty' )");
var irecords = ident.getArray("records");
int i=0;
while (i<300) { if (irecords[i].Warranty_End_Date__c > {!Today}) {irecords[i].ProjectState = "Out of warranty";} if (Acceptance_Date__c != null AND InstallDate < {!Today}-60) {irecords[i].ProjectState = "Factory Acceptance overdue";} i++;}
The first problem is the script fails at {IToday} and the second is that Today will be returned in european dd.mm.yyyy format while project milestones are returned in yyyy-mm-dd format.



Message Edited by FGNY on 11-26-2007 01:57 AM

  • November 26, 2007
  • Like
  • 0
I want to have a search field on the SalesForce home page (home tab) where one can enter a case number and after clicking on Search-button being redirected to this case. However something in the following code is wrong, the variable "ident" don't take the CaseID but something else. And I'm also not sure if the URL -creation statement is correct.
Code:
<html>
<head>
    <script src="/soap/ajax/10.0/connection.js"></script>
    <script language="JavaScript">

        function findCase(number) 
       {
        var ident = sforce.connection.query("Select Id from Case where CaseNumber  = '" + name + "' limit 1");
        window.parent.location.href = "https://emea.salesforce.com/{ident}";
        return false;
        }
    </script>
</head>
<body>
<div>
    <FORM NAME="myform" onSubmit="return findCase(this)">
        Enter Case Number: <BR>
        <INPUT TYPE="text" NAME="inputbox" size=10 VALUE=""/>
        <INPUT TYPE="SUBMIT" NAME="button" Value="Search Case"/><br>
    </FORM>
</div>
</body>
</html>

 
The other problem would be the integration of this S-Control in the home tab. If I enter this code in setup->customize->home->home page components->new, the script will be removed after save. But apparently it will work through a frame
Code:
<IFRAME src="/servlet/servlet.Integration—lid=xxxxxxxxxxxxxxx&amp;ic=1" 
frameBorder=0 width="100%" height=150></IFRAME>

 with xxxxxxxxxxxxxxx being the S-Control ID. However in this case the found case will be displayed in the frame, while it should be displayed in the standard view (or even better in a new register tab). Can this be solved?


 



Message Edited by FGNY on 11-07-2007 09:10 AM

  • November 07, 2007
  • Like
  • 0

Hello,

Despite creating S-Controls for our organization for several years we just started to create our first Apex Triggers and immediatly run into the "Test Classes"-problem. We created the following simple trigger which is working in the Sandbox but cannot transfer it to Production Environment without a Test Class.

 

When a user tries to set the Opportunity Stage to "Won", the trigger checks if there is a quotation file among opportunity attachments and if not, prevents saving the record with an error message. Here is the code:

 

trigger CheckOppAttachments on Opportunity (before update) 
{
    if (trigger.new[0].StageName == 'Closed Won')
    {
        Boolean pdf = false;
        Boolean pdfloop = false;
    
        Opportunity opp = trigger.new[0];
        Attachment[] atts = [SELECT Name FROM Attachment WHERE ParentId =: opp.Id];
        for (Integer i = 0; i < atts.size(); i++) 
        {
            pdfloop = atts[i].Name.contains(opp.Quotation_No__c);
            if (pdfloop)
            {
            pdf=true;
	    }
        }
		
	if (pdf)
	{}
	else
	{
	     opp.addError('The Stage can not be set to "Won" as long Quotation is not attached');
	}
    }
}   

 

Any example of a test class for such a trigger would be appreciated.

 

 

 

 

  • July 29, 2012
  • Like
  • 0
Salesforce Function "View Hierarchy" in the Account layout is very useful for displaying Account/ParentAccount relationship tree but sadly the displayed account field columns are not configurable. We built the following function which mimick the Salesforce hierarchy view performing "No. of hierarchy levels" +1 queries to retrieve the necessary data:

Code:
<script src="/soap/ajax/10.0/connection.js"></script>
<script type="text/javascript">

var level=1;
var space='        ';
var ac;
var accname="'" + "{!Account.Id}" + "'";

function first()//Retrieves data of highest level account
{
var ergo = sforce.connection.query("SELECT Account.Id, Account.Name, Account.Site, Account.Line_Name__c FROM Account WHERE Id =" + accname);  
rec = ergo.getArray("records");
document.write('<tr class="dataRow even"><th class="dataCell" scope="row"><a nowrap="nowrap" href="/' + rec[0].Id + '">' + rec[0].Name + '<\/a>
<\/th><td class="dataCell">' + rec[0].Site + '<\/td><td class="dataCell">' + rec[0].Line_Name__c + '<\/td><\/td><\/tr>'); function rekursiv(accid)//Runs once for each hierarchy level { var erg = sforce.connection.query("SELECT Account.Id, Account.Name, Account.Site, Account.Line_Name__c FROM Account WHERE ParentId IN (" + accid + ")"); records = erg.getArray("records"); ac=''; for (var j=0; j<level; j++) { space=space.concat(' '); } for(var i=0; i<records.length; i++) { var acc = records[i]; ac = ac.concat(",'" + acc.Id + "'"); document.write('<tr class="dataRow even"><th class="dataCell" scope="row">' + space + '<a nowrap="nowrap" href="/' + acc.Id + '">' + acc.Name + '<\/a>
<\/th><td class="dataCell">' + acc.Site + '<\/td><td class="dataCell">' + acc.Line_Name__c + '<\/td><\/tr>'); } if(ac!='')//If lower level Accounts found { level++; rekursiv(ac.slice(1)); } } rekursiv(accname); } </script>

 
However this function builds the following view


While it should be



It shows accounts grouped by their hierarchy level not by  their parent accounts and we have no idea how to correct it.
Is there a way to change the function to work properly?

Possibly it is necessary to pull an array of all Accounts in the hierarchy first, then sort them from each parent node down, and only afterwards generate output. But we failed to build a recursive function which sorts an array of accounts by their parent.



Message Edited by FGNY on 08-27-2008 02:32 AM
  • August 27, 2008
  • Like
  • 0
Hello, I have the following problem: I made an S-Control which is triggered by a button in custom object "Repair" and redirects to "new opportunity" edit screen with some values prepopulated from the Repair. However we use record types in opportunities and each time I have to select the record type first before the edit page appears (despite all opportunities created from Repairs should have the same record type). Is it possible to pass the record type in the URL, so the manual record type selection will be skipped? Here is the code:


Code:
var newUrl = "{!URLFOR($Action.Opportunity.New,null,[saveURL=URLFOR($SControl.Update_Repair, Repair__c.Id), retURL = $Request.retURL] ,true)}";

newUrl = newUrl + "&opp3=" + "Repair for " + {!Repair__c.Name} + "&00N200000003EQc=" + 'Repair' + "&opp4=" + "{!Repair__c.Account__c}";
window.parent.location.replace(newUrl);

 

  • August 11, 2008
  • Like
  • 0
Is there a possibility to update changed Saleforce objects at once? I wrote the following code which updates a field in a number of accounts, however the process takes much time, since each account is individually updated to salesforce after the change. Is there a possibility to change the objects first and then update them to salesforce at once.
Code:
var accounts = sforce.connection.query("SELECT Id, Name, Prospecting_Opps__c FROM Account WHERE Prospecting_Opps__c=true");
var rec = accounts.getArray("records");
alert(accs.size);
var j =0;
while (j<accs.size)
{
checkbox(rec[j].Id);
j++;
}

function checkbox(Accid)
{
var Acc = new sforce.SObject("Account");
Acc ["Id"] = Accid;
Acc ["Prospecting_Opps__c"] = "true";
sforce.connection.update([Acc]);
}

 
new.sforce.sObject returns an array and sforce.connection.update updates it to salesforce. Therefore those arrays need to be wrapped up in a structure like an "array of arrays". C++ for example knows two dimensional arrays caled matrix, but  as far I know Javascript don't know such element.
  • December 10, 2007
  • Like
  • 0
I want to create an S-Control which retrieves project milestones (dates) from an asset and compares these dates with today's date or "Today - x days". But the following code does not work.
Code:
var ident= sforce.connection.query("SELECT Id, PurchaseDate , Delivery_Date__c, InstallDate, Acceptance_Date__c, Warranty_End_Date__c, ProjectState FROM Asset WHERE Type__c IN ('SIS' , 'WIS') AND Asset_Autostatus__c NOT IN ('Out of Operation' , 'Out of Warranty' )");
var irecords = ident.getArray("records");
int i=0;
while (i<300) { if (irecords[i].Warranty_End_Date__c > {!Today}) {irecords[i].ProjectState = "Out of warranty";} if (Acceptance_Date__c != null AND InstallDate < {!Today}-60) {irecords[i].ProjectState = "Factory Acceptance overdue";} i++;}
The first problem is the script fails at {IToday} and the second is that Today will be returned in european dd.mm.yyyy format while project milestones are returned in yyyy-mm-dd format.



Message Edited by FGNY on 11-26-2007 01:57 AM

  • November 26, 2007
  • Like
  • 0
I want to have a search field on the SalesForce home page (home tab) where one can enter a case number and after clicking on Search-button being redirected to this case. However something in the following code is wrong, the variable "ident" don't take the CaseID but something else. And I'm also not sure if the URL -creation statement is correct.
Code:
<html>
<head>
    <script src="/soap/ajax/10.0/connection.js"></script>
    <script language="JavaScript">

        function findCase(number) 
       {
        var ident = sforce.connection.query("Select Id from Case where CaseNumber  = '" + name + "' limit 1");
        window.parent.location.href = "https://emea.salesforce.com/{ident}";
        return false;
        }
    </script>
</head>
<body>
<div>
    <FORM NAME="myform" onSubmit="return findCase(this)">
        Enter Case Number: <BR>
        <INPUT TYPE="text" NAME="inputbox" size=10 VALUE=""/>
        <INPUT TYPE="SUBMIT" NAME="button" Value="Search Case"/><br>
    </FORM>
</div>
</body>
</html>

 
The other problem would be the integration of this S-Control in the home tab. If I enter this code in setup->customize->home->home page components->new, the script will be removed after save. But apparently it will work through a frame
Code:
<IFRAME src="/servlet/servlet.Integration—lid=xxxxxxxxxxxxxxx&amp;ic=1" 
frameBorder=0 width="100%" height=150></IFRAME>

 with xxxxxxxxxxxxxxx being the S-Control ID. However in this case the found case will be displayed in the frame, while it should be displayed in the standard view (or even better in a new register tab). Can this be solved?


 



Message Edited by FGNY on 11-07-2007 09:10 AM

  • November 07, 2007
  • Like
  • 0
There is a new user showing up through the API, but not visible in the UI.

(This can be recreated via sforce explorer)

If I query the user list via the webservice, I get all my regular users, but now I am getting an additional on.  Its name is "Salesforce Administrator".  It says it was just created 8/3/07 (even though I have had my account for well over a year).  It has a license type of "BlackTab User". 

Can anyone help me out with what this user is?  And, is there an easy way to filter it out of my query?  (I want to be able to only get users that are available in the UI in my query).

Thanks
  • August 09, 2007
  • Like
  • 0