Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Badi ME_PROCESS_PO_CUST - Getting country of item delivery address

Former Member
0 Kudos

Hi all,

I'm just testing the Badi ME_PROCESS_PO_CUST and I've got a problem. I want to check the countries of all delivery addresses on item level, but I don't know how to get the country on item level.

I implemented method CHECK so far and in this method I'm using GET_ITEMS & GET_DATA to read the item data. But in structure MEPOITEM I don't find a field for the country of the delivery address. I also tried to get the country from table ADRC using the value of field ADRNR of MEPOITEM structure. This works until a user changes one country on item level manually. Then I'm getting the wrong country because the address number (ADRNR) doesn't change until saving the purchase order.

Somebody got a solution for this issue?

Thanks

Daniel

12 REPLIES 12

eduardo_hinojosa
Active Contributor
0 Kudos

Hi

In interface IF_PURCHASE_ORDER_ITEM_MM you also have these options:

GET_FOREIGN_TRADE

GET_SHIPPING_DATA

Try with them. About the second I have doubts, but surely the first will help you

Regards

Eduardo

0 Kudos

Hi Eduardo,

the two methods GET_FOREIGN_TRADE & GET_SHIPPING_DATA don't help. I've already checked them, but none of them gives me the country of the delivery address.

Any other ideas?

Daniel

0 Kudos

If you cant find, then you can try like this to find out in Process~item method itself,

But sure there might be other way to get the country also,..

just try this..

DATA lv_addr_ptr(30) VALUE '(SAPLMEGUI)ADDR1_DATA'.
FIELD-SYMBOLS: <e_addr> TYPE ADDR1_DATA.
  ASSIGN (lv_addr_ptr) TO <e_addr>.
<e_addr>-country = .... "<-You will get country here...

0 Kudos

Just tried the suggestion of playsuji and it doesn't work (I get an short dump "You attempted to access an unassigned field symbol"). If it doesn't work with that BadI, does someone know an user exit to do this.

Former Member
0 Kudos

The country of item delivery address can be obtained through ADRNR (or ADRN2 if ADRNR is empty) on PO item.

You already got ADRNR / ADRN2 when you called IF_PURCHASE_ORDER_ITEM_MM~GET_DATA method which returns structure of TYPE MEPOITEM. Here you can find MEPOITEM-ADRNR / ADRN2

You can read the the country (ADRC-LAND1) of delivery address from ADRC using ADRNR (if ADRNR is empty use ADRN2) where ADRC-ADDRNUMBER = ADRNR

The delivery address typically comes from the address of receiving plant EKPO-WERKS but it could be manually changed in the PO item. In any case the current item level delivery address as on the PO in ME22N can be read from ADRC by using ADRNR / ADRN2

0 Kudos

Reading the address from ADRC doesn't work, because if you change the country of one item manually the address number will be changed on saving the purchase order only. I need to check the address before saving the purchase order.

I'll try the method, which playsuji mentioned. Although I'm not clear about how to make the check for all items, not only for one. My requirement is that all items should have HU as country of delivery address, if one item has HU as country of the delivery address.

0 Kudos

Yes, I saw that after I already posted my response.

I spent more than 3 hours working on this today and we have some good news!

I tested the below code in CHECK method in my sandbox system and I was able to read the latest address directly from ME21N / ME22N screens as modified by the user before the PO is saved to database.

In the below code ls_address-data-country will contain latest country code as input by user before PO is saved.

METHOD if_ex_me_process_po_cust~check.

  DATA: lt_items                  TYPE purchase_order_items,
        ls_item                   TYPE purchase_order_item,
        ls_item_data              TYPE mepoitem,
        lt_item_data_tab          TYPE TABLE OF mepoitem,
        ls_comm_delivery_address  TYPE cmmda,
        ls_address_complete       TYPE szadr_addr1_complete,
        ls_address                TYPE LINE OF szadr_addr1_complete-addr1_tab.


  REFRESH: lt_item_data_tab.
  " Get the list of PO items
  lt_items  = im_header->get_items( ).

  LOOP AT lt_items INTO ls_item.

    "   Read each PO item data
    ls_item_data = ls_item-item->get_data( ).

* Check if PO item is not deleted
    CHECK ls_item_data-loekz IS INITIAL.

    "   Read address handle of current item from memory
    CLEAR: ls_comm_delivery_address.
    CALL FUNCTION 'MM_DELIVERY_ADDRESS_READ'
      EXPORTING
        im_ebeln                = ls_item_data-ebeln
        im_ebelp                = ls_item_data-ebelp
      IMPORTING
*       EX_ADDRESS_EXISTS       =
        ex_cmmda                = ls_comm_delivery_address
*       EX_ERROR_TAB            =
              .

    "   Read delivery address of current item from memory
    CLEAR: ls_address_complete.
    REFRESH: ls_address_complete-addr1_tab.
    CALL FUNCTION 'ADDR_GET_COMPLETE'
      EXPORTING
*       ADDRNUMBER                    =
        addrhandle                    = ls_comm_delivery_address-addr_handle
*       ARCHIVE_HANDLE                =
*       IV_CURRENT_COMM_DATA          = 'X'
      IMPORTING
        addr1_complete                = ls_address_complete
      EXCEPTIONS
        parameter_error               = 1
        address_not_exist             = 2
        internal_error                = 3
        wrong_access_to_archive       = 4
        OTHERS                        = 5.
    IF sy-subrc NE 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
    ENDIF.

    READ TABLE ls_address_complete-addr1_tab INTO ls_address INDEX 1.
  "   ls_address-data-country contains latest country code as input by user
  ENDLOOP.

ENDMETHOD.

To use above coding in PROCESS_ITEM method you can remove the LOOP and put

ls_item_data = im_item->get_data( ).

in place of

  REFRESH: lt_item_data_tab.
  " Get the PO items
  lt_items  = im_header->get_items( ).

  LOOP AT lt_items INTO ls_item.

    ls_item_data = ls_item-item->get_data( ).

0 Kudos

Hello Vishnu,

first, thank you for your suggestion. I implemented the code in the CHECK method, but it doesn't work for me. In my case the field ls_comm_delivery_address-addr_handle is always blank and so the function module ADDR_GET_COMPLETE returns sy-subrc 1.

I debugged it and the other fields of the structure ls_comm_delivery_address (for example EBELN & EBELP) are filled!?

Just tried to export the ADDRNUMBER in the ADDR_GET_COMPLETE function module also and then it seems to work:

CALL FUNCTION 'ADDR_GET_COMPLETE'
      EXPORTING
        ADDRNUMBER                    = ls_comm_delivery_address-adrnr
        addrhandle                    = ls_comm_delivery_address-addr_handle
*       ARCHIVE_HANDLE                =
*       IV_CURRENT_COMM_DATA          = 'X'
      IMPORTING
        addr1_complete                = ls_address_complete
      EXCEPTIONS
        parameter_error               = 1
        address_not_exist             = 2
        internal_error                = 3
        wrong_access_to_archive       = 4
        OTHERS                        = 5.

Edited by: Daniel Brack on Jan 3, 2012 1:29 PM

0 Kudos

Yes, you are right both ls_comm_delivery_address-adrnr and ls_comm_delivery_address-addr_handle should be passed to ADDR_GET_COMPLETE. There is a logic inside that function to read using any of these keys. But it always reads the latest changes.

I guess ADRNR will be filled when existing address number will be updated with the new address in ADRC table and ADDR_HANDLE will be filled when a new address record will be inserted with new address number. In any case the above code works and I tested both cases where only address handle is filled and only address number is filled.

0 Kudos

I just wondered, if I've to consider something with the field ADRN2 in the structure ls_comm_delivery_address?

But anyway, thanks a lot Vishnu. Don't know, if I would have managed this w/o your help.

One thing, if anybody else wants to use this solution. You've to insert a

type-pools: szadr.

at the top of the coding.

Edit: Just created a new purchase order, changed the country of one item manually and it doesn't seem to work. Problem is, that in structure ls_comm_delivery_address the fields ADRNR & ADDR_HANDLE are blank. Only the field ADDRNUMBER has a value!?

Edited by: Daniel Brack on Jan 3, 2012 5:31 PM

0 Kudos

Thanks Vishnu, this code was a lifesaver!!

I used to check the street and the city and when was not completed just send an error messsage and use   im_item->INVALIDATE( ). to prevent the posting

Best Regards

Martin

Former Member
0 Kudos

Thank you so much Vishnu! Saved my life!


Best Regards,

Marco