• magicforce9
  • SMARTIE
  • 675 Points
  • Member since 2013
  • Salesforce Advanced Developer
  • Financial Times


  • Chatter
    Feed
  • 21
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 0
    Questions
  • 92
    Replies
Hi , I got a situation where i need to invoke future method from batch class. And i know that it is not possible to do. But there might be some workarounds to achieve it, right? And i dont want to invoke future method using shedule apex as my requirement will hit governor limits of "Total number of schedule jobs exceed". So i tried in below ways, but still fighting with same issue.

My design is
Scenario 1 :
1. Schedule Apex ===> 2. BatchClass (Runs every hour) (Generates a map with "N" records for every batch context, and passes it to Future method in an apex class)  ===> 3. Future method ( then it will login to a salesforce account and generates an attachment and sends an email to a corresponding email address) .

Scenario 2 :

Since, It is not possible to invoke future method from batch, i tried implementing an apex class with a normal static method  invoking future method and in a batch class, for every context i.e., execute() method, it will invoke a normal method which in turn invokes future method, but still got the same error ( FATAL ERROR: Future method cant be called from future or Batch).
ie., 
global class BatchClass implements Database.batachable<Sobject> {
   global Iterable<ScheduledReport__c> start(Database.BatchableContext BC) {
    query=[];
    return query;
    }
     global void execute(Database.BatchableContext BC, List<ScheduledReport__c> scope) {
         FutureClass.normalMethod(mapRecords);
      }
      global void finish(Database.BatchableContext BC){
      }
}

Future Class: 

global class FutureClass {
    global static void normalMethod(Map<> mapR) {
        futureMethod(mapR);
    }
    @future(callout=true)
    global static void futureMethod(Map<> m) {
        //some code;
     }
}

Scenario 3 :

Instead of invoking future class method from batch i tried updating list of records and done checkbox value to true and i've implemented after update event trigger to get the all the records in which checkbox values are true and from trigger i tried invoking future method , still didnt work , i got an error (  FATAL ERROR: Future method cant be called from future or Batch). 

Please help me out. 

Thanks !
Hi...
global class AAAA implements System.Schedulable {
global String str{get;set;}
global String mail{get;set;}
global String nomJob{get;set;}
global String inputText{get;set;}
global String heure{get;set;}
global String minute{get;set;}
global String jourMois{get;set;}
global String mois{get;set;}
global String jourSemaine{get;set;}

global void execute(SchedulableContext sc) {
  newPublier();
}

global AAAA () {

}

global AAAA (String mail, String inputText, String heure, String minute, String jourMois, String mois, String jourSemaine) {
this.mail= mail;
this.inputText = inputText;
this.heure= heure;
this.minute= minute;
this.jourMois= jourMois;
this.mois= mois;
this.jourSemaine= jourSemaine;
}

public void setMail(String mail) {
    this.mail= mail;
}

public String getMail() {
    return mail;
}

public void setRequete(String inputText) {
    this.inputText= inputText;
}

public String getRequete() {
    return inputText;
}

public void setHeure(String heure) {
    this.heure= heure;
}

public String getHeure() {
    return heure;
}

public void setMinute(String minute) {
    this.minute= minute;
}

public String getMinute() {
    return minute;
}

public void setJourMois(String jourMois) {
    this.jourMois= jourMois;
}

public String getJourMois() {
    return jourMois;
}

public void setMois(String mois) {
    this.mois= mois;
}

public String getMois() {
    return mois;
}

public void setJourSemaine(String jourSemaine) {
    this.jourSemaine= jourSemaine;
}

public String getJourSemaine() {
    return jourSemaine;
}


public void schedulejob(){
        String aaa = getMail();
        String req = getRequete();
        String heu = getHeure();
        String min = getMinute();
        String jMois = getJourMois();
        String leMois = getMois();
        String jSemaine = getJourSemaine();
                
        String NomJobSchedulable = nomJob;
        AAAA p = new AAAA (aaa, req, heu, min, jMois, leMois,jSemaine);
        String sch = '0'+' '+min+' '+heu+' '+jMois+' '+leMois+' '+jSemaine;
 
        system.schedule(NomJobSchedulable , sch, p);   
}

public void newPublier(){

    String query=inputText;
    String premier=query.substringAfter('select ');   
    premier=  premier.substringBefore('from');
      
    string titre= premier+'\n';
    string contenuCSV = titre;

    string queryResultatString = '';

    list<sObject> queryResultat = (List<sObject>)database.query(inputText);
    for(sObject a: queryResultat)
    {

        queryResultatString = queryResultatString + string.valueof(a);
        
    }
    System.debug('Query result string:'+queryResultatString);

    list<string> queryLignes = queryResultatString.split('}');

    for(string s:queryLignes){
        list<string> queryColonnes = s.split(',');
        for(string st:queryColonnes){
            contenuCSV = contenuCSV + st.substringAfter('=') + ',';
        }

        contenuCSV = contenuCSV.substringBeforeLast(',').substringBeforeLast(',') + '\n';
    }

    String lignes = contenuCSV;
    List<String> parts = lignes.split('\n');
    integer lineNumber = queryResultat.size();

    integer nbLignesPJ = 1000;
    integer compterParties=0;

    for(integer i=0;i<lineNumber;i++){

      string fichierParties = parts[0] + '\n';

      if(math.mod(i,nbLignesPJ)<>0) continue;
      if((lineNumber-i)<nbLignesPJ){

        for(integer j=1;j<=(lineNumber-i);j++){
            fichierParties = fichierParties + parts[i+j] + '\n';
        }
      }
      if((lineNumber-i)>=nbLignesPJ){
         for(integer j=1;j<=nbLignesPJ;j++){
            fichierParties = fichierParties + parts[i+j] + '\n';
        }
      }
      //Envoyer le Mail
      Messaging.EmailFileAttachment csvPJ = new Messaging.EmailFileAttachment();
      blob csvBlob = Blob.valueOf(fichierParties);
      string csvNom = 'cases_fermes_'+Date.today().format()+'.csv';
      csvPJ.setFileName(csvNom);
      csvPJ.setBody(csvBlob);
      Messaging.SingleEmailMessage email =new Messaging.SingleEmailMessage();
      String[] adressMail = new list<string> {mail};
      compterParties++;
      String subject;
          subject = 'CSV - '+Date.today().format();
      email.setSubject(subject);
      email.setToAddresses(adressMail);
      email.setPlainTextBody('message');   
      email.setFileAttachments(new Messaging.EmailFileAttachment[]{csvPJ});
      Messaging.SendEmailResult [] envoyer = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email});
    }
  }   
}



