S4HCKS27 How to handle varied multi-level approval processes and leverage a Business Rules like Framework

Some organisations have somewhat straight forward approval rules in place. By that I mean that there is a well defined structure where for example based on amount ranges and cost assignment types, one or more approvers will need to be determined to approve a spend. The approval process can span across several levels and the only variable that determines how many levels of approvals will be required are usually determined by the amount to be approved.

Then there are some organisations, where the approval  process is much more complex. For example a first level could be determined based on the account assignment, the second level could be based on the material type (service vs stock material), the amount of the spend, etc… you get the point, there are many more variables in play, that make the process more complex as more business rules need to be catered for….and the last thing that you want is for those rules to exist in your code! It is OK for the logic to embedded in code, but the rules (i.e whether John or Jane should approve) should be maintained by your business users. When the rules change or when employee leaves the organisation, such changes to your approval rules should be the responsibility of the business users to maintain.

Thankfully in SAP S/4HANA Cloud, especially since 1805 with the introduction of new functionality that allows you to keep track of approval levels in your custom logic, things just got a whole lot simpler!

In this simple example shown in the video, we will create a 2 item purchase requisition. As we are also performing the approval process at the item level, we will fire off 2 work items – one for each purchase requisition item. In this example, we are wanting to route the approval to a person that is neither the person responsible for the cost object, nor the manager of the person that created the requisition. We will therefor use the workflow approval Badi to define the logic to determine the approver(s). However as I said previously, we do not want to code in the logic the person that will receive the workflow approval request. No – we want to leverage a Business Rules like structure to hold this information.

To do so, we have created a custom business object – an approval table, as shown below.

The table that we added is simple in structure. For it we track the approval level, the cost object (the cost centre) and the approver of this combination. For the sake of simplicity, we will use the same table for the 2 approval levels that we have, but you can imagine, that you would have a different table for each approval level (if the structure was different of course).

From a coding point of view, there are two key elements in our logic.

The first one is retrieving the cost centre that was indicated as the cost assignment of the requisition items. To retrieve this information we directly call an API –> i_purreqnacctassgmt_api01. The code used here is:

SELECT SINGLE costcenter FROM i_purreqnacctassgmt_api01 INTO @data(lv_purchasereqcostcenter)
WHERE purchaserequisition = @purchasingdocument AND
purchaserequisitionitem = @purchasingdocumentitem.

Then the next piece of code is that which we use to retrieve the user that will become the approver. As I said, we do not want this in the code – so we need to go and fetch that information from our custom business object. The code used here is:

SELECT single approvinguser FROM yy1_approvalstable INTO @ls_badi_approver
WHERE CostObject = @lv_purchasereqcostcenter AND
ApprovingLvl = 1.

Essentially we are retrieving the business user ID of theApprover , for which the cost centre and approval level match where we are in the purchase requisition approval process.

Video: Varied approval process supported by a Business Rules like Framework

Update 19 July 2018

By request, I am also adding the full custom logic code which I used to illustrate this determination.

DATA:

ls_badi_approver TYPE if_mmpur_workflow_agents_v2=>bd_mmpur_s_badi_approver,
lt_badi_approver TYPE if_mmpur_workflow_agents_v2=>bd_mmpur_t_badi_approver,
ls_previous_approver TYPE if_mmpur_workflow_agents_v2=>bd_mmpur_s_previous_approver,
ls_new_approver TYPE if_mmpur_workflow_agents_v2=>bd_mmpur_s_badi_approver.

SELECT SINGLE costcenter FROM i_purreqnacctassgmt_api01 INTO @data(lv_purchasereqcostcenter)
WHERE purchaserequisition = @purchasingdocument AND
purchaserequisitionitem = @purchasingdocumentitem.

SELECT single approvinguser FROM yy1_approvalstable INTO @ls_badi_approver
WHERE CostObject = @lv_purchasereqcostcenter AND
ApprovingLvl = 1.

APPEND ls_badi_approver TO lt_badi_approver.
ls_badi_approver-approvallevel = 1.

