[SalesForce] How to set a value multiple times within same update

I have a batch process that updates a bunch of currency fields on a parent record based on the month of a child record. It works great and runs every hour to find new records and update the parent record accordingly.

If the date changes on the child record it updates the new corresponding currency field on the parent. The problem is that it does not clear out the now incorrect currency field.

To start if the following is true:

child.Date__c = 2017-01-01
child.Amount__c = 100

Then the logic runs and the output is:

parent.Jan2017__c = 100;
parent.Feb2017__c = 0;
parent.Mar2017__c = 0;

Current Results

If the child record is updated and changes to this:

child.Date__c = 2017-02-01
child.Amount__c = 100

The logic runs and the result is:

Jan2017__c = 100;
Feb2017__c = 100;
Mar2017__c = 0;

Expected Result:

If the child record is updated and changes to this:

child.Date__c = 2017-02-01
child.Amount__c = 100

The logic runs and the result is:

Jan2017__c = 0;
Feb2017__c = 100;
Mar2017__c = 0;

How can I clear out the populated currency fields to 0 and then let the logic run to populate the correct value?

Example code:

global void execute(Database.BatchableContext BC, List<Revenue_Pipeline_Schedule__c> scope) {

    Map<Id, Revenue_Pipeline__c> pipelines = new Map<Id, Revenue_Pipeline__c>();

    for (Revenue_Pipeline_Schedule__c schedule : scope)
    {
        Id pipelineId = schedule.Revenue_Pipeline__c;
        pipelines.put(pipelineId, new Revenue_Pipeline__c(Id=pipelineId));
    }
    // now all keys are initialized

    for (Revenue_Pipeline_Schedule__c schedule : scope)
    {
        SObjectField field = RevenuePipelineScheduleUpdaterHelper.dateToField.get(schedule.Date__c);
        if (field != null)
        {
            pipelines.get(schedule.Revenue_Pipeline__c).put(field, schedule.Amount__c);
        }
    }   
    update pipelines.values();
}

Helper:

   public with sharing class RevenuePipelineScheduleUpdaterHelper {

    public static Map<Date, SObjectField> dateToField = new Map<Date, SObjectField>
    {
        Date.newInstance(2014, 10, 1) => Revenue_Pipeline__c.Oct2014__c,
        Date.newInstance(2014, 11, 1) => Revenue_Pipeline__c.Nov2014__c,
        Date.newInstance(2014, 12, 1) => Revenue_Pipeline__c.Dec2014__c,
        Date.newInstance(2015, 01, 1) => Revenue_Pipeline__c.Jan2015__c,
        };
    }

Best Answer

Not sure I fully understand, but I suggest:

for (Revenue_Pipeline_Schedule__c s : scope) {

    Revenue_Pipeline__c p = pipelines.get(s.Revenue_Pipeline__c);

    // First clear all
    for (SObjectField f : RevenuePipelineScheduleUpdaterHelper.dateToField.values()) {
        p.put(f, 0);
    }

    // Then fill in the one
    SObjectField f = RevenuePipelineScheduleUpdaterHelper.dateToField.get(s);
    if (f != null) {
        p.put(f, s.Amount__c);
    }
}
Related Topic