ETL = Extract Transform Load
The EPO Connector ETL solution is a well-architectured concept for data transfer out of SAP. Additionally standard interfaces like posting of financial documents are included. The EPO Connector ETL it is implemented in ABAP within the EPO Connector.
EPO Connector ETL connections can be set-up in 2 ways:
SAP Outbound
The data transfer starts in SAP. The destination system either provides APIs or Web Services or the data is written as files to an exchange folder.
SAP Inbound
The data transfer is triggered from outside by API calls or Web Service calls.
All documents about EPO Connector ETL can be found with the tag ETL
For any data which needs to be transferred, the relevant object keys must be added first into table /EPO1/ETLLOG by using static method /EPO1/CL_ETL_LOG->ADD_KEY.
The data transfer is based always on keys in table /EPO1/ETLLOG.
For SAP Inbound interfaces the data transfer is done with the 2 APIs getList (returning the keys only) and getData (returning the data). Additionally there is the getDefinition API for providing the structure of the interface and its fields.
For SAP Outbound interfaces the data transfer is done by the report /EPO1/ETL_SEND or report /EPO1/ETL_SEND_REALTIME, which are used as step in a SAP job.
Table /EPO1/ETLLOG hold all object keys for all ETL objects.
ETL Object Keys can be added with simple reports.
EPO Consulting provides those reports for many data objects in the SAP system.
Customers can copy those reports and change the logic to their needs.
Note: Adding keys must be done with static method /EPO1/CL_ETL_LOG=>ADD_KEY.
ETL Object Keys can be added by implementing a User-Exit.
EPO Consulting provides User-Exits for many data objects in the SAP system.
Customers can copy those User-Exits and implement it in their system.
By adding method /EPO1/CL_ETL_LOG=>RAISE_EVENT_EPO1_ETL those interfaces can transfer data in real-time.
Note: Adding keys must be done with static method /EPO1/CL_ETL_LOG=>ADD_KEY.
ETL Object Keys can be added when the ETL SAP Inbound API getList is called. This is configured in customizing table /EPO1/ETLOBJ_IN, field FILL_LOG_AT_GETLIST ("Fill Log" Checkbox)
Note: Adding keys at runtime of API getList can slow down this API.
Data can be transferred by using EPO Connector SAP Inbound calls. The APIs are getList, getData and getDefinition.
Testing can be done with a tool like Postman or SoapUI. EPO Consulting is providing Postman Collections.
Data can be transferred by using EPO Connector SAP Outbound calls.
After the installation of the EPO Connector and importing the ETL Workbench transports some customizing things must be done.
Please read the ETL Concept (above) first for better understanding.
Transaction SNRO: Object /EPO1/ETL, Button "Interval editing"
Insert number range 00 with the broadest range possible: 0000000000000001 to 9999999999999999
Depending on, if the EPO ETL Interface is SAP Inbound or SAP Outbound, the next steps are different.
In general there are 2 more customizing steps to be done:
Transaction SM30, table /EPO1/ETLOBJ defines the base properties of ETL objects. The 'Prefix Length' will be used in the SYNC - service (and checked against the actually used prefix).
Object | ServiceDir | Max Len | Prefix Len | Key Prefix Description | Key Description | Object name |
---|---|---|---|---|---|---|
ETLAccount | I | 10 | 4 | Company Code | SKA1-SAKNR Account | ETL Account |
ETLAsset | I | 16 | 4 | Company Code | ANLA- BUKRS ANLN1 ANLN2 | ETL Asset |
ETLCoPost | I | 10 | 4 | KOKRS | CSKS-KOKRS CSKS-KOSTL | ETL Cost Centres |
ETLCustmer | I | 10 | 4 | Company Code | KNB1-BUKRS, KNB1-KUNNR Customer | ETL Customer complete |
ETLEqui | I | 18 | 4 | Company Code | EQUI-EQUNR equipment number | ETL Equipment |
ETLFictr | I | 0 | 4 | FIKRS - Financial Managemt. Ar | FIKRS, FICTR | ETL Funds Center |
ETLFuncLoc | I | 18 | 4 | Company Code | IFLOT-TPLNR functional location | ETL Functional Location |
ETLKostl | I | 10 | 4 | KOKRS | CSKS-KOKRS CSKS-KOSTL | ETL Cost Centres |
ETLMateria | I | 18 | 4 | Company Code | MARA-MATNR Material | ETL Material |
ETLMatkl | I | 0 | 0 | MATKL | ETL Material class | |
ETLOrgStru | I | 0 | 0 | Company Code | BUKRS | ETL Org. Structure |
ETLPO | I | 18 | 4 | Company Code | EKKO-EBELN purchase order | ETL Room Number |
ETLRaumn | I | 0 | 4 | WERKS - Plant | WERKS, RAUMN | ETL Standort |
ETLStand | I | 0 | 4 | WERKS - Plant | WERKS, STAND | ETL Vendor |
ETLVendor | I | 0 | 4 | Company Code | ETL Werks | |
ETLWerks | I | 0 | 0 | WERKS |
All data objects provided must be fetched with the following 2 steps:
There are 2 other supporting services:
A) getSync: This API brings the objects in SAP and in the calling target system in sync.
B) getDefinition: This API returns the fields, their types and length and description of the called object
The EPO Connector can be called with SAP transaction /epo1/exc (add it to your favorites)
Transaction /EPO1/SERVICES12
For example create an EPO Connector Service with name "elo2sap"
Transaction /EPO1/EPORTIN12
and Transaction /EPO1/GFMCOP12
Transaction /EPO1/EPORTIN12
API: getList
Transaction /EPO1/EPORTIN12
API: getData
Transaction /EPO1/EPORTIN12
API: getDefinition
Transaction /EPO1/GFMCOP12
Assign function modules to the operations
ETL Customizing is done with transaction SM30 for the following 4 customizing tables (table /EPO1/ETLOBJ_OUT is not relevant):
Table | Description | Detail |
---|---|---|
/EPO1/ETLOBJ | Definition of an ETL object | |
/EPO1/ETLOBJ_IN | ETL Inbound: Function and structure for ETL objects | Only relevant for ETL Inbound scenarios |
ETL Outbound: Class and Realtime definition for ETL objects | Only relevant for ETL Outbound scenarios | |
/EPO1/ETLOBJ_SID | Object settings by SAP System ID | No deletion of an object entry after reading/sending |
/EPO1/ETLOBJ_FLD | Define key fields and always filled fields | Relevant only for API getDefinition |
Definition of ETL objects
Definition of the processing function module and its EPO1EXP exporting structure.
"Fill log" flag means, that it updates object entries (inserted into table /EPO1/ETLLOG) when API getList is called.
Note: With the EPO ETL solution there are 2 other options for filling table /EPO1/ETL. First there is a report provided and second there is the method /EPO1/CL_ETL_LOG->ADD_KEY, which can be used in SAP User-Exits for real-time updates.
By default object entries will be cleared out of table /EPO1/ETLLOG when API getData reads it.
This behaviour can be changed per SAP system Id with setting the flag “no deletion”.
Table entries for setting key fields and obligatory fields for the getDefinition API.
HTTP Method: GET
Authentication: Depending on SAP Server setting in SICF. E.g. HTTP Basic Authentication with a SAP User and Password.
URL: https://[SAP Server:Port]/epo1soa/jsonhandler/[EPO Connector Service]/getList/[ETL Object]/[ETL Key Prefix]?fromDate=YYYYMMDDhhmmss
URL Part | Optional | Description |
---|---|---|
http or https | no | Protocol |
[SAP Server:Port] | no | Name or IP of the SAP server or the proxy server (e.g. SAP Web Dispatcher). See transaction SMICM in SAP. |
/epo1soa/jsonhandler/ | no | EPO Connector JSON handler. See transaction SICF in SAP. Check also for the authentication methods here. |
[EPO Connector Service] | no | EPO Service, which has to be customized in SAP. |
/getList/ | no | API for getting list of object instances (=object numbers) |
[ETL Object] | no | Object, which is called. The object has to be customized in SAP. Objects can be anything from master data, document data or database table data. |
[ETL Key Prefix] | yes | The ETL Key Prefix can be an organisational unit like the company code. By default it is the company code for objects provided by EPO Consulting. |
Parameter fromDate | yes | This parameter should be available for all objects. It means all objects, which were created or updated on or after that date and time. The fromDate timestamp must be in format YYYYMMDDhhmmss. A fromDate in format YYYYMMDD is also accepted. hhmmss will be set to 000000. |
Getting all Vendor keys from company code 1000, created or changed on or after 1. Jan. 2020
Getting all Vendor keys from company code 1000
https://sap.epoconsulting.com/epo1soa/jsonhandler/elo2sap/getList/ELOVendor/1000
Getting all Vendor keys from all company codes
https://sap.epoconsulting.com/epo1soa/jsonhandler/elo2sap/getList/ELOVendor
Response to all ETL calls should have the following 3 root elements:
"epo1ok": "X", when the call was ok. "" or not existent, when an error occured.
"epo1message": [{ elements... }] is an array of objects, containing the following elements
"epo1exp": { elements... } is an objects, containing the following 3 elements
Example successful response:
{
"epo1ok": "X",
"epo1exp": {
"etlQty": 18,
"hasMoreResults": false,
"etlKeyT": [
"1000T-K520D01",
"1000T-K520C01",
"10000000000015"
]
}
}
Example error response:
{
"epo1message": [
{
"type": "E",
"id": "/EPO1/ETL_MESSAGES",
"number": 1,
"message": "No datasets selected",
"system": "T90CLNT090"
}
]
}
HTTP Method: POST
Authentication: Depending on SAP Server setting in SICF. E.g. HTTP Basic Authentication with a SAP User and Password.
URL: https://[SAP Server:Port]/epo1soa/jsonhandler/[EPO Connector Service]/getData/[ETL Object]
JSON Payload: In the payload the ETL keys for the requested objects must be sent.
Structure of the payload
"etlKeyT": [ array of keys ] containing the ETL keys, which were fetched with API getList.
Note: If the list is very large, you may call the getData API more often making packages. We recommend a package size between 100 and 2000 ETL object keys per payload = API call.
URL Part | Optional | Description |
---|---|---|
http or https | no | Protocol |
[SAP Server:Port] | no | Name or IP of the SAP server or the proxy server (e.g. SAP Web Dispatcher). See transaction SMICM in SAP. |
/epo1soa/jsonhandler/ | no | EPO Connector JSON handler. See transaction SICF in SAP. Check also for the authentication methods here. |
[EPO Connector Service] | no | EPO Service, which has to be customized in SAP. |
/getData/ | no | API for getting data of object instances (=object numbers) |
[ETL Object] | no | Object, which is called. The object has to be customized in SAP. Objects can be anything from master data, document data or database table data. |
Getting Vendor data for the 3 ETL Vendor keys sent in the JSON payload.
https://sap.epoconsulting.com/epo1soa/jsonhandler/elo2sap/getData/ELOVendor
{
"etlKeyT": [
"10000000100644",
"1000T-K500E00",
"1000T-K500C01"
]
}
Response to all ETL calls should have the following 3 root elements:
"epo1ok": "X", when the call was ok. "" or not existent, when an error occured.
"epo1message": [{ elements... }] is an array of objects, containing the following elements
"epo1exp": { elements... } is an objects, containing any structure. For ETL APIs the elements are normally following this structure:
Example successful response for ELOVendor:
{
"epo1ok": "X",
"epo1exp": [
{
"objectok": "X",
"etlKey": "10000000100644",
"object": {
"bukrs": "1000",
"lifnr": "0000100644",
"name": "Gartner KG. ",
"street": "Linzerstraße",
"aenam": "KROISSW"
}
},
{
"objectok": "X",
"etlKey": "1000T-K500E00",
"object": {
"bukrs": "1000",
"lifnr": "T-K500E00",
"name": "Elektroblitz GmbH Gr.00 ",
"street": "Teststrasse",
"houseNum1": "34/5",
"postCode1": "80331",
"city1": "München",
"country": "DE",
"smtpAddr": "test@epoconsulting.com",
"telNumber": "+49 1234456",
"faxNumber": "+49 454676747",
"stceg": "DE123456451",
"stcd1": "12345678",
"bank": [
{
"banka": "Giro-Bank",
"iban": "DE391001001067640584",
"swift": "SWIFT123451"
},
{
"banka": "Moneta SPARDA",
"iban": "DE803009905506674757",
"swift": "DEUTDEFFXXX"
}
],
"erdat": "2003-06-11",
"ernam": "WEISSANN",
"udate": "2022-05-17",
"aenam": "CICEKA"
}
},
{
"objectok": "X",
"etlKey": "1000T-K500C01",
"object": {
"bukrs": "1000",
"lifnr": "T-K500C01",
"name": "TAG Potsdam Gr.01 ",
"street": "Schopenhauerstraße",
"erdat": "2003-02-25",
"ernam": "RENDES",
"udate": "2020-09-15",
"aenam": "AIGNERM"
}
}
]
}
Example response with 1 ETL key wrong, which leads to an objectmessage:
{
"epo1ok": "X",
"epo1exp": [
{
"objectok": "X",
"etlKey": "10000000100644",
"object": {
"bukrs": "1000",
"lifnr": "0000100644",
"name": "Gartner KG. ",
"street": "Linzerstraße",
"houseNum1": "40",
"postCode1": "4650",
"city1": "Edt bei Lambach",
"country": "AT",
"stceg": "ATU24879503",
"erdat": "2021-12-15",
"ernam": "KROISSW",
"udate": "2021-12-15",
"aenam": "KROISSW"
}
},
{
"objectmessage": [
{
"type": "E",
"id": "/EPO1/ETL_MESSAGES",
"number": 12,
"message": "BUKRS and LIFNR combination in ETL_KEY not found: 1000T-K500E001",
"messageV1": "1000T-K500E001",
"system": "T90CLNT090"
}
]
}
]
}
Example error response when the request payload has got wrong structure:
Wrong Request
{
"etlKeyT_got_it_wrong": [
"10000000100644",
"1000T-K500E00"
]
}
{
"callstatus": {
"code": 999,
"type": "E",
"subject": "EPO XML Connector class exception",
"description": "No valid source context supplied",
"transactionid": "0000100000077776",
"mandt": "800",
"sysid": "WK1"
}
}
In order to get out-of-sync data aligned again, it is possible to implement a sync service which compares the data in the ETL server against the data in SAP. If differences are found, the ETL key of changed/created/deleted objects will be stored into the ETL log table. With the next getList / getData cycle, the different data will be aligned properly.
The function module /EPO1/ETL_SYNC is configured to be accessible via webservice (see EPO customizing).
Import parameters:
For a small set of object, the sync-service may be invoked by one single call - containing the complete list of ETL-key/timestamp combinations. However, for a large data set, the data transfer might be split into several webservice calls, transferring a smaller block of data to SAP.
The data processing will be started after receiving the LAST_BLOCK - flag set to 'X' in the background.
Depending on the ETL object (see table /EPO1/ETLOBJ_IN), a special function module will be called, which collects all the available information from SAP (containing the ETL-key and the timestamp of the last change).
Afterwards, both collected data (from the ETL-server and from SAP) are compared. Differences will be written into the /EPO1/ETLLOG - table, such that the differences can be equalized during the next GetList/GetData processing.
Please note, that a 'first data preparation' is also possible, when the ETL-server has no data for a given ETL-object/prefix; just send an empty OBJECT_LIST, resulting in a completely filled /EPO1/ETLLOG - table.
Please note, that for performance reasons, the SYNC service should not be called too often.
The current SYNC-status (idle, data collection, data processing), timestamp and error message of the last SYNC-run and a small statistic of created/changed/deleted objects is stored in table /EPO1/ETLSYNC_ST and is returned as part of the GetList response.
HTTP Method: GET
Authentication: Depending on SAP Server setting in SICF. E.g. HTTP Basic Authentication with a SAP User and Password.
URL: https://[SAP Server:Port]/epo1soa/jsonhandler/[EPO Connector Service]/getDefinition/[ETL Object]
URL Part | Optional | Description |
---|---|---|
http or https | no | Protocol |
[SAP Server:Port] | no | Name or IP of the SAP server or the proxy server (e.g. SAP Web Dispatcher). See transaction SMICM in SAP. |
/epo1soa/jsonhandler/ | no | EPO Connector JSON handler. See transaction SICF in SAP. Check also for the authentication methods here. |
[EPO Connector Service] | no | EPO Service, which has to be customized in SAP. |
/getDefinition/ | no | API for getting the definition of the getData API for an object |
[ETL Object] | no | Object, which is called. The object has to be customized in SAP. Objects can be anything from master data, document data or database table data. |
/object | yes | Only the fields of the object will be returned. All other fields except "epo1ok" will be skipped. The field names will be returned without object. prefix. |
Getting the definition for the getData API for the object ELOVendor
Full API definition:
https://sap.epoconsulting.com/epo1soa/jsonhandler/elo2sap/getDefinition/ELOVendor
API definition reduced to object (simplified)
https://sap.epoconsulting.com/epo1soa/jsonhandler/elo2sap/getDefinition/ELOVendor/object
Response to all ETL calls can have the following 3 root elements:
"epo1ok": "X", when the call was ok. "" or not existent, when an error occured.
"epo1message": [{ elements... }] is an array of objects, containing the following elements
"epo1exp": [{ elements... }] is an array of objects, containing the following elements
EPO standard ETL objects will contain the following 4 fields on root level (returned in field "name")
a) "objectok": Is "X", when the object was read successful.
b) "objectmessage": Contains messages for the object. It has the same structure as epo1message.
c) "etlKey": It contains the key of the object.
d) "object": The object contains the response structure of the EPO ETL API. If the path /object is added to the API call, the returned field names will be without the prefix object. For example instead of object.bukrs it will be just bukrs.
Example successful response for ELOVendor.
Like described above the element "epo1exp" contains the 4 elements "objectok", "objectmessage", "etlKey" and "object".
Only the "object" element will be different for different object types.
1{
2 "epo1ok": "X",
3 "epo1exp": [
4 {
5 "name": "objectok",
6 "type": "CHAR",
7 "outputlen": 1,
8 "sign": false,
9 "bytelength": 2,
10 "isKey": false,
11 "alwaysFilled": false,
12 "description": "Indicator"
13 },
14 {
15 "name": "objectmessage",
16 "type": "ARRAY",
17 "sign": false,
18 "isKey": false,
19 "alwaysFilled": false
20 },
21 {
22 "name": "objectmessage[].type",
23 "type": "CHAR",
24 "outputlen": 1,
25 "sign": false,
26 "bytelength": 2,
27 "isKey": false,
28 "alwaysFilled": false,
29 "description": "Message type"
30 },
31 {
32 "name": "objectmessage[].id",
33 "type": "CHAR",
34 "outputlen": 20,
35 "sign": false,
36 "bytelength": 40,
37 "isKey": false,
38 "alwaysFilled": false,
39 "description": "Message Class"
40 },
41 {
42 "name": "objectmessage[].number",
43 "type": "INT",
44 "outputlen": 3,
45 "sign": false,
46 "bytelength": 6,
47 "isKey": false,
48 "alwaysFilled": false,
49 "description": "Message number"
50 },
51 {
52 "name": "objectmessage[].message",
53 "type": "CHAR",
54 "outputlen": 220,
55 "sign": false,
56 "bytelength": 440,
57 "isKey": false,
58 "alwaysFilled": false,
59 "description": "Message text"
60 },
61 {
62 "name": "objectmessage[].logNo",
63 "type": "CHAR",
64 "outputlen": 20,
65 "sign": false,
66 "bytelength": 40,
67 "isKey": false,
68 "alwaysFilled": false,
69 "description": "Log number"
70 },
71 {
72 "name": "objectmessage[].logMsgNo",
73 "type": "INT",
74 "outputlen": 6,
75 "sign": false,
76 "bytelength": 12,
77 "isKey": false,
78 "alwaysFilled": false,
79 "description": "Message serial no."
80 },
81 {
82 "name": "objectmessage[].messageV1",
83 "type": "CHAR",
84 "outputlen": 50,
85 "sign": false,
86 "bytelength": 100,
87 "isKey": false,
88 "alwaysFilled": false,
89 "description": "Message Variable"
90 },
91 {
92 "name": "objectmessage[].messageV2",
93 "type": "CHAR",
94 "outputlen": 50,
95 "sign": false,
96 "bytelength": 100,
97 "isKey": false,
98 "alwaysFilled": false,
99 "description": "Message Variable"
100 },
101 {
102 "name": "objectmessage[].messageV3",
103 "type": "CHAR",
104 "outputlen": 50,
105 "sign": false,
106 "bytelength": 100,
107 "isKey": false,
108 "alwaysFilled": false,
109 "description": "Message Variable"
110 },
111 {
112 "name": "objectmessage[].messageV4",
113 "type": "CHAR",
114 "outputlen": 50,
115 "sign": false,
116 "bytelength": 100,
117 "isKey": false,
118 "alwaysFilled": false,
119 "description": "Message Variable"
120 },
121 {
122 "name": "objectmessage[].parameter",
123 "type": "CHAR",
124 "outputlen": 32,
125 "sign": false,
126 "bytelength": 64,
127 "isKey": false,
128 "alwaysFilled": false,
129 "description": "Parameter Name"
130 },
131 {
132 "name": "objectmessage[].row",
133 "type": "INT",
134 "outputlen": 10,
135 "sign": true,
136 "bytelength": 4,
137 "isKey": false,
138 "alwaysFilled": false,
139 "description": "Lines in parameter"
140 },
141 {
142 "name": "objectmessage[].field",
143 "type": "CHAR",
144 "outputlen": 30,
145 "sign": false,
146 "bytelength": 60,
147 "isKey": false,
148 "alwaysFilled": false,
149 "description": "Field name"
150 },
151 {
152 "name": "objectmessage[].system",
153 "type": "CHAR",
154 "outputlen": 10,
155 "sign": false,
156 "bytelength": 20,
157 "isKey": false,
158 "alwaysFilled": false,
159 "description": "Logical system (source of message)"
160 },
161 {
162 "name": "etlKey",
163 "type": "CHAR",
164 "outputlen": 255,
165 "sign": false,
166 "bytelength": 510,
167 "isKey": false,
168 "alwaysFilled": false,
169 "description": "Key"
170 },
171 {
172 "name": "object.bukrs",
173 "type": "CHAR",
174 "outputlen": 4,
175 "sign": false,
176 "bytelength": 8,
177 "isKey": true,
178 "alwaysFilled": true,
179 "description": "Company Code"
180 },
181 {
182 "name": "object.lifnr",
183 "type": "CHAR",
184 "outputlen": 10,
185 "sign": false,
186 "bytelength": 20,
187 "isKey": true,
188 "alwaysFilled": true,
189 "description": "Vendor"
190 },
191 {
192 "name": "object.name",
193 "type": "VARCHAR",
194 "sign": false,
195 "isKey": false,
196 "alwaysFilled": true,
197 "description": "Name"
198 },
199 {
200 "name": "object.street",
201 "type": "CHAR",
202 "outputlen": 60,
203 "sign": false,
204 "bytelength": 120,
205 "isKey": false,
206 "alwaysFilled": false,
207 "description": "Street"
208 },
209 {
210 "name": "object.houseNum1",
211 "type": "CHAR",
212 "outputlen": 10,
213 "sign": false,
214 "bytelength": 20,
215 "isKey": false,
216 "alwaysFilled": false,
217 "description": "House Number"
218 },
219 {
220 "name": "object.postCode1",
221 "type": "CHAR",
222 "outputlen": 10,
223 "sign": false,
224 "bytelength": 20,
225 "isKey": false,
226 "alwaysFilled": false,
227 "description": "Postal Code"
228 },
229 {
230 "name": "object.city1",
231 "type": "CHAR",
232 "outputlen": 40,
233 "sign": false,
234 "bytelength": 80,
235 "isKey": false,
236 "alwaysFilled": false,
237 "description": "City"
238 },
239 {
240 "name": "object.country",
241 "type": "CHAR",
242 "outputlen": 3,
243 "sign": false,
244 "bytelength": 6,
245 "isKey": false,
246 "alwaysFilled": true,
247 "description": "Country Key"
248 },
249 {
250 "name": "object.smtpAddr",
251 "type": "CHAR",
252 "outputlen": 241,
253 "sign": false,
254 "bytelength": 482,
255 "isKey": false,
256 "alwaysFilled": false,
257 "description": "E-Mail Address"
258 },
259 {
260 "name": "object.telNumber",
261 "type": "CHAR",
262 "outputlen": 30,
263 "sign": false,
264 "bytelength": 60,
265 "isKey": false,
266 "alwaysFilled": false,
267 "description": "Telephone"
268 },
269 {
270 "name": "object.faxNumber",
271 "type": "CHAR",
272 "outputlen": 30,
273 "sign": false,
274 "bytelength": 60,
275 "isKey": false,
276 "alwaysFilled": false,
277 "description": "Fax"
278 },
279 {
280 "name": "object.stceg",
281 "type": "CHAR",
282 "outputlen": 20,
283 "sign": false,
284 "bytelength": 40,
285 "isKey": false,
286 "alwaysFilled": false,
287 "description": "VAT Registration No."
288 },
289 {
290 "name": "object.stcd1",
291 "type": "CHAR",
292 "outputlen": 16,
293 "sign": false,
294 "bytelength": 32,
295 "isKey": false,
296 "alwaysFilled": false,
297 "description": "Tax Number 1"
298 },
299 {
300 "name": "object.busab",
301 "type": "CHAR",
302 "outputlen": 2,
303 "sign": false,
304 "bytelength": 4,
305 "isKey": false,
306 "alwaysFilled": false,
307 "description": "Clerk Abbreviation"
308 },
309 {
310 "name": "object.bank",
311 "type": "ARRAY",
312 "sign": false,
313 "isKey": false,
314 "alwaysFilled": false
315 },
316 {
317 "name": "object.bank[].banka",
318 "type": "CHAR",
319 "outputlen": 60,
320 "sign": false,
321 "bytelength": 120,
322 "isKey": false,
323 "alwaysFilled": false,
324 "description": "Bank name"
325 },
326 {
327 "name": "object.bank[].iban",
328 "type": "CHAR",
329 "outputlen": 34,
330 "sign": false,
331 "bytelength": 68,
332 "isKey": false,
333 "alwaysFilled": false,
334 "description": "IBAN"
335 },
336 {
337 "name": "object.bank[].swift",
338 "type": "CHAR",
339 "outputlen": 11,
340 "sign": false,
341 "bytelength": 22,
342 "isKey": false,
343 "alwaysFilled": false,
344 "description": "SWIFT/BIC"
345 },
346 {
347 "name": "object.erdat",
348 "type": "DATE",
349 "outputlen": 10,
350 "sign": false,
351 "bytelength": 16,
352 "isKey": false,
353 "alwaysFilled": false,
354 "description": "Created on"
355 },
356 {
357 "name": "object.ernam",
358 "type": "CHAR",
359 "outputlen": 12,
360 "sign": false,
361 "bytelength": 24,
362 "isKey": false,
363 "alwaysFilled": false,
364 "description": "Created by"
365 },
366 {
367 "name": "object.udate",
368 "type": "DATE",
369 "outputlen": 10,
370 "sign": false,
371 "bytelength": 16,
372 "isKey": false,
373 "alwaysFilled": false,
374 "description": "Date"
375 },
376 {
377 "name": "object.aenam",
378 "type": "CHAR",
379 "outputlen": 12,
380 "sign": false,
381 "bytelength": 24,
382 "isKey": false,
383 "alwaysFilled": false,
384 "description": "Changed by"
385 },
386 {
387 "name": "object.erpsy",
388 "type": "CHAR",
389 "outputlen": 7,
390 "sign": false,
391 "bytelength": 14,
392 "isKey": false,
393 "alwaysFilled": false,
394 "description": "ERP-System"
395 },
396 {
397 "name": "object.dunningData",
398 "type": "STRUCT",
399 "sign": false,
400 "isKey": false,
401 "alwaysFilled": false
402 },
403 {
404 "name": "object.dunningData.mandt",
405 "type": "CHAR",
406 "outputlen": 3,
407 "sign": false,
408 "bytelength": 6,
409 "isKey": false,
410 "alwaysFilled": false,
411 "description": "Client"
412 },
413 {
414 "name": "object.dunningData.lifnr",
415 "type": "CHAR",
416 "outputlen": 10,
417 "sign": false,
418 "bytelength": 20,
419 "isKey": false,
420 "alwaysFilled": false,
421 "description": "Vendor"
422 },
423 {
424 "name": "object.dunningData.bukrs",
425 "type": "CHAR",
426 "outputlen": 4,
427 "sign": false,
428 "bytelength": 8,
429 "isKey": false,
430 "alwaysFilled": false,
431 "description": "Company Code"
432 },
433 {
434 "name": "object.dunningData.maber",
435 "type": "CHAR",
436 "outputlen": 2,
437 "sign": false,
438 "bytelength": 4,
439 "isKey": false,
440 "alwaysFilled": false,
441 "description": "Dunning Area"
442 },
443 {
444 "name": "object.dunningData.mahna",
445 "type": "CHAR",
446 "outputlen": 4,
447 "sign": false,
448 "bytelength": 8,
449 "isKey": false,
450 "alwaysFilled": false,
451 "description": "Dunning Procedure"
452 },
453 {
454 "name": "object.dunningData.mansp",
455 "type": "CHAR",
456 "outputlen": 1,
457 "sign": false,
458 "bytelength": 2,
459 "isKey": false,
460 "alwaysFilled": false,
461 "description": "Dunning Block"
462 },
463 {
464 "name": "object.dunningData.madat",
465 "type": "DATE",
466 "outputlen": 10,
467 "sign": false,
468 "bytelength": 16,
469 "isKey": false,
470 "alwaysFilled": false,
471 "description": "Last Dunned"
472 },
473 {
474 "name": "object.dunningData.mahns",
475 "type": "INT",
476 "outputlen": 1,
477 "sign": false,
478 "bytelength": 2,
479 "isKey": false,
480 "alwaysFilled": false,
481 "description": "Dunning Level"
482 },
483 {
484 "name": "object.dunningData.lfrma",
485 "type": "CHAR",
486 "outputlen": 10,
487 "sign": false,
488 "bytelength": 20,
489 "isKey": false,
490 "alwaysFilled": false,
491 "description": "Dunn.recipient"
492 },
493 {
494 "name": "object.dunningData.gmvdt",
495 "type": "DATE",
496 "outputlen": 10,
497 "sign": false,
498 "bytelength": 16,
499 "isKey": false,
500 "alwaysFilled": false,
501 "description": "Legal dunn.proc.from"
502 },
503 {
504 "name": "object.dunningData.busab",
505 "type": "CHAR",
506 "outputlen": 2,
507 "sign": false,
508 "bytelength": 4,
509 "isKey": false,
510 "alwaysFilled": false,
511 "description": "Dunning clerk"
512 }
513 ]
514}
Example successful response for ELOVendor.
Like described above the element "epo1exp" contains the 4 elements "objectok", "objectmessage", "etlKey" and "object".
Only the "object" element will be different for different object types.
1{
2 "epo1ok": "X",
3 "epo1exp": [
4 {
5 "name": "bukrs",
6 "type": "CHAR",
7 "outputlen": 4,
8 "sign": false,
9 "bytelength": 8,
10 "isKey": true,
11 "alwaysFilled": true,
12 "description": "Company Code"
13 },
14 {
15 "name": "lifnr",
16 "type": "CHAR",
17 "outputlen": 10,
18 "sign": false,
19 "bytelength": 20,
20 "isKey": true,
21 "alwaysFilled": true,
22 "description": "Vendor"
23 },
24 {
25 "name": "name",
26 "type": "VARCHAR",
27 "sign": false,
28 "isKey": false,
29 "alwaysFilled": true,
30 "description": "Name"
31 },
32 {
33 "name": "street",
34 "type": "CHAR",
35 "outputlen": 60,
36 "sign": false,
37 "bytelength": 120,
38 "isKey": false,
39 "alwaysFilled": false,
40 "description": "Street"
41 },
42 {
43 "name": "houseNum1",
44 "type": "CHAR",
45 "outputlen": 10,
46 "sign": false,
47 "bytelength": 20,
48 "isKey": false,
49 "alwaysFilled": false,
50 "description": "House Number"
51 },
52 {
53 "name": "postCode1",
54 "type": "CHAR",
55 "outputlen": 10,
56 "sign": false,
57 "bytelength": 20,
58 "isKey": false,
59 "alwaysFilled": false,
60 "description": "Postal Code"
61 },
62 {
63 "name": "city1",
64 "type": "CHAR",
65 "outputlen": 40,
66 "sign": false,
67 "bytelength": 80,
68 "isKey": false,
69 "alwaysFilled": false,
70 "description": "City"
71 },
72 {
73 "name": "country",
74 "type": "CHAR",
75 "outputlen": 3,
76 "sign": false,
77 "bytelength": 6,
78 "isKey": false,
79 "alwaysFilled": true,
80 "description": "Country Key"
81 },
82 {
83 "name": "smtpAddr",
84 "type": "CHAR",
85 "outputlen": 241,
86 "sign": false,
87 "bytelength": 482,
88 "isKey": false,
89 "alwaysFilled": false,
90 "description": "E-Mail Address"
91 },
92 {
93 "name": "telNumber",
94 "type": "CHAR",
95 "outputlen": 30,
96 "sign": false,
97 "bytelength": 60,
98 "isKey": false,
99 "alwaysFilled": false,
100 "description": "Telephone"
101 },
102 {
103 "name": "faxNumber",
104 "type": "CHAR",
105 "outputlen": 30,
106 "sign": false,
107 "bytelength": 60,
108 "isKey": false,
109 "alwaysFilled": false,
110 "description": "Fax"
111 },
112 {
113 "name": "stceg",
114 "type": "CHAR",
115 "outputlen": 20,
116 "sign": false,
117 "bytelength": 40,
118 "isKey": false,
119 "alwaysFilled": false,
120 "description": "VAT Registration No."
121 },
122 {
123 "name": "stcd1",
124 "type": "CHAR",
125 "outputlen": 16,
126 "sign": false,
127 "bytelength": 32,
128 "isKey": false,
129 "alwaysFilled": false,
130 "description": "Tax Number 1"
131 },
132 {
133 "name": "busab",
134 "type": "CHAR",
135 "outputlen": 2,
136 "sign": false,
137 "bytelength": 4,
138 "isKey": false,
139 "alwaysFilled": false,
140 "description": "Clerk Abbreviation"
141 },
142 {
143 "name": "bank",
144 "type": "ARRAY",
145 "sign": false,
146 "isKey": false,
147 "alwaysFilled": false
148 },
149 {
150 "name": "bank[].banka",
151 "type": "CHAR",
152 "outputlen": 60,
153 "sign": false,
154 "bytelength": 120,
155 "isKey": false,
156 "alwaysFilled": false,
157 "description": "Bank name"
158 },
159 {
160 "name": "bank[].iban",
161 "type": "CHAR",
162 "outputlen": 34,
163 "sign": false,
164 "bytelength": 68,
165 "isKey": false,
166 "alwaysFilled": false,
167 "description": "IBAN"
168 },
169 {
170 "name": "bank[].swift",
171 "type": "CHAR",
172 "outputlen": 11,
173 "sign": false,
174 "bytelength": 22,
175 "isKey": false,
176 "alwaysFilled": false,
177 "description": "SWIFT/BIC"
178 },
179 {
180 "name": "erdat",
181 "type": "DATE",
182 "outputlen": 10,
183 "sign": false,
184 "bytelength": 16,
185 "isKey": false,
186 "alwaysFilled": false,
187 "description": "Created on"
188 },
189 {
190 "name": "ernam",
191 "type": "CHAR",
192 "outputlen": 12,
193 "sign": false,
194 "bytelength": 24,
195 "isKey": false,
196 "alwaysFilled": false,
197 "description": "Created by"
198 },
199 {
200 "name": "udate",
201 "type": "DATE",
202 "outputlen": 10,
203 "sign": false,
204 "bytelength": 16,
205 "isKey": false,
206 "alwaysFilled": false,
207 "description": "Date"
208 },
209 {
210 "name": "aenam",
211 "type": "CHAR",
212 "outputlen": 12,
213 "sign": false,
214 "bytelength": 24,
215 "isKey": false,
216 "alwaysFilled": false,
217 "description": "Changed by"
218 },
219 {
220 "name": "erpsy",
221 "type": "CHAR",
222 "outputlen": 7,
223 "sign": false,
224 "bytelength": 14,
225 "isKey": false,
226 "alwaysFilled": false,
227 "description": "ERP-System"
228 },
229 {
230 "name": "dunningData",
231 "type": "STRUCT",
232 "sign": false,
233 "isKey": false,
234 "alwaysFilled": false
235 },
236 {
237 "name": "dunningData.mandt",
238 "type": "CHAR",
239 "outputlen": 3,
240 "sign": false,
241 "bytelength": 6,
242 "isKey": false,
243 "alwaysFilled": false,
244 "description": "Client"
245 },
246 {
247 "name": "dunningData.lifnr",
248 "type": "CHAR",
249 "outputlen": 10,
250 "sign": false,
251 "bytelength": 20,
252 "isKey": true,
253 "alwaysFilled": true,
254 "description": "Vendor"
255 },
256 {
257 "name": "dunningData.bukrs",
258 "type": "CHAR",
259 "outputlen": 4,
260 "sign": false,
261 "bytelength": 8,
262 "isKey": true,
263 "alwaysFilled": true,
264 "description": "Company Code"
265 },
266 {
267 "name": "dunningData.maber",
268 "type": "CHAR",
269 "outputlen": 2,
270 "sign": false,
271 "bytelength": 4,
272 "isKey": false,
273 "alwaysFilled": false,
274 "description": "Dunning Area"
275 },
276 {
277 "name": "dunningData.mahna",
278 "type": "CHAR",
279 "outputlen": 4,
280 "sign": false,
281 "bytelength": 8,
282 "isKey": false,
283 "alwaysFilled": false,
284 "description": "Dunning Procedure"
285 },
286 {
287 "name": "dunningData.mansp",
288 "type": "CHAR",
289 "outputlen": 1,
290 "sign": false,
291 "bytelength": 2,
292 "isKey": false,
293 "alwaysFilled": false,
294 "description": "Dunning Block"
295 },
296 {
297 "name": "dunningData.madat",
298 "type": "DATE",
299 "outputlen": 10,
300 "sign": false,
301 "bytelength": 16,
302 "isKey": false,
303 "alwaysFilled": false,
304 "description": "Last Dunned"
305 },
306 {
307 "name": "dunningData.mahns",
308 "type": "INT",
309 "outputlen": 1,
310 "sign": false,
311 "bytelength": 2,
312 "isKey": false,
313 "alwaysFilled": false,
314 "description": "Dunning Level"
315 },
316 {
317 "name": "dunningData.lfrma",
318 "type": "CHAR",
319 "outputlen": 10,
320 "sign": false,
321 "bytelength": 20,
322 "isKey": false,
323 "alwaysFilled": false,
324 "description": "Dunn.recipient"
325 },
326 {
327 "name": "dunningData.gmvdt",
328 "type": "DATE",
329 "outputlen": 10,
330 "sign": false,
331 "bytelength": 16,
332 "isKey": false,
333 "alwaysFilled": false,
334 "description": "Legal dunn.proc.from"
335 },
336 {
337 "name": "dunningData.busab",
338 "type": "CHAR",
339 "outputlen": 2,
340 "sign": false,
341 "bytelength": 4,
342 "isKey": false,
343 "alwaysFilled": false,
344 "description": "Dunning clerk"
345 }
346 ]
347}
Data will be sent out to its destination by the report /EPO1/ETL_SEND or /EPO1/ETL_SEND_REALTIME. The collection, formatting and sending of data must be programmed in a subclass of /EPO1/CL_ETL_SEND, method UE_COLLECT_AND_SEND_DATA.
The method /epo1/cl_etl_send does not contain active ABAP code. Thus the method must be re-defined in another class. The method contains sample coding, which is commented out.
A sample implementation is class/method /EPO1/CL_MSCRM_ETL_SEND->UE_COLLECT_AND_SEND_DATA.
The EPO Connector can be called with SAP transaction /epo1/exc (add it to your favorites)
Transaction /EPO1/SERVICES12
For example create an EPO Connector Service with name "sap2mscrm"
Transaction /EPO1/EPORTIN12
and Transaction /EPO1/GFMCOP12
Transaction /EPO1/EPORTIN12
Configuration example for token request
Configuration example for API call
Transaction /EPO1/EC_EB_WSSP12 (Report /EPO1/EC_EB_SERVICE_PARAMETERS)
ETL Customizing is done with transaction SM30 for the following 3 customizing tables (table /EPO1/ETLOBJ_IN and /EPO1/ETLOBJ_FLD are not relevant):
Table | Description | Detail |
---|---|---|
/EPO1/ETLOBJ | Definition of an ETL object | |
/EPO1/ETLOBJ_OUT | ETL Outbound: Class and Realtime definition for ETL objects | Only relevant for ETL Outbound scenarios |
/EPO1/ETLOBJ_SID | Object settings by SAP System ID | No deletion of an object entry after reading/sending |
ETL Inbound: Function and structure for ETL objects | Only relevant for ETL Inbound scenarios | |
Define key fields and always filled fields | Relevant only for API getDefinition |
Definition of ETL objects
Definition of the processing class. The class must be a re-definition of class /epo1/cl_etl_send.
The flag "Real-time" allows sending data in real time.
Note: With the EPO ETL solution there are 2 other options for filling table /EPO1/ETL. First there is a report provided and second there is the method /EPO1/CL_ETL_LOG->ADD_KEY, which can be used in SAP User-Exits for real-time updates.
By default object entries will be cleared out of table /EPO1/ETLLOG when API getData reads it.
Data is sent with report /EPO1/ETL_SEND. The report can be scheduled as SAP job.
The report reads entries from table /EPO1/ETLLOG for the selected object. After successful sending the entries will be deleted, if not otherwise configured in table /epo1/etlobj_sid.
The technical protocol can be found in the EPO Connector message logging.
Data is sent in real-time with report /EPO1/ETL_SEND_REALTIME.