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

  • Chatter
    Feed
  • 144
    Best Answers
  • 0
    Likes Received
  • 1
    Likes Given
  • 15
    Questions
  • 778
    Replies
I tried using SalesForce Optimizer but apparently, it lies to me. It says that we don't have anything using API 20 or below, but I was sent an email from SalesForce that says " Our records show that you have apps using API version 20 or below". Since SalesForce is retiring API 7 - 20.  So how can I find where API 20 or below is being used so I can update it? 
I am working with events and cases but am having trouble on the concepts of joining two queries.  I need to query all events that:
  • completed yesterday
  • are related to a case (WhatId starts with 500)
  • are of event Type = 'Example'
Each of these are related to a case by definition of the original query, I now need to go through each of the cases and determine what the caseType__c is to determine the next_due_date__c which is a custom date field on the case which should calculate as:
  • Event Date + (If caseType__c = "Example" + 14, 60)

I am having a hard time figuring out how I work with values from two seperate arrays to come up with a calculation.  I was trying to use MAPs but I wasn't quite able to get it to work.

Can someone explain the approach?  Code examples would be great but I am more interested in the approach of how to do this...  So here is an example:

My SOQL Query to build the map between event and case
Map<WhatId, Event> eventCaseMap = new Map<WhatId, Event>([Select Id, WhatId, ActivityDate, Ended_Yesterday__c  From Event WHERE WhatId LIKE '500%' AND Type='Example' AND Ended_Yesterday__c = TRUE]);
Now that I have the map, I need to iterate through this to determine the caseType__c value to calculate the days until due, and then add that to the event ActivityDate so that I can update the case next_due_date__c.

If all the values existed on the same object I can get it to work, but trying to make a calculation off of two of them is where my problem is.  Thanks in advance for any help/direction.
 
Account a = new Account(name = 'Microtek Inc');
insert a;
List<Contact> ContactList = new List<Contact>();
for (Integer i = 0; i < 5; i++) {
       contactList.add(new Contact
            (
            accountID = a.id;
            FirstName = 'Charles ' + i;
            LastName = 'Test Contact' + i;
            NT_Login_Name__c = 'testuser' + i;
            Management_Level_Type__c = 'Director';
            Former_Employee__c = false;
    ));

List<sObject> objects = new List<sObject>();
objects.addAll((List<sObject>)(contactList));
insert objects;

will above work ?
Hello All,
I am new to developmennt. 
We have Number field on Account called Open Contact Count and on Contact we have Status field picklist values as Open In Progress and Completed. Whenever any contact is created/updated with Status as Open related to Account, we need to maintain count of Open contact on related Account. I have written trigger for same but not working. Please give your valuable suggestions.
trigger ChildCount on Contact (after insert,after delete,after update,after undelete) {
     set<id> accid=new set<id>();
    if(trigger.isInsert|| trigger.IsUpdate|| trigger.isUndelete)
    {
        for(Contact con:trigger.new)
        {
            accid.add(con.AccountId);
        }
    }

    if(trigger.isDelete|| trigger.IsUpdate)
    {
        for(Contact Con: trigger.old)
        {
            accid.add(con.AccountId);
        }
    }
    
   list<Account> aclist=[select id, Open_Contact_Count__c,(Select id from Contacts) from Account where id in: accid];

 

List<Account> acupdate=new list<Account>();
   
    for(Account acc: aclist)
    {
        
       list<contact> clist= acc.Contacts;
       Account a1=new Account();
       Contact c1=new Contact();
      
               a1.Id=acc.Id;
            a1.Open_Contact_Count__c = clist.size();
       
           acupdate.add(a1);
      
    }
            update acupdate;
    }

 
I am trying check if the suppliedemail field contains any of these domains but is not working.
If(CONTAINS("lincare.com:ndc-inc.com:preferredhomecare.com", SuppliedEmail),mod(value(CaseNumber),3)+1,0)
 
I need to take this SOQL query out of my for loop. I've been researching using the Map method but honestly stuck when it comes to applying the logic to what I have:

for (Lead newLead : newLeadList)
        {
            system.debug('here ryan');
            Id referringAccount = newLead.Referring_Account__c;
            Account accountPulls = [SELECT Account_Pulls_Medication_History__c FROM Account WHERE Id =: referringAccount];
                
            system.debug('here ryan'+accountPulls);
            if (accountPulls.Account_Pulls_Medication_History__c)
            {
                system.debug('here ryan2');
                if(newLead.Medication_History_Pull__c == null)
                {
                    newLead.Medication_History_Pull__c = 'Pending';
                    system.debug('here ryan3');
                }
            }
        }


Any help would be much appreciated
 
 

Hi there.
I have an object called "Work Orders". I have a related object called "Pre-Work Orders".
I want to reference the custom Status field from the Pre-Work order ON the Work Order record.
I don't know how to do this. Because it's a related object, I don't see any way to access it through the formula builder options?
I believe I can create a "related object" formula like so:

WorkOrder__r.Pre_Work_Order__r.Status__c
I keep getting this: 
Error: Field WorkOrder__r does not exist. Check spelling.
I'm unsure of the correct format I need to reference?
Any help would be appricated. Thank you.

@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;
    }
}
Hi Team,
I have a requirement to convert my picklist value to date in a new field.
My picklist values are as May 2020, June 2021. Now I want to convert this value to a date format in the new field as 05/01/2020.
And all my values should be converted to 1st day of the month which is selected in the picklist.
Example:

