• Andrew G
  • SMARTIE
  • 1454 Points
  • Member since 2014
  • Salesforce Learner

  • Chatter
    Feed
  • 48
    Best Answers
  • 0
    Likes Received
  • 1
    Likes Given
  • 10
    Questions
  • 315
    Replies
I'm trying to prevent an opportunity from saving when StageName = Verification but picklist named Client equals No or is blank. The picklist value must equal Yes. 

Validation rule allows opportunity record to save if picklist value = No or if picklist value is blank. Can someone help me with this? thx
AND(
ISPICKVAL( StageName, 'Verification)'),
ISPICKVAL( Client_Verified__c, 'Yes'))

 
  • October 15, 2019
  • Like
  • 0
I am trying to query salesforce data based on information that I am pulling from our HR system via a REST API callout to the HR system. 

Basically I am tring to find all contacts in my Salesforce org where the first name = the first name in the API Call. I know that first name is not specific enough, but I am starting here and once I can get records to match I will use a more unique identifier. 

Here is my code. I NEED HELP WITH LINE 28! I have left out authorization lines for privacy sake. 
 
request.setMethod('GET');
    HttpResponse response = http.send(request);
    // If the request is successful, parse the JSON response.
    if (response.getStatusCode() == 200) {
        // Deserializes the JSON string into collections of posts.
        Map<String,Object> wrapper = (Map<String,Object>) JSON.deserializeUntyped(response.getBody());
        if (wrapper.containsKey('data')) {
            Map<String, Object> wrapper2 = (Map<String,Object>) wrapper.get('data');
            if(wrapper2.containsKey('data')) {
                List<Object> people = (List<Object>)wrapper2.get('data');
                for (Object peopleWrapper : people) {
                    Map<String,Object> Employees = (Map<String,Object>) peopleWrapper;
                    if(Employees.containsKey('last_name')){
                    String ZenefitsLastName = (String) Employees.get('last_name');
                    String ZenefitsFirstName = (String) Employees.get('first_name');
                    String ZenefitseEmployeeId = (String) Employees.get('id');
                        
                        List<Contact> contactList = [SELECT Id, FirstName, LastName FROM Contact WHERE FirstName = Employees.get('first_name') LIMIT 200];
                        
					//we now need to find all contacts in SF that match the contacts in Employees
                    //once we have matches we need to synce each ID 
                   
                        
         
                            system.debug('Employees ' + Employees);
                            system.debug('last name ' + ZenefitsLastName);
                        	system.debug('Employee id ' + ZenefitseEmployeeId);
                        	system.debug('first name ' + ZenefitsFirstName);
                            system.debug('Contact list ' + contactList);
                            
                   			}
               			}
            		}
            
            return null;
        }
        return null;
    }
    return null;
}

 
Hi All

I have wirrten a small Apex trigger to stop chatter group members from leaving a group, based on the permissions of the gorup which are set in a record in the custom object Chatter_Groups__c. Whenever a new chatter group is created, a record is automatically created in this custom object with the necessary fields. 

My trigger is working as intended:
trigger disableChatterDelete on CollaborationGroupMember (before delete) {
    
    List<Chatter__c> chatterGroups = [SELECT Id,
                                      Name, 
                                      Chatter_Group_Id__c,
                                      Allowed_to_leave__c
                                      FROM Chatter__c];
    
    Id userProfileId = userinfo.getProfileId();
    String userProfileName = [SELECT ID, Name from Profile Where Id = : userProfileId].Name;
    
    for(CollaborationGroupMember collab : Trigger.Old){
        
        integer index;
        for(integer i = 0; i < chatterGroups.size();i++){
            if(collab.CollaborationGroupId == chatterGroups[i].Chatter_Group_Id__c) index = i;
        }
        
        if(chatterGroups[index].Allowed_to_leave__c == false){
            
            if(chatterGroups[index].Chatter_Group_Id__c == collab.CollaborationGroupId){
                
                if(userProfileName != 'System Administrator'){
                    
                    if(Trigger.isBefore){
                        
                        if(Trigger.isDelete){
                            
                            collab.adderror('This Group is mandatory for all staff');
                        }
                    }
                }
            }
        }
    }
}
This is my test class:
@isTest
public class disableChatterDeleteTest {
    
    static testMethod void testDisableChatterDeleter(){
        
        // Create a unique UserName
        String uniqueUserName = 'salesuser' + DateTime.now().getTime() + '@testorg.com';
        // This code runs as the system user
        Profile p = [SELECT Id FROM Profile WHERE Name='SADC Employee'];
        
        Test.startTest(); 
        User usr = new User(Alias = 'suser', Email='user@testorg.com',
                            EmailEncodingKey='UTF-8', LastName='SalesTesting', LanguageLocaleKey='en_US',
                            LocaleSidKey='en_US', ProfileId = p.Id,
                            TimeZoneSidKey='America/New_York',
                            UserName=uniqueUserName);
        
        // Create new Chatter Group
        CollaborationGroup grp = new CollaborationGroup();
        grp.Name = 'Test Group';
        grp.CollaborationType = 'Public';
        insert grp;
        
        //Create new Chatter Group record
        Chatter__c grpRec = new Chatter__c();
        grpRec.Name = 'Test Group Record';
        grpRec.Chatter_Group_Id__c = grp.Id;
        grpRec.Allowed_to_leave__c = false;
        
        // Create new group member
        CollaborationGroupMember grpMem = new CollaborationGroupMember();
        grpMem.MemberId = usr.Id;
        grpMem.CollaborationGroupId = grp.Id;
        
        System.runAs(usr){
            
            try{
                delete grpMem;
            }catch(Exception ex){
                system.debug('Exception');
            }
            Test.stopTest(); 
            
            List<CollaborationGroup> groupList = [SELECT Id, MemberCount
                                                  FROM CollaborationGroup 
                                                 Where Id = : grp.Id];
            System.assertEquals(groupList[0].MemberCount, 1 );
        }
    }
}

Running this test class does not result in an error, but i have 0 code coverage. If anyone could tell me where i am going wrong it would be much appreciated!

Thanks

Tom 
 
We have a set of JavaScript buttons which are designed to generate new opportunities when a user clicks a button from a related list on an account. These buttons were working as planned yesterday. Overnight, we refreshed our full UAT sandbox from production. This morning, when I try to generate a new opportunity in the sandbox, Salesforce opens up a new page and tries to log in to production. The process then errors out, as the system is trying to create an opportunity in the wrong environment. When you take the ID generated in production, then apply it back to the sandbox, a new opportunity is then created. I have reviewed the JavaScript button, and I see no references to the production org.

Here is one of the JavaScript buttons:
{!REQUIRESCRIPT("/soap/ajax/31.0/connection.js")} {!REQUIRESCRIPT("/soap/ajax/31.0/apex.js")} var opportunity = new sforce.SObject('Opportunity'); opportunity.Name = 'Do Not Delete'; opportunity.AccountId = '{!Account.Id}'; opportunity.RecordTypeId = '{!$Setup.Opportunity_Record_Type_Ids__c.Standard_Services__c}'; opportunity.StageName = 'Qualification'; var closeDate = new Date('{!TODAY()}'); closeDate.setMonth(closeDate.getMonth()+6); opportunity.CloseDate = closeDate; var result = sforce.connection.create([opportunity]); if(result[0].success == 'true'){ var serverPrefix = '{!$Setup.Server_Prefix__c.Server_Prefix__c}'; var oppId = result[0].id; parent.window.location.href = 'https://' + serverPrefix + '.salesforce.com/' + oppId; } else{ alert('Record creation failed - please notify system administrator'); }

The Standard Services Opportunity Record ID is in Custom Settings. The Record IDs point to Record types within UAT
Here is my class:

