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
Rogerio Lara 2028Rogerio Lara 2028 

Trigger on Opportunity to enforce related object

Hi developers,

I was wondering if anyone could save me today! Pleassseeee! ;-)

I have the following trigger and a validation rule that helps to enforce contact roles to be created for the opportunities depending on the sales stage and amount of the opportunity. This is working well.

------------------------------------------------------------------------------------------ This is what I have - FYI ---------------------------------------------------------------------------------

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; 
}
}

Validation rule: 
AND(OR(ISPICKVAL(StageName, 'Advanced Proposal'), ISPICKVAL (StageName, 'Final Negotiation'), ISPICKVAL (StageName, 'Contract Signed')),  Number_of_Contacts_Roles_Assigned__c <2,  Amount  >= 1000000)

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------Now this is what I need:

Standard Object = Opportunity
Custom Object = Strategic Client Opportunity Plan

I created a read only checkbox field on the opportunity = Has_Strategic_Client_Opportunity_Plan__c and left it unchecked

I want the trigger to check the "Has_Strategic_Client_Opportunity_Plan__c" when a new Strategic Client Opportunity Plan is created. 

Then I will create a validation rule on the opportunity to check whether this field is checked and the other required values too.

Does this make sense?

Your help is really appreciated. ;-)

Thank you,

Rog
Best Answer chosen by Rogerio Lara 2028
Nayana KNayana K
Please mark this post as solved.

All Answers

Nayana KNayana K
trigger StrategicClientOppPlanTrigger on Strategic_Client_Opportunity_Plan__c(after insert)
{
	Set<Id> setOppId = new Set<Id>();
	List<Opportunity> lstOpp = new List<Opportunity>();
	
	for(Strategic_Client_Opportunity_Plan__c objSCOP : Trigger.New)
	{
		if(objSCOP.Opportunity__c != NULL)
		{
			setOppId.add(objSCOP.Opportunity__c);
		}
	}
	
	/*** NOTE : I have added Has_Strategic_Client_Opportunity_Plan__c = FALSE in where condition because, if checkbox is already checked then I think no need to update the opportunity with again (as to avoid extra DML operations). You can remove if you want to  **/
	for(Opportunity objOpp : [	SELECT Id, Has_Strategic_Client_Opportunity_Plan__c 
								FROM Opportunity
								WHERE Has_Strategic_Client_Opportunity_Plan__c = FALSE AND Id IN:setOppId])
	{
		objOpp.Has_Strategic_Client_Opportunity_Plan__c = TRUE;
		lstOpp.add(objOpp);
	}
	if(!lstOpp.isEmpty())
		update lstOpp;
}

 
Rogerio Lara 2028Rogerio Lara 2028
Wow Nayana. Thank you so much for replying so quickly ;-) I really owe you one. I got this error message: [Description: Error] Error: Compile Error: Loop variable must be of type Opportunity at line 6 column 36 Any idea? Thank you, Rog
Nayana KNayana K
Trigger must be on Strategic_Client_Opportunity_Plan__c object. Not on Opportunity...It seems like you are writing trigger on Opportunity
Rogerio Lara 2028Rogerio Lara 2028
Silly me. Thank you Nayana. I’m going to test it now. ;-)
Nayana KNayana K
I am doing good Lara, hope you are also doing good :)
Rogerio Lara 2028Rogerio Lara 2028
Nayana, I couldn’t thank you enough. Thank you ever so much once again. If you don’t mind me asking, what part of the world you live? Thank you, Rog
Nayana KNayana K
I live in India, Bangalore :) Most welcome Lara.
Nayana KNayana K
Hi Lara,

I just want to tell you that please bulkify your trigger. What I mean is you should assume that in Bulk, Opportunities are going to be inserted/updated (say at a time 50 records inserted/update via dataloader or any apex code[say List<Opp> with 50 items added is inserted/updated]). So you should write a code to handle bulk data. And, that's the best practice. I will modify updatecontactrolecount trigger to bulkify it and post here.
Nayana KNayana K
Which part of the world you live in?
Rogerio Lara 2028Rogerio Lara 2028
I didn’t even think about that. In fact, I didn’t realise it. Thank you, thank you. Rog
Rogerio Lara 2028Rogerio Lara 2028
I’m in London.
Nayana KNayana K
As per my knowledge, updatecontactrolecount trigger should be on OpportunityContactRole, not on Opportunity. 
Let's imagine a scenario,

Opp1 is having 2 OCR ( OCR1, OCR2) and now you are updating Opp1, so Opp1 before update trigger fires and will have count = 2.

Now you will insert, OCR3 on Opp1, will your Opp trigger fires?No, because you are inserting OCR not updating Opp1. So ideally trigger should be on OCR3 to update parent Opp1 with count 3. 

When you insert OCR3 on Opp1, if you Opp1 is updating properly, then I believe there must be another trigger which is updating parent Opp or workflow/process builder is in place to update parent! By this, updatecontactrolecount trigger may be running internally and setting the count.

Please let me know if I am making sense..
Rogerio Lara 2028Rogerio Lara 2028
That makes sense and you are right, the trigger is running internally and setting the count. I will change it as you recommended. Thank you, Rog
Rogerio Lara 2028Rogerio Lara 2028
I’m trying to work out the best way to copy the Contact Role from the opportunity into another object. I’ve tried workflow but it didn’t work. So, I guess it will only work with trigger as well. It’s such a shame that Contact Role can’t be customised. So, I’ve created another object related to the SCOP that relates to opportunity. Opportunity > SCOP > Buying Influence The Buying Influence is essentially the contact role, but with more information. I don’t want to complicate things. Do you think this is too complicated? Rog
Nayana KNayana K
Let's keep it your code now, can we discuss on this tomorrow as I have many tasks to complete today. I have to do fast. Lets discuss tomorrow and sort it out. Is it fine?
Rogerio Lara 2028Rogerio Lara 2028
Of course. You’re ever so kind. Much obliged. ;-) Have a great day! Rog
Nayana KNayana K
trigger OCRTrigger on OpportunityContactRole(after insert, after update, after delete)
{
	OCRTriggerHandler objHandler = new OCRTriggerHandler();
	
	if(Trigger.isInsert && Trigger.isAfter)
	{
		objHandler.onAfterInsert(Trigger.New);
	}
	else if(Trigger.isUpdate && Trigger.isAfter)
	{
		objHandler.onAfterUpdate(Trigger.New);
	}
	else if(Trigger.isDelete && Trigger.isAfter)
	{
		objHandler.onAfterDelete(Trigger.Old);
	}
}

public class OCRTriggerHandler
{
	public void onAfterInsert(List<OpportunityContactRole> lstNewOCR)
	{
		updateParentOpp(lstNewOCR);
	}
	
	public void onAfterUpdate(List<OpportunityContactRole> lstNewOCR)
	{
		updateParentOpp(lstNewOCR);
	}
	
	public void onAfterDelete(List<OpportunityContactRole> lstOldOCR)
	{
		updateParentOpp(lstOldOCR);
	}
	