Someone give me the sample example of a test class to my class.
I want to publish my application but I do not know to do a test class.

rigger vig2 on join_object__c (after insert)
{
list<join_object__c> jcnewlist=new list<join_object__c>();
for(join_object__c jc:trigger.new)
{
  list<join_object__c> jclist=[select id,name,Account__r.name from join_object__c];
   jc.billing_adress__c=jc.Account__r.name;
   jcnewlist.add(jc);


error


Record is read-only: Trigger.vig2: line 7, column 1
I can create a trigger to update the field value from my custom object after an update of the PreviousFireTime field into CronTrigger?
How can I do this?

Thank you
I spent all of yesterday trying to write test classes for my two new triggers, but with zero experience with coding it has been a very difficult process.  All the apex triggers do is update the Last_activity_type__c field when a new activity is logged. Is there anyone who can help me write the test class code? Here are my triggers:
List<Id> OpportunityIds = new List<Id>();
List<Opportunity> OpportunityList = new List<Opportunity>();

for(Task t :trigger.new)
    {
    if(t.whatid!=null)
    {
        Schema.SObjectType tType= t.whatid.getSObjectType();
        if(tType == Opportunity.Schema.SObjectType)
        {
            OpportunityIds.add(t.Whatid);
        }
    }
    }
    {
    //Querying the related Opportunity based on whatid on Task
    Map<Id,Opportunity> OpportunityMap =  new Map<Id,Opportunity>([select id,Last_Activity_Subject__C from Opportunity where id in:OpportunityIds]);
 
    for(Task t :Trigger.new)

        for(Opportunity l : OpportunityMap.Values())
        {
            l.Last_Activity_Subject__C = t.subject;
            OpportunityList.add(l);
        }
    }
    // updating the Opportunity
    if(OpportunityList.size()>0)
    {
        update OpportunityList;
    }
}

trigger updateRelatedLead on Task (after insert,after update) {

List<Id> LeadIds = new List<Id>();
List<Lead> LeadList = new List<Lead>();

for(Task t :trigger.new)
    {
    if(t.whoId!=null)
    {
        Schema.SObjectType tType= t.whoId.getSObjectType();
        if(tType == Lead.Schema.SObjectType)
        {
            LeadIds.add(t.WhoId);
        }
    }
    }
    {
    //Querying the related Lead based on whoId on Task
    Map<Id,Lead> LeadMap =  new Map<Id,Lead>([select id,Last_Activity_Subject__C from Lead where id in:LeadIds]);
 
    for(Task t :Trigger.new)

        for(Lead l : LeadMap.Values())
        {
            l.Last_Activity_Subject__C = t.subject;
            LeadList.add(l);
        }
    }
    // updating the Lead
    if(LeadList.size()>0)
    {
        update LeadList;
    }
}
Hi I need a trigger on Account to automatically submit for approval process. I have a custom checkbox field name Usage Exclusion. My approval process criteria is if Usage Exclusion checkbox is checked then user can send it for approval request and once it is submitted then I have another custom checkbox field as Requested and it will be checked. If approved then custom checkbox field as Approved will be checked.
So I am looking for a trigger if user check the Usage Exclusion checkbox field and save the record it should automatically send for approval.

Please help me asap.


  • March 12, 2014
  • Like
  • 0

We have two custom objects. These objects have master details relationship that's why the owner of master  record is owner of child record.

 

In master we have a user look up field(Teaacher Name),based on this filed the owner field will need to update.Now the current user created by id is assigned to Record owner by default.

 

For example if we have 'John Smith' as 'Teacher name' ,we need to update owner field as 'John Smith'.WE HAVE MORE THAN 20 Teachers in our org.Work flow field update don't have the formula to do this in single work flow.

 

Is there is any alternative solution to do this Except Apex Trigger.

Thanks in Advance.

hi. i have a problem in saving the selected ids.

this is the id of the selected records:

for (integer i=0 ;i<selectedStudents.size();i++){
    //other codes
    selectedStudents.get(i).id
}

 how can i create multiple records using this?

 

 

  • November 14, 2013
  • Like
  • 0

HI,

          i wrote a trigger, it is working good, i write a test class for it the test class is also passed but trigger code coverage is showing 66% only how can i increase the trigger code to 75%. any help

trigger leadDuplicatePreventer2 on Lead(before insert, before update) 
{

    Map<String, Lead> leadMap = new Map<String, Lead>();

    for (Lead lead : System.Trigger.new) 
     {  

   if ((lead.LastName != null) &&(System.Trigger.isInsert || (lead.LastName != System.Trigger.oldMap.get(lead.Id).LastName))) 
   {  

            if (leadMap.containsKey(lead.LastName)) 
           {

                lead.LastName.addError('Another new lead has the '  + 'same LastName address.');

            } 
               else {

                leadMap.put(lead.LastName, lead);

            }

       }

    }   

    for (Lead lead : [SELECT LastName FROM Lead WHERE LastName IN :leadMap.KeySet()]) 
     {

        Lead newLead = leadMap.get(lead.LastName);

        newLead.LastName.addError('A lead with this LastName ' + 'address already exists.');

    }

}

   @test class for trigger

@istest public class TestleadDuplicatePreventer2 
{ 
Private Static testmethod void TestleadDuplicatePreventer2()
{ 
Lead objLead = new Lead(); 
objLead.LastName = 'Test Lead'; 
objLead.Company = 'Test Lead'; 
objLead.Status = 'Test LeadStatus'; 
objLead.LeadSource = 'Test LeadSource'; 
insert objLead; 
Lead objLead1 = new Lead(); 
objLead1.LastName = 'Test Lead2'; 
objLead1.Company = 'Test Lead2'; 
objLead1.Status = 'Test LeadStatus2'; 
objLead1.LeadSource = 'Test LeadSource2'; 
insert objLead1; 


} 
}

 

Hi,

Need to write a trigger on the following requirement:

 

When the ‘Active’ status on the attached Service Agreement object goes to ‘Inactive’, the associated Equipment Object's field is marked on the ‘Contract Status’ field with ‘Under Expired Contract’.

 

The service agreement object is in lookup relationship with the equipment object.

  • November 13, 2013
  • Like
  • 0
// The Purpose of this Trigger is to get the Count of Total Number of Childern the parent account has.


trigger countChildAccount on Account (after Insert, after Update, before delete) { Set<id> ids= new Set<id>(); List<Account> acclist = new List<Account>(); Integer count = 0; if(Trigger.isInsert || Trigger.isUpdate){ for(Account acc: Trigger.new){ if(acc.Ultimate_Parent_Client__c!=null) ids.add(acc.Ultimate_Parent_Client__c); acclist.add(acc); } } if(Trigger.isDelete){ for(Account acc: Trigger.old){ if(acc.Ultimate_Parent_Client__c!=null) ids.add(acc.Ultimate_Parent_Client__c); acclist.add(acc); } } if(ids.size()>0){ List<Account> accchild = new List<Account>([select id,Ultimate_Parent_Client__c from Account where Ultimate_Parent_Client__c IN: ids]); List<Account> accparent = new List<Account>([select id,No_of_Child_Accounts__c from Account where id IN: ids]); for(Account ac: accparent){ count =0; for(Account acchild: accchild){ if(acchild.Ultimate_Parent_Client__c == ac.id) count++; } ac.No_of_Child_Accounts__c = count; } try{ upsert accparent; }catch(DMLException ex){ System.debug('Exception is '+ex); } } }

 

@isTest
private class TestCountChildAccount {

    static testMethod void AccountSumTest() {
 
        
        
        Account tstAcct = new Account ( Name = 'Test932',
                                       BillingCity ='ultAccforDSAutomationTestCity',
                                               BillingCountry ='ultAccforDSAutomationCountry',
                                               BillingStreet ='ultAccforDSAutomationSt',
                                               BillingPostalCode ='536768',
                                               phone = '010101',
                                               Ultimate_Parent__c = True
                                      );
        insert tstAcct;

         Account tstAcct1 = new Account ( Name = 'Test932',
                                       BillingCity ='ultAccforDSAutomati1onTestCity',
                                               BillingCountry ='ultAccfo1rDSAutomationCountry',
                                               BillingStreet ='ultAccforD1SAutomationSt',
                                               BillingPostalCode ='5367618',
                                               phone = '0101101',
                                               Ultimate_Parent_Client__c = tstAcct.id
                                      );
Test.StartTest();
       Insert tstAcct;
Test.StopTest();

System.AssertEquals('1','No_Of_Child_Accounts__C');
        tstAcct.fax = '2344';
        
        update tstAcct;
        
        delete tstAcct;
        
        undelete tstAcct;

    }

}

 

HI , I have a Trigger which counts the total number of child accounts the parent account has , I am having difficulty in getting test coverage , any help on this one Plz

 

Thanks 

Akhil.

  • November 12, 2013
  • Like
  • 0

Hi All

 

I am held up with this and would really appreciate any suggestions, inputs , help.

 

I have a trigger on the Account object. The trigger pulls a user ID from a custom sObject. The User Id is successfully fetched. It also appears in the debug log that the fetched user Id is assigned correctly to the Account's OwnerID. However, when I go back and check the account record, it still shows the previous User Id and not the ID that is fetched from the custom object. 

 

I have pasted the trigger and debug log excerpt below. Any thoughts?

 

TRIGGER

 

trigger SetAccountOwner on Account (before insert, before update) {

Set<Id> accIds = new Set<Id>();
for(Account a:Trigger.new){
accIds.add(a.Id);
}
List<Account> acc = [Select Id, OwnerId, Billing_State_Abbreviation__c, BillingCity from Account where Id In: accIds];
Map<Id,String> accMap = new Map<Id,String>();
String strOwnerAddressKey ;
String strCity ;
List<Entity_Owner_Address_Map__c> ownerAddr = [Select Owner_Address_Key__c, Owner__c from Entity_Owner_Address_Map__c];
for(Account a: acc){
if(a.BillingCity==null){
strCity='DEFAULT';
}
else{
strCity=(String)a.BillingCity;
}
if(a.Billing_State_Abbreviation__c!=null){
strOwnerAddressKey = (String)a.Billing_State_Abbreviation__c + '-' + strCity;
accMap.put(a.Id, strOwnerAddressKey);
}
else{
// If State is absent, dont do anything
}
System.Debug('strOwnerAddressKey:' + strOwnerAddressKey);
strOwnerAddressKey = null; //Clear it
strCity = null; //Clear it //

// Now, loop through accMap and pull Owner Id from ownerAddr list, then update account
String strKeyInLoop;

for(Id ab:accMap.keySet()){
//System.Debug('a:'+a); // a Contains the account Id
strKeyInLoop=accMap.get(ab);
System.Debug('strKeyInLoop'+strKeyInLoop);
for(Entity_Owner_Address_Map__c e:ownerAddr){
System.Debug('e.Owner_Address_Key__c:'+e.Owner_Address_Key__c);
if((String)e.Owner_Address_Key__c==strKeyInLoop){
//ab.Id=a;
System.Debug('e.Owner__c:'+e.Owner__c);
System.Debug('a.OwnerId: Before '+a.OwnerId);
a.OwnerId = (Id)e.Owner__c;

System.Debug('a.OwnerId: After '+ a.OwnerId); // The debug log appears Good here, but the account record isnt actually updated
break;

}
}
}
}
}

 

DEBUG LOG:

 

11:55:33.116 (116084000)|USER_DEBUG|[41]|DEBUG|a.OwnerId: Before 005E0000003QJeKIAW
11:55:33.116 (116174000)|USER_DEBUG|[44]|DEBUG|a.OwnerId: After  005E0000000K9uHIAS

When I am trying to update a field by using @future method. It was showing an error message like " Future method cannot be called from a future or batch method " .

Here is my code...

 

My trigger is

 

trigger test on Contact (before insert,before update) {

for (Contact contact : Trigger.new) {

 

        string endPoint;      
        endPoint = ''https://test.com/body.json';
        Webcooks.GetRequest(endPoint,contact.LastName,contact.email);

        string endPoint2;      
        endPoint2 = ''https://test.com/response.json?email=';
        Webcooksstatus.GetRequest(endPoint,contact.LastName,contact.email);
        contact.Campaign_Monitor_Status__c = '';
        Webcooksstatus.test();

}

 

}

 

 

 

My class is...

 

Public class Webcooks
{
@future(callout=true)
public static void GetRequest(String url,string LastName,string email)
{


HttpRequest con = new HttpRequest();

con.setBody('{"EmailAddress": "'+email+'","Name": "'+LastName+'"}');
String username = 'dfsfsdffsfsa';
String password = '';

 

Blob headerValue = Blob.valueOf(username + ':' + password);
String authorizationHeader = 'BASIC ' +
EncodingUtil.base64Encode(headerValue);
con.setHeader('Authorization', authorizationHeader);
con.setEndpoint(url);
con.setMethod('POST');

Http http = new Http();
HTTPResponse res = http.send(con);

}
}

 

My second class is....

 

Public class Webcooksstatus
{

public static string statused{get;set;}
public static string status{get;set;}
public static string state{get;set;}

@future(callout=true)
public static void GetRequest(string url,string LastName,String email)
{
String body='{"EmailAddress": "'+email+'","Name": "'+LastName+'"}';
state = email;
HttpRequest con = new HttpRequest();
con.setMethod('GET');
String username = 'dfsfsdffsfsa';
String password = '';
Blob headerValue = Blob.valueOf(username + ':' + password);
String authorizationHeader = 'BASIC ' +
EncodingUtil.base64Encode(headerValue);
con.setHeader('Authorization', authorizationHeader);

con.setEndpoint(url+Email);

Http http = new Http();
HTTPResponse res = http.send(con);

JSONParser parser = JSON.createParser(res.getBody());
       
        while (parser.nextToken() != null) {
            if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) &&
                (parser.getText() == 'State')) {
                
                parser.nextToken();
               
                status = parser.getText();
               
            }
        }
         statused =status;
}

