Within the Logistics Execution module, there are few functions as important as Delivery Creation. After all, you can’t bill for what you don’t ship. Even within S/4 Hana, the VL10 transactions seem to offer the best, most flexible way to create deliveries. But what if you need to adjust the way SAP selects delivery scope in these transactions? Read on to see how I used the SAP Delivery Due Index routine to filter out certain deliveries from the list.
The Requirement: Prevent Unconfirmed Deliveries from Showing in VL10C
Sometimes we’re at the mercy of the system configuration that is placed in front of us. That’s the case for one of my clients, and it resulted in partially-confirmed Sales Orders showing up in VL10C. This meant that the shipping coordinator was forced to compare the delivery due list with order confirmations to ensure proper alignment.
The Delivery Due Index
How does SAP know what needs to be shipped? The ‘Delivery Due Index’! This is an SAP table where open delivery requirements are tracked. The table (VEPVG) contains basic information about delivery requirements like Shipping Point, Delivery Date, Route, Carrier, etc. The delivery due index is updated at various points in the logistics process, like when saving a Sales Document or Delivery.
The Solution: Custom SAP Delivery Due Index Routine to filter out Unconfirmed Sales Orders
Considering the nature of their business, I decided that the client is only interested in shipping fully confirmed Sales Documents. In order to accomplish this, we would need to make sure that only fully confirmed orders would appear in the Delivery Due list. After a bit of research, I found a routine (VOFM) which can be used to do exactly what I needed.
There is a routine that is executed when updating the Delivery Due Index (see above). The routine is accessible via VOFM at the following Node:
VOFM –> Requirements –> Subsequent Functions –> Delivery Due Index
The standard routine that was preconfigured in our system is ‘104’; it is already excluding some sales documents from the list — for example, orders on credit hold. The routine can access standard Sales Document tables such as VBAK and VBAP (and probably several others) which should give me what I need.
Additional Design Considerations
Now that I have a routine to use, I need to decide what logic to include to get the desired results. I want to be able to filter the list based on the Sales Document confirmation status. I also want to easily be able to switch the function on and off for particular orders. I definitely don’t want to paint my client into a corner.
First, let’s tackle the primary filter. Conveniently, S/4 HANA has a Sales Document header level confirmation status (VBAK-BESTK). In ECC 6.0, this field is located in VBUK instead. After some testing, I have confirmed that this field behaves as I need it to. I want to exclude documents that have a value of ‘A’ or ‘B’ — unconfirmed, or partially confirmed respectively.
I want to be sure to include an easy “off switch” in the event that the process isn’t working as expected, or if they simply want to ignore the validation for a particular order. I decided to tie this validation function to the ‘Complete Delivery’ flag located on the Sales Document header. In order to “enable” the function, I will update all customers to have the Complete Delivery function active. That way, if they wish to partially deliver the order, then can remove the flag. Alternatively, the users can simply use VL01n to directly create a partial delivery if desired; VL01n should bypass the custom validation entirely.
I decided to copy the standard ‘104’ to a new routine ‘904’ to accommodate the new validation. Click ‘Req.maintenance’ button to create new ones. I copied the code from 104 and added the below code. I created a new error message number (901) to capture a new note in the log describing this scenario. I added the two validations mentioned above and added a check for the Sales Org (VKORG) to prevent impacting other business units.
* Logic to exclude Unconfirmed Sales Orders
IF VBAK-BESTK CA 'AB' AND VBAK-AUTLF EQ 'X' AND
VBAK-VKORG EQ 'XXXX'.
* Read the subsequent function information for the message
PERFORM FOFUN_TEXT_READ USING GL_FOFUN
MESSAGE ID 'V1' TYPE 'E' NUMBER '901'
To summarize the code: if the Sales Order is not fully confirmed and the Complete Delivery indicator is active, and the Sales Org is equal to XXXX, the message will be issued to the log and the order will not be included in the Delivery Due Index and not considered when creating deliveries through VL10* transactions.
Lastly, the Routine must be set in configuration. This is done at the following configuration node (SPRO):
IMG -> Logistics Execution -> Shipping -> Worklists -> Maintain Requirements for Creating Worklists
It’s worth mentioning (if I haven’t done so already) that the SAP Delivery Due Index is not referenced when creating a delivery directly. Using VL01n, for example, will not check table VEPVG and will allow deliveries to be created while ignoring your custom Delivery Due Index logic.
One More Thing: The Selected Items Indicator
Please ignore this section. I no longer believe that this solution requires the Selected Items indicator be present.
The user exit that I mention above seems to only be called when the ‘Selected Items’ indicator is set on the Delivery Creation profile. Not to be confused with the ‘Profile for Shipping Due List’, the ‘Delivery Creation Profile’ contains different parameters which may apply differently depending on the scenario you’re working with. For instance, creating deliveries for Sales may need to be processed differently than deliveries for QM. Anyway… One of the parameters is the ‘Selected Items’ indicator which determines whether item-level details are considered during delivery creation. That seems to be the prerequisite for calling the aforementioned user exit.
It definitely works. As the SAP Delivery Due Index is updated, my code is called and the appropriate documents are excluded. What are your thoughts? Have you implemented anything similar to this before? Please share your thoughts in the comments.