Quick Guide to Parking and Posting of Incoming FI Invoices
This quick guide provides an overview of the basic procedure for parking and posting of incoming invoices as it can be a very complex process from a technical standpoint. A consultation contingent is available on request for OPTIMAL SYSTEMS for advice on the specific application and questions regarding the transfer of further posting information.
The SAP® module BAPI_ACC_DOCUMENT_POST can be used to post or park incoming FI invoices. After successful execution, this module also requires the call of BAPI_TRANSACTION_COMMIT in order to transfer the data to the posting. The commit module must be called up in the same process as the posting module. This can lead to problems in some environments or distribution scenarios as it is not possible to assign the HTTP calls to a dedicated process. In this case, the module /OSGMBH/D2S_DOCUMENT_POST can be used as an alternative. This is a wrapper around the two BAPIs mentioned above. The interface is almost identical to that of BAPI_ACC_DOCUMENT_POST. Only one additional return parameter 'RC' is added, which indicates the success or failure of the posting with the values '0' or '8'.
All entries for BAPI_ACC_DOCUMENT_POST shown below are therefore also valid for /OSGMBH/D2S_DOCUMENT_POST.
The SOAP services must be generated in the same way as described above, regardless of which modules are used. A SOAP service already exists for /OSGMBH/D2S_DOCUMENT_POST, which means that only the endpoint must be generated in the SOA Manager.
Version Dependency and Parking
The abovementioned BAPI was originally only intended for the final posting of invoices. Its functionality was later expanded to also enable parking. The extended functionality can also be retrofitted in older SAP® systems. See OSS note 2092366 for more information.
A simple way to check the existence of the functionality for parking is the existence of the DOC_STATUS field in the DOCUMENTHEADER input parameter. If available, the specific function of the BAPI is controlled via entries in this parameter.
If the DOC_STATUS parameter is not assigned a value, a real posting is made. This ensures compatibility with older applications. The new functionalities are triggered by the following values in the DOC_STATUS field:
Value for DOC_STATUS | Function |
---|---|
2 | Parked receipt |
3 | Fully saved receipt |
4 or empty | Posted receipt |
A | Parked receipt (only amounts in the currency of the transaction are transferred when posting) |
B | Fully saved receipt (only amounts in the currency of the transaction are transferred when posting) |
Calling the BAPI
The SAP®-side interface can be viewed in SAP® via transaction SE37. A header line and 1-n posting items must be transferred to park or post an invoice.
It is necessary to split the data into a total of four different transfer tables when transferring the item data. The following data must be generated from an invoice item:
- a vendor line in the ACCOUNTPAYABLE table parameter
- a G/L account line in the ACCOUNTGL table parameter
- a tax line in the ACCOUNTTAX table parameter
- three amount lines in the CURRENCYAMOUNT table parameter, which must be clearly assigned to the preceding entries.
The entries in the CURRENCYAMOUNT are assigned to the entries in the other tables via the ITEMNO_ACC field, which is contained in all tables. The value of this field is continuously incremented in CURRENCYAMOUNT and then used as a foreign key in the other three tables.
Example of a call in VBA syntax:
'Zunächst wird die Header-Zeile gefüllt:
DIM Param
' Kopfdaten füllen
SET HeaderData = CreateObject("Scripting.Dictionary")
Param = CreateObject("Scripting.Dictionary")
HeaderData("USERNAME") = "USER" 'Benutzer ist Pflichtfeld
HeaderData("HEADER_TXT") = "Kopftext" 'BKTXT
HeaderData("COMP_CODE") = "1000" 'Buchungskreis
HeaderData("DOC_DATE") = "13.04.2018" 'Belegdatum
HeaderData("PSTNG_DATE") = "13.04.2018" 'Buchungsdatum
HeaderData("DOC_TYPE") = "KR" 'Belegart
HeaderData("REF_DOC_NO") = "REF123" 'Referenz / Re.nr. des Lieferanten
' Kopfdaten zu Parameterobjekt hinzufügen
Param.Add "DOCUMENTHEADER",HeaderData
'Danach werden die Beträge für den Parameter CURRENCYAMOUNT erfasst. Die Begründung für die unterschiedlichen Werte erfolgt später.
DIM AmountData(2) 'beginnend mit 0
'Position 1 füllen
SET Entry = CreateObject("Scripting.Dictionary")
Entry("ITEMNO_ACC") = "0000000001"
Entry("CURR_TYPE") = "00"
Entry("CURRENCY") = "EUR"
Entry("AMT_DOCCUR") = "-119,00" 'Bruttobetrag
Entry("TAX_AMT") = "-19,00" 'Steuerbetrag
Entry("EXCH_RATE") = "1,00" 'Umrechnungskurs (kann auch leer bleiben)
'Position in Array anhängen
SET AmountData(0) = Entry
'Position 2 füllen
SET Entry = CreateObject("Scripting.Dictionary")
Entry("ITEMNO_ACC") = "0000000002"
Entry("CURR_TYPE") = "00"
Entry("CURRENCY") = "EUR"
Entry("AMT_DOCCUR") = "100,00" 'Nettobetrag
Entry("TAX_AMT") = "0,00"
Entry("EXCH_RATE") = "1,00" 'Umrechnungskurs
'Position in Array anhängen
SET AmountData(1) = Entry
'Position 3 füllen
SET Entry = CreateObject("Scripting.Dictionary")
Entry("ITEMNO_ACC") = "0000000003"
Entry("CURR_TYPE") = "00"
Entry("CURRENCY") = "EUR"
Entry("AMT_DOCCUR") = "19,00" 'Steuersumme
Entry("AMT_BASE") = "100,00" 'Steuerbasis
Entry("TAX_AMT") = "0,00"
Entry("EXCH_RATE") = "1,00" 'Umrechnungskurs
'Position in Array anhängen
SET AmountData(2) = Entry
'Positionen zu Parameterobjekt hinzufügen
Param.Add "CURRENCYAMOUNT", AmountData
'Nun können die Einträge für die anderen Parameter erzeugt weden.
'Array für Kreditorenpositionen erzeugen
DIM PayableData(0)
'Objekt für eine Position erzeugen
SET Entry = CreateObject("Scripting.Dictionary")
'Positionsdaten füllen
Entry("ITEMNO_ACC") = "0000000001"
Entry("VENDOR_NO") = "0000001000" 'Kreditor
Entry("PMNTTRMS") = "ZB01" 'Zahlungsbedingungen
Entry("BLINE_DATE") = "16.04.2018" 'Zahlungsfristenbasisdatum
Entry("DSCT_DAYS1") = "14" 'Skontofrist 1
Entry("ITEM_TEXT") = "Text 1" 'SGTXT
'Position in Array anhängen
SET PayableData(0) = Entry
'Positionen zu Parameterobjekt hinzufügen
Param.Add "ACCOUNTPAYABLE",PayableData
'Array für Sachkontenpositionen erzeugen
Dim AccountGLData(0)
'Objekt für eine Position erzeugen
SET Entry = CreateObject("Scripting.Dictionary")
'Positionsdaten füllen
Entry("ITEMNO_ACC") = "0000000002"
Entry("GL_ACCOUNT") = "0000476000" 'Sachkonto
Entry("ITEM_TEXT") = "Text 2" 'SGTXT
Entry("COSTCENTER") = "0000001000" 'Kostenstelle
Entry("VALUE_DATE") = "16.04.2018" 'Valutadatum
'Position in Array anhängen
SET AccountGLData(0) = Entry
'Positionen zu Parameterobjekt hinzufügen
Param.Add "ACCOUNTGL",AccountGLData
'Array für Steuerzeilen erzeugen
DIM TaxData(0)
'Objekt für eine Position erzeugen
SET Entry = CreateObject("Scripting.Dictionary")
'Positionsdaten füllen
Entry("ITEMNO_ACC") = "0000000003"
Entry("TAX_CODE") = "VA" 'Steuerkennzeichen
'Position in Array anhängen
SET TaxData(0) = Entry
'Positionen zu Parameterobjekt hinzufügen
Param.Add "ACCOUNTTAX",TaxData
The BAPI can be called once the parameters have been filled. The evaluation of success or failure requires the analysis of the RETURN parameter. This is also a table parameter. Several lines can be returned, so the entire content must be evaluated. The structure of a row in this table is based on the structure of SAP® messages.
Field | Data type | Description |
---|---|---|
TYPE |
CHAR1 |
Message type: S: Success, E: Error, W: Warning, I: Info, A: Abort, X: Exit |
ID |
CHAR20 |
Message class |
NUMBER | NUMC3 | Message number |
MESSAGE | CHAR220 | Message text |
LOG_NO | CHAR20 | Application log: log number |
LOG_MSG_NO | NUMC6 | Application log: internal serial number of the message |
MESSAGE_V1 | CHAR50 | Message variable |
MESSAGE_V2 | CHAR50 | Message variable |
MESSAGE_V3 | CHAR50 | Message variable |
MESSAGE_V4 | CHAR50 | Message variable |
PARAMETER | CHAR32 | Parameter name |
ROW | INT | Line in the parameter |
FIELD | CHAR30 | Field in the parameter |
SYSTEM | CHAR10 | System (logical system) from which the message originates |
The TYPE field is of crucial importance. If an error occurs, an 'E', 'A', or 'X' is entered here. The invoice was not parked in this case.
The MESSAGE field contains an error message. This message can contain placeholders of the form '&1' to '&4', which can be replaced by the contents of the fields MESSAGE_V1 to MESSAGE_V4. The error messages should be evaluated and logged in any case, at least during the test phase.
If there is no E, A, or X line in the RETURN parameter, but there is an S line, then the invoice has been parked. In this case, the OBJ_KEY export parameter of the BAPI contains the document number of the parked receipt. Please note that the value of this field consists of the concatenated values of the individual key fields and must therefore be broken down if the specific SAP® fields are required.
In the case of FI invoices, the value of the OBJ_KEY parameter has the following structure:
Item | Description |
---|---|
1 to 10 | Receipt number |
11 to 14 | Company code |
15 to 18 | Fiscal year |