public with sharing class BusinessUnitTriggerHandler 
{
    public static void checkDuplicate(List<BusinessUnits__c> units, Map<Id, BusinessUnits__c> oldMap, Boolean isInsert ) 
    {
      Map<String, Integer> businessUnitMap = new Map<String, Integer>();
      Set<String> lineOfBusiness = new Set<String>();
      Set<Id> contactIds = new Set<Id>();
      List<BusinessUnits__c> unitsToProcess = new List<BusinessUnits__c>();

      // Get System Admin profile Id
      Id profileId = [SELECT Id FROM Profile WHERE Name = 'System Administrator' LIMIT 1].Id;
      System.debug('UAC: profileId' + profileId);

      //Get current User Profile ID
      Id userProfileId = UserInfo.getProfileId() ;
    System.debug('UAC: userProfileId' + userProfileId);

    // Iterate over all business records 
        for( BusinessUnits__c bu : units )
        {  
          // When current user Non-Admin OR these fields are updated 
          if(  profileId != userProfileId &&
            ( isInsert || ( !isInsert && ( bu.LineOfBusiness__c != oldMap.get(bu.Id).LineOfBusiness__c || bu.Contact__c != oldMap.get(bu.Id).Contact__c))) ) 
          {
            lineOfBusiness.add(bu.LineOfBusiness__c);
            contactIds.add(bu.Contact__c);
            unitsToProcess.add(bu);
            businessUnitMap.put(bu.LineOfBusiness__c+bu.Contact__c, 0);
          }
        }
        System.debug('UAC: businessUnitMap' + businessUnitMap );
        if( businessUnitMap.size() == 0 ) return ;

        // Get existing Business records 
        for( BusinessUnits__c bu : [SELECT Id, LineOfBusiness__c, Contact__c FROM BusinessUnits__c 
                      WHERE Contact__c IN :contactIds AND LineOfBusiness__c IN :lineOfBusiness AND ID NOT IN :units ])
        {
          String key = bu.LineOfBusiness__c+bu.Contact__c;
          businessUnitMap.put( key, (businessUnitMap.get(key)+1) ) ;
        }
        System.debug('UAC: businessUnitMap' + businessUnitMap );
        if( businessUnitMap.size() == 0 ) return ;

        // Iterate again over inserted/updated records 
        for( BusinessUnits__c bu : unitsToProcess )
        {
          String key = bu.LineOfBusiness__c+bu.Contact__c;
          // When Already exists then show error
          if( businessUnitMap.containsKey(key) && businessUnitMap.get(key) > 0 ) bu.addError('Sorry. A Business Relationship for this Business Unit already exists for this Contact.');
        }
    }

    public static void changeOwner(List<BusinessUnits__c> units )
    {
        for(BusinessUnits__c bu : units )
        {
            if( bu.Sales_Rep__c != null && bu.OwnerId != bu.Sales_Rep__c  ) bu.OwnerId = bu.Sales_Rep__c ; 
        }
    }

    public static Map<String, BusinessUnitRulesManagement__c> lobAndUserRoleToBusinessUnitCS
    {
        get
        {
            if(lobAndUserRoleToBusinessUnitCS == null )
            {
                lobAndUserRoleToBusinessUnitCS = new Map<String, BusinessUnitRulesManagement__c>();
                for(BusinessUnitRulesManagement__c cs : BusinessUnitRulesManagement__c.getAll().values()) 
                {
                    lobAndUserRoleToBusinessUnitCS.put( cs.LineofBusiness__c + '' + cs.RoleDeveloperName__c, cs);
                }
            }
            //for(String key : lobAndUserRoleToBusinessUnitCS.keySet() ) System.debug('UAC: key ' + key  + ' value ' + lobAndUserRoleToBusinessUnitCS.get(key) );
            return lobAndUserRoleToBusinessUnitCS ;
        }
        private set ;
    }

    /**
    *   @Method:    updateContactFromCS()
    *   @Purpose:   When BusinessUnit is Updated then update SalesRep and EscrowOfficer fields from Contact based on Custom Setting fields 
    *   @Param:     List<BusinessUnits__c> units : List of new records - Trigger.new
    *               Map<Id,BusinessUnit__c> oldMap : map of old values - Trigger.oldMap
    *   @Return:    void : No return value
    *   @Date:      05/15/2017
    *
    *   @Updates: 
    */
    public static Boolean RUN_ONCE_UCFCS = true ; 
    public static void updateContactFromCS(List<BusinessUnits__c> units, Map<Id,BusinessUnits__c> oldMap, Boolean isInsert )
    {
        System.debug('UAC: BU updateContactFromCS START ' );
        Map<BusinessUnits__c, Id> businessUnitToContactId = new Map<BusinessUnits__c, Id>();
        Map<Id,Contact> existingContacts = new Map<Id,Contact>();
        Set<Id> contactIdsAddedForUpdate = new Set<Id>();
        List<Contact> contactsToUpdate = new List<Contact>();
        Set<Id> contactIds = new Set<Id>();
        Set<Id> userIds = new Set<Id>();
        Map<Id, String> userIdToUserRole = new Map<Id, String>();

        for(BusinessUnits__c bu : units)
        {
            BusinessUnits__c old =  !isInsert ? oldMap.get(bu.Id) : NULL ; 
            if( isInsert || ( !isInsert && (bu.Sales_Rep__c != old.Sales_Rep__c || bu.Escrow_Officer__c != old.Escrow_Officer__c)) ) 
            {
                if(bu.Sales_Rep__c != null ) userIds.add(bu.Sales_Rep__c);
                if(bu.Escrow_Officer__c != null && bu.Sales_Rep__c != bu.Escrow_Officer__c ) userIds.add(bu.Escrow_Officer__c);
                businessUnitToContactId.put(bu, bu.Contact__c);
                contactIds.add(bu.Contact__c);
            }
        }
        System.debug('UAC: businessUnitToContactId ' + businessUnitToContactId );

        for(User u : [SELECT Id, UserRole.DeveloperName FROM User WHERE ID IN :userIds ])
        {
            userIdToUserRole.put(u.Id, u.UserRole.DeveloperName );
        }
        System.debug('UAC: userIdToUserRole ' + userIdToUserRole );
        
        for(Contact con : Database.query( 'SELECT ' + getFields('Contact') + ' FROM Contact WHERE ID IN :contactIds ') )
        {
            existingContacts.put(con.Id, con);
        }

        for(BusinessUnits__c bu : businessUnitToContactId.keyset() )
        {
            String validUserRole = 
                //ContactTriggerHandler.currentUserRole == 'Administration' && 
                userIdToUserRole.containsKey(bu.Sales_Rep__c) ? userIdToUserRole.get(bu.Sales_Rep__c) : ContactTriggerHandler.currentUserRole ;

            // When no custom setting found for current User Role then Go Back
            if(!lobAndUserRoleToBusinessUnitCS.containsKey(bu.LineOfBusiness__c + '' + validUserRole)) continue ; 

            // Get Custom setting record
            BusinessUnitRulesManagement__c cs = lobAndUserRoleToBusinessUnitCS.get(bu.LineOfBusiness__c + '' + validUserRole);
            System.debug('UAC: cs ' + cs );

            if(cs == null ) continue ; 
            
            // Get related Contact 
            Contact con = existingContacts.get(businessUnitToContactId.get(bu));

            // When SalesRep or EscrowOfficer changed 
            if((bu.Sales_Rep__c != con.get(cs.SalesRepFieldonContactAPIName__c) || bu.Escrow_Officer__c != con.get(cs.EscrowOfficerFieldonContactAPIName__c) ) 
                    && !contactIdsAddedForUpdate.contains(con.Id) )
            {
                contactIdsAddedForUpdate.add(con.Id);
                Contact newContact = new Contact();
                newContact.Id = con.Id;
                System.debug('UAC: bu.Sales_Rep__c ' + bu.Sales_Rep__c );
                System.debug('UAC: bu.Escrow_Officer__c ' + bu.Escrow_Officer__c );
                if( !String.isBlank(cs.SalesRepFieldonContactAPIName__c)) newContact.put(cs.SalesRepFieldonContactAPIName__c, bu.Sales_Rep__c);
                if( !String.isBlank(cs.EscrowOfficerFieldonContactAPIName__c)) newContact.put(cs.EscrowOfficerFieldonContactAPIName__c, bu.Escrow_Officer__c);
                contactsToUpdate.add(newContact);
            } 
        }

        System.debug('UAC: contactsToUpdate ' + contactsToUpdate );

        // Update Contacts 
        if(contactsToUpdate.size() > 0 ) 
        {
            ContactTriggerHandler.RUN_ONCE_UBUFCS = false ;  
            BusinessUnitTriggerHandler.RUN_ONCE_UCFCS = false ;
            update contactsToUpdate ;
            ContactTriggerHandler.RUN_ONCE_UBUFCS = true ;  
            BusinessUnitTriggerHandler.RUN_ONCE_UCFCS = true ;
        }

        System.debug('UAC: BU updateContactFromCS END ' );
    
    }

    /**
    *   @Method:    getFields()
    *   @Purpose:   Use to get all fields of passing object  
    *   @Param:     String objName for which you want to get fields
    *   @Return:    Comma seprated fields
    *   @Date:      05/18/2017
    *
    *   @Updates: 
    */
    private static String getFields(String objectName)
    {
        //Broke this out of formatQuery because it could be used separately
        String fields = '';
        
        // Get All Objects List
        Map<String, Schema.SObjectType> gd = Schema.getGlobalDescribe();
        
        // Get object detail which passed as argument
        SObjectType objectType = gd.get(objectName);

        // Get passed object detail
        Schema.DescribeSObjectResult r = objectType.getDescribe();

        //Get all fields for passed object 
        Map<String, Schema.SObjectField> fieldMap = r.fields.getMap();

        // Itterate over all fields and check one by one 
        for (String f: fieldMap.keySet())
        { 
            // Get current field 
            Schema.SObjectField sof = fieldMap.get(f);
            // Get current field detail
            Schema.DescribeFieldResult dfr = sof.getDescribe();

            // when current field is accessible, creatable and defaultonCreare then concatinate in field string
            if( dfr.isAccessible() )
            {
                String fname = dfr.getName(); 
                fields += fname + ', '; 
            }
        }
        
        // remove last comma
        fields = fields.substring(0, fields.length() - 2);
        return fields;
    }


    public static Map<String, BusinessUnitRulesManagement__c> lobToBusinessUnitCS
    {
        get
        {
            if(lobToBusinessUnitCS == null )
            {
                lobToBusinessUnitCS = new Map<String, BusinessUnitRulesManagement__c>();
                for(BusinessUnitRulesManagement__c cs : BusinessUnitRulesManagement__c.getAll().values()) 
                {
                    if(!lobToBusinessUnitCS.containsKey(cs.LineofBusiness__c)) lobToBusinessUnitCS.put( cs.LineofBusiness__c, cs);
                }
            }
            //for(String key : lobToBusinessUnitCS.keySet() ) System.debug('UAC: key ' + key  + ' value ' + lobToBusinessUnitCS.get(key) );
            return lobToBusinessUnitCS ;
        }
        private set ;
    }

    /**
    *   @Method:    clearValueOnContact()
    *   @Purpose:   When BusinessUnit is Updated then update and clearOut SalesRep and EscrowOfficer fields from Contact based on Custom Setting fields 
    *   @Param:     List<BusinessUnits__c> units : List of new records - Trigger.new
    *               Map<Id,BusinessUnit__c> oldMap : map of old values - Trigger.oldMap
    *   @Return:    void : No return value
    *   @Date:      05/15/2017
    *
    *   @Updates: 
    */
    public static void clearValueOnContact(List<BusinessUnits__c> units)
    {
        System.debug('UAC: BU clearValueOnContact START ' );
     
        
     
        Map<Id, String> contactIdToLOB = new Map<Id, String>();
        Map<Id,Contact> contacts = new Map<Id,Contact>();

        // Iterate over BusinessUnit 
        for(BusinessUnits__c bu : units )
        {
            if(bu.Contact__c != null) contactIdToLOB.put(bu.Contact__c, bu.LineOfBusiness__c);
        }
        System.debug('UAC: BU contactIdToLOB ' + contactIdToLOB );
        if(contactIdToLOB.size() == 0) 
           return ; 

        // Get related Contacts 
        contacts = new Map<Id, Contact>( [SELECT Id FROM Contact WHERE ID IN :contactIdToLOB.keyset() ]);

        // Iterate over ContactIds 
        for(Id contactId : contactIdToLOB.keyset() )
        {   
            // Get Custom Setting Business Unit
            BusinessUnitRulesManagement__c cs = lobToBusinessUnitCS.get(contactIdToLOB.get(contactId));
            System.debug('UAC: cs ' + cs );

            if(cs == null ) continue ; 

            // Get Contact 
            Contact con = contacts.get(contactId);

            // Clear Out Values on Contact 
            if( !String.isBlank(cs.SalesRepFieldonContactAPIName__c)) con.put(cs.SalesRepFieldonContactAPIName__c, null);
            if( !String.isBlank(cs.EscrowOfficerFieldonContactAPIName__c)) con.put(cs.EscrowOfficerFieldonContactAPIName__c, null);
            System.debug('UAC: con ' + con );
        }

        // Update Contact
        ContactTriggerHandler.RUN_ONCE_UBUFCS = false ;
        update contacts.values() ;
        ContactTriggerHandler.RUN_ONCE_UBUFCS = true ; 

        System.debug('UAC: BU clearValueOnContact End ' );
    }

}

Test class:

