0

I have a list that has 2 months worth of records i.e MTD and Previous month. This list is built from JSON response.

SubmittedDate   IDL (yes/No)    SubmittedCount

2019-07-01      Y               10
2019-07-02      N               6
2019-07-05      Y               3
2019-07-06      N               23
2019-07-07      Y               5
2019-07-08      Y               12
2019-06-01      Y               22
2019-06-08      Y               5
2019-06-12      Y               11
2019-06-14      N               1
2019-06-21      N               3

I want to separate this list into two buckets, CurrentMonth and PreviousMonth, so that I can get the total for each bucket. And further, total for CurrentMonth where IDL == 'Y', and total for PreviousMonth where IDl == 'Y'

The output I am expecting is this -

July: TotaAppsSubmitted = 59 i.e (10+5+3+23+5+12) , IDL (Y) = 30 i.e(10+3+5+12)
June: TotalAppsSubmitted = 42 i.e (22+5+11+1+3), IDL (Y) = 38 i.e (22+5+11)

My question is:
How can I separate the records into CurrentMonth and PreviousMonth.?

public with sharing class MyController {

        public list<JSONWrapper> wrapper {get;set;}
        public integer previousmonthAppTotal{get;set;} 
        public integer mtdAppTotal{get;set;} 

        public void getDeserialize() {


            string jsonresponse = '[{"appList":[{"reportingPeriod":"2019-07-01","idl":"Y","submissionCount":10},{"reportingPeriod":"2019-07-02","idl":"Y","submissionCount":6},{"reportingPeriod":"2019-07-05","idl":"N","submissionCount":5},{"reportingPeriod":"2019-06-12","idl":"Y","submissionCount":16},{"reportingPeriod":"2019-06-13","idl":"Y","submissionCount":6},{"reportingPeriod":"2019-06-17","idl":"N","submissionCount":3}],"eclist":[{"dealerID":"XL1HX","submitUserID":"BCUSER1","bookedDate":"2019-05-22 00:00:00.0","ecEligible":"Y","caBookedCount":1,"ecBookedCount":0},{"dealerID":"XL1HX","submitUserID":"BCUSER1","bookedDate":"2019-06-05 00:00:00.0","ecEligible":"Y","caBookedCount":1,"ecBookedCount":0}]}]';


            wrapper = (list<JSONWrapper>) JSON.deserialize(jsonresponse, list<JSONWrapper>.class);

            getMTDTotalAppCount(wrapper);
            getPreviousMonthTotalAppCount(wrapper);

        }


        public integer getMTDTotalAppCount(list<JSONWrapper> wrapper) {

            Date datetoday =  system.today().format());
            Integer monthtoday = datetoday.month();

                for(JSONWrapper jw: wrapper){
                    jw.mtdAppTotal=0;

                    for ((JSONWrapper.ApplicationList cp : jw.appList) { 

                          integer reportingperiodmonth = Date.valueOf(cp.reportingperiod).month();
                          if ((system.today().month()) == reportingperiodmonth){
                            jw.mtdappTotal += cp.submissionCount;

                        }else{

                            jw.previousmonthAppTotal += cp.submissionCount;
                        }
                    }
                }

            return mtdAppTotal;
            return previousmonthAppTotal;
        }


        public integer getPreviousMonthTotalAppCount(list<JSONWrapper> wrapper) {


                for(JSONWrapper jw: wrapper){
                    jw.previousmonthAppTotal=0;

                    for ((JSONWrapper.ApplicationList cp : jw.appList) { 
                         if((system.today().month()) != reportingperiodmonth) 
                         {
                            jw.previousmonthAppTotal += cp.submissionCount;

                         }

                    }

                }

                return previousmonthAppTotal;

        }
}


public class JSONWrapper {

    public List<ApplicationList> appList{get;set;}
    public List<ElectronicContractList> eclist {get;set;}
    public integer previousmonthAppTotal{get;set;} 
    public integer mtdAppTotal{get;set;} 

    public class ApplicationList {
      public String dealerID{get;set;}
      public String dealerName{get;set;}
      public String reportingPeriod{get;set;}
      public String idl{get;set;}
      public Integer submissionCount{get;set;}
   }

    public class ElectronicContractList{
        public String  dealerID{get;set;}
        public String submitUserID{get;set;}
        public String bookedDate{get;set;}
        public String ecEligible{get;set;}
        public Integer caBookedCount{get;set;}
        public Integer ecBookedCount{get;set;}
    }
}   
  • 3
    What are the records? sObjects? Maps? Custom classes? What logic have you tried to accumulate these totals? – David Reed Jul 11 at 15:45
  • 1
    Gonna echo David here a bit. It's important to show us what you've tried so far. Remember, the goal here is to help you get unstuck in a way that helps you learn how to handle similar situations in the future. – Derek F Jul 11 at 15:51
  • @DavidReed and DerekF, I made changes to the method getMTDTotalAppCount and tested it. I got the totalAppCount for Current month. Repeated the same logic for the method getPreviousMonthTotalAppCount, but haven't tested it. Not sure if my approach is correct though. – user4947 Jul 11 at 18:42
  • tested the code, gives me the desired result i.e totalappcount for current month, and previous month. Now will add logic to count records where IDL == 'Y' – user4947 Jul 11 at 19:17
  • I'm not sure what you're asking here. You seem to have hit at least the first half of your objective, and are on the right track to complete it successfully. – David Reed Jul 11 at 19:18
0

The approach I'm seeing that you've taken can be broken down like this:

  • Deserialize the JSON
  • Call a method
    • Iterate over all apps
    • Accumulate and return some data
  • Call a different method
    • Iterate over all apps
    • Accumulate and return different data

You could continue this pattern, and create a new method to iterate over the apps and just add an additional condition (only add this to the count if its IDL == 'Y'), but this makes your code a bit WET (write everything twice [or thrice]).

I think that a better approach would sound something like this:

  • Deserialize the JSON
  • Iterate over all apps
    • Call a method to determine if this one app record is for the current month, and add it to a total if so
    • Call another method to determine if this one app record is for the current month and has IDL == 'Y', and add it to a total if so
    • Continue calling methods until you run out of data you want to aggregate

A brief example of this approach:

// Since this data isn't really going to change while we're running the code,
//   it's a good candidate to be made a static variable
private static Integer thisMonth = Date.today().month();

public Integer currentMonthTotal {get; set}

public void getDeserialize() {
    string jsonresponse = '[{"appList":[{"reportingPeriod":"2019-07-01","idl":"Y","submissionCount":10}, {"reportingPeriod":"2019-07-02","idl":"Y","submissionCount":6}, {"reportingPeriod":"2019-07-05","idl":"N","submissionCount":5}, {"reportingPeriod":"2019-06-12","idl":"Y","submissionCount":16}, {"reportingPeriod":"2019-06-13","idl":"Y","submissionCount":6}, {"reportingPeriod":"2019-06-17","idl":"N","submissionCount":3}], "eclist":[{"dealerID":"XL1HX","submitUserID":"BCUSER1","bookedDate":"2019-05-22 00:00:00.0","ecEligible":"Y","caBookedCount":1,"ecBookedCount":0}, {"dealerID":"XL1HX","submitUserID":"BCUSER1","bookedDate":"2019-06-05 00:00:00.0","ecEligible":"Y","caBookedCount":1,"ecBookedCount":0}]}]';

    wrapper = (list<JSONWrapper>) JSON.deserialize(jsonresponse, list<JSONWrapper>.class);

    currentMonthTotal = 0;

    for(JSONWrapper.ApplicationList appRecord :wrapper[0].appList){
        currentMonthTotal += getTotalAppCountCurrentMonth(appRecord);
    }
}

private Integer getTotalAppCountCurrentMonth(JSONWrapper.ApplicationList appRec){
    Integer result = 0;

    if(Date.valueOf(appRec.reportingPeriod).month() == MyController.thisMonth)){
        result = appRec.submissionCount;
    }

    // There isn't really a need for an explicit "else" here.
    // We've set things up so that the default value is 0, and it becomes non-zero
    //   if we meet our target condition
    return result;
}

Now, this approach isn't perfect, and there will still be some repeated code (your check for idl == 'Y' needs to also check the month). I would still argue that it's an improvement though.

  • The amount of repeated code is kept small
  • Adding new aggregations is simple and straightforward (make sure you have a variable, initialize it, add a new method to be called in the existing loop)
  • Keeps the common code (i.e. getting at the appList) in a central location (as opposed to being repeated in every method).

Going from here, you'll need to add your own methods (and the supporting bits) for getTotalAppCountCurrentMonthWithIDL, getTotalAppCountPreviousMonth, and getTotalAppCountPreviousMonthWithIDL

  • Thank you @DerekF for the detailed approach suggestion and for educating me. I will close this post soon. – user4947 Jul 12 at 14:27

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.