OAWD – Archive Link, Dateinamen protokollieren

Archive-Link, Ablage protokollieren

Intension

Für die Ablage von Rechnungsdokumenten in das elektr. Archiv, über die Transaktion OAWD, soll die Protokollierung erweitert werden. Während der Ablage geht die Verknüpfung zum Ursprungsbeleg (Datei) verloren. Um nachzuvollziehen, ob die Dateien auch tatsächlich eingelesen wurden, soll der Dateiname in Verbindung zur docID des Archivs protokolliert werden.  Der Dateiname enthält von Anfang an den gelesenen eindeutigen Barcode der Rechnung. So wird sichergestellt, dass jederzeit eine Kontrolle über abgelegte Dateien stattfinden kann.

Abgrenzung 1

Lösung 1

Barcode 3

Methode 4

Auswertung / Monitor

Tabellen und Strukturen

Benutzerparameter

Abgrenzung

Zur Transaktion existiert leider kein Userexit. Zum FuB ARCHIVELINK_FUNCTION gibt es zwar ein Exit aber leider wird dieses zum falschen Zeitpunkt angesprungen. Eine weitere Möglichkeit, eine BadI (ALINK_AUTH_CON) wird auch zu früh angesprungen und kann hier nicht verwendet werden.

Die Daten werden in zwei Tabellen gespeichert. Die hier verwendete Tabelle /PSIIC/CAPT stammt vom Hersteller der Software zur optischen Erfassung und Weiterverarbeitung der Rechnungsbelege. In anderen Systemen wird sich das unterscheiden. Eine zweite zusätzliche Tabelle ZFI_ARCHLNK_LOG wurde von mir angelegt und enthält unter anderem die Archiv-Doc-ID. Über diese Doc-Id kann ein Bezug der Tabellen zueinander hergestellt werden.

roter-pfeil

Lösung

Erweiterungsimplementierung in den Funktionsbaustein HTTP_POST_FILES_255 einbauen und eine Methode zur weiteren Verarbeitung erstellen.

Den FuB se37 anzeigen und dort auf den Button „Erweitern“ klicken.

image001

Erweiterungs-Optionen einblenden

image003_1

Den Cursor auf eine Erweiterung stellen und über das Menü Bearbeiten->Erweiterungsoptionen entweder Implementierung anlegen oder ändern.

image005_1

Hier ist ein Methodenaufruf mit zwei Übergabeparametern als Erweiterung angelegt worden. Der Parameter „ABSOLUTE_URI“ enthält hier den kompletten String, wie er an das elektr. Archiv gesendet wird.

http:///archivelink?create&pVersion=0046&contRep=ZY&docId=00155DDE32011EE395FFD3C4682EBE06&docProt=rcud&accessMode=c&authId=CN%3DDEV,OU%3DI0020078064,OU%3DSAPWebAS,O%3DSAPTrustCommunity,C%3DDE&expiration=20131128092

Aus diesem String wird, durch den Methodenaufruf, die docID extrahiert. Über die docID wird eine Verknüpfung zum Dateinamen erstellt.

Den dazu gehörenden Dateinamen finden wir in dem Übergabeparameter COMM_ERR-Name.

roter-pfeil

Barcode

Die abzulegenden Papierdokumente werden mit einem Barcodeklebeetikett versehen. Das Scannprogramm erkennt diesen Barcode als Dokumententrennung. Nach jedem erkannten Barcode wird ein neues PDF-Dokument erzeugt. Der Dateiname wird aus dem Datums- und Zeitstempel, einer laufenden Nummer und dem erkannten Barcode mit Prefix gebildet.

Beispiel: 20131217_083849_014_BAR99999998.PDF


Das Prefix (_BAR) wird in der nachfolgend beschriebenen Methode erkannt und leitet den Barcode ein. Dieser wird als Zusatzinformation, zusammen mit dem Dateinamen in der Log-Tabelle gespeichert.

roter-pfeil

Methode

Klasse: Z_ARCHIVE_LINK

Methode: ZIF_ARCHIVE_LINK~FGET

image007

Die Methode dient dazu, die Archivelink Dokument-ID aus der URL zu extrahieren und den Dateinamen festzustellen, um diese in der DB-Tabelle ZFI_ARCHLNK_LOG zu speichern.

 