	private void updateParentOpp(List<OpportunityContactRole> lstOCR)
	{
		Map<Id, Integer> mapOppIdToOCRCount = new Map<Id, Integer>();
		Set<Id> setOppIdWithPrimaryTrue = new Set<Id>();
		List<Opportunity> lstOpp = new List<Opportunity>();
		Opportunity objOppToUpdate;
		
		for(OpportunityContactRole objOCR : lstOCR)
		{
			/** 1. On insert, no matter what we have to update parent Opp to reflect count. So add OppId to mapOppIdToOCRCount
			2. On Update, only if isPrimary is changed (from true to false or vice versa)then only collect 
			OppId to update Primary_Contact_Assigned__c respectively. So adding this filter would help in avoiding 
			unnecessay DML operations on Parent opportunity..make sense?
			3. On delete, collect old OCR's OppId (after delete Trigger.New = null) 
			so that OCR count is decreased and we want to update that on parent Opp. 
			In trigger I am passing Trigger.Old to the method. Observe carefully
			
			***/
			if(Trigger.isInsert || 
			(Trigger.isUpdate && Trigger.oldMap.get(objOCR.Id).IsPrimary != objOCR.IsPrimary)
			|| Trigger.Delete)
			{
				//Intially keep the count 0
				mapOppIdToOCRCount.put(objOCR.OpportunityId, 0);
			}
		}
		
		/** Imagine in BULK,  5 OCRs are getting inserted in order.
		Say, Opp1 - OCR1(Primary false), OCR2(Primary true), OCR3(Primary false)
			 Opp2 - OCR4(Primary true), OCR5(Primary false)
		
		Below For loop Tracing,
		
		Iteration 1 : OCR1 Primary false process
		
		if(objOCR.IsPrimary)									==> if(false)
		{
			setOppIdWithPrimaryTrue.add(objOCR.OpportunityId);	==> no enter in the loop
		}
		
		mapOppIdToOCRCount.put(objOCR.OpportunityId, mapOppIdToOCRCount.get(objOCR.OpportunityId)+1); ==> mapOppIdToOCRCount.put(Opp1, 1)
		
		OUTCOME ========> setOppIdWithPrimaryTrue = {}, mapOppIdToOCRCount = {Opp1 => 1}
		
		Iteration 2 : OCR2 Primary true process
		
		if(objOCR.IsPrimary) 									==> if(true)
		{
			setOppIdWithPrimaryTrue.add(objOCR.OpportunityId);	==> setOppIdWithPrimaryTrue.add(Opp1)
		}
		
		mapOppIdToOCRCount.put(objOCR.OpportunityId, mapOppIdToOCRCount.get(objOCR.OpportunityId)+1); ==> mapOppIdToOCRCount.put(Opp1, 2)
		
		OUTCOME ========> setOppIdWithPrimaryTrue = {Opp1}, mapOppIdToOCRCount = {Opp1 => 2}
		
		Iteration 3 : OCR3 Primary false process
		
		if(objOCR.IsPrimary) 									==> if(false)
		{
			setOppIdWithPrimaryTrue.add(objOCR.OpportunityId);	==> no enter in the loop
		}
		
		mapOppIdToOCRCount.put(objOCR.OpportunityId, mapOppIdToOCRCount.get(objOCR.OpportunityId)+1); ==> mapOppIdToOCRCount.put(Opp1, 3)
		
		OUTCOME ========> setOppIdWithPrimaryTrue = {Opp1}, mapOppIdToOCRCount = {Opp1 => 3}
		
		
		Iteration 4 : OCR4 Primary true process
		
		if(objOCR.IsPrimary) 									==> if(true)
		{
			setOppIdWithPrimaryTrue.add(objOCR.OpportunityId);	==> setOppIdWithPrimaryTrue.add(Opp2)
		}
		
		mapOppIdToOCRCount.put(objOCR.OpportunityId, mapOppIdToOCRCount.get(objOCR.OpportunityId)+1); ==> mapOppIdToOCRCount.put(Opp2, 1)
		
		OUTCOME ========> setOppIdWithPrimaryTrue = {Opp1, Opp2}, mapOppIdToOCRCount = {Opp1 => 3, Opp2 => 1}
		
		Iteration 5 : OCR5 Primary false process
		
		if(objOCR.IsPrimary) 									==> if(false)
		{
			setOppIdWithPrimaryTrue.add(objOCR.OpportunityId);	==> no enter in the loop
		}
		
		mapOppIdToOCRCount.put(objOCR.OpportunityId, mapOppIdToOCRCount.get(objOCR.OpportunityId)+1); ==> mapOppIdToOCRCount.put(Opp2, 2)
		
		OUTCOME ========> setOppIdWithPrimaryTrue = {Opp1, Opp2}, mapOppIdToOCRCount = {Opp1 => 3, Opp2 => 2}
		
		***/
		for(OpportunityContactRole objOCR : [SELECT IsPrimary, OpportunityId 
											FROM OpportunityContactRole
											WHERE OpportunityId IN: mapOppIdToOCRCount.keySet()])
		{
			if(objOCR.IsPrimary)
			{
				setOppIdWithPrimaryTrue.add(objOCR.OpportunityId);
			}
			
			mapOppIdToOCRCount.put(objOCR.OpportunityId, mapOppIdToOCRCount.get(objOCR.OpportunityId)+1);
		}
		
		
		for(Id idOpp : mapOppIdToOCRCount.keySet())
		{
			objOppToUpdate = new Opportunity(Number_of_Contacts_Roles_Assigned__c = mapOppIdToOCRCount.get(idOpp));
			objOppToUpdate.Primary_Contact_Assigned__c = setOppIdWithPrimaryTrue.contains(idOpp) ? TRUE: FALSE;
			lstOpp.add(objOppToUpdate);
		}
		
		if(!lstOpp.isEmpty())
			update lstOpp;
		
	}
}

 
Nayana KNayana K
Please mark this post as solved.
This was selected as the best answer
Rogerio Lara 2028Rogerio Lara 2028
Hi Nayana,

Thank you so much. This is really incredible! Really appreaciate your kind help. 

Rog
Rogerio Lara 2028Rogerio Lara 2028
Hi Nayana,

Sorry to bother you again. One last question. I've been trying to do this for the past week, but I'm not getting anywhere...

How do I combine the 2 visualforce pages for related objects, so to display on the same page layout, edit and save. 

I'm trying to creat an edit visualforce page, so that when I create a new SCOP, I will, on the same page layout,be able to also create and save buying influence 1,2,3 etc. I know that I will have to override the 'new' button. for the SCOP for the new visualforce page.


<apex:page standardcontroller="Opportunity_Positioning__c">
<apex:messages />
    <apex:sectionheader title="{!$ObjectType.Opportunity_Positioning__c.label} Edit" subtitle="{!IF(ISNULL(Opportunity_Positioning__c.Name), 'New Strategic Client Opportunity Plan',Opportunity_Positioning__c.Name)}"/>
    <apex:form >
        <apex:pageblock mode="edit" title="{!$ObjectType.Opportunity_Positioning__c.label} Edit">
            <apex:pageblockbuttons >
                <apex:commandbutton value="Save" action="{!Save}"/>
                <apex:commandbutton value="Cancel" action="{!Cancel}"/>
            </apex:pageblockbuttons>

            <!-- **********   [Record Type : Master ]   **********  -->
            <apex:outputpanel >
                <apex:pageblocksection title="Information" showheader="true" columns="2">
                    <apex:inputfield value="{!Opportunity_Positioning__c.Name}" required="true"/>
                    <apex:pageblocksectionitem />
                    <apex:inputfield value="{!Opportunity_Positioning__c.Opportunity__c}" required="true"/>
                    <apex:pageblocksectionitem />
                </apex:pageblocksection>
                <apex:pageblocksection title="Summary of my position today" showheader="true" columns="2">
                    <apex:inputfield value="{!Opportunity_Positioning__c.Current_Status__c}" required="false"/>
                    <apex:inputfield value="{!Opportunity_Positioning__c.Key_Actions_Required__c}" required="false"/>
                    <apex:inputfield value="{!Opportunity_Positioning__c.Strengths__c}" required="false"/>
                    <apex:inputfield value="{!Opportunity_Positioning__c.Red_Flags__c}" required="false"/>
                    <apex:pageblocksectionitem />
                    <apex:inputfield value="{!Opportunity_Positioning__c.Adequacy_of_Current_Position__c}" required="false"/>
                </apex:pageblocksection>
                <apex:pageblocksection title="Competitive Positioning" showheader="true" columns="2">
                    <apex:inputfield value="{!Opportunity_Positioning__c.Position_vs_c__c}" required="false"/>
                    <apex:inputfield value="{!Opportunity_Positioning__c.Primary_Competitor__c}" required="false"/>
                </apex:pageblocksection>
            </apex:outputpanel>
        </apex:pageblock>
    </apex:form>
    </apex:page>

