Correct warehouse placement involves the movement of materials that don't always satisfy the specific requirements of existing systems. Learn how to use custom strategies for placement of materials and other placement needs.
Key Concept
A placement strategy defines the logic for determining target storage bins for materials that are moved into a warehouse. Using custom placement strategies, you can program special algorithms in already available user exits to satisfy specific placement requirements.
My focus here is on how to use the placement user exit and how
to overcome certain challenges associated with it. The explanations
of how the user exit is designed can be used by anyone who needs
to develop a placement strategy following a specific custom logic.
The custom logic itself is not discussed in this article.
Why Custom Placement Strategy?
In this particular situation, the development of a custom placement
strategy was necessary due to a shortcoming in standard placement
strategies. To optimize bin space, we decided to use the "addition-to-existing-stock" strategy.
According to this strategy, every time materials are received
in the warehouse, the system checks for existing stock of the
same material and tries to fill up any space in those bins with
the newly received material.
Should there be no existing stock or no remaining capacity
in any of the bins with existing stock, the "next empty
bin" strategy is used. This standard strategy sounded great
until we found out that the combination of this strategy with
storage unit (SU) management does not work in the way my client
needed. Following the standard addition-to-existing-stock strategy,
the system tries to add to existing storage units, whereas in
this case the client needed to create new storage units that
they could place in the bins which contained the same material.
You might need to use a custom strategy to implement a specific
placement logic that applies to your warehouse for many reasons,
such as grouping products by specific characteristics (e.g.,
product group).
SAP User Exit MWMTO003
SAP Enhancement (user exit) MWMT0003 allows
the integration of custom logic placement strategy to transfer
order (TO) processing. It provides four different hooks into
the flow of TO creation where you can apply custom code to manipulate
the placement of stock.
To access this user exit and review the documentation, use
transaction SMOD. For general details of the
SAP user exit development, refer to the chapter "Customer
Exits" under "Changing the SAP Standard (BC)" of
the standard SAP help.
The following steps show how to activate the custom placement
user exit:
Step 1. Set the appropriate flag in the configuration
of the relevant storage types (Figure 1). You
can activate custom strategy via user exits for each storage
type. This gives you the flexibility to use the custom strategy
for some but not all your storage types. If different custom
logic is required for different storage types, you need to
embed the differentiation in the code of the user exit.

Figure 1
Set the flag in the storage type definition
Step 2. Implement your custom logic. Create
an SAP Enhancement project using transaction CMOD.
Assign the above-mentioned SAP user exit MWMTO003 to
your project and go to the components page (Figure 2).

Figure 2
Implement relevant components in MWMTO003
Each component represents an SAP function module,
which is delivered with a predefined parameter interface
but does not contain code. Once a user exit project
is activated, the standard process flow always branches
into the custom code by calling these function modules
from the appropriate main programs.
Once you assign MWMTO003, the
green checks indicate that the individual components
have been implemented (coded) and the green lights
indicate the project and the individual components
are activated.
Components of MWMTO003 and Their
Functions
To begin developing your custom placement strategy,
you must understand the exact sequence of events
in the process of creating a TO and the exact points
in the process where each component of the user exit
is called. The flowchart in Figure 3 explains
the sequence of events. It is followed by a description
of how you can use each component and sample code
supporting the use with this approach.