@isTest
private class BusinessUnitTriggerHandlerTest 
{
      Map<String, Integer> businessUnitMap = new Map<String, Integer>();
      Set<String> lineOfBusiness = new Set<String>();
      Set<Id> contactIds = new Set<Id>();
      List<BusinessUnits__c> unitsToProcess = new List<BusinessUnits__c>();
      Set<Id> userIds = new Set<Id>();
      Map<Id, String> userIdToUserRole = new Map<Id, String>();
     Map<BusinessUnits__c, Id> businessUnitToContactId = new Map<BusinessUnits__c, Id>();
     Map<Id,Contact> existingContacts = new Map<Id,Contact>();
     Map<String, BusinessUnitRulesManagement__c> lobToBusinessUnitCS;
       Map<Id, String> contactIdToLOB = new Map<Id, String>();
        Map<Id,Contact> contacts = new Map<Id,Contact>();
    static testMethod void testCheckDuplicate() 
    {
         
   
        Profile profile = [Select Id from Profile where name = 'ORT Direct Sales User'];
        //UserRole ur = [Select Id from UserRole where UserRole.DeveloperName = 'Central_Direct_Agency'];

        User nonAdminUser = new User( ProfileId = profile.Id, Username = System.now().millisecond() + 'test2@test.com.dev',UserRoleId = '00E1G000000IWzyUAG',
                                    Alias = 'batman', Email='bruce.wayne@wayneenterprises.com', EmailEncodingKey='UTF-8',Firstname='Bruce',
                                    Lastname='Wayne',LanguageLocaleKey='en_US',LocaleSidKey='en_US',TimeZoneSidKey='America/Chicago' );
        System.runAs(new User( Id = UserInfo.getUserId() ))
        {
            Database.insert(nonAdminUser);
        }

        Account acc = TestUtility.createAccount( TestUtility.default_account_rt, false );
        acc.Name = 'sfdcpoint';
        acc.Account_Status__c = 'Active';
        acc.AccountNumber = '001';
        insert acc; 
    
        System.runAs(nonAdminUser)
        {
            Contact cont = TestUtility.createContact( TestUtility.default_contact_rt , acc, false ); 
            cont.MailingStreet = 'Test Street' ;
            cont.MailingCity = 'Minneapolis';
            cont.MailingState = 'MN';
            cont.MailingPostalCode = '55347';
            cont.MailingCountry = 'United States' ; 
            insert cont;
            
            
            BusinessUnitRulesManagement__c cs = new BusinessUnitRulesManagement__c();
            cs.Name = 'AgencyManager';
            cs.EscrowOfficerFieldonContactAPIName__c = 'Text';
            cs.LineofBusiness__c = 'testlob';
            cs.RoleDeveloperName__c = 'uniquetest';
            cs.SalesRepFieldonContactAPIName__c = 'conttext';
            cs.Status__c = 'alltext';
            insert cs;
            Id userId = UserInfo.getUserId() ;
          

            BusinessUnits__c bu = new BusinessUnits__c( Contact__c = cont.Id, LineOfBusiness__c = ' Agency',Sales_Rep__c = UserId );
          
            insert bu ; 
  
            try
            {
                BusinessUnits__c bu1 = new BusinessUnits__c( Contact__c = cont.Id,LineOfBusiness__c = 'Western Title Division',Sales_Rep__c = UserId  );
                insert bu1 ;  
            }
            catch(DmlException de )
            {

            } 
  

        }
    

    }
 
Hi All,

Can any one help me to calculate number of sunday's in a given month and year using apex and vf page.

Ex: If i select March 2017 from vf page, i need to calculate number of sunday's from selected month and year.

Thanks in advance.
Hello,

I want to know different costing for each of these licence.

- sales, community, guest, service,marketing, etc

thank you
Hello,

How can i mange the permission of "mass delete" , can it be managed at profile or role ?

thank you
Hello, I have a situation where I need to check if a field is already updated or not before firing a trigger.
Meaning,
I have just finished apex specialist super badge where everytime a case is updated to closed, a new maintenance request is made automatically. But, what if the status is already updated to closed and i go ahead edit it and save it without doing anything, in this case another maintenance request will be made which should not be made.
So, I should case.status field is already updated to closed or not. How can i achieve this in trigger. I want that trigger does not fire if the field is already updated.

Below is the trigger that i have tried but i m really not sure about it.

trigger MaintenanceRequest on Case (before update,after update) {
    // call MaintenanceRequestHelper.updateWorkOrders
    if(trigger.isBefore && trigger.isUpdate)
    {
        for(Case c: trigger.old)
        {
            if(c.Status!='Closed')
            {
              MaintenanceRequestHelper.updateWorkOrders();          
            }
        }
    }
      
}
I have a working trigger that I'm starting to build my test class for.  I've done a few lines and ran a test to make sure it's working as it should and everything seems okay, except the trigger itself is 0% coverage.  Can someone help me figure out why?  I'm an amature with this stuff, so please go easy on me if it's something very simple.

Trigger:
trigger PartnerLeadAssignment on Lead (before insert) {
    
    List<Lead> leadList = new List<Lead>();
    for(Lead l : trigger.new){
        leadList.add(l);
        if(l.Company == null){
            l.Company = l.FirstName + ' ' + l.LastName;
        
            if(l.LeadSource == 'Website' && (l.Lead_Subtype__c == 'Free Resource' || l.Lead_Subtype__c == 'Contact Requested' || l.Lead_Subtype__c == 'Connect with Advisor' || l.Lead_Subtype__c == 'WMC Footer') && l.Referring_Brand_Id__c == '0010H00002SuHKtQAN'){
                l.OwnerId = '0050H0000090O6HQAU';
                }

            if(l.LeadSource == 'Website' && (l.Lead_Subtype__c == 'Free Resource' || l.Lead_Subtype__c == 'Contact Requested' || l.Lead_Subtype__c == 'Connect with Advisor' || l.Lead_Subtype__c == 'WMC Footer') && l.Referring_Brand_Id__c == '0010H00002Vv9gqQAB'){
                l.OwnerId = '0050H00000BwRULQA3'; 
                }    
            if(l.LeadSource == 'Website' && (l.Lead_Subtype__c == 'Free Resource' || l.Lead_Subtype__c == 'Contact Requested' || l.Lead_Subtype__c == 'Connect with Advisor' || l.Lead_Subtype__c == 'WMC Footer') && l.Referring_Brand_Id__c == '0010H00002PZz8zQAD'){
                l.OwnerId = '0050H000009LmB3QAK';
                }
            if(l.LeadSource == 'Website' && (l.Lead_Subtype__c == 'Free Resource' || l.Lead_Subtype__c == 'Contact Requested' || l.Lead_Subtype__c == 'Connect with Advisor' || l.Lead_Subtype__c == 'WMC Footer') && l.Referring_Brand_Id__c == '001i000001siaFLAAY'){
                l.OwnerId = '005i0000007xZy2AAE';
                }
            if(l.LeadSource == 'Website' && (l.Lead_Subtype__c == 'Free Resource' || l.Lead_Subtype__c == 'Contact Requested' || l.Lead_Subtype__c == 'Connect with Advisor' || l.Lead_Subtype__c == 'WMC Footer') && l.Referring_Brand_Id__c == '001i000001R92ADAAZ'){
                l.OwnerId = '005i0000004jpjbAAA';  
                }
            if(l.LeadSource == 'Website' && (l.Lead_Subtype__c == 'Free Resource' || l.Lead_Subtype__c == 'Contact Requested' || l.Lead_Subtype__c == 'Connect with Advisor' || l.Lead_Subtype__c == 'WMC Footer') && l.Referring_Brand_Id__c == '0010H00002LTwKnQAL'){
                l.OwnerId = '0050H0000090Mz0QAE';  
                }
            if(l.LeadSource == 'Website' && (l.Lead_Subtype__c == 'Free Resource' || l.Lead_Subtype__c == 'Contact Requested' || l.Lead_Subtype__c == 'Connect with Advisor' || l.Lead_Subtype__c == 'WMC Footer') && l.Referring_Brand_Id__c == '001i000000Rr2XRAAZ'){
                l.OwnerId = '005i0000006ozUbAAI'; 
                }
            if(l.LeadSource == 'Website' && (l.Lead_Subtype__c == 'Free Resource' || l.Lead_Subtype__c == 'Contact Requested' || l.Lead_Subtype__c == 'Connect with Advisor' || l.Lead_Subtype__c == 'WMC Footer') && l.Referring_Brand_Id__c == '001i000001lbahkAAA'){
                l.OwnerId = '005i0000007CtxhAAC';  
                }
            if(l.LeadSource == 'Website' && (l.Lead_Subtype__c == 'Free Resource' || l.Lead_Subtype__c == 'Contact Requested' || l.Lead_Subtype__c == 'Connect with Advisor' || l.Lead_Subtype__c == 'WMC Footer') && l.Referring_Brand_Id__c == '0010H00002WhyBJQAZ'){
                l.OwnerId = '0050H00000BNF5XQAX';  
                }
            if(l.LeadSource == 'Website' && (l.Lead_Subtype__c == 'Free Resource' || l.Lead_Subtype__c == 'Contact Requested' || l.Lead_Subtype__c == 'Connect with Advisor' || l.Lead_Subtype__c == 'WMC Footer') && l.Referring_Brand_Id__c == '0010H00002Gbu8mQAB'){
                l.OwnerId = '0050H00000A9mp3QAB';  
                }
            if(l.LeadSource == 'Website' && (l.Lead_Subtype__c == 'Free Resource' || l.Lead_Subtype__c == 'Contact Requested' || l.Lead_Subtype__c == 'Connect with Advisor' || l.Lead_Subtype__c == 'WMC Footer') && l.Referring_Brand_Id__c == '0010H00002QeX7JQAV'){
                l.OwnerId = '0050H0000090IR1QAM';  
                } 
            if(l.LeadSource == 'Website' && (l.Lead_Subtype__c == 'Free Resource' || l.Lead_Subtype__c == 'Contact Requested' || l.Lead_Subtype__c == 'Connect with Advisor' || l.Lead_Subtype__c == 'WMC Footer') && l.Referring_Brand_Id__c == '0010H00002Wk18hQAB'){
                l.OwnerId = '0050H00000BwWykQAF';  
                }
            if(l.LeadSource == 'Website' && (l.Lead_Subtype__c == 'Free Resource' || l.Lead_Subtype__c == 'Contact Requested' || l.Lead_Subtype__c == 'Connect with Advisor' || l.Lead_Subtype__c == 'WMC Footer') && l.Referring_Brand_Id__c == '0010H00002QeXBVQA3'){
                l.OwnerId = '0050H0000090HG2QAM';  
                }
            if(l.LeadSource == 'Website' && (l.Lead_Subtype__c == 'Free Resource' || l.Lead_Subtype__c == 'Contact Requested' || l.Lead_Subtype__c == 'Connect with Advisor' || l.Lead_Subtype__c == 'WMC Footer') && l.Referring_Brand_Id__c == '0010H00002JJNojQAH'){
                l.OwnerId = '0050H000009LjrVQAS';  
                }
            if(l.LeadSource == 'Website' && (l.Lead_Subtype__c == 'Free Resource' || l.Lead_Subtype__c == 'Contact Requested' || l.Lead_Subtype__c == 'Connect with Advisor' || l.Lead_Subtype__c == 'WMC Footer') && l.Referring_Brand_Id__c == '0010H00002WhxgEQAR'){
                l.OwnerId = '0050H00000BpsLdQAJ';  
                }
            if(l.LeadSource == 'Website' && (l.Lead_Subtype__c == 'Free Resource' || l.Lead_Subtype__c == 'Contact Requested' || l.Lead_Subtype__c == 'Connect with Advisor' || l.Lead_Subtype__c == 'WMC Footer') && l.Referring_Brand_Id__c == '001i000001p21CnAAI'){
                l.OwnerId = '005i0000007E1poAAC';  
                }
            if(l.LeadSource == 'Website' && (l.Lead_Subtype__c == 'Free Resource' || l.Lead_Subtype__c == 'Contact Requested' || l.Lead_Subtype__c == 'Connect with Advisor' || l.Lead_Subtype__c == 'WMC Footer') && l.Referring_Brand_Id__c == '001i000000N2CBbAAN'){
                l.OwnerId = '005i00000058XOlAAM'; 
                }
            if(l.LeadSource == 'Website' && (l.Lead_Subtype__c == 'Free Resource' || l.Lead_Subtype__c == 'Contact Requested' || l.Lead_Subtype__c == 'Connect with Advisor' || l.Lead_Subtype__c == 'WMC Footer') && l.Referring_Brand_Id__c == '001i000000N2CJ8AAN'){
                l.OwnerId = '005i0000007CVm0AAG'; 
                }
            if(l.LeadSource == 'Website' && (l.Lead_Subtype__c == 'Free Resource' || l.Lead_Subtype__c == 'Contact Requested' || l.Lead_Subtype__c == 'Connect with Advisor' || l.Lead_Subtype__c == 'WMC Footer') && l.Referring_Brand_Id__c == '0010H00002QectbQAB'){
                l.OwnerId = '0050H0000090OXcQAM';  
                }
}
}

Test Class:
 
@isTest
public class PartnerLeadAssignmentTest {
    static testMethod void insertLead(){
        
        List<Lead> leadList = new List<Lead>();
        Lead l = New Lead(Company = '', FirstName = 'First', LastName = 'Last', leadSource = 'Website', lead_SubType__c = 'Contact Requested');
        leadList.add(l);
        if(l.Referring_Brand_Id__c == '0010H00002SuHKtQAN'){  
        
 	       insert l;
        
    	    l=[Select Company, FirstName, LastName, Referring_Brand_Id__c, LeadSource, OwnerId, RecordTypeId FROM Lead Where Id =:l.Id];
        	System.assertEquals('0050H0000090O6HQAU', l.OwnerId);
           }
        if(l.Referring_Brand_Id__c == '0010H00002Vv9gqQAB'){ 
            
            insert l;
            
            l=[Select Company, FirstName, LastName, Referring_Brand_Id__c, LeadSource, OwnerId, RecordTypeId FROM Lead Where Id =:l.Id];
        	System.assertEquals('0050H00000BwRULQA3', l.OwnerId); 
        }
        
        
    }
}

 
Hi,

I have multiple classes related to single object. some test classes covering code coverage upto 40 to 50 which doesn't have separate test class. my question is should i write test class again for every class or can use(call all classes) same test class for mutiple classes. Please help.
Trigger code

trigger Ag_PurchaseContract_UpdateTradeConfirmation_Trigger on Ag_Purchase_Contract__c (after insert,after update) {

    set<string> tradeConfirmationNumSet = new set<String>();
    string purchaseContractName = null;
    for (Ag_Purchase_Contract__c purchase : Trigger.new)    
    {
      list<Ag_Purchase_Contract__c> purlist = [select id, Trade_Confirmation_No__c,name from Ag_Purchase_Contract__c where Trade_Confirmation_No__c = :purchase.Trade_Confirmation_No__c and name != :purchase.name];
   
      if (purlist != null && purlist.size() > 0 && purchase.Trade_Confirmation_No__c != null)
       {
         purchase.adderror('The TradeNumber is used in a different Purchase contract. The purchase contract number is ' + purlist[0].name  );
       }
       else
       {
         purchaseContractName = purchase.name;
         if(purchase.Trade_Confirmation_No__c != null )
         {
            if (purchase.Trade_Confirmation_No__c == Trigger.NewMap.get(purchase.Id).Trade_Confirmation_No__c)
            {
               tradeConfirmationNumSet.add(Trigger.NewMap.get(purchase.Id).Trade_Confirmation_No__c);
              
            }
            
            List<Trade_Confirmation__c> tcList = [Select ID,purchase_contract__c,name from Trade_Confirmation__c where id IN :tradeConfirmationNumSet];
          
            for (Trade_Confirmation__c tc: TClist)
            {
                tc.purchase_contract__c = purchaseContractName;
            }
             update tcList;
        }
     }
  }
}

the above trigger is working and 
test class is 

@isTest
private class Test_Ag_PurchaseContract {
    @istest static void testSuccess(){
    set<string> tradeConfirmationNumSet = new set<String>();
        
    string purchaseContractName = 'AGP/19/03/16599';
     String tradeConfirmationnum  = 'AGC0000012';
    Ag_Purchase_Contract__c purchase = new  Ag_Purchase_Contract__c();
     

      list<Ag_Purchase_Contract__c> purlist = [select id, Trade_Confirmation_No__c,name from Ag_Purchase_Contract__c where Trade_Confirmation_No__c = :tradeConfirmationnum and name=:purchaseContractName limit 1];
   
      if (purlist != null && purlist.size() > 0)
       {
         purchase.adderror('The TradeNumber is used in a different Purchase contract. The purchase contract number is ' + purlist[0].name  );
       }
       else
       {
        if(purchase.Trade_Confirmation_No__c != null )
         {
           
               tradeConfirmationNumSet.add(tradeConfirmationnum);
         }
            
         List<Trade_Confirmation__c> tcList = [Select ID,purchase_contract__c,name from Trade_Confirmation__c where id IN :tradeConfirmationNumSet limit 1];
         system.debug('purchaseContractName '+  purchase.name);
         system.debug('purchaseContractName After assign '+  purchaseContractName);
         system.debug('TClist :'+tcList.size());
           
           if(TClist!=null && TClist.size()>0)
           {
                for (Trade_Confirmation__c tc: TClist)
         {
           tc.purchase_contract__c = purchaseContractName;
           system.debug('tc.purchase_contract__c '+ tc.purchase_contract__c);
         }
           }
            
        
         try
         {
             update tcList;
         }
         catch(Exception e)
         {
             system.assertEquals(e.getMessage(), e.getMessage()) ;
         } 
       }
  }
}
With this test class Code coverage is zero.how to write pls help me , 

 

I have a trigger that updates the quantity of one opportunity product when another one's quantity is updated. Everything seems to be working when I mess around in the sandbox. However, the last test class assertion keeps failing. Does anyone know why it's failing? Any help is greatly appreciated.

Here's my trigger:

trigger UpdateInverterQuantity on OpportunityLineItem (before update) {
    Map<Id, Product2> prodMap = new Map<Id, Product2>([
        SELECT Id, Name 
          FROM Product2
         WHERE Name = 'Heliene 60M-BLK 310W' 
            OR Name = 'Heliene 60M-HBLK 300W'
    ]); 

    for (OpportunityLineItem oli : Trigger.new) {

        // Get related inverter from same opportunity
        List<OpportunityLineItem> inverters = [ 
            SELECT Id, Quantity, Product2.Name 
              FROM OpportunityLineItem
             WHERE OpportunityId = :oli.OpportunityId
               AND (Product2.Name = 'APSystems QS1'
                OR Product2.Name = 'YC600') 
             LIMIT 1
        ];

        if (prodMap.ContainsKey(oli.Product2Id)) { // panel 1 or panel 2
            // Get quantity of panels
            if (!inverters.isEmpty()) {
                // set inverter quantity formulas
                Decimal inverterQuantityOne = (inverters.get(0).Quantity / 4);
                Decimal inverterQuantityTwo = (inverters.get(0).Quantity / 2);
                inverterQuantityOne = inverterQuantityOne.round(System.RoundingMode.CEILING);
                inverterQuantityTwo = inverterQuantityTwo.round(System.RoundingMode.CEILING);

                // update quantity of inverter
                if (inverters.get(0).Product2.Name == 'APSystems QS1') { // inverter 1  
                    inverters.get(0).Quantity = inverterQuantityOne;
                } else if (inverters.get(0).Product2.Name == 'YC600') { // inverter 2
                    inverters.get(0).Quantity = inverterQuantityTwo;
                }
                update inverters;
            }
        }
    }
}


And here's my test class:

@isTest
private class UpdateInverterQuantityTest {
    @isTest static void updatePanelQuantity() {
        // create an opportunity
        Opportunity myOpp  = new Opportunity();
        myOpp.Name         = 'Test';
        myOpp.StageName    = 'Closed Won';
        myOpp.CloseDate    = Date.today();
        myOpp.Pricebook2Id = Test.getStandardPricebookId();
        insert myOpp;

        Id pricebookId = Test.getStandardPricebookId();

        //Create your panel
        Product2 panel = new Product2(
            Name        = 'Heliene 60M-HBLK 300W',
            ProductCode = 'H300W',
            isActive    = true
        );
        insert panel;

        //Create your inverter
        Product2 firstInverter = new Product2(
            Name        = 'APSystems QS1',
            ProductCode = 'APS',
            isActive    = true
        );
        insert firstInverter;

        //Create your pricebook entry for panel
        PricebookEntry  panelEntry = new PricebookEntry(
            Pricebook2Id = pricebookId,
            Product2Id   = panel.Id,
            UnitPrice    = 100.00,
            IsActive     = true
        );
        insert panelEntry;

        //Create your pricebook entry for inverter
        PricebookEntry inverterEntry = new PricebookEntry(
            Pricebook2Id = pricebookId,
            Product2Id   = firstInverter.Id,
            UnitPrice    = 100.00,
            IsActive     = true
        );
        insert inverterEntry;

        // add panel to opp products
        OpportunityLineItem oli = new OpportunityLineItem(
            OpportunityId    = myOpp.Id,
            Quantity         = 20,
            PricebookEntryId = panelEntry.Id,
            TotalPrice       = 20 * panelEntry.UnitPrice
        );
        insert oli;

        // add inverter to opp products
        OpportunityLineItem oli2 = new OpportunityLineItem(
            OpportunityId    = myOpp.Id,
            Quantity         = 20,
            PricebookEntryId = inverterEntry.Id,
            TotalPrice       = 20 * inverterEntry.UnitPrice
        );
        insert oli2;

        // Get updated inverter quantity
        OpportunityLineItem inverter = [
            SELECT Quantity
              FROM OpportunityLineItem
             WHERE OpportunityId = :oli.OpportunityId
               AND Id = :oli2.Id
             LIMIT 1
        ];

        System.assertEquals(5, inverter.Quantity);

        // Update quantity of panels
        oli.Quantity = 40;
        update oli;

        // Get updated quantity of inverters
        OpportunityLineItem updatedInverter = [
            SELECT Quantity
              FROM OpportunityLineItem
             WHERE OpportunityId = :oli.OpportunityId
               AND Id = :oli2.Id
             LIMIT 1
        ];

        System.assertEquals(10, updatedInverter.Quantity);
    }
}
I have an Apex Trigger that has for main goal to set the 'Assigned To' (OwnerId) field depending on on the 'Related To' (WhatId) record's type.

I feel like I'm going a little bit crazy at this very instant because I could have sworn the trigger was working last week.

This is give or take what my code looks like currently:
trigger EventAssignToTrigger on Event (before insert) {
    for (Event e :Trigger.New) {
        String relatedObject = e.What.Type;
        
        if(e.What.Type == 'Account' || e.What.Type == 'Contract__c') {
            //related to Account, NDA Contract, or Vendor Contract
            if(e.What.Type == 'Account' || e.what.recordTypeId == '0121t000000EC3cAAG') {
                e.OwnerId = '0231w0000010AWx';  //Calendar 1
            } else if (e.what.recordTypeId == '0121t000000EC3mAAG') {
                e.OwnerId = '0231t000001EAwZ';  //Calendar 2
            }  else {
                e.OwnerId = '0231t000001EAwj'; //Calendar 3
            }
            
        }   
    }
}

The code above is slightly simplified but that is basically the just of it. For some reason I can't seem to access the 'What.Type' or 'What.RecordTypeId' from the trigger. Is that normal?
I know WhatId returns what it should but for some reason What.* returns null.
If this is normal, what are my options in terms of getting the WhatId object's type and record type?
Hello All
I'm new to Apex.  I have successfully created a Case Trigger and a Class which I call from it.   I have 100% coverage of my Class methods.   I now need to write test coverage for my Case Trigger code.  Classes and Methods seem straight forward to me as it's pure calls.  For the Case Trigger code, I need to do things to the system to have it invoke things.  This I do not know how to do despite trying to find examples.

I believe a simple example would help me understand the technique and in fact would be the solution I need for this my first attempt at Trigger testing.

My Case trigger is to designed to take action when the Case  Status field changes.
My trigger test needs to change the status to traverse the different actions that are taken based on the new status.
  1. Do I need to create a new case record for each test then change the status before I loose the scope of the test?
    • Note there are several required fields I would need to satisfy to create a new case record
  2. If yes to the above how can I push the creation of the record into a sub-class and then reference that case record while still in the scope of the test classes?

   Mark
 
I created a trigger that should display an error message if the owner of a opportunity tries to enter the same number in a field that is already on another record. Ny trigger below is working somewhat. The message shows at the field level when there is another opportunity with the same number, but it shows the error message regardless of who owns the record. I'm not sure how to get the trigger to reconize that the user trying to enter the number is the same as the owner. 

I first tried using "integer" in my set collection, but when i tried to compile I recieved the following error message
Invalid bind expression type of String for column of type Decimal
So I create a formula field (quoteprioritynum__c) and use TEXT to get this to work with Set<string><string> I tried a few things but I wasn't able to save my trigger successfully. 

So I'm stuck with the trigger half working. Any help would be greatly appreciated. 
 
trigger TR_RejectDupPri on Opportunity (before insert,before update) {
//Display error message if another opportunity has the same number in Quting_Priority__c field

 Set<string> oppSet = new Set<string>();

 for(Opportunity o : trigger.new){

     oppSet.add(o.quoteprioritynum__c);
       
 }

 //query all existing record for quoteprioritynum__c
 List<Opportunity> oppsList = [select id, Owner.Id,Quting_Priority__c,LastModifiedBy.Id,quoteprioritynum__c from Opportunity where quoteprioritynum__c in :oppSet];

for(Opportunity o:trigger.new) 
{
    //Update
    if(Trigger.isUpdate && o.quoteprioritynum__c==o.quoteprioritynum__c && oppsList.size()>0 && Trigger.oldmap.get(o.id).quoteprioritynum__c!=o.quoteprioritynum__c && o.LastModifiedBy.Id == o.Owner.Id )
    {
       o.Quting_Priority__c.adderror('Another quote has the same priority number, please enter a new number!');
    }

    //Only check for size
    if(Trigger.isInsert && o.quoteprioritynum__c==o.quoteprioritynum__c && oppsList.size()>0 && o.LastModifiedBy.Id == o.Owner.Id)
    {
       o.Quting_Priority__c.adderror('Another quote has the same priority number, please enter a new number!');

    }

} 
}

 
if field 1 is populated, use field 1
If Field 1 is blank, use field 2
if field 1 and field 2 is blank use field 3
if field 1, field 2, field 3 are all blank use blank value

**Description; assigning a person to a managers role (these are all text fields)
1. if field 1 is not blank, use field 1
2. if field 1 is blank, use name on field 2
3. if field 1 and field 2 are blank, use name on field 3
4. if field 1, field 2, field 3 are all blank, leave manager's role field blank
 

Hello,

I have a simple trigger to update a few custom fields on the User Profile Object. Not sure what is missing...I want my trigger to fire when the User Profile is updated.

Thanks for your help!

 

trigger Update_User_Custom_Fields_Trigger on User (before insert, before update) {
for(User u:trigger.new){
u.Last_Login_for_PB_Flows__c = u.LastLoginDate;
u.Managers_Email_for_PB_Flows__c = u.Managers_Email_del__c;
u.AboutMe = '*** This is a Test ***'
}
}

 

Hi

On the Visualforce page, there is a check box to select to enable the visualforce page to be available under Lightning.
User-added image

Since we use GitHub, how do I see this change in the Git Repository?  Is there an XML tag that is set to true when this check box is enabled?

Regards
Andrew
 
Hello

We are using the FSL managed package.  Needing to write some test coverage for the Maintenance Plan.  In the test class, I am trying to create the Maintenance Plan record as such:
MaintenancePlan maintPlan 
		= new MaintenancePlan( AccountId = testaccs[0].Id,
						Billing_Account__c = testaccs[0].Id,
						WorkTypeId = mpWt[0].Id,
						StartDate = tempDate,
						Customer_Purchase_Order_No__c = 'dummy data',
						Invoicing_Method__c = 'One Invoice per Work Order',
						Crew_Size__c = 2,
						Frequency = 1,
						FrequencyType = 'Months',
						GenerationTimeframe = 1,
						GenerationTimeframeType = 'Months',
						NextSuggestedMaintenanceDate = tempDate,
						WorkOrderGenerationMethod = 'One work order line item per asset',
						SvcApptGenerationMethod = 'One service appointment per work order',
						MaintenancePlanTitle = 'Dummy Title',
						Description = 'Dummy Description'
						);

But on Save, I get an error:
Result: [OPERATION FAILED]: classes/CS_WorkOrderTriggerHandler_Test.cls: Field does not exist: WorkOrderGenerationMethod on MaintenancePlan (Line: 313, Column: 5)
classes/CS_WorkOrderTriggerHandler_Test.cls: Field does not exist: SvcApptGenerationMethod on MaintenancePlan (Line: 313, Column: 5)
(bold added for highlights)
Now in my field list for Maintenance Plan I see :
Snippet showing the offending field names which error message says 'doesn't exist'

So, I've copy pasted the Names but same error.
I have check Field Level Security  - System Admin plus others are listed.
Thoughts or feedback?

Regards
Andrew
 
Hi
In the FSL managed package, from a Maintenance Plan there is an action "Generate Work Orders". 
Shows action menu for Generate Work Orders action
I have done some customisation which rely on the Work Order being generated from the Maintenance Plan.

For my test coverage, how do I invoke the "Generate Work Orders" action in a test class?

Regards
Andrew
Hi
I'm doing a trigger that is triggered from the Assigned Resource.  The trigger works in the UI, however, I'm having an issue with the Test Code.

I receive an error:
FIELD_CUSTOM_VALIDATION_EXCEPTION, Cannot change status from New to Scheduled: []

Now, if i do the same from the UI, there is no error regarding the status change.  The status change is allowed in the FSL administration.  I can assign using the dispatcher console - all good.  And I can mimic the process i'm using in the test code in the UI (editing the SA directly) with out error.  
Wondering if any one has seen this error before?
Code is included below:
@isTest static void test_AssignedResource_Insert() {
		List<AssignedResource> toInsert = new List<AssignedResource>();

		//retrieve a service resource
		List<ServiceResource> listSR = new List<ServiceResource>([SELECT Id, Name FROM ServiceResource WHERE Name = 'Technician One']);
		ServiceResource sr1 = listSR[0];

		// retrieve the Service Appointment created by test data
		List<WorkOrder> workOrders = new List<WorkOrder>([SELECT Id FROM WorkOrder WHERE Subject ='Test Subject1']);
		List<Id> woIds = new List<Id>();
		for (WorkOrder wo : workOrders ) {
			woIds.add(wo.Id);
		}
		if (woIds.size() > 0 ) {
			List<ServiceAppointment> appts = new List<ServiceAppointment> ();
			appts = [SELECT Id FROM ServiceAppointment WHERE Work_Order__c IN :woIds];
			//for all the appts - should be one - create an assigned resource
			if(appts.size()>0) {
				for( ServiceAppointment sa : appts ) {
					sa.SchedStartTime = datetime.newInstance(2019, 4, 19, 11, 00, 0);
					sa.SchedEndTime = datetime.newInstance(2019, 4, 19, 11, 30, 0);

					AssignedResource ar = new AssignedResource(ServiceAppointmentId=sa.Id,ServiceResourceId=sr1.Id);
					toInsert.add(ar);
				}
				update appts;

				insert toInsert;

				List<ServiceAppointment> assignedSA = new List<ServiceAppointment>([SELECT Id,Technician_Name__c FROM ServiceAppointment WHERE Work_Order__c IN :woIds]);
				System.assertEquals(assignedSA.size(), 1);
				System.assertEquals(assignedSA[0].Technician_Name__c,sr1.Name);

			} else {

			}


		} else {
			//exception
			System.assertNotEquals(woIds.size(), 0);
		}


	}
the error occurs on the insert of the assigned resources
insert toInsert;
IF i change the code such that I manually do the status change in the code example:
sa.SchedStartTime = datetime.newInstance(2019, 4, 19, 11, 00, 0);
sa.SchedEndTime = datetime.newInstance(2019, 4, 19, 11, 30, 0);
sa.Status = 'Scheduled';
the error is returned for the update of the service appointments.
update appts;

Feed back greatly appreciated.

Andrew




 
Hi
I'm playing with an Apex trigger for Work Order Object.   In the trigger,I have a need to reference a list of Work Types on multiple occassions, in different parts of the trigger.  The question relates to how do I minimise the number of times I do a SOQL to get those work types.
Example of Trigger
trigger cs_workorderTrigger on WorkOrder (before insert, after insert, after update) {
    if ( trigger.isBefore ) {
        if ( trigger.isInsert ) {
            CS_WorkOrderTriggerHandler.handleBeforeInsert( trigger.new );
	}
    } else {  //trigger is after
        if ( trigger.isInsert ) {
            CS_WorkOrderTriggerHandler.handleAfterInsert( trigger.new );
        } else {
            CS_WorkOrderTriggerHandler.handleAfterUpdate( trigger.new );
	}
    }
}
And my (cut down) hanlder looks like:
public with sharing class CS_WorkOrderTriggerHandler {
			
	public static void handleBeforeInsert(List<WorkOrder> newWorkOrders) {
		populateWorkOrder( newWorkOrders );
	}

	public static void handleAfterInsert(List<WorkOrder> workOrders){
		//declare some variables 
		List<Id> listWorkTypeIds = new List<Id>();

		//List of Ids where their is an auto generate feature enabled
		List<Worktype> workTypes = new List<WorkType>([SELECT Id FROM WorkType WHERE ShouldAutoCreateSvcAppt = TRUE]);

		for ( WorkOrder workOrder : workOrders ) {
			//do some stuff with work Order - like checking the work type Id
		}
	}


	public static void handleAfterUpdate(List<WorkOrder> oldWorkOrders, List<WorkOrder> workOrders, Map<Id,WorkOrder> newValues, Map<Id,WorkOrder> oldValues) {
		//declare some variables 
		List<Id> listWorkTypeIds = new List<Id>();

		//List of Ids where their is an auto generate feature enabled - HEY , THIS IS THE SAME AS THE AFTER INSERT QUERY

		for ( WorkOrder workOrder : workOrders ) {
			//do some other stuff with the work orders, and I still need the work type ids, but this work here is different to the after Insert stuff so i can't combine into a single method.
		}
	}

	public static void populateWorkOrder(List<WorkOrder>workOrders) {
		System.debug('DEBUG: populate Work Order');
		//Here I am going to do some other stuff, and I need that slightly different list of that Work Type Ids
		//something like 
		List<workType> workTypes = new List<WorkType>([SELECT Id,Customer_Type__c,Name FROM WorkType WHERE ShouldAutoCreateSvcAppt = TRUE]);
		//and play with the list a bit differently
	}

	public static void createServiceAppointments(WorkOrder workOrder, Integer saToCreate ) {
		//Create some records here
	}
	
}

I tried doing a constructor at the top of the trigger handler, but I was getting errors like "non static method can be called form static method" or something like that.  It basically broke the other methods I have within the trigger handler.

Any pointers appreciated.

Andrew G
Hello

I'm doing a bit of code where I'm checking if a Work Type Id in a Work Order is in a List for Work Type Ids, but the contains method does not seem to be detecting the match:
Code snippet 
List<ServiceAppointment> svcAppts = new List<ServiceAppointment>();

		//List of Ids where their is an auto generate feature enabled
		List<Id> listWorkTypeIds = new List<Id>();
		for ( WorkType wt : [SELECT Id FROM WorkType WHERE ShouldAutoCreateSvcAppt = TRUE] )  {
			listWorkTypeIds.add(wt.Id);
		}
		System.debug('DEBUG : Worktype count ' + listWorkTypeIds.size());

		
		for ( WorkOrder workOrder : workOrders ) {
			tempDecimal = workOrder.Crew_Size__c;
			crewSize  = tempDecimal.intValue();
			System.debug('DEBUG : crewSize: ' + crewSize);
			
			tempDecimal = workOrder.ServiceAppointmentCount;
			System.debug('DEBUG : RAW service count : ' + tempDecimal);
			System.debug('****DEBUG : list work type : ' + listWorkTypeIds[0]);
			System.debug('****DEBUG : WO work type : ' + workOrder.workTypeId);

			if (listWorkTypeIds.contains(workOrder.workTypeId)) {
				apptCount = tempDecimal.intValue() + 1;		
				System.debug('DEBUG : ADJUSTED service count : ' + tempDecimal);				
			} else {
				apptCount = tempDecimal.intValue();
				System.debug('DEBUG : SAME service count : ' + tempDecimal);
			}
Now, the debug looks like this:
08:10:49.875 (1834107162)|SOQL_EXECUTE_BEGIN|[92]|Aggregations:0|SELECT Id FROM WorkType 
08:10:49.875 (1848717624)|SOQL_EXECUTE_END|[92]|Rows:1
08:10:49.875 (1849133376)|USER_DEBUG|[95]|DEBUG|DEBUG : Worktype count 1
08:10:49.875 (1849315483)|USER_DEBUG|[101]|DEBUG|DEBUG : crewSize: 1
08:10:49.875 (1849418406)|USER_DEBUG|[104]|DEBUG|DEBUG : RAW service count : 0
08:10:49.875 (1849462073)|USER_DEBUG|[105]|DEBUG|****DEBUG : list work type : 08q0l00000001jtAAA
08:10:49.875 (1849543426)|USER_DEBUG|[106]|DEBUG|****DEBUG : WO work type : 08q0l00000001jtAAA
08:10:49.875 (1849692808)|USER_DEBUG|[113]|DEBUG|DEBUG : SAME service count : 0

So, the debug shows that the Ids are apparently the same, but the IF statement using the the contains does resolve to TRUE.

Any thoughts on what I am missing?

Regards
Andrew
 
Hello

Playing with Work Types and the Auto Create feature.  I know there is a check box to tick which will auto create the Service Appointments.
However, I have a need to generate multiple Service Appointments for a single Work Order.  The multiple appointments will have the same parameters as a crew will come together to do that particular piece of work.  (Note: the Service Crew feature in FSL does not meet the needs of the business).

Now, I have played with Process Builder to action this, but I get unusual results when the auto create feature is enabled.  (And yes, we do need the auto create feature for other business processes).
In process builder I can populate the address for the Work Order from the Case, and then address to Service Appointment from Work Order.  I can get the multiple service appointments by using the recursive feature of the Process Builder. 
However, if I set the WorkType to a type with Auto Create, I get extra Service Appointments and/or Service Appointments without addresses.

So, the question is, in the execution process of events, (i.e. before trigger, after triggers, process builder...etc), where does the Auto Create feature kick in ?  It is obviously part of the managed package and can't be viewed by us mere mortals, but it is happening, but when/where?
And a slight aside, when does the standard field Service Appointment Count (in Work Order) populate in that series of events?  As understanding that may also provide an option for a solution.

Part of the reason for asking is that I am looking to take this to a trigger, but I'm thinking i may run into the same issues there.

Regards
Andrew
Potentially silly question.

We have purchased Community Licenses and intend to have/offer our customers to use the Salesforce App to access our community page. (As well as being browser based).
With Community License there is an API limit.
The question would be "Does the Salesforce App interactions count against the API limits for the Community License?"

LIttle background - our company was considering constructing a custom App using RESTful API to interacts, and these I know would count.  Just curious if the Salesforce App operated in the same manner.

Regards
Andrew
Hello

Having an issue implementing some code which is to create a PDF document from a trigger.  I have used this as a reference/start point :
https://jungleeforce.wordpress.com/2014/06/11/generate-a-pdf-and-attach-it-to-record-from-a-trigger-in-salesforce-restful/comment-page-1/
The code:
public with sharing class SvcApptTriggerController {
	@Future(callout=true)
	public static void addPDFAttach(string sessionId, list<id> svcApptIdList){
		System.debug('@@@@@ in addPDFAttach of SvcApptTriggerController');

		HttpRequest req = new HttpRequest();
		req.setEndpoint('https://'+URL.getSalesforceBaseUrl().getHost()+'/services/apexrest/AddPDFtoSvcAppt/');
		req.setMethod('POST');
		req.setBody('{"svcApptIdList":'+JSON.serialize(svcApptIdList)+'}');
		req.setHeader('Authorization', 'Bearer '+ sessionId);
		req.setHeader('Content-Type', 'application/json');
		Http http = new Http();
		System.debug('@@@@@ before TEST if');
		if(!test.isRunningTest()){
			System.debug('@@@@@ in TEST if');
			HTTPResponse res = http.send(req);
		}
	}
}
The debug log snippet:
Error message from debug log - Unauthorised
Screenshot of remote Site settings:
Remote Site Settings

So the endpoint reported in the debug logs is in the remote site settings.
The PDF creation code works from the workbench - which obviously uses a different authentication model (name/password).

Feeling that I have missed something obvious.

Regards
Andrew
 
Hello
I am doing an inline table as a lightning component, but after the save event the button will not disappear.
I have found a post that mentions clearing the default values,
component.find("SADataTable").set("v.draftValues", null);
but playing with that line will cause the button to hide, but the table data does not reload after save.
I have also played with firing a refreshview, but no luck either
$A.get('e.force:refreshView').fire();
My component
<aura:component controller="ServiceAppointmentListController" implements="flexipage:availableForRecordHome,force:hasRecordId" access="global" >
    <aura:attribute name="recordId" type="Id" />
    <aura:attribute name="WorkOrder" type="WorkOrder" />
    <aura:attribute name="ServiceAppointments" type="ServiceAppointment" />
	<aura:attribute name="Columns" type="List" />
    <aura:attribute name="saveDraftValues" type="Object" />
    <aura:handler name="init" value="{!this}" action="{!c.myAction}" />
    <force:recordData aura:id="workOrderRecord" recordId="{!v.recordId}" targetFields="{!v.WorkOrder}" layoutType="FULL" />
    <lightning:card title="{! 'Service Appointment List for ' + v.WorkOrder.WorkOrderNumber}">
        <!-- Service Appointment list goes here -->
        <lightning:datatable 
                aura:id="SADataTable"
                keyField="Id" 
        		data="{! v.ServiceAppointments }" 
                columns="{! v.Columns }" 
                onsave="{!c.handleSave}" />
    </lightning:card> 
</aura:component>
The JS controller
({
	myAction : function(component, event, helper) {
        component.set("v.Columns", [
            {label:"Appt Id", fieldName:"AppointmentNumber", type:"text"},
            {label:"Duration", fieldName:"Duration", type:"number", editable : 'true'},
            {label:"Duration Type", fieldName:"DurationType", type:"text", editable : 'true'}
        ]);
		var action = component.get("c.getServiceAppointments");
        action.setParams({
            recordId: component.get("v.recordId")
        });
        action.setCallback(this, function(data) {
            component.set("v.ServiceAppointments", data.getReturnValue());
        });
        $A.enqueueAction(action);
	},
    handleSave: function (component, event, helper ) {
		helper.saveDataTable(component, event, helper);
    }
})
The helper manages the save and posts toast messages.
({
    saveDataTable : function(component, event, helper) {
        var editedRecords =  component.find("SADataTable").get("v.draftValues");
        var totalRecordEdited = editedRecords.length;
        var action = component.get("c.updateServiceAppointments");
        action.setParams({
            'editedSAList' : editedRecords
        });
        action.setCallback(this,function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                //***if update is successful ***
                if(response.getReturnValue() === true){
                    helper.showToast({
                        "title": "Record Update",
                        "type": "success",
                        "message": totalRecordEdited+" Service Appointment Records Updated"
                    });
                    helper.reloadDataTable();
                } else{ //***if update failed ***
                    helper.showToast({
                        "title": "Error!!",
                        "type": "error",
                        "message": "Error in update"
                    });
                }
            }
        });
        $A.enqueueAction(action);
    },

    //*** Show toast with provided params ***
    showToast : function(params){
        var toastEvent = $A.get("e.force:showToast");
        if(toastEvent){
            toastEvent.setParams(params);
            toastEvent.fire();
        } else{
            alert(params.message);
        }
    },
    //*** reload data table ***
    reloadDataTable : function(){
    var refreshEvent = $A.get("e.force:refreshView");
        if(refreshEvent){
            refreshEvent.fire();
        }
    }
})
For completeness, my Server Side controller
public class ServiceAppointmentListController {
    @AuraEnabled
    public static List<ServiceAppointment> getServiceAppointments(Id recordId) {
       return [SELECT Id, AppointmentNumber, Duration, DurationType  FROM ServiceAppointment WHERE ParentRecordId = :recordId];
    }
    
