• empuc
  • NEWBIE
  • 130 Points
  • Member since 2012

  • Chatter
    Feed
  • 4
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 1
    Questions
  • 43
    Replies

Hi Everyone.

 

I want to know current login user has edit permission to lead object or not ...

 

Thanks in Advance

Hi Can you help with the trigger.

 

I want to update the status field on parent case when child case status is updated? Is it possible. Can you send me the sample for that?

 

I have seen sample trigger the other way round for updating child case when parent case is updated.

 

http://wiki.developerforce.com/page/Synchronize_A_Parent_Case's_Status_To_The_Status_Of_Its_Children

 

Any help with be appreciated.

 

Thanks

Abi

  • March 28, 2013
  • Like
  • 0

I am trying to copy a custom contact roles object over to the standard opportunity contact roles object so that we can have custom fields but not lose the functionality of the standard object.  I have a trigger that on insert, update, delete, etc of the custom object it is supposed to check the standard object and insert, delete or update.  The delete and update works fine but when I try to create a new custom contact role record I get the error of execution of AfterInsert caused by: System.NullPointerException

 

Can anyone please help me figure out what is causing this?  I'm trying to do an upsert so that it will both update those that are already existing and insert those that are new.

 

Thanks,

Amanda

 

 

trigger CustomOCRtoStandardOCRSync on Opportunity_Contact_Role__c (after delete, after insert, after undelete,
after update) {


    // collect related opportunities
    Set<Id> opptyIds = new Set<Id>();
    List<Opportunity_Contact_Role__c> cocrList = (trigger.isDelete) ? trigger.old : trigger.new;
    for(Opportunity_Contact_Role__c cocr : cocrList) {
        opptyIds.add(cocr.opportunity__c);
    }
    
    // grab list of current custom contact roles and map by opportunity
    Map<Id, Map<Id, Opportunity_Contact_Role__c>> cOcrMap = new Map<Id, Map<Id, Opportunity_Contact_Role__c>>();
    for(Opportunity_Contact_Role__c cocr : [
        select contact__c, opportunity__c, role__c, primary__c
        from Opportunity_Contact_Role__c
        where opportunity__c in :opptyIds
    ]) {
        // initialize map for opportunity if it's the first time we've seen it
        if(!cOcrMap.containsKey(cocr.opportunity__c)) {
            cOcrMap.put(cocr.opportunity__c, new Map<Id, Opportunity_Contact_Role__c>());
        }
        Map<Id, Opportunity_Contact_Role__c> opportunitycontactMap = cOcrMap.get(cocr.opportunity__c);
        
        // map by contact id
        opportunitycontactMap.put(cocr.contact__c, cocr);
    }
    
    // grab list of current standard contact roles and organize
    Map<Id, Map<Id, OpportunityContactRole>> standardOCRMap = new Map<Id, Map<Id, OpportunityContactRole>>();
    for(OpportunityContactRole ocr : [
        select contactId, opportunityId, role, isPrimary
        from OpportunityContactRole
        where opportunityId in :opptyIds
    ]) {
        // initialize map for opportunity if it's the first time we've seen it
        if(!standardOCRMap.containsKey(ocr.opportunityId)) {
            standardOCRMap.put(ocr.opportunityId, new Map<Id, OpportunityContactRole>());
        }
        Map<Id, OpportunityContactRole> contactMap = standardOCRMap.get(ocr.opportunityId);
        
        // map by contact id
        contactMap.put(ocr.contactId, ocr);
    }

    // find contact roles that need to be deleted
    List<OpportunityContactRole> toBeDeleted = new List<OpportunityContactRole>();
    for(Id opptyId : standardOCRMap.keySet()) {
        for(Id contactId : standardOCRMap.get(opptyId).keySet()) {
            
            // does this exist in the custom version?
            Boolean exists = false;
            if(cOCRMap.containsKey(opptyId)) {
                Map<Id, Opportunity_Contact_Role__c> opportunitycontactMap = cOCRMap.get(opptyId);
                if(!opportunitycontactMap.containsKey(contactId)) {
                    // doesn't existing in the custom table, so we need to delete it
                    toBeDeleted.add(standardOCRMap.get(opptyId).get(contactId));
                }
            }
                
        }
    }
    delete toBeDeleted;
    
 // find new contact roles that need to be created or updated
    List<OpportunityContactRole> toBeUpserted = new List<OpportunityContactRole>();
    for(Id opptyId : cOCRMap.keySet()) {
        for(Opportunity_Contact_Role__c cocr : cOCRMap.get(opptyId).values()) {
            
            // get the existing one if it exists
            OpportunityContactRole existing = new OpportunityContactRole();
            if(standardOCRMap.containsKey(opptyId)) {
                Map<Id, OpportunityContactRole> contactMap = standardOCRMap.get(opptyId);
                existing = contactMap.get(cocr.contact__c);
            }
            system.debug('-->existing.role;' + existing.role);
            system.debug('-->cocr.role_c;' + cocr.role__c);
            // update the fields
            existing.role = cocr.role__c;
            existing.isPrimary = cocr.primary__c;
            toBeUpserted.add(existing);
            
        }
    }
    upsert toBeUpserted;
    



}

 

 

