-2

I have this construction: enter image description here

If we create a Factory 2 with InDateTime__c = OutDateTime__c of the Tool 1 with the same Opportunity 1 (with another Factory 1 with the same Opportunity 1 relationship), this Tool 1 will get Parts__c from the Factory 2.

Sometimes it works with Parts__c field and sometimes not. I don't know where is the problem. Can you help me please?

Helper:

public static void updateTool(List<Factory__c> createFactoryTrigger){
    Map<Id, Tool__c> mapToConnect = new Map<Id, Tool__c>();
    List<Tool__c> listToUpsert = new List<Tool__c>();
    List<Tool__c> actualTools = [SELECT OutDateTime__c, Factory__r.Opportunity__c, Parts__c FROM Tool__c
                                WHERE OutDateTime__c >= : DateTime.now()];

    for(Tool__c tool : actualTools){
        mapToConnect.put(tool.Factory__r.Opportunity__c, tool);
    }

    for(Factory__c factory : createFactoryTrigger){
        Id opportunityId = factory.Opportunity__c;

        DateTime toolDT = mapToConnect.get(opportunityId).OutDateTime__c;
        Date toolD = date.newinstance(toolDT.year(), toolDT.month(), toolDT.day());
        DateTime factoryDT = factory.InDateTime__c;
        Date factoryD = date.newinstance(factoryDT.year(), factoryDT.month(), factoryDT.day());

        if(mapToConnect.containsKey(opportunityId) && toolD == factoryD && factory.Count__c > 0){ 
            mapToConnect.get(opportunityId).Parts__c = String.valueOf(factory.Count__c) + ' parts';
            listToUpsert.add(mapToConnect.get(opportunityId));
        }
    }
    upsert listToUpsert Id;
}

Trigger:

trigger ToolsTrigger on Factory__c (after insert) { 
    if(Trigger.isAfter && Trigger.isInsert) {
        triggerHelper.updateTool(Trigger.new);
    }
}
2

There are actually multiple problems in code.

  1. Below query is returning all tools after now and not specific to opportunities which are in trigger context of factory. Its a big performance problem.

    SELECT OutDateTime__c, Factory__r.Opportunity__c, Parts__c FROM Tool__c
                                 WHERE OutDateTime__c >= : DateTime.now()
    
  2. If there are multiple tools under opportunity you are referring to only 1 tool for given opportunity. (because it will be replacing previous tool for same opp)

    for(Tool__c tool : actualTools){
        mapToConnect.put(tool.Factory__r.Opportunity__c, tool);
    }
    

There is 1 tool per factory but multiple factories per opportunity. This means there will be multiple tools per opportunity.

  1. Because of above point, you are comparing only 1 tool under opportunity with factory.

  2. You said in question you want to compare datetime but you are comparing only dates.

    toolD == factoryD
    

Try below method:

Here, we are constructing mapToConnect by using both opp id and date as keys.

public static void updateTool(List<Factory__c> createFactoryTrigger){
    Map<Id, Factory__c> newFactoriesMap = (Map<Id, Factory__c>)Trigger.newMap;
    Set<Id> oppIds = new Set<Id>();
    Map<Id, Map<Date,Tool__c>> mapToConnect = new Map<Id, Map<Date,Tool__c>>();
    List<Tool__c> listToUpsert = new List<Tool__c>();

    for(Factory__c factory : createFactoryTrigger){
        oppIds.add(factory.Opportunity__c);
    }

    List<Tool__c> actualTools = [SELECT OutDateTime__c, Factory__r.Opportunity__c, Parts__c FROM Tool__c
                                 WHERE Factory__r.Opportunity__c = :oppIds];

    for(Tool__c tool : actualTools){
        if(!mapToConnect.containsKey(tool.Factory__r.Opportunity__c))
            mapToConnect.put(tool.Factory__r.Opportunity__c, new Map<Date,Tool__c>());

        Date toolDate = date.newinstance(tool.OutDateTime__c.year(), tool.OutDateTime__c.month(), tool.OutDateTime__c.day());
        mapToConnect.get(tool.Factory__r.Opportunity__c).put(toolDate,tool);
    }

    for(Factory__c factory : createFactoryTrigger){
        if(mapToConnect.containsKey(factory.Opportunity__c) && 
           mapToConnect.get(factory.Opportunity__c).containsKey(factory.InDateTime__c) && 
           factory.Count__c > 0) 
        {
            mapToConnect.get(factory.Opportunity__c).get(factory.InDateTime__c).Parts__c = String.valueOf(factory.Count__c) + ' parts';
            listToUpsert.add(mapToConnect.get(factory.Opportunity__c).get(factory.InDateTime__c));
        }
    }
    upsert listToUpsert Id;
}

PS: There might be typos in code. As I dont have these objects, I cannot compile this method. But it gives overall idea how to handle multiple tools and how to construct mapToConnect.

  • No, I want to compare date from datetime. No, it is not multiple (each Factory has only 1 Tool). And I really didn't understand about now. Can you tell me, please, how can I fix my problem? – MichaelLev19 Jul 31 at 8:41
  • From your design its clear that there might be multiple factories under each opportunity (although 1 tool for a factory). So it makes multiple tools for opportunity – salesforce-sas Jul 31 at 8:49
  • It can be multiple factories under each opportunity. But each Factory has only 1 tool. Always. It's an inside rule. – MichaelLev19 Jul 31 at 8:59
  • added in point-2 and also suggested method. There might be typos in code (Since I dont have those objects, I cant compile it) – salesforce-sas Jul 31 at 9:12
  • Thank you. But where do we use newFactoriesMap? And I also got here if(!mapToConnect.containsKey(tool.Factory__r.Opportunity__c)) mapToConnect.put(tool.Factory__r.Opportunity__c, new Map<Date,Tool__c>); Unexpected token ')'. Hmmm. – MichaelLev19 Jul 31 at 10:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.