Preisfindung im Kundenauftrag von außen anstossen

In diesem Beitrag zeige ich dir, wie du die Preisfindung eines Kundenauftrags neu ausführen lassen kannst. Das grundsätzliche Verfahren sieht so aus:

  1. Userexit in SAPMV45A anpassen
  2. Parameter setzen
  3. BAPI aufrufen
  4. Parameter zurücknehmen

Um die Preisfindung von außen triggern zu können, musst du Änderungen im Programm SAPMV45A durchführen. Zuerst benötigst du jedoch die Möglichkeit, einen Parameter zur Laufzeit zu setzen, der dann im SAPMV45A abgefragt werden kann. Das kann gut über eine der beiden Methoden erfolgen:

  1. EXPORT TO MEMORY und IMPORT FROM MEMORY
  2. Öffentliches Attribut der eigenen globalen Klasse

Anlage der globalen Klasse

Als erstes musst du eine Klasse anlegen mit der die neue Preisfindung durchgeführt werden soll. In meinem Beispiel heißt sie ZCL_SD_NP (New Pricing).

Lege das öffentliche Klassenattribut KNPRS vom Typ KNPRS an (static). Das ist die Preisfindungsart, mit der die Art der neuen Preisfindung gesteuert werden kann.

Quelltext (relevanter Teil ) in MV45AFZB:

FORM userexit_new_pricing_vbap CHANGING new_pricing.
  IF zcl_sd_np=>knprs IS NOT INITIAL.  
     new_pricing = zcl_sd_np=>knprs.
   ENDIF.
ENDFORM.                    "USEREXIT_NEW_PRICING_VBAP
FORM userexit_new_pricing_vbkd CHANGING new_pricing.
  IF zcl_sd_np=>knprs IS NOT INITIAL. 
     new_pricing = zcl_sd_np=>knprs.
   ENDIF.
ENDFORM.                    "USEREXIT_NEW_PRICING_VBKD

Quelltext Klasse

Nun brauchen wir noch die Methode TRIGGER_NEW_PRICING

DATA: 
  ls_bapisdh1x  TYPE bapisdh1x,
  lt_pos        TYPE STANDARD TABLE OF bapisditm WITH NON-UNIQUE DEFAULT KEY,
  lt_posx       TYPE STANDARD TABLE OF bapisditmx WITH NON-UNIQUE DEFAULT KEY,
  lt_return     TYPE bapiret2_t.
FIELD-SYMBOLS: 
  <ls_pos>      LIKE LINE OF lt_pos,
  <ls_posx>     LIKE LINE OF lt_posx.


CLEAR ct_bapiret2.
knprs = iv_knprs.
*--------------------------------------------------------------------*
* Get all positions to be redermined
*--------------------------------------------------------------------*
SELECT posnr AS itm_number werks AS plant
INTO CORRESPONDING FIELDS OF TABLE lt_pos
FROM vbap
WHERE vbeln = iv_vbeln_va.

LOOP AT lt_pos ASSIGNING <ls_pos>.
APPEND INITIAL LINE TO lt_posx ASSIGNING <ls_posx>.
<ls_posx>-itm_number = <ls_pos>-itm_number.
<ls_posx>-updateflag = 'U'.
ENDLOOP.

ls_bapisdh1x-updateflag = 'U'.
CALL FUNCTION 'BAPI_SALESORDER_CHANGE'
  EXPORTING
    salesdocument    = iv_vbeln_va
    order_header_inx = ls_bapisdh1x
  TABLES
    return           = ct_bapiret2
    order_item_in    = lt_pos
    order_item_inx   = lt_posx
  EXCEPTIONS
    ERROR_MESSAGE = 1.

CLEAR knprs.  " Only once

TRY.
    DATA(ls_return) = ct_bapiret2[ type = 'E' ].
    CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
    RAISE EXCEPTION TYPE zcx_my_exception.
  CATCH CX_SY_ITAB_LINE_NOT_FOUND.
    CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'.
ENDTRY.

Durch Aufruf der Methode ZCL_SD_NP=>TRIGGER_NEW_PRICING( … ) kannst du nun einen Beleg dazu bewegen, eine neue Preisfindung durchzuführen.

Enno Wulff