function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Sandy ShawSandy Shaw 

Incompatible types: Asset, OpportunityLineItem

Hi,
I am writing a cross object trigger. 
This is my first map: Map<Id,List<Asset>> acc_asset_map = new Map<Id,List<Asset>>();
    for(Id k:account_id){
        List<Asset> asset = new List<Asset>();
        asset = [SELECT Product2Id FROM Asset WHERE AccountId = :k];
        acc_asset_map.put(k,asset);
    }

And this is the second map:      Map<Id,List<OpportunityLineItem>> opp_prod_map = new Map<Id,List<OpportunityLineItem>>();
     for (Id i:opp_id){
         List<OpportunityLineItem> oppLineItem = new List<OpportunityLineItem>();
         oppLineItem = [SELECT Product2Id FROM OpportunityLineItem WHERE OpportunityId = :i];
         opp_prod_map.put(i,oppLineItem);
     }
I want to compare the value of my two maps. So I have a for loop go trough a list of all my AccountId. Then I get all the OpportunityId under each AccountId. With each OpportunityId, I want to check if there is any same Product2Id under my Opportunity and my Asset. Though both of the value I put in my map are 'Product2Id', they are get from different Object types. One is from Asset, and the other is from OpportunityLineItem. 
So am I on the reight direction if I want to check whether the account asset and the opporutnity under that account have the same product?
If so, is there anyway to fix this bug?
Thanks in advance!
Best Answer chosen by Sandy Shaw
rajat Maheshwari 6rajat Maheshwari 6

Hi Sandy,

Below is code snippet which will work for you :) Please let me know in case of any issue.

Map<Id,List<Asset>> acc_asset_map = new Map<Id,List<Asset>>();
Map<Id,List<OpportunityLineItem>> opp_prod_map = new Map<Id,List<OpportunityLineItem>>();


	for(Asset ast: [SELECT Product2Id, AccountId FROM Asset WHERE AccountId IN: account_Id])
{
    if(acc_asset_map!=null && acc_asset_map.containsKey(ast.Product2Id))
        {
            List<asset> asset_List = acc_asset_map.get(ast.Product2Id);
            asset_List.add(ast);
            acc_asset_map.put(ast.Product2Id,asset_List);
        }
    else
       acc_asset_map.put(ast.Product2Id,new List<Asset>{ast});
		
}


	for(OpportunityLineItem oli: [SELECT Product2Id, OpportunityId FROM OpportunityLineItem WHERE OpportunityId IN (Select Id from Opportunity where AccountId IN:account_Id)])
{
      if(opp_prod_map!=null && opp_prod_map.containsKey(oli.OpportunityId))
         {
             List<OpportunityLineItem> oppLineItem_Recd = opp_prod_map.get(oli.Product2Id);

oppLineItem_Recd.add(oli);
opp_prod_map.put(oli.Product2Id,oppLineItem_Recd);
          }
        else
           opp_prod_map.put(oli.Product2Id,new List<OpportunityLineItem>{oli});

}
	
	for(Id prodId : acc_asset_map.keyset())
           {
		if(opp_prod_map!=null && opp_prod_map.containsKey(prodId))
                     {
                          for(OpportunityLineItem oppLine_Recd : opp_prod_map.get(prodId))
                             {
                                  // do logic on basis of matching product id
                              }
                     }
                 else
                    // do logic on basis of unmatching record
           }

Thanks
     Rajat Maheshwari
     rajatzmaheshwari@gmail.com

All Answers

Tarun J.Tarun J.
Hello Sandy,

First thing I would like to say is, you should avoid using SOQL query in FOR LOOP. Above code is using 2 SOQL query in FOR LOOP.

Regarding code, per my understanding, you want to check whether Asset and OpportunityLineItem contains the same product or not. As both objects have Product2Id, if it points to same product, it will return same value. 

Here is the sample code which might help you. I have added few comments, you make changes as per your requirement:
 
