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
Soledad AngelSoledad Angel 

make documents required for opportunities

Hello all,

there is a trigger and validation rule in my org that forces users to add Contact Roles after certain stage of the opp. How can I modify the trigger (below) to force them adding documents?


_________________________________

Custom field> checkbox> "Primary Contact Assigned"

Custom field> number> "Number of Contacts Roles Assigned"

Triger>
trigger updatecontactrolecount on Opportunity (before insert, before update)
{

Boolean isPrimary;
Integer iCount;

Map<String, Opportunity> oppty_con = new Map<String, Opportunity>();//check if the contact role is needed and add it to the oppty_con map
for (Integer i = 0; i < Trigger.new.size(); i++) 
{
        oppty_con.put(Trigger.new[i].id,
        Trigger.new[i]);      
}
isPrimary = False; 
for (List<OpportunityContactRole> oppcntctrle :[select OpportunityId from OpportunityContactRole where (OpportunityContactRole.IsPrimary = True and OpportunityContactRole.OpportunityId in :oppty_con.keySet())])
{
 if (oppcntctrle .Size() >0)
 {
 isPrimary = True;     
 }
}
iCount = 0;
for (List<OpportunityContactRole> oppcntctrle2 : [select OpportunityId from OpportunityContactRole where (OpportunityContactRole.OpportunityId in :oppty_con.keySet())])//Query for Contact Roles
{    
 if (oppcntctrle2 .Size()>0)
 {
 iCount= oppcntctrle2 .Size();     
 }
}
for (Opportunity Oppty : system.trigger.new) //Check if  roles exist in the map or contact role isn't required 
{
Oppty.Number_of_Contacts_Roles_Assigned__c = iCount;
Oppty.Primary_Contact_Assigned__c =isPrimary; 
}
}
Best Answer chosen by Soledad Angel
LBKLBK
If you still want to keep it as a separate trigger, here is the code.
 
trigger countoppfiles on Opportunity (before insert, before update)
 {
    Map<Id, Integer> mapFileCount = new Map<Id, Integer>();
    SET<Id> keys = trigger.newMap.keyset();
    List<ContentDocumentLink> lstFiles = [SELECT ContentDocumentId,Id,LinkedEntityId FROM ContentDocumentLink WHERE LinkedEntityId IN :keys];

    for (ContentDocumentLink objFile : lstFiles)//Query for Files
    {    
        Integer iCountFiles = 0;
         if (mapFileCount.containsKey(objFile.LinkedEntityId)) {
            iCountFiles = mapFileCount.get(objFile.LinkedEntityId);
         }
         mapFileCount.put(objFile.LinkedEntityId, iCountFiles + 1);
    }

    for (Opportunity Oppty : system.trigger.new) //Reset the file count
    {
        Oppty.Number_of_Files__c = mapFileCount.get(Oppty.Id);
    }
}

 

All Answers

LBKLBK
Hi Angel,

By documents, did you mean Notes & attachments?

 
Soledad AngelSoledad Angel
LBK,

actually, we use the related list: Files.

User-added image
LBKLBK
I need the structure of the Files object and it's relationship with Opportunity to determine the changes needed in the Trigger.

Can you please provide the API Names of the Object and all the fields in it?
 
Soledad AngelSoledad Angel
LBK,

I am not sure where to get the info in this case, but I can immediately tell you that is a standard option for, at least, accounts and opportunities. It is not a custom object we created. 
LBKLBK
hi Angel,

Your answer lies in ContentDocumentLink object.

Here is the code you can add to your trigger for updating the files count.
 
Map<Id, Integer> mapFileCount = new Map<Id, Integer>();
List<ContentDocumentLink> lstFiles : [SELECT ContentDocumentId,Id,LinkedEntityId FROM ContentDocumentLink WHERE LinkedEntityId IN :oppty_con.keySet())];
for (ContentDocumentLink objFile : lstFiles)//Query for Files
{    
	Integer iCountFiles = 0;
	 if (mapFileCount.containsKey(objFile.LinkedEntityId)) {
		iCountFiles = mapFileCount.get(objFile.LinkedEntityId);
	 }
	 mapFileCount.put(objFile.LinkedEntityId, iCountFiles + 1);
}

for (Opportunity Oppty : system.trigger.new) //Reset the file count
{
	Oppty.Number_of_Files__c = mapFileCount.get(Oppty.Id);
}
Please check for syntactical errors, because I have assumed the field name for file count to be Number_of_Files__c.

Let me know if this helps.
Soledad AngelSoledad Angel
LBK,

I am getting an error: 
"Error: Compile Error: unexpected token: ':' at line 3 column 35"
LBKLBK
Can you post your new code now?

I am not able to understand what is in line 3.
Soledad AngelSoledad Angel
Error: Compile Error: unexpected token: ':' at line 3 column 35


