I have a similar situation for this. I used the code at the following link as my base, and modified it from there to meet my requirements.
https://developer.salesforce.com/forums/?id=906F00000008yPpIAI
Here is the code that I have in my system.
trigger CopyPrimaryContact on Opportunity (before update) {
// THIS TRIGGER WILL OVERWRITE ANY CONTACT DEFINED IN THE CUSTOM FIELD OPPORTUNITY_CONTACT__C ON THE OPPORTUNITY OBJECT.
// SET THIS FIELD TO READ ONLY OR CHANGE THE FUNCTIONALITY BELOW TO AVIOD DATA BEEING OVERWRITTEN BY MISTAKE...
List<OpportunityContactRole> contactRoleArray = [select ContactID, isPrimary from OpportunityContactRole where Role != 'Dealer Sales Rep' and OpportunityId IN :Trigger.newMap.keySet() ORDER BY isPrimary DESC, createdDate];
for (Opportunity o : Trigger.new) {
// CREATE ARRAY OF ALL CONTACT ROLES ON THIS OPPORTUNITY. THE REASON WHY WE DONT PICK THE PRIMARY CONTACT ROLE ONLY
// IS BECAUSE THE PRIMARY FLAG IS NOT SET WHEN LEADS ARE CONVERTED TO OPPORTUNITIES. ONLY WHEN CREATING OPPORTUNITIES
// MANUALLY FROM THE CONTACT OBJECT THE IS PRIMARY CHECKBOX IS CHECKED...
if (o.Opportunity_Contact__c == null && contactRoleArray.size() > 0) {
// IF PRIMARY IS DEFINED THEN THIS WILL BE THE FIRST OBJECT. IF NOT THE FIRST ADDED CONTACT ROLE WILL BE ADDED...
o.Opportunity_contact__c = contactRoleArray[0].ContactID;
}
}
}
I also have a second trigger that will create a new Contact Role if the user enters the name in the lookup field. I wrote this one to allow the user to add the contact role without having to save the record, scroll down to contacts, add the new contact role, save, then re-edit the record to move to the next stage. This trigger lets the user add the contact role during the initial edit or creation. There is a check to prevent duplicate roles from being created as a result of the first trigger.
trigger CreateContactRole on Opportunity (after insert, after update) {
List<OpportunityContactRole> OppContactRole = new List<OpportunityContactRole>();
List<OpportunityContactRole> contactRoleArray = [select ContactID, isPrimary from OpportunityContactRole where Role != 'Dealer Sales Rep' and OpportunityId IN :Trigger.newMap.keySet() ORDER BY isPrimary DESC, createdDate];
for (Opportunity OppNew : Trigger.new) {
if (contactRoleArray.size() > 0 && OppNew.Opportunity_Contact__c != null && OppNew.Opportunity_Contact__c != contactRoleArray[0].ContactID){
OpportunityContactRole ocr = new OpportunityContactRole();
ocr.OpportunityId = OppNew.Id;
ocr.ContactId = OppNew.Opportunity_Contact__c;
ocr.Role = 'Department Contact';
OppContactRole.add(ocr); // For Bulk processing of the Records.
}else if (contactRoleArray.size() == 0 && OppNew.Opportunity_Contact__c != null){
OpportunityContactRole ocr = new OpportunityContactRole();
ocr.OpportunityId = OppNew.Id;
ocr.ContactId = OppNew.Opportunity_Contact__c;
ocr.Role = 'Department Contact';
OppContactRole.add(ocr); // For Bulk processing of the Records.
}
}
// Inserting the New Contact Role
insert OppContactRole;
}