and

apex:page standardcontroller="Buying_Influence__c">
<apex:messages />
    <apex:sectionheader title="{!$ObjectType.Buying_Influence__c.label} Edit" subtitle="{!IF(ISNULL(Buying_Influence__c.Name), 'New Buying Influence',Buying_Influence__c.Name)}"/>
    <apex:form >
        <apex:pageblock mode="edit" title="{!$ObjectType.Buying_Influence__c.label} Edit">
            <apex:pageblockbuttons >
                <apex:commandbutton value="Save" action="{!Save}"/>
                <apex:commandbutton value="Cancel" action="{!Cancel}"/>
            </apex:pageblockbuttons>

            <!-- **********   [Record Type : Master ]   **********  -->
            <apex:outputpanel >
                <apex:pageblocksection title="Information" showheader="true" columns="2">
                    <apex:inputfield value="{!Buying_Influence__c.Name}" required="true"/>
                    <apex:inputfield value="{!Buying_Influence__c.SCOP__c}" required="true"/>
                    <apex:inputfield value="{!Buying_Influence__c.Name__c}" required="false"/>
                    <apex:pageblocksectionitem />
                    <apex:inputfield value="{!Buying_Influence__c.Buying_influence_role__c}" required="false"/>
                    <apex:pageblocksectionitem />
                    <apex:inputfield value="{!Buying_Influence__c.Degree_of_Influence__c}" required="true"/>
                    <apex:pageblocksectionitem />
                    <apex:inputfield value="{!Buying_Influence__c.Mode__c}" required="true"/>
                    <apex:pageblocksectionitem />
                </apex:pageblocksection>
                <apex:pageblocksection title="How well is based covered for this contact" showheader="true" columns="1">
                    <apex:inputfield value="{!Buying_Influence__c.Rating_for_base_covered__c}" required="true"/>
                    <apex:inputfield value="{!Buying_Influence__c.Evidence_to_support_your_rating__c}" required="false"/>
                </apex:pageblocksection>
            </apex:outputpanel>
        </apex:pageblock>
    </apex:form>
 </apex:page>
Nayana KNayana K
Hi Rog, 

Sorry, due to work load I din't visit dev forum.
As per https://dfc-org-production.force.com/forums/ForumsMain?id=9060G000000XcUKQA0 , seems above problem solved.
Cheers! Happy coding.
 