    @AuraEnabled
    public static boolean updateServiceAppointments(List<ServiceAppointment> editedSAList) {
        try {
            update editedSAList;
            return true;
        } catch(Exception e){
            return false;
        }
    }
}

Any assistance appreciated.  I have been troubleshooting this for a day, but seem to be going around in circles.
Regards
Andrew 





 

Hello all,

I've created a custom field called "Case_Queue__c" on the Case object. I want the field to display the name of the Queue the case is currently assigned to.

I thought I could use a formula on text field but it's not working:

IF( Owner:Queue.Id <> null, Owner:Queue.QueueName, "No Value" )

What am I missing, please?

Thank you,
B

Hey Guys,

i dont know why, but i am not able to cover the following switch statment.
public void createPdfSections(){
        List<OpportunityLineItem> oliList = [Select Id, Name, ListPrice, TotalPrice,  Quantity,  Product2.CustomQuoteCategory__c,      
                                            ON_Produktbeschreibung_detailliert__c, Produkt__c, CustomQuoteQuantity__c,Custom_Quote_List_Price__c,
                                            Product2.family, Product2.domain__c, Product2.size__c, Product2.Subname__c,SumListPrice__c
                                            FROM OpportunityLineItem
                                            WHERE OpportunityId =:opportunityId Limit 50];

        for(OpportunityLineItem oli : oliList){
            switch on oli.Product2.CustomQuoteCategory__c { // add the prdocuts to different sections for the vf template
                when 'BAS' {
                    sectionFlat.add(oli);
                }
                when 'EMP' {
                    sectionEmployerBranding.add(oli);  
                }
                when 'PER'{
                    sectionPerformance.add(oli);  
                }
                when 'SER'{
                    sectionService.add(oli);  
                }
                when else {
                    sectionSonstiges.add(oli);
                }
            }
        }
    }
Thats my test code : 
@isTest
public class TestCreateCustomOpportunityQuote {  
    @isTest private static void TestCreateCustomOpportunityQuote(){
   
         Opportunity opp = new Opportunity ();
         opp.name = 'test';
         opp.StageName = '40 - Demo Termin vereinbart';
         opp.CloseDate = System.today();
         insert opp;
        
         PageReference testPage = Page.CustomizeOpportunityQuote;
         testPage.getParameters().put('id', opp.id);
         Test.setCurrentPage(testPage);
         ApexPages.StandardController sc = new ApexPages.StandardController(opp);
         CreateCustomOpporutnityQuote tstCtrl = new CreateCustomOpporutnityQuote(sc);
         tstCtrl.opportunityId = testPage.getParameters().get(opp.id);
        
         tstCtrl.image = 'test';
         tstCtrl.secondtext = 'test';
         tstCtrl.subject = 'test';
         tstCtrl.firsttext = 'test';
         tstCtrl.pageBreak = false;
         tstCtrl.pageBreak1 = false;
         tstCtrl.pageBreak2 = false;
         tstCtrl.pageBreak3 = false;
         tstCtrl.qDate = System.today();
     } 
        