Jan 2020-  01/01/2020
March 2021- 03/01/2021
April 2013 -  04/01/2013

It should be mm/dd/yyyy. And "dd" should be always 01.
i have searched many formulas to convert it to the required format, but could not achieve.
Please help me in achieving it.

Thanks,
Mahesh  
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();
    }

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 





 
Can we call a trigger from Batch class and batch class from trigger? if yes then what are the limitations.
On Account, How to fetch no. of open Opportunity
I tried using SalesForce Optimizer but apparently, it lies to me. It says that we don't have anything using API 20 or below, but I was sent an email from SalesForce that says " Our records show that you have apps using API version 20 or below". Since SalesForce is retiring API 7 - 20.  So how can I find where API 20 or below is being used so I can update it? 
I'm trying to figure out what the formula would be to require one picklist be selected if a certain item in another multi select picklist field is chosen.

I.E.  If Project type which is a multi select picklist contain PG then the PG type picklist field should be required.

Thanks,

Hi all ,

I have one requirement i need to bypass validation rule for one profile using apex class code not trigger how can i do that .
can any one help me on this 

 

I'm, just getting 63% code coverage..not able to incerase c..can any one help me
User-added image
Test class:
@isTest
public class TestOpportunityContactRoleHandler {
    @isTest static void TestBeforeInsertMethod(){
        
        Contact ConRec= new Contact();
        ConRec.FirstName = 'Test';
        ConRec.LastName   = 'Test';
        insert ConRec;
        
        Opportunity opps = new opportunity();
        opps.Name='test';
        opps.StageName='Processing';
        insert opps;
        
        OpportunityContactRole oppRole = new OpportunityContactRole();
        oppRole.Role='ROLE1';
        oppRole.ContactId = ConRec.Id;
        oppRole.OpportunityId = opps.Id;
        insert oppRole;
    }

 

please help with Process builder

 

AND(
ISCHANGED([Lead].Lead_Stage__c),
TEXT([Lead].Lead_Stage__c ) = "reengaged", 
OR(
TEXT([Lead].Source_Subtype__c) = "CPL", 
TEXT([Lead].scorecarr__c)  = "CPL" 
)
)

I have to 2 object having master-detail relationship. 
I want to update a Status picklist field in Parent object if any update is happening on either of the object (Parent or child).
What will be the best approach?

 
We need to update a checkbox field to true on the Service Resource object if the logeed in user is the manager or manager.manager of the service Resource user record. Please suggest.
I am working with events and cases but am having trouble on the concepts of joining two queries.  I need to query all events that:
  • completed yesterday
  • are related to a case (WhatId starts with 500)
  • are of event Type = 'Example'
Each of these are related to a case by definition of the original query, I now need to go through each of the cases and determine what the caseType__c is to determine the next_due_date__c which is a custom date field on the case which should calculate as:
  • Event Date + (If caseType__c = "Example" + 14, 60)

I am having a hard time figuring out how I work with values from two seperate arrays to come up with a calculation.  I was trying to use MAPs but I wasn't quite able to get it to work.

Can someone explain the approach?  Code examples would be great but I am more interested in the approach of how to do this...  So here is an example:

My SOQL Query to build the map between event and case
Map<WhatId, Event> eventCaseMap = new Map<WhatId, Event>([Select Id, WhatId, ActivityDate, Ended_Yesterday__c  From Event WHERE WhatId LIKE '500%' AND Type='Example' AND Ended_Yesterday__c = TRUE]);
Now that I have the map, I need to iterate through this to determine the caseType__c value to calculate the days until due, and then add that to the event ActivityDate so that I can update the case next_due_date__c.

If all the values existed on the same object I can get it to work, but trying to make a calculation off of two of them is where my problem is.  Thanks in advance for any help/direction.
 
Trigger is :
if(Trigger.isInsert){
                CompetitorRecordHandler.CreateRelatedCompetitor(Trigger.new);
            }

Handler class is below:
public static void CreateRelatedCompetitor(List<OpportunityLineItem> newList){
        
        List<Opportunity_Competitor__c> ocList = new List<Opportunity_Competitor__c>();
        
        for(OpportunityLineItem oli : newList){
            Opportunity_Competitor__c OppComp= new Opportunity_Competitor__c();
            
            OppComp.Forecast_Date__c=String.ValueOf(oli.ServiceDate);
            OppComp.Opportunity_Product__c=oli.Id;
            OppComp.Opportunity__c=oli.OpportunityId;
            OppComp.Product__c=oli.Product_Name__c;
            
            ocList.add(OppComp);
        }
        if(!ocList.isEmpty()){
            ocList.sort();
            insert ocList;
        }

I want to Sort my "ocList" on "Forecast_Date__c" basis. Can anyone help me?
Hi Team,

I have an object called Leave Tracker, where users enter the leave date, reason, and number of hours, user can create more than one record in a day with different hours, ex: 1 entry with 2 hours and another entry with 4 hours. but my request is that we should not allow a user to create/update a leave tracker record if the leave hours are more than 8 in a single day per user?

any help is appreciated.

Thanks,
Madhu

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!