* | Static Public Method Z_ARCHIVE_LINK=>ZIF_ARCHIVE_LINK~FGET
* +————————————————————————————————-+
* | [—>] ABSOLUTE_URI                   TYPE       C
* | [—>] COMPONENT_PATH                 TYPE       C
* +————————————————————————————–
METHOD ZIF_ARCHIVE_LINK~FGET.
   DATA: PATT TYPE STRING VALUE `docId=`,
         TEXT TYPE STRING,
         OFF TYPE I,
         MOFF TYPE I,
         MLEN TYPE I,
         DOCID TYPE C LENGTH 32,
         FNAME TYPE C LENGTH 50,
         LV_SMRTFX TYPE C LENGTH 1,
         LV_TEXT TYPE STRING.
   DATA: LT_WA TYPE ZFI_ARCHLNK_LOG.

   IF SY-TCODE ‚OAWD‘. „Nur bei Transaktion OAWD
     EXIT.
   ENDIF.
   OFF = 0.
   WHILE SY-SUBRC = 0.
*     Finde die Position, an der die ArchivID mitgegeben wird
     FIND PATT IN SECTION OFFSET OFF OF
           ABSOLUTE_URI
           MATCH OFFSET MOFF
           MATCH LENGTH MLEN.
     IF SY-SUBRC = 0.
       OFF = MOFF + MLEN.
     ENDIF.
   ENDWHILE.
   LT_WA-DOCID = ABSOLUTE_URI+OFF(32).

   PATT = ‚_BAR‘.                                         „Der Barcode im Dateinamen wird an diesem Prefix erkannt
   OFF = 0.

*   Benutzerparameter: Wenn dieser gestzt ist, dann findet eine Prüfung auf doppelt erfasste Dateien statt
   GET PARAMETER ID ‚ZSMARTFIX_ABLAGE‘ FIELD LV_SMRTFX.

IF SY-TCODE = ‚OAWD‘. „der SY-SUBRC wird wieder zurückgesetzt
   ENDIF.
   WHILE SY-SUBRC = 0.
*     Finde die Position, an der der Barcode im Dateinamen steckt
     FIND PATT IN SECTION OFFSET OFF OF
           COMPONENT_PATH
           MATCH OFFSET MOFF
         MATCH LENGTH MLEN.
     IF SY-SUBRC = 0.
       OFF = MOFF + MLEN.
     ENDIF.
   ENDWHILE.

   LT_WA-FNAME = COMPONENT_PATH.

   IF LV_SMRTFX = ‚X‘.
     IF OFF GT 4.
       LT_WA-BARCODE = COMPONENT_PATH+OFF(8).                                           „Barcode gefunden?
       SELECT COUNT(*) FROM ZFI_ARCHLNK_LOG
         WHERE BARCODE = LT_WA-BARCODE.
     ELSE.                                                   „kein Barcode im Dateinamen, dann prüfe nur Dateiname
       SELECT COUNT(*) FROM ZFI_ARCHLNK_LOG
     WHERE FNAME EQ COMPONENT_PATH.
     ENDIF.

     IF SY-SUBRC = 0.
       CONCATENATE ‚Die Datei:‘ COMPONENT_PATH ‚wurde bereits eingelesen‘ INTO LV_TEXT SEPARATED BY ‚ ‚.
       MESSAGE LV_TEXT TYPE ‚I‘.
     ENDIF.
   ENDIF.

   INSERT ZFI_ARCHLNK_LOG FROM LT_WA.
* ein Commit der DB erfolgt später im Hauptprogramm sowieso!
ENDMETHOD.                   „ZIF_ARCHIVE_LINK~FGET

roter-pfeil

Auswertereport

Das Ergebnis wird als ALV-Grid dargestellt. Hier mal ein Beispiel:


Beispiel_01

In diesem Beispiel hier werden die beiden Tabellen ZFI_ARCHLNK_LOG und /PSIIC/CAPT über einen Join ausgelesen.

Das Coding zum Report:

*&———————————————————————*
*& Report ZFI_MOMI_VERIFIER
*&
*&———————————————————————*
*&
*&
*&———————————————————————*

