Search code examples
salesforceapex

Please tell me how to fill in the fields in the list that lies on the map


I have a map

Map<Id, List<ExpenseController.MonthRow>> monthsPerKeeper = new Map<Id, List<ExpenseController.MonthRow>>();

This is how she looks: enter image description here

Right now I'm only showing the months ("monthNumber") that are full. I need to fill in all the missing ("monthNumber") and the ("amount") field for that ("monthNumber") should be 0.

It should look like this: enter image description here

I tried to get the value from the map by id (that is, the List) but I don't know how to refer to the fields in this List to fill them in

for (Id c : monthsPerKeeper.keySet()) {
            if(monthsPerKeeper.containsKey(c)) {
                for (ExpenseController.MonthRow a : monthsPerKeeper.get(c)) {
                    
                    List<ExpenseController.MonthRow> monthsListAdd = new List<ExpenseController.MonthRow>();
                    for (Integer i = 1; i < 13; i++)  {

                        if (!monthsPerKeeper.get(c).monthNumber.containsKey(i)) {
                            ExpenseController.MonthRow row = new ExpenseController.MonthRow();
                            row.monthName = ExpenseController.monthNumbers.get(i);
                            row.amount = 0;
                            row.monthNumber = i;

                            monthsListAdd.add(row);
                        }
                        
                    }
                }
            }
        }   

Solution

  • so you have monthsListAdd with say 5 dummy months and want to add it to the original list of 7 real months? Many ways to do it, seeing how your screenshot list is unsorted and really the gaps (no expenses this month) can be anywhere... I'd probably reverse the whole thing, start with 12 placeholders with 0 amounts and just update them as I go through list...

    Anyway:

    After that for (ExpenseController.MonthRow a : monthsPerKeeper.get(c)) { ends add this:

    monthsPerKeeper.get(c).addAll(monthsListAdd);

    I stil think you'll have this in rubbish order so maybe read up about "implements Comparable" to sort your list of helper objects after they're all added up?


    edit

    To make it cleaner I'd use a Map where key is month number and value is... well, if all you need is Amount then probably Map<Integer,Decimal> would do. If you'd want to display more - Map<Integer, ExpenseController.MonthRow> probably. Or you know, use the fact that List could have month numbers as indexes ;)

    Consider this query (works in my sandbox and returns me something but with gaps. And that's OK)

    SELECT CALENDAR_MONTH(CloseDate), SUM(Amount)
    FROM Opportunity
    WHERE CloseDate = THIS_YEAR AND IsWon = true AND Owner.Profile.Name = 'System Administrator' AND Amount != null
    GROUP BY CALENDAR_MONTH(CloseDate)
    

    enter image description here

    It's not even sorted - but I don't care.

    Map<Integer, Decimal> myMap = new Map<Integer, Decimal>{
        1 => 0,
        2 => 0,
        3 => 0,
        4 => 0,
        5 => 0,
        6 => 0,
        7 => 0,
        8 => 0,
        9 => 0,
        10 => 0,
        11 => 0,
        12 => 0
    };
    
    for(AggregateResult ar : [SELECT CALENDAR_MONTH(CloseDate) m, SUM(Amount) a
        FROM Opportunity
        WHERE CloseDate = THIS_YEAR AND IsWon = true AND Owner.Profile.Name = 'System Administrator' AND Amount != null
        GROUP BY CALENDAR_MONTH(CloseDate)]){
        myMap.put((Integer) ar.get('m'), (Decimal) ar.get('a'));
    }
    
    for(Integer i = 1; i < 13; ++i){
        System.debug(i + ' ' + DateTime.newInstance(2022,i,1).format('MMMM') + ': ' + myMap.get(i));
        // instead of debug you'd have your someList.add(new ExpenseController.MonthRow(...) or whatever
    }
    
    

    enter image description here