        @testSetup static void Setup(){
            Id pricebookId = Test.getStandardPricebookId();
            
            Product2 pro = new Product2();
            pro.name = 'test';
            pro.Produktbeschreibung_detailliert__c = 'test';
            pro.Family = 'Anzeigen Flat'; 
            pro.IsActive = true;
            insert pro;
            
            Product2 pro1 = new Product2();
            pro1.name = 'test1';
            pro1.Produktbeschreibung_detailliert__c = 'test';
            pro1.Family = 'Exklusiv Logo'; 
            pro1.IsActive = true;
            insert pro1;
            
            Product2 pro2 = new Product2();
            pro2.name = 'test2';
            pro2.Produktbeschreibung_detailliert__c = 'test';
            pro2.Family = 'Top Job'; 
            pro2.IsActive = true;
            insert pro2;
            
            Product2 pro3 = new Product2();
            pro3.name = 'test3';
            pro3.Produktbeschreibung_detailliert__c = 'test';
            pro3.Family = 'Dienstleistungen'; 
            pro3.IsActive = true;
            insert pro3;
            
            Product2 pro4 = new Product2();
            pro4.name = 'test4';
            pro4.Produktbeschreibung_detailliert__c = 'test';
            pro4.Family = 'Sonstiges'; 
            pro4.IsActive = true;
            insert pro4;
                        
            PricebookEntry pEntry = new PricebookEntry (); 
            pEntry.Product2Id = pro.id;
            pEntry.UseStandardPrice = false;
            pEntry.UnitPrice = 600; 
            pEntry.Pricebook2Id = pricebookId;
            pEntry.IsActive = true;
            insert pEntry; 
            
            PricebookEntry pEntry1 = new PricebookEntry (); 
            pEntry1.Product2Id = pro1.id;
            pEntry1.UseStandardPrice = false;
            pEntry1.UnitPrice = 600; 
            pEntry1.Pricebook2Id = pricebookId;
            pEntry1.IsActive = true;
            insert pEntry1;
            
            PricebookEntry pEntry2 = new PricebookEntry (); 
            pEntry2.Product2Id = pro2.id;
            pEntry2.UseStandardPrice = false;
            pEntry2.UnitPrice = 600; 
            pEntry2.Pricebook2Id = pricebookId;
            pEntry2.IsActive = true;
            insert pEntry2;
            
            PricebookEntry pEntry3 = new PricebookEntry (); 
            pEntry3.Product2Id = pro3.id;
            pEntry3.UseStandardPrice = false;
            pEntry3.UnitPrice = 600; 
            pEntry3.Pricebook2Id = pricebookId;
            pEntry3.IsActive = true;
            insert pEntry3;
            
            PricebookEntry pEntry4 = new PricebookEntry (); 
            pEntry4.Product2Id = pro4.id;
            pEntry4.UseStandardPrice = false;
            pEntry4.UnitPrice = 600; 
            pEntry4.Pricebook2Id = pricebookId;
            pEntry4.IsActive = true;
            insert pEntry4;
        
            Account acc = new Account();
            acc.name = 'testAcc';
            acc.BillingStreet = 'testStreet';
            acc.BillingCity = 'München';
            acc.BillingPostalCode = '80331';
            acc.BillingCountry = 'Deutschland';
            acc.RecordTypeId = '012D0000000BZ8L';
            insert acc;
            
            Account acc1 = new Account();
            acc1.name = 'testAcc1';
            acc1.BillingStreet = 'testStreet';
            acc1.BillingCity = 'Brüssel';
            acc1.BillingPostalCode = '020203';
            acc1.BillingCountry = 'Belgien';
            acc1.ON_UID_Nummer__c = 'U2323232';
            acc1.RecordTypeId = '012D0000000BZ8L';
            insert acc1;
            
            // Formelfeld --> query
            Account tstAcc = [Select ON_Steuerart__c FROM Account WHERE name = 'testAcc1'];
            system.assertEquals('Nicht steuerbar (EU mit UStID-Nr.)', tstAcc.ON_Steuerart__c );

            
            Contact con = new Contact();
            con.AccountId = acc.id;
            con.FirstName = 'böser';
            con.LastName = 'Moritz';
            con.Salutation = 'Herr';
            con.Briefanrede__c = 'Sehr geehrter';
            con.Entscheider__c = true;
            insert con;
            
            Contact con1 = new Contact();
            con1.AccountId = acc1.id;
            con1.FirstName = 'netter';
            con1.LastName = 'Moritz';
            con1.Salutation = 'Herr';
            con1.Briefanrede__c = 'Sehr geehrter';
            con1.Entscheider__c = true;
            insert con1;
            
            
            Opportunity opp = new Opportunity ();
            opp.AccountId = acc.Id; 
            opp.Name = 'test';
            opp.StageName = '40 - Demo Termin vereinbart';
            opp.Override_Region__c = 'München';
            opp.CloseDate = System.today();
            opp.z_Entscheider__c = con.id;
            opp.z_Vertragsbeginn__c = system.today();
            opp.z_Enddatum__c = system.today().addDays(360);
            opp.Type = 'Bestandskundengeschäft'; 
            opp.ON_Kein_Rabatt_ausweisen__c = false; 
            insert opp;
            
            system.assertEquals('test', opp.Name);

            Opportunity opp1 = new Opportunity ();
            opp1.AccountId = acc.Id; 
            opp1.Name = 'test1';
            opp1.StageName = '40 - Demo Termin vereinbart';
            opp1.Override_Region__c = 'München';
            opp1.CloseDate = System.today();
            opp1.z_Entscheider__c = con.id;
            opp1.z_Vertragsbeginn__c = system.today();
            opp1.z_Enddatum__c = system.today().addDays(360);
            opp1.Type = 'Bestandskundengeschäft'; 
            opp1.ON_Kein_Rabatt_ausweisen__c = true; 
            insert opp1;
            
            Opportunity opp2 = new Opportunity ();
            opp2.AccountId = acc1.Id; 
            opp2.Name = 'test2';
            opp2.StageName = '40 - Demo Termin vereinbart';
            opp2.Override_Region__c = 'München';
            opp2.CloseDate = System.today();
            opp2.z_Entscheider__c = con1.id;
            opp2.z_Vertragsbeginn__c = system.today();
            opp2.z_Enddatum__c = system.today().addDays(360);
            opp2.Type = 'Bestandskundengeschäft'; 
            opp2.ON_Kein_Rabatt_ausweisen__c = true; 
            insert opp2;
            
            OpportunityLineItem oli = new OpportunityLineItem ();
            oli.TotalPrice = 500;
            oli.Produkt__c = 'test';
            oli.Quantity = 4;
            oli.OpportunityId = opp.Id;
            oli.Product2Id = pro.id;
            oli.ON_Produktbeschreibung_detailliert__c = 'test';                            
            oli.PricebookEntryId = pEntry.id;
            insert oli;
            
            OpportunityLineItem oli1 = new OpportunityLineItem ();
            oli1.TotalPrice = 600;
            oli1.Produkt__c = 'test1';
            oli1.Quantity = 4;
            oli1.OpportunityId = opp.Id;
            oli1.Product2Id = pro1.id;
            oli1.ON_Produktbeschreibung_detailliert__c = 'test';                            
            oli1.PricebookEntryId = pEntry1.id;
            insert oli1;
            
            OpportunityLineItem oli2 = new OpportunityLineItem ();
            oli2.TotalPrice = 1000;
            oli2.Produkt__c = 'test2'; 
            oli2.Quantity = 4;
            oli2.OpportunityId = opp.Id;
            oli2.Product2Id = pro2.id;
            oli2.ON_Produktbeschreibung_detailliert__c = 'test';                            
            oli2.PricebookEntryId = pEntry2.id;
            insert oli2;
            
            OpportunityLineItem oli3 = new OpportunityLineItem ();
            oli3.TotalPrice = 1000;
            oli3.Produkt__c = 'test2'; 
            oli3.Quantity = 4;
            oli3.OpportunityId = opp.Id;
            oli3.Product2Id = pro3.id;
            oli3.ON_Produktbeschreibung_detailliert__c = 'test';                            
            oli3.PricebookEntryId = pEntry3.id;
            insert oli3;
            
            OpportunityLineItem oli4 = new OpportunityLineItem ();
            oli4.TotalPrice = 1000;
            oli4.Produkt__c = 'test2'; 
            oli4.Quantity = 4;
            oli4.OpportunityId = opp.Id;
            oli4.Product2Id = pro4.id;
            oli4.ON_Produktbeschreibung_detailliert__c = 'test';                            
            oli4.PricebookEntryId = pEntry4.id;
            insert oli4;
    
        }
    