REPORT ZFI_MOMI_VERIFIER.

TABLES:     /PSIIC/CAPT, ZFI_ARCHLNK_LOG, ZPSIICCAPT, USR02.

*DATA:       ZPSIICCAPT LIKE TABLE OF /PSIIC/CAPT WITH HEADER LINE.
DATA: BEGIN OF LT_ZPSIICCAPT OCCURS 0.
       INCLUDE STRUCTURE ZPSIICCAPT.
DATA: END OF LT_ZPSIICCAPT.

DATA: BEGIN OF LT_ZPSIICCAPT_D OCCURS 0.
       INCLUDE STRUCTURE ZPSIICCAPT.
DATA: END OF LT_ZPSIICCAPT_D.

TYPE-POOLS: SLIS.
DATA:       G_REPID             LIKE   SY-REPID.
DATA:      GS_LAYOUT            TYPE   SLIS_LAYOUT_ALV,
           WA_AKTUELLE_ZEILE   LIKE LINE OF LT_ZPSIICCAPT,
           LT_RETURN           TYPE   SY-SUBRC,
           LINE               TYPE I,
           LT_TMP             LIKE LT_ZPSIICCAPT,
           INDEX               TYPE SYINDEX
.
TYPES: BEGIN OF TY_DATA.
       INCLUDE STRUCTURE ZPSIICCAPT.
TYPES: END OF TY_DATA.

FIELD-SYMBOLS TYPE TY_DATA.

DATA: SELTAB   TYPE RANGE OF I,
         SELECTION LIKE LINE OF SELTAB,
         INT       TYPE I,
         RSPAR     TYPE TABLE OF RSPARAMS,
         WA_RSPAR LIKE LINE OF RSPAR.

SELECTIONSCREEN: BEGIN OF BLOCK EIN WITH FRAME TITLE TEXT-EIN.
SELECT-OPTIONS P_BLNUM FOR /PSIIC/CAPT-BLNUM.
SELECT-OPTIONS DATUM FOR /PSIIC/CAPT-ERDAT.
SELECT-OPTIONS NAME FOR USR02-BNAME.
PARAMETERS: P_DUB TYPE ZFI_DUB.
SELECTIONSCREEN: END OF BLOCK EIN.
SELECTIONSCREEN: BEGIN OF BLOCK ZWE WITH FRAME TITLE TEXT-ZWE.
SELECT-OPTIONS STATUS FOR /PSIIC/CAPT-PSTAT.
SELECT-OPTIONS OBJECT   FOR /PSIIC/CAPT-INP_OBJTYPE DEFAULT ‚/PSIIC/CAPT‘.
SELECTIONSCREEN: END OF BLOCK ZWE.
SELECTIONSCREEN: BEGIN OF BLOCK DRE WITH FRAME TITLE TEXT-DRE.
SELECT-OPTIONS P_FNAME   FOR ZFI_ARCHLNK_LOG-FNAME.
SELECTIONSCREEN: END OF BLOCK DRE.

CLEAR LT_ZPSIICCAPT[].
* Nach einzelner Rechnung (Dateiname/Barcode) suchen
IF NOT P_FNAME IS INITIAL.
SELECT *   INTO CORRESPONDING FIELDS OF TABLE LT_ZPSIICCAPT
   FROM ZFI_ARCHLNK_LOG AS ARC LEFT JOIN /PSIIC/CAPT AS CAPT
   ON ARC~DOCID = CAPT~ORG_ARC_DOC_ID
   WHERE FNAME IN P_FNAME.
APPEND LT_ZPSIICCAPT.
ELSEIF NOT P_DUB IS INITIAL.

PERFORM DUPLIKATE.

ELSE.

SELECT *   INTO CORRESPONDING FIELDS OF TABLE LT_ZPSIICCAPT
   FROM /PSIIC/CAPT AS CAPT LEFT JOIN ZFI_ARCHLNK_LOG AS ARC
   ON CAPT~ORG_ARC_DOC_ID = ARC~DOCID
   WHERE
   PSTAT IN STATUS AND
   ERNAM IN NAME AND
   ERDAT IN DATUM AND
   BLNUM IN P_BLNUM.
APPEND LT_ZPSIICCAPT.
ENDIF.

