• Xmike
  • NEWBIE
  • 0 Points
  • Member since 2005

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 1
    Questions
  • 5
    Replies
I have been starting to work with triggers and this one works... as long as you are not bulk inserting. My issue is that we have a custom child object to Cases calles SVC WO and grandchild object called FS Labor. When the labor object is inserted or updated, it needs to update both the SVC WO and the Case depending on logic. The logic is working fine. I know that the problem is that I am trying to do updates within the for loops. If I try to get them out, I no longer have access to the variables described in the loop.

trigger StatUpd on FS_Labor__c (after insert, after update) { List<Id> CasesToUpdate = new List<Id>{}; List<Id> WOsToUpdate = new List<Id>{}; // Find cases and WOs to update for(FS_Labor__c fsl : Trigger.new){ CasesToUpdate.add(fsl.CaseId__c); WOsToUpdate.add(fsl.Service_WO__c); // Update the WOs Field_Service_WO__c[] wos = [select id, Arrival_Time_on_Site__c, Date_and_Time_Back_Online__c from Field_Service_WO__c where id in:WOsToUpdate]; for(Field_Service_WO__c wo: wos){ IF(wo.Arrival_Time_on_Site__c == null || (Trigger.isupdate && wo.Arrival_Time_on_Site__c == Trigger.oldMap.get(fsl.id).Start_Time__c)) wo.Arrival_Time_on_Site__c = fsl.Start_Time__c; IF(fsl.Final_Status__c == 'Functional') wo.Date_and_Time_Back_Online__c = fsl.Stop_Time__c; update wo; // Update the cases Case[] cases = [select id, Service_Status__c from Case where id in :CasesToUpdate]; for(Case c: cases){ If(wo.Date_and_Time_Back_Online__c == null || fsl.Stop_Time__c >= wo.Date_and_Time_Back_Online__c) c.Service_Status__c = fsl.Final_Status__c; update c; } } } }

 

  • April 11, 2009
  • Like
  • 0
    I'm using the leadDuplicatePreventer example in the cookbook to prevent a user from duplicating a product/serial number in assets. I've gotten it to work with only checking for unique serial number, but i'm stuck on getting it to check the Product2Id field as well. Could use a helping hand :)

trigger assetPreventDuplicateSerial on Asset (before insert, before update) {
    Map<String, Asset> assetMap = new Map< String, Asset>();
    for(Asset asset : System.Trigger.new){
    if((asset.SerialNumber != null) &&
        (System.Trigger.isInsert || (asset.SerialNumber != System.Trigger.oldMap.get(asset.id).SerialNumber))) {
            if (assetMap.containsKey(asset.SerialNumber) && assetMap.containsKey(asset.Product2ID)){
                asset.SerialNumber.addError('Another Asset has the same serial number');
            }
            else{
                assetMap.put(asset.SerialNumber,asset);
            }
        }
    }
   
    for(Asset asset : [SELECT SerialNumber FROM Asset
                        WHERE SerialNumber IN :assetMap.KeySet() AND
                        Asset.Product2Id IN :assetMap.KeySet()]) {
                            Asset newAsset = assetMap.get(asset.SerialNumber);
                            newAsset.SerialNumber.addError('An asset with this serial number already exists.');
                        }
       
   
}
Hi:

Thank you for attending one of my hands-on sessions on  S-Controls.
I hope Dreamforce was a great experience for you.

I have set up this discussion for class members to post and answer questions you might have after Dreamforce.

Please add your question under this post and a class participant or myself will answer you.

I will monitor this post for 2 weeks after Dreamforce.

Thank you

Here is the source:

Code:
<html>
<head>
<!-- Answers this is the working scontrol for class -->
<!-- author Michael Fullmore Salesforce.com -->
<!-- version .1 8/21/2007 -->
<!-- version 1.0 8/28/2007 -->

 <!-- addes the salesforce.com css file (look and feel) -->
 <link href="/dCSS/Theme2/default/common.css" media="handheld,print,projection,screen,tty,tv" rel="stylesheet" type="text/css" />
 
 <!-- adding my own styles to this scontrol -->
 <style type="text/css">
  .edit{display:none;}
  p{width:70%}
 </style>
 
    <!-- these two script tags add the salesforce.com AJAX API and are required to "talk to salesforce" -->
    <script type="text/javascript" src="/js/functions.js"></script>
    <script src="/soap/ajax/10.0/connection.js"></script>
    
    <!-- this script tag starts our code, you can have as many script tags in your file as needed. we only need 1 for this demo -->
    <script type="text/javascript">
    
    //create the oppty object
    var opp = {id:"{!Opportunity.Id}", stage:"{!Opportunity.StageName}", nextStep:"{!Opportunity.NextStep}", description:"{!Opportunity.Description}"};
    
 //create an array of stages that we want to lock
    var lockedStages = ["Perception Analysis","Proposal/Price Quote","Negotiation/Review"," Closed Won","Closed Lost"];
    
    //checking to see if the user has access or not
    function doesUserHaveAccess(){
     //this is the first AJAX call, nice! Bonus points, what is it doing—
     var user = sforce.connection.getUserInfo();
     
     //get the profile name
     var profileNameQuery = sforce.connection.query("select Name from Profile where Id = '" + user.profileId + "'");
     var profileNameRecords = profileNameQuery.getArray("records");
     var profileName = profileNameRecords[0].Name;
     
     //next check if the user is locked out of oppty
     if(profileName == 'System Administrator'){ //adding TEST to the system administrator string to test with sys admin

      //using URLFOR to "skip over the override the second time around.
      window.parent.location.href = "{!URLFOR($Action.Opportunity.Edit, Opportunity.Id,[retURL=URLFOR($Action.Opportunity.View, Opportunity.Id)],true)}";
     }else{
           
      //if the user is not in the admin user group then we show the edit page for them. This page just gives us access to 3 fields on the opportunity
      showPage();
     }
    }
    
    function showPage(){
     document.getElementById('edit').style.display = 'block';
     document.getElementById('next').value = opp.nextStep;
     document.getElementById('des').value = opp.description;
    }
    
    //custom edit screen button actions
    function saveEdit(){
     //create an opportunity object
     var o = new sforce.SObject("Opportunity");
     
     //fill the opportunity SObject with data
      o.Id = opp.id;
      o.NextStep = document.getElementById('next').value;
      o.Description = document.getElementById('des').value;
      
     //save the SObject to salesforce, using the AJAX Tool Kit
     var saveO = sforce.connection.update([o]);
      if(saveO[0].getBoolean("success") == false){
       error(saveO[0]);
      }
     //go back to the opportunity
     window.parent.location.href = "/" + opp.id;
    }
    
    function cancelEdit(){
     window.parent.location.href = "/" + opp.id;
    }
    
    //help error function
    function error(e){
     alert("There is an error\n\n" + e);
    }
    
    //where the page starts it's loading
    function initPage(){
    
     var isLocked = false;
     //this function starts the process, every scontrol needs to start somewhere, and I like using initPage
     
     //first thing we need to do is check to see what stage the oppty is in.
     for(i=0; i<lockedStages.length; i++){
      if(opp.stage == lockedStages[i]){
       //if it's in a "locked" stage then we go and see if the user has access.
       isLocked = true;
       break;
      }
     }
     if(isLocked){
      doesUserHaveAccess();
     }else{
   //if the oppty is not is the "locked" stages then put up the normal edit page
      window.parent.location.href = "{!URLFOR($Action.Opportunity.Edit, Opportunity.Id,[retURL=URLFOR($Action.Opportunity.View, Opportunity.Id)],true)}";     
     }
    }
    
/****************************************************************************************************
**what's next–                      *
**Try adding a stage advancer, something that puts the opportunity in the next stage for the reps *
**Add your own fields                    *
**Display read only fields                   *
****************************************************************************************************/ 
    
    </script>
</head>
<body onload="initPage();" class="opportunity overviewPage">
 <div id="edit" class="edit">
  <div class=bPageTitle>
   <div class="ptBody secondaryPalette">
    <div class="content">
     <img class="pageTitleIcon" title="Opportunity" alt="Opportunity" src="/s.gif"/>
      <h1 class="pageType">Opportunity Edit (Custom)<span class="titleSeparatingColon">:</span></h1>
      <h2 class="pageDescription">{!Opportunity.Name}</h2>
      <br>
    </div>
   </div>
  </div>
  <div class="bPageBlock secondaryPalette">
   <div class="pbBody">
    <div class="pbSubsection">
     <p>This Opportunity is in a stage that is locked by your company. The only fields that you have access to are 
     Next Steps and Description. If you need to make edits to other fields please contact your Administrator. <br>Thank you.</p>
     <label for="next">Next Step:&nbsp;&nbsp;&nbsp;</label>
     <input type="text" id="next" size="80" />
     <br><br>
     <label for="des">Description:</label>
     <textarea id="des" cols="60" rows="5"></textarea>
     <br><br>
     <input type="button" id="btn1" value="Save" class="btn" onclick="saveEdit();" />
     <input type="button" id="btn2" value="Cancel" class="btn" onclick="cancelEdit();" />
    </div>
   </div>
  </div>
 </div>
</body>
</html>

 



Message Edited by mikef on 09-21-2007 11:59 AM

  • September 15, 2007
  • Like
  • 0
Is there is a way to create a custom button to place next to a field to copy data from one field to another?  For example, we have a case description field.  On the same page we now have a Billing Description field.  Sometimes these need to be different, other times they are the same.  So I was wondering if it is possible to have a button next to the Billing Description that would copy the case description field to the Billing Description field?
Has anyone else been seeing unexpected behavior from the email notifications controlled by the Case Support Settings since switching to Winter 07?

I haven't been able to track all circumstances that trigger it, but it seems that Case Assigned notifications are getting sent to often and under new circumstances. Specifically, Cases that get closed by the Case Owner or another User trigger the Case Assigned notifications even though there was no change in Case Owner assignment, only in the Status.

It seems like changing the Status now also triggers the Case Assignment notifications. If Status is the only thing changed, the Case Owner gets notified.

If a Comment is added, an additional email is sent, which is expected behavior since we enable the Notify Case Owners of Comments setting.

Luke

P.S. Peter Dapkus recommended posting here in his blog entry - is there a better board for Non-Apex related discussions?
We've noticed that some emails we send through the new Email to Case facilities are not routed properly. After doing a little digging around it appears that the logic in salesforce depends on the correct email headers being supplied in the emails that are sent up to SFDC.

Since we do notcontrol the email headers that are being sent to us and thus sent to SFDC...it made me wonder:

What are the exact email header values that the API is looking for to correct route emails via the email-to-case facilities?

Can someone provide a list?

Thanks,
- B
  • July 13, 2005
  • Like
  • 0