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
Jean Grey 10Jean Grey 10 

Match up data on VF page

I am using Apex to find all opportunities related to certain tasks:
public with sharing class DemoOppsController {
    
    //set up controller & extension for vf page
    ApexPages.StandardSetController setCon;

    public DemoOppsController(ApexPages.StandardSetController controller) {
        setCon = controller;
    }    
    
    //set up variables
    public List<Task> demoList {get;set;}
    public List<Task> ownerList {get;set;}
    public List<Id> repIdList {get;set;}
    public List<User> repList {get;set;}
    public List<Id> conIdList {get;set;}
    public List<Contact> conList {get;set;}
    public List<Id> accIdList {get;set;}
    public Set<Id> accSet {get;set;}
    public List<Account> accList {get;set;}
    public List<Id> oppIdList {get;set;}
    public Set<Id> oppSet {get;set;}
    public List<Opportunity> oppList {get;set;}
    public List<Id> IdList {get;set;}
    public List<Wrapper> wrapTastic {get;set;}
    
    public void getDemos(){
		//get tasks
        demoList = new List<Task> ([SELECT Id, ActivityDate, WhoId,Who.Name,Owner.Name, Type,Subject,Status,AccountId, OwnerId,Owner.UserRole.Name, WhatId
                                    FROM Task 
                                    WHERE ActivityDate<=TODAY AND ActivityDate=THIS_YEAR AND Type='Call:DM' ORDER BY Owner.UserRole.Name]);
        //get rep Ids
		repIdList = new List<Id>();
        repList = new List<User>();
        for(Task t :demoList){
	        repIdList.add(t.OwnerId);
            for(User u :[SELECT Id,Name,UserRole.Name,Territory__c From User WHERE Id IN :repIdList ORDER BY UserRole.Name]){
                repList.add(u);
            }
           		}
        system.debug('repIdList : '+repIdList);
        //get contact Ids
        conIdList = new List<Id>();
        conList = new List<Contact>();
        for(Task t :demoList){
            conIdList.add(t.WhoId);
            for(Contact c :[SELECT Id, LeadSource,OwnerId,AccountId FROM Contact WHERE Id IN :conIdList ORDER BY Owner.UserRole.Name]){
                conList.add(c);
            }
                }
        //get account Ids from Tasks
        accSet = new Set<Id>();
        accList = new List<Account>();
        for(Task t :demoList){
            accSet.add(t.AccountId);}
        //get account Ids from conList
        for(Contact cons :conList){
            accSet.add(cons.AccountId);}
            for(Account a :[SELECT Id, OwnerId,Owner.UserRole.Name FROM Account WHERE Id IN :accSet ORDER BY Owner.UserRole.Name]){
                accList.add(a);
            }
        //get Opps Ids
        oppIdList = new List<Id>();
        oppSet = new Set<Id>();
        //may need to add commission split to this
        for(Opportunity opp :[SELECT Id,AccountId,Owner.UserRole.Name FROM Opportunity WHERE OwnerId IN :repIdList AND CloseDate = THIS_YEAR ORDER BY Owner.UserRole.Name]){
	        for(Account acc :accList){
       	        if(acc.Id == opp.AccountId){
                    oppSet.add(opp.Id);
            	    }
            }
        }
        for(Commission_Split__c cs :[SELECT Id,User__c,Opportunity__c,Opportunity__r.Id FROM Commission_Split__c 
                                     WHERE Opportunity__r.CloseDate = THIS_YEAR AND Opportunity__r.AccountId IN :accList]){
                                         oppSet.add(cs.Opportunity__r.Id);
                                     }
                oppList = new List<Opportunity>([SELECT Id,Name,Amount,StageName,OwnerId,AccountId,Owner.UserRole.Name,Owner.Name 
                                                 FROM Opportunity 
                                                 WHERE Id IN :oppSet
                                                 ORDER BY Owner.UserRole.Name]);

		system.debug('demoList '+demoList);
        system.debug('repList '+repList);
        system.debug('conList '+conList);
        system.debug('accList '+accList);
        system.debug('oppList '+oppList);
        
        }

}
I have confirmed in debug logs that this is working as expected. The problem is in displaying the data so that the opportunities appear next to the related tasks. Right now I just have two lists side by side, with no matching so the data is hard to read. Here is my vf page:
<apex:page standardController="User" extensions="DemoOppsController" recordSetVar="users" tabStyle="User" sidebar="false" action="{!getDemos}">

    
    <style>
        #col1,#col2{width:45%;display:inline-block;}
    </style>

        <apex:pageBlock title="SMB Demos with Opportunity Info">
               	<div id="col1">
			<apex:pageBlockSection title="Demos">
                <apex:pageBlockTable value="{!demoList}" var="d">
                    <apex:column headerValue="Team" value="{!d.Owner.UserRole.Name}"></apex:column>
                    <apex:column headerValue="Rep Name" value="{!d.Owner.Name}"></apex:column>
                    <apex:column headerValue="Contact Name"><apex:outputLink value="{!d.WhoId}">{!d.Who.Name}</apex:outputLink></apex:column>
                    <apex:column headerValue="Date" value="{!d.ActivityDate}"></apex:column>
                    <apex:column headerValue="Demos" value="{!d.Subject}"></apex:column>

                </apex:pageBlockTable>
            </apex:pageBlockSection>
    </div>
    <div id="col2">
            <apex:pageBlockSection title="Opportunities">
                <apex:pageBlockTable value="{!oppList}" var="o">
                    <apex:column headerValue="Team" value="{!o.Owner.UserRole.Name}"></apex:column>
                    <apex:column headerValue="Opportunity Owner" value="{!o.Owner.Name}"></apex:column>
                    <apex:column headerValue="Opportunity Name"><apex:outputLink value="{!o.Id}">{!o.Name}</apex:outputLink></apex:column>
            	</apex:pageBlockTable>
            </apex:pageBlockSection>

    </div>
    </apex:pageBlock>
    </apex:page>
