cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

Incompatibilities at freight unit consolidation

petra_just
Active Participant
4,518

hi experts,

today, I have a request to define incompatibility criteria for freight unit consolidation using report /SCMTMS/SUBSEQUENT_FUB_LOGINT. The report allows to consolidate several sales orders of the same ship-to even after the initial FU has already been built. This may help reduce the number of FUs a lot in the cockpit as many customers place several orders in a day. But, the consolidation shall only happen if the unloading point and the incoterm 2 are the same. To fulfill this requirement, we have defined an incompatibility setting that we have assigned to the freight unit building rule.

But, the incompatibility is ignored. Actually, I learned from the post of Bernd Dittrich that there is no more persistent TRQ object any more in S/4 Hana embedded. He suggests to use class /SCMTMS/CL_COND_TRQTR_EXTR to make the system read the trq object. I have copied the class and wnated to adapt it for my two trq fields.

But, the it_boinst_key is referring to a TRQ item that is not persisted. If I try to retrieve the trq data, it dumps.
What coding do I have to write to fill the field UNLOAD_POINT which was previously in the TRQ item.

How to pass the content of the field to the dad.

Link to the Blog from Bernd Dittrich:

https://blogs.sap.com/2019/01/30/wks-how-to-access-trq-data-in-tm-embedded-in-s4/

thanking you in advance for helping me out with some sample coding.

regards

Petra Hunger

Accepted Solutions (1)

Accepted Solutions (1)

Drago
Product and Topic Expert
Product and Topic Expert
0 Likes

Strictly from the programming perspective, yes, you cannot use BOPF retrieves on the trasient TRQ. In the class that you copied, /SCMTMS/CL_COND_TRQ_CT_EXTR, there is code that casts the object IO_CONTEXT to the expected TRQ data container, from which you can then access "node" data via the corresponding member attributes.

But before that, you might wanna look into Rajesh's suggestion.

BR, DragoÈ™

petra_just
Active Participant
0 Likes

Hi Dragos,

have found the field unloading point in the item_stages MT and copied and changed the class as below.

But et_bokey_dokey_data is empty. I need to start from the item object, read the first PRD item and take one of the stage entries. The field I am looking for is UNLOAD_POINT. Would you please tell me what I am doing wrong?

METHOD /SCMTMS/IF_COND_DETERM_CLASS~EXTRACT_DATA_MASS.

      BREAK-POINT.

    "Petra Hunger, 10.05.2021
    "This class reads the transient TRQ context data and finds the uloiading point.
    "Then, it passes the unloading location to the target table.

    DATA: lo_trq_data TYPE REF TO /scmtms/cl_trq_data.
    CONSTANTS: lc_own_class TYPE /scmtms/cond_det_class VALUE 'ZCL_UNLOAD_POINT'.
    CLEAR et_bokey_dokey_data.

    " Check prerequisites
    IF NOT io_context IS INSTANCE OF /scmtms/cl_trq_data.
      IF io_context IS NOT BOUND.
        " Try to get TRQ container as fallback
        TRY.
            lo_trq_data = /scmtms/cl_fu_builder_helper=>get_trq_data_container( ).
          CATCH /scmtms/cx_fu_builder_fatal.
        ENDTRY.
      ELSE.
        ASSERT ID /scmtms/tech_cons CONDITION 1 = 0. " This class can only be used with a provided data container
      ENDIF.
    ELSE.
      lo_trq_data ?= io_context.
    ENDIF.

    ASSERT ID /scmtms/tech_cons CONDITION lo_trq_data IS BOUND.
    CHECK lo_trq_data IS BOUND.


    LOOP AT FILTER #( it_dobo_link USING KEY class_data WHERE class_name = lc_own_class ) ASSIGNING FIELD-SYMBOL(<fs_do_bo>).

          "check item data
          WHEN /scmtms/if_trq_c=>sc_node-item.

            /scmtms/cl_cond_ol=>extract_dc_data_for_do_result(
              EXPORTING
                it_boinst_key          = it_boinst_key
                is_do_bo_link          = <fs_do_bo>
                it_result              = lo_trq_data->mt_d_trq_item
                it_kl_entry_target     = CORRESPONDING #( lo_trq_data->mt_d_trq_item MAPPING source_key = key target_key = key )
                it_cond_root           = it_cond_root
              CHANGING
                ct_bokey_dokey_data    = et_bokey_dokey_data ).

          "check stage data
          /scmtms/cl_cond_ol=>extract_dc_data_for_do_result(
           EXPORTING
             it_boinst_key          = it_boinst_key
             is_do_bo_link          = <fs_do_bo>
             it_result              = lo_trq_data->mt_root_item_stages
             it_kl_entry_target     = CORRESPONDING #( lo_trq_data->mt_root_item_stages MAPPING source_key = item_key target_key =  root_key )
             it_cond_root           = it_cond_root
           CHANGING
             ct_bokey_dokey_data    = et_bokey_dokey_data ).


          WHEN OTHERS.
            ASSERT ID /scmtms/tech_cons CONDITION 1 = 0. " Only TRQ itrem and root is supported by this class
            CONTINUE.
        ENDCASE.


    ENDLOOP.
  ENDMETHOD.
<br>

Answers (4)

Answers (4)

petra_just
Active Participant

hi experts,

finally, I managed to write a class to read the unloading point from the transient trq object as follows: it works now.

Thanks for your help to both of you Rajesh and Dragos. Since I used Dragos suggestion, I am marking his answer as correct. But, we may also use Rajeshs suggestion.

METHOD /scmtms/if_cond_determ_class~extract_data_mass.

    "Petra Hunger, 10.05.2021

    "This class reads the transient TRQ context data and finds the uloiading point.
    "Then, it passes the unloading location to the target field

    DATA: lo_trq_data       TYPE REF TO /scmtms/cl_trq_data,
          lt_item_key       TYPE /bobf/t_frw_key,
          lv_item_key       TYPE /bobf/conf_key,
          is_do_bo_link     TYPE /scmtms/s_cond_do_data_k,
          lo_fdt_ref        TYPE REF TO data,
          lo_fdt_data_descr TYPE REF TO cl_abap_datadescr,
          lo_fdt_do         TYPE REF TO if_fdt_data_object,
          ls_bodo           TYPE /scmtms/s_bokey_dokey_data,
          lv_bokey          TYPE /bobf/conf_key.

    CONSTANTS: lc_own_class TYPE /scmtms/cond_det_class VALUE 'ZCL_UNLOAD_POINT'.
    CLEAR et_bokey_dokey_data.
    FIELD-SYMBOLS: <fs_res>   TYPE any,
                   <ls_key>   TYPE any,
                   <fs_bodo>  TYPE /scmtms/s_bokey_dokey_data,
                   <lv_bokey> TYPE /bobf/conf_key.

    " Check context
    IF NOT io_context IS INSTANCE OF /scmtms/cl_trq_data.
      IF io_context IS NOT BOUND.
        " Try to get TRQ container as fallback

        TRY.
            lo_trq_data = /scmtms/cl_fu_builder_helper=>get_trq_data_container( ).
          CATCH /scmtms/cx_fu_builder_fatal.
        ENDTRY.
      ELSE.
        ASSERT ID /scmtms/tech_cons CONDITION 1 = 0. 
      ENDIF.
    ELSE.
      lo_trq_data ?= io_context.
    ENDIF.

    ASSERT ID /scmtms/tech_cons CONDITION lo_trq_data IS BOUND.
    CHECK lo_trq_data IS BOUND.
    LOOP AT FILTER #( it_dobo_link USING KEY class_data WHERE class_name = lc_own_class ) ASSIGNING FIELD-SYMBOL(<fs_do_bo>).

      CASE <fs_do_bo>-node_key.

          "Item node
        WHEN /scmtms/if_trq_c=>sc_node-item.
          /scmtms/cl_cond_ol=>extract_dc_data_for_do_result(
          EXPORTING
            it_boinst_key          = it_boinst_key
            is_do_bo_link          = <fs_do_bo>
            it_result              = lo_trq_data->mt_d_trq_item
            it_kl_entry_target     = CORRESPONDING #( lo_trq_data->mt_d_trq_item MAPPING source_key = key target_key = key )

          CHANGING
            ct_bokey_dokey_data    = et_bokey_dokey_data ).

          LOOP AT it_boinst_key ASSIGNING FIELD-SYMBOL(<ls_boinst>).
            IF sy-subrc = 0.
              LOOP AT lo_trq_data->mt_d_trq_item 
              ASSIGNING FIELD-SYMBOL(<ls_trq_item>) WHERE key = <ls_boinst>-key.

                IF sy-subrc = 0.
                  DATA(lv_unload_point) = <ls_trq_item>-unload_point.
                  DATA(lv_trq_item) = <ls_trq_item>-key.
                ENDIF.
                "Fill target table
                READ TABLE it_cond_root ASSIGNING FIELD-SYMBOL(<fs_cond_root>) 
                     WITH TABLE KEY key = <fs_do_bo>-root_key.
                IF sy-subrc = 0.
                  DATA(lv_fieldname) = <fs_do_bo>-direct_access-bo_field_name.
                  CREATE DATA ls_bodo-data LIKE lv_fieldname.
                  ASSIGN ls_bodo-data->* TO <fs_res>.
                  <fs_res>             = lv_fieldname.
                  ls_bodo-bokey      = <ls_boinst>-key.
                  ls_bodo-dokey      = <fs_do_bo>-dobj_id.
                  ls_bodo-target_key = lv_trq_item.

                  INSERT ls_bodo INTO TABLE et_bokey_dokey_data.
                ENDIF.
              ENDLOOP. "loop over each item
            ENDIF.
          ENDLOOP.
        WHEN OTHERS.
          ASSERT ID /scmtms/tech_cons CONDITION 1 = 0. " Only TRQ itrem and root is supported by this class
          CONTINUE.
      ENDCASE.
    ENDLOOP.

  ENDMETHOD.
petra_just
Active Participant
0 Likes

hi again,

have tried Rajeshs idea as attached. But, again I have a problem reading the transient TRQ object. I get only keys of trq items. I need a hint please how to read the transient trq object.

class.jpg

0 Likes

hi both,

thank you for your answers. i will investigate both options and revert back as soon as possible.

thanks

Petra

0 Likes

Hi Petra ,

Condition-based incompatibilities are not always suitable.That is why SAP provided possibility of defining incompatibility through external strategy .For example , If you define incompatibilities with conditions and a freight unit has several products, the system only determines the first product, and it does this randomly. You can avoid this restriction by using example strategy TM_INCOMP.

Please check assigned class /SCMTMS/CL_INCOMP_STR_PROD_DEM for reference code .