SELECT single approvinguser FROM yy1_approvalstable INTO @ls_badi_approver
WHERE CostObject = @lv_purchasereqcostcenter AND
ApprovingLvl = 2.

APPEND ls_badi_approver TO lt_badi_approver.
ls_badi_approver-approvallevel = 2.

** remove the previous approvers from the list of BAdI approvers
LOOP AT previousapproverlist INTO ls_previous_approver.
READ TABLE lt_badi_approver INTO ls_badi_approver
WITH KEY businessuser = ls_previous_approver-businessuser.
CHECK sy-subrc = 0.
DELETE lt_badi_approver WHERE approvallevel = ls_badi_approver-approvallevel.
ENDLOOP.
*
** determine the next approval level and appropriate approvers
READ TABLE lt_badi_approver INTO ls_badi_approver INDEX 1.
LOOP AT lt_badi_approver INTO ls_new_approver
WHERE approvallevel = ls_badi_approver-approvallevel.
APPEND ls_new_approver-businessuser TO approverlist.
ENDLOOP.

If you want to replicate my custom business object, here is its structure.

Lastly, I am also adding the ‘After modification’ logic that I used in my custom business object. This logic is used to increment the ID number of the custom object entries as well as retrieve the name of the user id entered (useful to confirm that the entered code is a valid one).

* After Modify Determination for Node ID APPROVALSTABLE
*
* Importing Parameter : association (Navigation to Parent/Child/Associated Node Instances)
* write (API for creating and updating Custom Business Object Node Instances)
* Changing Parameter : APPROVALSTABLE (Current Node Data)

* set ID
IF approvalstable-entryid IS INITIAL.
SELECT MAX( entryid ) FROM yy1_approvalstable INTO @DATA(current_max_id).
approvalstable-entryid = current_max_id + 1.
ENDIF.

IF approvalstable-approvinguser IS NOT INITIAL.
approvalstable-approvername = cl_abap_context_info=>get_user_formatted_name( approvalstable-approvinguser ).
ENDIF.

If you enjoy this post, please consider subscribing to our youtube channel and follow the hashtag #S4HCKS on twitter.

Version used in recording 


S4HCKS26 Extend S/4HANA Cloud with a native iOS SAPFiori app with the iOS SDK

In this SAP S/4HANA Cloud Knowledge Snippet (S4HCKS), we will be exploring how easily you can extend your SAP S/4HANA Cloud system by building a native iOS app for your users. You might ask the question why? After all my S/4HANA Cloud system is consumed via a web browser so why would I want to build an app for that? I take your point, but:

  • Not all apps can be consumed on a phone size screen (either the app is not available or the user experience would be terrible)
  • With a native app, the GUI elements reside in the app on the phone (if you are in an area where mobile charges are steep, this is important)
  • With a native app, you can have offline capabilities which is mighty helpful when there is no cellular coverage
  • You might want to create a mashup app that interacts with your S/4HANA cloud system as well as other external systems (without needing for the user to log on to multiple apps)
  • Maybe you have a predominantly nomadic workforce and it makes sense to build a native app that integrates with other functions on your device (camera, phone, GPS, etc…)
  • ….and many more.

So in this snippet, we will use a custom business object as the starting point, expose the data from this custom object as an Odata service, consume it as a service that is registered as a destination on the SAP Cloud Platform – and all that on an native iOS app built with the SAP iOS SDK. Why? Because I want to demystify the preconceived idea that this is too complex and in fact show how easy it is to do all this with the tools that SAP provides. I am by no stretch of the imagination a developer, so if I can do it, then so can you. Furthermore, all the tools used in this snippet are free, so there really is no excuse to not give it a go! You just need an Apple Mac!

There are certain things that are not covered in this movie, such as creating a communication arrangement in S/4Cloud, or what you need to do on the SAP Cloud platform, where to download the iOS SDK, etc…. There are plenty of blogs, videos and tutorials out there to help you for that. I have however listed a few choice ones below that I found very helpful during my explorations.

