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

  • Chatter
    Feed
  • 84
    Best Answers
  • 0
    Likes Received
  • 1
    Likes Given
  • 12
    Questions
  • 504
    Replies
version 47.0

Trying to craft a unit test. Using @testSetup method, which instantiates some objects within a System.RunAs to avoid the DML problem. But (at least) one of my objects instantiated within the System.RunAs is not visible to the test method even tho it does indeed get instantiated and inserted in the test setup method
@isTest
public class TaskHandlerTest {
    public static Id profileId  = [SELECT Id FROM Profile WHERE Name ='ASUO API User Profile'].Id;
    public static User thisUser = [SELECT Id FROM User WHERE Name = 'API ASU EdPlus ASUO'];
    
    public static UserRole testUserRole_ASU;
    public static Contact contact_ASU;

    @testSetup
    static void setUpTest() {

        testUserRole_ASU = new UserRole(
            Name = 'ASU Local',
            OpportunityAccessForAccountOwner = 'Edit'
        );
        insert testUserRole_ASU;
        System.RunAs( thisUser) {
            contact_ASU = new Contact(
                FirstName = 'Pete',
                LastName = 'Townshend',
                Email = 'thewho1@who.com',
                Last_Contact_Method__c = 'text',
                Last_Contact_Attempt__c = Datetime.valueOf('2020-04-04 00:00:00')
            );
            insert contact_ASU;
            System.debug('contact_ASU inserted with Id: ' + contact_ASU.Id);
        }
    }

    @IsTest
    static void test_pass_new_EmailOutbound() {
        Test.startTest();
        TestDataFactory.createCustomSetting('Object Triggers');
        Task task = new Task(
            Description = 'pass_new_EmailOutbound',
            TaskSubType = 'Email',
            Email_Direction__c = 'Outbound',
            WhoId = contact_ASU.Id,  // <--- throws "dereferencing null value" msg here
            Actual_End__c = Datetime.valueOf( '2020-05-20 00:00:00')
        );
        insert task;  // should trigger TaskHandler after_insert()

        System.assertEquals( contact_ASU.Last_Contact_Method__c, 'Email');
        System.assertEquals( contact_ASU.Last_Contact_Attempt__c, task.Actual_End__c);
        Test.stopTest();
    }
}
contact_ASU is declared static outside of setUpTest().
The debug log shows my contact_ASU does get instantiated and inserted and has an Id.  Both setUpTest and test_pass_new_EmailOutbound() are declared static.

So I would expect contact_ASU to be visible to test_pass_new_EmailOutbound() --  what am I doing wrong/ not doing right ?

TIA,

Chris

 
Hi,

I'm using two objects: Cases and Agreements, each with two record types (NDA and MSA). I want to create a Case with a record type NDA that will create an NDA record type record in the Agreements object.

I can do this with Process Builder, except I can't seem to get the Case NDA request to create a NDA record type in Agreements - for some reason it defaults to MSA. 

Just wondering if it's possible to select various record types, (Case NDA  create Agreement NDA record) or does Process Builder only know how to create a new record in another object w/out being able to distinguish record types? If it's not possible, does anyone have any workarounds?