*———————————————————————–
* Beginn ALV-Ausgabe
* Layout bestimmen.
PERFORM LAYOUT_ALLG_BUILD USING GS_LAYOUT.

* Daten als ALV-Liste anzeigen.
PERFORM ALV_ANZEIGEN.

*———————————————————————–
* Ende ALV-Ausgabe
* Jetzt kann END-OF-SELECTION folgen
*———————————————————————–

*———————————————————————–
* Unterprogramm fuer Ausgabe der ALV-Liste
*———————————————————————–
FORM ALV_ANZEIGEN.

G_REPID = SY-REPID.

CALL FUNCTION ‚REUSE_ALV_GRID_DISPLAY‘
   EXPORTING
     I_CALLBACK_PROGRAM     = G_REPID
     I_CALLBACK_USER_COMMAND = ‚REAKTION_AUF_DOPPELKLICK‘
     I_GRID_TITLE           = ‚in Erkennung‘
     I_SAVE                 = ‚A‘
     I_STRUCTURE_NAME       = ‚ZPSIICCAPT‘
     IS_LAYOUT               = GS_LAYOUT
   TABLES
     T_OUTTAB               = LT_ZPSIICCAPT.
IF SY-SUBRC 0.
   „Hier koennen Sie auf Fehler beim ALV-Aufruf reagieren“

ENDIF.
ENDFORM. „alv_anzeigen.

*———————————————————————
* Unterprogramm fuer Layoutangaben
*———————————————————————

FORM LAYOUT_ALLG_BUILD USING LS_LAYOUT TYPE SLIS_LAYOUT_ALV.
LS_LAYOUT-ZEBRA = ‚X‘.
LS_LAYOUT-COLWIDTH_OPTIMIZE = ‚X‘.
ENDFORM. „layout_allg_build.

*&———————————————————————*
*&     Form REAKTION_AUF_DOPPELKLICK
*&———————————————————————*
*       text
*———————————————————————-*
*     –>I_UCOMM   text
*     –>I_SELFIELD text
*———————————————————————-*
FORM REAKTION_AUF_DOPPELKLICK USING I_UCOMM
   I_SELFIELD TYPE SLIS_SELFIELD.

CASE I_UCOMM.
   WHEN ‚&IC1‘. „bei Doppelklick
     READ TABLE LT_ZPSIICCAPT INTO WA_AKTUELLE_ZEILE
       INDEX I_SELFIELD-TABINDEX.
*     Klick auf die Dokument-ID
     IF I_SELFIELD-FIELDNAME = ‚WI_ID‘.
       CLEAR LT_RETURN.
       CALL FUNCTION ‚SAP_WAPI_DIALOG_PROTOCOL‘
       EXPORTING
         WORKITEM_ID         = WA_AKTUELLE_ZEILE-WI_ID
       IMPORTING
         RETURN_CODE         = LT_RETURN
*       TABLES
*         MESSAGE_LINES       =
*         MESSAGE_STRUCT       =
               .
       IF NOT LT_RETURN IS INITIAL.
         MESSAGE ‚Zu diesem Workflow kein Protokoll gefunden.‘ TYPE ‚I‘.
       ENDIF.
     ELSE.
       PERFORM FILL_SELECT.
       SUBMIT OAFIND_2 USING SELECTION-SCREEN ‚1000‘
       WITH SELECTION-TABLE RSPAR
               AND RETURN.
     ENDIF.
     .
*     Hier koennen Sie auf den Doppelklick reagieren.
*     wa_aktuelle_zeile enthaelt die Zeile,
*     die doppelgeklickt wurde.
*     I_SELFIELD-FIELDNAME enthaelt den Namen
*     des angeklickten Felds in der internen Tabelle.
ENDCASE.
ENDFORM. „REAKTION_AUF_DOPPELKLICK

*&———————————————————————*
*&     Form Fill_Select
*&———————————————————————*
*       text
*———————————————————————-*
* –> p1       text
*
*———————————————————————-*
FORM FILL_SELECT .