        // positiver Test
        @isTest static void testSectionGenerator(){

            Opportunity opp = [SELECT Id, Name FROM Opportunity WHERE Name = 'test' LIMIT 1]; 
            System.assertEquals(opp.name, 'test');
            List<OpportunityLineItem> testList = [Select Id, Product2.CustomQuoteCategory__c FROM OpportunityLineItem  WHERE OpportunityId =: opp.Id Limit 50];
            System.assertEquals(testList.isEmpty(), false);

            ApexPages.StandardController sc = new ApexPages.StandardController(opp);
            CreateCustomOpporutnityQuote tstCtrl = new CreateCustomOpporutnityQuote(sc);
            Test.startTest();
            tstCtrl.createPdfSections();
            List<OpportunityLineItem> bas = tstCtrl.sectionFlat;
            List<OpportunityLineItem> emp = tstCtrl.sectionEmployerBranding;
            List<OpportunityLineItem> perv = tstCtrl.sectionPerformance;
            List<OpportunityLineItem> serv = tstCtrl.sectionService;
            List<OpportunityLineItem> sons = tstCtrl.sectionSonstiges;
            Test.stopTest();
        }
}
What i am doing wrong ? The switch statment is not covered and if i call the methode, it does not create values for the list variables.  

 

Hi,

I have one scenario where Account has one custom field Email__c(Long Text) and this account has multiple Contacts. Each contact Email field. I want to write a Trigger on  Contact when there is new contact comes it's email field also populate in the Account's custom field which is Email__c and all the email of contacts are separated by ; when we delete this contact it's Email also gets deleted from Account's custom field which is Email__c.

Please find enclosed code:-
trigger emailupdate on Contact (after insert, after update, after delete) {
    if(trigger.IsAfter && trigger.isInsert)
    {    
        List<Account> li = new list<Account>();
        List<Id> ids = new List<Id>();
        //String allEmailOfContacts = '';
        for(Contact c : trigger.new){
            ids.add(c.AccountId);
        }
        Map< Id, Account> accountMap = new Map<Id, Account>([Select Id,Email__c from Account where Id In:ids]);
        for(Contact c: trigger.new)
        {
            Account a = accountMap.get(c.AccountId);
            if(a != null)
            {
                a.Email__c += c.Email+ ';';
                //allEmailOfContacts = allEmailOfContacts + c.Email + ';';        
                li.add(a);
            }
        }
        update li;
    }

}

Hi,

I am getting 50% code coverage.
@RestResource(urlMapping='/leadactivity/getlist/*')
global with sharing  class myActivityTask {
    
    @HttpGet
    global static  list<cust_map> doGetLead(){
        
        list<task> activityLog=new list<task> ();
        Map<Task,Id> CombinedItems=new Map<Task,Id>();
        
        RestRequest req = RestContext.request;
        RestResponse res = RestContext.response;
        map<string,string> paramsMap=RestContext.request.params;
        string actdate=paramsMap.get('actdate');
        system.debug('Result' +actdate);
        Datetime dt1 = Datetime.valueOf(actdate);
        list<cust_map> results = new list<cust_map>();        
        list<Task> taskList=[SELECT Subject,CallType,CompletedDateTime,CreatedById,CreatedDate,WhoId,who.type FROM Task where CreatedDate>:dt1];
        
        for(task str:taskList){
            cust_map obj = new cust_map();
            if(str.who.type!='Lead')
                continue;
            
            Lead result = [SELECT ID FROM Lead WHERE Id = :str.WhoId];

            obj.CallObject =     str.Subject;
            obj.CallType = str.CallType;
            obj.CompletedDateTime = str.CompletedDateTime;
            obj.lId = result.ID;
            results.add(obj);
        }
       
        return results;
    }
    global class cust_map{
        Global String CallObject=null;
        Global String CallType=null;
        Global Datetime CompletedDateTime=null;
        Global String lId = null;
    }
       
}

Test class
========
@isTest
private class MyActivityTask_Test{
   
