Given the limited configuration opportunities to control financial postings, substitution user exits are an effective way to minimize manual journal entries and enhance reporting capabilities. Using two examples relating to manual cash applications in A/R, the author demonstrates how to optimize substitution user exits.
Financial postings are generated from many sources within R/3. While limited configuration is available to control these postings, opportunities to minimize manual journal entries and enhance reporting capabilities do exist. User exit code within financial substitutions is one such opportunity.
This article will use manual cash applications in accounts receivable to demonstrate the capabilities of user exits. My first example illustrates alignment of the payment terms and profit center for partial payments with the original invoice. The second example shows how to post bad debt directly to Profitability Analysis with an appropriate assignment based on data found in the original invoice.
The capabilities of financial user exits go far beyond these accounts receivable applications. Other examples that I have encountered recently include:
- Expensing delivery goods issues to different accounts based on sales order reason code
- Expensing sample goods issues to different cost centers based on sales organization or plant
- Checking the user name against a custom table to ensure they are posting cash to the appropriate account
- Determining a profit center for balance sheet postings based on offsetting line items
Accounts Receivable Cash Applications
Physical checks remain a popular payment medium in the United States, and therefore manual cash applications are a required process. Many businesses use the concept of partial payments, whereby the original invoice remains open on the customer's account and offsetting line items are created for the amount of payments. This optimizes the ability to analyze a customer's account history in a single screen.
Partial payments typically inherit payment terms based on the customer master and date of cash application. This creates an aging report in which sales invoices are in the aged columns and offsetting credits appear in the current column. For example, consider an invoice with payment terms of net 30 days for $18,000 dated March 1, 2004. The customer pays $10,000 on April 1, 2004. If the customer master once again indicates payment terms of net 30 days, that credit ages from the April 1 date. The aging report later that week shows $18,000 in the Overdue 1-30 column and a $10,000 credit in the Current column. Most executives prefer to have partial payments align with their respective invoices. My first user exit example explains how to derive the payment terms for a partial payment from the original invoice.
Another shortfall of cash applications is the inability to write bad debt off to a specific account assignment without manually keying the account and cost center. The logic required to programmatically determine the appropriate expense account and cost object (cost center, internal order, profitability segment, etc.) is often available by analyzing the customer master, original invoice, or some other combination of underlying data. My second user exit example demonstrates this method. It allows you to write bad debt directly to a profitability segment found in the original invoice without the user manually researching or assigning this cost object.
Note! See the sidebar, "Technical Setup," for several steps your development team must take before you use ABAP code in the financial user exits I will describe. |
Payment Terms for Partial Payments
With the initial technical steps in place, you can now implement the configuration and specific exit code that is required to modify your partial payment line items. The configuration enables user exit code to be called each time a new financial line item is generated that meets specified logical conditions. For this example, I will replicate the payment terms from the referenced document (initial invoice) whenever a referenced document number is available (indicates partial payment application).
The first step is to configure a financial substitution at the line item level. If you already have a substitution in place at the line item call-up point, feel free to add new steps in addition to those already being used.
The configuration transaction to access this financial substitution setup is OBBH. Create a new entry in the table. (Figure 1.) Specify your company code, call up point 2 (line item) in the CallPnt column, enter a name for your substitution, and indicate an activation level of 1 to make the substitution effective. Save this entry and select Environment>Substitution from the menu path. You are asked to confirm that this new substitution should be created. Answer "Yes" to the dialog.

Figure 1
OBBH (setting up a new user exit)
Enter an appropriate description for your new substitution (Figure 2). Next, you create a step within the substitution rule. You can create many steps within each substitution rule. Each individual step consists of logical conditions and one or more substitution values. Whenever a financial line item is generated, the conditions are evaluated. If they are true, the substitution values are used to update the financial document. For my example, I use ABAP code to substitute multiple field values.

Figure 2
New substitution overview where you provide a description
Click on the create step icon to create a new substitution step. This brings up a dialog box (Figure 3) showing which fields are currently available for substitution in your system. Note that you must change entries in table GB01 to modify this list of available fields. If you make a change to a field not included in this list in your user exit code, R/3 simply returns it to its original value.

Figure 3
Substitution fields available
Table GB01 can be maintained using the maintenance program found in the technical steps section of this article or directly using table maintenance. Note the class number provided in the header of the dialog box. In this case, it is Class 009. This corresponds to the class field found in table GB01. As you are using ABAP code in your exit, it is not necessary to specify which fields will be modified. Check the Only exit option, which always appears first in the list, and the green check mark to proceed.
You have now created a new substitution step. It consists of a prerequisite (when should I run?) and a substitution (what should I do?). Now you configure the prerequisite so that this substitution step is only considered when appropriate. Click on the prerequisite button. You are presented with a formula-builder screen (Figure 4). You can put together logical expressions by clicking and double-clicking on items at the bottom of the screen.