test();
}

public static void test()
{
list<Contact> ContactsToUpdate =  new List<Contact>();
for (Contact c : [Select Id, Name,Campaign_Monitor_Status__c  From Contact where email=:state]) {

c.Campaign_Monitor_Status__c = statused ;

ContactsToUpdate.add(c);
}
update ContactsToUpdate;

}

}

 

 

I want to update "Campaign_Monitor_Status__c"  field with the "statused".... Please Help me

 

 

 

New to triggers and trying to find a code example to do the following:

 

Child opportunities linked to parent opportunites on Parent_Opportunity__c lookup

 

If parent CloseDate or StageName changes, I would like a trigger to update all child opportuntiies

  • November 05, 2013
  • Like
  • 0

I'm trying to code a trigger to auto-Submit a record through the Approval Process on a Custom Object. I want to do this to make the record Read Only (I know there are others ways to do this, but I'm up for a challenge!). 

 

My Approval Process criteria is only: when "Locked__c" (checkbox) is "True". I also have it set to auto-reject by default and lock the record

 

The code I'm using is below, but I'm receiving error message: 
Error: Compile Error: Variable does not exist: Locked__c at line 3 column 12

 

I'm new to Apex coding, so any help is greatly appreciated! If any other information is needed, just let me know. 

 

trigger Record_Lock on Plan_and_Profile__c (after update, after insert) {
for (Plan_and_Profile__c a: Trigger.new) { 
    if (a.(Locked__c == 'True')) {
      // Create an approval request for the account
      Approval.ProcessSubmitRequest req1 =
      new Approval.ProcessSubmitRequest();
      req1.setComments('Automatic record lock.');
      req1.setObjectID(a.id);
      
      // Submit the approval request for the account
      Approval.ProcessResult result = Approval.process (req1);
    }
  }
}

 

  • November 05, 2013
  • Like
  • 0