Rogerio Lara 2028Rogerio Lara 2028
Hi Nayana, Thank you for your email. This post is solved. I am trying to accomplish something else now. ;-) Learning lots, but struggling with my deadlines. ☹ Thank you, Rog
Nayana KNayana K
Let me know if I can be any help.
Rogerio Lara 2028Rogerio Lara 2028
If you don’t mind. That would be greatly appreciated. I have 2 Objects: 1) Opportunity Positioning (Parent custom object) 2) Buying Influence (Child object) The Buying Influence is related to Opportunity Positioning. I am trying to find a easy and seamless way for the buying Influence be added to the Opportunity Positioning, rather than having to first create parent, than go to related list and create the buying influences one by one. So I have started to work on visualforce and classes so that I can accomplish the above. This is what I have got so far, but experiencing issues: If you don’t mind could you help me fix this, please. ;-) Thank you Visualforce and controller (below) for Buying Influence: Error: Unknown property 'Opportunity_Positioning__cStandardController.Buying_Influence__c' extensions="EditableBuyingInfluenceExtension" value="{!Opportunity_Positioning__c.Name}"/> value="{!Opportunity_Positioning__c.Opportunity__c}"/> headerValue="Rating for base covered"> headerValue="Equivalent Collinson Stakeholder"> headerValue="Evidence to support your rating"> Buying Influence Controller [Description: Error] Error: Compile Error: unexpected token: 'FROM' at line 13 column 28 public with sharing class EditableBuyingInfluenceExtension extends EditableBuyingInfluenceList { public Opportunity_Positioning__c mydemo {get; private set;} public List children {get; set;} public EditableBuyingInfluenceListExtension(ApexPages.StandardController stdController) { super(stdController); this.mydemo = [SELECT Id, Name, FROM Opportunity_Positioning__c WHERE Id =: stdController.getRecord().Id]; this.childList = [SELECT Id, Name, SCOP__c, Influencer_Name__c, Buying_influence_role__c, Degree_of_Influence__c, Rating_for_base_covered__c, Equivalent_Collinson_Stakeholder__c Evidence_to_support_your_rating__c FROM Buying_Influence__c WHERE Opportunity_Positioning__c =: mysObject.Id]; children = new List(); children.addALL(this.childList); } /* * This method is necessary for reference on the Visualforce page, * in order to reference non-standard fields. */ /*public List getChildren() { return (List)childList; }*/ public PageReference saveChildren(){ try{ upsert children; //use the redirect method like the demographic page if needed after upsert }catch(DMLException saveEx){ //do something } return null; } public override sObject initChildRecord() { Buying_Influence__c child = new Buying_Influence__c(); child.Opportunity_Positioning__c = mydemo.Id; return child; } }
Nayana KNayana K
Can you please post page and controller code properly..Its unclear.
Rogerio Lara 2028Rogerio Lara 2028
Hi Nayana, Of course. Thank you. Please find attached codes. Thank you ever so much. Rog
Nayana KNayana K
Use tool to add code ('<>'  (9th tool from left)) while you are writing comment to this post.
Rogerio Lara 2028Rogerio Lara 2028
I didn’t even notice that. Thank you ;-) I will definitely do.
Rogerio Lara 2028Rogerio Lara 2028
<apex:page standardcontroller="Opportunity_Positioning__c">
           extensions="EditableBuyingInfluenceExtension"
<apex:sectionheader title="{!$ObjectType.Buying_Influence__c.label} Edit" subtitle="{!IF(ISNULL(Buying_Influence__c.Name), 'New Buying Influence',Buying_Influence__c.Name)}"/>
    <apex:form >
        <apex:pageblock mode="edit" title="{!$ObjectType.Buying_Influence__c.label} Edit">
            <apex:pageblockbuttons >
                <apex:commandbutton value="Save" action="{!Save}"/>
                <apex:commandbutton value="Cancel" action="{!Cancel}"/>
            </apex:pageblockbuttons>
            <apex:pageblocksection title="Information" showheader="true" columns="2">
                    <apex:outputText> value="{!Opportunity_Positioning__c.Name}"/>
                    <apex:outputText> value="{!Opportunity_Positioning__c.Opportunity__c}"/>
                    <apex:pageblocksectionitem />
            <apex:pageBlockSectionItem >
                <apex:pageblocksection id="childList" columns="1" title="Buying Influence" collapsible="false">
                <apex:variable var="rowNum" value="{!ZERO}" />
                <apex:outputLabel value="No Buying Influence currently exist. Click below to Add." rendered="{!NOT(hasChildren)}"/>
                    <apex:pageBlockTable value="{!children}" var="Buying Influence" rendered="{!hasChildren}">
                    <apex:column headerValue= "Buying Influence">
                    <apex:inputfield value="{!Buying_Influence__c.Name}" required="true"/>
                    <apex:column headerValue= "SCOP">
                    <apex:inputfield value="{!Buying_Influence__c.SCOP__c}" required="true"/>
                    <apex:column headerValue= "Influencer Name">
                    <apex:inputfield value="{!Buying_Influence__c.Influencer_Name__c}" required="true"/>
                    <apex:column headerValue= "Buying Influence role">
                    <apex:inputfield value="{!Buying_Influence__c.Buying_influence_role__c}" required="true"/>
                    <apex:column headerValue= "Degree of Influence">
                    <apex:inputfield value="{!Buying_Influence__c.Degree_of_Influence__c}" required="true"/>
                    <apex:pageblocksectionitem />
               </apex:column>
               <apex:pageblocksection title="How well is based covered for this contact" showheader="true" columns="2">
               </apex:pageblocksection>
               </apex:column> headerValue="Rating for base covered">
                    <apex:inputfield value="{!Buying_Influence__c.Rating_for_base_covered__c}" required="true"/>
               </apex:column> headerValue="Equivalent Collinson Stakeholder">
                    <apex:inputfield value="{!Buying_Influence__c.Equivalent_Collinson_Stakeholder__c}" required="false"/>
               </apex:column> headerValue="Evidence to support your rating">
                    <apex:inputfield value="{!Buying_Influence__c.Evidence_to_support_your_rating__c}" required="false"/>
                    </apex:column>
                    <apex:column headerValue=" ">
                    <!-- This is the second half of the trick to keep track
                    of your row index for deletion. -->
                    <apex:variable var="rowNum" value="{!rowNum + 1}" />
                    <apex:commandLink value="Delete" action="{!removeFromList}" rerender="childList,messages" immediate="true"> 
     <apex:param name="removeIndex" assignTo="{!removeIndex}" value="{!rowNum}" />
            </apex:commandLink>
          </apex:column>
        </apex:pageBlockTable>
        <apex:commandButton value="Add Buying Influence" action="{!addToList}" rerender="childList, messages" immediate="true" />
      </apex:pageBlockSection>
     </apex:pageblocksectionitem>
     </apex:outputtext> </apex:outputtext>
    </apex:pageblocksection>
</apex:pageblock>
</apex:form>
</apex:page>
Buying Influence Controller
 
public with sharing class EditableBuyingInfluenceExtension extends EditableBuyingInfluenceList
{


 public Opportunity_Positioning__c mydemo {get; private set;}
 public List<Quota__c> children {get; set;}
  public EditableBuyingInfluenceListExtension(ApexPages.StandardController stdController) 
  {
    super(stdController);

this.mydemo = [SELECT Id,
                              Name, ( select id,name from  Buying_Influence__r)
                            FROM Opportunity_Positioning__c
                            WHERE Id =: stdController.getRecord().Id];
    
    this.childList = [SELECT Id,
                          Name,
                          SCOP__c,
                          Influencer_Name__c,
                          Buying_influence_role__c,
                          Degree_of_Influence__c,
                          Rating_for_base_covered__c,
                          Equivalent_Collinson_Stakeholder__c
                          Evidence_to_support_your_rating__c
                          
                      FROM Buying_Influence__c
                      WHERE Opportunity_Positioning__c =: mysObject.Id];

     children = new List<Buying_Influence__c>();
     children.addALL(this.childList);
  }

  /*
   * This method is necessary for reference on the Visualforce page, 
   * in order to reference non-standard fields.
   */
  /*public List<Quota__c> getChildren()
  {
    return (List<Quota__c>)childList;
  }*/

  public PageReference saveChildren(){

      try{
           upsert children;
           //use the redirect method like the demographic page if needed after upsert
      }catch(DMLException saveEx){
         //do something
       }

       return null;
   }


  public override sObject initChildRecord()
  {
    Buying_Influence__c child = new Buying_Influence__c();
    child.Opportunity_Positioning__c = mydemo.Id;
   
    
    return child;
  }
}


 
Nayana KNayana K
public with sharing class EditableBuyingInfluenceExtension extends EditableBuyingInfluenceList
{
	public Opportunity_Positioning__c objOP 	{	get; set;	}
	public List<Buying_Influence__c> lstBI 		{	get; set;	}
	Integer removeIndex							{	get; set;	}
	
	public EditableBuyingInfluenceListExtension(ApexPages.StandardController stdController) 
	{
		super(stdController);
		
		objOP = new Opportunity_Positioning__c();
		lstBI = new List<Buying_Influence__c>();
		
		if(stdController.getId() != NULL)
		{
			lstBI = [SELECT Id,
                          Name,
                          SCOP__c,
                          Influencer_Name__c,
                          Buying_influence_role__c,
                          Degree_of_Influence__c,
                          Rating_for_base_covered__c,
                          Equivalent_Collinson_Stakeholder__c,
                          Evidence_to_support_your_rating__c,
						  Opportunity_Positioning__c, Opportunity_Positioning__r.Name, Opportunity_Positioning__r.Opportunity__c
                          
                      FROM Buying_Influence__c
                      WHERE Opportunity_Positioning__c =: stdController.getId()];
			if(!lstBI.isEmpty())
			{
				objOP.Id = lstBI[0].Opportunity_Positioning__c;
				objOP.Name = lstBI[0].Opportunity_Positioning__r.Name;
				objOP.Opportunity__c = lstBI[0].Opportunity_Positioning__r.Opportunity__c;
			}
			else
			{
				objOP = [SELECT Id, Name, Opportunity__c FROM Opportunity_Positioning__c WHERE Id =:stdController.getId()];
			}
		}
  }

	public void addToList()
	{
		lstBI.add(new Buying_Influence__c());
	}
	
	public void removeFromList()
	{
		system.debug('===removeIndex==='+removeIndex);
		lstBI.remove(removeIndex);
	}
	
   public PageReference saveChildren(){

      try{
			upsert objOP;
			
			for(Buying_Influence__c objBI : lstBI)
			{
				objBI.Opportunity_Positioning__c = objOP.Id;
			}
			if(!lstBI.isEmpty())
				upsert lstBI;
           PageReference p = new PageReference('/'+objOP.Id);
		   return p;
      }catch(Exception e){
         ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.ERROR, e.getMessage());
            ApexPages.addMessage(myMsg);
		 
       }

       return null;
   }


	  /*public override sObject initChildRecord()
	  {
		Buying_Influence__c child = new Buying_Influence__c();
		child.Opportunity_Positioning__c = mydemo.Id;
	   
		
		return child;
	  }*/
}
 
<apex:page standardcontroller="Opportunity_Positioning__c">
           extensions="EditableBuyingInfluenceExtension"
	<apex:sectionheader title="{!$ObjectType.Opportunity_Positioning__c.label} Edit" subtitle="{!IF(ISNULL(Opportunity_Positioning__c.Name), 'New/Edit Opportunity Position', Opportunity_Positioning__c.Name)}"/>
    <apex:form >
		<apex:pageMessages id = "messages"/>
		
        <apex:pageblock mode="edit" title="{!$ObjectType.Buying_Influence__c.label} Edit">
            <apex:pageblockbuttons >
                <apex:commandbutton value="Save" action="{!Save}" rerender="messages"/>
                <apex:commandbutton value="Cancel" action="{!Cancel}"/>
            </apex:pageblockbuttons>
			
            <apex:pageblocksection title="Information" showheader="true" columns="2">
				<apex:inputField value="{!objOP.Name}"/>
				<apex:inputField value="{!objOP.Opportunity__c}"/>
            <apex:pageBlockSection>
			
            <apex:pageblocksection id="childList" columns="1" title="Buying Influence" collapsible="false">
			
                <apex:variable var="rowNum" value="{!0}" />
				
                <apex:outputLabel value="No Buying Influence currently exist. Click below to Add." rendered="{!lstBI.size == 0}"/>
				<apex:pageBlockTable value="{!lstBI}" var="BI" rendered="{!lstBI.size > 0}">
					<apex:column headerValue= "Buying Influence">
						<apex:inputfield value="{!BI.Name}" required="true"/>
						
					<apex:column headerValue= "SCOP">
					<apex:inputfield value="{!BI.SCOP__c}" required="true"/>
					<apex:column headerValue= "Influencer Name">
					<apex:inputfield value="{!BI.Influencer_Name__c}" required="true"/>
					<apex:column headerValue= "Buying Influence role">
					<apex:inputfield value="{!BI.Buying_influence_role__c}" required="true"/>
					<apex:column headerValue= "Degree of Influence">
					<apex:inputfield value="{!BI.Degree_of_Influence__c}" required="true"/>
				  
				   </apex:column>
				   <apex:pageblocksection title="How well is based covered for this contact" showheader="true" columns="2">
				   </apex:pageblocksection>
				   </apex:column> headerValue="Rating for base covered">
						<apex:inputfield value="{!BI.Rating_for_base_covered__c}" required="true"/>
				   </apex:column> headerValue="Equivalent Collinson Stakeholder">
						<apex:inputfield value="{!BI.Equivalent_Collinson_Stakeholder__c}" required="false"/>
				   </apex:column> headerValue="Evidence to support your rating">
						<apex:inputfield value="{!BI.Evidence_to_support_your_rating__c}" required="false"/>
					</apex:column>
					<apex:column headerValue="">
					
						<apex:commandLink value="Delete" action="{!removeFromList}" rerender="childList,messages" immediate="true"> 
							<apex:param name="removeIndex" value="{!rowNum}" assignTo="{!removeIndex}"/>
						</apex:commandLink>
						
						<apex:variable var="rowNum" value="{!rowNum+1}" />
					</apex:column>
				</apex:pageBlockTable>
			
			<apex:commandButton value="Add Buying Influence" action="{!addToList}" rerender="childList, messages" immediate="true" />
      </apex:pageBlockSection>
</apex:pageblock>
</apex:form>
</apex:page>

Not Sure how effectively this will work or any error..Without trying in personal org, its bit difficult to trace if any mistakes in my code. STill you can give a try. 

by using immediate try, not sure whether assignTo rowNum will work or not. On removeFromList, I have kept debug, check whether removeIndex is set properly or not.
Rogerio Lara 2028Rogerio Lara 2028
Hi Nayana,

I'm getting this message now: 


Error: NewBuyingInfluence line 58, column 3: The element type "apex:pageblocksection" must be terminated by the matching end-tag "</apex:pageblocksection>"
Error: The element type "apex:pageblocksection" must be terminated by the matching end-tag "</apex:pageblocksection>".
Rogerio Lara 2028Rogerio Lara 2028
and for the Controller I am getting this message:

Error: Compile Error: No such column 'Opportunity_Positioning__c' on entity 'Buying_Influence__c'. If you are attempting to use a custom field, be sure to append the '__c' after the custom field name. Please reference your WSDL or the describe call for the appropriate names. at line 16 column 21
Rogerio Lara 2028Rogerio Lara 2028
Hi Nayana,

I think I will leave this visualforce pages for now due to the little time I have to find a quick solution that will help the end users.
I need to create a child record when a new parent record is created.

I am trying to create an Apex trigger that creates or forces a child record to be created when a new parent record is created, but unfortunately isn't working :-(

 
trigger CreateBuyingInfluence on Opportunity_Positioning__c (after insert)

 {
    List<Buying_Influence__c> Childs = new List<Buying_Influence__c>();

    for(Opportunity_Positioning__c a : trigger.new)
    {
       Buying_Influence__c Child = new Buying_Influence__c ();
       Child.SCOP__c = a.id;
       Buying_Influence__c.Name = 'testName'; 

       Childs.add(Child);      
    }

    insert Childs;
}

I'm getting this error message: Error: Compile Error: Expression cannot be assigned at line -1 column -1

As always, thank you for your time.
 
Nayana KNayana K
trigger CreateBuyingInfluence on Opportunity_Positioning__c (after insert)

 {
    List<Buying_Influence__c> Childs = new List<Buying_Influence__c>();

    for(Opportunity_Positioning__c a : trigger.new)
    {
       Buying_Influence__c Child = new Buying_Influence__c ();
       Child.SCOP__c = a.id;
      Child.Name = 'testName'; 

       Childs.add(Child);      
    }

    insert Childs;
}

 
Rogerio Lara 2028Rogerio Lara 2028
Thank you Nayana. It’s setting off the trigger but because I have required field on the child object Buying Influence I am getting an error. Is there a workaround it, or will I have to remove “required” from the fields? Error: Invalid Data. Review all error messages below to correct your data. Apex trigger CreateBuyingInfluence caused an unexpected exception, contact your administrator: CreateBuyingInfluence: execution of AfterInsert caused by: System.DmlException: Insert failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, Required fields are missing: [Degree of Influence, Rating for base covered]: [Degree of Influence, Rating for base covered]: Trigger.CreateBuyingInfluence: line 15, column 1
Rogerio Lara 2028Rogerio Lara 2028
What if I just want to redirect the page? Let’s say, when the Opportunity Positioning is created then upon saving the record a trigger will prompt me to create Buying Influences or direct me to the buying influence pages.? I removed required from those fields and the trigger is creating a new record but with 5 fields not being populated. Any suggestions as to what would be best in this case? Thank you so much. Rog
Nayana KNayana K
<apex:page standardcontroller="Opportunity_Positioning__c"
           extensions="EditableBuyingInfluenceExtension">
	<apex:sectionheader title="{!$ObjectType.Opportunity_Positioning__c.label} Edit" subtitle="{!IF(ISNULL(Opportunity_Positioning__c.Name), 'New/Edit Opportunity Position', Opportunity_Positioning__c.Name)}"/>
    <apex:form >
	
		 <apex:actionStatus id="eventStatus"  >
             <apex:facet name="start">
              <apex:outputPanel >
                <div id="loadingComponent" 
                     style="width:100%; height:100%; position:absolute; top:0; 
                            left:0; background-color: black; opacity: 0.4; z-index: 999;">
                    <div style="position:absolute;top:50%;left:50%">
                        <apex:image value="/img/loading32.gif"></apex:image> 
                    </div>
                </div>
               </apex:outputPanel>
            </apex:facet>   
        </apex:actionStatus>
		
		<apex:pageMessages id = "messages"/>
		
        <apex:pageblock mode="edit" title="{!$ObjectType.Buying_Influence__c.label} Edit">
            <apex:pageblockbuttons >
                <apex:commandbutton value="Save" action="{!saveChildren}" rerender="messages" status="eventStatus"/>
                <apex:commandbutton value="Cancel" action="{!cancel}" rerender="messages" status="eventStatus"/>
            </apex:pageblockbuttons>
			
            <apex:pageblocksection title="Information" showheader="true" columns="2">
				<apex:inputField value="{!objOP.Name}"/>
				<apex:inputField value="{!objOP.Opportunity__c}"/>
            </apex:pageBlockSection>
			
            <apex:pageblocksection id="childList" columns="1" title="Buying Influence" collapsible="false">
			
                <apex:variable var="rowNum" value="{!0}" />
				
                <apex:outputLabel value="No Buying Influence currently exist. Click below to Add." rendered="{!lstBI.size == 0}"/>
				<apex:pageBlockTable value="{!lstBI}" var="BI" rendered="{!lstBI.size > 0}">
					<apex:column headerValue= "Buying Influence">
						<apex:inputfield value="{!BI.Name}"/>
					</apex:column>	
					<apex:column headerValue= "SCOP">
						<apex:inputfield value="{!BI.SCOP__c}"/>
					</apex:column>	
					<apex:column headerValue= "Influencer Name">
						<apex:inputfield value="{!BI.Influencer_Name__c}"/>
					</apex:column>	
					<apex:column headerValue= "Buying Influence role">
						<apex:inputfield value="{!BI.Buying_influence_role__c}"/>
					</apex:column>	
					<apex:column headerValue= "Degree of Influence">
						<apex:inputfield value="{!BI.Degree_of_Influence__c}"/>
					</apex:column>	
				  
				   </apex:column headerValue="Rating for base covered">
						<apex:inputfield value="{!BI.Rating_for_base_covered__c}" />
					</apex:column>	
					
				   <apex:column headerValue="Equivalent Collinson Stakeholder">
						<apex:inputfield value="{!BI.Equivalent_Collinson_Stakeholder__c}"/>
					</apex:column>	
					
				   <apex:column headerValue="Evidence to support your rating">
						<apex:inputfield value="{!BI.Evidence_to_support_your_rating__c}"/>
					</apex:column>
					
					<apex:column headerValue="">
					
						<apex:commandLink value="Remove" action="{!removeFromList}" rerender="childList,messages" immediate="true" status="eventStatus"> 
							<apex:param name="removeIndex" value="{!rowNum}" assignTo="{!removeIndex}"/>
						</apex:commandLink>
						
						<apex:variable var="rowNum" value="{!rowNum+1}" />
					</apex:column>
					
				</apex:pageBlockTable>
			
			<apex:commandButton value="Add Buying Influence" action="{!addToList}" rerender="childList, messages" immediate="true" "eventStatus"/>
      </apex:pageBlockSection>
</apex:pageblock>
</apex:form>
</apex:page>
 
public with sharing class EditableBuyingInfluenceExtension 
{
	public Opportunity_Positioning__c objOP 	{	get; set;	}
	public List<Buying_Influence__c> lstBI 		{	get; set;	}
	public Integer removeIndex							{	get; set;	}
	
	public EditableBuyingInfluenceListExtension(ApexPages.StandardController stdController) 
	{
		objOP = new Opportunity_Positioning__c();
		lstBI = new List<Buying_Influence__c>();
		
		if(stdController.getId() != NULL)
		{
			lstBI = [SELECT Id,
                          Name,
                          SCOP__c,
                          Influencer_Name__c,
                          Buying_influence_role__c,
                          Degree_of_Influence__c,
                          Rating_for_base_covered__c,
                          Equivalent_Collinson_Stakeholder__c,
                          Evidence_to_support_your_rating__c,
						  Opportunity_Positioning__c, Opportunity_Positioning__r.Name, Opportunity_Positioning__r.Opportunity__c
                          
                      FROM Buying_Influence__c
                      WHERE Opportunity_Positioning__c =: stdController.getId()];
			if(!lstBI.isEmpty())
			{
				objOP.Id = lstBI[0].Opportunity_Positioning__c;
				objOP.Name = lstBI[0].Opportunity_Positioning__r.Name;
				objOP.Opportunity__c = lstBI[0].Opportunity_Positioning__r.Opportunity__c;
			}
			else
			{
				objOP = [SELECT Id, Name, Opportunity__c FROM Opportunity_Positioning__c WHERE Id =:stdController.getId()];
			}
		}
  }

	public void addToList()
	{
		lstBI.add(new Buying_Influence__c());
	}
	
	public void removeFromList()
	{
		system.debug('===removeIndex==='+removeIndex);
		lstBI.remove(removeIndex);
	}
	
   public PageReference saveChildren(){

      try{
			upsert objOP;
			
			for(Buying_Influence__c objBI : lstBI)
			{
				objBI.Opportunity_Positioning__c = objOP.Id;
			}
			if(!lstBI.isEmpty())
				upsert lstBI;
           PageReference p = new PageReference('/'+objOP.Id);
		   return p;
      }catch(Exception e){
         ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.ERROR, e.getMessage());
            ApexPages.addMessage(myMsg);
		 
       }

       return null;
   }
   
	public PageReference cancel()
    {
        if(objOP.Id != null)
            return new Pagereference('/'+objOP.Id);
         return null;
    }
}