   public testmethod static void MyActivityTask(){
       
       // insert lead data
       lead l = new lead();
       l.LastName = 'Test Lead';
       l.Company = 'Test Company';
       l.Status = 'Closed - Converted';
       insert l;
       
       task t = new task();
       t.Subject = 'Test Subject';
       t.Status = 'new';
       t.Priority = 'Normal';
       t.CallType = 'Outbound';
       t.WhoId = l.Id;
       insert t;
       
       Test.startTest();
       
       // call custom controller
       myActivityTask mat = new myActivityTask();
       myActivityTask.cust_map wrap = new myActivityTask.cust_map();
       wrap.lId = t.WhoId;
       wrap.CompletedDateTime = t.CompletedDateTime;
     
       RestResponse res = new RestResponse();
       RestRequest req = new RestRequest();
       
       req.params.put('actdate', 'my_actdate');
       
       req.httpMethod = 'Get';
       req.addHeader('Content-Type', 'application/json'); // Add a JSON Header as it is validated
       req.requestURI = '/services/apexrest/https:/veditechnologies-dev-ed.my.salesforce.com/leadactivity/getlist' ;  
       RestContext.request = req;
       RestContext.response = res;
       
       List<myActivityTask.cust_map> results = myActivityTask.doGetLead();
       
       Test.stopTest();
     
   }
   
}

Thanks
I'm trying to get an opportunity field 'Opp Stage' to show up on the Account layout page under 'Account Stage' but this doesn't seem to be possible. In the past, using a simple formula, I've been able to show Account fields in the Opp page layout or the Contact page layout but not the other way around. 
I want to count the number of child records that were created within 90 days of the master record begin date. Is there a way to pass a Master Record variable to the filter of the roll-up summary? Or is there a more elegent way of getting this data? 
i have custom picklist field status__c on Account object with bellow values
None
Scheduled
Dispatched
In Progress
Completed
Cannot Complete
Canceled

in this piclist field if value None is selected then next time if i am going to update value there  should be only Scheduled,Canceled value display
likewise if  Scheduled is selected available option Dispatched,Canceled
if In Progress  is selected show Completed,Cannot Complete
  how can i achive that using flow

I am trying to update the Hours_Worked_Last_2_Weeks__c field on the Placement__c object through running a batch class on the related Timesheet__c object. Each Timesheet__c that meets the criteria, should add it's Total_Hours__c to it's Placement__c's Hours_Worked_Last_2_Weeks__c. I'm getting no error but the Hours_Worked_Last_2_Weeks__c is not populating.

Batch Class:

public class hfFlagB implements Database.Batchable<sObject>, Database.Stateful{
   List<Timesheet__c> tsList = [SELECT Id FROM Timesheet__c WHERE Status__c ='Approved' AND Week_Ending__c = LAST_N_DAYS:15 ];
   Set<String> tsSet = new Set<String>();
	public Database.QueryLocator start(Database.BatchableContext bc) {
     for(Timesheet__c ts : tsList){
        tsSet.add(ts.Id);
     }
        return Database.getQueryLocator('SELECT Id, Total_Hours__c, Placement__r.Hours_Worked_Last_2_Weeks__c, Placement__c FROM Timesheet__c WHERE Id IN :tsSet');
        }
   public void execute(Database.BatchableContext BC, List<Timesheet__c> a){
      for(Timesheet__c t : a){
         t.Placement__r.Hours_Worked_Last_2_Weeks__c +=  t.Total_Hours__c;   
        }
     }
   public void finish(Database.BatchableContext BC){
   }
}
I am creating events on Account object. In the event object I have two date/time fields Start Time and End Time.
My question is how I can validate new Start Time or End Time of an event exists with any  existing event related to an Account?

The only way I can think to validate if the sessions overlap is to use a trigger with the addError() method.
It means new event should not be created on an Account if there is an existing event relays with same date/time.
how can I compare the times of each event for an Account?

here is my trigger I am failing to achieve my requirement. Any one help me appretiated.
trigger sessionValidation on Event (before insert,before update) {
    Set<ID> accID = new set<ID>();

    for(Event eve : trigger.new)
    {
      accID.add(eve.AccountId);
    }
  
    List<Event> ExistingEventList = [Select StartDateTime , EndDateTime from Event where AccountID in : accID];
    system.debug('ExistingEventList :'+ExistingEventList);
    
    for(Event sNew : trigger.new)
    {
        
        for(Event sOld : ExistingEventList)
        {
                            if((sNew.StartDateTime <= sOld.StartDateTime && sNew.EndDateTime  >=  sOld.StartDateTime && sNew.EndDateTime <= sOld.EndDateTime) || 
                   (sNew.StartDateTime <= sOld.StartDateTime && sNew.EndDateTime  >= sOld.StartDateTime && sNew.EndDateTime >= sOld.EndDateTime) ||
                   )
            {
                sNew.addError('Overlap Session');
            }
        }
    }
}
 