Figure 4
Prerequisite formula builder screen
For my example, I double-clicked on Accounting Document Segment and subsequently Reference Document Number to select this field for comparison. I then clicked on the Not Equals (<>) logical operator, the Constant button, and finally the green check box. As a result, I am considering only line items in which the reference document number is not blank (BSEG-REBZG < > ‘'). You could use further logic to restrict this exit to only certain accounts or other characteristics if desired.
Now that the prerequisite is in place, you are ready for assistance from your development team. It needs to create a new form in the custom user exit program (see the technical setup section, ZFI_EXITS) that contains your logic (Figure 5). Your development team can append this form code at the bottom of the existing program code. The user exit number (U180 in this example) must begin with the letter U and contain a unique three-digit number. The form needs to use this same name. As you can see in the figure, this exit is simply reading table BSEG to find the payment terms, baseline date, and profit center of the original line item and setting them to the same values in this current line item.

Figure 5
User exit logic within ZFI_EXITS
You must also create a definition of the form in the user exit program. This definition must appear within form GET_EXIT_TITLES (Figure 6). The name must be consistent with that of the form name. The title is used to provide a description when assigning this exit in configuration.

Figure 6
User exit definition within ZFI_EXITS
With this logic in the program, you can complete your user exit by assigning the form number. Click once on Substitutions under your current substitution step (found just under the substitution in the tree hierarchy) and enter the form name (Figure 7). You may need to exit and re-enter configuration for the form to be available after your development team has completed the required programming steps covered previously.

Figure 7
Assign a user exit number
At this point, the user exit is nearly ready for testing. The only remaining step is ensuring that all fields being changed within the logic are available for substitution. Do this by viewing the contents of table GB01 for the given class number. Remember, you originally spotted the appropriate class number in Figure 3. In this case, all fields were in the table, but they contained X in the exclude column, which prevents their use. I ran program ZGB01 (Figure 8) repeatedly to enable BSEG-ZFBDT, BSEG-ZTERM, BSEG- ZBD1T, BSEG-ZBD2T, BSEG-ZBD3T, and BSEG-PRCTR. My results are shown in Figure 9. If you navigate back to the screen displayed in Figure 3, all these fields would now have become options for substitutable fields.

Figure 8
Report ZGB01 user interface

Figure 9
GB01 table with correct entries
Finally, SAP delivers report RGUGBR00 that can be used to force regeneration of the substitution rules. To verify that all of your substitution changes are taken into consideration, it is a good practice to run this report with all options selected each time that substitution rules are updated.
Partial payments now generate line items with the same payment terms and profit center as the original invoice against which they are applied. (Figure 10.) You can continue to use document and posting dates when analyzing the date of financial activities, but the baseline date and payment terms ensure your aging report aligns the original invoice with any partial payments ( Figure 11.)

Figure 10
Entering partial payment via manual cash applications (transaction F-28)

Figure 11
Original invoice and partial payment with same Days in arrears despite different document dates
Bad Debt Write-Off
This user exit is similar to partial payments. The key difference is that you are going to change the expense account, account type, and profitability segment within the user exit to write off bad debt. The first step is to define a new reason code that enables you to identify those postings that should hit bad debt (Figure 12). This configuration can be found in the IMG (transaction SPRO) via menu path Financial Accounting>Accounts Receivable and Accounts Payable>Incoming Payments>Incoming Payments Global Settings>Overpayment/Underpayment>Define Reason Codes.

Figure 12
New reason code for bad debt
Again, you need your development team to include a new form and definition in program ZFI_EXITS. This code is illustrated in Figures 13 and 14. Note the profitability segment is found from any line within the original document that contained a profitability assignment. This may not be the perfect approach, because bad debt could be attributed to a single product when the invoice was placed for multiple products, but it serves as a useful example.

Figure 13
Append this logic to the end of ZFI_EXITS

Figure 14
Include this logic within form GET_EXIT_TITLES of program ZFI_EXITS
You insert a new step within the substitution, as defined in transaction OBBH. The prerequisite in this case checks for the newly defined reason code Z01 (BSEG-REBZG = ‘Z01'). Program ZGB01 again is used to maintain GB01. In this case, the fields BSEG-PAOBJNR, BSEG-PASUBNR, BSEG-BSCHL, BSEG-HKONT, BSEG-KUNNR, and BSEG-KOART must all be available.
Once this exit is in place, residual items created with a reason code of Z01 (Figure 15) automatically create expense postings with assignments to PA segments (Figure 16). If you are using costing-based PA, do not forget to maintain your "transfer of actual values" posting rules to specify which value field should be incremented by these financial accounting postings.

Figure 15
Residual items posting via manual cash applications (transaction F-28)

Figure 16
Bad debt write-off to PA
Transporting Changes
The majority of changes you have made are automatically attached to transport requests that can be released and moved through your transport path for further testing. The exception is the substitution rule itself. You must explicitly request a transport. Navigate to the substitution via transaction OBBH (menu path Environment>Substitution) and choose Substitution>Transport from the resulting menu path. Select only the first box in the next screen and execute to create a transport request. It is also advisable to run program RGUGBR00 in each of your destination clients after the imports to be sure the updated substitution rules are in place prior to testing.
Technical Setup
You must take several steps the first time you use ABAP code within financial user exits. These steps require the assistance of your development team. Once the steps are in place, you will require only minimal assistance to implement new user exit logic.
First, you must create a custom program in which user exit logic resides. The standard program that contains examples of user exit substitutions is RGGBS000. I often copy this program to something with a common name, such as ZFI_EXITS. After creating the new program, you adjust the configuration via transaction GCX2 to reference this new custom program. (Figure 1.) You receive a warning message that you are changing SAP configuration, but this process is outlined in several support notes.
R/3 limits the fields that may be substituted. This is controlled by the contents of table GB01. You need to maintain this table in order to achieve your substitution objectives. You can either have your ABAP team create a maintenance view for this table or implement the program shown in Figure 2 that allows you to update the table directly.

Figure 1
OBBH (setting up a new user exit)

Figure 2
New substitution overview where you provide a description
Matt Christensen
Matt Christensen is the director of Enterprise Performance Management at PRAGMATEK Consulting Group in Minneapolis. He has more than seven years of experience implementing a broad set of SAP financial modules, including configuration and development in R/3, Business Information Warehouse, and Strategic Enterprise Management. Matt holds an undergraduate degree in computer science and an MBA in finance.
You may contact the author at matt.christensen@pragmatek.com.
If you have comments about this article or publication, or would like to submit an article idea, please contact the editor.