Thank you!
Hi - I am an admin that is trying to code something into our instance to calculate business hours between 2 date/time fields based on owner location to account for time zone changes. I was able to find and tweak the code from this website (https://www.tech-vision.us/salesforce-the-number-of-business-hours-between-two-date-time-fields/). I then wrote a Test Class but am only able to get to 55% code coverage and cannot figure out why. 

Trigger:
trigger Demo_Response_Biz_Hours_Time_Zones on Lead (before insert, before update) {
   
    //Selecting all active BusinessHours records
    List<BusinessHours> BusinessHours_List = [SELECT Id, Name FROM BusinessHours WHERE IsActive = true];
   
    //Adding map where BusinessHours Name will be the key
    Map<String, BusinessHours> LocationName_BusinessHours_Map = new Map<String, BusinessHours> ();
   
    //Filling the map | Location Name, BusinessHours Object
    for (BusinessHours b : BusinessHours_List) {
        LocationName_BusinessHours_Map.put(b.Name, b);
    }
    for (Lead leadObj : Trigger.new) {
        
        //This part of a trigger only works when we add new records
        if (Trigger.isInsert) {
            
            //We check if both Start Time & Completed Time fields are not empty
            if (leadObj.Demo_Form_Submission_Date__c != NULL && leadObj.First_Activity_Most_Recent_Demo_Request__c != NULL) {
                
                //Then we do another check if current record is tied to a location that has business hours record
                if (LocationName_BusinessHours_Map.containsKey(leadObj.Owner_Location__c)) {
                    decimal result = BusinessHours.diff(LocationName_BusinessHours_Map.get(leadObj.Owner_Location__c).Id, leadObj.Demo_Form_Submission_Date__c, leadObj.First_Activity_Most_Recent_Demo_Request__c);
                    Decimal resultingHours = result / (60 * 60 * 1000);
                    leadObj.APEXTEST_Demo_Response_Time_Zones__c = resultingHours.setScale(1);
                } else{
                    
                    //Just as a safety net, let's use default business hours in case there is no match between Location name and BH name
                    if(LocationName_BusinessHours_Map.get('Default').Id != NULL){
                        decimal result = BusinessHours.diff(LocationName_BusinessHours_Map.get('Default').Id, leadObj.Demo_Form_Submission_Date__c, leadObj.First_Activity_Most_Recent_Demo_Request__c);
                        Decimal resultingHours = result / (60 * 60 * 1000);
                        leadObj.APEXTEST_Demo_Response_Time_Zones__c = resultingHours.setScale(1);
                    }
                }
            }
        } else if (Trigger.isUpdate) {
            
            //This part of a trigger only works when we perform update
           
            //Checking if Start Time or Completed Time has been changed & if they are not empty
            if ((leadObj.Demo_Form_Submission_Date__c != NULL && leadObj.First_Activity_Most_Recent_Demo_Request__c != NULL) && ((leadObj.Demo_Form_Submission_Date__c != Trigger.oldMap.get(leadObj.id).Demo_Form_Submission_Date__c) || (leadObj.First_Activity_Most_Recent_Demo_Request__c != Trigger.oldMap.get(leadObj.id).First_Activity_Most_Recent_Demo_Request__c))) {
                if (LocationName_BusinessHours_Map.containsKey(leadObj.Owner_Location__c)) {
                    decimal result = BusinessHours.diff(LocationName_BusinessHours_Map.get(leadObj.Owner_Location__c).Id, leadObj.Demo_Form_Submission_Date__c, leadObj.First_Activity_Most_Recent_Demo_Request__c);
                    Decimal resultingHours = result / (60 * 60 * 1000);
                    leadObj.APEXTEST_Demo_Response_Time_Zones__c = resultingHours.setScale(1);
                } else{
                    if(LocationName_BusinessHours_Map.get('Default').Id != NULL){
                        decimal result = BusinessHours.diff(LocationName_BusinessHours_Map.get('Default').Id, leadObj.Demo_Form_Submission_Date__c, leadObj.First_Activity_Most_Recent_Demo_Request__c);
                        Decimal resultingHours = result / (60 * 60 * 1000);
                        leadObj.APEXTEST_Demo_Response_Time_Zones__c = resultingHours.setScale(1);
                    }
                }
            } else if (leadObj.Demo_Form_Submission_Date__c == NULL || leadObj.First_Activity_Most_Recent_Demo_Request__c == NULL) {
                
                //Another safety net that will reset Hours spent in case Start Time OR Completed time becomes empty after update.
               
                //That way you won't have old & inaccurate data from past calculations.
                leadObj.APEXTEST_Demo_Response_Time_Zones__c = NULL;
            }
        }
    }
}

Test Class:
@isTest

public class TestDemoResponseTime {

    Static testmethod void LeadTest() {
    
        //create a lead
        Lead leadObj = new Lead();
        leadObj.LastName = 'Test';
        leadObj.Company = 'Test ABC';
        leadObj.LeadSource = 'Sales Prospecting';
        leadObj.Lead_Source_Detail__c = 'Apex Test Class';
        leadObj.OwnerID = '0054G000008UaurQAC';
        leadObj.Demo_Form_Submission_Date__c = datetime.newInstance(2020, 04, 15, 14, 00, 00);
                
        insert leadObj;
        
        //business hours
        BusinessHours b = [SELECT Id FROM BusinessHours WHERE Name = 'Denver'];
        
        //update the lead
        leadObj = [SELECT Id, LastName, Company, LeadSource, Lead_Source_Detail__c, OwnerID, Owner_Location__c, Demo_Form_Submission_Date__c, First_Activity_Most_Recent_Demo_Request__c FROM Lead WHERE Id != NULL];
        leadObj.First_Activity_Most_Recent_Demo_Request__c = datetime.newInstance(2020, 04, 16, 19, 00, 00);
        
        update leadObj;
   }
}

I've checked the developer console and the sections that aren't covered are:
if (LocationName_BusinessHours_Map.containsKey(leadObj.Owner_Location__c)) {
                    decimal result = BusinessHours.diff(LocationName_BusinessHours_Map.get(leadObj.Owner_Location__c).Id, leadObj.Demo_Form_Submission_Date__c, leadObj.First_Activity_Most_Recent_Demo_Request__c);
                    Decimal resultingHours = result / (60 * 60 * 1000);
                    leadObj.APEXTEST_Demo_Response_Time_Zones__c = resultingHours.setScale(1);

Does anyone have any ideas on what I'm missing? Thank you!
Hi there,

Please help with this class where I am getting an error upon saving the test class below:
 
@isTest
public class APTS_ResendCreditMemoEmailTest{
    static testMethod  void creditMemoDocumentGenerationTest(){

        Profile profileSO = [SELECT Id FROM Profile WHERE Name = 'Standard User' LIMIT 1];
        
        User userSO = APTS_TestDataFactory.getUser('LastName123','medidate', profileSO.ID);
        insert userSO;
        System.runAs(userSO){
            EmailTemplate emailTemplateSO1 = APTS_TestDataFactory.getEmailTemplate('APTS Non Japan Invoice','APTS_Non_Japan_Invoice', userSO.ID);
            List<EmailTemplate> listEmailTemplate = new List<EmailTemplate>();
            listEmailTemplate.add(emailTemplateSO1);
            insert emailTemplateSO1;
        }

        insert APTS_TestDataFactory.getTaxConnectorConfigSetting();

        //Create & Insert Core Currency
        appirio_core__Currency__c coreCurrencyUSD = APTS_TestDataFactory.getCoreCurrency('U.S. Dollar','USD', TRUE);
        LIst<appirio_core__Currency__c> coreCurrencylist = new List<appirio_core__Currency__c>();
        coreCurrencylist.add(coreCurrencyUSD);
        insert coreCurrencylist;
        
        APTS_Legal_Entity__c legalEntitySO= APTS_TestDataFactory.getLegalEntity('Japan', coreCurrencyUSD.ID, FALSE);
        legalEntitySO.APTS_LE_Company_Code__c = 'ABC';
        legalEntitySO.APTS_LE_Country__c  = 'DEF';
        insert legalEntitySO;

        Apttus_Config2__PaymentTerm__c paymentTermSO = APTS_TestDataFactory.createPaymentTerm('Net 120', 'Net 120 Days', 120 , TRUE);
        insert paymentTermSO;

        APTS_Invoice_Number_Settings__c invoiceNumberSettingSO = APTS_TestDataFactory.getInvoiceNumberSetting(legalEntitySO.ID);
        insert invoiceNumberSettingSO;

        //Create & Insert Account
        Account accSO = APTS_TestDataFactory.getAccount('Test Account');
        accSO.APTS_Global_MSA__c = TRUE;
        insert accSO;
        
        Contact contactSO1 = APTS_TestDataFactory.getContact(accSO.ID, 'Japan', 'Last1', 'Japan');
        Contact contactSO2 = APTS_TestDataFactory.getContact(accSO.ID, 'Esker', 'Last2', 'Japan');
        List<Contact> listContact = new List<Contact>();
        listContact.add(contactSO1);
        listContact.add(contactSO2);
        insert listContact;

        Apttus_Config2__AccountLocation__c accountLocationSO1 = APTS_TestDataFactory.getAccountLocation('USA Account Location', accSO.ID, 'USA');
        accountLocationSO1.Apttus_Config2__DefaultInvoiceTemplate__c = 'APTS Non Japan Invoice';
        Apttus_Config2__AccountLocation__c accountLocationSO2 = APTS_TestDataFactory.getAccountLocation('USA Account Location', accSO.ID, 'USA');
        List<Apttus_Config2__AccountLocation__c> accountLocationList = new List<Apttus_Config2__AccountLocation__c>();
        accountLocationList.add(accountLocationSO1);
        accountLocationList.add(accountLocationSO2);
        insert accountLocationList;

        Opportunity oppSO1 = APTS_TestDataFactory.getOppty(accSO.ID, 'USA Opp');
        Opportunity oppSO2 = APTS_TestDataFactory.getOppty(accSO.ID, 'USA Opp');
        List<Opportunity> oppList = new List<Opportunity>();
        oppList.add(oppSO1);
        oppList.add(oppSO2);
        insert oppList;

        Apttus_Config2__Order__c orderSo = APTS_TestDataFactory.getOrder(accSO.Id, oppSO1.ID, accountLocationSO1.ID);
        orderSo.Apttus_Config2__PaymentTermId__c = paymentTermSO.ID;
        orderSo.APTS_Invoice_Delivery_Method_Email__c = true;
        orderSo.APTS_Invoice_Delivery_Method_Print__c = true;
        insert orderSo;

        Apttus_Billing__Invoice__c invoiceSO1 = APTS_TestDataFactory.getInvoice(accSO.ID, paymentTermSO.ID);
        invoiceSO1.APTS_Legal_Entity__c = legalEntitySO.ID;
        invoiceSO1.Apttus_Billing__LocationId__c = accountLocationSO1.ID;
        invoiceSO1.APTS_Order__c = orderSo.ID;
        
        Apttus_Billing__Invoice__c invoiceSO2 = APTS_TestDataFactory.getInvoice(accSO.ID, paymentTermSO.ID);
        invoiceSO2.APTS_Legal_Entity__c = legalEntitySO.ID;
        invoiceSO2.Apttus_Billing__LocationId__c = accountLocationSO2.ID;
        invoiceSO2.APTS_Order__c = orderSo.ID;

        List<Apttus_Billing__Invoice__c> invoiceList = new List<Apttus_Billing__Invoice__c>();
        invoiceList.add(invoiceSO1);
        invoiceList.add(invoiceSO2);
        insert invoiceList;

        Apttus_Billing__CreditMemo__c creditMemoSO = APTS_TestDataFactory.getCreditMemmo(accSO.ID, invoiceSO1.ID);
        creditMemoSO.APTS_Legal_Entity__c = legalEntitySO.ID;
        creditMemoSO.Apttus_Billing__LocationId__c = accountLocationSO1.ID;
        creditMemoSO.APTS_Shipping_Location__c = accountLocationSO1.ID;
        //creditMemoSO.Apttus_Billing__Status__c = 'Approved';
        creditMemoSO.Apttus_Billing__DeliveryStatus__c = 'Pending';
        creditMemoSO.APTS_Order__c = orderSo.ID;

        List<Apttus_Billing__CreditMemo__c>creditMemolist = new List<Apttus_Billing__CreditMemo__c>();
        creditMemolist.add(creditMemoSO);
        insert creditMemolist;
        
        Attachment attachmentSO = APTS_TestDataFactory.getAttachment(creditMemoSO.ID,'CreditMemo Attachment');
        List<Attachment> listAttachment = new List<Attachment>();
        listAttachment.add(attachmentSO);
        insert listAttachment;


        Apttus_Billing__RelatedARTransaction2__c relatedARTransactionSO = APTS_TestDataFactory.getRelatedARTransaction(invoiceSO1.ID);
        relatedARTransactionSO.Apttus_Billing__TxnType__c = 'Refund';
        relatedARTransactionSO.Apttus_Billing__DestinationCreditMemoId__c = creditMemoSO.ID;
        insert relatedARTransactionSO;
        
        Test.startTest();
        Test.setCurrentPageReference(new PageReference('Page.myPage'));
        System.currentPageReference().getParameters().put('creditMemoID', creditMemoSO.ID);
        System.currentPageReference().getParameters().put('status', 'Approved');

        APTS_ResendCreditMemoEmail resendCreditMemoEmail = new APTS_ResendCreditMemoEmail();
        resendCreditMemoEmail.resendEmail();
        
        Test.stopTest();

    }
}

The error is:

Error: Compile Error: Method does not exist or incorrect signature: void getOrder(Id, Id, Id) from the type APTS_TestDataFactory at line 62

Any guidance would be most appreciated. Thank you!
 
Hi All,

When Record is submitted as Draft. Profile should have edit access for that Draft.
Two profile: P1 and P2. Two page layout created for both profile one is read only and other Read/Write access. When P1 submit a record as status is saved as Draft . P1 should have access to Edit that record.

Page layout in detail page if I had Edit button. It assign to both the page layout. Is there any other way around to achieve this.

Thanks for the help in advance
public with sharing class FieldnotEmptycontrl {

    public static Property__c field {get; set;}

    public FieldnotEmptycontrl(){
    field = new Property__c();

    }

    public static void fieldNotEmpty(List<Property__c> prop){

        if(field.Business__c == null || field.Contact__c == null){

            field.Business__c.addError('You must enter a value!');
            field.Contact__c.addError('You must enter a value!');

        if(field.Business__c != null && field.Contact__c != null){

            field.Business__c.addError('Cannot use two fields at the same time. Please choose only one field Business or Contact');
            field.Contact__c.addError('Cannot use two fields at the same time. Please choose only one field Business or Contact');
        }

        }
    }
}
Here is the Trigger calling the above class and method, but it shows the error • triggers/fieldNotEmpty.trigger: ERROR at line 1, column 1 - Must specify the metadata file 
trigger fieldNotEmpty on Property__c (before insert, before update, after insert) {

    if (Trigger.isBefore) {
        if(Trigger.isInsert){

            FieldnotEmptycontrl.fieldNotEmpty(Trigger.new);
          
        }
    }
}
Please help me to resolve the issue
 
The below batch class will be processing a little over 2.5 million records. The START method will be sending in the whole 2.5 million records to the execute method and the execute method does the processing on each of the 2.5 million records inside a for loop. 
Also the for loop has a SOQL inside which I believe cannot be avoided to get the right numbers. 
Is this the right way of doing this or are there any other better ways. Please help!

Also when the running the below batch class I get the First Error: Too many query rows error.
 
global class MDUSquadRawDataBatchTest implements Database.Batchable<sObject>, Database.Stateful {  
    List<Address_Master__c> addressList = new List<Address_Master__c>();
    Set<String> addresses = new Set<String>();
   
    // Start Method
    global Database.QueryLocator start(Database.BatchableContext BC) {
        return Database.getQueryLocator('SELECT Street_Address__c,City_Name__c FROM MDU_Squad_Raw_Data__c');
    }   
    
    // Execute method
    global void execute(Database.BatchableContext BC, List<MDU_Squad_Raw_Data__c> rawData) {        
        for(MDU_Squad_Raw_Data__c mduRawData: rawData) {
            List<MDU_Squad_Raw_Data__c> addressData = [SELECT Street_Address__c,City_Name__c,Province_Code__c,Postal_Code__c,Internet_Service__c,Video_Service__c,Phone_Service__c FROM MDU_Squad_Raw_Data__c WHERE Street_Address__c=:mduRawData.Street_Address__c AND City_Name__c=:mduRawData.City_Name__c];
            String fullAddress = addressData[0].Street_Address__c+' '+addressData[0].City_Name__c+' '+addressData[0].Province_Code__c+' '+addressData[0].Postal_Code__c;
            
            Address_Master__c theAddress = new Address_Master__c();
            if(!addresses.contains(fullAddress.substringBeforeLast(' '))) {
                theAddress.Name = addressData[0].Street_Address__c;
                theAddress.City_Name__c = addressData[0].City_Name__c;
                theAddress.Province_Code__c = addressData[0].Province_Code__c;
                theAddress.Postal_Code__c = addressData[0].Postal_Code__c; 
                fullAddress = addressData[0].Street_Address__c+' '+addressData[0].City_Name__c+' '+addressData[0].Province_Code__c+' '+addressData[0].Postal_Code__c;
                theAddress.Full_Address_Ext_Id__c = fullAddress;

                addresses.add(fullAddress.substringBeforeLast(' '));
                addressList.add(theAddress); 
            }                                                     
        }            
        Database.Upsert(addressList, Address_Master__c.Fields.Full_Address_Ext_Id__c, true);
    }
    // Finish Method    
    global void finish(Database.BatchableContext BC) {
        
    } 
}

I request if someone could please help me with this, as I am dealing with this for some time, with no idea on how to fix this.
Hello all. I am making a class that ensures that there is an attachment on an Opp whenever its closed won. Below is my class that actually does the logic. Below that is the test class. The logic works fine but I can only get 42% coverage though. The underlined code is what is not being covered, this is in a Lightning instance fyi. Thanks for the help!

public class OpportunityHandler {
    public static void checkOppForAttachment (List<Opportunity> oppList){
        
        for(Opportunity opp : oppList){
            if(opp.stageName == 'Closed Won' || opp.stageName == 'Closed Won (R)'){
                ContentDocumentLink cdl = null;
                List<ContentDocumentLink> cdl2 = [Select Id from ContentDocumentLink where LinkedEntityId =:opp.Id];
                   
                if (cdl2.isEmpty()){

                    opp.addError('Please ensure the contract is attached prior to closing this Opportunity');
                }
            }
        }
    }
}

Test Class
@isTest
public class OpportunityHandlerTest {
    @isTest public static void validateAttachment() {
        //Create Account and Opportunity
    List<RecordType> acctRecType = [Select Id from RecordType where developerName = 'Company' and sObjectType = 'Account'];
    List<RecordType> oppRecType  = [Select Id from RecordType where developerName = 'AM_Channel' and sObjectType = 'Opportunity'];
            Test.startTest();
        try{
    Account acct      = new Account();
    acct.name         = 'Test Account1';
    acct.RecordTypeId = acctRecType.get(0).id;
    insert acct;
        
    Opportunity opp     = new Opportunity();
        opp.Name        = 'test opp';
        opp.CloseDate   = system.today()+1;
        opp.StageName   = 'Initial Pitch/Demo';
        opp.Use_Case__c = 'Brand Tracker';
        opp.AccountId   = acct.Id;
        opp.RecordTypeId = oppRecType.get(0).id;
        insert opp;
        
    Opportunity opp2     = new Opportunity();
        opp2.Name        = 'test opp2';
        opp2.CloseDate   = system.today()+1;
        opp2.StageName   = 'Initial Pitch/Demo';
        opp2.Use_Case__c = 'Brand Tracker';
        opp2.AccountId   = acct.Id;
        opp2.RecordTypeId = oppRecType.get(0).id;
        insert opp2;
       

    ContentVersion contentVersion = new ContentVersion(
          Title          = 'a picture',
          PathOnClient   = 'Pic.jpg',
          VersionData    = Blob.valueOf('Test Content'),
          IsMajorVersion = true);
        insert contentVersion; 
        
List<ContentDocument> documents = [SELECT Id, Title, LatestPublishedVersionId FROM ContentDocument];

//create ContentDocumentLink  record 
    ContentDocumentLink cdl = New ContentDocumentLink();
        cdl.LinkedEntityId = opp.id;
        cdl.ContentDocumentId = documents[0].Id;
        cdl.shareType = 'V';
        cdl.visibility = 'AllUsers';
        insert cdl;
        
List<Opportunity> updateList = new List<Opportunity>();

List<ContentDocumentLink> cdl2 = [Select Id from ContentDocumentLink where LinkedEntityId =:opp.Id];
            List<Opportunity> oldOpp = [Select id from Opportunity where Name = 'test opp'];
                for (Opportunity runUpdate : oldOpp){
                    runUpdate.stageName = 'Closed Won (R)';
                    updateList.add(runUpdate);
                    system.debug(runUpdate.stageName);
                    update updateList;
                    System.assertEquals(documents.size(), 1);
                }
             }
        catch(Exception e){
            System.Assert(e.getMessage().contains('Please ensure the contract is attached prior to closing this Opportunity'));
        }
            test.stopTest();
    }

}
Hey..

I have 4-5 workflows which do the same function on the Account object. They all put a Date Stamp based on different fileds in a picklist. Since we have 5 options in a picklist and we are tracking the date of every option, I have to create 5 different workflows. 

I have little to no experience working with Triggers. Is it possible to achieve this with 1 trigger?


Thanks 
Hey all!

With some help I wrote this custom trigger that allows our reps to list some additional contacts and their information on Lead records that then transform into Contact records on lead convert.
 
trigger CreateMoreLeadContacts on Lead (after update) {

list < Contact > listContacts = new List < Contact>();

for(Lead objLead : trigger.new) {

if(objlead.IsConverted && !trigger.oldMap.get(objLead.Id).IsConverted) {

Contact c1=New Contact(
LastName=objLead.Secondary_Lead_Contact_Name__c,
Phone=objLead.Secondary_Lead_Phone__c,
Email=objLead.Secondary_Lead_Email__c);

c1.AccountId = objLead.ConvertedAccountId;
listContacts.add(c1);

Contact c2=New Contact(
LastName=objLead.Tertiary_Lead_Contact_Name__c,
Phone=objLead.Tertiary_Lead_Phone__c,
Email=objLead.Tertiary_Lead_Email__c);

c2.AccountId = objLead.ConvertedAccountId;
listContacts.add(c2);

     }
        
    }
    
    if ( listContacts.size() > 0 )
        insert listContacts;

}
The trigger works just fine and as expected... however, i've now indentified an issue when trying to convert a Lead when no data is present in both "Secondary Contact Lead Name" & "Tertiary Contact Lead Name".

Only way to get around this with the current trigger is to list dummy Contact name data in the custom lead fields before the Lead gets converted.

What would be the best way to encapsulate the trigger so that it doesn't fire when names aren't listed / just when one additional contact is listed? 



 
The situation: I spun off a sandbox, and within that sandbox, I commented out large portions of code in order to disable a feature we're not going to use, and was linked to an installed package we wished to uninstall.  I ran the entire suit of Apex tests and everything passed with flying colors.

The problem: When I try to deploy the resulting change set into production, I get told "Dependent class is invalid and needs recompilation" for every single item of the change set.  It points to a method in one particular class as the source of the error - a method that I comment out, and I made sure every piece of code referring to that method was commented out too.

According to the help files, the solution was to recompile all Apex classes.  Very well.  Did this in Production, did this in Sandbox, started a new change set and deployment.  Still no dice, the error pops up again.  But I can't recompile any more than what I've already done, so what gives?

How am I supposed to get rid of this error and complete my deployment into production?
I have my client asking below
if an apportunity creation fails, due to any error (validation, trigger, workflow etc), then that should send some alert message or record the information somewhere.


I know flow errors can be sent, or trigger errors can be handled, but in general someone (could be any user, community user, integration user etc) tries to create a record, this fails , how do I capture and send information to specific user or an admin.

I know this can be debugged , that shows there was an error to create record, but is it possible to capture such information and record it elsewhere

thanks
aslam
I have this validation rule in status, where it has 3 values (analysis, process, completed), all the profiles can assign these 3 statuses, but once it is in the completed value you must activate the rule where only the administrator can change that value 
I have it like this:

AND(
          ISPICKVAL(Status__c, "completed"), 
          RecordType.Name = "Sales", 
          NOT( ISNEW()), 
          $Profile.Name <> "System Administrator"
)

Could you help me?
public class CreateCampaignfromLead {
    Public static void AddCampaignmember(list<lead>ListLead){
        list<lead>ListLd=new list<lead>();
        Id OppId;
        Date FCDate;
        Id CampId;
        list<campaignmember> cmmlist = new list<campaignmember>();
        for(Lead ld:ListLead){
            if(ld.Agent_Site_Source__c=='Re-Marketed opportunity' && ld.Referenced_Opportunity__c !=null ){
                OppId=ld.Referenced_Opportunity__c;  
            }
            List<opportunity>OppList=[select id,stagename,Future_Contact_Date__c from opportunity where 
                                      (stagename='No Solution - Not Qualified' OR 
                                       stagename='No Solution - No Experience' 
                                       OR stagename='No Solution - Age Experience' OR
                                       stagename='No Solution - Outside of quote period') AND ID=:OppId];
            
            for(opportunity Opp:OppList){
                FCDate=opp.Future_Contact_Date__c;
            }  
            if(OppList.Isempty()){
                List<opportunity>OpList=[select Id,stagename,CloseDate from opportunity where (stagename='NTU - Deal Lost' OR 
                                                                                               stagename='NTU - Too Expensive' )AND ID=:OppId];
                
                for(opportunity Opp:OpList){
                    FCDate=opp.CloseDate;
                }
            }
            list<campaign>camplist = new list<campaign>();
            camplist = [select Id , Name,Campaign_Date__c from campaign  where
                        CALENDAR_MONTH(Campaign_Date__c) = :FCDate.month() AND CALENDAR_YEAR(Campaign_Date__c) 
                        =:FCDate.YEAR()];
            for(campaign cam:camplist){
                CampId=cam.Id;
            }
            campaignmember cmm = new campaignmember();
            cmm.campaignid= CampId;
            cmm.LeadId =ld.id;
            cmmlist.add(cmm);
        }
        insert cmmlist;
    }
}
I need to avoid booking at the same time i.e one booking is at 7pm to 8pm and another one is booking at 7:30pm to 8pm.
can anyone help to resolve this
I have 5 Controllers which affect opportunities. Each has a test which provides > 90% code coverage in UAT. When I look in production, these tests provide 0% code coverage when the Controllers and related tests are identical between UAT and production. General question is what could cause these tests to fail given the success in UAT and the artifacts promote successfully to production?
Here's the formula I am using for a Validation Rule to require a specific phone number format be entered (xxx) xxx-xxxx. This formula works for me.

AND(
NOT(ISBLANK(HomePhone)),
NOT(REGEX(HomePhone, "\\([0-9]{3}\\) [0-9]{3}-[0-9]{4}"))
)

Is there anything I can add to the formula to prevent it from firing on a specific record type? Let's call it "Record Type A".

Thanks.
Hi,

current formula has 5 405 compiled size, as we know the limit is 5 000.
Do you have any idea how to reduce it?

if(OR(AND(ClientBasket__c = "B",
OR(ISPICKVAL(Owner.FLSA_Job_Title__c,"Junior Account Manager 1"),ISPICKVAL(Owner.FLSA_Job_Title__c,"Junior Account Manager 2"),ISPICKVAL(Owner.FLSA_Job_Title__c,"Account Manager"), ISPICKVAL(Owner.FLSA_Job_Title__c,"Key Account Manager")))=true,
AND(OR(ClientBasket__c = "C",
OR(ISPICKVAL(Owner.FLSA_Job_Title__c,"Senior Key Account Manager"),ISPICKVAL(Owner.FLSA_Job_Title__c,"Expert"))))),1,

if(OR(AND(ClientBasket__c="A",
OR(ISPICKVAL(Owner.FLSA_Job_Title__c,"Junior Account Manager 1"),ISPICKVAL(Owner.FLSA_Job_Title__c,"Junior Account Manager 2"),ISPICKVAL(Owner.FLSA_Job_Title__c,"Account Manager")=true)),
AND(ClientBasket__c = "B",
OR(ISPICKVAL(Owner.FLSA_Job_Title__c,"Senior Key Account Manager"),ISPICKVAL(Owner.FLSA_Job_Title__c,"Expert")))),2,

if(AND(ClientBasket__c = "A",
OR(ISPICKVAL(Owner.FLSA_Job_Title__c,"Key Account Manager"),ISPICKVAL(Owner.FLSA_Job_Title__c,"Senior Key Account Manager")))=true,3,

if(AND(ClientBasket__c = "A",ISPICKVAL(Owner.FLSA_Job_Title__c,"Expert"))=true,4,

0))))
I have written a trigger to roll up opportunity amount on quota. The code is working fine. I have a problem in line 34.
 If I add two new opportunity with amoth as 100 and 100. The roll up is 200.
Again if I edit it recaclulates and adds 200 which is euql to 400. This logic is wrong how to correct it.

trigger Roll on Opportunity (before insert,before update,after insert,after update){
    Set<Id> setOpportunityIds=new Set<Id>();
    
    for(Opportunity c:Trigger.new)
        if(c.StageName == 'Closed Won' && c.Closed_Date__c == 'January' )
        
        
        setOpportunityIds.add(c.id);
    
    
    
    List<Quota__c> ListOfAllOrgs = [select id,RecordTypeId, Actual_Amount__c,Opportunity__c,Quota_Amount__c from Quota__c];
    List<Quota__c> lstCommissionToUpdate=new List<Quota__c>();
    
    for(AggregateResult result:[Select Quota__c,SUM(Amount) From Opportunity 
                                WHERE Id IN :setOpportunityIds GROUP BY Quota__c LIMIT 1 ])
    {
        
        for(Quota__c org : ListOfAllOrgs)
            
        {
            
                    System.debug('Amount value in Org is' + Decimal.ValueOf(String.ValueOf(result.get('expr0'))));
            if(result.get('Quota__c') == org.Id && org.Actual_Amount__c == null )
            {
                if(  org.RecordTypeId == '0122v000002KFRAAA4')
                {
                    org.Actual_Amount__c = 0;
                }
                else{
                    org.Actual_Amount__c = org.Actual_Amount__c + Decimal.ValueOf(String.ValueOf(result.get('expr0'))); 
                    
                    
                    if(result.get('Quota__c') == org.Id && org.Actual_Amount__c != null )
                    {
                        if(  org.RecordTypeId == '0122v000002KFRAAA4')
                        {
                            org.Actual_Amount__c = 0;
                        }
                        else{
                            org.Actual_Amount__c = org.Actual_Amount__c + Decimal.ValueOf(String.ValueOf(result.get('expr0'))); 
                            
                            System.debug('Amount value in Org is' + Decimal.ValueOf(String.ValueOf(result.get('expr0'))));
                        }
                        
                        
                        
                        
                        lstCommissionToUpdate.add(org);
                        System.debug('Amount value in Org is' + Decimal.ValueOf(String.ValueOf(result.get('expr0'))));
                    }
                }
            }
            if(lstCommissionToUpdate.size()>0){
                
                update lstCommissionToUpdate;
                System.debug('Amount value in Org is' + Decimal.ValueOf(String.ValueOf(result.get('expr0'))));
            }
        }
    }
}
We import a csv file daily to new records in a custom object. One of those fields is a long-text area, which I will call "notes". When the notes are imported, they come in as one very long string of text, and each note is separated by "*** yyyy-dd-mm***" (three asterics surrounding the date of the note). I want my "before insert" trigger to organize the long text area, such that a new paragraph begins with each new note. Can someone please assist with writing this trigger?  Here is what I have so far but it is not working:

trigger DischargeAfterInsert on Discharge__c (after insert) {

    for (discharge__c disch : trigger.new){
        string progressnotes = disch.progress_notes__c;
        progressnotes = progressnotes.replace('. ***', '. <br> ***');
        update disch;
            }
}
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 





 
version 47.0

Trying to craft a unit test. Using @testSetup method, which instantiates some objects within a System.RunAs to avoid the DML problem. But (at least) one of my objects instantiated within the System.RunAs is not visible to the test method even tho it does indeed get instantiated and inserted in the test setup method
@isTest
public class TaskHandlerTest {
    public static Id profileId  = [SELECT Id FROM Profile WHERE Name ='ASUO API User Profile'].Id;
    public static User thisUser = [SELECT Id FROM User WHERE Name = 'API ASU EdPlus ASUO'];
    
    public static UserRole testUserRole_ASU;
    public static Contact contact_ASU;

    @testSetup
    static void setUpTest() {

        testUserRole_ASU = new UserRole(
            Name = 'ASU Local',
            OpportunityAccessForAccountOwner = 'Edit'
        );
        insert testUserRole_ASU;
        System.RunAs( thisUser) {
            contact_ASU = new Contact(
                FirstName = 'Pete',
                LastName = 'Townshend',
                Email = 'thewho1@who.com',
                Last_Contact_Method__c = 'text',
                Last_Contact_Attempt__c = Datetime.valueOf('2020-04-04 00:00:00')
            );
            insert contact_ASU;
            System.debug('contact_ASU inserted with Id: ' + contact_ASU.Id);
        }
    }

    @IsTest
    static void test_pass_new_EmailOutbound() {
        Test.startTest();
        TestDataFactory.createCustomSetting('Object Triggers');
        Task task = new Task(
            Description = 'pass_new_EmailOutbound',
            TaskSubType = 'Email',
            Email_Direction__c = 'Outbound',
            WhoId = contact_ASU.Id,  // <--- throws "dereferencing null value" msg here
            Actual_End__c = Datetime.valueOf( '2020-05-20 00:00:00')
        );
        insert task;  // should trigger TaskHandler after_insert()

        System.assertEquals( contact_ASU.Last_Contact_Method__c, 'Email');
        System.assertEquals( contact_ASU.Last_Contact_Attempt__c, task.Actual_End__c);
        Test.stopTest();
    }
}
contact_ASU is declared static outside of setUpTest().
The debug log shows my contact_ASU does get instantiated and inserted and has an Id.  Both setUpTest and test_pass_new_EmailOutbound() are declared static.

So I would expect contact_ASU to be visible to test_pass_new_EmailOutbound() --  what am I doing wrong/ not doing right ?

TIA,

Chris

 
trigger TriggerNew1Problem on Account(after insert)
{
    Set<String> setacc = new Set<String>();
    for(Account a : Trigger.new)
    {
        setacc.add(a.Name);
    }
    
    List<Account> acclist = [Select Id, Name, (Select Id, Name From Opportunities)
    From Account Where Name In : setacc
    ];
    List<Opportunity> opplist = new List<Opportunity>();
    
    Map<String, Account> nmap = new Map<String, Account>();
    for(Account a : acclist)
    {
        nmap.put(a.Name, a);
    }
    
    for(Account acc : Trigger.new)
    {
        if(nmap.get(acc.Name)!=null)
        {
            opplist.add(new Opportunity(AccountId =acc.Id, Name ='Duplicate Opportunity'+acc.Name, StageName = 'prospecting'
            , CloseDate = System.today()));         
        }
        else if(nmap.get(acc.Name)==null)
        {
             opplist.add(new Opportunity(AccountId =acc.Id, Name ='First Opportunity'+acc.Name, StageName = 'prospecting'
            , CloseDate = System.today()));
        }
    }
    if(opplist.size()>0)
    {
        insert opplist;
    }
}
when i inserted duplicate name in account then print duplicate opportunity name on the bases of account if not a duplicate account name then print first opportunity
But First Opportunity is not printed
Dear Salesforce Professional

I am a beginner in Programming.
Please help me resolve this problem.

I have a requirement to create a child record (on Billing Line object) if parent records (on Billing object) exist I need to attach the child record (Billing Line) to the parent (Billing) but if Parent record doesn't exist I need to create parent and child records.

This trigger is supposed to fire when I check a checkbox on a TEST object.

For some reason, my code can't find parent records and can't create one.

I get this error message
"TriggerTestBillingLineCreate: execution of AfterUpdate caused by: System.DmlException: Insert failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, Required fields are missing: [AcctSeed__Customer__c]: [AcctSeed__Customer__c] Class.testBillingLineCreate.createBillingLine: line 48, column 1 Trigger.TriggerTestBillingLineCreate: line 5, column 1"

Basically, it is saying the required field is missing when I am trying to create a parent record. I don't understand why it is missing if I populate it there and in some cases why it needs to create a parent record if a parent exists in a database. It just needs to find it and link a child record to the parent.

I attached my code below. I appreciate any advice. Thank you for your help!


public class testBillingLineCreate {
    public static void createBillingLine (list<TEST__c> TestList, map<id, TEST__c> oldMap)
    {
     list<AcctSeed__Billing_Line__c> billingLineList=new List<AcctSeed__Billing_Line__c>();      
     list<AcctSeed__Billing__c> billingList= new list<AcctSeed__Billing__c>();
        
         for(TEST__c objtest:TestList)
        {
        if(objtest.Billed__c==true && oldMap.get(objtest.Id).Billed__c==false)

        {
          for(AcctSeed__Billing__c billings:[select id, name, AcctSeed__Customer__c, advAcctSeed__Matter__c from AcctSeed__Billing__c where AcctSeed__Status__c='Approved']){

          if(billings.AcctSeed__Customer__c==objtest.Account__c && billings.advAcctSeed__Matter__c==objtest.Matter__c){

            AcctSeed__Billing_Line__c bill=new AcctSeed__Billing_Line__c();
           bill.AcctSeed__Billing__c=billings.Id;
            bill.AcctSeed__Project__c=objtest.Project__c;
            bill.AcctSeed__Hours_Units__c=objtest.time__c;                  
            bill.AcctSeed__Rate__c=objtest.Rate__c; 

            billingLineList.add(bill);
        }




         else {
              AcctSeed__Billing__c billings2=new AcctSeed__Billing__c();
              billings2.AcctSeed__Customer__c= objtest.Account__c;
               billings2.advAcctSeed__Matter__c=objtest.matter__c;
            billings2.AcctSeed__Status__c='Approved';
             billings2.AcctSeed__Date__c=date.today();
             billingList.add(billings2);

               AcctSeed__Billing_Line__c bill1=new AcctSeed__Billing_Line__c();
           bill1.AcctSeed__Billing__c=billings2.Id;
            bill1.AcctSeed__Project__c=objtest.Project__c;
            bill1.AcctSeed__Hours_Units__c=objtest.time__c;                  
            bill1.AcctSeed__Rate__c=objtest.Rate__c; 

            billingLineList.add(bill1);

            }
    }

        }
        insert billingList;
        insert billingLineList;
        }}}
We have several CPQ product rules that are validation rules. When in the Quote Line Editor we have a rep that adds a product. When clicking Save the product rule will fire the red validation error message at the top of the page.

Is there a way that you can automate the creation of a case when that error message appears?
Hi, i am new to salesforce i am creating pdf attatchment with sending mail...... i get this answer,please help me for this,my code is

public class MyAttatchment {
Account acc;
    public String myName{set;get;}
    public MyAttatchment(){
        acc =[select Id,Name from Account where Name=:myName limit 1];
    }
    public void pageReferenceShow(){
        Messaging.SingleEmailMessage myMail = new Messaging.SingleEmailMessage();
        Messaging.EmailFileAttatchment fMail = new Messaging.EmailFileAttatchment();
         pageReference pdf = page.Attatchment.pdf;
        pdf.getParameters().put(Id,(String.accId));
        pdf.setRedirect(true);
        Blob b =pdf.getContent();
        fMail.setFileName('Attatchment.pdf');
        fMail.setBody(b);
        myMail.setSubject('MonthBill');
        String toAdd = new String[]{'n.satti534@gmail.com'};
            myMail.setToAddress(toAdd);
        myMail.setBody('Plz Find Attatchment');
        myMail.setFileAttachments( new Messaging.EmailFileAttatchment[]{fMail});
        Messaging.sendEmail(new Messaging.Email[]{myMail});
        return null;
        
    }
}

i get error like this..invalid type:messaging.emailfileattatchment
I am trying to add a new contact record with below condition where Account has greter than  99 employees  an limit is 1.
Though new  contact is not getting created in accounts where  employess are more than 99.
let me know what is wrong in below code.
(New to apex)
Contact c = new Contact(Account = [SELECT Name FROM Account 
    WHERE NumberOfEmployees > 99 Limit 1]);
c.FirstName = 'Test';
c.LastName = 'AM';
System.debug('Contact name  is '+c);    
global with sharing class GetObjectsAWS{
 
    @AuraEnabled

    public static List<ContentssArray> GetObject(){
   String jsonResponse = XMLParser.xmlToJson(res.getBody());
       // String json ='Contents:{"Key": "my-third-image.jpg", "LastModified": "2009-10-12T17:50:30.000Z", "ETag": "\"1b2cf535f27731c974343645a3985328\"", "Size": "64994", "StorageClass": "STANDARD_IA", "Owner": {"ID": "75aa57f09aa0c8caeab4f8c24e99d10f8e7faeebf76c078efc7c6caea54ba06a", "DisplayName": "mtd@amazon.com"}}';
        system.debug('+++++Body is'+jsonResponse);
      
        Map<String,Object> jsonParsed =(Map<String,Object> ) JSON.deserializeUntyped(jsonResponse);
        Map<String,Object> content_collection = ( Map<String,Object>) jsonParsed.get('ListBucketResult');
        List<Object> ContentssArray =( List<Object> ) content_collection.get('Contents');
        
        for(Object inidividualEntries : ContentssArray){
            Map<String,Object> ind = (Map<String,Object> )inidividualEntries;
            System.debug('Key = '+ ind.get('Key'));
            System.debug('Size = '+ ind.get('Size'));
             
            System.debug('---------------------------------------------');
        }

   return ContentssArray;

    }
Trying to dispay the JSON response in the lightnign component. Hence returning LIST in the apex controller. But getting below errors:
Invalid type: ContentssArray
Illegal conversion from List<Object> to List<ContentssArray>
Thanks In Advance
  • April 19, 2020
  • Like
  • 0
Hi,

I'm using two objects: Cases and Agreements, each with two record types (NDA and MSA). I want to create a Case with a record type NDA that will create an NDA record type record in the Agreements object.

I can do this with Process Builder, except I can't seem to get the Case NDA request to create a NDA record type in Agreements - for some reason it defaults to MSA. 

Just wondering if it's possible to select various record types, (Case NDA  create Agreement NDA record) or does Process Builder only know how to create a new record in another object w/out being able to distinguish record types? If it's not possible, does anyone have any workarounds?

Thank you!
Hi - I am an admin that is trying to code something into our instance to calculate business hours between 2 date/time fields based on owner location to account for time zone changes. I was able to find and tweak the code from this website (https://www.tech-vision.us/salesforce-the-number-of-business-hours-between-two-date-time-fields/). I then wrote a Test Class but am only able to get to 55% code coverage and cannot figure out why. 

Trigger:
trigger Demo_Response_Biz_Hours_Time_Zones on Lead (before insert, before update) {
   
    //Selecting all active BusinessHours records
    List<BusinessHours> BusinessHours_List = [SELECT Id, Name FROM BusinessHours WHERE IsActive = true];
   
    //Adding map where BusinessHours Name will be the key
    Map<String, BusinessHours> LocationName_BusinessHours_Map = new Map<String, BusinessHours> ();
   
    //Filling the map | Location Name, BusinessHours Object
    for (BusinessHours b : BusinessHours_List) {
        LocationName_BusinessHours_Map.put(b.Name, b);
    }
    for (Lead leadObj : Trigger.new) {
        
        //This part of a trigger only works when we add new records
        if (Trigger.isInsert) {
            
            //We check if both Start Time & Completed Time fields are not empty
            if (leadObj.Demo_Form_Submission_Date__c != NULL && leadObj.First_Activity_Most_Recent_Demo_Request__c != NULL) {
                
                //Then we do another check if current record is tied to a location that has business hours record
                if (LocationName_BusinessHours_Map.containsKey(leadObj.Owner_Location__c)) {
                    decimal result = BusinessHours.diff(LocationName_BusinessHours_Map.get(leadObj.Owner_Location__c).Id, leadObj.Demo_Form_Submission_Date__c, leadObj.First_Activity_Most_Recent_Demo_Request__c);
                    Decimal resultingHours = result / (60 * 60 * 1000);
                    leadObj.APEXTEST_Demo_Response_Time_Zones__c = resultingHours.setScale(1);
                } else{
                    
                    //Just as a safety net, let's use default business hours in case there is no match between Location name and BH name
                    if(LocationName_BusinessHours_Map.get('Default').Id != NULL){
                        decimal result = BusinessHours.diff(LocationName_BusinessHours_Map.get('Default').Id, leadObj.Demo_Form_Submission_Date__c, leadObj.First_Activity_Most_Recent_Demo_Request__c);
                        Decimal resultingHours = result / (60 * 60 * 1000);
                        leadObj.APEXTEST_Demo_Response_Time_Zones__c = resultingHours.setScale(1);
                    }
                }
            }
        } else if (Trigger.isUpdate) {
            
            //This part of a trigger only works when we perform update
           
            //Checking if Start Time or Completed Time has been changed & if they are not empty
            if ((leadObj.Demo_Form_Submission_Date__c != NULL && leadObj.First_Activity_Most_Recent_Demo_Request__c != NULL) && ((leadObj.Demo_Form_Submission_Date__c != Trigger.oldMap.get(leadObj.id).Demo_Form_Submission_Date__c) || (leadObj.First_Activity_Most_Recent_Demo_Request__c != Trigger.oldMap.get(leadObj.id).First_Activity_Most_Recent_Demo_Request__c))) {
                if (LocationName_BusinessHours_Map.containsKey(leadObj.Owner_Location__c)) {
                    decimal result = BusinessHours.diff(LocationName_BusinessHours_Map.get(leadObj.Owner_Location__c).Id, leadObj.Demo_Form_Submission_Date__c, leadObj.First_Activity_Most_Recent_Demo_Request__c);
                    Decimal resultingHours = result / (60 * 60 * 1000);
                    leadObj.APEXTEST_Demo_Response_Time_Zones__c = resultingHours.setScale(1);
                } else{
                    if(LocationName_BusinessHours_Map.get('Default').Id != NULL){
                        decimal result = BusinessHours.diff(LocationName_BusinessHours_Map.get('Default').Id, leadObj.Demo_Form_Submission_Date__c, leadObj.First_Activity_Most_Recent_Demo_Request__c);
                        Decimal resultingHours = result / (60 * 60 * 1000);
                        leadObj.APEXTEST_Demo_Response_Time_Zones__c = resultingHours.setScale(1);
                    }
                }
            } else if (leadObj.Demo_Form_Submission_Date__c == NULL || leadObj.First_Activity_Most_Recent_Demo_Request__c == NULL) {
                
                //Another safety net that will reset Hours spent in case Start Time OR Completed time becomes empty after update.
               
                //That way you won't have old & inaccurate data from past calculations.
                leadObj.APEXTEST_Demo_Response_Time_Zones__c = NULL;
            }
        }
    }
}

Test Class:
@isTest

public class TestDemoResponseTime {

    Static testmethod void LeadTest() {
    
        //create a lead
        Lead leadObj = new Lead();
        leadObj.LastName = 'Test';
        leadObj.Company = 'Test ABC';
        leadObj.LeadSource = 'Sales Prospecting';
        leadObj.Lead_Source_Detail__c = 'Apex Test Class';
        leadObj.OwnerID = '0054G000008UaurQAC';
        leadObj.Demo_Form_Submission_Date__c = datetime.newInstance(2020, 04, 15, 14, 00, 00);
                
        insert leadObj;
        
        //business hours
        BusinessHours b = [SELECT Id FROM BusinessHours WHERE Name = 'Denver'];
        
        //update the lead
        leadObj = [SELECT Id, LastName, Company, LeadSource, Lead_Source_Detail__c, OwnerID, Owner_Location__c, Demo_Form_Submission_Date__c, First_Activity_Most_Recent_Demo_Request__c FROM Lead WHERE Id != NULL];
        leadObj.First_Activity_Most_Recent_Demo_Request__c = datetime.newInstance(2020, 04, 16, 19, 00, 00);
        
        update leadObj;
   }
}

I've checked the developer console and the sections that aren't covered are:
if (LocationName_BusinessHours_Map.containsKey(leadObj.Owner_Location__c)) {
                    decimal result = BusinessHours.diff(LocationName_BusinessHours_Map.get(leadObj.Owner_Location__c).Id, leadObj.Demo_Form_Submission_Date__c, leadObj.First_Activity_Most_Recent_Demo_Request__c);
                    Decimal resultingHours = result / (60 * 60 * 1000);
                    leadObj.APEXTEST_Demo_Response_Time_Zones__c = resultingHours.setScale(1);

Does anyone have any ideas on what I'm missing? Thank you!
Hi,

I am running in to an issue that I was hoping someone might have some insight in to. I have a method in a class triggered by contact insert or update. This method will check to see if a contact has a box checked and if it does, it will create a correspondinng user record with the ContactId set to the Id of the contact that was being created/edited. 

The issue that I am having is with the test code coverage. I am getting the error "UNKNOWN_EXCEPTION, portal account owner must have a role". Now I have seen the workaround for this by creating a user with a role and then putting the community user creation code inside System.runAs context with the user you created. This works for community users created in the test class itself, however, if the test class is not actually creating the community user directly, but rather by creating a contact which triggers the class mentioned above to create a community user, it fails with the same role error mentioned above. 

In all my searching, all I have found is a solution to the first issue where the community user is being created in the test class itself. I have not found any info for resolving it if the test class it then calling out to another class that creates the user. Any info on how I might be able to resolve would be greatly appreciated.

Thanks,

Chris
 
  • April 13, 2020
  • Like
  • 0
I have wirtten the below test class. The code coverage is only 92% I want to make it to 100%

Apex class

public class ConvertTheLead
{
    public Lead__c leadObj{get;set;}
    List<Account> acctList = new List<account>();
    public static final string stage='prospecting';
    public static final string status='Qualified';
    
    public ConvertTheLead(ApexPages.StandardController stdController)
    {
        leadObj = new Lead__c();
        Lead__c ldId =  (Lead__c)stdController.getRecord();
        leadObj = [select id,Company__c,State_Province__c,Phone__c,Street__c,Name__c,MobilePhone__c,Email__c,LeadSource__c,Industry__c,No_of_Employees__c,Annual_Revenue__c,Status__c,Name1__c     from lead__c where id =:ldId.Id];
    }
    
    public PageReference RedirecttoSite()
    {
        String currentLead = '/' + leadObj.Id;
        PageReference pageRef = new PageReference(currentLead);
        return pageRef;
    }
    
    public PageReference convertbutton()
    {
        
        if(leadObj.Status__c != status){
            ApexPages.Message errormsg1 = new ApexPages.Message(ApexPages.severity.ERROR,'Please change the lead status to qualified & then try to convert the lead');
            ApexPages.addMessage(errormsg1);
            return null;
        }
        try{
            Account acc = new Account();
            acc.Name = leadObj.Company__c;
            acc.BillingState= leadObj.State_Province__c;
            acc.Phone = leadObj.Phone__c;
            acc.Industry = leadObj.Industry__c;
            acc.AnnualRevenue = leadobj.Annual_Revenue__c;
            acc.NumberOfEmployees = integer.valueof(leadobj.No_of_Employees__c);
            insert acc;
            
            Opportunities__c opp = new Opportunities__c();
            opp.Name = leadObj.Name1__c    ;
            opp.Account_Name__c = acc.Id;
            opp.Close_Date__c= system.today()+30;
            opp.Stage__c = stage;
            opp.Lead_Source__c = leadobj.LeadSource__c;
            insert opp;
            
            Contact cc = new Contact();
            cc.LastName = leadObj.Name1__c;
            cc.Email = leadObj.Email__c;
            cc.Phone = leadObj.Phone__c;
            cc.AccountId = acc.Id;
            cc.Opportunities__c = opp.Id;
            cc.Phone = leadObj.Phone__c;
            cc.MobilePhone = leadobj.MobilePhone__c;
            cc.Address__c = leadobj.Street__c;
            insert cc;
            
            if(acc.Id!=null){
                list<Lead__c> Listleads = [select id from Lead__c where id=:leadObj.Id];
                if(!Listleads.isEmpty()){
                    Delete Listleads;
                }
                String currentAccount = '/' + acc.Id;
                PageReference pageRef = new PageReference(currentAccount);
                pageRef.setRedirect(true);
                return pageRef;
            }
        }catch(Exception e){
            ApexPages.Message errormsg = new ApexPages.Message(ApexPages.severity.confirm,e.getMessage());
            ApexPages.addMessage(errormsg);
        }
        
        return null;
    }
}

Vf page

<apex:page standardController="Lead__c" cache="true" extensions="ConvertTheLead" action="{!convertbutton}" lightningStylesheets="true" docType="html-5.0">
    <head>
        <apex:slds /> 
    </head> 
    <apex:form > 
        <apex:pageMessages ></apex:pageMessages>
        <div class="slds-page-header">
            <div class="slds-page-header__row">
                <div class="slds-page-header__col-title">
                    <div class="slds-media">
                        <div class="slds-media__figure">
                            <span class="slds-icon_container slds-icon-standard-lead" title="Lead Convert"> 
                                <apex:commandLink action="{!RedirecttoSite}">
                                    <img src="/apexpages/slds/latest/assets/icons/action/lead_convert_60.png"/> 
                                </apex:commandLink>
                                <span class="slds-assistive-text">Lead</span>
                            </span>
                        </div>
                        <div class="slds-media__body">
                            <div class="slds-page-header__name">
                                <div class="slds-page-header__name-title">
                                    <h1>
                                        <span class="slds-page-header__title slds-truncate" title="{!leadObj.Name1__c}">{!leadObj.Name1__c}</span>
                                    </h1>
                                </div>
                            </div>
                            <p class="slds-page-header__name-meta">Lead Convert&nbsp;&nbsp;<apex:commandLink value="Redirect to Lead" style="font-weight:bold;font-size:15px;" action="{!RedirecttoSite}"/></p> 
                        </div> 
                    </div>
                </div>
            </div>
        </div> 
    </apex:form> 
</apex:page>

test class

@isTest
public class ConvertTestClass {
     
    public static testMethod void test1() {
        
        Lead__c ld = new Lead__c ();
        ld.First_Name__c = 'Test';
        ld.Name    ='first';
        ld.Company__c ='Test company';
        ld.Status__c = 'Qualified';
        insert ld;
        
        Test.StartTest(); 

        PageReference pageRef = Page.RedirectingToLead; 
        Test.setCurrentPage(pageRef);


        ApexPages.StandardController sc = new ApexPages.StandardController(ld);
        ConvertTheLead testAccPlan = new ConvertTheLead(sc);
        testAccPlan.RedirecttoSite();
        testAccPlan.convertbutton();
        Test.StopTest();
        
    }
    
    public static testMethod void test2() {
        
        Lead__c ld = new Lead__c ();
        ld.First_Name__c = 'Test';
        ld.Name    ='first';
        ld.Company__c ='Test company';
        // Set Status as any valid value other then "Qualified"
        ld.Status__c = 'New'; 
        insert ld;
        
        Test.StartTest(); 

        PageReference pageRef = Page.RedirectingToLead; 
        Test.setCurrentPage(pageRef);


        ApexPages.StandardController sc = new ApexPages.StandardController(ld);
        ConvertTheLead testAccPlan = new ConvertTheLead(sc);
        testAccPlan.RedirecttoSite();
        testAccPlan.convertbutton();
        Test.StopTest();
        
    }
    
}

User-added image
Hi there,

Please help with this class where I am getting an error upon saving the test class below:
 
@isTest
public class APTS_ResendCreditMemoEmailTest{
    static testMethod  void creditMemoDocumentGenerationTest(){

        Profile profileSO = [SELECT Id FROM Profile WHERE Name = 'Standard User' LIMIT 1];
        
        User userSO = APTS_TestDataFactory.getUser('LastName123','medidate', profileSO.ID);
        insert userSO;
        System.runAs(userSO){
            EmailTemplate emailTemplateSO1 = APTS_TestDataFactory.getEmailTemplate('APTS Non Japan Invoice','APTS_Non_Japan_Invoice', userSO.ID);
            List<EmailTemplate> listEmailTemplate = new List<EmailTemplate>();
            listEmailTemplate.add(emailTemplateSO1);
            insert emailTemplateSO1;
        }

        insert APTS_TestDataFactory.getTaxConnectorConfigSetting();

        //Create & Insert Core Currency
        appirio_core__Currency__c coreCurrencyUSD = APTS_TestDataFactory.getCoreCurrency('U.S. Dollar','USD', TRUE);
        LIst<appirio_core__Currency__c> coreCurrencylist = new List<appirio_core__Currency__c>();
        coreCurrencylist.add(coreCurrencyUSD);
        insert coreCurrencylist;
        
        APTS_Legal_Entity__c legalEntitySO= APTS_TestDataFactory.getLegalEntity('Japan', coreCurrencyUSD.ID, FALSE);
        legalEntitySO.APTS_LE_Company_Code__c = 'ABC';
        legalEntitySO.APTS_LE_Country__c  = 'DEF';
        insert legalEntitySO;

        Apttus_Config2__PaymentTerm__c paymentTermSO = APTS_TestDataFactory.createPaymentTerm('Net 120', 'Net 120 Days', 120 , TRUE);
        insert paymentTermSO;

        APTS_Invoice_Number_Settings__c invoiceNumberSettingSO = APTS_TestDataFactory.getInvoiceNumberSetting(legalEntitySO.ID);
        insert invoiceNumberSettingSO;

        //Create & Insert Account
        Account accSO = APTS_TestDataFactory.getAccount('Test Account');
        accSO.APTS_Global_MSA__c = TRUE;
        insert accSO;
        
        Contact contactSO1 = APTS_TestDataFactory.getContact(accSO.ID, 'Japan', 'Last1', 'Japan');
        Contact contactSO2 = APTS_TestDataFactory.getContact(accSO.ID, 'Esker', 'Last2', 'Japan');
        List<Contact> listContact = new List<Contact>();
        listContact.add(contactSO1);
        listContact.add(contactSO2);
        insert listContact;

        Apttus_Config2__AccountLocation__c accountLocationSO1 = APTS_TestDataFactory.getAccountLocation('USA Account Location', accSO.ID, 'USA');
        accountLocationSO1.Apttus_Config2__DefaultInvoiceTemplate__c = 'APTS Non Japan Invoice';
        Apttus_Config2__AccountLocation__c accountLocationSO2 = APTS_TestDataFactory.getAccountLocation('USA Account Location', accSO.ID, 'USA');
        List<Apttus_Config2__AccountLocation__c> accountLocationList = new List<Apttus_Config2__AccountLocation__c>();
        accountLocationList.add(accountLocationSO1);
        accountLocationList.add(accountLocationSO2);
        insert accountLocationList;

        Opportunity oppSO1 = APTS_TestDataFactory.getOppty(accSO.ID, 'USA Opp');
        Opportunity oppSO2 = APTS_TestDataFactory.getOppty(accSO.ID, 'USA Opp');
        List<Opportunity> oppList = new List<Opportunity>();
        oppList.add(oppSO1);
        oppList.add(oppSO2);
        insert oppList;

        Apttus_Config2__Order__c orderSo = APTS_TestDataFactory.getOrder(accSO.Id, oppSO1.ID, accountLocationSO1.ID);
        orderSo.Apttus_Config2__PaymentTermId__c = paymentTermSO.ID;
        orderSo.APTS_Invoice_Delivery_Method_Email__c = true;
        orderSo.APTS_Invoice_Delivery_Method_Print__c = true;
        insert orderSo;

        Apttus_Billing__Invoice__c invoiceSO1 = APTS_TestDataFactory.getInvoice(accSO.ID, paymentTermSO.ID);
        invoiceSO1.APTS_Legal_Entity__c = legalEntitySO.ID;
        invoiceSO1.Apttus_Billing__LocationId__c = accountLocationSO1.ID;
        invoiceSO1.APTS_Order__c = orderSo.ID;
        
        Apttus_Billing__Invoice__c invoiceSO2 = APTS_TestDataFactory.getInvoice(accSO.ID, paymentTermSO.ID);
        invoiceSO2.APTS_Legal_Entity__c = legalEntitySO.ID;
        invoiceSO2.Apttus_Billing__LocationId__c = accountLocationSO2.ID;
        invoiceSO2.APTS_Order__c = orderSo.ID;

        List<Apttus_Billing__Invoice__c> invoiceList = new List<Apttus_Billing__Invoice__c>();
        invoiceList.add(invoiceSO1);
        invoiceList.add(invoiceSO2);
        insert invoiceList;

        Apttus_Billing__CreditMemo__c creditMemoSO = APTS_TestDataFactory.getCreditMemmo(accSO.ID, invoiceSO1.ID);
        creditMemoSO.APTS_Legal_Entity__c = legalEntitySO.ID;
        creditMemoSO.Apttus_Billing__LocationId__c = accountLocationSO1.ID;
        creditMemoSO.APTS_Shipping_Location__c = accountLocationSO1.ID;
        //creditMemoSO.Apttus_Billing__Status__c = 'Approved';
        creditMemoSO.Apttus_Billing__DeliveryStatus__c = 'Pending';
        creditMemoSO.APTS_Order__c = orderSo.ID;

        List<Apttus_Billing__CreditMemo__c>creditMemolist = new List<Apttus_Billing__CreditMemo__c>();
        creditMemolist.add(creditMemoSO);
        insert creditMemolist;
        
        Attachment attachmentSO = APTS_TestDataFactory.getAttachment(creditMemoSO.ID,'CreditMemo Attachment');
        List<Attachment> listAttachment = new List<Attachment>();
        listAttachment.add(attachmentSO);
        insert listAttachment;


        Apttus_Billing__RelatedARTransaction2__c relatedARTransactionSO = APTS_TestDataFactory.getRelatedARTransaction(invoiceSO1.ID);
        relatedARTransactionSO.Apttus_Billing__TxnType__c = 'Refund';
        relatedARTransactionSO.Apttus_Billing__DestinationCreditMemoId__c = creditMemoSO.ID;
        insert relatedARTransactionSO;
        
        Test.startTest();
        Test.setCurrentPageReference(new PageReference('Page.myPage'));
        System.currentPageReference().getParameters().put('creditMemoID', creditMemoSO.ID);
        System.currentPageReference().getParameters().put('status', 'Approved');

        APTS_ResendCreditMemoEmail resendCreditMemoEmail = new APTS_ResendCreditMemoEmail();
        resendCreditMemoEmail.resendEmail();
        
        Test.stopTest();

    }
}

The error is:

Error: Compile Error: Method does not exist or incorrect signature: void getOrder(Id, Id, Id) from the type APTS_TestDataFactory at line 62

Any guidance would be most appreciated. Thank you!
 
Hi All,

When Record is submitted as Draft. Profile should have edit access for that Draft.
Two profile: P1 and P2. Two page layout created for both profile one is read only and other Read/Write access. When P1 submit a record as status is saved as Draft . P1 should have access to Edit that record.

Page layout in detail page if I had Edit button. It assign to both the page layout. Is there any other way around to achieve this.

Thanks for the help in advance
Iam getting this error :-


System.UnexpectedException: No more than one executeBatch can be called from within a test method. Please make sure the iterable returned from your start method matches the batch size, resulting in one executeBatch invocation.
Stack Trace: External entry point

@isTest(seealldata = true)
public class QuoteTrigger_PayTerms_GenerateDoc_Test{
             
         Static testMethod Void testMethod2(){
           
             Account acc = new Account();
             acc.Name = 'Test Account';
             acc.Website ='www.test.com';
             acc.Type='Banking';
             insert acc;
             
             Contact con = new contact();
             con.lastname='test contact';
             con.LeadSource = 'Inbound';
             con.Contact_Status__c='Open';
             con.accountid=acc.id;
             insert con;
             
             opportunity opp = new opportunity();
             opp.name ='Test Opp';
             opp.stagename='Closed Won';
             opp.Type= 'New Business';
             opp.CloseDate=system.today().addmonths(2);
             opp.Upsell_Potential__c ='No';
             opp.RenewalDate__c = system.today();
             opp.accountid=acc.id;
             opp.Contact_Name__c=con.id;
             insert opp;  
             
             OpportunityContactRole ocr = new OpportunityContactRole();
                ocr.ContactId = con.Id;
                ocr.OpportunityId = opp.Id;
                ocr.IsPrimary = TRUE;
                ocr.Role = 'Decision Maker';
                insert ocr;
             
             SBQQ__Quote__c oldquote2 = new SBQQ__Quote__c();
             oldquote2.SBQQ__Primary__c = true;
             oldquote2.SBQQ__Opportunity2__c = opp.id;
             oldquote2.SBQQ__StartDate__c = system.today();
             oldquote2.SBQQ__EndDate__c= system.today().addmonths(3);
             oldquote2.SBQQ__SubscriptionTerm__c=1;
             oldquote2.Status_Of_Approval__c='Pending';
             oldquote2.Document_Template__c= 'Auto Renew 3';
             oldquote2.SBQQ__PaymentTerms__c= 'monthly';
             oldquote2.SBQQ__BillingCountry__c ='United States';
             oldquote2.Long_Form__c=false;
             oldquote2.Logo__c = false;
             oldquote2.Attach_Terms_and_Conditions__c= 'No';
             insert oldquote2;
   //--------------------------------------------------------------------------Annual Starts here----------------
             oldquote2.Document_Template__c= 'Auto Renew';
             oldquote2.SBQQ__PaymentTerms__c= 'Annual';
             oldquote2.Logo__c = false;
             oldquote2.Attach_Terms_and_Conditions__c= 'Enterprise SaaS';
             update oldquote2;
             
             oldquote2.Document_Template__c= 'Auto Renew';
             oldquote2.SBQQ__PaymentTerms__c= 'Annual';
             oldquote2.Logo__c = true;
             oldquote2.Attach_Terms_and_Conditions__c= 'Enterprise SaaS';      
             update oldquote2;   
             
             oldquote2.Document_Template__c= 'Auto Renew';
             oldquote2.SBQQ__PaymentTerms__c= 'Monthly';
             oldquote2.Logo__c = false;
             oldquote2.Attach_Terms_and_Conditions__c= 'Enterprise SaaS';
             update oldquote2;
             
             oldquote2.Document_Template__c= 'Auto Renew';
             oldquote2.SBQQ__PaymentTerms__c= 'Monthly';
             oldquote2.Logo__c = true;
             oldquote2.Attach_Terms_and_Conditions__c= 'Enterprise SaaS';      
             update oldquote2;   
         

         }
             
               
             Static testMethod Void testMethod3(){

//----------------------------------------------Standard saas------------------------------------------------
           

             Account acc = new Account();
             acc.Name = 'Test Account';
             acc.Website ='www.test.com';
             acc.Type='Banking';
             insert acc;
             
             Contact con = new contact();
             con.lastname='test contact';
             con.LeadSource = 'Inbound';
             con.Contact_Status__c='Open';
             con.accountid=acc.id;
             insert con;
             
             opportunity opp = new opportunity();
             opp.name ='Test Opp';
             opp.stagename='Closed Won';
             opp.Type= 'New Business';
             opp.CloseDate=system.today().addmonths(2);
             opp.Upsell_Potential__c ='No';
             opp.RenewalDate__c = system.today();
             opp.accountid=acc.id;
             opp.Contact_Name__c=con.id;

             insert opp;  
             
              OpportunityContactRole ocr = new OpportunityContactRole();
              ocr.ContactId = con.Id;
              ocr.OpportunityId = opp.Id;
              ocr.IsPrimary = TRUE;
              ocr.Role = 'Decision Maker';
              insert ocr;
             
             SBQQ__Quote__c oldquote2 = new SBQQ__Quote__c();
             oldquote2.SBQQ__Primary__c = true;
             oldquote2.SBQQ__Opportunity2__c = opp.id;
             oldquote2.SBQQ__StartDate__c = system.today();
             oldquote2.SBQQ__EndDate__c= system.today().addmonths(3);
             oldquote2.SBQQ__SubscriptionTerm__c=1;
             oldquote2.Status_Of_Approval__c='Pending';
             oldquote2.Document_Template__c= 'Auto Renew';
             oldquote2.SBQQ__PaymentTerms__c= 'monthly';
             oldquote2.SBQQ__BillingCountry__c ='United States';
             oldquote2.Long_Form__c=false;
             oldquote2.Logo__c = false;
             oldquote2.Attach_Terms_and_Conditions__c= 'No';
             insert oldquote2;

             oldquote2.Document_Template__c= 'Auto Renew';
             oldquote2.SBQQ__PaymentTerms__c= 'Annual';
             oldquote2.Logo__c = false;
             oldquote2.Attach_Terms_and_Conditions__c= 'Standard SaaS';
             update oldquote2;
             
             oldquote2.Document_Template__c= 'Auto Renew';
             oldquote2.SBQQ__PaymentTerms__c= 'Annual';
             oldquote2.Logo__c = true;
             oldquote2.Attach_Terms_and_Conditions__c= 'Standard SaaS';      
             update oldquote2;   
             
             oldquote2.Document_Template__c= 'Auto Renew';
             oldquote2.SBQQ__PaymentTerms__c= 'Monthly';
             oldquote2.Logo__c = false;
             oldquote2.Attach_Terms_and_Conditions__c= 'Standard SaaS';
             update oldquote2;
             
             oldquote2.Document_Template__c= 'Auto Renew';
             oldquote2.SBQQ__PaymentTerms__c= 'Monthly';
             oldquote2.Logo__c = true;
             oldquote2.Attach_Terms_and_Conditions__c= 'Standard SaaS';      
             update oldquote2;   
         

         }
            
    
        
    }
  • March 31, 2020
  • Like
  • 0
I am trying to pull the data from `Opportunity` object in SalesForce using bulk API. My query looks like this:

```
opportunity = sf.bulk.Opportunity.query('SELECT Id, Name, LeadSource, Probability from Opportunity')
print(opportunity)
```
It does return the data with no issues, however, if I want to select more columns it gives me:

```
IndexError: list index out of range
```
Help! 
Our org is fairly new, 15 months and I have an Apex Trigger that auto creates a Membership record based on one day after the Expiration Date. The new Membership record is created with one day added, My question is related to the "deactivation" of the prevous record when the new reord is created. I am completely new to Apex as this is an urgent request to get this automated so we can remove the manual updates to the "older" Memberhsip records, either by individual or data load. here is my trigger. How to modify to deactivate the previous membership record?
**/
trigger MembershipTrigger on Membership__c (before insert, after insert, after update) {
    
    if(Trigger.isInsert && Trigger.isBefore) {
        MembershipHelper.SetPreviousMembership( (List<Membership__c>)Trigger.new );
    }

    if(Trigger.isAfter) {
        MembershipHelper.UpdateAccountJoinDate( (List<Membership__c>)Trigger.new );
    }
}
 

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!