I have often been approached with workflow tasks where the requirements have been to have the system send an email to inform certain users about a change in some transactional data. Just send the email, nothing else. No interaction by the user.
Such tasks can easily be accomplished by small workflows. It is relatively easy to build a workflow that will listen to a specific event, gather some data and send an email with some information to one or more users. After the workflow has run, there will be lots of data in the workflow log, if it ever becomes necessary to troubleshoot a specific workflow.
If we do not take into consideration all the overhead that the system has to build for a workflow to run with the sole purpose of sending an email, then the workflow would be the perfect solution for such tasks. Seeing it in this light and in the light that workflows are actually tools intended to have interaction from the user, I tried another approach to solve a task whose only purpose was to send an email to inform about a change in a date.
The specific case
A change in a date can seem something trivial, but let’s say we have a project (defined in the Project Builder, transaction CJ20N) for which we have defined a milestone dealing with a certain event in the project. If it is about a very important milestone in the project, like let’s say a customer placing an order, it could be interesting for some people in an organization to know when the customer commits itself to the project by placing the order.
The milestones in the Project Builder have an area dedicated to dates relative to the milestone. One of these dates, e.g. “Basic fixed date” (date on which the milestone should be reached) combined with an Authorization Group could be used to represent the date the customer commits itself to the order. At the time when the project is defined, this field can be empty and when the customer commits itself, the respective date can be entered in this field, which will trigger the email to inform the relevant people about it. The same will happen if the customer finds out that changes to the date are necessary.
Steps to solve the task of informing via email
Detecting a change in the date
The triggering point here is a change in the Basic Fixed Date of a milestone. Whether or not it is a workflow that will send the email to inform about a change in this date, we still have to detect a change in this date. How is it then possible to detect that this date has been changed?
The first obvious answer is to search the system for any events carrying the relevant data, being raised when a project definition is saved. Another is to find customer exits or BAdIs related to project definition. One good bet would be PROJECTDEF_UPDATE or WORKBREAKDOWN_UPDATE, but the milestones are not available within any of the methods in these BAdI definitions.
After not being successful in finding a BAdI, I opted for an implicit enhancement at a suitable place within the code behind CJ20N. I found that form routine ON_COMMIT of include LCJWBF05 would be a suitable place. This include is part of function group CJWB, which handles changes to projects and the code in it is executed every time a project definition is saved. Place for an implicit enhancement is provided at the end of this include.
To detect a change in the Basic Fixed date, I looked at internal table BT_MLST (structure RCJ_MLST) containing all milestones and visible within the form routine being enhanced. Field BEAKZ of the structure has type TRTYP, a well defined domain in the Data Dictionary, making it possible to determine the action on a milestone. A ‘V’ for BEAKZ means the milestone in question in being changed. Since internal table BT_MLST can contain more than one milestone being changed, other criteria can be setup to make it possible to determine one specific milestone, e.g. the Authorization Group, filed BEGRU of BT_MLST. The new value for the Basic Fixed Date will be in field EDATU of BT_MLST. Comparing this value with what is in database table MLST for the milestone in question, makes it possible to determine if a change in this date is occurring.
Sending the email
To find the place to determine if a change in the Basic fixed Date had taken place required an untraditional solution using an implicit enhancement. I prefer using other techniques like customer exits or BAdIs. But once a suitable place is found, an implicit enhancement can give many advantages.
As argued before, it would require relatively lots of system resources to use a workflow to send the email informing of the change in the date. If I were to use a workflow, I use have used a standard task using method SendTaskDescription of business object SELFITEM. Instead, I opted to build a function module that gathers the necessary information and formats it, and calls function module SO_DOCUMENT_SEND_API1. This function module is then called from within the implicit enhancement.
Determining the receivers of the email
A requirement was that it should be simple to maintain the list of receivers directly in the production system for each company code. The choice has been to use a rule with responsibility where the container parameter is the company code. At runtime the company code used to determine the receivers is the company code of the project definition.
The function module created uses function module RH_GET_ACTORS to find which users were assigned in the rule for the company code in question. The list with one or more users is used to look up in HR table PA0105 subtype 0010 to determine their company email address.
What started being a task that was thought to be solved by a workflow, ended up being a pure ABAP-solution. The most time-consuming part of this task has been to find a suitable place to check if the milestone date was being changed, since no BAdI or customer-exit containing the appropriate data could be found. The use of an implicit enhancement is my view an untraditional way of including one’s own code in an SAP application, but it is fully “legal” and new, contrary to modifications, and I have used it in other situations also.
Once I was able to determine if the milestone date had been changed, it would have been possible to raise an event to start a workflow that would send the email. Instead, I chose to use code it in ABAP.