Please try this code and let me know if any issues.
Rogerio Lara 2028Rogerio Lara 2028
Hi Nayana, Thank you for this. I am getting the following error message: [Description: Error] Error: OppPlan line 55, column 22: The element type "apex:pageblocksection" must be terminated by the matching end-tag "" [Description: Error] Error: The element type "apex:pageblocksection" must be terminated by the matching end-tag "".
Nayana KNayana K
<apex:page standardcontroller="Opportunity_Positioning__c"
           extensions="EditableBuyingInfluenceExtension">
	<apex:sectionheader title="{!$ObjectType.Opportunity_Positioning__c.label} Edit" subtitle="{!IF(ISNULL(Opportunity_Positioning__c.Name), 'New/Edit Opportunity Position', Opportunity_Positioning__c.Name)}"/>
    <apex:form >
	
		 <apex:actionStatus id="eventStatus"  >
             <apex:facet name="start">
              <apex:outputPanel >
                <div id="loadingComponent" 
                     style="width:100%; height:100%; position:absolute; top:0; 
                            left:0; background-color: black; opacity: 0.4; z-index: 999;">
                    <div style="position:absolute;top:50%;left:50%">
                        <apex:image value="/img/loading32.gif"></apex:image> 
                    </div>
                </div>
               </apex:outputPanel>
            </apex:facet>   
        </apex:actionStatus>
		
		<apex:pageMessages id = "messages"/>
		
        <apex:pageblock mode="edit" title="{!$ObjectType.Buying_Influence__c.label} Edit">
            <apex:pageblockbuttons >
                <apex:commandbutton value="Save" action="{!saveChildren}" rerender="messages" status="eventStatus"/>
                <apex:commandbutton value="Cancel" action="{!cancel}" rerender="messages" status="eventStatus"/>
            </apex:pageblockbuttons>
			
            <apex:pageblocksection title="Information" showheader="true" columns="2">
				<apex:inputField value="{!objOP.Name}"/>
				<apex:inputField value="{!objOP.Opportunity__c}"/>
            </apex:pageBlockSection>
			
            <apex:pageblocksection id="childList" columns="1" title="Buying Influence" collapsible="false">
			
                <apex:variable var="rowNum" value="{!0}" />
				
                <apex:outputLabel value="No Buying Influence currently exist. Click below to Add." rendered="{!lstBI.size == 0}"/>
				<apex:pageBlockTable value="{!lstBI}" var="BI" rendered="{!lstBI.size > 0}">
					<apex:column headerValue= "Buying Influence">
						<apex:inputfield value="{!BI.Name}"/>
					</apex:column>	
					
					<apex:column headerValue= "SCOP">
						<apex:inputfield value="{!BI.SCOP__c}"/>
					</apex:column>	
					
					<apex:column headerValue= "Influencer Name">
						<apex:inputfield value="{!BI.Influencer_Name__c}"/>
					</apex:column>	
					
					<apex:column headerValue= "Buying Influence role">
						<apex:inputfield value="{!BI.Buying_influence_role__c}"/>
					</apex:column>
					
					<apex:column headerValue= "Degree of Influence">
						<apex:inputfield value="{!BI.Degree_of_Influence__c}"/>
					</apex:column>	
				  
				   <apex:column headerValue="Rating for base covered">
						<apex:inputfield value="{!BI.Rating_for_base_covered__c}" />
					</apex:column>	
					
				   <apex:column headerValue="Equivalent Collinson Stakeholder">
						<apex:inputfield value="{!BI.Equivalent_Collinson_Stakeholder__c}"/>
					</apex:column>	
					
				   <apex:column headerValue="Evidence to support your rating">
						<apex:inputfield value="{!BI.Evidence_to_support_your_rating__c}"/>
					</apex:column>
					
					<apex:column headerValue="">
					
						<apex:commandLink value="Remove" action="{!removeFromList}" rerender="childList,messages" immediate="true" status="eventStatus"> 
							<apex:param name="removeIndex" value="{!rowNum}" assignTo="{!removeIndex}"/>
						</apex:commandLink>
						
						<apex:variable var="rowNum" value="{!rowNum+1}" />
					</apex:column>
					
				</apex:pageBlockTable>
			
			<apex:commandButton value="Add Buying Influence" action="{!addToList}" rerender="childList, messages" immediate="true" "eventStatus"/>
      </apex:pageBlockSection>
