• Marco Pinder
  • NEWBIE
  • 105 Points
  • Member since 2011

  • Chatter
    Feed
  • 4
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 14
    Questions
  • 29
    Replies

Hi all,

 

Does anyone know if it is possible to generate an iCalendar/.ical/.ics file based on the content of a Salesforce record?

 

Ideally we would like to be able to have a custom button on a record that on pressing it generates a Meeting Invite to be saved/sent from Outlook. The recipients/attendees, subject, dates, etc. would be defined by fields on the Salesforce record.

 

I have searched the AppExchange but cannot find anything that meets this requirement. Any help or advice is much appreciated.

 

Thanks,

 

Marco

Hi,

 

I originally created a custom button on the Contact page layout that allowed me to start a flow. The code that worked fine is as follows:

 

/flow/Enable_SLink_Access
&varContactId={!Contact.Id}
&retURL=/{!Contact.Id}

 This worked great. However I now need to add some JavaScript to this button to analyse the current users profile to allow or deny running the flow.

 

The new code now looks like this:

 

//Required by Salesforce.com to run OnClick JavaScript
{!RequireScript("/soap/ajax/10.0/connection.js")}

if ( '{!User.Profile}' != 'System Administrator' )
{
alert('You are not authorised to edit SLink Settings for this Contact');
}
else
{
window.open('/flow/Enable_SLink_Access&varContactId={!Contact.Id}&retURL=/{!Contact.Id}');
}

 However now it takes me to an invalid URL where the message on screen says 'URL No Longer Exists'.

 

The URL has become: https://cs2.salesforce.com/flow/Enable_SLink_Access&varContactId=003R000000Z7dEv&retURL=/003R000000Z7dEv

 

Can anyone help me with the code I should dress up the flow bit of the code with please?

 

Thanks very much,

 

Marco

Hi all,

 

I have written the following trigger that automatically starts an approval process for a campaign record provided that the 'Estimated_Cost_per_head__c' value is greater than or equal to 25.

 