Lastly, I would like to point out that I was damn impressed with how much the development team was able to pack in this SDK! As you will see in the video, after having indicated just the web service that I want to consume, the app that is built out of the iOS SDK is just so complete! Sure you cannot put that in the hands of your users, but the amount of functionality that is delivered in this app, without needing for me to type a single line of code is just mind blowing. It sets the stage for you to be able to, with minimal changes, to build an awesome app to your users.

Video: Extend SAP S/4HANA Cloud with a native iOS SAPFiori app with the SAP iOS SDK

If you enjoy this post, please consider subscribing to our youtube channel and follow the hashtag #S4HCKS on twitter.


S4HCKS22 User Authorizations in SAP S/4HANA Cloud

In this S/4HANA Cloud Knowledge Snippet, we will be going back to basics and look at a topic that is too often considered as an after thought : Authorizations. In other words who can see and do things in your system. Whilst it is understandable that you want to go straight to the heart of the action and explore all the great features of SAP S/4HANA Cloud, I can only recommend that you give this topic its due attention – as not doing so could be prejudicial to your organization.

This snippet will begin with a introduction to the topic, explaining the authorisation concept in SAP S/4HANA Cloud, and then move on to a concrete use case in the system – showing you how to create a role, maintain the authorisations that you want this user to have and then see if that user is indeed able to do what I want to do. Toward the end of the snippet I also show you some additional features that are available to you when working with roles, and in particular how to move them from your testing environment to your production landscape.

For those of you that want to jump right to a topic, I have below indicated the time markers:

Introduction to authorizations in SAP S/4HANA Cloud – how things hang together  00:45
The apps to work with to manage roles 01:30
From authorization to user and everything in between 03:00
A concrete example – Setting it up in the system 10:22
Topic round offs 36:00
If you enjoy this post, please consider subscribing to our youtube channel and follow the hashtag #S4HCKS on twitter.


SAP Batch Determination made easy

Recently a colleague encountered the following problem:

His customer tracks perishable products that are bought / inventory managed / sold using the SAP functionality Batch Management (LO-BM). The products have a shelf life and therefore a “Use by/Expiration” date. His problem was that he was able to correctly update the characteristic “Expiration date” of the batch, but was not able to select batches during the delivery stage, based on the “Expiration date” – i.e batches that were still fit for use.

So here is a tutorial on how to select batches during the delivery (but it could be applied to any batch search requirement) for which the shelf life has not expired. It has to be noted that SAP covers all kinds of scenario.

– It might be company practice to ship out the door products with a minimum shelf life of X days
– It might be that a specific customer requires a product with a different, longer minimum remaining shelf life
– It might also be that products that are shipped to a specific country require a yet again different minimum shelf life

It might be that you require all three or a logical combination of all three. SAP will easily cover all those requirements and more.

This tutorial only covers the batch determination process in SD, but once you get the jist of it you should be able to apply this to any other module where that function is covered. I also assume that you have set up your system in such way that you are able to have products batch managed.

Step 1 – Standard SAP characteristics you will import

The first thing you need to do is to check that your SAP client has all the required SAP standard characteristics. To do this go to transaction CT04 and query your system to find all characteristics that are called LOBM*.

If a list of values such as the one below is returned then it means that you are all set to go to Step 2 – Create and assign Batch class to products.

If not it means that you need to copy them from client 000. To do that go to customizing and follow the path indicated: Customizing / Logistics – General / Batch Management / Batch Valuation / Updates Standard Characteristics (or transaction BMSM)

The following messages will be displayed if everything goes well.

Once that is done you might want to go back to transaction CT04 and query for characteristics called LOBM*.

Why do I need to do that do you ask? Well for one thing all the work is done for you. Secondly and more importantly the standard SAP functions that will enable us to dynamically calculate the “Expiration date” based on minimum remaining shelf life, makes use of these standard characteristics – they are hard coded in the ABAP functions.

Moving on to step 2 and getting your basic data right.

