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.

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>
| improve this answer | |
  • 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 '17 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 '17 at 19:13
  • This worked fine when I was building the map like Map<Asset, Boolean> – Allen Mann May 26 '17 at 19:18
  • @AllenMann Edited in an alternative version that should work; you'll need to adjust your page accordingly. – sfdcfox May 26 '17 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 '17 at 19:24

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.