  • October 22, 2019
  • Like
  • 0
I'm trying to prevent an opportunity from saving when StageName = Verification but picklist named Client equals No or is blank. The picklist value must equal Yes. 

Validation rule allows opportunity record to save if picklist value = No or if picklist value is blank. Can someone help me with this? thx
AND(
ISPICKVAL( StageName, 'Verification)'),
ISPICKVAL( Client_Verified__c, 'Yes'))

 
  • October 15, 2019
  • Like
  • 0
Hey guys, 

i have read several articels about best practice for triggers. Most of the 'rules' are easaly to understand and logical. 

One of the rules is 'less logic trigger'. I understand that it doesn't make sense to write very complex triggers.  But in my opinion, when i have one trigger per object, at least i have to tell trigger when he needs to fire the specific classes. 

To be more specific: 

I have three classes, each of them should be fired after a specific update: 

- 1 classe creates a copy of the opportunity (fire after closed won)
- 1 class creates different tasks (fire after the owner has changed)
- 1 class for an apex callout (fire after field is updated for the first time) 
- 1 class for handle recursion

All of these classes are related to the opportunity object. So i have to create one trigger with the context variable (after update).  Sometimes i can handle the logic within the class but often i need the trigger.oldmap variable to make sure, that the trigger act like it should.

so my trigger would look sth like
trigger opptrigger on Opportunity (after update) {

for (Opportunity opp : trigger.new){

if(!HelperClassTrigger.SetOfIDs.contains(opp.Id)){

Opporuntiy oldOpp = trigger.oldMap.get(opp.Id)

if( !oldOpp.isWon && opp.isWon){
// class for copy creation
}

if( !oldOpp.OwnerId != opp.OwnerId){
// class for owner change
}

if(String.IsEmpty(oldOpp.Field__c) 
&& !String.IsEmpty(old.Field__c)){
// class for callout
}
}
}





 
Hi Experts
How can i create a formula to Append Discount fileds (Percentge or number)

Actually the case is,
On Case Object, I created a field "Discount" and "Discount History". In our organisation, time to time we offer certain value of discounts to our customers and I tried creating something to track the discount history like when was the last discount given to this account and last discount value using this formula.

$User.LastName + ', ' + $User.FirstName + ' ' + TEXT(Today()) + ' - ' + Discount__c + BR() + BR() + Discount_History__c
"But I am getting error that expected TEXT and recieved number" because discount is a number.

Any help will be highly appreciated.
Thanks
I am trying to query salesforce data based on information that I am pulling from our HR system via a REST API callout to the HR system. 

Basically I am tring to find all contacts in my Salesforce org where the first name = the first name in the API Call. I know that first name is not specific enough, but I am starting here and once I can get records to match I will use a more unique identifier. 

Here is my code. I NEED HELP WITH LINE 28! I have left out authorization lines for privacy sake. 
 
request.setMethod('GET');
    HttpResponse response = http.send(request);
    // If the request is successful, parse the JSON response.
    if (response.getStatusCode() == 200) {
        // Deserializes the JSON string into collections of posts.
        Map<String,Object> wrapper = (Map<String,Object>) JSON.deserializeUntyped(response.getBody());
        if (wrapper.containsKey('data')) {
            Map<String, Object> wrapper2 = (Map<String,Object>) wrapper.get('data');
            if(wrapper2.containsKey('data')) {
                List<Object> people = (List<Object>)wrapper2.get('data');
                for (Object peopleWrapper : people) {
                    Map<String,Object> Employees = (Map<String,Object>) peopleWrapper;
                    if(Employees.containsKey('last_name')){
                    String ZenefitsLastName = (String) Employees.get('last_name');
                    String ZenefitsFirstName = (String) Employees.get('first_name');
                    String ZenefitseEmployeeId = (String) Employees.get('id');
                        
                        List<Contact> contactList = [SELECT Id, FirstName, LastName FROM Contact WHERE FirstName = Employees.get('first_name') LIMIT 200];
                        
					//we now need to find all contacts in SF that match the contacts in Employees
                    //once we have matches we need to synce each ID 
                   
                        
         
                            system.debug('Employees ' + Employees);
                            system.debug('last name ' + ZenefitsLastName);
                        	system.debug('Employee id ' + ZenefitseEmployeeId);
                        	system.debug('first name ' + ZenefitsFirstName);
                            system.debug('Contact list ' + contactList);
                            
                   			}
               			}
            		}
            
            return null;
        }
        return null;
    }
    return null;
}

 
I am trying to write an Apex Trigger that will automatically assign a value of 'Meeting' to the custom picklist field Activity_Type__c on the Event object. Because this is a required field, the only way it can be Null is if the Event was created through Lightning Sync from Outlook to Salesforce. I am getting a code coverage error for this. Does anyone have any ideas on improving this code?

trigger Update_Event_Activity_Type on Event (before insert) {

     try {  
    
    //iterate over the new activities
    for(Event newEvent : trigger.new){
        if(newEvent.Activity_Type__c == Null){
            newEvent.Activity_Type__c = 'Meeting';
        }  
     }            
    }
    
    Catch(Exception e){
      system.debug(e);
    }
}

We are happy to provide a space for you to list developer and admin openings that may be of interest to the Force.com community. Please ensure your posts are effectively titled with the position and location you're looking for, and don't forget to include instructions for applying or getting in touch with you when you post. 

 

If you are a developer looking for work, you are allowed to post that here, however you are not allowed to post the same information repeatedly (spamming). You also may not use this space for advertising your business. 

 

This board is offered as a service to our community and those found to be abusing it will be banned from posting. Examples of abuse include posting blanket generic responses to job listings & starting new topics that only serve to advertise your business.

 

I welcome your feedback and suggestions!