Hello Everyone!

 

I've wanted to add address visualization on some SFDC page-layout standard page with Google Maps functionality (as a embeded VF section). I  found existing piece of code - here : http://phollaio.tumblr.com/post/22058038379/inline-google-maps-using-visualforce and modified it to my needs. Its works really nice on IE / FF, but the problem is with Chrome which display a blank section there :( I've tried to find any security settings on chrome, which could block it, but without any results :( 

 

Maybe some of You already encountered the same problem?

 

Thanks in advance for any feed back and help!

 

  • September 10, 2012
  • Like
  • 0

This table is not appearing when I render the vfpage. What do I need to change in my vf page?

 

<apex:page standardcontroller="PCN_s__c" extensions="pcntable" >
<apex:form >
 <apex:pageBlock >
 <apex:repeat value="{!pcnlist}" var="pcn" >   
   <table> 
        <tr> 
            <td> <apex:outputlabel value="Project Impact"/> </td>
            <td> <apex:outputlabel value="Current Project"/> </td>
            <td> <apex:outputlabel value="Revised Project"/> </td>
            <td> <apex:outputlabel value="Change"/> </td>
            <td> <apex:outputlabel value="Approved"/> </td>
       </tr>
       <tr> 
            <td> <apex:outputlabel value="PROD. LABOR HOURS & COST:"/> </td>
            <td> <apex:inputfield value="{!pcn.Current_PROD_LABOR_HOURS__c}"/> <apex:inputfield value="{!pcn.Current_PROD_LABOR_COST__c}"/> </td>
            <td> <apex:inputfield value="{!pcn.Revised_PROD_LABOR_HOURS__c}"/> <apex:inputfield value="{!pcn.Revised_PROD_LABOR_COST__c}"/> </td>
       </tr>
       <tr>
            <td> <apex:outputlabel value="ENG. LABOR HOURS & COST:"/> </td>
            <td> <apex:inputfield value="{!pcn.Current_ENG_LABOR_HOURS__c}"/> <apex:inputfield value="{!pcn.Current_ENG_LABOR_COST__c}"/> </td>
            <td> <apex:inputfield value="{!pcn.Revised_ENG_LABOR_HOURS__c}"/> <apex:inputfield value="{!pcn.Revised_ENG_LABOR_COST__c}"/> </td>
      </tr>
       <tr>
            <td> <apex:outputlabel value="MATERIAL COST:"/> </td>
            <td> <apex:inputfield value="{!pcn.Current_MATERIAL_COST__c}"/> </td>
            <td> <apex:inputfield value="{!pcn.Revised_MATERIAL_COST__c}"/> </td>
      </tr>
       <tr>
            <td> <apex:outputlabel value="PRINT RELEASE DATE:"/> </td>
            <td> <apex:inputfield value="{!pcn.Current_PRINT_RELEASE_DATE__c}"/> </td>
            <td> <apex:inputfield value="{!pcn.Revised_PRINT_RELEASE_DATE__c}"/> </td>
      </tr>
       <tr>
            <td> <apex:outputlabel value="SCHED. SHIP DATE:"/> </td>
            <td> <apex:inputfield value="{!pcn.Current_SCHED_SHIP_DATE__c}"/> </td>
            <td> <apex:inputfield value="{!pcn.Revised_SCHED_SHIP_DATE__c}"/> </td>
      </tr>
       <tr>
            <td> <apex:outputlabel value="ADDITIONAL COMPONENTS:"/> </td>
            <td> <apex:inputfield value="{!pcn.Current_ADDITIONAL_COMPONENTS__c}"/> </td>
            <td> <apex:inputfield value="{!pcn.Revised_ADDITIONAL_COMPONENTS__c}"/> </td>
      </tr>
       <tr>
            <td> <apex:outputlabel value="TOTAL COST:"/> </td>
            <td> <apex:inputfield value="{!pcn.Current_TOTAL_COST__c}"/> </td>
            <td> <apex:inputfield value="{!pcn.Revised_TOTAL_COST__c}"/> </td>
      </tr>
       <tr>
            <td> <apex:outputlabel value="SELLING PRICE:"/> </td>
            <td> <apex:inputfield value="{!pcn.Current_SELLING_PRICE__c}"/> </td>
            <td> <apex:inputfield value="{!pcn.RevisedSELLING_PRICE__c}"/> </td>
      </tr>
  </table>
</apex:repeat>
</apex:pageBlock>
</apex:form>
</apex:page>

I have not written any batch apex yet.  I want to update a field on a custom object that will then fire a trigger to rollup sales dollars to managers.  I have the rollup working properly when I manually update the controlling field, but I want to be able to schedule this job to run each day. 

 

Anyone have a good example of this type of code?

 

  • April 01, 2013
  • Like
  • 0

Hello Every body ,

 

I need to use radio buttons to select Salesforce records (not simple values). I used the input radio but the problem is that i can't make one of these checked by default based on a value returned from the controller . 

 

Here is the code of the Visualforce : 

 

<apex:pageblock id="consel" title="Couleurs">
            <apex:pageblocktable id="allcons" value="{!SelectedCouleur}" var="selcolor">  
            
            <apex:column headervalue="Sélectionner">
            
          
                        
                        
                        
                        
                        
                           <apex:actionsupport action="{!selectcouleur}" event="onclick" rerender="label">  
                        <input type="radio" name="couleur"/>                    
                            <apex:param name="couleurid " value="{!selcolor.Id}" assignTo="{!idcouleur}">
                        </apex:param></apex:actionsupport>  
                        
                     
            </apex:column>
                        
                        
                        
                    <apex:column headervalue="Couleur extérieur">
                        <apex:outputfield value="{!selcolor.Couleurexterieur__r.Name}">
                    </apex:outputfield></apex:column> 
                                        
                    <apex:column headervalue="Garniture">
                        <apex:outputfield value="{!selcolor.Couleurinterieur__r.Name}">
                    </apex:outputfield></apex:column> 
                    
                    <apex:column headervalue="Prix couleur extérieur">
                        <apex:outputfield value="{!selcolor.Prixexterieur__c}">
                    </apex:outputfield></apex:column> 
                    
                    <apex:column headervalue="Prix Garniture">
                        <apex:outputfield value="{!selcolor.Prixcouleurinterieur__c}">
                    </apex:outputfield></apex:column> 
                   
                </apex:pageblocktable>
</apex:pageblock>  

 Thank you for your advance Help !

 

 

 

 

Hi everyone I'm trying to return an aggregate result to pass to visualforce charts with this controller. i need to sum multiple datapoints with different where clauses from the same object.

 

this is the error i get...

 

Error: Compile Error: Didn't understand relationship 'Booking__c' in FROM part of query call. If you are attempting to use a custom relationship, be sure to append the '__r' after the custom relationship name. Please reference your WSDL or the describe call for the appropriate names. at line 7 column 13

 

Booking__c is the same object as the main query

 

any insights are greatly appreciated

 

public with sharing class BkgPerformance {
public List<AggregateResult> getData() {

 

// return

List<AggregateResult> working =

 

[SELECT COUNT(Id) theCount,
(select count(Id) from Booking__c where Booking_Stage__c = 'Pending') thePending,

(select count(Id) from Booking__c where Booking_Stage__c = '1st Payment'), theFirst,

(select count(Id) from Booking__c where Booking_Stage__c = '2nd Payment'), theSecond,

CALENDAR_YEAR(CreatedDate) theYear


FROM Booking__c

GROUP BY CALENDAR_YEAR(CreatedDate)
ORDER BY CALENDAR_YEAR(CreatedDate)];

 


return (working);

}


}

Quick question on adding some custom fields.  And let me state first I am totally new to visualforce development - although I know lots of programming languages.  Have not set up anything with Visualforce though!

My client wants to add a new section to their Opportunity object to define a sequence of events for the Opportunity.  They would like to have up to 50 instances of a set of three fields, but only show 5, then scroll down to see the rest.

Basically, they want one header, and then up to 50 sets of 3 fields (without individual labels) , but only 5 sets showing, and scroll to see the rest.  Hope that makes sense.  

So like the below showing in a scrolling section, and as you scroll down the rest of the fields are shown.  Can anyone help me with the best way to set this up??

They are in Professional Edition.

Thanks!


Due Date              Date Realized                 Sequence of Events

|-----------|                    |-----------|                     |-----------------------------------------------------------------|        |
|-----------|                    |-----------|                     |-----------------------------------------------------------------|        |
                                                                                                                                                                           |
|-----------|                    |-----------|                     |-----------------------------------------------------------------|        |
|-----------|                    |-----------|                     |-----------------------------------------------------------------|        |
                                                                                                                                                                           |
|-----------|                    |-----------|                     |-----------------------------------------------------------------|        |
|-----------|                    |-----------|                     |-----------------------------------------------------------------|        |
                                                                                                                                                                           |
|-----------|                    |-----------|                     |-----------------------------------------------------------------|        |
|-----------|                    |-----------|                     |-----------------------------------------------------------------|        |
                                                                                                                                                                           |
|-----------|                    |-----------|                     |-----------------------------------------------------------------|        |
|-----------|                    |-----------|                     |-----------------------------------------------------------------|        \/    

                                                                                                                                                     SCROLL to see more 

A consultant built some Visualforce pages for us and upon adding them to our Contact page layouts, I'm finding that they do not display properly for any Profile but the System Administrator profile. Even if I clone the system admin profile and assign it as a test to a different user, it continues to not display properly. 

 

For the system admins, the Contact record displays normally, with the below VF page inline about halfway down the page when field

 

contact.Legacy_RecordType__c == 'Fellow/Alum'

 

For any other profile, upon loading a Contact record it:

1) Jumps down the page to this VF page

