2

I have a master detail relation ship between two objects where NdF__c is the parent, and the child is LineExpense__c.

I want to insert many LineExpense__c relating to one NdF__c, so I add dynamically LineExpense__c rows using a wrapper class. The probleme I have I guess, is in the save() method, I need to assign NdF__c ID in LineExpense__c with the current inserting NdF__c. the relationship name is LineExpenses__r

here is my controller: public with sharing class CTRL002LineExpense {

   private ID ndfId;
    public List<NdF__c> lstNDF{get;set;}
 public List<LineExpenseWrapper> wrappers {get; set;}
 public static Integer toDelIdent {get; set;}
 public static Integer addCount {get; set;}
 private Integer nextIdent=0;
 String NDFId = ApexPages.currentPage().getParameters().get('NdF__c.ID');

public CTRL002LineExpense(ApexPages.StandardController controller) {

    ndfId= controller.getId();
    wrappers=new List<LineExpenseWrapper>();
      for (Integer idx=0; idx<5; idx++)
       {
        wrappers.add(new LineExpenseWrapper(nextIdent++));
       }
    }


    public void delWrapper()
   {
    Integer toDelPos=-1;
   for (Integer idx=0; idx<wrappers.size(); idx++)
   {
   if (wrappers[idx].ident==toDelIdent)
   {
   toDelPos=idx;
  }
  }
  if (-1!=toDelPos){
  wrappers.remove(toDelPos);
 }
}
public void addRows(){
 for (Integer idx=0; idx<addCount; idx++)
 {
 wrappers.add(new LineExpenseWrapper(nextIdent++));
}
   }

    public PageReference save()
        {
       List<NdF__c> lstNDF= new List<NdF__c>();
  List<LineExpense__c> expes=new List<LineExpense__c>();

  for(NdF__c ndf: lstNDF){
  for (LineExpenseWrapper wrap : wrappers)
  {
       ndf.ID=ndfId;
       wrap.exp.Expense__r.ID=ndfId;
       expes.add(wrap.exp);
 }
  }
      insert lstNDF;
      insert expes;
      return new PageReference('/' + Schema.getGlobalDescribe().get('NdF__c').getDescribe().getKeyPrefix() + '/o'); 
       }
 public PageReference cancel()
  {
 return null;
} 

  public class LineExpenseWrapper
   {
   public LineExpense__c exp{get; private set;}
     public Integer ident {get; private set;}
     public LineExpenseWrapper(Integer inIdent)
     {
          ident=inIdent;
          exp= new LineExpense__c();
     }
    }
   }

And my VF page is:

         <apex:pageBlockButtons location="top">
         <apex:commandButton value="Save" action="{!save}" />
            <apex:commandButton value="Cancel" action="{!cancel}"/>
            </apex:pageBlockButtons>

            <apex:actionRegion >
                <apex:pageBlockSection title="Expenses Information" columns="2">
                <apex:inputField value="{!NdF__c.Start_date__c}"/>
                <apex:inputField value="{!NdF__c.End_date__c}"/>
            </apex:pageBlockSection>
         </apex:actionRegion>

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

     <apex:column headerValue="Date">
        <apex:inputField value="{!wrapper.exp.Date__c}"/>
     </apex:column>

     <apex:column headerValue="Food / Meal Expenses">
        <apex:inputText value="{!wrapper.exp.Food_Expenses__c}"/>
     </apex:column>
     <apex:column headerValue="Transport Expenses">
        <apex:inputField value="{!wrapper.exp.Transport_Expenses__c}"/>
     </apex:column>
     <apex:column headerValue="Phone Expenses">
        <apex:inputField value="{!wrapper.exp.Phone_Expenses__c}"/>
     </apex:column> 
     <apex:column headerValue="Other Expenses">
        <apex:inputField value="{!wrapper.exp.Other_Expenses__c}"/>
     </apex:column> 
      <apex:column headerValue="Comment">
        <apex:inputField value="{!wrapper.exp.Comment__c}"/>
     </apex:column> 
    <!-- <apex:column headerValue="File" value="{!}">
    <apex:inputFile value="{!wrapper.att.body}" filename="{!wrapper.att.name}"/>
    </apex:column> --> 
     <apex:column headerValue="Action">
        <apex:commandButton value="Delete" action="{!delWrapper}" rerender="wtable">
           <apex:param name="toDelIdent" value="{!wrapper.ident}" assignTo="{!toDelIdent}"/> 
        </apex:commandButton>
     </apex:column> 
  </apex:pageBlockTable>
     </apex:pageblockSection> 
  <apex:commandButton value="Add Row" action="{!addRows}" rerender="wtable">
     <apex:param name="addCount" value="1" assignTo="{!addCount}"/> 
  </apex:commandButton>
  <apex:commandButton value="Add 5 Rows" action="{!addRows}" rerender="wtable">
     <apex:param name="addCount" value="5" assignTo="{!addCount}"/> 
  </apex:commandButton>

         <apex:pageBlockButtons location="bottom">
             <apex:commandButton value="Save" action="{!save}" />
            <apex:commandButton value="Cancel" action="{!cancel}"/>
            </apex:pageBlockButtons>

enter image description here

Here is a screenshot of my vf page:

2

Note this has changed based on the comments.

This is the sort of code I would expect to see:

 private ApexPages.StandardController sc;
 public CTRL002LineExpense(ApexPages.StandardController sc)
 {
     this.sc = sc;
     ...
 }
 public PageReference save() {
     ...
     Ndf__c ndf = (Ndf__c) sc.getRecord();
     upsert ndf;
     List<LineExpense__c> expes = new List<LineExpense__c>();
     for (LineExpenseWrapper wrap : wrappers)
     {
         wrap.exp.NdF__c = ndf.Id;
         expes.add(wrap.exp);
     }
     insert expes;        // Or upsert if this page supported editing
     ...
 }

The above code will work for the "new" as well as "edit" case because it does an upsert (insert or update as needed) of the Ndf__c object. Once that has been done the object will have an Id assigned and it is that Id that should be directly assigned to the "foreign key" Id field of the LineExpense__c objects.

  • Yes you are right, I edited my code, but the error still on insert expes; because I have to insert the NdF__c here. do I have to work on my wrapper class? – LoveLace May 29 '14 at 11:04
  • Are you saying that the parent object does not exist before the save? In that case you first insert that object which will set its Id field, and then set that Id on the child objects and then insert them. – Keith C May 29 '14 at 11:08
  • Yes, I will insert both parent and children at the same time. I add this line: wrap.exp.Expense__r.ID=ndfId; to the save() method but still not working. see my save() method edit – LoveLace May 29 '14 at 11:16
  • I've modified my answer. See e.g. salesforce.stackexchange.com/questions/13548/… that explains that you can;t create relationships via the __r fields (except when external ids are used which is not a common case). – Keith C May 29 '14 at 13:27
  • I get this error REQUIRED_FIELD_MISSING, Required fields are missing: [Start date, End date]: [Start date, End date] from upsert ndf line – LoveLace May 29 '14 at 13:49
0

All you need do to is sc.getID() after the save of main object Ndf__c and assign that id value to the child records by iterating through the line expenses list and then call the insert of line expenses.

Regards Kamal

0

Here is a link to the compete solution. You can use as is:

https://salesforcemann.wordpress.com/2016/11/11/pet-project-create-parent-and-child-records-from-visualforce-page-for-any-salesforce-object/?1=1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.