trigger AuthSpendProcessApproval on Campaign (after insert, after update){ for (Campaign c : trigger.new){ if (c.Estimated_Cost_per_head__c >= 25){ if (c.Approved__c == FALSE){ // Create an approval request for the Campaign Approval.ProcessSubmitRequest app = new Approval.ProcessSubmitRequest(); app.setObjectId(c.Id); //Submit the approval request for the Campaign Approval.ProcessResult result = Approval.Process(app); } } } }

 My test class passes fine and under most circumstances this trigger works the way I intended, however I have found a way to break it and would welcome some feedback please.

 

When I create a new Campaign record there are certain fields that have been set as mandatory that I deliberately don't complete. I get the error message reminding me to complete them (which I do), however instead of saving the record correctly I am supplied with the following error message:

 

Validation Errors While Saving Record(s)
There were custom validation error(s) encountered while saving the affected record(s). The first validation error encountered was "Apex trigger AuthSpendProcessApproval caused an unexpected exception, contact your administrator: AuthSpendProcessApproval: execution of AfterUpdate caused by: System.DmlException: Process failed. First exception on row 0; first error: ALREADY_IN_PROCESS, Cannot submit object already in process.: []: Trigger.AuthSpendProcessApproval: line 16, column 49".

 

This to me suggests that the record has already been entered into the approval process at the point of trying to save the record the first time (when it is unsuccessful due to mandatory data missing).

 

This error does not appear if I create a Campaign record from scratch with all data supplied first time around.

 

I then spoke to one of our database guys to try and understand database transactions better, but I am still confused as to what circumstance is causing the record to (in my mind) prematurely enter the approval process.

 

Can anyone shed some light on this please?

 

Thanks,

 

Marco

Hi all,

 

I have written a trigger on the Campaign object that works as required. Basically if a field (Estimated Cost) is above £25 then the trigger fires and the Campaign is submitted for approval (process is already set up). The code for teh trigger is as follows:

 

trigger AuthSpendProcessApproval on Campaign (after insert){
    
    for (Campaign c : trigger.new){
    
        if (c.Estimated_Cost_per_head__c >= 25){
                
            // Create an approval request for the Campaign
        
            Approval.ProcessSubmitRequest app = new Approval.ProcessSubmitrequest();
            app.setObjectId(c.Id);
        
            //Submit the approval request for the Campaign
        
            Approval.ProcessResult result = Approval.process(app);
        }
    }
}

 However I am now trying to create a Test Method, but after following some guidance online I am getting stuck. The Test Method I have written so far is:

 

@isTest
private class AuthSpendProcessApprovalTest{
    static testMethod void AuthSpendProcessApprovalTest(){
    
    //Set up Campaign record

    Campaign c = new Campaign(Name = 'Test', Estimated_Cost_per_head__c = 26);
    
    // Cause the trigger to execute
    
    insert c;
    
    //Create an approval request for the Campaign
    
    Approval.ProcessSubmitRequest app = new Approval.ProcessSubmitrequest();
    app.setObjectId(c.Id);
    
    // Submit the approval request for the Campaign
    
    Approval.ProcessResult result = Approval.process(app);
    
    // Verify that the results are as expected
    
    System.assert(result.isSuccess());
    
    System.assertEquals(
        'Pending', result.getInstanceStatus(),
        'Instance Status'+result.getInstanceStatus());
    }
}

 The error I get is:

 

System.DmlException: Process failed. First exception on row 0; first error: ALREADY_IN_PROCESS, Cannot submit object already in process.: []

 

From this message I understand that my Test Method is trying to submit the Campaign record to the Approval Process when it has already been submitted.

 

How can I test that when I perform the 'insert c' in the test, that the record has actually been submitted for approval?

 

Thanks,

 

Marco

Hi all,

 

I have written a very basic trigger that assigns a Type value to a Task that is created through the Email Bcc functionality that Salesforce provides.

 

I have tested the trigger and it works when sending a single Email into Salesforce. The code for this trigger is:

 

trigger EmailTask on Task (before insert, before update) {
    
        for (Task t : trigger.new){
            if (t.Subject.contains('Email:')){
                if (t.Type == 'Other - see subject'){
                    t.Type = 'Email';
                }
            }
        }
}

 However, from working on a previous trigger, I know that in order to meet Salesforce limits I must handle for updating large data sets.

 

So I have tried to modify this trigger in order to comply with these limits and I have come up with the following:

 

trigger EmailTask2 on Task (before insert, before update){

    Set<Id> taskId = new Set<Id>();
    List<Task> updated = new List<Task>();
    for (Task t : trigger.new){
        taskId.add(t.Id);
    }
    List<Task> tasks = [SELECT Id, Subject, Type FROM Task WHERE Id in: taskId];
        for (Task t : trigger.new){
            for (Task task : tasks){
                if (task.Subject.contains('Email:')){
                    if (task.Type == 'Other - see subject'){
                        task.Type = 'Email';
                        updated.add(task);
                    }
                }
            }
        }
        if (updated.size()>0){
            upsert updated;
        }
}

 However this does not work as any Emails I send to Salesforce are recorded with their default Type value ('Other - see subject') not the value of 'Email' that I intend.

 

I am not a coder and have stumbled my way through this, so would really appreciate a bit of guidance on how to tweak my code in order to work.

 

Thanks,

 

Marco

Hi,

 

Could someone please assist me with the below Apex Class and advise what I would need to change in order to only have it action Active Contacts, rather than Active and Inactive ones as it does in it's current form.

 

Thanks,

 

Marco

 

global class TrackContactUpdates implements Database.Batchable<Sobject> {
    global Database.QueryLocator start(Database.BatchableContext bc) {
        return Database.getQueryLocator('select id from contact' + (Test.isRunningTest()?' order by createddate desc limit 1':''));
    }
    
    global void execute(Database.BatchableContext bc,List<Contact> contacts) {
        Map<id,Contact> contactRecords = new Map<Id,Contact>(contacts);
        for(Contact c:[select id,
                        (select id,createddate from contractcontactroles order by createddate desc limit 1),
                        (select id,createddate from opportunitycontactroles order by createddate desc limit 1),
                        (select id,createddate from accountcontactroles order by createddate desc limit 1)
                       from contact where id in :contacts]) {
            contactRecords.get(c.id).last_contract_role_date__c = c.contractcontactroles.isempty()?null:c.contractcontactroles[0].createddate;
            contactRecords.get(c.id).last_opportunity_role_date__c = c.opportunitycontactroles.isempty()?null:c.opportunitycontactroles[0].createddate;
            contactRecords.get(c.id).last_account_role_date__c = c.accountcontactroles.isempty()?null:c.accountcontactroles[0].createddate;
        }
        update contactRecords.values();
    }
    
    global void finish(Database.BatchableContext bc) {
    
    }
    
    private static testMethod void test() {
        TrackContactUpdates t = new TrackContactUpdates();
        Account a = new Account(Name='Test');
        insert a;
        Contact c = new Contact(Firstname='Test',LastName='Test',AccountId=a.Id);
        insert c;
        Opportunity o = new Opportunity(Name='Test',CloseDate=System.today(),amount=1.00,stagename='Closed Won',AccountId=a.id);
        insert o;
        Contract ct = new Contract(Name='Test',AccountId=a.id,Status='Draft',Sales_Region__c='UK');
        insert ct;
        AccountContactRole acr = new AccountContactRole(Role='Vendor',ContactId=c.id,AccountId=a.id,isprimary=false);
        insert acr;
        acr = [select id,createddate from accountcontactrole where id = :acr.id];
        OpportunityContactRole ocr = new OpportunityContactRole(Role='Vendor',ContactId=c.id,OpportunityId=o.id,isprimary=false);
        insert ocr;
        ocr = [select id,createddate from opportunitycontactrole where id = :ocr.id];
        ContractContactRole ccr = new ContractContactRole(Role='Vendor',ContactId=c.id,ContractId=ct.id);
        insert ccr;
        ccr = [select id,createddate from contractcontactrole where id = :ccr.id];
        Test.startTest();
        TrackContactUpdates tcu = new TrackContactUpdates();
        Database.executeBatch(tcu);
        Test.stopTest();
        c = [select id,last_contract_role_Date__c,last_account_role_date__c,last_opportunity_role_date__c from contact where id = :c.id];
        system.assertEquals(ccr.createddate,c.last_contract_role_Date__c);
        system.assertEquals(ocr.createddate,c.last_opportunity_role_Date__c);
        system.assertEquals(acr.createddate,c.last_account_role_Date__c);
    }
}

 

Hi,

 

Is there a way to extract a matrix of data that illustrates all fields in our org (standard and custom) on all objects (again, standard and custom) and show the Field-Level Security they have in relation to all Profiles?

 

This stems from the fact we have numerous fields that have been created with no field-level access to the System Administrator profile. There is now a requirement that absolutely all fields must be visible by the Sys Admin profile and i wondered if there is an easy way to find this out.

 

Thanks for any help you can provide.

 

Regards,

 

Marco

Hi all,

 

I am writing a trigger and have a String named 'mappedDueDate' with a value assigned to it, such as:

 

mappedDueDate = '17/11/2011'

 

How can I parse this into a DateTime value so that in my trigger I can create a task with the correct Due Date.

 

e.g.

 

taskActivityDate = mappedDueDate

 

At the moment, I get an error message.

 

I am not a programmer and have received some guidance to understand that I need to parse the string value, but I do not know how.

 

Any help is much appreciated.

 

Thanks,

 

Marco

Hi,

 

I have written a trigger that creates a Task when a CampaignMember attends a specific event. The trigger works great and I am now writing my Test Method so that I can implement this code in our live org, however I am not a coder and not sure how to achieve this.

 

I have written a couple of triggers recently along with the Test Methods and received some excellent help from this board.

 

Below is the trigger and Test Method I need help with so any advice is much appreciated.

 

 

trigger PowerOf3 on CampaignMember (after insert, after update) {
    Set<Id> contactIds = new Set<Id>();

    for (CampaignMember cm : trigger.new){
        contactIds.add(cm.ContactId);
    }
    List<Contact> contacts = [
        SELECT Id, AccountId, OwnerId, Contact.Account.Id, Contact.Account.Name, Contact.Owner.Id
, Contact.Owner.Name
        FROM Contact 
        WHERE Id in :contactIds
    ];
    Map<String, Contact> contactMap = new Map<String, Contact>();
    for (Contact contact : contacts){
        contactMap.put(contact.Id, contact);
    }
    for (CampaignMember cm : trigger.new){
        Contact currentContact = contactMap.get(cm.ContactId);
        String campaignId = cm.CampaignId;
        String powerOf3Id = '701R0000000AJPBIA4';
        if (campaignId == powerOf3Id){
            if (cm.Status == 'Attended'){
                Task task = new Task();
                task.RecordTypeId = '012R00000004lckIAA';
                //Contact contact = [SELECT Id,AccountId,OwnerId FROM Contact WHERE Id = :cm.ContactId];
                task.WhoId = cm.ContactId;
                task.WhatId = cm.CampaignId;
                task.Priority = 'Normal';
                task.Status = 'Not Started';
                task.Subject = 'Power of 3 Follow Up';
                task.Type = 'Call - outbound';
                //Account account = [SELECT Id,Name FROM Account WHERE Id = :contact.AccountId];
                task.Client_Account_Name__c = currentContact.account.Name;
                //User user = [SELECT Id,Name FROM User WHERE Id = :contact.OwnerId];
                task.Contact_Owner__c = currentContact.owner.Name;
                String mappedUserId = '';
                if (currentContact.owner.Id == '00530000000gSl9'){
                    mappedUserId = '00530000000kvVm';                    
                } else if (currentContact.owner.Id == '00530000000kvVm'){
                    mappedUserId = '00530000000kvVm';
                } else if (currentContact.owner.Id == '00530000000iMq2'){
                    mappedUserId = '00530000000lcQ1';
                } else if (currentContact.owner.Id == '00530000000lcQ1'){
                    mappedUserId = '00530000000lcQ1';
                } else if (currentContact.owner.Id == '00530000000i4Dg'){
                    mappedUserId = '00550000001Cjog';
                } else if (currentContact.owner.Id == '00550000001Cjog'){
                    mappedUserId = '00550000001Cjog';
                } else if (currentContact.owner.Id == '00530000000i4Dt'){
                    mappedUserId = '00550000001Cjog';
                } else if (currentContact.owner.Id == '00530000000i4D4'){
                    mappedUserId = '00550000000mez5';
                } else if (currentContact.owner.Id == '00550000000mez5'){
                    mappedUserId = '00550000000mez5';
                } else {
                    mappedUserId = '00550000000mFkK';
                }
                task.OwnerId = mappedUserId;
                upsert task;
            }
        }   
    }
}

 

@isTest
private class PowerOf3Test{
    static testMethod void PowerOf3Test(){

    //Set up the User record
    User u = new User(Firstname='Test',LastName='Test',Username='test.test@test.com',Email='test.test@test.com',Alias='ttest',CommunityNickname='test.test',TimeZoneSidKey='GMT',LocaleSidKey='en_GB',EmailEncodingKey='ISO-8859-1',ProfileId='00e50000000yyaB',LanguageLocaleKey='en_US');
    insert u;

    //Set up the Contact record
    Contact c = new Contact(Firstname='Test',LastName='Test');
    insert c;

    //Set up the Campaign record
    Campaign cg = new Campaign(Name='Test');
    insert cg;

    //Set up the CampaignMember record
    CampaignMember cm = new CampaignMember(CampaignId = cg.id,ContactId=c.id,Status='Sent');
    upsert cm;
    
    //Set up the Task record
    Task t = new Task(Subject = 'Test');
    upsert t;
    
    //Cause the Trigger to execute
    cm.Status='Attended';
    upsert cm;

    //Verify that the results are as expected
    Contact c2 = [SELECT Id,AccountId,OwnerId FROM Contact WHERE Id=:cm.ContactId];
    Campaign cg2 = [SELECT Id FROM Campaign WHERE Id=:cg.Id];
    CampaignMember cm2 = [SELECT ContactId,CampaignId,Status FROM CampaignMember WHERE ContactId=:c.Id];
    public List<Task> gettask() {
        return [SELECT RecordTypeId,WhoId,WhatId,Priority,Status,Subject,Type,Client_Account_Name__c,Contact_Owner__c,OwnerId FROM Task WHERE RecordTypeId='012R00000004lckIAA' AND WhoId=:c.Id];
    }
    String mappedUserId='';
    if(c2.Id=='00530000000gSl9'){
        mappedUserId='00530000000kvVm';
    } else if (c2.Id=='00530000000kvVm'){
        mappedUserId='00530000000kvVm';
    } else if (c2.Id=='00530000000iMq2'){
        mappedUserId='00530000000lcQ1';
    } else if (c2.Id=='00530000000lcQ1'){
        mappedUserId='00530000000lcQ1';
    } else if (c2.Id=='00530000000i4Dg'){
        mappedUserId='00550000001Cjog';
    } else if (c2.Id=='00550000001Cjog'){
        mappedUserId='00550000001Cjog';
    } else if (c2.Id=='00530000000i4Dt'){
        mappedUserId='00550000001Cjog';
    } else if (c2.Id=='00530000000i4D4'){
        mappedUserId='00550000000mez5';
    } else if (c2.Id=='00550000000mez5'){
        mappedUserId='00550000000mez5';
    } else {
        mappedUserId='00550000000mFkK';
    }
    System.assertEquals(t2.RecordTypeId,'012R00000004lckIAA');
    System.assertEquals(t2.WhoId,c2.Id);
    System.assertEquals(t2.WhatId,cg2.Id);
    System.assertEquals(t2.Priority,'Normal');
    System.assertEquals(t2.Status,'Not Started');
    System.assertEquals(t2.Subject,'Power of 3 Follow Up');
    System.assertEquals(t2.Type,'Call - outbound');
    System.assertEquals(t2.Client_Account_Name__c,c2.AccountId);
    System.assertEquals(t2.Contact_Owner__c,c2.OwnerId);
    System.assertEquals(t2.OwnerId,mappedUserId);
    }
}

 Can anyone advise me on how the Test Method should be made please?

 

Thanks,

 

Marco

Hi,

 

I am receiving a error regarding too many SOQL queries when trying to upload several hundred contacts onto a campaign due to a trigger I have created.

 

From reading around the forum I believe that it is because my SOQL statement is inside a FOR loop which loops more times than the governor limits allow. I have read that I should perform the SOQL query outside of the FOR loop and use Lists and Maps to achieve what I require.

 

The trigger is pretty basic at the moment, however my coding skills are very limited and I'm not sure how to implement Lists or Maps.

 

I have posted my trigger below and if someone can instruct me on how to implement the Lists and Maps I would be very grateful.

 

trigger CampaignMemberUpdate on CampaignMember (after insert, after update) {
    for (CampaignMember cm : trigger.new){
        Contact contact = [SELECT Id from Contact where id = :cm.ContactId];
        contact.Campaign_Member_Update_Date__c = cm.LastModifiedDate;
        upsert contact;
    }
}

 

Thanks,

 

Marco

I have written the following test method to test a Trigger on the FeedItem object (to prevent deletion through Chatter):

 

@isTest
private class deleteBlockerTest{
        static testMethod void deleteBlockerTest() {
           
            //Set up the User record.
            User u = new User(Firstname='Test',LastName='Test',Username='test.test@test.com.globalsb',Email='test.test@test.com',Alias='ttest',CommunityNickname='test.test',TimeZoneSidKey='GMT',LocaleSidKey='en_GB',EmailEncodingKey='ISO-8859-1',ProfileId='00e50000000yyaB',LanguageLocaleKey='en_US');
            insert u;
           
            //Set up the UserFeed record.
            FeedItem fi = new FeedItem(Body='Test text for Item Body',ParentId=u.Id);
            upsert fi;
                                                        
            //Cause the Trigger to execute.
            delete fi;
           
            //Verify that the results are as expected.
            FeedItem fi2 = [select Id,IsDeleted from FeedItem where id = :fi.Id];
            System.assertEquals(fi2.isdeleted,false);
            }
        }

 

However, I am getting the following error message:

 

System.DmlException: Delete failed. First exception on row 0 with id 0D5R0000002Lkp1KAC; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, deleteBlocker: execution of BeforeDelete caused by: System.NullPointerException: Attempt to de-reference a null object Trigger.deleteBlocker: line 2, column 20: []

 

Can someone please advise me what I am doing wrong?

 

Thanks,

 

Marco

Hi,

 

I have created a trigger on the CampaignMember object as below:

 

trigger CampaignMemberUpdate on CampaignMember (after insert, after update) {
    for (CampaignMember cm : trigger.new){
        Contact contact = [SELECT Id from Contact where id = :cm.ContactId];
        contact.Campaign_Member_Update_Date__c = cm.LastModifiedDate;
        upsert contact;
    }
}

 

This trigger works well and updates the Campaign_Member_Update_Date__c field as expected.

 

I am now writing the test method for the trigger and have created the following:

 

@isTest
private class CampaignMemberUpdateTest{
        static testMethod void CampaignMemberUpdateTest() {
            
            //Set up the Contact record.
            Contact c = new Contact(Firstname='Test',LastName='Test');
            insert c;
            
            //Set up the Campaign record.
            Campaign cg = new Campaign(Name='Test');
            insert cg;
            
            //Set up the CampaignMember record.
            CampaignMember cm = new CampaignMember(CampaignId=cg.id,ContactId=c.id);
            
            //Cause the Trigger to execute.
            insert cm;
            
            //Verify that the results are as expected.
            c = [select Id,Campaign_Member_Update_Date__c from contact where id = :cm.ContactId];
            System.assertEquals(cm.LastModifiedDate,c.Campaign_Member_Update_Date__c);
            }
        }

 

However, when i run this test I get an error at the 'System.assertEquals' line with the following message:

 

System.AssertException: Assertion Failed: Expected: null, Actual: 2011-09-08 12:30:31

 

I then tried to set a 'cm.LastModifiedDate' value when creating the CampaignMember record, however I am unable to save the test method as the 'cm.LastModifiedDate' field is not writeable.

 

Does anyone know how I can fix this please?

 

Thanks,

 

Marco 

Hi,

 

I have seven different date fields on the contact object that I want to compare in order to find the most recent and then insert that into another custom field.

 

My current approach is not working as I am using several formula fields where each one consists of an IF statement that compares the previous formula field with one of the seven date fields and returns the greatest value.

 

For example:

 

Formula Field 1 = Comparing Date Field 1 with Date Field 2

Formula Field 2 = Comparing Formula Field 1 with Date Field 3

Formula Field 3 = Comparing Formula Field 2 with Date Field 4

And so on...

 

However I am now reaching a character limit on the compiled code (I'm guessing because it is going back through all of the previous IF statements and it becomes too large).

 

I have tried using the CASE() function but I still reach character limits.

 

Unfortunately the MAX() function only works with numbers, not date fields.

 

Does anyone have any advice how I could achieve my goal of finding the most recent date from a list of 7 fields?

 

Thanks,

 

Marco

I am investigating a way to identify the last time a contact in our org was last contacted or used within the system. This includes being added to a campaign as a campaign member, having an activity on the record (task or event), being sent an external email from email marketing software and being added as a contact role on an opportunity, a contract, etc.

Now, I have been able to handle for all the above events EXCEPT for when a contact is added as a contact role. It seems that there is no way to display this information on the contact record or reference the date they were added as a contact role in a formula of any sort. I know I can run a report, but this is not an option for 350,000 contacts!

The reason behind this is basically for data protection, and not wanting to hold a contact record for longer than necessary.

I fear that I could get to a situation where I deactivate and then ultimately delete a contact prematurely when they had been added as a contact role to an important opportunity only last week!

Does anyone know of anyway that I can consolidate all contact roles a contact may have across any object and display this in some way on the contact record?

Thanks in advance,

Marco

Hi all,

 

I have written the following trigger that automatically starts an approval process for a campaign record provided that the 'Estimated_Cost_per_head__c' value is greater than or equal to 25.

 

trigger AuthSpendProcessApproval on Campaign (after insert, after update){ for (Campaign c : trigger.new){ if (c.Estimated_Cost_per_head__c >= 25){ if (c.Approved__c == FALSE){ // Create an approval request for the Campaign Approval.ProcessSubmitRequest app = new Approval.ProcessSubmitRequest(); app.setObjectId(c.Id); //Submit the approval request for the Campaign Approval.ProcessResult result = Approval.Process(app); } } } }

 My test class passes fine and under most circumstances this trigger works the way I intended, however I have found a way to break it and would welcome some feedback please.

 

When I create a new Campaign record there are certain fields that have been set as mandatory that I deliberately don't complete. I get the error message reminding me to complete them (which I do), however instead of saving the record correctly I am supplied with the following error message:

 

Validation Errors While Saving Record(s)
There were custom validation error(s) encountered while saving the affected record(s). The first validation error encountered was "Apex trigger AuthSpendProcessApproval caused an unexpected exception, contact your administrator: AuthSpendProcessApproval: execution of AfterUpdate caused by: System.DmlException: Process failed. First exception on row 0; first error: ALREADY_IN_PROCESS, Cannot submit object already in process.: []: Trigger.AuthSpendProcessApproval: line 16, column 49".

 

This to me suggests that the record has already been entered into the approval process at the point of trying to save the record the first time (when it is unsuccessful due to mandatory data missing).

 

This error does not appear if I create a Campaign record from scratch with all data supplied first time around.

 

I then spoke to one of our database guys to try and understand database transactions better, but I am still confused as to what circumstance is causing the record to (in my mind) prematurely enter the approval process.

 

Can anyone shed some light on this please?

 

Thanks,

 

Marco

Hi all,

 

I have written a trigger on the Campaign object that works as required. Basically if a field (Estimated Cost) is above £25 then the trigger fires and the Campaign is submitted for approval (process is already set up). The code for teh trigger is as follows:

 

trigger AuthSpendProcessApproval on Campaign (after insert){
    
    for (Campaign c : trigger.new){
    
        if (c.Estimated_Cost_per_head__c >= 25){
                
            // Create an approval request for the Campaign
        
            Approval.ProcessSubmitRequest app = new Approval.ProcessSubmitrequest();
            app.setObjectId(c.Id);
        
            //Submit the approval request for the Campaign
        
            Approval.ProcessResult result = Approval.process(app);
        }
    }
}

 However I am now trying to create a Test Method, but after following some guidance online I am getting stuck. The Test Method I have written so far is:

 

@isTest
private class AuthSpendProcessApprovalTest{
    static testMethod void AuthSpendProcessApprovalTest(){
    
    //Set up Campaign record

    Campaign c = new Campaign(Name = 'Test', Estimated_Cost_per_head__c = 26);
    
    // Cause the trigger to execute
    
    insert c;
    
    //Create an approval request for the Campaign
    
    Approval.ProcessSubmitRequest app = new Approval.ProcessSubmitrequest();
    app.setObjectId(c.Id);
    
    // Submit the approval request for the Campaign
    
    Approval.ProcessResult result = Approval.process(app);
    
    // Verify that the results are as expected
    
    System.assert(result.isSuccess());
    
    System.assertEquals(
        'Pending', result.getInstanceStatus(),
        'Instance Status'+result.getInstanceStatus());
    }
}

 The error I get is:

 

System.DmlException: Process failed. First exception on row 0; first error: ALREADY_IN_PROCESS, Cannot submit object already in process.: []

 

From this message I understand that my Test Method is trying to submit the Campaign record to the Approval Process when it has already been submitted.

 

How can I test that when I perform the 'insert c' in the test, that the record has actually been submitted for approval?

 

Thanks,

 

Marco

Hi all,

 

I have written a very basic trigger that assigns a Type value to a Task that is created through the Email Bcc functionality that Salesforce provides.

 

I have tested the trigger and it works when sending a single Email into Salesforce. The code for this trigger is:

 

trigger EmailTask on Task (before insert, before update) {
    
        for (Task t : trigger.new){
            if (t.Subject.contains('Email:')){
                if (t.Type == 'Other - see subject'){
                    t.Type = 'Email';
                }
            }
        }
}

 However, from working on a previous trigger, I know that in order to meet Salesforce limits I must handle for updating large data sets.

 

So I have tried to modify this trigger in order to comply with these limits and I have come up with the following:

 

trigger EmailTask2 on Task (before insert, before update){

    Set<Id> taskId = new Set<Id>();
    List<Task> updated = new List<Task>();
    for (Task t : trigger.new){
        taskId.add(t.Id);
    }
    List<Task> tasks = [SELECT Id, Subject, Type FROM Task WHERE Id in: taskId];
        for (Task t : trigger.new){
            for (Task task : tasks){
                if (task.Subject.contains('Email:')){
                    if (task.Type == 'Other - see subject'){
                        task.Type = 'Email';
                        updated.add(task);
                    }
                }
            }
        }
        if (updated.size()>0){
            upsert updated;
        }
}

 However this does not work as any Emails I send to Salesforce are recorded with their default Type value ('Other - see subject') not the value of 'Email' that I intend.

 

I am not a coder and have stumbled my way through this, so would really appreciate a bit of guidance on how to tweak my code in order to work.

 

Thanks,

 

Marco

Hi,

 

Is there a way to extract a matrix of data that illustrates all fields in our org (standard and custom) on all objects (again, standard and custom) and show the Field-Level Security they have in relation to all Profiles?

 

This stems from the fact we have numerous fields that have been created with no field-level access to the System Administrator profile. There is now a requirement that absolutely all fields must be visible by the Sys Admin profile and i wondered if there is an easy way to find this out.

 

Thanks for any help you can provide.

 

Regards,

 

Marco

Hi all,

 

I am writing a trigger and have a String named 'mappedDueDate' with a value assigned to it, such as:

 

mappedDueDate = '17/11/2011'

 

How can I parse this into a DateTime value so that in my trigger I can create a task with the correct Due Date.

 

e.g.

 

taskActivityDate = mappedDueDate

 

At the moment, I get an error message.

 

I am not a programmer and have received some guidance to understand that I need to parse the string value, but I do not know how.

 

Any help is much appreciated.

 

Thanks,

 

Marco

Hi,

 

I have written a trigger that creates a Task when a CampaignMember attends a specific event. The trigger works great and I am now writing my Test Method so that I can implement this code in our live org, however I am not a coder and not sure how to achieve this.

 

I have written a couple of triggers recently along with the Test Methods and received some excellent help from this board.

 

Below is the trigger and Test Method I need help with so any advice is much appreciated.

 

 

trigger PowerOf3 on CampaignMember (after insert, after update) {
    Set<Id> contactIds = new Set<Id>();

    for (CampaignMember cm : trigger.new){
        contactIds.add(cm.ContactId);
    }
    List<Contact> contacts = [
        SELECT Id, AccountId, OwnerId, Contact.Account.Id, Contact.Account.Name, Contact.Owner.Id
, Contact.Owner.Name
        FROM Contact 
        WHERE Id in :contactIds
    ];
    Map<String, Contact> contactMap = new Map<String, Contact>();
    for (Contact contact : contacts){
        contactMap.put(contact.Id, contact);
    }
    for (CampaignMember cm : trigger.new){
        Contact currentContact = contactMap.get(cm.ContactId);
        String campaignId = cm.CampaignId;
        String powerOf3Id = '701R0000000AJPBIA4';
        if (campaignId == powerOf3Id){
            if (cm.Status == 'Attended'){
                Task task = new Task();
                task.RecordTypeId = '012R00000004lckIAA';
                //Contact contact = [SELECT Id,AccountId,OwnerId FROM Contact WHERE Id = :cm.ContactId];
                task.WhoId = cm.ContactId;
                task.WhatId = cm.CampaignId;
                task.Priority = 'Normal';
                task.Status = 'Not Started';
                task.Subject = 'Power of 3 Follow Up';
                task.Type = 'Call - outbound';
                //Account account = [SELECT Id,Name FROM Account WHERE Id = :contact.AccountId];
                task.Client_Account_Name__c = currentContact.account.Name;
                //User user = [SELECT Id,Name FROM User WHERE Id = :contact.OwnerId];
                task.Contact_Owner__c = currentContact.owner.Name;
                String mappedUserId = '';
                if (currentContact.owner.Id == '00530000000gSl9'){
                    mappedUserId = '00530000000kvVm';                    
                } else if (currentContact.owner.Id == '00530000000kvVm'){
                    mappedUserId = '00530000000kvVm';
                } else if (currentContact.owner.Id == '00530000000iMq2'){
                    mappedUserId = '00530000000lcQ1';
                } else if (currentContact.owner.Id == '00530000000lcQ1'){
                    mappedUserId = '00530000000lcQ1';
                } else if (currentContact.owner.Id == '00530000000i4Dg'){
                    mappedUserId = '00550000001Cjog';
                } else if (currentContact.owner.Id == '00550000001Cjog'){
                    mappedUserId = '00550000001Cjog';
                } else if (currentContact.owner.Id == '00530000000i4Dt'){
                    mappedUserId = '00550000001Cjog';
                } else if (currentContact.owner.Id == '00530000000i4D4'){
                    mappedUserId = '00550000000mez5';
                } else if (currentContact.owner.Id == '00550000000mez5'){
                    mappedUserId = '00550000000mez5';
                } else {
                    mappedUserId = '00550000000mFkK';
                }
                task.OwnerId = mappedUserId;
                upsert task;
            }
        }   
    }
}

 

@isTest
private class PowerOf3Test{
    static testMethod void PowerOf3Test(){

    //Set up the User record
    User u = new User(Firstname='Test',LastName='Test',Username='test.test@test.com',Email='test.test@test.com',Alias='ttest',CommunityNickname='test.test',TimeZoneSidKey='GMT',LocaleSidKey='en_GB',EmailEncodingKey='ISO-8859-1',ProfileId='00e50000000yyaB',LanguageLocaleKey='en_US');
    insert u;

    //Set up the Contact record
    Contact c = new Contact(Firstname='Test',LastName='Test');
    insert c;

    //Set up the Campaign record
    Campaign cg = new Campaign(Name='Test');
    insert cg;

    //Set up the CampaignMember record
    CampaignMember cm = new CampaignMember(CampaignId = cg.id,ContactId=c.id,Status='Sent');
    upsert cm;
    
    //Set up the Task record
    Task t = new Task(Subject = 'Test');
    upsert t;
    
    //Cause the Trigger to execute
    cm.Status='Attended';
    upsert cm;

    //Verify that the results are as expected
    Contact c2 = [SELECT Id,AccountId,OwnerId FROM Contact WHERE Id=:cm.ContactId];
    Campaign cg2 = [SELECT Id FROM Campaign WHERE Id=:cg.Id];
    CampaignMember cm2 = [SELECT ContactId,CampaignId,Status FROM CampaignMember WHERE ContactId=:c.Id];
    public List<Task> gettask() {
        return [SELECT RecordTypeId,WhoId,WhatId,Priority,Status,Subject,Type,Client_Account_Name__c,Contact_Owner__c,OwnerId FROM Task WHERE RecordTypeId='012R00000004lckIAA' AND WhoId=:c.Id];
    }
    String mappedUserId='';
    if(c2.Id=='00530000000gSl9'){
        mappedUserId='00530000000kvVm';
    } else if (c2.Id=='00530000000kvVm'){
        mappedUserId='00530000000kvVm';
    } else if (c2.Id=='00530000000iMq2'){
        mappedUserId='00530000000lcQ1';
    } else if (c2.Id=='00530000000lcQ1'){
        mappedUserId='00530000000lcQ1';
    } else if (c2.Id=='00530000000i4Dg'){
        mappedUserId='00550000001Cjog';
    } else if (c2.Id=='00550000001Cjog'){
        mappedUserId='00550000001Cjog';
    } else if (c2.Id=='00530000000i4Dt'){
        mappedUserId='00550000001Cjog';
    } else if (c2.Id=='00530000000i4D4'){
        mappedUserId='00550000000mez5';
    } else if (c2.Id=='00550000000mez5'){
        mappedUserId='00550000000mez5';
    } else {
        mappedUserId='00550000000mFkK';
    }
    System.assertEquals(t2.RecordTypeId,'012R00000004lckIAA');
    System.assertEquals(t2.WhoId,c2.Id);
    System.assertEquals(t2.WhatId,cg2.Id);
    System.assertEquals(t2.Priority,'Normal');
    System.assertEquals(t2.Status,'Not Started');
    System.assertEquals(t2.Subject,'Power of 3 Follow Up');
    System.assertEquals(t2.Type,'Call - outbound');
    System.assertEquals(t2.Client_Account_Name__c,c2.AccountId);
    System.assertEquals(t2.Contact_Owner__c,c2.OwnerId);
    System.assertEquals(t2.OwnerId,mappedUserId);
    }
}

 Can anyone advise me on how the Test Method should be made please?

 

Thanks,

 

Marco

Hi,

 

I am receiving a error regarding too many SOQL queries when trying to upload several hundred contacts onto a campaign due to a trigger I have created.

 

From reading around the forum I believe that it is because my SOQL statement is inside a FOR loop which loops more times than the governor limits allow. I have read that I should perform the SOQL query outside of the FOR loop and use Lists and Maps to achieve what I require.

 

The trigger is pretty basic at the moment, however my coding skills are very limited and I'm not sure how to implement Lists or Maps.

 

I have posted my trigger below and if someone can instruct me on how to implement the Lists and Maps I would be very grateful.

 

trigger CampaignMemberUpdate on CampaignMember (after insert, after update) {
    for (CampaignMember cm : trigger.new){
        Contact contact = [SELECT Id from Contact where id = :cm.ContactId];
        contact.Campaign_Member_Update_Date__c = cm.LastModifiedDate;
        upsert contact;
    }
}

 

Thanks,

 

Marco

I have written the following test method to test a Trigger on the FeedItem object (to prevent deletion through Chatter):

 

@isTest
private class deleteBlockerTest{
        static testMethod void deleteBlockerTest() {
           
            //Set up the User record.
            User u = new User(Firstname='Test',LastName='Test',Username='test.test@test.com.globalsb',Email='test.test@test.com',Alias='ttest',CommunityNickname='test.test',TimeZoneSidKey='GMT',LocaleSidKey='en_GB',EmailEncodingKey='ISO-8859-1',ProfileId='00e50000000yyaB',LanguageLocaleKey='en_US');
            insert u;
           
            //Set up the UserFeed record.
            FeedItem fi = new FeedItem(Body='Test text for Item Body',ParentId=u.Id);
            upsert fi;
                                                        
            //Cause the Trigger to execute.
            delete fi;
           
            //Verify that the results are as expected.
            FeedItem fi2 = [select Id,IsDeleted from FeedItem where id = :fi.Id];
            System.assertEquals(fi2.isdeleted,false);
            }
        }

 

However, I am getting the following error message:

 

System.DmlException: Delete failed. First exception on row 0 with id 0D5R0000002Lkp1KAC; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, deleteBlocker: execution of BeforeDelete caused by: System.NullPointerException: Attempt to de-reference a null object Trigger.deleteBlocker: line 2, column 20: []

 

Can someone please advise me what I am doing wrong?

 

Thanks,

 

Marco

Our head of Sales wants to auto-follow opportunities for our Americas and Asia offices that are over a certain stage. Could Swarm 3 is not able to have more than one criteria, i.e. follow all opportunities at a certain stage versus following opportunities of certain people once they hit a certain stage.

 

Does anyone know if an APEX trigger would solve this? Or if there is another solution to get this setup. In the mean time I have created list views with the information and will manually update the opportunities he follows, based on the criteria, using the mass "follow" and "unfollow" buttons.