trigger countoppfiles on Opportunity (before insert, before update)
{Map<Id, Integer> mapFileCount = new Map<Id, Integer>();
List<ContentDocumentLink> lstFiles : [SELECT ContentDocumentId,Id,LinkedEntityId FROM ContentDocumentLink WHERE LinkedEntityId IN :oppty_con.keySet())];
for (ContentDocumentLink objFile : lstFiles)//Query for Files
{    
    Integer iCountFiles = 0;
     if (mapFileCount.containsKey(objFile.LinkedEntityId)) {
        iCountFiles = mapFileCount.get(objFile.LinkedEntityId);
     }
     mapFileCount.put(objFile.LinkedEntityId, iCountFiles + 1);
}

for (Opportunity Oppty : system.trigger.new) //Reset the file count
{
    Oppty.Number_of_Files__c = mapFileCount.get(Oppty.Id);
}
}
LBKLBK
Try this code instead.
 
Map<Id, Integer> mapFileCount = new Map<Id, Integer>();
	SET<String> keys = oppty_con.keyset();
	List<ContentDocumentLink> lstFiles = [SELECT ContentDocumentId,Id,LinkedEntityId FROM ContentDocumentLink WHERE LinkedEntityId IN :keys];

	for (ContentDocumentLink objFile : lstFiles)//Query for Files
	{    
		Integer iCountFiles = 0;
		 if (mapFileCount.containsKey(objFile.LinkedEntityId)) {
			iCountFiles = mapFileCount.get(objFile.LinkedEntityId);
		 }
		 mapFileCount.put(objFile.LinkedEntityId, iCountFiles + 1);
	}

	for (Opportunity Oppty : system.trigger.new) //Reset the file count
	{
		Oppty.Number_of_Files__c = mapFileCount.get(Oppty.Id);
	}
I have just changed the second and third lines of the code.
 
LBKLBK
By the way, I strongly recommend that you merge this code into the existing trigger rather than writing a separate trigger for File Count alone.
Soledad AngelSoledad Angel
Error: Compile Error: Variable does not exist: oppty_con at line 4 column 24

trigger countoppfiles on Opportunity (before insert, before update)
 {
Map<Id, Integer> mapFileCount = new Map<Id, Integer>();
    SET<String> keys = oppty_con.keyset();
    List<ContentDocumentLink> lstFiles = [SELECT ContentDocumentId,Id,LinkedEntityId FROM ContentDocumentLink WHERE LinkedEntityId IN :keys];

    for (ContentDocumentLink objFile : lstFiles)//Query for Files
    {    
        Integer iCountFiles = 0;
         if (mapFileCount.containsKey(objFile.LinkedEntityId)) {
            iCountFiles = mapFileCount.get(objFile.LinkedEntityId);
         }
         mapFileCount.put(objFile.LinkedEntityId, iCountFiles + 1);
    }

    for (Opportunity Oppty : system.trigger.new) //Reset the file count
    {
        Oppty.Number_of_Files__c = mapFileCount.get(Oppty.Id);
    }
}
LBKLBK
That is because you are creating it as a separate trigger. I have made use of the oppty_con map from your existing trigger (the original code you have posted in your question). Can you make it as part of the existing trigger itself? You can add this code just before the last } symbol in your code.
LBKLBK
If you still want to keep it as a separate trigger, here is the code.
 
trigger countoppfiles on Opportunity (before insert, before update)
 {
    Map<Id, Integer> mapFileCount = new Map<Id, Integer>();
    SET<Id> keys = trigger.newMap.keyset();
    List<ContentDocumentLink> lstFiles = [SELECT ContentDocumentId,Id,LinkedEntityId FROM ContentDocumentLink WHERE LinkedEntityId IN :keys];

    for (ContentDocumentLink objFile : lstFiles)//Query for Files
    {    
        Integer iCountFiles = 0;
         if (mapFileCount.containsKey(objFile.LinkedEntityId)) {
            iCountFiles = mapFileCount.get(objFile.LinkedEntityId);
         }
         mapFileCount.put(objFile.LinkedEntityId, iCountFiles + 1);
    }

    for (Opportunity Oppty : system.trigger.new) //Reset the file count
    {
        Oppty.Number_of_Files__c = mapFileCount.get(Oppty.Id);
    }
}

 
This was selected as the best answer
Soledad AngelSoledad Angel
LBK,

Unfortunately, it is not working. For some reason it breaks my other trigger whether I keep it together or separate. Plus, it is not actually updating the Number_of_Files__c fields, I always see it blank whether I add documents or not, or apply a validation rule or not. It does not trigger errors, but it is not working as intended.
LBKLBK
Can you try to disable the other triggers and have only this trigger?

You are trying to populate this field on update of Opportunity itself. And, there is a validation rule on opportunity that is stopping you from saving it if this field is empty. I guess it could be a Catch 22 situation.

Try to disable the other trigger and validation rule and try this again.
Soledad AngelSoledad Angel
Yep, works like a charm. You rocked! thanks so much!