[SalesForce] Time based workflow in trigger.

I have a time based workflow which sends mail to opportunity Owner 7 days before the close date. Whenever close date gets changes, the time based workflow scheduling for mail also get changed. Everything works fine.

Now, the problem comes when someone make the opportunity as private, when a opportunity becomes private, salesforce does not fire workflow rule for it. Now , Opportunity has closed date say Dec 30 2013, and time based workflow schedule mail for Dec 23. Someone make the opportunity private then changes the closed date for March 30 2014. Now, as the opp is private and mail date does not get changed.Owner will get the mail on Dec 23 even if the close date changed to March 30.

Can i schedule a time based workflow with trigger only. without any involvement of workflow.
Please suggest.

Best Answer

I honestly did not know that private opportunities did not trigger workflows. Good to know.

You could accomplish this with some scheduled Apex. I would still allow your workflow to send them emails for non private opportunities, but create a class to address the private opportunities.

I put this together from a few classes that I have, you can obviously adjust it to fit your needs, and change the wording should you want to, but

Something like this should work

global class myScheduledClass implements Schedulable {

    public static String chron = '0 0 3 ? * MON-FRI';  //Every weekday at 3am 

    global static String scheduleJob() {
        myScheduledClass schedJob = new myScheduledClass();
        return System.schedule('My Opportunity Scheduled Job', chron, schedJob);
    }

    global void execute(SchedulableContext sc) {

        map<Id,Opportunity> oppsMap = new map<Id,Opportunity>([Select Id, Name, Amount, StageName, CloseDate, OwnerId From Opportunity Where CloseDate =: system.today().addDays(7) and IsPrivate = true]);
        map<Id,User> userMap = new map<Id,User>([Select Id, Name, Email From User Where Id In (Select OwnerId From Opportunity Where Id In : oppsMap.values)]);

        List<Messaging.SingleEmailMessage> emails = new List<Messaging.SingleEmailMessage>();

        for(Opportunity o : oppsMap.values()){
            Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();

            email.setSubject('Your Opporuntity closes in 7 days');

            String body;
            body = '<html><body style="font-family: Arial; font-size: 10pt;">';                     

            body = body + '<font size=+1><strong>Opportunity Closing Soon</strong></font><br/><br/>';
            body = body + 'Dear, ' + userMap.get(o.OwnerId).Name + '<br/><br/>';
            body = body + 'This is to inform you that you have an opportunity that is scheduled to close one week from today.<br/><br/>'; 

            body = body + '<table width="50%" rules="none"style="margin-left: 3em;">';
            body = body + '<tr><td>Opportunity:</td><td>' + o.Name + '</td></tr>'
            body = body + '<tr><td>Stage:</td><td>' + o.StageName + '</td></tr>'
            body = body + '<tr><td>Amount:</td><td>' + o.Amount + '</td></tr></table><br/><br/>'

            body = body + 'You can find the opportunity here: <a href=' + System.Label.hostURL + '/' + o.Id + 'target="_blank">' + o.Name + '</a><br/><br/>'

            body = body + 'Thank You,<br/><br/>';
            body = body + 'Your Friendly SF Developer<br/>';
            email.setHtmlBody(body);

            email.setTargetObjectId(o.OwnerId);
            emails.add(email);          
        }       
        if(!emails.isEmpty()){
            Messaging.sendEmail(emails);
        }       
    }
}
Related Topic