Hi,

 

I'm not a developer but I need an help for a Trigger that I tried to do.

 

I need to store all the product code(s) linked to an opportunity after insert/delete/update/undelete of a Product.

 

I've created a field in the Opportunity table (Product_Code_Selected__C) in order to store this information.

 

I'm able to get the PricebookEntryID but I need to store the product code. I Know that I have to do a sub query, but I tried without success. 

I have also an issue if I try to delete a product from an opportunity (I'm expecting that the field will be updated without the product deleted) but I'm receiving this error message:

 

OppProductCode_trigger: execution of AfterDelete

caused by: System.NullPointerException: Attempt to de-reference a null object

Trigger.OppProductCode_trigger: line 5, column 1

 

Could you please help me? This is the Aper Trigger

 

trigger OppProductCode_trigger on OpportunityLineItem (after delete, after insert, after undelete, 
after update) {
    //Setup the array to hold the Id to Iterate through
    Set<Id> CurrentOppId = new Set<Id>();
        for (OpportunityLineItem OppLnItem : Trigger.new){
        	CurrentOppId.add(OppLnItem.OpportunityId);
    }
 
    	// Create List of One Opportunity Id to Update
	    List<Opportunity> OppId = 
	    	[Select o.Id from Opportunity o
	    		where o.Id in: CurrentOppId];

    		// Create List of Opportunity Products to iterate through later
		    List<OpportunityLineItem> relatedOLIs =
			    [Select oli.Id, oli.PricebookEntryId from OpportunityLineItem oli
	    			where oli.OpportunityId in: CurrentOppId];

    // Used to not add ',' on first OpportunityLineItem PricebookEntryID
    Boolean isFirst = true;
       
    //Iterate through the Opportunity to Update (should be just one record)
    for (Opportunity opp2 : OppId){
	    opp2.Product_Code_Selected__c = '';

	    //Iterate through the line items to add PricebookEntryID data to the Opportunity
	    for (OpportunityLineItem oli2 : relatedOLIs){
	                   	if(isFirst) {
	                		opp2.Product_Code_Selected__c += oli2.PricebookEntryId;
	                		isFirst = false;
	            		}
	            		else {
	                		opp2.Product_Code_Selected__c += ',' + oli2.PricebookEntryId; 
		            	}
	    }
    }
	try{
        update OppId;
    }catch(DMLException d){
        system.debug('\n\nERROR UPDATING Opportunity: '+d.getDMLMessage(0));
    }
}

 Many thanks in advance

Regards

Valerio

 

I've been trying to create a trigger to connect entries between two custom objects upon bulk upload...I was able to get some help with the code but there's a compile error that I can't figure out. Can anyone help? It'd be greatly appreciated.

 

What we're trying to do:  basically we have two custom objects, "Sales" and "Reps". We upload a list of sales (in .csv format) into the Sales object each week. We want to make it so that every time a Sale entry gets created it is assigned to the Rep who made that sale (Sales has a master-detail relationship with Reps). Each sale lists the Name and ID# of the rep who made it, but not the Salesforce ID of the corresponding Rep entry. So we want the apex trigger to match each Sale to the correct Rep by comparing the Name and/or ID fields in both objects.

 

The code we've got so far is:

trigger SaleTrigger on Sale__c (before insert){

   //This set will store all the RepId's.

   Set<String> repIDs = new Set<String>();

   //Loop through all the new sales to be created.
   for(Sale__c sale : Trigger.new){
      //Get the rep's ID of each sale and add it to the Set
      //Note: I am assuming the API/Unique name of the Rep ID     
      //field is Rep_Id__c;
      repIDs.add(sale.Rep_ID__c);
   }

   //Now we have all the Rep ID's in the set.
   // Issue an single SOQL to get the Salesforce ID's of all the reps.
   
   Map<String,ID> mapReps = new Map<String,ID>();
   for(Rep__c repRecord : [Select ID,Rep_ID__c From Rep__c WHERE Rep_ID__c IN (:repIDs)]){
      mapReps.put(repRecord.Rep_ID__c,repRecord.ID);
   }
   
  //The mapReps has a map of all Rep ID's with Rep Salesforce ID's
   for(Sale__c sale : Trigger.new){
      ID repSalesforceID = mapReps.get(sale.Rep_ID__c);
      //This is the MD field in Sale__c.
      sale.Rep__c = repSalesforceID;
   }
   
}

 

The error I'm getting on trying to save is:  "Invalid bind expression type of SET<String> for column of type String"

It occurs on line 19 which is: 

 

for(Rep__c repRecord : [Select ID,Rep_ID__c From Rep__c WHERE Rep_ID__c IN (:repIDs)]){

 

Can anyone help me figure this out? I'd be extremely grateful.

 

I need help to write a method which will do some kind of string formatting.

 

I have list of ids of an object. It may be any object.Like this:

List listContactIds = [select id from contact limit 5];

 

And I have a certain string format like this:

String format = ‘{name} belongs to {Account.Name}’;

 

I need to call a method. Suppose the method name is formatString.

formatString(listContacts, format);

 

The method should be able to return list of formatted strings.Like this Rahul belongs to Google

We can take the exact field names enclosed in {} from the 'format' string

How to acheive this?

  • October 31, 2013
  • Like
  • 0

I have an approval process set for solutions.  What I want is if the INTERNAL ONLY checkbox is unchecked and the status is Accepted, the Visible in Self-Service Portal box needs to get checked.  A workflow isn't working as I don't think it thinks it has been edited.  If I go into the solution and change something and it fits the criteria, it will then check the box.  It won't do this right after the approval process is run.

 

Can I accomplish this in a trigger?  If so, please tell me how.  I SUCK at triggers!

  • October 30, 2013
  • Like
  • 0

I have a batch class that collects values from the contact custom field YTD_GDC_Total__c and totals them at the account level and then inserts to totals into the associated custom account field.  I have an example of the code below showing one field being summed/totaled.  

 

I've begun adding additional fields (beyond what is shown in the code below) and, finally, after I added the last two fields, I'm now getting Batchable Instance Is Too Big error.  

 

I found this threadwhich I think may describe the cause of my error: "..(having a) global variable  which was keeping instances of lists of records that were created in each execution of the method 'execute' " - I think I'm keeping too many map collections in memory.  Any thoughts on how to resolve or does anyone know if a more efficient code pattern to summarize contact field @ the account level (without using aggregate queries)?

 

Thanks in advance!

 

CODE:

 

global class BatchAccntSummary implements Database.Batchable<sObject>, Database.Stateful

{

  public String query = 'SELECT Id, Name, AccountId, Account.RecordTypeId, Account.Name, YTD_GDC_Total__c ' +

                'FROM Contact WHERE Account.RecordTypeId = \'012500000009WdF\' ' +

                'AND (YTD_GDC_Total__c > 0.00)';  

  global Map<Id, Account> branchesToUpt = new Map<Id, Account>();

  global Boolean uniqueFirm = true;

  global Boolean addMapToList;

  global Integer counter = 0;

  global Map<Id, Decimal> branch_total_YTD_GDC;

  global Decimal total_YTD_GDC_Cont;

  global Decimal currbranch_total_YTD_GDC;

 

  /* 

  * OBJECTIVE:       Method used to initialize all the variables once.

  */

  global void initVars()

{

    branchesToUpt = new Map<Id, Account>();

    uniqueFirm = true;

    counter = 0;

 

  // YTD GDC TOTAL

  branch_total_YTD_GDC = new Map<Id, Decimal>();

  total_YTD_GDC_Cont = 0.00;

  currbranch_total_YTD_GDC = 0.00;  

}

 

  /* 

  * OBJECTIVE:       Start method of the Batchable interface 

  */

  global database.querylocator start(Database.BatchableContext BC)

  {

    initVars();

    return Database.getQueryLocator(query);

  }

 

  /* 

  * OBJECTIVE:       Utility method needed to handle null values.

  */

  global Decimal formatDecimal(Decimal valToFormat)

  {

    Decimal processedValue = 0.00;

    if (valToFormat != null)

      processedValue = valToFormat;

    else

      processedValue = 0.00; 

    return processedValue; 

  }

  

  /* 

  * OBJECTIVE:       Execute method of the Batchable interface 

  */

  global void execute(Database.BatchableContext BC, List<sObject> scope)

  {

    Account currAccnt;

    for (sObject s : scope) {

      addMapToList = false;

      uniqueFirm = true;    

      Contact c = (Contact)s;

 

total_YTD_GDC_Cont  = formatDecimal(c.YTD_GDC_Total__c);

 

      System.debug('Processing contact: ' + c.Name);

      // DEBUG Stuff

      System.debug('######## Size of branch_total_YTD_GDC _Map: ' + branch_total_YTD_GDC.size());

     

      // Check if the map already contains the firm id

      if (branch_total_YTD_GDC.containsKey(c.AccountId)) {

        uniqueFirm = false

      } 

     

      // If the map does not contain the firm id

      if (uniqueFirm) {

        System.debug('###### Size of m: ' + branch_total_YTD_GDC.size());

       

        branch_total_YTD_GDC.put(c.AccountId, total_YTD_GDC_Cont);

       

        currAccnt = new Account(Id = c.AccountId, Branch_Total_YTD_GDC__c = branch_total_YTD_GDC.get(c.AccountId));

 

        System.debug('Adding account: ' + c.Account.Name + ' w/ sales: ' + branch_total_YTD_GDC.get(c.AccountId) +

                    ', contact person: ' + c.Name);    

 

      }

      // If the map does contain the firm id

      else if (!uniqueFirm) {

          if (branch_total_YTD_GDC.containsKey(c.AccountId)) {

         

            currbranch_total_YTD_GDC = branch_total_YTD_GDC.get(c.AccountId);

           

            branch_total_YTD_GDC.put(c.AccountId,(total_YTD_GDC_Cont + currbranch_total_YTD_GDC));

           

            currAccnt = new Account(Id=c.AccountId,Branch_Total_YTD_GDC__c = branch_total_YTD_GDC.get(c.AccountId));                                    

                                   

            System.debug('Account: ' + c.Account.Name + ' w/ sales: ' + branch_total_YTD_GDC.get(c.AccountId) +

                        ', contact person: ' + c.Name);                        

          } 

      }

      if (currAccnt != null)

        branchesToUpt.put(c.AccountId, currAccnt);

    }

    update branchesToUpt.values();

    branchesToUpt.clear();

  }

 

  /* 

  * OBJECTIVE:       Batch finish Method.

  */

  global void finish(Database.BatchableContext BC)

  {

 

  }

}

 

Hi All,

I am getting this error while performing 'Run All Tests'. However, individual test classes works fine. This error is also intermittent. I am not sure how to fix this and why I'm getting this error. Can anyone help?

Hey guys, I was having a little trouble working on some apex classes because the only way I can is by working them in my sandbox, now I am wondering how to 'move' these files into the real workspace of the actual salesforce area. 

 
Hi , I got a situation where i need to invoke future method from batch class. And i know that it is not possible to do. But there might be some workarounds to achieve it, right? And i dont want to invoke future method using shedule apex as my requirement will hit governor limits of "Total number of schedule jobs exceed". So i tried in below ways, but still fighting with same issue.

My design is
Scenario 1 :
1. Schedule Apex ===> 2. BatchClass (Runs every hour) (Generates a map with "N" records for every batch context, and passes it to Future method in an apex class)  ===> 3. Future method ( then it will login to a salesforce account and generates an attachment and sends an email to a corresponding email address) .

Scenario 2 :

Since, It is not possible to invoke future method from batch, i tried implementing an apex class with a normal static method  invoking future method and in a batch class, for every context i.e., execute() method, it will invoke a normal method which in turn invokes future method, but still got the same error ( FATAL ERROR: Future method cant be called from future or Batch).
ie., 
global class BatchClass implements Database.batachable<Sobject> {
   global Iterable<ScheduledReport__c> start(Database.BatchableContext BC) {
    query=[];
    return query;
    }
     global void execute(Database.BatchableContext BC, List<ScheduledReport__c> scope) {
         FutureClass.normalMethod(mapRecords);
      }
      global void finish(Database.BatchableContext BC){
      }
}

Future Class: 

global class FutureClass {
    global static void normalMethod(Map<> mapR) {
        futureMethod(mapR);
    }
    @future(callout=true)
    global static void futureMethod(Map<> m) {
        //some code;
     }
}

Scenario 3 :

Instead of invoking future class method from batch i tried updating list of records and done checkbox value to true and i've implemented after update event trigger to get the all the records in which checkbox values are true and from trigger i tried invoking future method , still didnt work , i got an error (  FATAL ERROR: Future method cant be called from future or Batch). 

Please help me out. 

Thanks !
I am trying to create a contact record upon user record creation. It should only create a contact record if certain user role are selected. I have the following trigger which works fine if I remove IF statement for ROLE...could someone please help? Again, I have been trying to create a contact record upon creating user record only when certain ROLE are set for the user...Thanks..
trigger CreateContact on User (after insert) {    
    List<Contact> ur = new List<Contact>();
    for (User usr: Trigger.New){
	     if(usr.UserRole.Name=='role name'|| usr.UserRole.Name=='role name')      
              ur.add (new Contact(
                         FirstName = usr.FirstName,
                         LastName = usr.LastName));
                         
    }
	if(!ur.isEmpty())
        insert ur; 
}

 
  • November 25, 2014
  • Like
  • 0
This is my trigger 
trigger UpdatePrimaryApllicationAllocationSet on Primary_Application_Allocation__c (after insert,after delete) {

    list<id> lst = new list<id>();
    if(trigger.isInsert){
    for(Primary_Application_Allocation__c paa : trigger.new) {
        lst.add(paa.opportunity__c);
    }}
    if(trigger.isDelete){
        for(Primary_Application_Allocation__c paa : trigger.old) {
        lst.add(paa.opportunity__c);
        }
    }
   
    list<Opportunity> opplst = new list<Opportunity>();
    opplst=[SELECT Primary_Application_Allocation_Set__c FROM Opportunity where Id in :lst];

    if(trigger.isInsert) {
        for(Primary_Application_Allocation__c paa : trigger.new) {
            for(Opportunity o : opplst) {
                if(paa.Opportunity__c == o.Id) {
                    o.Primary_Application_Allocation_Set__c = true;
                }
            }
        }
        update opplst;
    }
   
    if(trigger.isDelete) {
        for(Primary_Application_Allocation__c paa : trigger.old) {
            for(Opportunity o : opplst) {
                if(paa.Opportunity__c == o.id) {
                    o.Primary_Application_Allocation_Set__c = False;
                }
            }
        }
        update opplst;
    }
           
}


and down i have written a test class but it is totally mess cause i am unaware of test class can any one help me in doing this..

@isTest

public class UpdatePrimaryApllicationAllocationSet {

    static testMethod void UpdatePrimaryApllicationAllocationSet() {
          Test.startTest();
          Primary_Application_Allocation__c paa = new Primary_Application_Allocation__c(name='sample');
          opportunity o = [select name,oppotunity from opportunity where o.opportunity = paa.opportunity];
          insert paa;
          update o;
          Test.stopStart();
         
    }
   
}

Hi every one,
       I have a problem regarding Email to Lead i.e, when ever the customer sending an email to salesforce then the lead is automatically  created in our organization. But the total lead details goes to Description field but i don't want like that .My requirement is, In the mail customer sends like this
  Name : kishore
  Company : XXXXXXX
Industry : Banking

I want this details directly in that partucular fields. So how can i acheive this one Please help me out........

Advance Thank you.
Hi,
following code gets me the bus hours for case but its getting wrong bus hour id.
Because debug log shows values stored is like this in map

{Europe/London=01mG00000008TvcIAE}
{Europe/London=01mG00000008TvbIAE}

-----
--it should simulate this code--
-----
List<Case> caseList = [SELECT Id, BusinessHoursId, EntitlementId, Entitlement.SlaProcess.Name, Case_Timezone__r.TimeZoneSidKey__c FROM Case WHERE Id in :lCases];
       
        for (Case c :caseList)
        {
            if (c.EntitlementId != null)
            {
                try
                {
                    if (c.Entitlement.SlaProcess.Name == 'Mission Critical' || c.Entitlement.SlaProcess.Name == 'Mission Critical (GCS Management Override)')
                        c.BusinessHoursId = [SELECT Id FROM BusinessHours WHERE TimeZoneSidKey = :c.Case_Timezone__r.TimeZoneSidKey__c AND Name Like '08x05%'].Id;
                    else if (c.Entitlement.SlaProcess.Name == 'Enterprise' || c.Entitlement.SlaProcess.Name == 'Enterprise (GCS Management Override)')
                        c.BusinessHoursId = [SELECT Id FROM BusinessHours WHERE TimeZoneSidKey = :c.Case_Timezone__r.TimeZoneSidKey__c AND Name Like '08x05%'].Id;
                    else if (c.Entitlement.SlaProcess.Name == 'Standard')
                        c.BusinessHoursId = [SELECT Id FROM BusinessHours WHERE TimeZoneSidKey = :c.Case_Timezone__r.TimeZoneSidKey__c AND Name Like '08x05%'].Id;
                   
                    System.debug ('====C'+ c + '====BID'+ c.BusinessHoursId);
                    update c;
-----


CURRENT CODE to fix that gets wrong business hours:
----------------------------------------------------------------------------------
List<Case> caseList = [SELECT Id, BusinessHoursId, EntitlementId, Entitlement.SlaProcess.Name, Case_Timezone__r.TimeZoneSidKey__c FROM Case WHERE Id in :lCases];
       List<BusinessHours> bHours=[SELECT Id FROM BusinessHours WHERE Name Like '08x05%'];
       List<case> caseListUpdate = new List<case>{};

       Map<String,Id> caseListMap=new Map<String,Id>();
      
      for(BusinessHours bh:bHours)
       {
            for(Case c:caseList)
            {
            caseListMap.put(c.Case_Timezone__r.TimeZoneSidKey__c,bh.Id);
            }
        }
      System.debug('######This is my MAPDATA:'+ caseListMap);

      
        for (Case c :caseList)
        {
            if (c.EntitlementId != null)
            {
                try
                {
               
  Boolean bEntryCriteria = caseListMap !=  null && c.Case_Timezone__c != null && c.Case_Timezone__r.TimeZoneSidKey__c != null && caseListMap.containsKey(c.Case_Timezone__r.TimeZoneSidKey__c);
if (bEntryCriteria && (caseListMap.get(c.Case_Timezone__r.TimeZoneSidKey__c) != null || caseListMap.get(c.Case_Timezone__r.TimeZoneSidKey__c) != ''))
            
            {   
               // if (caseListMap.get(c.Case_Timezone__r.TimeZoneSidKey__c) != null || caseListMap.get(c.Case_Timezone__r.TimeZoneSidKey__c) != '')
                    //   {
                    
                    if (c.Entitlement.SlaProcess.Name != null && c.Entitlement.SlaProcess.Name == 'Mission Critical' || c.Entitlement.SlaProcess.Name == 'Mission Critical (GCS Management Override)')
                           c.BusinessHoursId = caseListMap.get(c.Case_Timezone__r.TimeZoneSidKey__c);
                       
                    else if (c.Entitlement.SlaProcess.Name != null && c.Entitlement.SlaProcess.Name == 'Enterprise' || c.Entitlement.SlaProcess.Name == 'Enterprise (GCS Management Override)')
                        c.BusinessHoursId = caseListMap.get(c.Case_Timezone__r.TimeZoneSidKey__c);
                    
                    else if (c.Entitlement.SlaProcess.Name != null && c.Entitlement.SlaProcess.Name == 'Standard')
                        c.BusinessHoursId = caseListMap.get(c.Case_Timezone__r.TimeZoneSidKey__c);
                       
                       // }
For a given record, how could I go about getting all the fields in that object (schema describe?) and back up field specific data for a record. The use case would be, if I deleted a record, could I backup all fields and associated values into a text file or something? Would want it to be scalable so that if I added a new field, I wouldn't have to modify the code everytime.
Hi...
global class AAAA implements System.Schedulable {
global String str{get;set;}
global String mail{get;set;}
global String nomJob{get;set;}
global String inputText{get;set;}
global String heure{get;set;}
global String minute{get;set;}
global String jourMois{get;set;}
global String mois{get;set;}
global String jourSemaine{get;set;}

global void execute(SchedulableContext sc) {
  newPublier();
}

global AAAA () {

}

global AAAA (String mail, String inputText, String heure, String minute, String jourMois, String mois, String jourSemaine) {
this.mail= mail;
this.inputText = inputText;
this.heure= heure;
this.minute= minute;
this.jourMois= jourMois;
this.mois= mois;
this.jourSemaine= jourSemaine;
}

public void setMail(String mail) {
    this.mail= mail;
}

public String getMail() {
    return mail;
}

public void setRequete(String inputText) {
    this.inputText= inputText;
}

public String getRequete() {
    return inputText;
}

public void setHeure(String heure) {
    this.heure= heure;
}

public String getHeure() {
    return heure;
}

public void setMinute(String minute) {
    this.minute= minute;
}

public String getMinute() {
    return minute;
}

public void setJourMois(String jourMois) {
    this.jourMois= jourMois;
}

public String getJourMois() {
    return jourMois;
}

public void setMois(String mois) {
    this.mois= mois;
}

public String getMois() {
    return mois;
}

public void setJourSemaine(String jourSemaine) {
    this.jourSemaine= jourSemaine;
}

public String getJourSemaine() {
    return jourSemaine;
}


public void schedulejob(){
        String aaa = getMail();
        String req = getRequete();
        String heu = getHeure();
        String min = getMinute();
        String jMois = getJourMois();
        String leMois = getMois();
        String jSemaine = getJourSemaine();
                
        String NomJobSchedulable = nomJob;
        AAAA p = new AAAA (aaa, req, heu, min, jMois, leMois,jSemaine);
        String sch = '0'+' '+min+' '+heu+' '+jMois+' '+leMois+' '+jSemaine;
 
        system.schedule(NomJobSchedulable , sch, p);   
}

public void newPublier(){

    String query=inputText;
    String premier=query.substringAfter('select ');   
    premier=  premier.substringBefore('from');
      
    string titre= premier+'\n';
    string contenuCSV = titre;

    string queryResultatString = '';

    list<sObject> queryResultat = (List<sObject>)database.query(inputText);
    for(sObject a: queryResultat)
    {

        queryResultatString = queryResultatString + string.valueof(a);
        
    }
    System.debug('Query result string:'+queryResultatString);

    list<string> queryLignes = queryResultatString.split('}');

    for(string s:queryLignes){
        list<string> queryColonnes = s.split(',');
        for(string st:queryColonnes){
            contenuCSV = contenuCSV + st.substringAfter('=') + ',';
        }

        contenuCSV = contenuCSV.substringBeforeLast(',').substringBeforeLast(',') + '\n';
    }

    String lignes = contenuCSV;
    List<String> parts = lignes.split('\n');
    integer lineNumber = queryResultat.size();

    integer nbLignesPJ = 1000;
    integer compterParties=0;

    for(integer i=0;i<lineNumber;i++){

      string fichierParties = parts[0] + '\n';

      if(math.mod(i,nbLignesPJ)<>0) continue;
      if((lineNumber-i)<nbLignesPJ){

        for(integer j=1;j<=(lineNumber-i);j++){
            fichierParties = fichierParties + parts[i+j] + '\n';
        }
      }
      if((lineNumber-i)>=nbLignesPJ){
         for(integer j=1;j<=nbLignesPJ;j++){
            fichierParties = fichierParties + parts[i+j] + '\n';
        }
      }
      //Envoyer le Mail
      Messaging.EmailFileAttachment csvPJ = new Messaging.EmailFileAttachment();
      blob csvBlob = Blob.valueOf(fichierParties);
      string csvNom = 'cases_fermes_'+Date.today().format()+'.csv';
      csvPJ.setFileName(csvNom);
      csvPJ.setBody(csvBlob);
      Messaging.SingleEmailMessage email =new Messaging.SingleEmailMessage();
      String[] adressMail = new list<string> {mail};
      compterParties++;
      String subject;
          subject = 'CSV - '+Date.today().format();
      email.setSubject(subject);
      email.setToAddresses(adressMail);
      email.setPlainTextBody('message');   
      email.setFileAttachments(new Messaging.EmailFileAttachment[]{csvPJ});
      Messaging.SendEmailResult [] envoyer = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email});
    }
  }   
}



Someone give me the sample example of a test class to my class.
I want to publish my application but I do not know to do a test class.

rigger vig2 on join_object__c (after insert)
{
list<join_object__c> jcnewlist=new list<join_object__c>();
for(join_object__c jc:trigger.new)
{
  list<join_object__c> jclist=[select id,name,Account__r.name from join_object__c];
   jc.billing_adress__c=jc.Account__r.name;
   jcnewlist.add(jc);


error


Record is read-only: Trigger.vig2: line 7, column 1
I can create a trigger to update the field value from my custom object after an update of the PreviousFireTime field into CronTrigger?
How can I do this?

Thank you