Any suggestions? Thanks in advance!

 
Tiago Armando CoelhoTiago Armando Coelho
Hi Jean. 

You can you the master-detail pattern.

Please check the link below for some example in other languages
https://docs.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/master-details.

Kind regards, 
Jean Grey 10Jean Grey 10
This is great, but how do I apply to vf code? I'm not familiar with xaml.
Jean Grey 10Jean Grey 10
Updated controller code has been bulkified, the vf page is displaying all correct data but we need it to be sorted. Any suggestions would be greatly appreciated!
 
    public with sharing class DemoOppsController {
        
        //set up controller & extension for vf page
        ApexPages.StandardSetController setCon;

        public DemoOppsController(ApexPages.StandardSetController controller) {
            setCon = controller;
        }    
        
        //set up variables
        public List<Task> demoList {get;set;}
        public List<Task> ownerList {get;set;}
        public List<Id> repIdList {get;set;}
        public List<User> repList {get;set;}
        public List<Id> conIdList {get;set;}
        public List<Contact> conList {get;set;}
        public List<Id> accIdList {get;set;}
        public Set<Id> accSet {get;set;}
        public List<Account> accList {get;set;}
        public List<Id> oppIdList {get;set;}
        public Set<Id> oppSet {get;set;}
        public List<Opportunity> oppList1 {get;set;}
        public List<Opportunity> oppList {get;set;}
        public List<Commission_Split__c> csList {get;set;}
        public List<Id> IdList {get;set;}
        public List<Account> oppAccList {get;set;}

        
        public void getDemos(){
            //get tasks
            demoList = new List<Task> ([SELECT Id, ActivityDate, WhoId,Who.Name,Type,Subject,Status,AccountId,Account.Name,OwnerId,Owner.Name,Owner.UserRole.Name, WhatId
                                        FROM Task 
                                        WHERE ActivityDate<=TODAY AND ActivityDate=THIS_MONTH AND Type='Call:DM' ORDER BY Account.Name]);
            //get rep Ids
            repIdList = new List<Id>();
            repList = new List<User>();
            for(Task t :demoList){
                repIdList.add(t.OwnerId);
            }
            repList = [SELECT Id,Name,UserRole.Name,Territory__c From User WHERE Id IN :repIdList ORDER BY UserRole.Name];
            system.debug('repIdList : '+repIdList);
            //get contact Ids
            conIdList = new List<Id>();
            conList = new List<Contact>();
            for(Task t :demoList){
                conIdList.add(t.WhoId);
            }
            conList = [SELECT Id, LeadSource,OwnerId,AccountId,Owner.Name FROM Contact WHERE Id IN :conIdList ORDER BY Owner.UserRole.Name];
            //get account Ids from Tasks
            accSet = new Set<Id>();
            accList = new List<Account>();
            for(Task t :demoList){
                accSet.add(t.AccountId);}
            //get account Ids from conList
            for(Contact cons :conList){
                accSet.add(cons.AccountId);}
            //accList is the list of accounts related to contacts and demos
            accList = [SELECT Id, OwnerId,Owner.UserRole.Name,Owner.Name FROM Account WHERE Id IN :accSet ORDER BY Owner.UserRole.Name];
            //get Opps Ids
            oppIdList = new List<Id>();
            oppList1 = new List<Opportunity>();
            oppList = new List<Opportunity>();
            oppSet = new Set<Id>();
            //oppList1 is list of opps owned by same rep as demos, and same account as accList
            oppList1 = [SELECT Id,AccountId,Account.Name,Owner.UserRole.Name,Amount,Owner.Name,Name FROM Opportunity WHERE OwnerId IN :repIdList AND AccountId IN :accList AND CloseDate = THIS_YEAR ORDER BY Owner.UserRole.Name];
            for(Opportunity opp :oppList1){
                oppSet.add(opp.Id);}
            //csList is list of commission splits with same rep as demos and same opp as oppList
            csList = [SELECT Id,User__c,Opportunity__r.Account.Name,Opportunity__r.Amount,Opportunity__c,Opportunity__r.Name,Opportunity__r.Id,User__r.Name FROM Commission_Split__c 
                                         WHERE Opportunity__r.CloseDate = THIS_YEAR AND Opportunity__r.AccountId IN :accList AND User__c IN :repIdList];
            for(Commission_Split__c cs :csList){
                oppSet.add(cs.Opportunity__c);}
            //create oppList from opportunities and commission splits
            oppList = [SELECT Id,AccountId,Account.Name,Owner.UserRole.Name,Amount,Owner.Name,Name FROM Opportunity WHERE Id IN :oppSet ORDER BY Account.Name];

            system.debug('demoList '+demoList);
            system.debug('repList '+repList);
            system.debug('conList '+conList);
            system.debug('accList '+accList);
            system.debug('oppList '+oppList);
            
            }

    }