2) Renders the page regardless of the Legacy Record Type

3) Leaves open for editing the lookup field 

!contact.EG_Finalist_Fellow_Org__c

 

Does anyone have any idea what might be going on? The consultant also installed the InlineVFExpander (https://appexchange.salesforce.com/listingDetail?listingId=a0N30000004cEEyEAM) which all profiles also have access to.

 

Things I've checked in my attempts to fix this:

-The fellowext class has profile access for all profiles

-The profiles all have access to all fields referenced here

 

<apex:page standardController="Contact"  extensions="fellowext" sidebar="false" rendered="{!contact.Legacy_RecordType__c == 'Fellow/Alum'}"  showHeader="false">
    <script>
function doRedirect()
{
window.parent.location.href = 'https://na14.salesforce.com/apex/FellowAlum_Edit?id={!contact.Id}';
}

</script>
        <apex:form >
            <apex:pageBlock title="Fellow/Alum Details" id="thePageBlock" mode="detail" rendered="{!contact.Legacy_RecordType__c == 'Fellow/Alum'}">
                <apex:pageMessages />
                <apex:pageBlockButtons >
                    <apex:commandButton value="Edit Fellow/Alum Fields" action="{!go}" onComplete="doRedirect()"/>
                                  
                </apex:pageBlockButtons>
                
                    <apex:pageBlockSection title="FELLOW/ALUM" columns="2">
                        
                       
                                <apex:outputField value="{!contact.EG_Finalist_Fellow_Org__c}" />
                                <apex:outputField value="{!contact.Fellow_Type__c}"/>
                                <apex:outputField value="{!contact.Fellowship_Year__c}"/>
                                <apex:outputField value="{!contact.Finalist_Year__c}"/> 
                                <apex:outputField value="{!contact.EG_Funded_Org_Structure__c}"/>
                                 </apex:pageBlockSection>
                                 
                                 <apex:pageBlockSection title="Fellow/Alumni Specifics" columns="2">
                                <apex:outputField value="{!contact.Program_Area__c}"/>   
                                <apex:outputField value="{!contact.Facebook_Profile__c}"/>  
                                <apex:outputField value="{!contact.Population_Expertise__c}"/>
                                <apex:outputField value="{!contact.Twitter_Handle__c}"/>
                                <apex:outputField value="{!contact.Geographic_Expertise__c}"/>
                                <apex:outputField value="{!contact.YouTube_Vimeo__c}"/>
                                <apex:outputField value="{!contact.Geographic_Reach_EG_Fellowship__c}"/>
                                <apex:outputField value="{!contact.Blog__c}"/>
                                <apex:pageBlockSectionItem ></apex:pageBlockSectionItem>
                                <apex:outputField value="{!contact.Flickr__c}"/>
                                <apex:pageBlockSectionItem ></apex:pageBlockSectionItem>
                                <apex:outputField value="{!contact.LinkedIn__c}"/> 
                                <apex:pageBlockSectionItem ></apex:pageBlockSectionItem> 
                                <apex:outputField value="{!contact.Tumblr__c}"/> 
                                <apex:pageBlockSectionItem ></apex:pageBlockSectionItem>
                                <apex:outputField value="{!contact.Product_Link__c}"/>
                                
                                </apex:pageBlockSection> 
                                <apex:pageBlockSection title="Fellow/Alumni Specifics(Text)" columns="1">
                                <apex:outputField value="{!contact.Bold_Idea__c}"/>
                                <apex:outputField value="{!contact.Professional_Expertise__c}"/> 
                                <apex:outputField value="{!contact.Website_Metadata__c}"/> 
                                <apex:outputField value="{!contact.Bio__c}"/> 
                                <apex:outputField value="{!contact.Moment_of_Obligation__c}"/> 
                                <apex:outputField value="{!contact.Product_Description__c}"/> 
                                <apex:outputField value="{!contact.EG_Funded_Org_Overview__c}"/> 
                                </apex:pageBlockSection>    

        </apex:pageBlock>
        </apex:form>
    </apex:page>

 

  • March 29, 2013
  • Like
  • 0

Close to my wits' end on this one. I have a trigger that calls a Future class. When I run through my tests I get up to 7 future calls. I then add another conditional to my SOQL query in the trigger, and the whole thing breaks, highlighting a random line in my class and saying  I'm suddenly using 11 future calls.

 

Trigger:

 

if (trigger.isInsert) {
			for (Contact workingContact : trigger.new) {
				// Check for existing Contacts
				List<Contact> orgContacts = [Select Id, Name, Email from Contact where ( Name = :workingContact.Name and Email = :workingContact.Email and Email != null and Id != :workingContact.Id)];
				if (orgContacts.size() != 0) {
					NotificationEmail.AvianisError(orgContacts[0].Id, orgContacts[0].Name, 'Duplicate Contact found on Contact insert');
					continue;
				}
				// Insert Contact into Avianis
				if (workingContact.AvianisID__c == null && workingContact.AccountId != null) {
					Avianis.aviContactFuture('insert', workingContact.Id);
				}
			}
		}

 Future method called:

// Contact method
    @future (callout=true)
    public static void aviContactFuture(String operation, String conId) {
    	
    	// Get contact info
        List<Contact> sfContacts = new List<Contact>();
        
        sfContacts = [SELECT Contact.Id, ...
                      FROM Contact WHERE Contact.Id = :conID ALL ROWS];
                      
        if (sfContacts.size() == 0) {
        	return;
        }   

    	aviContact(operation, sfContacts[0]);
    }

 The aviContact method builds a SOAP envelope and sends it, then updates the Contact with a return value. Eclipse is highlighting a random line in the aviContact method (where it's setting a variable with "") as System.LimitException: Too many future calls: 11

 

In case it matters, here's the NotificationEmail.AvianisError method:

public static void AvianisError(Id EId, String EName, String ErrType) {
		// Send notification email if Avianis trigger encounters an error.
		
		Messaging.SingleEmailMessage mail = new Messaging.Singleemailmessage();
		mail.setSaveAsActivity(false);
		String mailSubject = 'Avianis Trigger Error: ' + EName;
		String mailBody = 'Error for: ' + EName + ' https://na14.salesforce.com/' + EId + '\n\n' + 'Error Code: ' + ErrType;
		mail.setToAddresses(new String[] {'**@**.com'});
		mail.setSubject(mailSubject);
		mail.setPlainTextBody(mailBody);
		
		Messaging.sendEMail(new Messaging.SingleEmailMessage[] {mail});
		
	}

 

I'm going nuts here, any ideas?

Hi Everyone.

 

I want to know current login user has edit permission to lead object or not ...

 

Thanks in Advance

Hi can anyone tell me why i am getting this error for this code? i am at my wits end. I have marked the line where i am getting the error

 

public class FindScope {
  list<list<opportunity>> theList;
  list<String> piclistVals = new list<string>();
  String s;
  list<string> pv;
  list<opportunity> listOfOpp; 
 
  public list<String> getPicklistVals(){
    Schema.DescribeFieldResult fieldResult = opportunity.stageName.getDescribe();
  for(Schema.PicklistEntry f :  fieldResult.getPicklistValues()){
    piclistVals.add(f.getValue());
   
  }
  return piclistVals;
  }
  public list<list<opportunity>> getOpportunities(){
         theList =  new list<list<opportunity>>();
         for(Integer i = 0; i < piclistVals.size(); i++){
         String pvalue = pv[i];  
       listOfOpp = [select id, name, stagename, amount from opportunity where stagename = :pvalue];
       thelist.add(listOfOpp);
         
   }
      return thelist;
  } 
   public list<opportunity> getProspecting(){
     
       oppProspecting = thelist[0];
        list<opportunity> myopp = new list<opportunity>();
         ;     
        return oppProspecting;
    }
     public list<opportunity> getQualification(){
      list<opportunity> oppQualification = new list<opportunity>();
       oppQualification = thelist[0];
        System.debug(oppQualification);       
        return oppQualification;
    }
      public list<opportunity> getNeedsAnalysis(){
      list<opportunity> oppNeedsAnalysis = new list<opportunity>();
       oppNeedsAnalysis = thelist[2];
        return oppNeedsAnalysis;
    } 
     public list<opportunity> getValueProposition(){
      list<opportunity> oppValueProposition = new list<opportunity>();
       oppValueProposition = thelist[3];
        return oppValueProposition;
    }       
    
}

  • March 29, 2013
  • Like
  • 0

I am trying to copy a custom contact roles object over to the standard opportunity contact roles object so that we can have custom fields but not lose the functionality of the standard object.  I have a trigger that on insert, update, delete, etc of the custom object it is supposed to check the standard object and insert, delete or update.  The delete and update works fine but when I try to create a new custom contact role record I get the error of execution of AfterInsert caused by: System.NullPointerException

 

Can anyone please help me figure out what is causing this?  I'm trying to do an upsert so that it will both update those that are already existing and insert those that are new.

 

Thanks,

Amanda

 

 

trigger CustomOCRtoStandardOCRSync on Opportunity_Contact_Role__c (after delete, after insert, after undelete,
after update) {


    // collect related opportunities
    Set<Id> opptyIds = new Set<Id>();
    List<Opportunity_Contact_Role__c> cocrList = (trigger.isDelete) ? trigger.old : trigger.new;
    for(Opportunity_Contact_Role__c cocr : cocrList) {
        opptyIds.add(cocr.opportunity__c);
    }
    
    // grab list of current custom contact roles and map by opportunity
    Map<Id, Map<Id, Opportunity_Contact_Role__c>> cOcrMap = new Map<Id, Map<Id, Opportunity_Contact_Role__c>>();
    for(Opportunity_Contact_Role__c cocr : [
        select contact__c, opportunity__c, role__c, primary__c
        from Opportunity_Contact_Role__c
        where opportunity__c in :opptyIds
    ]) {
        // initialize map for opportunity if it's the first time we've seen it
        if(!cOcrMap.containsKey(cocr.opportunity__c)) {
            cOcrMap.put(cocr.opportunity__c, new Map<Id, Opportunity_Contact_Role__c>());
        }
        Map<Id, Opportunity_Contact_Role__c> opportunitycontactMap = cOcrMap.get(cocr.opportunity__c);
        
        // map by contact id
        opportunitycontactMap.put(cocr.contact__c, cocr);
    }
    
    // grab list of current standard contact roles and organize
    Map<Id, Map<Id, OpportunityContactRole>> standardOCRMap = new Map<Id, Map<Id, OpportunityContactRole>>();
    for(OpportunityContactRole ocr : [
        select contactId, opportunityId, role, isPrimary
        from OpportunityContactRole
        where opportunityId in :opptyIds
    ]) {
        // initialize map for opportunity if it's the first time we've seen it
        if(!standardOCRMap.containsKey(ocr.opportunityId)) {
            standardOCRMap.put(ocr.opportunityId, new Map<Id, OpportunityContactRole>());
        }
        Map<Id, OpportunityContactRole> contactMap = standardOCRMap.get(ocr.opportunityId);
        
        // map by contact id
        contactMap.put(ocr.contactId, ocr);
    }

    // find contact roles that need to be deleted
    List<OpportunityContactRole> toBeDeleted = new List<OpportunityContactRole>();
    for(Id opptyId : standardOCRMap.keySet()) {
        for(Id contactId : standardOCRMap.get(opptyId).keySet()) {
            
            // does this exist in the custom version?
            Boolean exists = false;
            if(cOCRMap.containsKey(opptyId)) {
                Map<Id, Opportunity_Contact_Role__c> opportunitycontactMap = cOCRMap.get(opptyId);
                if(!opportunitycontactMap.containsKey(contactId)) {
                    // doesn't existing in the custom table, so we need to delete it
                    toBeDeleted.add(standardOCRMap.get(opptyId).get(contactId));
                }
            }
                
        }
    }
    delete toBeDeleted;
    
 // find new contact roles that need to be created or updated
    List<OpportunityContactRole> toBeUpserted = new List<OpportunityContactRole>();
    for(Id opptyId : cOCRMap.keySet()) {
        for(Opportunity_Contact_Role__c cocr : cOCRMap.get(opptyId).values()) {
            
            // get the existing one if it exists
            OpportunityContactRole existing = new OpportunityContactRole();
            if(standardOCRMap.containsKey(opptyId)) {
                Map<Id, OpportunityContactRole> contactMap = standardOCRMap.get(opptyId);
                existing = contactMap.get(cocr.contact__c);
            }
            system.debug('-->existing.role;' + existing.role);
            system.debug('-->cocr.role_c;' + cocr.role__c);
            // update the fields
            existing.role = cocr.role__c;
            existing.isPrimary = cocr.primary__c;
            toBeUpserted.add(existing);
            
        }
    }
    upsert toBeUpserted;
    



}