</apex:pageblock>
</apex:form>
</apex:page>

 
Rogerio Lara 2028Rogerio Lara 2028
Thank you Nayana, I’m trying to fix the below now. I’m getting this message [Description: Error] Error: Tes line 82, column 132: Element type "apex:commandButton" must be followed by either attribute specifications, ">" or "/>" [Description: Error] Error: Element type "apex:commandButton" must be followed by either attribute specifications, ">" or "/>".
Rogerio Lara 2028Rogerio Lara 2028
I can that line, but not sure why I’m still getting the message: [Description: Error] Error: Tes line 82, column 132: Element type "apex:commandButton" must be followed by either attribute specifications, ">" or "/>" [Description: Error] Error: Element type "apex:commandButton" must be followed by either attribute specifications, ">" or "/>".
Nayana KNayana K
<apex:commandButton value="Add Buying Influence" action="{!addToList}" rerender="childList, messages" immediate="true" status="eventStatus"/>
Rogerio Lara 2028Rogerio Lara 2028
I am really excited now. This is the farthest we got. Just a question, should I do the following or use the other class? [Description: Error] Error: Apex class 'EditableBuyingInfluenceExtension' does not exist [Description: Quick Fix] Create Apex class 'public with sharing class EditableBuyingInfluenceExtension' [Description: Quick Fix] Create Apex class 'public class EditableBuyingInfluenceExtension'
Rogerio Lara 2028Rogerio Lara 2028
So sorry :-( I am now getting this message: Error: Unknown method 'Opportunity_Positioning__cStandardController.saveChildren()'
Nayana KNayana K
Go with any and replace code
Nayana KNayana K
Strange! I have called saveChildren in page and have written code in extension too and method is public!
Rogerio Lara 2028Rogerio Lara 2028
I’m getting this message when trying to create the controller: Error: Compile Error: No such column 'Opportunity_Positioning__c' on entity 'Buying_Influence__c'. If you are attempting to use a custom field, be sure to append the '__c' after the custom field name. Please reference your WSDL or the describe call for the appropriate names. at line 14 column 21
Rogerio Lara 2028Rogerio Lara 2028
This is the extension I am trying to create:

Error: Compile Error: No such column 'Opportunity_Positioning__c' on entity 'Buying_Influence__c'. If you are attempting to use a custom field, be sure to append the '__c' after the custom field name. Please reference your WSDL or the describe call for the appropriate names. at line 14 column 21
 
public with sharing class EditableBuyingInfluenceExtension 
{
    public Opportunity_Positioning__c objOP     {   get; set;   }
    public List<Buying_Influence__c> lstBI      {   get; set;   }
    public Integer removeIndex                          {   get; set;   }
    
    public EditableBuyingInfluenceListExtension(ApexPages.StandardController stdController) 
    {
        objOP = new Opportunity_Positioning__c();
        lstBI = new List<Buying_Influence__c>();
        
        if(stdController.getId() != NULL)
        {
            lstBI = [SELECT Id,
                          Name,
                          SCOP__c,
                          Influencer_Name__c,
                          Buying_influence_role__c,
                          Degree_of_Influence__c,
                          Rating_for_base_covered__c,
                          Equivalent_Collinson_Stakeholder__c,
                          Evidence_to_support_your_rating__c,
                          Opportunity_Positioning__c, Opportunity_Positioning__r.Name, Opportunity_Positioning__r.Opportunity__c
                          
                      FROM Buying_Influence__c
                      WHERE Opportunity_Positioning__c =: stdController.getId()];
            if(!lstBI.isEmpty())
            {
                objOP.Id = lstBI[0].Opportunity_Positioning__c;
                objOP.Name = lstBI[0].Opportunity_Positioning__r.Name;
                objOP.Opportunity__c = lstBI[0].Opportunity_Positioning__r.Opportunity__c;
            }
            else
            {
                objOP = [SELECT Id, Name, Opportunity__c FROM Opportunity_Positioning__c WHERE Id =:stdController.getId()];
            }
        }
  }

    public void addToList()
    {
        lstBI.add(new Buying_Influence__c());
    }
    
    public void removeFromList()
    {
        system.debug('===removeIndex==='+removeIndex);
        lstBI.remove(removeIndex);
    }
    
   public PageReference saveChildren(){

      try{
            upsert objOP;
            
            for(Buying_Influence__c objBI : lstBI)
            {
                objBI.Opportunity_Positioning__c = objOP.Id;
            }
            if(!lstBI.isEmpty())
                upsert lstBI;
           PageReference p = new PageReference('/'+objOP.Id);
           return p;
      }catch(Exception e){
         ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.ERROR, e.getMessage());
            ApexPages.addMessage(myMsg);
         
       }

       return null;
   }
   
    public PageReference cancel()
    {
        if(objOP.Id != null)
            return new Pagereference('/'+objOP.Id);
         return null;
    }
}

 
Nayana KNayana K
Is it not Opportunity_Positioning__c is parent field API name? Put proper name there
Rogerio Lara 2028Rogerio Lara 2028
You are correct. The API name is Opportunity_Positioning__c. and I created a master relationship with Opportunities.
Nayana KNayana K
Weired, If API name is proper then it won't throw error. Can you please post screenshot of field page.
Rogerio Lara 2028Rogerio Lara 2028


