• Andrew G
  • PRO
  • 4112 Points
  • Member since 2014
  • Salesforce Learner

  • Chatter
    Feed
  • 134
    Best Answers
  • 0
    Likes Received
  • 1
    Likes Given
  • 15
    Questions
  • 717
    Replies
@RestResource(urlMapping='/v1/BookDetails/')
global class bookManager 
{
@httpGet
global static Book__c doGetBook()
{
    Book__c book = new Book__c();
    Map<String,String> paramsMap = RestContext.request.params;
    String bookId = paramsMap.get('Id');
    book = [select Id, Name, Price__c from Book__c where Id IN =: bookId]; // getting sytax error in this line
    return book;
}
}
Hi and thanks in advance for any help.
Situation:
I wrote a web service to grab new cases from an external source.  That part works fine, BUT an after update trigger fires when uploading new cases and i get a ''Apex CPU time limit exceeded".  I thought if I skipped the Record Type it would skip the trigger code. 
This line causes the error is the for loop, which occurs before the RT check:
for (Case cse : Trigger.new){
trigger CompleteResolutionTimeMilestone on Case (after update) {
    
    for (Case cse : Trigger.new){        
        system.debug('cse.RecordTypeId ' + cse.RecordTypeId);
        if (cse.RecordTypeId != Schema.Sobjecttype.Case.getRecordTypeInfosByDeveloperName().get('Maintenance').getRecordTypeId()){
          if (UserInfo.getUserType() == 'Standard'){
        
           DateTime completionDate = System.now(); 
              List<Id> updateCases = new List<Id>();
              for (Case c : Trigger.new){
                  if (((c.isClosed == true)||(c.Status == 'Closed'))&&((c.SlaStartDate 
                        <= completionDate)&&(c.SlaExitDate == null)))
            updateCases.add(c.Id);
                       }
    if (updateCases.isEmpty() == false)
        milestoneUtils.completeMilestone(updateCases, 'Support Resolution Time', completionDate);
    }
        }// end if (cse.RecordTypeId !=
    }
}
Regards,
Eric
 
        
 
I think I am iterating ov erht same list twice.  Will someone help me streamline the code.  Can I get the second for loop inside the first and be efficient?
Attachment__c newAttachment = (Attachment__c ) so;
        String objectType;
        List<Plan__c > palnId = new List<Plan__c>();
        Map<String,String> planMap = new Map<String,String>();
        
        if( this.linkMap.containsKey( newAttachment.ContentDocumentId__c ) ){
            List<ContentDocumentLink> links = this.linkMap.get( newAttachment.ContentDocumentId__c );
            if( !links.isEmpty() ){
                for( ContentDocumentLink link : links ){
                    objectType = String.valueOf( link.LinkedEntityId.getSObjectType() );
                    switch on ( objectType ){
                        when 'Activity__c' {
                            newAttachment.Activity__c= link.LinkedEntityId;
                        }
                        when 'Project__c' {
                            newAttachment.Proj__c= link.LinkedEntityId;
                        }
                    }
                }
            }
    
            List<Plan__c> plans= new List<Plan__c>();

            for (ContentDocumentLink cont : links ){                    
                if(newAttachment.Activity__c != null || newAttachment.Proj__c != null){
                    ContentDocumentLink cdl = new ContentDocumentLink();
                    cdl.LinkedEntityId = parentId;
                    cdl.ContentDocumentId = cont.ContentDocumentId;
                    cdl.ShareType = 'V';
                    cdl.Visibility = 'AllUsers';
                    cdl_List.add(cdl);
                    break;
                }
            }
        }

 
Hello Salesforce community!

I am having issues with the below formula checkbox to validate.  I am receiving the error 'Incorrect number of parameters for function 'IF()'. Expected 3, received 4'.  It has to be something silly such as a misplaced bracket - Any help would be greatly appreciated!
 
/* If the override is checked, this field should be true */
IF( Marketing_Cloud_Sync_Override__c = True, True,

/* If the unSync is checked, this field should be false */
IF( Marketing_Cloud_unSync_Override__c  = True, False,

/* For Member Contacts, if they are 18 or above and the status is set to active, this field should be true */
IF( RecordType.DeveloperName = "Member" &&
    FLOOR((TODAY()-Birthdate)/365.2425) >= 18 &&
    ISPICKVAL(Contact_Status__c , "Active"),True,False,

/* For Lead Contacts, if they are 18 or above, email is not blank, the contact is less than a year old, this field should be true */
IF( RecordType.DeveloperName = "Lead" &&
    FLOOR((TODAY()-Birthdate)/365.2425) >= 18 &&
    (NOT ISBlank(Email)) &&
    (TODAY()-DATEVALUE(CreatedDate)<= 365),True,False,

/* For Group Contacts, if the email is not blank, this should should be true */
IF( RecordType.DeveloperName = "Group_Contact" &&
   (NOT ISBlank(Email)),True,False,False)))))

 
Hello,
I have the following trigger on Case that defaults entitlements on Case record. I need to have 75% code coverage but i only managed to get 57% (found it on internet). Could anyone help me and amend the below test class to achieve the 75%?
Also, i don't really need the trigger to look at Contacts, only at Account level so that could be removed from the trigger if it is easier with writing the test class.
I would appreciate your help.
EwaUser-added image

The TRIGGER
trigger DefaultEntitlement on Case (Before Insert, Before Update) {
    Set<Id> contactIds = new Set<Id>();
    Set<Id> acctIds = new Set<Id>();
    for (Case c : Trigger.new) {
        contactIds.add(c.ContactId);
        acctIds.add(c.AccountId);
    }
    
    List <Entitlement> entls = [Select e.StartDate, e.Id, e.EndDate, 
                e.AccountId, e.AssetId
                From Entitlement e
                Where e.AccountId in :acctIds And e.EndDate >= Today 
                And e.StartDate <= Today];
        if(entls.isEmpty()==false){
            for(Case c : Trigger.new){
                if(c.EntitlementId == null && c.AccountId != null){
                    for(Entitlement e:entls){
                        if(e.AccountId==c.AccountId){
                            c.EntitlementId = e.Id;
                            if(c.AssetId==null && e.AssetId!=null)
                                c.AssetId=e.AssetId;
                            break;
    
    
                    }
                } 
            }
        } 
    } else{
        List <EntitlementContact> entlContacts = 
                [Select e.EntitlementId,e.ContactId,e.Entitlement.AssetId 
                From EntitlementContact e
                Where e.ContactId in :contactIds
                And e.Entitlement.EndDate >= Today 
                And e.Entitlement.StartDate <= Today];
    if(entlContacts.isEmpty()==false){
        for(Case c : Trigger.new){
            if(c.EntitlementId == null && c.ContactId != null){
                for(EntitlementContact ec:entlContacts){
                    if(ec.ContactId==c.ContactId){
                        c.EntitlementId = ec.EntitlementId;
                        if(c.AssetId==null && ec.Entitlement.AssetId!=null)
                            c.AssetId=ec.Entitlement.AssetId;
                        break;
                        }
                    } 
                }
            } 
        }
    }
}


THE TEST CLASS

@isTest
private class DefaultEntitlementTest {

    static testMethod void myUnitTest() {
        Account acc = new Account(Name='testacc');
        insert acc;

        Contact con = new Contact(FirstName='john', LastName='doe', Email='john@doe.com', AccountId=acc.Id);
        insert con;

        Asset ass = new Asset(AccountId=acc.Id,ContactId=con.Id, Name='testing');
        insert ass;

        Entitlement ent = new Entitlement(Name='Testing', AccountId=acc.Id, StartDate=Date.valueof(System.now().addDays(-2)), EndDate=Date.valueof(System.now().addYears(2)), AssetId=ass.Id);
        insert ent;

        Entitlement ent2 = new Entitlement(Name='test2', AccountId=acc.Id, StartDate=Date.valueof(System.now().addDays(-10)), EndDate=Date.valueof(System.now().addYears(3)));
        insert ent2;

        EntitlementContact ec = new EntitlementContact(EntitlementId=ent.Id, ContactId=con.Id);
        insert ec;

        List<Case> listC = new list<Case>();
        List<Id> newCaseIds = new List<Id>();
        for(Integer i=0;i<20;i++){
            Case c = new Case(ContactId=con.Id, AccountId=con.AccountId, Subject='Test Subject'+i, Origin='Webform_B2B');

            listC.add(c);
        }
        test.startTest();
        insert listC;

        test.stopTest();
        for (Case caseObj:listC) {
            newCaseIds.add(caseObj.Id);
        }

        List<Case> entls = [Select EntitlementId, AssetId, ContactId, AccountId From Case Where Id in :newCaseIds];

        for (Case caseObj:entls) {

            System.debug(caseObj.Id + ' here are the values ' + caseObj.EntitlementId + ' and here ent.Id ' + ent.Id);

            System.assertEquals(caseObj.EntitlementId, ent.Id);

        }
        Contact con2 = new Contact(FirstName = 'Jane',
        LastName = 'Doe',
        Email='jane@doe.com');

        insert con2;
        Entitlement ent3 = new Entitlement(Name='Testing', AccountId=acc.Id, StartDate=Date.valueof(System.now().addDays(2)), EndDate=Date.valueof(System.now().addYears(2)), AssetId=ass.Id);
        insert ent3;

        EntitlementContact ec2 = new EntitlementContact(EntitlementId=ent3.Id, ContactId=con2.Id);
        insert ec2;
        Case c1 = new Case(ContactId=con2.Id, AccountId=con.AccountId, Subject='Test Subject', Origin='Webform_B2B');
        insert c1;
        update c1;
    }
}
I have minimal Salesforce development experience and I am struggling with getting a test class built to cover 2 triggers.

In the following Salesforce help article there are 2 triggers, 1 to auto-complete a milestone when an email is sent to the case contact, and a second to complete a milestone when the case is marked complete.
https://help.salesforce.com/articleView?id=entitlements_milestones_trigger.htm&type=5 (http://https://help.salesforce.com/articleView?id=entitlements_milestones_trigger.htm&type=5)
There is also a util class and test class for the until. Everything works great in my DEV sandbox; however, I can't promote to production as I don't have min 75% code coverage. I don't have any other custom APEX in my org. Below are the 2 triggers, any assistance with a test class would be much appreciated.

Case object trigger;
trigger CompleteResolutionTimeMilestone on Case (after update) {
if (UserInfo.getUserType() == 'Standard'){
    DateTime completionDate = System.now(); 
        List<Id> updateCases = new List<Id>();
        for (Case c : Trigger.new){
                if (((c.isClosed == true)||(c.Status == 'Closed'))&&((c.SlaStartDate 
                    <= completionDate)&&(c.SlaExitDate == null)))
    updateCases.add(c.Id);
    }
if (updateCases.isEmpty() == false)
    milestoneUtils.completeMilestone(updateCases, 'Case Resolved', completionDate);
}

email message object trigger;
trigger CompleteFirstResponseEmail on EmailMessage (after insert) {
if (UserInfo.getUserType() == 'Standard'){
    DateTime completionDate = System.now();
    Map<Id, String> emIds = new Map<Id, String>();
    for (EmailMessage em : Trigger.new){
        if(em.Incoming == false)
            emIds.put(em.ParentId, em.ToAddress);
    }
    if (emIds.isEmpty() == false){
        Set <Id> emCaseIds = new Set<Id>();
        emCaseIds = emIds.keySet();
            List<Case> caseList = [Select c.Id, c.ContactId, c.Contact.Email,
                c.OwnerId, c.Status,
                c.EntitlementId,
                c.SlaStartDate, c.SlaExitDate
                From Case c where c.Id IN :emCaseIds];
        if (caseList.isEmpty()==false){
                List<Id> updateCases = new List<Id>();
                for (Case caseObj:caseList) {
                    if ((emIds.get(caseObj.Id)==caseObj.Contact.Email)&&
                        (caseObj.EntitlementId != null)&&
                        (caseObj.SlaStartDate <= completionDate)&&
                        (caseObj.SlaStartDate != null)&&
                        (caseObj.SlaExitDate == null))
                            updateCases.add(caseObj.Id);
                }
                if(updateCases.isEmpty() == false)
                    milestoneUtils.completeMilestone(updateCases, 
                            'First Response', completionDate);
        }
    }
}

 
Hello, I am getting the following error message. This is my first Apex Trigger and would really appreciate some help. The trigger looks up the lead postalcode in a custom object of zip codes and territory information and populates a lookup field on the lead with the record id of the corresponding zip code in the custom object.
System.LimitException: Too many SOQL queries: 101

Are there any changes I can make to elimate this error? Here is the code:
1trigger LeadAssignmentTrigger on Lead (before insert, before update)
2{
3    List<Lead> leadsToUpdate = new List<Lead>();3
4
5    for (Lead lead : Trigger.new)
6    {    
7      if (lead.PostalCode != NULL)
8      {
9          // Find the sales rep for the current zip code
10          List<Territory_Zip_Codes__c> zip = [select id from Territory_Zip_Codes__c
11                             where Name = :lead.PostalCode limit 1];     
12               
13          // if you found one
14          if (zip.size() > 0)
15          {   
16              //assign the lead owner to the zip code owner
17              lead.Territory_Zip_Code__c = zip[0].id;
18         
19              leadsToUpdate.add(lead);
20         
21          }
22       }
23    }
24}
  • December 22, 2020
  • Like
  • 0
Hi there,
I am getting a code coverage failure warning. I'm not a developer, so I don't know where I went wrong? Thank you for your help.

1. I created an Apex Trigger and Apex Test Class
2. I attempted to deploy the change set and received:

Error: Code Coverage Failure
Your organization's code coverage is 0%. You need at least 75% coverage to complete this deployment. Also, the following triggers have 0% code coverage. Each trigger must have at least 1% code coverage.

Apex Trigger
trigger FeedCommentUpdatetoNetPlanning on FeedComment (after insert) 
{
    Id profileId = UserInfo.getProfileId();
    String profileName =[Select Id, Name from Profile where Id=:profileId].Name;
    Set<id> SalesEngineeringSet = new Set<Id>();
    List<SALES_ENGINEERING_REQUEST__c> serList = new List<SALES_ENGINEERING_REQUEST__c>();
    for(FeedComment f : Trigger.New)
    {
        if(profileName  == 'GeoLinks Net Planning')
        {
            SalesEngineeringSet.add(f.ParentId);
        }          
    }
    
    if(!SalesEngineeringSet.IsEmpty()){
        for(SALES_ENGINEERING_REQUEST__c ser : [SELECT ID,Status__c FROM SALES_ENGINEERING_REQUEST__c WHERE ID In: SalesEngineeringSet]){
            if(ser.Status__c != 'Approved' && ser.Status__c != 'Unable to Meet Request'){
                ser.Status__c = 'Awaiting Reply from Rep';
                serList.add(ser);
            }
        }
    }
    
    if(!serList.IsEmpty())
        update serList;
}

Test Class
@isTest
public class FeedCommentUpdatetoNetPlanning {
    
    @isTest
    public static void testFeedCommentUpdatetoNetPlanning() {
        
        //Create a User with Profile 'Net Planning Department'
        Id pid = [Select Id FROM Profile WHERE Name = 'Net Planning Department'].Id;
        
        User u = new User();
        u.ProfileId = pid;
        //here fill all the required fields for the User Record
        insert u;
        
        SALES_ENGINEERING_REQUEST__c s = new SALES_ENGINEERING_REQUEST__c();
        s.Status__c = //any Value othe than "Approved" and "Unable to Meet Request"
        //here fill all the required fields for the SALES_ENGINEERING_REQUEST__c Record
        s.Name = 'Test SER 1';
        s.Layer__c = 'Layer 2';
        
        //Since test class runs in the current user mode and in this Trigger lines will be covered only when the    //User has a Profile - 'Net Planning Department' hence we need trigger this event as the new User created with this //Profile
        System.runAs(u) {
            FeedComment f = new FeedComment();
            //here fill all the required fields for FeedCommentRecord
            
            Test.startTest();
            insert f;
            Test.stopTest();
        }
        
        
        SALES_ENGINEERING_REQUEST__c updatedRecord = [SELECT Id,Status__c  FROM SALES_ENGINEERING_REQUEST__c WHERE Id =: s.Id];
        System.assertequals('Approved',updatedRecord.Status__c);
    }
    
}
I'm not sure why it's failing when I try to run 1000 records through. Anything I can do? 

Here's my Trigger:
trigger PlaybooksEnrollmentLead on Lead (before update, after update) {
    
    if(trigger.isbefore) {
        Map<Id, Lead> leadMap = new Map<Id, Lead>();
        for(Lead l : trigger.new) {
            Lead oldLead = trigger.oldMap.get(l.Id);
    
            if(oldLead.Playbooks_Play_Name__c != l.Playbooks_Play_Name__c && l.Playbooks_Play_Name__c != null) {
                // Pass this to class that creates new Enrollment
                PlaybooksEnrollmentEngine.CreateRecordLead(trigger.new);
            } else if(oldLead.Playbooks_Play_Status__c != l.Playbooks_Play_Status__c  ||
                       oldLead.Playbooks_Step_Number__c != l.Playbooks_Step_Number__c) {
                leadMap.put(l.Id, l);
                PlaybooksEnrollmentEngine.UpdateEnrollmentLead(leadMap);
            }
        }
    }

    if(trigger.isAfter) {
        Map<Id, Lead> leadMap = new Map<Id, Lead>();
        for(Lead l : trigger.new){
            if(l.IsConverted == TRUE && l.Playbooks_Play_Name__c != null && l.Playbooks_Play_Status__c != 'Failure' && l.Playbooks_Play_Status__c != 'Unenrolled') {
                leadMap.put(l.Id, l);
                PlaybooksEnrollmentEngine.LeadConverted(leadMap);
            }
        }
    }
    
}
And here's my Class:
public class PlaybooksEnrollmentEngine {

    public static void CreateRecordLead(List<Lead> leads) {
        
        // Create a list that inserts the PB Enrollment records
        List<Playbooks_Enrollment__c> insertList = new List<Playbooks_Enrollment__c>();

        for(Lead l : leads){
            // Create new Playbooks Enrollment record
            Playbooks_Enrollment__c pbE = new Playbooks_Enrollment__c();

            pbE.Object_Enrolled__c = 'Lead';
            pbE.Lead__c = l.Id;
            pbE.Name             = l.Playbooks_Play_Name__c;
            pbE.Enroller__c      = l.LastModifiedById;
            pbE.Play_Name__c     = l.Playbooks_Play_Name__c;
            pbE.Next_Step_Due__c = l.Playbooks_Next_Step_Due_Date__c;
            pbE.Play_Status__c   = l.Playbooks_Play_Status__c;
            pbE.Step_Number__c   = l.Playbooks_Step_Number__c; 

            if(!insertList.contains(pbE)){
                insertList.add(pbE);
            }
        }

        insert insertList;
    }
}

It's currently happening when I update the fields to trigger on Before Update, not the conversion part. Any help is appreciated, thanks!
My organization uses Conga to manage contracts. These contracts can have up to 5 related “Legal Entities”, and we have five Legal Entity lookup fields on the Contract Agreement object. Ideally we would use a junction object, but I was overruled. Now I am trying to write APEX that combines all related agreements on the Legal Entity record page, regardless which legal entity field they are related to, and display it on a visual force page.


I’ve stumbled through writing the controller and visualforce page.

However, I am having trouble with achieving 75% code coverage with a test .


Here is my class
public class CombineContractAgreement {
    Id LegalEntityId;
public CombineContractAgreement(ApexPages.StandardController controller){
    LegalEntityId = ((SB_Legal_Entity__c)controller.getRecord()).Id;
    }

    public List<APXT_Redlining__Contract_Agreement__c>GetAllRelatedAgreement()
    {
     List <APXT_Redlining__Contract_Agreement__c> AllRelatedAgreements;
        AllRelatedAgreements = [SELECT Name, Agreement_Type__C, APXT_Redlining__Status__c, APXT_Redlining__Effective_Date__c,
        Agreement_Name__c FROM APXT_Redlining__Contract_Agreement__c WHERE Customer_Legal_Entity__c = :LegalEntityId OR Customer_Legal_Entity_2__c = :LegalEntityId OR 
                                Customer_Legal_Entity_3__c = :LegalEntityId OR Party_4__c = :LegalEntityId OR Party_5__c = :LegalEntityId];
                                    return AllRelatedAgreements;
    }
}

Visualforce
<apex:page StandardController="SB_Legal_Entity__c" extensions="CombineContractAgreement" lightningStylesheets="true">
    <apex:pageBlock title="All Related Agreements">
        <apex:pageBlockTable value="{!AllRelatedAgreement}" var="item">
            <apex:column >
                <apex:outputLink value="https://hyclonehorizon--sb1.lightning.force.com/{!item.ID}">{!item.Name}</apex:outputLink>
            </apex:column>    
            <apex:column value="{!item.Agreement_Name__c}" />
            <apex:column value="{!item.Agreement_Type__c}" />
            <apex:column value="{!item.APXT_Redlining__Status__c}" />
            <apex:column value="{!item.APXT_Redlining__Effective_Date__c}" />
        </apex:pageBlockTable>
    </apex:pageBlock>
</apex:page>

Test Class
@isTest
public class CombineContractAgreementTest {
    
    static testMethod void testMethod1(){

        //Create required legal alias for Legal Entitiy Object
        Legal_Alias__c ali = new Legal_Alias__c();
        ali.Name     = 'NameLegalAlias';
        system.debug('The Legal Alias name is '+ali.Name);
        insert ali;
        

		//Create Legal Entity
        SB_Legal_Entity__c testEntity = new SB_Legal_Entity__c();
        testEntity.Legal_Alias__c = ali.Id;
        testEntity.Name     = 'testLegalEntity';
        insert testEntity;
        
        //Create Contract Agreement
        APXT_Redlining__Contract_Agreement__c testAgreement = new APXT_Redlining__Contract_Agreement__c();
        testAgreement.Customer_Legal_Entity__c          = testEntity.id;
        testAgreement.APXT_Redlining__Status__c         = 'inactive';
        testAgreement.APXT_Redlining__Effective_Date__c = date.today();
        testagreement.Agreement_Name__c                 = 'TestAgreement';
        insert testAgreement;
        System.debug('The Contract Agreements Legal Entity is' + testAgreement.Customer_Legal_Entity__c);
        
        
      Test.StartTest();
        //current page equal the legal entity page
        ApexPages.StandardController stdctrl = new ApexPages.StandardController(testEntity);
        ApexPages.currentPage().getParameters().put('id',testEntity.Id);
        CombineContractAgreement testCombineAgree = new CombineContractAgreement(stdctrl);
        stdctrl.cancel();
      Test.Stoptest();

        }


        
    }

Result:
User-added image​​​​​​​
 

Hello everyone!
I am trying to reach 100% test coverage for the following code, currently it's 88%. I received this error: 

System.DmlException: Insert failed. First exception on row 0; first error: INVALID_CROSS_REFERENCE_KEY, Cannot create a portal user without contact: [ContactId]

The profile is a community user profile, how can I solve this problem. Any help would be welcome, thank you.
 
public class StudentCheckController {
    public List<Class__c> classes{get; set;}
    String dayFormat = 'MM/DD';
    public Id classId{get; set;}
    public string userEmail{get;set;}
    public string userProfile;

    public StudentCheckController(ApexPages.StandardController sc) {
        userEmail = UserInfo.getUserEmail();
        userProfile = UserInfo.getProfileId();
        System.debug(userProfile);
        getClasses();

    }
    public void getClasses() {
        Id cohortRecordTypeId = Schema.SObjectType.class__c.getRecordTypeInfosByName().get('Cohort').getRecordTypeId();

        System.debug(cohortRecordTypeId);
        // Limit visibility to SSS community user
        if(userProfile != '00a7i000000dSK9OOL') {
            
            classes = [ SELECT
                id,
                name,
                class_nights__c,
                start_date__c,
                end_date__c,
                status__c,
                class__c,
                instructor__r.email
                FROM class__c WHERE RecordTypeId = :cohortRecordTypeId AND status__c = 'Active'];
                System.debug(classes);

        } else {
            classes = [ SELECT
                id,
                name,
                class_nights__c,
                start_date__c,
                end_date__c,
                status__c,
                class__c,
                instructor__r.email
                FROM class__c WHERE  RecordTypeId = :cohortRecordTypeId AND status__c = 'Active' AND instructor__r.email = :userEmail];
                System.debug(classes);

        }
    }

    public Pagereference newPage() {
        // Pagereference pf = new Pagereference('/apex/StudentList?id=' + classId);
        Pagereference pf = new Pagereference('https://armhat.force.com/coordinatorportal/StudentList?id=' + classId);
        return pf;
    }
}
 
Test Class:


@isTest
public class StudentCheckControllerTest {
   

static testMethod void testGetClassesNotEqualToProfile(){
        class__c newClass = new class__c(name = 'Test Class', class_nights__c = 'Monday / Wednesday', start_date__c = date.today() - 10, end_date__c = date.today() + 45);
        insert newClass;
        ApexPages.StandardController sc = new ApexPages.StandardController(newClass);
        StudentCheckController pc = new StudentCheckController(sc);
        pc.userEmail = 'test@gmail.com';
        pc.newPage();
        pc.userEmail = 'dreyes@armhat.com';
        pc.getClasses();
    }

static testMethod void testGetClassesEqualToProfile(){
        
        UserRole portalRole = [Select Id From UserRole Where PortalType = 'None' Limit 1];
        system.debug('portalRole is ' + portalRole);
        
        Profile p = [SELECT Id FROM Profile WHERE Id='00a7i000000dSK9OOL']; 

        User u = new User(Alias = 'testUser', UserRoleId = portalRole.Id, Email='standarduser@testorg.com', 
        EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US', 
        LocaleSidKey='en_US', ProfileId = p.Id, 
        TimeZoneSidKey='America/New_York', UserName='testUser@example.com');
        

        System.runAs(u) {
        

class__c newClass = new class__c(name = 'Test Class', class_nights__c = 'Monday / Wednesday', start_date__c = date.today() - 10, end_date__c = date.today() + 45);
        insert newClass;
        ApexPages.StandardController sc = new ApexPages.StandardController(newClass);
        StudentCheckController pc = new StudentCheckController(sc);
        pc.userEmail = 'test@gmail.com';
        pc.newPage();
        pc.userEmail = 'dreyes@armhat.com';
        pc.getClasses();
    }

Hi, 
I have a before update trigger on an account number field which increments the number field by 1 every time a record is updated or created new.
Also, a process builder on the same field and doing the same increments on the same field by one so when I put value "1" in that field it updates it to 4 so does that means trigger executes again after process builder updates that field 
Thanks in advance 
Hi,
I am trying to create a test for a class that has if/else logic based on different lookup values for a field.  Below is a snippet of the code that I need to test.  I typcially would like to use Test Data Factory and testSetup when writing my unit tests.  I am trying to figure out the most efficient way to accomplish this.  

Should I create different student records with the different affliate lookup values in the Test Data Factory or is it more efficient to create one student record do a fetch a update with the different values in each test method?
 
if(student__c.affiliate__c == 'freshman') {
   // do stuff
}
else if(student__c.affiliate__c == 'sophomore') {
  // do stuff
}
else if (student__c.affiliate__c == 'junior') {
  // do stuff
}

Both student__c and affiliate__c are custom object.  There is a lookup r/ship b/n them.

 
  • October 24, 2020
  • Like
  • 0
trigger LeadAssignOwnerByPostalCode on Lead (before insert, before update) {

    List<Lead> lList = new List<Lead>();
    
   
    Map<String,Zip_Code__c> zipCodeMap = new Map<String,Zip_Code__c>();
    
    Map<id, User> userMap = new Map<id, User>();
    
    Set<String> userIds = new Set<String>();
    
    Set<String> zipCodeString = new Set<String>();
    
    List<Zip_Code__c> zipCodeList = new List<Zip_Code__c>();
    
    List<Messaging.SingleEmailMessage> listmail = new List<Messaging.SingleEmailMessage>(); 

    for(Lead l: Trigger.new)
    {       
        
        System.debug('LeadAssignmentByZipCode -- Do_Not_Use_ZipAssignment_del__c ' + l.Do_Not_Apply_Zip_Assignment_Rules__c);
        
        //Do_Not_Use_ZipAssignment_del__c
        if(l.Do_Not_Apply_Zip_Assignment_Rules__c == true || l.LeadSource != 'Lead from Hubspot') continue;
        
        if(Trigger.isUpdate){
            System.debug('LeadAssignmentByZipCode -- Update Trigger -- ');
            Lead oldLead = Trigger.oldMap.get(l.id);
            if(l.PostalCode.equals(oldLead.PostalCode)) continue;
        } else
            System.debug('LeadAssignmentByZipCode -- Insert Trigger -- ');
        
        
        if(l.PostalCode <> null){
            zipCodeString.add(l.PostalCode);
            System.debug('LeadAssignmentByZipCode -- Lead -- ' + l.Name + ' Zip -- ' + l.PostalCode);
                
        }
    }
    
    if(!zipCodeString.IsEmpty())
    {
        System.debug('LeadAssignmentByZipCode -- Leads To Process ' + zipCodeString.size());
      
        zipCodeList = [SELECT  id, Name, UserAssigned__c, Dealer_Lead_Email_Address__c  FROM Zip_Code__c WHERE Name IN: zipCodeString ];
        
    } else{
        System.debug('LeadAssignmentByZipCode -- No Leads To Process');
    }
    
    
    if(!zipCodeString.IsEmpty()){
        
        System.debug('LeadAssignByZip --- zipCodeString Count --> ' + zipCodeString.size());
        
        
        for(Zip_Code__c z: zipCodeList){
            
            if(!zipCodeMap.containsKey(z.Name)){
                zipCodeMap.put(z.name, z);
                userIds.add(z.UserAssigned__c);
            }
            
        }
    }else
        System.debug('LeadAssignByZip --- zipCodeString Count --> zero');
         
        
    if(!userIds.IsEmpty()){
        
        System.debug('LeadAssignByZip --- userIds Count --> ' + userIds.size());
        userMap = new Map<id,User>([SELECT id, email FROM User WHERE id IN: userIDs]);
        
    }else
        System.debug('LeadAssignByZip --- userIds Count --> zero');
            

    for(Lead lead: Trigger.New) {
        
        if(lead.Do_Not_Apply_Zip_Assignment_Rules__c == true) continue;
        
        if(Trigger.isUpdate){
            System.debug('LeadAssignmentByZipCode -- Update Trigger -- ');
            Lead oldLead = Trigger.oldMap.get(lead.id);
            if(lead.PostalCode.equals(oldLead.PostalCode)) continue;
        } else
            System.debug('LeadAssignmentByZipCode -- Insert Trigger -- ');
        
        
        if(zipCodeMap.containsKey(lead.PostalCode)){
            
            Id owner = zipCodeMap.get(lead.PostalCode).UserAssigned__c;
            lead.OwnerId = owner;
            
        
            lead.Dealer_Lead_Person__c = zipCodeMap.get(lead.PostalCode).Dealer_Lead_Email_Address__c;
            //Added by Abhishek : End
            }
            }

}

And here is the current test class:
 
@isTest(SeeAllData=true)
private class TestLeadAssignmentByZipCode {

    static testMethod void testLeadAssignedByZipCode() {

        try{
            
            test.startTest();
            
            Zip_Code__c  zip = new ZIP_Code__c();
            zip.Name = '20716';
            zip.UserAssigned__c = UserInfo.getUserId();
            
            insert zip;
            
            Lead lead = new Lead();
            
            lead.FirstName = 'James';
            lead.Company = 'Acme';
            lead.Street = '100 West Street';
            lead.City = 'Marlboro';
            lead.State = 'MD';
            lead.PostalCode = '20716';
            
            insert lead;
            
            lead.PostalCode = '20710';
            
            
            update lead;
            
            String s2 = CheckOrganizationID.getServer();
            
            test.stopTest();
            
            
            
            
        }catch (Exception e){
        
            System.Debug('Error While Testing testLeadAssignedByZipCode');
            
        }           

    }
}

I'm stuck at 51%, can anyone help?
Hi, I am at learning stage of Apex Trigger. So, can someone please help me with this question?
Hi All,
I am trying to create a process  in Process builder to update a custom text field in Case object for below criteria.

1)    Case description is not null 
AND
2)    Case description Ischanged
OR
3)    Case descripton IsNew()

I created a criteria for Executioning actions as Formula evaluates to true under criteria section with below formula. But this formula is giving syntax error. 

Formula:
[Case].Description  !=NULL AND (IsChanged() OR IsNew())
I have created an Apex trigger in my sandbox environment but I am receiving an error message when I try to validate it in my production environment. It is saying
Code Coverage Failure.
Your organization's code coverage is 73%. You need at least 75% coverage to complete this deployment. Also, the following triggers have 0% code coverage. Each trigger must have at least 1% code coverage.
Hi, can someone guide me how can i cover atleast 75 of this class?
 
public class WorkOrderRelatedList{
    
    public SVMXC__Service_Order_Line__c[] WorkDetailList{get;set;}
    String u = UserInfo.getUserId();
    public WorkOrderRelatedList(ApexPages.standardController std){
        WorkDetailList=new SVMXC__Service_Order_Line__c[]{};
         string WorkOrderId=ApexPages.currentPage().getParameters().get('id');
        if(WorkOrderId==NULL){
            system.debug('No Id available');
        }
        else{
            SVMXC__Service_Order__c[] AccWL=new SVMXC__Service_Order__c[]{};
            AccWL=[Select id,  (select ID, Name, lastmodifieddate, SVMXC__Line_Type__c,SVMXC__Product__c, SVMX_PS_Consumed_Qty__c, SIG_SC_Description__c, SVMXC__Group_Member__c, 
                                       SVMX_PS_Customer_Start_Date__c, SVMX_PS_Customer_Start_Time__c, SVMX_PS_Customer_End_Time__c, SVMX_PS_Customer_End_Date__c, SIG_Duration_Hours__c
                                from SVMXC__Service_Order_Line__r where (SVMXC__Line_Type__c = 'Labor' AND  CreatedById =:  u) OR (SVMXC__Line_Type__c = 'Travel' AND  CreatedById =:  u ) OR SVMXC__Line_Type__c = 'Parts' )  
                  from SVMXC__Service_Order__c where id =:WorkOrderId];
            for( SVMXC__Service_Order__c c:AccWL ){
                for(SVMXC__Service_Order_Line__c obj:c.SVMXC__Service_Order_Line__r ){
                    WorkDetailList.add(obj);
                }
            }
        }
    }
}



I only covered 45%...

 

@isTest
class WorkOrderRelatedList_UT{

    @isTest
    static void testtMethod() 
    { 
          String u = UserInfo.getUserId();
          SVMXC__Service_Order__c woTest = new SVMXC__Service_Order__c();
          woTest.SVMXC__Priority__c = 'Normal';
          insert woTest;
          
          SVMXC__Service_Order__c wo = [Select ID from SVMXC__Service_Order__c where Id =: woTest.id];
         
        
         ApexPages.StandardController sc = new ApexPages.StandardController(woTest);
         WorkOrderRelatedList testWo     = new WorkOrderRelatedList(sc);
        
         PageReference pageRef = Page.WorkDetailRelatedList; // Add your VF page Name here
         pageRef.getParameters().put('id', String.valueOf(wo.Id));
         Test.setCurrentPage(pageRef);
         
         SVMXC__Service_Order_Line__c workDetail = new SVMXC__Service_Order_Line__c();
         workDetail.SVMXC__Service_Order__c = wo.Id;
         workDetail.RecordTypeId = '0121i000000Gs2VAAS';
         workDetail.SVMXC__Line_Type__c = 'Labor';
         
         insert workDetail;
        
        
    }
}


My visualforce page:

 

<apex:page standardController="SVMXC__Service_Order__c" extensions="WorkOrderRelatedList" tabStyle="SVMXC__Service_Order_Line__c" lightningStylesheets="true">
<style>
body .bPageBlock .pbBody .labelCol{
     float:left;
}
</style>
    
    <apex:pageBlock Title="My Work Details">
        
            <apex:pageBlockTable style="width:100%" value="{!WorkDetailList}" var="n" >
                <apex:column style="width:50px" headerValue="Line Number" value="{!n.Name}"/>
                <apex:column style="width:50px" headerValue="Line Type" value="{!n.SVMXC__Line_Type__c}" />
                <apex:column style="width:10px" headerValue="Part" value="{!n.SVMXC__Product__c}" />
                <apex:column style="width:1px" headerValue="Consumed Qty" value="{!n.SVMX_PS_Consumed_Qty__c}" />
                <apex:column style="width:10px" headerValue="SC Description" value="{!n.SIG_SC_Description__c}" />
                <apex:column style="width:10px" headerValue="Technician" value="{!n.SVMXC__Group_Member__c}" />
                <apex:column style="width:10px" headerValue="Reported Start Date" value="{!n.SVMX_PS_Customer_Start_Date__c}" />
                <apex:column style="width:10px" headerValue="Reported Start Time" value="{!n.SVMX_PS_Customer_Start_Time__c}" />
                <apex:column style="width:10px" headerValue="Reported End Date" value="{!n.SVMX_PS_Customer_End_Date__c}" />
                <apex:column style="width:10px" headerValue="Reported End Time" value="{!n.SVMX_PS_Customer_End_Time__c}" />
                <apex:column style="width:10px" headerValue="Duration(hours)" value="{!n.SIG_Duration_Hours__c}" />


           
   </apex:pageBlockTable>
        
        
    </apex:pageBlock>    
    
</apex:page>

​​​​​​​

Hey All,

I'm a bit new to writing apex and test classes, but I'm unsure why I'm getting the compiling error "Variable does not exist: Monthly_Recurring_Fees__c". I'm attempting to pull the "Monthly_Recurring_Fees__c" field from the "queriedOrder" query. Any help is appreciated!

@isTest
private class OrderRollupSummaryTest {

    private static testMethod void doTest() {
    	
    	Account testAcc  = new Account ();          
    			testAcc.Name = 'Test Account';
    			testAcc.Primary_Vertical__c = 'Multifamily Housing';
    			testAcc.Total_Locations_Owned_Managed__c = 1;
    			
    			insert testAcc;


    	Opportunity testOpp  = new Opportunity ();
       			testOpp.Name = 'Test Opportunity';
    			testOpp.AccountId = testAcc.Id;
    			testOpp.Opportunity_Source__c = 'Sales Generated';
    			testOpp.Type = 'New';
    			testOpp.StageName = 'Contract';
    			testOpp.Number_of_locations_for_opportunity__c = 1;
    			testOpp.Amount = 0;
    			testOpp.Implementation__c = 0;
    			testOpp.CloseDate = System.today() + 5;
    			testOpp.Deal_Confidence__c = 100;
    			
    			insert testOpp;

    	Package__c testPackage  = new Package__c ();
    			testPackage.Name = 'Test Package';
    			testPackage.Package_Type__c = 'Website Package';
    			testPackage.Status__c = 'Active';
    			testPackage.One_Time_Price__c = String.ValueOf(200);
    			testPackage.Monthly_Recurring_Price__c = String.ValueOf(100);
    			
    			insert testPackage;


    	Order_Sheet__c testOrder  = new Order_Sheet__c ();
    			testOrder.Opportunity__c = testOpp.id;
    			
    			insert testOrder;


    	Order_New_Location__c testOrderLocation  = new Order_New_Location__c ();
    			testOrderLocation.Order_Sheet__c = testOrder.id;
    			testOrderLocation.Name = 'Test Location';
    			
    			insert testOrderLocation;


    	Order_Location_Package__c testOrderPackage  = new Order_Location_Package__c ();
    			testOrderPackage.Order__c = testOrder.Id;
    			testOrderPackage.New_Location_Name__c = testOrderLocation.Id;
    			testOrderPackage.Package__c = testPackage.Id;
    			
    			insert testOrderPackage;

        Discount__c testMRFDiscount  = new Discount__c ();
                testMRFDiscount.Location_Package__c = testOrderPackage.Id;
                testMRFDiscount.Dollar_Discount__c = 50;
                testMRFDiscount.Fee__c = 'Monthly Recurring Fees';
                
                insert testMRFDiscount;

        Discount__c testOTFDiscount  = new Discount__c ();
                testOTFDiscount.Location_Package__c = testOrderPackage.Id;
                testOTFDiscount.Dollar_Discount__c = 50;
                testOTFDiscount.Fee__c = 'One-Time Fees';
                
                insert testOTFDiscount;


 /* --- OrderRollupSummaryTest Test --- */
		Test.startTest();

		/* --- Run Create Method--- */
    	OrderRollupSummary.rollupAllorderlocations(new List<Order_New_Location__c>{testOrderLocation});
		
		/* --- Query for Order--- */
		list<Order_Sheet__c>queriedOrder = [Select Monthly_Recurring_Fees__c FROM Order_Sheet__c WHERE Id = :testOrder.id];
        System.debug('Price after trigger fired: ' + queriedOrder.Monthly_Recurring_Fees__c);
		
		/* --- Checks to see if amounts updated --- */
        system.assertEquals(50, queriedOrder.Monthly_Recurring_Fees__c);

        Test.stopTest();


    }
}
Hello,

I am trying to create a test class for a relatively simple custom controller extension.  However, I am having trouble covering one of my methods in the controller that handled deletion of records.

I need to somehow pass a value for the DelAddrId variable in my controller from my test class, but I'm not sure how to do that. Can anyone assist?

Test Class
@isTest 
private class Test_AcctAddressesController {

    static testMethod void testMethod1() 
    {
        Account testAccount = test_CreateRecords.createAcct(0);
        insert testAccount;
        
        Contact testContact = test_CreateRecords.createCont(testAccount.Id);
        insert testContact;
        
	Test.StartTest();
        Account_Addresses__c testAcctAddr = new Account_Addresses__c();
            testAcctAddr.Account__c = testAccount.Id;
            testAcctAddr.Street__c = '1010 Test Ave';
            testAcctAddr.City__c = 'New York';
            testAcctAddr.State__c = 'NY';
            testAcctAddr.Zip_Postal_Code__c = '11212';
            testAcctAddr.Country__c = 'USA';
            testAcctAddr.Primary__c = TRUE;
            testAcctAddr.Current__c = TRUE;
        insert testAcctAddr;

        PageReference testPage = Page.Acct_Addresses;
			testPage.getParameters().put('DelAddrId', testAcctAddr.Id);   
   		Test.setCurrentPage(testPage);

        ApexPages.StandardController AcctAdd = new ApexPages.standardController(testAccount);
        	AcctAddresses AcctAdd1 = new AcctAddresses(AcctAdd);
System.assertNotEquals(null,AcctAdd1.deleteAddress());

        AcctAdd1.save();
        AcctAdd1.deleteAddress();
	Test.StopTest();
    }
}

Controller
public class AcctAddresses {     

    public List<Account_Addresses__c> addresses{get;set;}
    public string DelAddrId { get; set;}
    public Account accounts {get;set;} 
    public Account acct {get;set;} 

//Constructor 

    public AcctAddresses(ApexPages.StandardController controller) { 

        acct = (account)controller.getRecord();      

        accounts = [SELECT Id
                    FROM account
                    WHERE id=: acct.id LIMIT 1]; 

        addresses = [SELECT Id, Name, Primary__c, Current__c, Street__c, City__c, State__c, Zip_Postal_Code__c, Country__c, Account__c
                    FROM Account_Addresses__c
                    WHERE Account__r.Id = :accounts.id ORDER BY Primary__c, State__c];     
} 

//This method is to edit the existing contact record while clicking the Edit link 

        public pageReference Save(){
            update addresses;
        return ApexPages.CurrentPage();
        }

//This method is to delete the contact record while clicking the Del link 

    public pageReference deleteAddress(){

        Account_addresses__c ToBeDeleted = [SELECT Id FROM Account_addresses__c WHERE id = : DelAddrId LIMIT 1]; 
	        delete ToBeDeleted; 
    		    String baseUrl = URL.getSalesforceBaseUrl().toExternalForm(); 
        		PageReference redirectPage = new PageReference(baseUrl+'/'+acct.id); 
        	return redirectPage;  
    }   
}

 
Have a need to create a Global Action to create a record.  
The object type is not selectable as one of the options in the Create Record option.
User-added image

Is it possible to create a Lightning component to create the Object required?  Or have I missed something simple?

regards
Andrew
 
short version,
I have had to create a lead conversion process where we are using Apex code to convert the lead.  When all the required fields have been entered, on Save, the record is converted.  I have created a Process Builder that invokes some Apex which converts the lead.  The behaviour is that the lead is still displayed but the status has been updated.

NOW, the client wants to have the system open the related Opportunity that has been created.  I am at a loss on how to do this.

I would appreciate some help / guidance.  I'm thinking either something to have the Apex class open the record, or can I do a lightning component or similar in the converted lead?

Regards
Andrew
Ok,  here's a doozy, because Salesforce Support said come here.

OK, SOQL query using MAP
Map<Id, RecentlyViewed> recentlyViewedMap = new Map<Id, RecentlyViewed>([SELECT Id FROM RecentlyViewed WHERE Type = 'Account']);
It throws an error:
Line: 1, Column: 1
System.ListException: Row with duplicate Id at index: 19


So, i then change up the query and right it as below with System.debug to analsye the query results:
List <RecentlyViewed> recentlyViewedList = new List <RecentlyViewed> ([SELECT Id, Name FROM RecentlyViewed WHERE Type = 'Account']);

for(RecentlyViewed a : recentlyViewedList ) {
    System.debug( 'a' + a.Id + ':' + a.Name);
}
When i review the debug, I can see that the records contain a duplicate.  When I viewed the Recently Viewed Accounts via the UI, the duplicate record does not display.  The duplicate only appears when I complete the SOQL and pass to a LIST.

So, how do I clear the duplicated records from what I assume is the RecentlyViewed table that sits in the back end of Salesforce?

Regards 
Andrew

notes:
1.  I know why the error is being thrown.  
2.  Yes, I know how to write code to side step the issue, but why should I need to code to cope with Salesforce having corrupted tables?
3. I have tried clearing Cache in my browser and even tried a different browser, but when we think about this, the issue is not how it is being displayed in a browser, but how the results are being pulled from a SF table (for want of a better term).
4.  The code (i.e. the SOQL query to MAP) does not throw an error for 3 other people I had test this.  The error pertains to my recently viewed records only.

 
Hi all

I understand the concepts and best practice for process builders, but i want to deepen my understanding.
This help file:
https://help.salesforce.com/articleView?id=process_limits.htm&type=5
states:
"Each Create a Record action uses one DML statement. Each Quick Action action uses one DML statement. Each Update Records action uses one SOQL query and one DML statement. "

With reference to the terms "Quick Action" and "Update Records", what is the difference? Is a Quick Action an update to the record that starts the process builder, and an Update Records is an update to a related record? (hence the SOQL to find the record, before we update it  - the DML)

Am I to assume that the Update Record action consumes one SOQL because I need to find the record first?  Does the SOQL occur if the Update Record is happening to the record that started the Process Builder? 

Consider this Process Builder :
User-added image

Do I assume that in Decision Point 1 , since I am doing 3 x Immediate Actions (IA) with each being an Update , that this Decision Point will result in 3 x DML and 3 x SOQL ?  Or is an update to the record which started it a Quick Action and hence only 3 x DML?

Next question to consider, if I have criteria around a IA which is an update, and the IA does not meet that criteria, and therefore does not execute the update, does this count as a SOQL?  but obviously no DML.


This is in consideration that I have inherited a process builder which is getting a too many SOQL query or CPU timeout errors.  I have reviewed the process builder, but before i start a rebuild (it is quite complex), i just want to get some clarity.

Regards
Andrew
Hi

I have a need to be able to create 2 different types of Cases on our Community Portal.

Basically, I have 2 global actions that each create a Case but with a different Record Type.  I have created the buttons on the home page of my community site.  I know they throw to the Create Record Page and I have created 2 x page variations, but when I try the preview and try the buttons, I get which ever page variation is set to Default.

Surely i'm not the first to try this.  Is there some documenation that clearly descibes how to do this?  Or if someone can give me some direction it would be appreciated

Regards
Andrew G
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 





 
@RestResource(urlMapping='/v1/BookDetails/')
global class bookManager 
{
@httpGet
global static Book__c doGetBook()
{
    Book__c book = new Book__c();
    Map<String,String> paramsMap = RestContext.request.params;
    String bookId = paramsMap.get('Id');
    book = [select Id, Name, Price__c from Book__c where Id IN =: bookId]; // getting sytax error in this line
    return book;
}
}
Hi, I'm new in APEX and I've been told to fix this test class:
 
@Istest
Public class MillisecondBatchConvertController_Test{
public static testMethod void testBatch() {
       
    Team_Form__c tfCustom = new Team_Form__c();
    tfCustom = [Select Id from Team_Form__c LIMIT 1];
    List <PS_TF_Status_Track__c> stList = new List<PS_TF_Status_Track__c>();
    for(integer count = 0; count<=1; count++){
        PS_TF_Status_Track__c st = new PS_TF_Status_Track__c(Hours__c=count,Minutes__c=count,Days__c=count,Team_Form__c=tfCustom.Id);
     stList.add(st);}
       
        insert stList;
       
        Test.startTest();
        MillisecondBatchConvertController mbcCon=new MillisecondBatchConvertController();
        ID batchprocessid = Database.executeBatch(mbcCon,1);
        Test.stopTest();
    }
}


And I'm getting this error:

System.QueryException: List has no rows for assignment to SObject

I suppose this is because tfCustom.Id is empty but why is doesn't have any value?

Thanks in advance

Can we add additional fields to the gantt display in Field Service Lightning?  Right now, the only thing that shows is the Service Appointment Number.
So in this example for inserting Content docuemnt link.  How can I limit access to a specifc user group or profile?  And how could I use a CMT so that an admin can update or add groups so that the sahring is not hard coded in the apex?
Thanks
//Get attachment
Attachment attach = [SELECT Id, Name, Body, ContentType, ParentId From Attachment LIMIT 1];
 
//Insert ContentVersion
ContentVersion cVersion = new ContentVersion();
cVersion.ContentLocation = 'S';
cVersion.PathOnClient = attach.Name;
cVersion.Origin = 'H';
cVersion.OwnerId = attach.OwnerId;
cVersion.Title = attach.Name;
cVersion.VersionData = attach.Body;
Insert cVersion;
 
//After saved the Content Verison, get the ContentDocumentId
Id conDocument = [SELECT ContentDocumentId FROM ContentVersion WHERE Id =:cVersion.Id].ContentDocumentId;
 
//Insert ContentDocumentLink
ContentDocumentLink cDocLink = new ContentDocumentLink();
cDocLink.ContentDocumentId = conDocument;//Add ContentDocumentId
cDocLink.LinkedEntityId = attach.ParentId;//Add attachment parentId
cDocLink.ShareType = 'I';
cDocLink.Visibility = 'InternalUsers';
Insert cDocLink;
Hello, I am getting this error when trying to run my test class: System.DmlException: Insert failed. First exception on row 0; first error: FIELD_INTEGRITY_EXCEPTION, There exists no recipient to which you can send this List Email to.: []   Class.CampaignEmailHistoryTest.testNotesExtension: line 10, column 1


How can I fix this? 

Here is the test class:
@isTest
public class CampaignEmailHistoryTest {
    @isTest
    static void testNotesExtension(){

Campaign testCampaign= new Campaign(Name= 'Test');
insert testCampaign;
        
ListEmail le = new ListEmail(campaignId=testCampaign.id, subject= 'hey there',Status= 'Scheduled'); 
    insert le;
   
  ApexPages.StandardController con = new ApexPages.StandardController(testCampaign);
  CampaignEmailHistoryExtension  dce = new CampaignEmailHistoryExtension(con);
         
    }
    
}


And the real class:
public class CampaignEmailHistoryExtension {
public final Campaign thisCampaign;
 
    Public List<ListEmail> listEmails {get; set;}
 
    Public CampaignEmailHistoryExtension(ApexPages.StandardController stdController){
        this.thisCampaign = (Campaign)stdController.getRecord();

        try{
  
            Campaign camp=[Select Id, Name from Campaign where Id = :this.thisCampaign.id];
        
        listEmails = [SELECT ID, campaignId, CreatedDate, CreatedById, CreatedBy.FirstName, CreatedBy.LastName, subject, LastViewedDate
                      FROM ListEmail 
                      WHERE  campaignId IN (Select id from Campaign where Id = :this.thisCampaign.id)];
        }
        catch(exception e){
            Apexpages.addMessage(new ApexPages.Message(ApexPages.SEVERITY.FATAL, 'No old records'));
        }       
}
}

public with sharing class adpContactUsController {

    public String personalizedMessage1 {get; set;}
    public String personalizedMessage2 {get; set;}
    public String personalizedMessage3 {get; set;}
    
    public adpContactUsController (){
        User u = [Select Id, ContactId from User where Id =: UserInfo.getUserId()];
        
        List<Contact> conlist = [Select Id, Advocacy_Staff_Partner__c,Advocacy_Staff_Partner__r.X18_ID__c from Contact where id =: u.ContactId]; 
                
        if(conlist.size() > 0){
            if(conlist[0].Advocacy_Staff_Partner__c == null) {
                personalizedMessage1 = defaultMessage();
            }
            else {
            ADP_StaffData__c adpStaffData = ADP_StaffData__c.getValues(conlist[0].Advocacy_Staff_Partner__c);
            if(adpStaffData != null) {
                personalizedMessage1 = adpStaffData.Personal_Message1__c;
                personalizedMessage2 = adpStaffData.Personal_Message2__c;
                personalizedMessage3 = adpStaffData.Personal_Message3__c;
            }
            
           }
        } else {
            personalizedMessage1 = defaultMessage();
        }
        
    }
    
    private String defaultMessage(){
        List<ADP_StaffData__c> adpStaffDatalist = ADP_StaffData__c.getAll().values();
            String defMsg = '';
            for(ADP_StaffData__c adpDefMsg : adpStaffDatalist){
                if(adpDefMsg.Default_Message__c) {
                   defMsg = adpDefMsg.Personal_Message1__c + ' ' + adpDefMsg.Personal_Message2__c + ' ' + adpDefMsg.Personal_Message3__c;
                   break;                 
                }
            }
            return defMsg.replaceAll('null', '');
    }
    
    public PageReference SeeAllAdvocates(){
        
        PageReference pageRef = new PageReference('/apex/AdvocatesListView');
        pageRef.setRedirect(true);
        return pageRef;
        
    }
    
    public PageReference EmailNewAdvocates(){
        
        PageReference pageRef = new PageReference('/apex/AdvocatesListView?type=new');
        pageRef.setRedirect(true);
        return pageRef;
        
    }
    
    public PageReference EmailAllAdvocates(){
        
        PageReference pageRef = new PageReference('/apex/AdvocatesListView?type=all');
        pageRef.setRedirect(true);
        return pageRef;
        
    }
    
    public PageReference createNewHouseholdContact(){
         Contact con = New Contact();
         Id Contact_HRTypeID = Schema.sObjectType.Contact.getRecordTypeInfosByName().get('Household Contact').getRecordTypeId();
         PageReference contactDetailsPage = new PageReference('/003/e');
         contactDetailsPage.getParameters().put('RecordType',Contact_HRTypeID);
         String returnURL = '/'+Page.adpHomeNew.getUrl().right(10);
         contactDetailsPage.getParameters().put('retURL', returnURL.escapeHtml3());
         contactDetailsPage.setRedirect(true);
         return contactDetailsPage;
    }
}
//////////////////////////////////////////
@isTest
public class adpContactUsControllerTest {
    
    @testSetup static void setup() {
        
        Profile p = [SELECT Id FROM Profile WHERE Name='System Administrator'];

        fF_Location__c defaultLocation = new fF_Location__c(Name = 'Default Location', Is_Default_Unknown_Location__c = true);
        insert defaultLocation; 
        
        User u = new User(Alias = 't3stUser', Email='testUser@testkeyimpact.com', EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US', 
                          LocaleSidKey='en_US', ProfileId = p.Id, TimeZoneSidKey='America/Los_Angeles', UserName='testusertest@keyimpact.com');
        
        INSERT u;
        Id RecordTypeIdContact = Schema.SObjectType.Contact.getRecordTypeInfosByName().get('Organization Contact').getRecordTypeId();
        Id RecordTypeIdAccount = Schema.SObjectType.Account.getRecordTypeInfosByName().get('Household').getRecordTypeId();
        Account acc = new Account();
        acc.Name = 'test account';
        acc.recordtypeid = RecordTypeIdAccount;
        insert acc;
        contact con = new contact();
        con.recordtypeid = RecordTypeIdContact;
        con.AccountId = acc.id;
        con.LastName = 'test con';
        con.Email = 'test0@test.com';
        insert con;
        
        contact con1 = new contact();
        con1.Advocacy_Staff_Partner__c = con.id; 
        con1.recordtypeid = RecordTypeIdContact;
        con1.LastName = 'test con1';
        con1.Email = 'test1@test.com';
        insert con1;
    }
    static testmethod void loginTest(){ 
        adpContactUsController adpCon =  new adpContactUsController();
        adpCon.SeeAllAdvocates();
        adpCon.EmailNewAdvocates();
        adpCon.createNewHouseholdContact();
        PageReference pageRef = adpCon.EmailAllAdvocates();
        System.assertNotEquals (null,pageRef);
    }
}
Hi, 
I am working on a method to manually escalate a case from a user to a queue. And this has to happen on a button click on the case record page. So I started by creating a global action and using pre defined fields for this. I set the status to escalated and I am trying to set the case owner to a queue that I created. But it does not show the picklist like it did for the status and shows a formula field. Not sure what to enter in there to find the queue. Any help would be much appreciated !
Hi and thanks in advance for any help.
Situation:
I wrote a web service to grab new cases from an external source.  That part works fine, BUT an after update trigger fires when uploading new cases and i get a ''Apex CPU time limit exceeded".  I thought if I skipped the Record Type it would skip the trigger code. 
This line causes the error is the for loop, which occurs before the RT check:
for (Case cse : Trigger.new){
trigger CompleteResolutionTimeMilestone on Case (after update) {
    
    for (Case cse : Trigger.new){        
        system.debug('cse.RecordTypeId ' + cse.RecordTypeId);
        if (cse.RecordTypeId != Schema.Sobjecttype.Case.getRecordTypeInfosByDeveloperName().get('Maintenance').getRecordTypeId()){
          if (UserInfo.getUserType() == 'Standard'){
        
           DateTime completionDate = System.now(); 
              List<Id> updateCases = new List<Id>();
              for (Case c : Trigger.new){
                  if (((c.isClosed == true)||(c.Status == 'Closed'))&&((c.SlaStartDate 
                        <= completionDate)&&(c.SlaExitDate == null)))
            updateCases.add(c.Id);
                       }
    if (updateCases.isEmpty() == false)
        milestoneUtils.completeMilestone(updateCases, 'Support Resolution Time', completionDate);
    }
        }// end if (cse.RecordTypeId !=
    }
}
Regards,
Eric
 
Doctor On Demand is seeking a remote Sr Salesforce Developer (https://careers.jobscore.com/careers/doctorondemand/jobs/senior-salesforce-developer-remote-auVqIyurGr66PxaKj7Io52?ref=rss&sid=68) to join our growing Salesforce team! Please use the link to directly apply, we'd love to hear from you!

Hi All,

I am not a developer and I am trying to copy one existing trigger and test class from the Org and while running the Test Class getting below error- 

System.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, State/Province is required for Australia, United States and Canada.: []

I even have included the BillingState in the Account creation to so that validation rule do not trigger. But still no luck. Can anyone help me in reviewing the below codes? 

APEX Trigger-
trigger limitCreationsFromZoominfo on Contact (before insert) {
//This trigger limit to 25 the number of contacts that can be created from Zoominfo per person per month (#33899)
//We can detect that the Contact comes from Zoominfo because: LeadSource = "Zoominfo"
//We need to filter the existing contacts (for the count operation) using the fields: 
//  CreatedBy = <same user> 
//  CreatedDate = <in the last 30 days> 
//  LeadOrigin = "Zoominfo"
    
    
//  Users with roles "System Administrator", "Denodo Systems Integration" or "Operations Supervisor" should not be affected by this rule.
    Id profileId = UserInfo.getProfileId();
    String profileName=[Select Id, Name from Profile where Id=:profileId].Name; 
    if ( !profileName.contains('Operations Supervisor') && !profileName.contains('System Administrator') 
            && !profileName.contains('Denodo Systems Integration')){
            
            String userId = UserInfo.getUserId();
            Datetime limitDate = System.now().addDays(-30);                            
            List<Contact> contactsToInsertFromZoominfo = new List<Contact>();
            for(Contact contactToInsert : System.Trigger.new){
                if (contactToInsert.LeadSource == 'Zoominfo'){
                    contactsToInsertFromZoominfo.add(contactToInsert);
                }
            }
            //if there are insertions from Zoominfo, check the limit
            if (contactsToInsertFromZoominfo.size() > 0) {
                List<AggregateResult> currentContactsZoominfo = [SELECT Count(Id) currentContacts FROM Contact 
                                      WHERE Lead_Origin__c ='Zoominfo' and CreatedDate >= :limitDate and CreatedById = :userId];
                for (Contact contactToInsert : contactsToInsertFromZoominfo) {
                    if ( (Integer.valueOf(currentContactsZoominfo.get(0).get('currentContacts')) + contactsToInsertFromZoominfo.size()) > 25 ){
                        contactToInsert.addError('You can not import more than 25 contacts from Zoominfo in 30 days.');                        
                    }   
                }
                             
            }    
            
     }
    
      
}




APEX Class Test -

/**
 * This class contains unit tests for validating the behavior of Apex classes
 * and triggers.
 *
 * Unit tests are class methods that verify whether a particular piece
 * of code is working properly. Unit test methods take no arguments,
 * commit no data to the database, and are flagged with the testMethod
 * keyword in the method definition.
 *
 * All test methods in an organization are executed whenever Apex code is deployed
 * to a production organization to confirm correctness, ensure code
 * coverage, and prevent regressions. All Apex classes are
 * required to have at least 75% code coverage in order to be deployed
 * to a production organization. In addition, all triggers must have some code coverage.
 * 
 * The @isTest class annotation indicates this class only contains test
 * methods. Classes defined with the @isTest annotation do not count against
 * the organization size limit for all Apex scripts.
 *
 * See the Apex Language Reference for more information about Testing and Code Coverage.
 */
@isTest
private class limitCreationsFromZoominfoTest {
    static testMethod void myUnitTest() {
        Test.startTest();

        Profile pISS = [SELECT Id FROM Profile WHERE Name='Inside Sales Specialist'];               
        User userISS = new User(Alias = 'userISS', UserName='newuserISS@relatedtotest.com', Email = 'test2@relatedtotest.com', 
                             EmailEncodingKey='UTF-8', FirstName = 'testuser2', LastName = 'ISS', ProfileId = pISS.Id,
                             TimeZoneSidKey='America/Los_Angeles',  LocaleSidKey='en_US', LanguageLocaleKey='en_US');           
        insert userIss;

        System.runAs(userISS){
            // Seed the database with some accounts, and make sure they can be bulk inserted successfully.
            Account account1 = new Account(Name = 'Test1RelatedTo Inc.', BillingCountry = 'United States', BillingState = 'California');
            Account[] accts = new Account[] {account1};
            insert accts;
            
            List<Contact> contacts = new List<Contact>();
            for (Integer i =0 ; i < 26; i++){
                String emailc = 'test' + i + '@relatedtotest.com';
                contacts.add(new Contact(LastName='Test1', AccountId=account1.Id, Email=emailc, MailingCountry = 'United States', MailingState = 'California', LeadSource='Zoominfo'));
            }
            contacts.add(new Contact(LastName='Test4', AccountId=account1.Id, Email='testa@relatedtotest.com', MailingCountry = 'United States', MailingState = 'California', LeadSource='Other'));
            contacts.add(new Contact(LastName='Test5', AccountId=account1.Id, Email='testb@relatedtotest.com', MailingCountry = 'United States', MailingState = 'California', LeadSource='Web'));
            
            try{
                insert contacts;  
                System.assert(false);
            } catch (DmlException e) {     
                System.assert(e.getNumDml() == 101); 
                System.assert(e.getDmlMessage(0).contains('You can not import more than 25 contacts from Zoominfo in 30 days.'));               
            }
                                  
        }
                    
                             
        Test.stopTest();
    }       
}

 

Any help would be much appreciated. 

        
 
I think I am iterating ov erht same list twice.  Will someone help me streamline the code.  Can I get the second for loop inside the first and be efficient?
Attachment__c newAttachment = (Attachment__c ) so;
        String objectType;
        List<Plan__c > palnId = new List<Plan__c>();
        Map<String,String> planMap = new Map<String,String>();
        
        if( this.linkMap.containsKey( newAttachment.ContentDocumentId__c ) ){
            List<ContentDocumentLink> links = this.linkMap.get( newAttachment.ContentDocumentId__c );
            if( !links.isEmpty() ){
                for( ContentDocumentLink link : links ){
                    objectType = String.valueOf( link.LinkedEntityId.getSObjectType() );
                    switch on ( objectType ){
                        when 'Activity__c' {
                            newAttachment.Activity__c= link.LinkedEntityId;
                        }
                        when 'Project__c' {
                            newAttachment.Proj__c= link.LinkedEntityId;
                        }
                    }
                }
            }
    
            List<Plan__c> plans= new List<Plan__c>();

            for (ContentDocumentLink cont : links ){                    
                if(newAttachment.Activity__c != null || newAttachment.Proj__c != null){
                    ContentDocumentLink cdl = new ContentDocumentLink();
                    cdl.LinkedEntityId = parentId;
                    cdl.ContentDocumentId = cont.ContentDocumentId;
                    cdl.ShareType = 'V';
                    cdl.Visibility = 'AllUsers';
                    cdl_List.add(cdl);
                    break;
                }
            }
        }

 
I have created one custom field which is Commission, over there i am trying to calculate commission. IF LeadSource is web and Amount is greter than 1000. Then commission should be 2% of amount. Other wise it should be 1% of Amount.
IF LeadSource is Phone Inquiry and Amount is greater than 50000 then the commission should be 10% of Amount. Other wise 5% of Amount.

OR(IF(AND(ISPICKVAL( LeadSource , "Phone Inquiry"),  Amount  < 50001) ,  Amount  * 10 / 100 , Amount  * 5 / 100 ),IF(AND(ISPICKVAL( LeadSource , "Web"),  Amount  < 1001) ,  Amount  * 2 / 100 , Amount  * 1 / 100 ))
Hello,
I have the following trigger on Case that defaults entitlements on Case record. I need to have 75% code coverage but i only managed to get 57% (found it on internet). Could anyone help me and amend the below test class to achieve the 75%?
Also, i don't really need the trigger to look at Contacts, only at Account level so that could be removed from the trigger if it is easier with writing the test class.
I would appreciate your help.
EwaUser-added image

The TRIGGER
trigger DefaultEntitlement on Case (Before Insert, Before Update) {
    Set<Id> contactIds = new Set<Id>();
    Set<Id> acctIds = new Set<Id>();
    for (Case c : Trigger.new) {
        contactIds.add(c.ContactId);
        acctIds.add(c.AccountId);
    }
    
    List <Entitlement> entls = [Select e.StartDate, e.Id, e.EndDate, 
                e.AccountId, e.AssetId
                From Entitlement e
                Where e.AccountId in :acctIds And e.EndDate >= Today 
                And e.StartDate <= Today];
        if(entls.isEmpty()==false){
            for(Case c : Trigger.new){
                if(c.EntitlementId == null && c.AccountId != null){
                    for(Entitlement e:entls){
                        if(e.AccountId==c.AccountId){
                            c.EntitlementId = e.Id;
                            if(c.AssetId==null && e.AssetId!=null)
                                c.AssetId=e.AssetId;
                            break;
    
    
                    }
                } 
            }
        } 
    } else{
        List <EntitlementContact> entlContacts = 
                [Select e.EntitlementId,e.ContactId,e.Entitlement.AssetId 
                From EntitlementContact e
                Where e.ContactId in :contactIds
                And e.Entitlement.EndDate >= Today 
                And e.Entitlement.StartDate <= Today];
    if(entlContacts.isEmpty()==false){
        for(Case c : Trigger.new){
            if(c.EntitlementId == null && c.ContactId != null){
                for(EntitlementContact ec:entlContacts){
                    if(ec.ContactId==c.ContactId){
                        c.EntitlementId = ec.EntitlementId;
                        if(c.AssetId==null && ec.Entitlement.AssetId!=null)
                            c.AssetId=ec.Entitlement.AssetId;
                        break;
                        }
                    } 
                }
            } 
        }
    }
}


THE TEST CLASS

@isTest
private class DefaultEntitlementTest {

    static testMethod void myUnitTest() {
        Account acc = new Account(Name='testacc');
        insert acc;

        Contact con = new Contact(FirstName='john', LastName='doe', Email='john@doe.com', AccountId=acc.Id);
        insert con;

        Asset ass = new Asset(AccountId=acc.Id,ContactId=con.Id, Name='testing');
        insert ass;

        Entitlement ent = new Entitlement(Name='Testing', AccountId=acc.Id, StartDate=Date.valueof(System.now().addDays(-2)), EndDate=Date.valueof(System.now().addYears(2)), AssetId=ass.Id);
        insert ent;

        Entitlement ent2 = new Entitlement(Name='test2', AccountId=acc.Id, StartDate=Date.valueof(System.now().addDays(-10)), EndDate=Date.valueof(System.now().addYears(3)));
        insert ent2;

        EntitlementContact ec = new EntitlementContact(EntitlementId=ent.Id, ContactId=con.Id);
        insert ec;

        List<Case> listC = new list<Case>();
        List<Id> newCaseIds = new List<Id>();
        for(Integer i=0;i<20;i++){
            Case c = new Case(ContactId=con.Id, AccountId=con.AccountId, Subject='Test Subject'+i, Origin='Webform_B2B');

            listC.add(c);
        }
        test.startTest();
        insert listC;

        test.stopTest();
        for (Case caseObj:listC) {
            newCaseIds.add(caseObj.Id);
        }

        List<Case> entls = [Select EntitlementId, AssetId, ContactId, AccountId From Case Where Id in :newCaseIds];

        for (Case caseObj:entls) {

            System.debug(caseObj.Id + ' here are the values ' + caseObj.EntitlementId + ' and here ent.Id ' + ent.Id);

            System.assertEquals(caseObj.EntitlementId, ent.Id);

        }
        Contact con2 = new Contact(FirstName = 'Jane',
        LastName = 'Doe',
        Email='jane@doe.com');

        insert con2;
        Entitlement ent3 = new Entitlement(Name='Testing', AccountId=acc.Id, StartDate=Date.valueof(System.now().addDays(2)), EndDate=Date.valueof(System.now().addYears(2)), AssetId=ass.Id);
        insert ent3;

        EntitlementContact ec2 = new EntitlementContact(EntitlementId=ent3.Id, ContactId=con2.Id);
        insert ec2;
        Case c1 = new Case(ContactId=con2.Id, AccountId=con.AccountId, Subject='Test Subject', Origin='Webform_B2B');
        insert c1;
        update c1;
    }
}
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




 

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!