Step 2 – Create and assign Batch class to products you will do

In our case we have one product, to which we have assigned one class (of technical type 023 – batches). This class has been conveniently called “EXPIRATION” and contains only one characteristic. That characteristic is one of the standard SAP ones called “LOBM_VFDAT – Expiration date, shelf life”. The system has been set up in such a way that when ever I do a goods receipt on this product, SAP will ask me to input the production date and then based on the shelf life of the product, automatically calculate the expiration date of my batch.

This will update a standard SAP table field (MCHA-VFDAT / MCH1-VFDAT – depending on the validity of your batch across plants). This will in turn update the value of the characteristics LOBM-VFDAT within the batch .

So if we look at the shelf life list report (transaction MB5M) we see that this information concurs with that contained in the classification of our batches.

Step 3 – Create a Batch search class you will do

This is a class that will be used to search and find applicable batches during batch determination. It is not directly assigned to the product – it will be assigned to the batch search strategy of the product.

The question is, what characteristics should we put in this class?

If we go back to basics, what we will want to do, is find batches that have a remaining shelf life of X days. If we view this requirement in a different way, we can say that we will want to find batches that have an expiry date that is equal or greater to “delivery date + X days” . My class will therefore use the following characteristics:
– LOBM-VFDAT : The expiration date of the batch – that value SAP will calculate.
– LOBM-LFDAT : The delivery date – that value will be automatically updated by SAP with the delivery date from the delivery

All we need is a characteristic where we will be able to input the value corresponding to X (minimum remaining shelf life required). Again, we do not need to do anything, SAP provides the characteristic “LOBM_RLZ – Remaining Shelf Life for Batch”, to do just that. We therefore have a class (also of technical type 023 – batches) that looks like this.

Step 4 – Create a sort rule you will do

It’s all good to build a batch search class to find batches, but assuming SAP finds numerous batches, how should they be sorted (i.e which should be the first one used?) ? By batch number? Of course not, we want to sort batches based on the expiration date in ascending order (the batches with the date closest to the present should be the first to go).

To do this, call transaction CU70.

Give your sort sequence a name and in the following screen, give it a description as well.

Then click on the characteristics button and assign the characteristic LOBM-VFDAT to it. Also select/amend the sort order that you want.

Save your sort key.

Step 5 – Create a batch search strategy you will do

We want to create a search strategy during delivery processing, i.e in SD – Sales and distribution. So call transaction VCH1 – to create it. We’ll create a strategy determined based on the customer and the material (standard strategy type SD01 caters for that).

Enter your customer and product (amend the strategy as required).

Click on the “selection Criteria” button to assign the search class. In this case we indicated our search class, which copied across the characteristics associated with it.
We also indicate the value “>=30” in the characteristic “Remaining Shelf Life for Batch” – this means that we will only want to select batches that have an expiration date that is greater or equal to delivery date + 30 days.

Now go back to the previous screen and now click on the “sort” button. There you will assign the sort rule you created in the previous step.

Save your work.

Step 6 – Putting it into practice - the fruit of your efforts you will see

Now that we have created all the required basic data, let’s see how it all hangs together.

We have a sales order for which we create a delivery – batch search will be triggered manually to better follow the process.
In the delivery, we go to the batch determination screen and we see that the system has automatically searched, found and proposed batches that have a remaining shelf life that is greater or equal to 30 days only and it has sorted them according to expiration date – just what we wanted.

The system here proposes 3 batches (yet remember that above, it did indicate that we had 5 batches in the system). To get a better idea of what parameters were calculated/used to determine those three batches, click on the “selection criteria button”.

We see the >=30 that we typed in the batch search strategy. We also see that the system took the delivery date “08.09.2008” added 30 days to it and determined that the batch it was going to search for had to have an expiration date greater or equal to 08.10.2008.

We can also change the search parameters here (this is customizable). We’ll change the value of 30 to 4 right there in the batch determination.

This shows even more batches – logical as we have indicated that batches should only have a remaining shelf life of 4 days or more.