User-added imageUser-added image
Nayana KNayana K
Hmm we were using wrong API Name.
public with sharing class EditableBuyingInfluenceExtension 
{
    public Opportunity_Positioning__c objOP     {   get; set;   }
    public List<Buying_Influence__c> lstBI      {   get; set;   }
    public Integer removeIndex                          {   get; set;   }
    
    public EditableBuyingInfluenceListExtension(ApexPages.StandardController stdController) 
    {
        objOP = new Opportunity_Positioning__c();
        lstBI = new List<Buying_Influence__c>();
        
        if(stdController.getId() != NULL)
        {
            lstBI = [SELECT Id,
                          Name,
                          SCOP__c,
                          Influencer_Name__c,
                          Buying_influence_role__c,
                          Degree_of_Influence__c,
                          Rating_for_base_covered__c,
                          Equivalent_Collinson_Stakeholder__c,
                          Evidence_to_support_your_rating__c,
                          SCOP__c, SCOP__r.Name, SCOP__r.Opportunity__c
                          
                      FROM Buying_Influence__c
                      WHERE SCOP__c =: stdController.getId()];
            if(!lstBI.isEmpty())
            {
                objOP.Id = lstBI[0].SCOP__c;
                objOP.Name = lstBI[0].SCOP__r.Name;
                objOP.Opportunity__c = lstBI[0].SCOP__r.Opportunity__c;
            }
            else
            {
                objOP = [SELECT Id, Name, Opportunity__c FROM Opportunity_Positioning__c WHERE Id =:stdController.getId()];
            }
        }
  }

    public void addToList()
    {
        lstBI.add(new Buying_Influence__c());
    }
    
    public void removeFromList()
    {
        system.debug('===removeIndex==='+removeIndex);
        lstBI.remove(removeIndex);
    }
    
   public PageReference saveChildren(){

      try{
            upsert objOP;
            
            for(Buying_Influence__c objBI : lstBI)
            {
                objBI.SCOP__c = objOP.Id;
            }
            if(!lstBI.isEmpty())
                upsert lstBI;
           PageReference p = new PageReference('/'+objOP.Id);
           return p;
      }catch(Exception e){
         ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.ERROR, e.getMessage());
            ApexPages.addMessage(myMsg);
         
       }

       return null;
   }
   
    public PageReference cancel()
    {
        if(objOP.Id != null)
            return new Pagereference('/'+objOP.Id);
         return null;
    }
}


 
Rogerio Lara 2028Rogerio Lara 2028
I see ;-) . 

