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
Sulabh_KapoorSulabh_Kapoor 

Name of Months within the start and end dates

Hi,

PS: I am preparing a design so no code is written so far. 

In my custom object, I store the start and end dates of a particular campaign, let's say start date is 01/01/2017, the end date is 03/31/2018. For these 15 months, I need to create an opportunity (one for each month) and need to mark the close date as the end date of every month. This process of Opportunity creation is going to happen through a trigger.

I would like to check if anyone has done something similar to this and can share a code snippet or provide the best practices around this.

Thanks.
Best Answer chosen by Sulabh_Kapoor
Paul S.Paul S.
You could create a map where the month number is the key and the month name is the value.
Map<Integer, String> mapOfMonthNameByMonthNumber = new Map<Integer, String>();

// There's probably a more elegant way to do this...
mapOfMonthNameByMonthNumber.put(1, 'January');
mapOfMonthNameByMonthNumber.put(2, 'February');
mapOfMonthNameByMonthNumber.put(3, 'March');
mapOfMonthNameByMonthNumber.put(4, 'April');
mapOfMonthNameByMonthNumber.put(5, 'May');
mapOfMonthNameByMonthNumber.put(6, 'June');
mapOfMonthNameByMonthNumber.put(7, 'July');
mapOfMonthNameByMonthNumber.put(8, 'August');
mapOfMonthNameByMonthNumber.put(9, 'September');
mapOfMonthNameByMonthNumber.put(10, 'October');
mapOfMonthNameByMonthNumber.put(11, 'November');
mapOfMonthNameByMonthNumber.put(12, 'December');

Integer oppsToCreate = Campaign.StartDate.monthsBetween(Campaign.EndDate) + 1 // Need to add 1 to account for the end date month

List<Opportunity> oList = new List<Opportunity>();

for(Integer i = 0; i < oppsToCreate; i++){

    Date closeDateToUse = Campaign.StartDate.addMonths(i+1).toStartOfMonth -1 // Start date of 12/16/2017 becomes 1/1/2018 - 1 day = 12/31/2017

    Opportunity o = new Opportunity(
        CloseDate = closeDateToUse,
        Month_Name_Field = mapOfMonthNameByMonthNumber.get(closeDateToUse.month()),
        ...other fields...
    );
    oList.add(o);
}

insert oList;


 

All Answers

Paul S.Paul S.
Sulabh - this sounds like you could use the monthsBetween method (and add 1 to account for the last month) to determine the number of opportunities you needed to create.  Once you have this, you could perform a loop that many number of times to create your opportunities.  As for the close dates, you could take your campaign start date and use the addMonths and toStartOfMonth date methods.

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_date.htm

Something like this should get you started:
Integer oppsToCreate = Campaign.StartDate.monthsBetween(Campaign.EndDate) + 1 // Need to add 1 to account for the end date month

List<Opportunity> oList = new List<Opportunity>();

for(Integer i = 0; i < oppsToCreate; i++){
    Opportunity o = new Opportunity(
        ...
        CloseDate = Campaign.StartDate.addMonths(i+1).toStartOfMonth -1  // Start date of 12/16/2017 becomes 1/1/2018 - 1 day = 12/31/2017 
    );
    oList.add(o);
}

insert oList;

 
Sulabh_KapoorSulabh_Kapoor
Thanks Paul. This gets me to the point where I have the number of months but I am looking for the NAME of every month that is included in the loop. I know I can use the IF-ELSE conditions or the SWITCH CASE conditions to find the name by passing the month number of the close date but I am looking for more of an OOTB solution. I checked the date methods URL you shared but did not find anything which salesforce supports to automatically convert the number to a month for eg - 01 is January, 02 is February......... so on.
Paul S.Paul S.
You could create a map where the month number is the key and the month name is the value.
Map<Integer, String> mapOfMonthNameByMonthNumber = new Map<Integer, String>();

// There's probably a more elegant way to do this...
mapOfMonthNameByMonthNumber.put(1, 'January');
mapOfMonthNameByMonthNumber.put(2, 'February');
mapOfMonthNameByMonthNumber.put(3, 'March');
mapOfMonthNameByMonthNumber.put(4, 'April');
mapOfMonthNameByMonthNumber.put(5, 'May');
mapOfMonthNameByMonthNumber.put(6, 'June');
mapOfMonthNameByMonthNumber.put(7, 'July');
mapOfMonthNameByMonthNumber.put(8, 'August');
mapOfMonthNameByMonthNumber.put(9, 'September');
mapOfMonthNameByMonthNumber.put(10, 'October');
mapOfMonthNameByMonthNumber.put(11, 'November');
mapOfMonthNameByMonthNumber.put(12, 'December');

Integer oppsToCreate = Campaign.StartDate.monthsBetween(Campaign.EndDate) + 1 // Need to add 1 to account for the end date month

List<Opportunity> oList = new List<Opportunity>();

for(Integer i = 0; i < oppsToCreate; i++){

    Date closeDateToUse = Campaign.StartDate.addMonths(i+1).toStartOfMonth -1 // Start date of 12/16/2017 becomes 1/1/2018 - 1 day = 12/31/2017

    Opportunity o = new Opportunity(
        CloseDate = closeDateToUse,
        Month_Name_Field = mapOfMonthNameByMonthNumber.get(closeDateToUse.month()),
        ...other fields...
    );
    oList.add(o);
}

insert oList;


 
This was selected as the best answer
Sulabh_KapoorSulabh_Kapoor
@paul - Instead of map, I used custom setting but I really liked your approach. Thanks for the help