CLEAR RSPAR[].
WA_RSPAR-SELNAME = ‚OBJECT‘.
WA_RSPAR-KIND = ‚S‘.
WA_RSPARSIGN = ‚I‘.
WA_RSPAR-OPTION = .
WA_RSPAR-LOW = OBJECT-LOW.
WA_RSPAR-HIGH = .
APPEND WA_RSPAR TO RSPAR.

WA_RSPAR-SELNAME = ‚OBJECTID‘.
WA_RSPAR-KIND = ‚S‘.
WA_RSPARSIGN = ‚I‘.
WA_RSPAR-OPTION = .
WA_RSPAR-LOW = ‚*‘ .
WA_RSPAR-HIGH = .
APPEND WA_RSPAR TO RSPAR.

WA_RSPAR-SELNAME = ‚ARCHIVE‘.
WA_RSPAR-KIND = ‚S‘.
WA_RSPARSIGN = ‚I‘.
WA_RSPAR-OPTION = .
WA_RSPAR-LOW = ‚ZY‘ .
WA_RSPAR-HIGH = .
APPEND WA_RSPAR TO RSPAR.

WA_RSPAR-SELNAME = ‚ARCDOCID‘.
WA_RSPAR-KIND = ‚S‘.
WA_RSPARSIGN = ‚I‘.
WA_RSPAR-OPTION = .
WA_RSPAR-LOW = WA_AKTUELLE_ZEILE-ORG_ARC_DOC_ID.
WA_RSPAR-HIGH = .
APPEND WA_RSPAR TO RSPAR.
ENDFORM.                   “ Fill_Select


*&———————————————————————*
*&     Form duplikate
*&———————————————————————*
*       text
*———————————————————————-*
* –> p1       text
*
*———————————————————————-*
FORM DUPLIKATE .
SELECT * INTO CORRESPONDING FIELDS OF TABLE LT_ZPSIICCAPT_D
     FROM /PSIIC/CAPT AS CAPT LEFT JOIN ZFI_ARCHLNK_LOG AS ARC
     ON CAPT~ORG_ARC_DOC_ID = ARC~DOCID
     WHERE
     PSTAT IN STATUS AND
     ERNAM IN NAME AND
     ERDAT IN DATUM AND
     BLNUM IN P_BLNUM.
APPEND LT_ZPSIICCAPT_D.

SORT LT_ZPSIICCAPT_D BY FNAME.
CLEAR LINE.

LOOP AT LT_ZPSIICCAPT_D.
*   lese schon den nächsten Datensatz in den Speicher
   INDEX = SY-TABIX + 1.
   READ TABLE LT_ZPSIICCAPT_D INDEX INDEX INTO LT_TMP TRANSPORTING ALL FIELDS
   .
*   Vergleiche mit dem aktuellen Datensatz
   IF LT_ZPSIICCAPT_D-FNAME = LT_TMP-FNAME.
*     aktuellen und nächsten Datensatz in die Ausgabetabelle schreiben
     APPEND LT_ZPSIICCAPT_D TO LT_ZPSIICCAPT.
     APPEND LT_TMP TO LT_ZPSIICCAPT.
    CLEAR LT_TMP.
   ENDIF.
ENDLOOP.

DELETE ADJACENT DUPLICATES FROM LT_ZPSIICCAPT.

ENDFORM.                   “ duplikate

roter-pfeil

Tabellendefinition

Tabelle ZFI_ARCHLNK_LOG anlegen: In dieser Tabelle wird der Dateiname und der Barcode abgelegt.


Tab_01



Struktur ZPSIICCAPT anlegen: Die Struktur wird für die Ausgabe und Anzeige benötigt.

Tab_02


Dazu wird In der se11 eine Struktur angelegt und zwei Tabellen inkludiert.


Tab_03 Tab_04

Tab_05

roter-pfeil

Benutzerparameter

Die Methode prüft auch, ob die gleiche Datei bereits abgelegt wurde und gibt eine Warnmeldung aus. Damit dies steuerbar ist, wurde ein Benutzerparameter angelegt. Der Parameter ZSMARTFIX_ABLAGE hat einen Wert „X“ oder ist initial.

Benutzerparameter


Einen Benutzerparameter kann man mit der TA se80 -> Objekt bearbeiten erzeugen.

SET/GET-Parameter-ID


roter-pfeil


Schreibe einen Kommentar