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
DixitDixit 

HOW TO MAKE A SUMMARY OF RECORDS

Hello!~

I'm having trouble to find the best option to do a summary record with n records of the same type. 
Let me explain. 

I have a VF with a extension which gives me a list of a custom Object (ex: List<products__c> prods) i have this "products" n times with differents IDs but some with the same model...
So i have a WrapperClass that recives as a parameter a list of products. (Public productWrapper (List<products__c> p))
I want to summarize the quantity of products of the same model.

EX (i get in the list) 
ID     MODEL  QUANTITY  
01       A           10
02       B            5
03       C            1
04       A            3
05       A            5
06       B            10
07       C            20

so i want my wrapper class to tell me:
Model A: 18 pieces
Model B: 15 pieces
Model C: 21 pieces


but i don't know how exactly to achieve that... 
I know that an AggregateResult list should work but i will group those models for differents parameters and sumarize it as well for those parameters....

Any help?
Thanks.
ztrankztrank
Hi Dianna,
This might be more complicated that it needs to be, but it can easily be expanded for different parameters. I created a subclass to summarize the products, and used a Map to change the quantity of the summary by Model type. The same technique can be used for any field or derived parameter. I also implemented comparable to sort it, because in the page I made it chose a reverse order, and I wanted to ensure a more common sense order.
public class productWrapper {
    private List<ProductsSummary> productsSummarized;
    
    // Default constructor, uses SOQL to find Products__c
    public productWrapper() {
        setProductsSummarized([SELECT Model__c, Quantity__c FROM Products__c]);
    }
    
    // Constructor that can take a list of Products__c forgoing the query
    public productWrapper(List<Products__c> products) {
        setProductsSummarized(products);
    }
    
    // Exposes the summary list
    public List<ProductsSummary> getProductsSummarized() {
        if(productsSummarized == null)
            return new List<ProductsSummary>();
        return productsSummarized;
    }
    
    // Sets the summary list
    // Groups the summaries by Model
    // Sorts the final list.
    private void setProductsSummarized(List<Products__c> products) {
        // If products parameter is null, set the list to an empty list
        if(products == null)
            productsSummarized = new List<ProductsSummary>();
        // Map to hold the Model => Summary
        Map<String,ProductsSummary> modelToSummary = new Map<String,ProductsSummary>();
        
        // For each Products__c, check to see if we already found the Model
        // If we have, call setQuantity on the summary to increase the quantity
        // If we haven't, create a new summary and set model and quantity
        for(Products__c p : products) {
            if(p.Model__c == null || p.Quantity__c == null)
                continue;
            if(modelToSummary.get(p.Model__c) != null)
                modelToSummary.get(p.Model__c).setQuantity(p.Quantity__c);
            else
                modelToSummary.put(p.Model__c, new ProductsSummary(p));
        }
        
        // if the Map has values, set the list to the map's values, then sort
        if(!modelToSummary.isEmpty()){
            productsSummarized = modelToSummary.values();
            productsSummarized.sort();
        }
    }
    
    public class ProductsSummary implements Comparable {
        public String Model {get;private set;}
        public Decimal Quantity {get; private set;}
        
        // Construct new summary based on incoming Products__c
        public ProductsSummary(Products__c p) {
            this.model = p.Model__c;
            this.Quantity = p.Quantity__c;
        }
        
        // if quantity is null, set the quantity to the parameter
        // if not, add the parameter to the quantity
        public void setQuantity(Decimal quantity) {
            if(quantity == null)
                this.Quantity = quantity;
            else
                this.Quantity += quantity;
        }
        
        // implementation of compareTo
        public integer compareTo(Object compareTo) {
            ProductsSummary ps = (ProductsSummary)compareTo;
            if(Model == ps.Model) return 0;
            if(Model > ps.Model) return 1;
            return -1;
        }
    }
}

You'll notice that I use an SOQL query to find the Products__c in my default constructor, but you can obviously change that, and I included a constructor that will take a List of Products__c. Here is the visualforce page:
 
<apex:page controller="productWrapper">
    <apex:pageBlock>
    	<apex:pageBlockTable value="{!productsSummarized}" var="p">
            <apex:column >
            	<apex:facet name="header">Model</apex:facet>
                <apex:outputText value="{!p.Model}"/>
            </apex:column>
            <apex:column >
            	<apex:facet name="header">Total Quantity</apex:facet>
                <apex:outputText value="{!p.Quantity}"/>
            </apex:column>
        </apex:pageBlockTable>
    </apex:pageBlock>
</apex:page>

This could probably be done much quicker by someone with more experience, but this is how I would approach the problem with the knowledge that I will be summarizing other parameters too. If you want to get crazy you can make the summary an abstract class so you can apply it to more than just Products__c, but I think that is out of the scope of the question.
DixitDixit

I got it for myself, if anyone has a problem related to this... 

I got 3 wrappers (clasification by product, clasification by level, clasification by sytem), i got my list of products and iterate them to see how many clasifications was (in a set<string> of clasifications) in the clasification wrapper i made a list of levels for every clasification (i got different level floors in the products) and then i got a wrapper for every level get a clasification by product. 

so i got something like this:

Clasification : Fire
  -Level 1:
     *Product1(10)
     *Product2(5)
     *Product3(20)
  -Level 2: 
     *Product1(15)
     *Product4(5)

Clasification: Water
  -Level 1
     *Product 3(44)
     *Product 5(11)

......and so.