Error: Compile Error: duplicate field selected: SCOP__c at line 14 column 21

I can't see it. :-/
Nayana KNayana K
lstBI = [SELECT Id,
                          Name,
                          SCOP__c,
                          Influencer_Name__c,
                          Buying_influence_role__c,
                          Degree_of_Influence__c,
                          Rating_for_base_covered__c,
                          Equivalent_Collinson_Stakeholder__c,
                          Evidence_to_support_your_rating__c,
                           SCOP__r.Name, SCOP__r.Opportunity__c
                          
                      FROM Buying_Influence__c
                      WHERE SCOP__c =: stdController.getId()];

 
Rogerio Lara 2028Rogerio Lara 2028
Thank you. Now, invalid constructor name

Error: Compile Error: Invalid constructor name: EditableBuyingInfluenceListExtension at line 7 column 12
Nayana KNayana K
EditableBuyingInfluenceExtension has to be extension name and I hope you are creating this class. EditableBuyingInfluenceListExtension is different name!
Rogerio Lara 2028Rogerio Lara 2028
I am trying to create class but I am getting this message
Error: Compile Error: Invalid constructor name: EditableBuyingInfluenceListExtension at line 7 column 12
Nayana KNayana K
public with sharing class EditableBuyingInfluenceExtension 
{
    public Opportunity_Positioning__c objOP     {   get; set;   }
    public List<Buying_Influence__c> lstBI      {   get; set;   }
    public Integer removeIndex                          {   get; set;   }
    
    public EditableBuyingInfluenceExtension(ApexPages.StandardController stdController) 
    {
        objOP = new Opportunity_Positioning__c();
        lstBI = new List<Buying_Influence__c>();
        
        if(stdController.getId() != NULL)
        {
            lstBI = [SELECT Id,
                          Name,
                          SCOP__c,
                          Influencer_Name__c,
                          Buying_influence_role__c,
                          Degree_of_Influence__c,
                          Rating_for_base_covered__c,
                          Equivalent_Collinson_Stakeholder__c,
                          Evidence_to_support_your_rating__c,
                           SCOP__r.Name, SCOP__r.Opportunity__c
                          
                      FROM Buying_Influence__c
                      WHERE SCOP__c =: stdController.getId()];
            if(!lstBI.isEmpty())
            {
                objOP.Id = lstBI[0].SCOP__c;
                objOP.Name = lstBI[0].SCOP__r.Name;
                objOP.Opportunity__c = lstBI[0].SCOP__r.Opportunity__c;
            }
            else
            {
                objOP = [SELECT Id, Name, Opportunity__c FROM Opportunity_Positioning__c WHERE Id =:stdController.getId()];
            }
        }
  }

    public void addToList()
    {
        lstBI.add(new Buying_Influence__c());
    }
    
    public void removeFromList()
    {
        system.debug('===removeIndex==='+removeIndex);
        lstBI.remove(removeIndex);
    }
    
   public PageReference saveChildren(){

      try{
            upsert objOP;
            
            for(Buying_Influence__c objBI : lstBI)
            {
                objBI.SCOP__c = objOP.Id;
            }
            if(!lstBI.isEmpty())
                upsert lstBI;
           PageReference p = new PageReference('/'+objOP.Id);
           return p;
      }catch(Exception e){
         ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.ERROR, e.getMessage());
            ApexPages.addMessage(myMsg);
         
       }

       return null;
   }
   
    public PageReference cancel()
    {
        if(objOP.Id != null)
            return new Pagereference('/'+objOP.Id);
         return null;
    }
}

 
Nayana KNayana K
Extremely sorry :( I am doing lots of mistakes
Rogerio Lara 2028Rogerio Lara 2028
Great news the controller saved. Now I will test it. No need to apologise at all. I am ever so grateful for working together on this with me. Rog
Nayana KNayana K
All ok Rog?
Rogerio Lara 2028Rogerio Lara 2028
It's creating the page ;-) which is really exciting. But, when I add it as new button to the SCOP related listbto the opportunity I'm getting the following error messages:

User-added image
When I click the Button:
Id value 00626000004aBMr is not valid for the Opportunity_Positioning__c standard controller 

Then, if I remove the id value from the URL then it takes me to the page above. So then If I click the Add Buying Influenc the I get another message.

Rerender is not currently supported with rich text editing enabled 
Nayana KNayana K
Oh I have not worked with rich text area in VF page. What you can do is comment the whole apex:column for the field containing rich text and try again (Just to check if working for other fields). Give valid OP id and check the functionality
Rogerio Lara 2028Rogerio Lara 2028
Thank you so much Nayana. I will try that and see how I get on.

Have a great weekend!

Best,
Rog