You need to sign in to do that
Don't have an account?
cambart14
Insert Record then Update Current Record
We have a product specification form (Product_Brief__c) that once saves needs to insert a Project. Once that Project is inserted, I need to take the Project ID and update the Product Brief with that ID.
The code below works properly to create a Project. When I try and use that Project ID to update the Product Brief (last two lines of code) it gives me this error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY.
Any help here would be much appreciated!
The code below works properly to create a Project. When I try and use that Project ID to update the Product Brief (last two lines of code) it gives me this error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY.
Any help here would be much appreciated!
trigger ProjectCreation on Product_Brief__c (after insert, after update) { Product_Brief__c pb = [SELECT ID, Opportunity__r.ID, Opportunity__r.Owner.ID, Select_Product__c, Related_Project__c FROM Product_Brief__c WHERE ID =: trigger.new]; Project__c p = new Project__c(); p.RecordTypeID = '012W00000008nXT'; p.Related_Opportunity__c = pb.Opportunity__r.ID; p.Sales_Rep__c = pb.Opportunity__r.Owner.ID; p.Project_Description__c = pb.Select_Product__c; p.Project_Category__c = 'Bags and Tubing Sets'; p.Status__c = 'Active'; p.Start_Date_and_Time__c = System.Now(); insert p; pb.Related_Project__c = p.ID; update pb; }
Trigger: Class:
All Answers
2. Call it and pass the Product Brief and Project Ids as arguments to that method.
3. Update the record in that future method.
4. Add a check in your trigger to skip the logic if context is future [If (System.isFuture() == true)].
Please try with below code and replace YourRecordTypeName with original recordtype name which you want to assign because we should not use hard code Id .
Let me know any issue .
if(Static flag==true){
Set static flag to =false
update object;
}
Dear Cambart,
If you need to update the same object record the ways possible are
1. Time based workflow
2. Future method
Future method is used as per the following approach.
Donot forget to select best answer to make our efforts visible in the developer forum.
Please mark this as solution by selecting it as best answer if this solves your problem, So that if anyone has this issue this post can help
@Mudasir Wani I was able to successfully create the two apex class. When trying to save the trigger you have indicated I run into this error below. Is this because it is trying to pass an ID into a List? Any insight you have would be appreciated.
Error: Compile Error: Method does not exist or incorrect signature: ProductBriefHandler.createProject(List<Product_Brief__c>) at line 4 column 5
public Static void createProject(List<Product_Brief__c> productBrief){
Just use this in your trigger -
ProductBriefFutureHandler.createProject(Trigger.newMap.keyset());
I now have the trigger and two classes created. When I create a new Product Brief, not project is created. I'm not getting any error message or anything else. Below is the full code.
Trigger: Class: Class
1. Projects are not being inserted (this needs to be added).
2. Project Id is not being set on Product Brief but rather on Project itself (this needs to be replaced with correct code).
Trigger: Class:
---------------------------------------------------------------------
public class ProductBriefFutureHandler {
@future
public static void createProject(Set<Id> pbIds){
List<Product_Brief__c> pbList = new List<Product_Brief__c>(); //this will hold the inserted or updated records
Map<Id, Project__c> pbVsProjects = new Map<Id, Project__c>(); //this will help us map Projects to their Products
//query the products
pbList = [SELECT ID, Opportunity__r.ID, Opportunity__r.Owner.ID Select_BPC_Product_ASI__c, Related_Project__c FROM Product_Brief__c WHERE ID IN :pbIds];
//iterate over each product and create a corresponding project
for(Product_Brief__c pb : pbList){
Project__c proj = new Project__c();
proj.RecordTypeID = Project__c.sObjectType.getDescribe().getRecordTypeInfosByName().get('ASI').getRecordTypeId();
proj.Related_Opportunity__c = pb.Opportunity__r.ID;
proj.Sales_Rep__c = pb.Opportunity__r.Owner.ID;
proj.Project_Description__c = pb.Select_BPC_Product_ASI__c;
proj.Project_Category__c = 'ASI Bags and Tubing Sets';
proj.Status__c = 'Active';
proj.Start_Date_and_Time__c = System.Now();
pbVsProjects.put(pb.Id, proj); //put the product and associated project in the map
}
insert pbVsProjects.values(); //insert the projects, after insertion Id field would be populated in the inserted list
//iterate over each product again to map to correct project
for(Product_Brief__c pb : pbList) {
pb.Related_Project__c = pbVsProjects.get(pb.Id).Id; //get() shall give us the correct Project and then we need to traverse to Id
}
update pbList; //update the products
}
}
------------------------------------------------------------------------------------------
Please go through the comments to understand why its so. Forgive me for using Product instead of Product Brief.
I see the following challenges in this approach now -
1. The update on Product Briefs in last statement of the future method would trigger the trigger again (since its on After Update event as well).
Solution would be the below change in trigger -
---------------------------------------------------------------------
trigger ASIProjectCreation on Product_Brief__c (after insert, after update) {
//skip the snippet below if context is Future i.e. trigger has been called from a transaction executing within a Future method
if(!System.isFuture()){
ProductBriefFutureHandler.createProject(Trigger.newMap.keySet());
}
}
-----------------------------------------------------------------------
We do not need the ProductBriefHandler class anymore, you may want to delete that.
--------------------------------------------------------------------------------------------------------------------------------------
Everything should work fine now except following -
1. You are creating a new Project everytime a Product Brief is being inserted or modified. This is a logical flaw.
There should be some criteria to determine when to create a new Project for example on update of Product Brief only when certain fields change in a specific way as your Product Brief already has an associated Project that you had created while creating the Product Brief itself.
Fix this logical flaw and you are rocking :)
2. In case you expect recursion for example say you create a Product Brief and then a workflow fires which does a field update on it, this should trigger your trigger again for update event (though it has already executed for insert and logically is not required to run again), you may want to introduce some Static variables to control the behavior (for time being you are good to go if you already don't have a recursive scenario in place).
Thanks for the insight; we won't be loading any Product Brief records via API. Though, I am curious what piece of the code is not bulkified. The DML statements are all outside of the FOR loops and I'm not immediately seeing anything else out of place.
1. Product_Brief__c pb = [SELECT Related_Project__c FROM Product_Brief__c WHERE ID =: trigger.new];
if(pb.Related_Project__c == NULL){
This will work only till batch size is 1. If batch size is 2 or more, your query is going to return a list and you are going to run in an exception. Also, pb.Related_Project__c will throw exception as index is not specified.
2. If you even include an index in above, you would just be deciding on calling the Class method based on 1st record. You should filter the Ids that do not have Project and only pass those Ids to the method, not all records in Trigger.New.