Figure 3
Standard transfer order item creation process Click here for a larger image. You may need to mouse-over the image in the new screen and click on the size button to make the image full-size.
One of the technical challenges of implementing
a custom placement strategy is that the user exit
components are executed multiple times during the
process of creating a TO. During each run, you need
to know what happened during the previous runs through
the user exit. In other words, when you are processing
a TO with multiple items (e.g., because you are creating
multiple storage units), the information that is
provided to you in each call of the user exit only
pertains to the current item, even though you need
the information about previously processed items.
For example, you will need more information to decide
if there is still sufficient capacity in a bin that
you used for previous items. You cannot read the
previous items from the database either, because
all items are posted together when the TO is finished
and saved. To overcome this problem, you need to
use the EXPORT TO MEMORY and IMPORT
FROM MEMORY functions (For details, refer
to ABAP/4 documentation).
Note
The R/3 Enhancement Concept, also referred to as customer exits, is a set of user exits organized in logical groups called "Enhancements." Unlike the original type of user exits, these can be activated and deactivated as needed. For details, refer to the R/3 standard help and search for "Customer Exits" under "Changing the SAP Standard (BC)"
Tip!
Activation and implementation of a custom picking strategy is similar to that of a placement strategy.
Tip!
It is not mandatory to implement all components of a user exit. You can implement and use only those components that are relevant to the logic you are implementing.
Step 1. User exit component 001
In this step, the calling program provides the
user exit with all relevant information regarding
the TO item to be created in parameters like I_LTAK or
I_LTAP,
such as material, quantities and weights, and source.
Using this information, you need to apply custom
logic to determine a suitable target bin and return
the target bin in the export parameter E_NLPLA.
Using the export parameter E_SUBRC,
you can let the calling program know whether a target
bin was found or not and what the system should do
next if no target bin could be determined (e.g.,
apply next-empty-bin logic or let the user enter
a bin manually). For more detail, refer to the documentation
for user exit MWMTO003.
In addition, you need to store the information
about the current TO item in an internal table and
export the contents to memory, so that you can access
and use this information during the next call of
this user exit component.
Sample code component 001 for this
purpose is shown in Figure 4. In the
first step, the previously exported content of the
internal table (if any) is made available by using
the IMPORT FROM MEMORY statement.
(For details, refer to ABAP/4 documentation.) Data
that is imported belongs to the currently processed
transfer requirement, as the transfer requirement number
is used as the memory ID. However, it might still be
obsolete if the transfer requirement was processed
previously within the same session but not saved.
*-------------------------------------------------------*
* INCLUDE ZXLTOU03
* Placement user exit component 001 *
*-------------------------------------------------------*
DATA: BEGIN OF t_ltap OCCURS 20.
INCLUDE STRUCTURE ltap.
DATA: dstamp LIKE sy-datum,
tstamp LIKE sy-uzeit.
DATA: END OF t_ltap.
DATA: garg LIKE seqg3-garg.
DATA: enq_tab TYPE TABLE OF seqg3 WITH HEADER LINE.
* Import previously exported content of internal table
IMPORT t_ltap FROM MEMORY ID i_ltak-tbnum.
* Remove any obsolete table entries
IF sy-subrc = 0.
CONCATENATE sy-mandt i_ltak-lgnum i_ltak-tbnum
INTO garg.
CALL FUNCTION 'ENQUEUE_READ'
EXPORTING
gclient = sy-mandt
gname = 'LTBK'
garg = garg
guname = sy-uname
TABLES
enq = enq_tab
EXCEPTIONS
communication_failure = 1
system_failure = 2
OTHERS = 3.
READ TABLE enq_tab INDEX 1.
IF sy-subrc = 0.
LOOP AT t_ltap.
IF t_ltap-dstamp < enq_tab-gtdate OR
( t_ltap-dstamp = enq_tab-gtdate AND
t_ltap-tstamp < enq_tab-gttime ).
DELETE t_ltap.
ENDIF.
ENDLOOP.
ENDIF.
ENDIF.
* Apply custom logic to determine target bin
*...
*...
* Assign determined bin
e_nlpla = ...
e_subrc = r_cus_ok.
|
| Figure
4 |
Sample code for
component 001, to determine a suitable target
bin |
So that you can identify obsolete cases, every
record of the internal table is stamped with a date
and time. The stamps are compared with the current
lock-entry time stamp, which represents the latest
start of processing a transfer requirement. With
the data provided by the calling program and the
data imported from memory, the custom logic can be
applied to determine the target bin. The target bin
is then passed back to the calling program with appropriate
return code.
Step 2. User exit component 002
This component is used only if you check manually
entered storage bins against custom rules. This may
be necessary if the user overrode the proposed storage
bin. The suitability of the bin selected by the user
can be validated, accepted, or rejected using this
component. If information about previously processed
items is relevant for this check, you can import
the information using the identical code that is
used for this purpose in components 001 and 003.
Based on the results of the check, the calling
program is informed whether the manually entered
bin is to be accepted, accepted with warning, or
rejected. For further details, refer to the standard
documentation for the user exit.
Step 3. User exit component 003
This is an important component if the temporary
storage of the processed items is relevant to custom
logic when processing subsequent items. This component
is called upon completion of processing a TO item
and provides the perfect opportunity to save all
relevant information in the internal table. The internal
table is exported to memory and imported again in
subsequent calls to this and other user exit components.
The sample code demonstrates how all of the TO
item information is saved and enhanced by adding
date and time stamps. The date and time stamps are
used to identify obsolete records of the internal
table.
Sample code component 003 in Figure
5 demonstrates how to append to the contents
of the internal table when a new TO item is created.
This is accomplished using the EXPORT TO
MEMORY statement. The first part, which
deals with removing obsolete internal table records,
is identical to the code explained under the sample
code for component 001.
*-------------------------------------------------------*
* INCLUDE ZXLTOU05
* Placement user exit component 003 *
*-------------------------------------------------------*
DATA: BEGIN OF t_ltap OCCURS 20.
INCLUDE STRUCTURE ltap.
DATA: dstamp LIKE sy-datum,
tstamp LIKE sy-uzeit.
DATA: END OF t_ltap.
DATA: garg LIKE seqg3-garg.
DATA: enq_tab TYPE TABLE OF seqg3 WITH HEADER LINE.
* Import previously exported content of internal table
IMPORT t_ltap FROM MEMORY ID i_ltak-tbnum.
IF sy-subrc = 0.
* Remove any obsolete table entries
CONCATENATE sy-mandt i_ltak-lgnum i_ltak-tbnum
INTO garg.
CALL FUNCTION 'ENQUEUE_READ'
EXPORTING
gclient = sy-mandt
gname = 'LTBK'
garg = garg
guname = sy-uname
TABLES
enq = enq_tab
EXCEPTIONS
communication_failure = 1
system_failure = 2
OTHERS = 3.
READ TABLE enq_tab INDEX 1.
IF sy-subrc = 0.
LOOP AT t_ltap.
IF t_ltap-dstamp < enq_tab-gtdate OR
( t_ltap-dstamp = enq_tab-gtdate AND
t_ltap-tstamp < enq_tab-gttime ).
DELETE t_ltap.
ENDIF.
ENDLOOP.
ENDIF.
ENDIF.
* Add entry for the current item
t_ltap = i_ltap.
t_ltap-dstamp = sy-datum.
t_ltap-tstamp = sy-uzeit.
APPEND t_ltap.
* Export content of internal table to memory
EXPORT t_ltap TO MEMORY ID i_ltak-tbnum.
|
| Figure
5 |
Sample code for
component 003, to update the internal table for
a new TO |
Step 4. User exit component 004
This component is called each time the user removes
a previously created item manually. If the concept
explained here to store information about previously
processed items is relevant, the implementation of
this component is mandatory and must be used to remove
the correct item from the internal table when a previously
created TO item is removed.
Sample code component 004 in Figure 6 demonstrates
how to update the content of the internal table when
a previously created item is removed from the TO.
*----------------------------------------------------------------------*
* INCLUDE ZXLTOU06
* Placement user exit component 004
*
*----------------------------------------------------------------------*
DATA: t_ltap TYPE TABLE OF ltap WITH HEADER LINE.
IMPORT t_ltap FROM MEMORY ID i_ltak-tbnum.
DELETE t_ltap INDEX i_ltap-tapos.
EXPORT t_ltap TO MEMORY ID i_ltak-tbnum.
|
| Figure
6 |
Sample code for
component 004, to update the
internal table for the removal of an item from
the TO |
Ali Sarraf
Ali Sarraf is the managing partner at Enowa Consulting. He has 15 years of experience as a senior consultant for SAP Business Suite applications and 20 years of IT experience. During much of his career, he has focused on helping customers optimize their logistics business processes by analyzing and explaining cause-and-effect relationships and by bringing the machine and the human sides of IT closer together.
You may contact the author at ali.sarraf@enowa.com.
If you have comments about this article or publication, or would like to submit an article idea, please contact the editor.