JAP: An APS or APO module in SAP

2019-04-08 10:40:12

JAP: An APS or APO module in SAP

So, how does JAP work?

A good method for the policy is made-to-order (MTO) mixed with made-to-stock (MTS), which many small and medium-sized enterprises  use to fulfill customer orders. The approach has been used for products with multilevel bills of materials (BOM) with various subassemblies, which uses stock production for internal orders in SAP.

Every plant manager needs to know how to manage his or her tasks. Amid the thousands of problems that are possible every day, a good manager should pay closest attention to the theory of constraints (TOC). In any case, he or she absolutely needs a big picture of the situation.

Painting a picture of reality: Production scheduling!

As an initial step, the routine involves selecting all of the primary demands (i.e., customer orders) and storing them in an internal table.

As an example of coding: See function module.

 CALL FUNCTION 'SD_SELECT_SALES_DOCUMENTS'
      EXPORTING
        iv_trvog          = iv_trvog
*       IV_BSTKD          =
*       IV_ZPAVW          =
        iv_vboff          = 'X'
        iv_vball          = 'X'
      TABLES
        t_vbmtv           = lt_vbmtv
*       LVBMTV            =
        i_vkorg_rt        = vkorg_rt
*       I_VTWEG_RT        =
*       I_SPART_RT        =
        i_matnr_rt        = matnr_rt
*       I_KUNNR1_RT       =
*       i_vkbur_rt        =
*       I_VKGRP_RT        =
        i_auart_rt        = auart_rt
*       I_ERNAM_RT        =
*       I_VBELN_RT        =
*       I_AUDAT_RT        =
        i_werks_rt        = werks_rt
*       I_ZPERS_RT        =
        i_datab_rt        = datab_rt
*       I_ERDAT_RT        =
              .

After the primary demands are built, all collective orders (i.e., order networks) can be built. To that end, I use a function module:  MD_SALES_ORDER_STATUS_REPORT

CALL FUNCTION 'MD_SALES_ORDER_STATUS_REPORT'
     EXPORTING
*      EDELET                   = 0000
       edelkz                   = ls_zkndposition-delkz
       edelnr                   = ls_zkndposition-del12
       edelps                   = ls_zkndposition-delps
*      EPLSCN                   = 000
*      AVAILABILITY_CHECK       = ' '
       no_savety_stock          = safety_stock
*      DATA_IN_MEMORY           = ' '
*      MEMORY_ID                = 'PLHS'
       ematnr                   = gs_zkndposition-matnr
       ewerks                   = gs_zkndposition-werk
*      EBERID                   = ' '
       emdps                    = ls_emdps
       nodisp                   = 'X'
       i_ignore_mtold           = 'X'
*      I_PROFID                 = ' '
*      I_REP_REFRESH            = ' '
*      IS_PROFILE               =
*      IT_VBEP_KEYS             =
       no_commit_work           = 'X'
*    IMPORTING
*      ET_MLDELAY               =
*      ET_RTREE_SEL             =
     TABLES
       iioelx                   = gt_ioel
     EXCEPTIONS
       error                    = 1
       OTHERS                   = 2
             .

The module provides an internal IOELX table. In the following step, by using a recursive method, an ABAP class is used to build the final collective order (order network) for each primary demand stored in the database.

That sort of collective order is the cornerstone of the entire JAP module.

All components (e.g., planned orders, production orders, and purchase orders) have their own schedules and due dates because stock production affords no connections among BOM levels.

Therefore, the next class method is used to search all BOM levels and thereby calculate the new schedule for each component in order to create dependency between subassemblies and their lower parts. This step serves the entire process time for the customer orders, as the picture below illustrates:

METHOD get_net_for_schedule.
    DATA: lo_schedule TYPE REF TO lcl_order_schedule.
   LOOP AT gt_orders_schedules ASSIGNING FIELD-SYMBOL(<schedule>) WHERE delnr = gs_zkndposition-delnr
    AND delps = gs_zkndposition-delps.
    lo_schedule = lcl_order_schedule=>create( is_schedule = <schedule>  io_order = me ).
    IF <schedule>-delkz NE 'PP' AND <schedule>-delkz NE 'U4'.
     LOOP AT gt_ioel ASSIGNING FIELD-SYMBOL(<prim>) WHERE rsnum = <schedule>-delnr
      AND rspos = <schedule>-delps AND etenr = <schedule>-delet AND sobes NE ' '.

       lo_schedule->set_primary_replenishement( <prim> ).
     ENDLOOP.

    ELSEIF <schedule>-delkz = 'PP'.
     get_lt_ioel_for_pp_u4( <schedule> ).
     LOOP AT gt_ioel ASSIGNING FIELD-SYMBOL(<prim_pp>) WHERE rsart+0(2) = <schedule>-delnr+0(2)
      AND dat00 = <schedule>-dat00 AND sobes NE ' '.

       lo_schedule->set_primary_replenishement( <prim_pp> ).
     ENDLOOP.

     ELSEIF <schedule>-delkz = 'U4'.
     get_lt_ioel_for_pp_u4( <schedule> ).
      LOOP AT gt_ioel ASSIGNING FIELD-SYMBOL(<prim_u4>) WHERE rsnum = <schedule>-delnr
      AND rspos = <schedule>-delps AND etenr = <schedule>-delet AND sobes NE ' '.

       lo_schedule->set_primary_replenishement( <prim_u4> ).
     ENDLOOP.
     ENDIF.
         lcl_order_schedule=>gt_zordernet_all =
      VALUE #( BASE lcl_order_schedule=>gt_zordernet_all  ( LINES OF lo_schedule->gt_zordernet ) ).
   ENDLOOP.

  ENDMETHOD.

  METHOD set_primary_replenishement.
     gs_zordernet = CORRESPONDING #( i_prim MAPPING delnrpos = delnr ).
     set_custom_order( CHANGING c_gs_zordernet = gs_zordernet ).
     gs_zordernet-stuffe = gv_level.
     gs_zordernet-adresnet = gv_adress.
     gv_adress = gv_adress + 1.
     gt_zordernet = VALUE  #( BASE gt_zordernet ( gs_zordernet ) ).

     gt_plant_orders = VALUE  #( BASE gt_plant_orders ( CORRESPONDING #( i_prim ) ) ).
     CLEAR gs_zordernet.

     set_second_replenishement( i_prim ).

  ENDMETHOD.

  METHOD set_second_replenishement.
   DATA: lv_nxtrs TYPE delnr.
   lv_nxtrs = i_ioel-nxtrs.
     CLEAR gs_zordernet.
     gv_level = gv_level + 1.
      LOOP AT go_order->gt_ioel ASSIGNING FIELD-SYMBOL(<ioel>) WHERE rsnum = lv_nxtrs AND sobes <> ' '
                                                                         AND plumi = '+'.  .
            gs_zordernet = CORRESPONDING #( <ioel> MAPPING delnrpos = delnr dat00 = rsdat ).
            IF <ioel>-delkz IN rt_delkz.
             gs_zordernet-dat00_s = <ioel>-dat00.
            ENDIF.
            set_custom_order( CHANGING c_gs_zordernet = gs_zordernet ).
            gs_zordernet-stuffe = gv_level.
                 gs_zordernet-adresnet = gv_adress.
                 gv_adress = gv_adress + 1.
            gt_zordernet = VALUE  #( BASE gt_zordernet ( gs_zordernet ) ).
            gt_plant_orders = VALUE  #( BASE gt_plant_orders ( CORRESPONDING #( <ioel> ) ) ).
            CLEAR gs_zordernet.
      IF <ioel>-nxtrs IS NOT INITIAL.
       set_second_replenishement( <ioel> ).
      ENDIF.
      ENDLOOP.
    gv_level = gv_level - 1.
  ENDMETHOD.

These primary demands (e.g., customer orders) with their order networks (e.g., collective orders) are stored in a database table. Every night, the approach is run as a task after MRP is complete. Such data provide various opportunities to see the bigger picture. In fact, a user can view the realistic processing time for the order and take action based on the critical path, which can be viewed from the perspective of the entire collective order. Another option for the purchase department is to view critical departmental purchase positions and take action against potential problems. There are many others ways to evaluate the data and view it from various angles as well.

So, what’s the difference from others’ similar software?

JAP is not complicated, easy to understand, and fully integrated in SAP. Moreover, it allows users to easily change the logic of the routines and how they work by using APAB.

The next step involves building the bigger picture in order view capacity requirements and their constraints.

…to be continued….