1

Assuming I have a page that searches for a certain Parent (Parent1__c) record, wherein upon search, all its details including its child (Child1__c) records would be displayed automatically. Each child record has a checkbox for selection.

However, there's this another custom object (Child2__c), child object of Parent2__c (used as the standardcontroller).

How can I select and update all selected rows, and at the same time, map and insert all the selected values to Child2__c object?

Controller:

public class SampleController {

    private ApexPages.StandardController con;
    public Parent2__c parent2 {get;set;}
    public Parent1__c parent1qry {get;set;}
    public List<wrapper1> wrapList1 {get;set;}
    public List<wrapper2> wrapList2 {get;set;}
    public List<Parent2__c> parent2list {get;set;}
    public List<Child2__c> child2list {get;set;}
    public Parent2__c NewParent2 {get;set;}

    public SampleController(ApexPages.StandardController controller) {
        con = controller;

        wrapList1 = new List<wrapper1>();
        parent2 = new Parent2__c();
        parent1 = new Parent1__c();
        parent2list = new List<Parent2__c>(); 
        child2list = new List<Child2__c>();
    }

    public void init() {

        List<Child1__c> items = new List<Child1__c>();

        List<wrapper1> tempWrap = new List<wrapper1>();

        if(parent2.Parent1__c != null) {
            parent1qry = [SELECT Id, Name, Account__c, Account__r.Name,  Date__c, Total_Amount__c FROM Parent1__c WHERE Id=:parent2.Parent1__c];

            items = [SELECT Id, Parent1__c, Item__c,  Item__r.Name, Quantity__c, Unit_Price__c, Total_Price__c FROM Child1__c WHERE Parent1__c =: parent2.Parent1__c];

        }

        for(Child1__c liloop : items) {
            tempWrap.add(new wrapper1(false,liloop));
        }


        if(tempWrap != null) {
            wrapper1 = tempWrap;
        }
    }

    public PageReference save() {

        List<Parent2__c> ListParent2 = new List<Parent2__c>();
        List<wrapper2> LineItemList = new List<wrapper2>(); 
        List<Child1__c> litem = new List<Child1__c>(); 
        Parent2__c NewParent2 = new Parent2__c();

        NewParent2.Date_of_Return__c = parent2.Date_of_Return__c;
        NewParent2.Customer_Name__c = parent1qry.Account__c;


        Set<Id> newIds = new Set<Id>();

        for(wrapper1 wloop : wrapList1) {
            if(wloop.IsSelected) {
                NewParent2.Child1__c = wloop.line.Id;
                if(wloop.line.Parent1__c != null) {
                    NewParent2.Parent1__c = wloop.line.Parent1__c;

                }
                ListParent2.add(NewParent2);
            }
        }

        if(ListParent2.size() > 0) {
            insert ListParent2;

            Set<Id> ids = new Set<Id>();

             for(Parent2__c idloop : ListParent2) {
                ids.add(idloop.Id);

            } 

            List<Parent2__c> parent2qry = [SELECT Id, Name, Customer_Name__c, Date_of_Return__c, Parent1__c, Child1__c FROM Parent2__c WHERE ID IN : ids];


            parent2list = parent2qry; 


        }

        PageReference pageref = new PageReference('/' + NewParent2.Id);
        pageref.setRedirect(true);
        return pageref;
    } 

    public class wrapper1 {
        public Child1__c line {get;set;}
        public Boolean IsSelected {get;set;}

        public wrapper1(Boolean s, Child1__c li) {

            IsSelected = s;
            line = li;  

        }

    } 

    public class wrapper2 {
        public Child2__c c2 {get;set;}
        public Integer index {get;set;}

    }


}

Sample

Let's assume on the Parent__2 page, the user searched for this record from the Parent1__c object: Receipt12345678

After searching, some details about Receipt12345678, including all the bought products (Child1__c), would be displayed automatically like this:

Receipt # (Parent1__c): Receipt12345678
Date Purchased: 1/1/2016
Total Amount: 23,000.00

Products Bought:

enter image description here

Note that return reasons and # of items to return fields are empty upon display. Values for these fields will be inputted manually by the user right on this page alone.

When the save button is clicked, all the selected values from the Child1__c must be updated, and all the selected rows from this table must be inserted to Child2__c related list like this:

enter image description here

  • can you share the code what you have done so far. – Tushar Sharma Aug 8 '16 at 8:50
  • @TusharSharma pls see added controller in my edited post. – Gaynerys Aug 8 '16 at 9:25
  • In my controller, only the details of the Parent1__c record are successfully inserted. – Gaynerys Aug 8 '16 at 13:53
  • If parent2 is the target object of the controller extension, you are losing the reference to it with the constructor line parent2 = new Parent2__c(); - I think you need parent2 = controller.getRecord();. That said, the question is confusing and could get more help by using edit to put in a specific example of what you want to do – cropredy Aug 8 '16 at 19:11
  • @cropredy I don't have any problem regarding Parent2__c record insertion. I just explained what my posted controller is doing for the mean time, since it is also a requirement to insert new Parent2__c record. But my main concern here is I can't update the selected records from the Child1__c object, and at the same time, map and insert those selected Child1__c field values to Child2__c field values. – Gaynerys Aug 9 '16 at 1:36
0

Thank you for the edited post, it is much clearer now

At its essence, your problem is how to copy the fields from Child1__c to Child2__c, both of which you are managing inside of respective inner classes Wrapper1 and Wrapper2

This can be done as follows inside your save() method

map<Schema.SObjectField,Schema.SObjectField> fromFldToFldMap = 
          new map<Schema.SObjectField,SChema.SObjectField> {
               Child1__c.Foo__c => Child2__c.Foo__c,
               Child1__c.Bar__c => Child2__c.Bar__c,
               ... note Child2 field names don't have to be same as Child1
               .. but types must be same};

Wrapper2[] wrapList2 = new List<Wrapper2>();   
for (Wrapper1 w1 : wrapList1) { //copies all Child1s to Child2s
   Wrapper2 w2 = new Wrapper2();
   w2.c2 = new Child2__c(Parent2__c = parent2.Id); // parent of ea Child2
   w2.index = wrap2List.size();
   wrap2List.add(w2);   // add to list of all Child2

   // Copy values from Child1 obj to Child2 obj using our map of source name to target name
   // Relies on SObject class methods get(..) and put(..)
   for (Schema.SObjectField fldToken : fromFldToFldMap.keySet())
       w2.c2.put(fromFldToFldMap.get(fldToken),  // name of fld in Child2
                 w1.line.get(fldToken);        // value (as Object) of corresp fld in Child1
}

I omitted any check for isSelected in wrapper1 if that influences the copy - you can easily add that in yourself

I also assumed because this is a VF page that you are only dealing with one Parent1 and one target Parent2 object, not lists of each.

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.