//Create a List to store accountId and opportunity Id (opp_Id) in separate FOR LOOP.
	
	Map<Id,List<Asset>> acc_asset_map = new Map<Id,List<Asset>>();
	for(Asset ast: [SELECT Product2Id, AccountId FROM Asset WHERE AccountId IN: accountId]){
		acc_asset_map.put(ast.Product2Id, ast);             //Map of Product Id and Asset
	}
	
	Map<Id,List<OpportunityLineItem>> opp_prod_map = new Map<Id,List<OpportunityLineItem>>();
	for(OpportunityLineItem oli: [SELECT Product2Id, OpportunityId FROM OpportunityLineItem WHERE OpportunityId IN: opp_Id]){
		opp_prod_map.put(oli.Product2Id, oli);                //Map of Product Id and OpportunityLineItem
	}
	
	//HERE both map key contains ProductId. You can run FOR LOOP and compare
	for(Id prodId: acc_asset_map.keySet()){
		Boolean matchProd = opp_prod_map.containsKey(prodId);
		
		//If 'matchProd' is TRUE, means OpportunityLineItem contains the same product as Asset.
		
	}

-Thanks,
TK

Did this answer your question? If not, let me know what didn't work, or if so, please mark it solved.
rajat Maheshwari 6rajat Maheshwari 6

Hi Sandy,

Below is code snippet which will work for you :) Please let me know in case of any issue.

Map<Id,List<Asset>> acc_asset_map = new Map<Id,List<Asset>>();
Map<Id,List<OpportunityLineItem>> opp_prod_map = new Map<Id,List<OpportunityLineItem>>();


	for(Asset ast: [SELECT Product2Id, AccountId FROM Asset WHERE AccountId IN: account_Id])
{
    if(acc_asset_map!=null && acc_asset_map.containsKey(ast.Product2Id))
        {
            List<asset> asset_List = acc_asset_map.get(ast.Product2Id);
            asset_List.add(ast);
            acc_asset_map.put(ast.Product2Id,asset_List);
        }
    else
       acc_asset_map.put(ast.Product2Id,new List<Asset>{ast});
		
}


	for(OpportunityLineItem oli: [SELECT Product2Id, OpportunityId FROM OpportunityLineItem WHERE OpportunityId IN (Select Id from Opportunity where AccountId IN:account_Id)])
{
      if(opp_prod_map!=null && opp_prod_map.containsKey(oli.OpportunityId))
         {
             List<OpportunityLineItem> oppLineItem_Recd = opp_prod_map.get(oli.Product2Id);

oppLineItem_Recd.add(oli);
opp_prod_map.put(oli.Product2Id,oppLineItem_Recd);
          }
        else
           opp_prod_map.put(oli.Product2Id,new List<OpportunityLineItem>{oli});

}
	
	for(Id prodId : acc_asset_map.keyset())
           {
		if(opp_prod_map!=null && opp_prod_map.containsKey(prodId))
                     {
                          for(OpportunityLineItem oppLine_Recd : opp_prod_map.get(prodId))
                             {
                                  // do logic on basis of matching product id
                              }
                     }
                 else
                    // do logic on basis of unmatching record
           }

Thanks
     Rajat Maheshwari
     rajatzmaheshwari@gmail.com
This was selected as the best answer
Tarun J.Tarun J.
Hey Rajat,

Thanks for correcting the code. I missed that it is a Map of List. :)

-Thanks,
TK
rajat Maheshwari 6rajat Maheshwari 6

Hi Tarun,

I understand :) No worry

Thanks
Rajat Maheshwari
rajatzmaheshwari@gmail.com

Sandy ShawSandy Shaw
Hi Rajat,

Thanks for the code snipet. But I have a question, for the opp_prod_map, every time I only put the (oli.Product2Id, oppLineItem_Recd) into the map, where the Product2Id is the key and the list is the value. Then how could "opp_prod_map.containsKey(oli.OpportunityId)" check whether this opportunitylineItem has been visited or not.