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
wattsswattss 

How to link a custom object to a standard object

I am developing a custom object, Work Order, that has an Opportunity field that is a look up relationship with the Opportunity object.

When the Stage of the Opportunity is changed to 'Closed Won' a trigger is fired that creates a new Work Order record.

Although the code compiles, in practice when the trigger fires an exception is thrown. The work order record is created however there is no link between the Opportunity and Work Order. 

The message displayed is as follows:


Error: Invalid Data. 
Review all error messages below to correct your data.
Apex trigger opportunityIsWon caused an unexpected exception, contact your administrator: opportunityIsWon: execution of AfterUpdate caused by: System.StringException: Invalid id: Test 02D: Trigger.opportunityIsWon: line 16, column 13


The trigger code is as follows:

trigger opportunityIsWon on Opportunity (after update) {
    
    for (Opportunity opp : Trigger.new) {
        if (opp.StageName == 'Closed Won') {
       Work_Order__c workOrder = new Work_Order__c();
         workOrder.Description__c = opp.Name;
       workOrder.Status__c = 'New';
        
         workOrder.Opportunity__c = opp.Name;

         insert workOrder;
        }
        
    }
}


How can I programmatically link the Opportunity and Work Order objects?
Best Answer chosen by Admin (Salesforce Developers) 
JimRaeJimRae

You don't want to use the Opportunity Name for the link, even though it appears that way in the UI.  You need to use the ID of the Opportunity.  Your Trigger also has some bulk safe issues, sincey you are trying to insert each of the work orders as they are processed, you could get a "too many DML statements" error if you update a lot of opportunities at the same time.

Something like this should work:

 

 

trigger opportunityIsWon on Opportunity (after update) { List<Work_Order__c> newWO = new List<Work_Order__c>(); for (Opportunity opp : Trigger.new) { if (opp.StageName == 'Closed Won') { Work_Order__c workOrder = new Work_Order__c(); workOrder.Description__c = opp.Name; workOrder.Status__c = 'New'; workOrder.Opportunity__c = opp.id; newWO.add(workOrder); } } try{ insert newWO; }catch(DMLException d){ system.assert(false,'ERROR INSERTING NEW WORK ORDERS:'+d.getDMLMessage(0)); } }

 

 

 

 

 

All Answers

JimRaeJimRae

You don't want to use the Opportunity Name for the link, even though it appears that way in the UI.  You need to use the ID of the Opportunity.  Your Trigger also has some bulk safe issues, sincey you are trying to insert each of the work orders as they are processed, you could get a "too many DML statements" error if you update a lot of opportunities at the same time.

Something like this should work:

 

 

trigger opportunityIsWon on Opportunity (after update) { List<Work_Order__c> newWO = new List<Work_Order__c>(); for (Opportunity opp : Trigger.new) { if (opp.StageName == 'Closed Won') { Work_Order__c workOrder = new Work_Order__c(); workOrder.Description__c = opp.Name; workOrder.Status__c = 'New'; workOrder.Opportunity__c = opp.id; newWO.add(workOrder); } } try{ insert newWO; }catch(DMLException d){ system.assert(false,'ERROR INSERTING NEW WORK ORDERS:'+d.getDMLMessage(0)); } }

 

 

 

 

 

This was selected as the best answer
wattsswattss

Jim,

 

Thank you for your reply. That worked. Your additional code was useful as I'm new to the Salesforce environment.

 

 

Steve