0

I am building some visualforce pages for Sales Console to show assets with maintenance type views.

I am building the map in apex exactly the way I want, the issue is with rendering the data in VF. My map:

public with sharing class SalesConsolesAssets {

public Account acct;
public Map<AggregateResult, Boolean> assets { get; set; }
public List<SBQQ__Subscription__c> subscriptions { get; set; }
public List<Contract> contracts { get; set; }
date d = system.today();

public SalesConsolesAssets() {

    //Get acctId from console
    acct = [SELECT Id FROM Account
            WHERE Id = :ApexPages.currentPage().getParameters().get('id')];

    //Join Assets and Subs to find maintenance status
    Set<String> subFamilySet = new Set<String> ();
    for (SBQQ__Subscription__c setSubs :[SELECT SBQQ__Product__r.Discount_Family__c, SBQQ__StartDate__c, SBQQ__EndDate__c FROM SBQQ__Subscription__c WHERE SBQQ__Account__c = :acct.Id AND SBQQ__EndDate__c > :d]) {
        subFamilySet.add(setSubs.SBQQ__Product__r.Discount_Family__c);
    }


    List<AggregateResult> aggregateAssetsList = [SELECT Name, Product2.Discount_Family__c, COUNT(Qty__c) qty
                                                 FROM Asset
                                                 WHERE(AccountId = :acct.Id AND Status = 'Purchased' AND Product2.Id != null)
                                                 GROUP BY Product2.Discount_Family__c, Name];

    Map<AggregateResult, Boolean> assetSubStatus = new Map<AggregateResult, Boolean> ();
    for (AggregateResult ar : aggregateAssetsList) {
        String dFamily = (String) ar.get('Discount_Family__c');
        if (subFamilySet.contains(dFamily)) {
            assetSubStatus.put(ar, true);
        } else {
            assetSubStatus.put(ar, false);
        }
    }
    //Get Contracts
    contracts = [SELECT Name, EndDate, AccountId FROM Contract WHERE AccountId = :acct.Id AND SBQQ__ActiveContract__c = 1];
}

}

I am trying to use the boolean in the map to change the background color:

<apex:page controller="SalesConsolesAssets" showHeader="true" sidebar="false">
   <apex:includeScript value="/support/console/20.0/integration.js" />
   <html xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
      <apex:stylesheet value="{!URLFOR($Resource.SLDS102, 'assets/styles/salesforce-lightning-design-system-vf.min.css')}" />
      <style type="text/css">
         .t {
         background-color: #baefc4;
         font-weight: bold;
         margin-bottom: 3px;
         }
          .f {
              background-color: #efbaba;
              font-weight: bold;
              margin-bottom: 3px;
          }
         }
      </style>
      <div class="slds">
         <div class="slds-scope">
            <table class="slds-table slds-table_bordered slds-table_cell-buffer">
               <thead>
                  <tr scope="col" class="slds-cell-wrap">
                     <th scope="col" class="slds-cell-wrap">
                        <div class="slds-truncate" title="Purchased Assets/Subscription Status"></div>
                        <!-- <th class="col">Maint?</th>-->
                     </th>
                  </tr>
               </thead>
               <tbody>
                  <apex:repeat value="{! assets}" var="a">
                        <tr class="{!IF(assets[a],'t','f')}"> 
                           <td data-label="Discount Family" class="slds-cell-wrap">
                              <div class="slds-truncate">
                                  {!a['Discount_Family__c']}
                              </div>
                           </td>
                           <td data-label="Quantity" class="slds-cell-wrap">
                              <div class="slds-truncate">
                                 {!a['qty']}
                              </div>
                           </td>
                        </tr>
                  </apex:repeat>
               </tbody>
            </table>
             <br></br>
             <br></br>
             <h2>&nbsp;&nbsp;Active Contracts</h2>
             <apex:dataTable value="{! contracts}" var="c" styleClass="slds-table slds-table--bordered slds-table--cell-buffer slds-table--fixed-layout">
               <thead>
                  <tr scope="col" class="slds-cell-wrap">
                     <th scope="col" class="slds-cell-wrap">
                        <div class="slds-truncate" title="Active Contracts">Active Contracts</div>
                     </th>
                  </tr>
               </thead>
               <tbody>
                  <tr>
                     <th scope="row" data-label="Contract Name">
                        <apex:column value="{!c.Name}"/>
                     </th>
                     <apex:column value="{!c.EndDate}" />
                  </tr>
               </tbody>
            </apex:dataTable>
         </div>
      </div>
   </html>
</apex:page>

I can show the aggregate results fine, just having trouble with the boolean. This code worked find when I was using an Sobject instead of aggregate result in the map.

1 Answer 1

2

Using non-primitive keys in Visualforce is tricky at best. Consider using a wrapper class:

public with sharing class SalesConsolesAssets {

    public Account acct;
    public class Wrapper {
        public AggregateResult result { get; set; }
        public Boolean showColor { get; set; }
    }
    public Wrapper[] wrappers { get; set; }
    public List<SBQQ__Subscription__c> subscriptions { get; set; }
    public List<Contract> contracts { get; set; }
    date d = system.today();

    public SalesConsolesAssets() {

        //Get acctId from console
        acct = [SELECT Id FROM Account
                WHERE Id = :ApexPages.currentPage().getParameters().get('id')];

        //Join Assets and Subs to find maintenance status
        Set<String> subFamilySet = new Set<String> ();
        for (SBQQ__Subscription__c setSubs :[SELECT SBQQ__Product__r.Discount_Family__c, SBQQ__StartDate__c, SBQQ__EndDate__c FROM SBQQ__Subscription__c WHERE SBQQ__Account__c = :acct.Id AND SBQQ__EndDate__c > :d]) {
            subFamilySet.add(setSubs.SBQQ__Product__r.Discount_Family__c);
        }


        List<AggregateResult> aggregateAssetsList = [SELECT Name, Product2.Discount_Family__c, COUNT(Qty__c) qty
                                                     FROM Asset
                                                     WHERE(AccountId = :acct.Id AND Status = 'Purchased' AND Product2.Id != null)
                                                     GROUP BY Product2.Discount_Family__c, Name];
        wrappers = new Wrapper[0];
        for(AggregateResult ar: aggregateAssetsList) {
            Wrapper w = new Wrapper();
            w.result = ar;
            w.showColor = subFamilySet.contains((String)ar.get('Discount_Family__c'));
            wrappers.add(w);
        }

        //Get Contracts
        contracts = [SELECT Name, EndDate, AccountId FROM Contract WHERE AccountId = :acct.Id AND SBQQ__ActiveContract__c = 1];
    }
}

<apex:page controller="SalesConsolesAssets" showHeader="true" sidebar="false">
   <apex:includeScript value="/support/console/20.0/integration.js" />
   <html xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
      <apex:stylesheet value="{!URLFOR($Resource.SLDS102, 'assets/styles/salesforce-lightning-design-system-vf.min.css')}" />
      <style type="text/css">
         .t {
         background-color: #baefc4;
         font-weight: bold;
         margin-bottom: 3px;
         }
          .f {
              background-color: #efbaba;
              font-weight: bold;
              margin-bottom: 3px;
          }
         }
      </style>
      <div class="slds">
         <div class="slds-scope">
            <table class="slds-table slds-table_bordered slds-table_cell-buffer">
               <thead>
                  <tr scope="col" class="slds-cell-wrap">
                     <th scope="col" class="slds-cell-wrap">
                        <div class="slds-truncate" title="Purchased Assets/Subscription Status"></div>
                        <!-- <th class="col">Maint?</th>-->
                     </th>
                  </tr>
               </thead>
               <tbody>
                  <apex:repeat value="{!wrappers}" var="w">
                        <tr class="{!IF(w.showColor,'t','f')}"> 
                           <td data-label="Discount Family" class="slds-cell-wrap">
                              <div class="slds-truncate">
                                  {!w.result['Discount_Family__c']}
                              </div>
                           </td>
                           <td data-label="Quantity" class="slds-cell-wrap">
                              <div class="slds-truncate">
                                 {!w.result['qty']}
                              </div>
                           </td>
                        </tr>
                  </apex:repeat>
               </tbody>
            </table>
             <br></br>
             <br></br>
             <h2>&nbsp;&nbsp;Active Contracts</h2>
             <apex:dataTable value="{! contracts}" var="c" styleClass="slds-table slds-table--bordered slds-table--cell-buffer slds-table--fixed-layout">
               <thead>
                  <tr scope="col" class="slds-cell-wrap">
                     <th scope="col" class="slds-cell-wrap">
                        <div class="slds-truncate" title="Active Contracts">Active Contracts</div>
                     </th>
                  </tr>
               </thead>
               <tbody>
                  <tr>
                     <th scope="row" data-label="Contract Name">
                        <apex:column value="{!c.Name}"/>
                     </th>
                     <apex:column value="{!c.EndDate}" />
                  </tr>
               </tbody>
            </apex:dataTable>
         </div>
      </div>
   </html>
</apex:page>
6
  • Does not like it: Map key core.apexpages.el.adapters.AggregateResultELAdapter@18f5c546 not found in map Error is in expression '{!IF(assets[a],'t','f')}' in component <apex:repeat> in page
    – Allen Mann
    May 26, 2017 at 18:55
  • @AllenMann Using any non-primitive key is probably not ideal. I can see why your approach wouldn't work, and I'm not entirely surprised this didn't work either. Consider using a wrapper class and building a list instead.
    – sfdcfox
    May 26, 2017 at 19:13
  • This worked fine when I was building the map like Map<Asset, Boolean>
    – Allen Mann
    May 26, 2017 at 19:18
  • @AllenMann Edited in an alternative version that should work; you'll need to adjust your page accordingly.
    – sfdcfox
    May 26, 2017 at 19:20
  • @AllenMann Using non-primitives doesn't always work in Visualforce, because they go through some sort of translation between Apex and Visualforce. Using a wrapper class would be more reliable.
    – sfdcfox
    May 26, 2017 at 19:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .