01-02-2012 12:30 PM
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
01-02-2012 4:19 PM
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
01-02-2012 5:19 PM
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
01-03-2012 1:35 AM
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...
01-03-2012 10:09 AM
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.
01-03-2012 4:49 AM
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
01-03-2012 9:36 AM
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.
01-03-2012 10:48 AM
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( ).
01-03-2012 12:17 PM
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
01-03-2012 1:06 PM
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.
01-03-2012 1:54 PM
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
09-19-2014 7:53 PM
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
10-06-2016 8:40 PM