Hallo zusammen,
wir haben jetzt eine Lösung, die bei uns auch scheinbar funktioniert:
Im Exit MV50AFZ1:
If sy-UCOMM = 'WABU'
OR sy-UCOMM = 'WABU_T'.
If likp-expkz = 'X'.
CALL FUNCTION 'Z_FAKTURA_ANLEGEN'
STARTING NEW TASK 'Z_FAKT_ANL'
EXPORTING
I_VBELN = likp-vbeln
I_MJAHR = emkpf-mjahr
I_MBLNR = emkpf-mblnr.
Endif.
Endif.
Funktionbaustein "Z_FAKTURA_ANLEGEN":
FUNCTION Z_FAKTURA_ANLEGEN.
*"----------------------------------------------------------------------
*"*"Lokale Schnittstelle:
*" IMPORTING
*" VALUE(I_VBELN) LIKE LIKP-VBELN
*" VALUE(I_FKART) TYPE FKART DEFAULT 'ZF8D'
*" VALUE(I_MJAHR) TYPE MKPF-MJAHR OPTIONAL
*" VALUE(I_MBLNR) TYPE MKPF-MBLNR OPTIONAL
*" EXPORTING
*" VALUE(E_VBELN) TYPE VBELN_VF
*"----------------------------------------------------------------------
* VERWENDUNG von FuBa:
* FuBa wird im UserExit Form userexit_save_document(MV50AFZ1)
* aufgerufen. (Transaktion VL02N)
*
* FUNKTIONALITÄT:
* 1.) Die Verbuchung wird abgewartet
* 2.) Nach der Verbuchung wird die Faktura angelegt (V01)
*__________________________________________________
data: l_mode type char1 value 'N',
l_subrc like sy-subrc,
l_errmail type flag.
field-symbols: <fs_msg> TYPE BDCMSGCOLL.
*__________________________________________________
refresh: gt_msg, gt_mail.
*** (Zuerst die Verbuchung abwarten, und dann die Tabelle KNA1 prüfen)
PERFORM wait_for_update_of_bel1
USING i_vbeln i_mblnr i_mjahr
CHANGING l_subrc.
if l_subrc ne 0.
* raise NOCH_NICHT_VERBUCHT. "---Verbuchung noch nicht fertig
message e398(00) with 'Verbuchung wurde nicht beendet.'(010)
into gs_mail.
append gs_mail to gt_mail.
endif.
if l_subrc is initial.
perform faktura_anlegen_fubas using i_fkart
changing i_vbeln gt_mail[] l_errmail
e_VBELN.
endif.
if not l_errmail is initial.
perform sendmail_fehlerlist using i_vbeln i_fkart
gt_mail[].
endif.
ENDFUNCTION.
Form "WAIT_FOR_UPDATE_OF_BEL1":
*&---------------------------------------------------------------------
*& Form WAIT_FOR_UPDATE_OF_BEL1
*&---------------------------------------------------------------------
FORM wait_for_update_of_bel1 USING p_vbeln TYPE likp-vbeln
p_mblnr TYPE mkpf-mblnr
p_mjahr TYPE mkpf-mjahr
* p_wait_up_to_seconds TYPE i
CHANGING p_subrc TYPE sy-subrc.
DATA: l_garg TYPE seqg3-garg,
lt_enq TYPE STANDARD TABLE OF seqg3,
l_start_time TYPE sy-uzeit,
l_runtime TYPE i,
p_wait_up_to_seconds TYPE i value 15,
l_subrc TYPE sy-subrc.
*______________________________________________________________________
* Zuerst die Verbuchung abwarten, und dann die Tabelle KNA1 prüfen
* Verbuchung abwarten (Sperre lesen)
CONCATENATE sy-mandt p_vbeln INTO l_garg.
MOVE sy-uzeit TO l_start_time.
APPEND INITIAL LINE TO lt_enq[].
WHILE l_subrc = 0 AND NOT lt_enq[] IS INITIAL
AND l_runtime =< p_wait_up_to_seconds.
REFRESH lt_enq.
CALL FUNCTION 'ENQUEUE_READ'
EXPORTING
* GCLIENT = SY-MANDT
gname = 'LIKP'
garg = l_garg
* GUNAME = SY-UNAME
* LOCAL = ' '
IMPORTING
* NUMBER =
subrc = l_subrc
TABLES
enq = lt_enq[]
* EXCEPTIONS
* COMMUNICATION_FAILURE = 1
* SYSTEM_FAILURE = 2
* OTHERS = 3
.
IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
* WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
l_runtime = sy-uzeit - l_start_time.
ENDWHILE.
* Verbuchung prüfen: MKPF lesen, bis Beleg da ist.
MOVE sy-uzeit TO l_start_time.
SELECT SINGLE COUNT( * ) FROM mkpf WHERE mblnr = p_mblnr
AND mjahr = p_mjahr.
WHILE sy-subrc = 4 AND l_runtime =< p_wait_up_to_seconds.
WAIT UP TO 1 SECONDS.
l_runtime = sy-uzeit - l_start_time.
SELECT SINGLE COUNT( * ) FROM mkpf WHERE mblnr = p_mblnr
AND mjahr = p_mjahr.
ENDWHILE.
* Entweder alles in Ordnung oder Wartezeit ist abgelaufen.
IF lt_enq[] IS INITIAL AND sy-subrc = 0.
* Kunde Anlegen: Verbuchung richtig abgelaufen und Kundendaten sind da.
CLEAR p_subrc.
ELSEIF NOT lt_enq[] IS INITIAL AND sy-subrc = 0.
* Kunde Ändern: Verbuchung noch nicht abgelaufen,
p_subrc = 2.
ELSEIF lt_enq[] IS INITIAL AND sy-subrc <> 0.
* Verbuchung schon abgelaufen,
* aber Beleg sind noch nicht da (Verbuchung abgebrochen?).
p_subrc = 4.
ELSEIF NOT lt_enq[] IS INITIAL AND sy-subrc <> 0.
* Verbuchung noch nicht abgelaufen
* Beleg ist auch noch nicht da (Verzögerung?).
p_subrc = 8.
ENDIF.
* START TEST: Im Fehlerfall die zuständige Personen benachrichtigen
IF p_subrc <> 0.
ENDIF.
* START TEST: Im Fehlerfall die zuständige Personen benachrichtigen
ENDFORM. " WAIT_FOR_UPDATE_OF_BEL1
Form "FAKTURA_ANLEGEN_FUBAS":
*&---------------------------------------------------------------------*
*& Form FAKTURA_ANLEGEN_FUBAS
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
form faktura_anlegen_fubas using i_fkart TYPE FKART
changing i_vbeln like LIKP-VBELN
it_mail type tt_mail
i_errmail type flag
E_VBELN_vf TYPE VBELN_VF.
* Kommumikationstabelle XKOMFK
DATA: BEGIN OF XKOMFK OCCURS 0.
INCLUDE STRUCTURE KOMFK.
DATA: END OF XKOMFK.
DATA: BEGIN OF XTHEAD OCCURS 50. "aktueller Tabellenstand
INCLUDE STRUCTURE THEADVB.
DATA: END OF XTHEAD.
* Aktueller Tabellenstand VBFS
DATA: BEGIN OF XVBFS OCCURS 20.
INCLUDE STRUCTURE VBFS.
DATA: END OF XVBFS.
* Aktueller Tabellenstand VBSS
DATA: BEGIN OF XVBSS OCCURS 10.
INCLUDE STRUCTURE VBSS.
DATA: END OF XVBSS.
* Aktueller Tabellenstand
DATA: BEGIN OF XVBRK OCCURS 10.
INCLUDE STRUCTURE VBRKVB.
DATA: END OF XVBRK.
* Aktueller Tabellenstand
DATA: BEGIN OF XVBRP OCCURS 100.
INCLUDE STRUCTURE VBRPVB.
DATA: END OF XVBRP.
* Belegpartnertabelle : Aktueller Tabellenstand
DATA: BEGIN OF XVBPA OCCURS 0.
INCLUDE STRUCTURE VBPAVB.
DATA: END OF XVBPA.
DATA: BEGIN OF XKOMV OCCURS 50.
INCLUDE STRUCTURE KOMV.
DATA: END OF XKOMV.
DATA : LV_BAD_DATA LIKE RVSEL-XFELD.
*__________________________________________________
clear: vbsk.
refresh xkomfk.
RV60A-fkart = i_fkart.
vbsk-mandt = sy-mandt.
vbsk-smart = 'F'.
vbsk-ernam = sy-uname.
vbsk-erdat = sy-datum.
vbsk-uzeit = sy-uzeit.
xkomfk-mandt = sy-mandt.
xkomfk-vbeln = i_vbeln.
xkomfk-vbtyp = 'J'.
append xkomfk.
i_errmail = 'X'. "--Fehler. Gelöscht nach erfolgreichem Anlegen
*** Fakturen erzeugen
CALL FUNCTION 'RV_INVOICE_CREATE'
EXPORTING
INVOICE_TYPE = RV60A-FKART
INVOICE_DATE = RV60A-FKDAT
PRICING_DATE = RV60A-PRSDT
DELIVERY_DATE = RV60A-FBUDA
SELECT_DATE = RV60A-SELDAT
VBSK_I = VBSK
IMPORTING
VBSK_E = VBSK
OD_BAD_DATA = LV_BAD_DATA
TABLES
XKOMFK = XKOMFK
XTHEAD = XTHEAD
XVBFS = XVBFS
XVBSS = XVBSS
XVBRK = XVBRK
XVBRP = XVBRP
XVBPA = XVBPA
XKOMV = XKOMV.
* Meldungen in die Mailtabelle sammeln
loop at xvbfs.
MESSAGE ID xvbfs-msgid TYPE xvbfs-msgty
NUMBER xvbfs-msgno
WITH xvbfs-msgv1 xvbfs-msgv2 xvbfs-msgv3 xvbfs-msgv4
into gs_mail-text.
append gs_mail to it_mail.
endloop.
* Fehler beim Anlegen des Belegs? --> FehlerKz einstellen (wegen Mail)
read table xvbfs with key msgty = 'E' transporting no fields.
check not sy-subrc is initial. "Kein Fehler aufgetreten
*** Fakturabeleg hinzufügen
CALL FUNCTION 'RV_INVOICE_DOCUMENT_ADD'
EXPORTING
VBSK_I = VBSK
WITH_POSTING = 'A'
* WITHOUT_REFRESH = ' '
PREISFINDUNGSART = 'I'
* I_NO_VBLOG = ' '
* I_NO_NAST = ' '
* I_NO_FI_DOC = ' '
* I_NO_PRICING = ' '
IMPORTING
VBSK_E = VBSK
TABLES
XKOMFK = xkomfk
XKOMV = xkomv
XTHEAD = xthead
XVBFS = xvbfs
XVBPA = xvbpa
XVBRK = xvbrk
XVBRP = xvbrp
XVBSS = xvbss.
* Fehler beim Anlegen des Belegs? --> FehlerKz einstellen (wegen Mail)
* Meldungen in die Mailtabelle sammeln
if not xvbfs[] is initial.
loop at xvbfs.
"---Fakturabelegnummer übernehmen---"
if xvbfs-msgty = 'S' and xvbfs-msgid = 'VF'
and xvbfs-msgno = '311'.
move xvbfs-msgv1 to E_VBELN_vf. "---Fakturabelegnummer
clear i_errmail.
endif.
MESSAGE ID xvbfs-msgid TYPE xvbfs-msgty
NUMBER xvbfs-msgno
WITH xvbfs-msgv1 xvbfs-msgv2 xvbfs-msgv3 xvbfs-msgv4
into gs_mail-text.
append gs_mail to it_mail.
endloop.
else.
if xvbfs-msgty = 'S' and xvbfs-msgid = 'VF' and xvbfs-msgno = '311'.
clear i_errmail.
move xvbfs-msgv1 to E_VBELN_vf. "---Fakturabelegnummer
MESSAGE ID xvbfs-msgid TYPE xvbfs-msgty
NUMBER xvbfs-msgno
WITH xvbfs-msgv1 xvbfs-msgv2 xvbfs-msgv3 xvbfs-msgv4
into gs_mail-text.
append gs_mail to it_mail.
else.
"--Messageb muss nicht hingefügt werden...?
endif.
endif.
* break-point.
ENDFORM. " FAKTURA_ANLEGEN_FUBAS
Danke für Eure Hilfe !
Matthias