-2
public void addVisibilite() {
    Map<Id, List<Id>> accountContactRelationIdsMap = new Map<Id, List<Id>>();

    for (AccountContactRelation accountContactRelation : (List<AccountContactRelation>) Trigger.new) {
        String oldRoles = (Trigger.isUpdate) ? ((AccountContactRelation) Trigger.oldMap.get(accountContactRelation.Id)).Roles : null;

        if (accountContactRelation.Roles != null && accountContactRelation.Roles.contains(labelVisibilitePortail) && (Trigger.isInsert ||
                (Trigger.isUpdate && (oldRoles == null || !oldRoles.contains(labelVisibilitePortail))))) {
            if (!accountContactRelationIdsMap.containsKey(accountContactRelation.AccountId)) {
                accountContactRelationIdsMap.put(accountContactRelation.AccountId, new List<Id>());
            }
            accountContactRelationIdsMap.get(accountContactRelation.AccountId).add(accountContactRelation.ContactId);
        }
    }
     
    Set<Id> setIds = accountContactRelationIdsMap.keySet();
     Database.executeBatch(new toInsertOrderBillPriceShares_Batch('SELECT Id, FAB_AccountBill__c, FAB_AccountOrder__c FROM FAB_Order_Bill_Price__c WHERE FAB_AccountOrder__c IN : setIds OR FAB_AccountBill__c IN : setIds'));

And here's my batch ;

public toInsertOrderBillPriceShares_Batch(List<AccountContactRelation> oldRelations, List<AccountContactRelation> relations ) { 
        for (AccountContactRelation accountContactRelation : relations) {
        String oldRoles = (Trigger.isUpdate) ? ((AccountContactRelation) Trigger.oldMap.get(accountContactRelation.Id)).Roles : null;

        if (accountContactRelation.Roles != null && accountContactRelation.Roles.contains(labelVisibilitePortail) && (Trigger.isInsert ||
                (Trigger.isUpdate && (oldRoles == null || !oldRoles.contains(labelVisibilitePortail))))) {
            if (!accountContactRelationIdsMap.containsKey(accountContactRelation.AccountId)) {
                accountContactRelationIdsMap.put(accountContactRelation.AccountId, new List<Id>());
            }
            accountContactRelationIdsMap.get(accountContactRelation.AccountId).add(accountContactRelation.ContactId);
        }
    }
     System.debug('Firaaas Account contact relation'+accountContactRelationIdsMap); 
    }
       

global Database.QueryLocator start(Database.BatchableContext BC) {
   return Database.getQueryLocator([
    SELECT Id, FAB_AccountBill__c, FAB_AccountOrder__c 
    FROM FAB_Order_Bill_Price__c 
    WHERE FAB_AccountOrder__c IN : accountContactRelationIdsMap.keyset() OR FAB_AccountBill__c IN : accountContactRelationIdsMap.keyset()    
]);
   

Execute batch :

Database.executeBatch(new toInsertOrderBillPriceShares_Batch(Trigger.old, Trigger.new)); 

My batch doesn't work preperly , don't know where the problem in my code Maybe i need to change decalaration of Old roles String oldRoles = (Trigger.isUpdate) ? ((AccountContactRelation) Trigger.oldMap.get(accountContactRelation.Id)).Roles : null; ?

3
  • 1
    No more cosmetic edits and rollbacks. Enough is enough.
    – David Reed
    Commented Mar 23, 2021 at 14:45
  • I am unlocking this question by request to allow it to be improved. I would encourage returning to the original form of this question, which is answered below, and making one round of changes to improve it as much as possible. If this question continues to receive high volumes of cosmetic edits or rollbacks, it will be locked again.
    – David Reed
    Commented Jun 22, 2021 at 22:13
  • I have locked this question again based on irrelevant edits that do not improve the question, as well as other rule-breaking material.
    – David Reed
    Commented Dec 28, 2022 at 16:33

1 Answer 1

3

In this situation, don't. Pass the set of Ids into your batch class's constructor and store it in an instance variable:

public class toInsertOrderBillPriceShares_Batch implements Database.Batchable<sObject> {
    private Set<Id> setIds;

    public toInsertOrderBillPriceShares_Batch(Set<Id> setIds) {
        this.setIds = setIds;
    }

Then, write a non-dynamic query that uses an Apex bind (:) to reference the stored set.

public Database.QueryLocator start(Database.BatchableContext BC) { 
    return Database.getQueryLocator([
        SELECT Id, FAB_AccountBill__c, FAB_AccountOrder__c 
        FROM FAB_Order_Bill_Price__c 
        WHERE FAB_AccountOrder__c IN : setIds OR FAB_AccountBill__c IN : setIds    
    ]);
}

Apex binds in query strings are evaluated at query time. The variables referenced must be in scope when the query is executed, which is not the case here since the variable is only in scope in the method calling the batch. If you store setIds within the batch class so that it is in scope, the dynamic query will work, but you do not need to use a dynamic query here.

Note that none of this should be global unless you are building a managed package and know exactly what you're doing.

1
  • 2
    I've removed a lengthy off-topic comment thread and will reiterate that all discussion regarding SFSE's question format and any blocks applied by the system must take place on meta.salesforce.stackexchange.com. Material about these policies is located in the Help Center.
    – David Reed
    Commented Nov 16, 2020 at 21:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .