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/ETLLOG. 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
https://sap.epoconsulting.com/epo1soa/jsonhandler/elo2sap/getList/ELOVendor/1000?fromDate=20200101000000
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 details of the sync API are described in a separate page.
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/ETLLOG. 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.
There are several objects defined and implemented by EPO. However, a customer may define and implement any other objects. Simply study (and copy) one of the available function modules and create similar function modules for other objects.
GET_DATA | /EPO1/ETL_COPOSTING |
SYNC | /EPO1/ETL_COPOSTING_SYNC |
Sync-Prefix | COBK-KOKRS |
ETL-key | KOKRS, BELNR |
CDHDR-key | KOKRS, BELNR |
CDHDR-ID | SACH |
data table(s) | COBK |
GET_DATA | /EPO1/ETL_KOSTL |
SYNC | /EPO1/ETL_KOSTL_SYNC |
Sync-Prefix | KOKRS |
ETL-key | KOKRS, KOSTL |
CDHDR-key | KOKRS, KOSTL |
CDHDR-ID | KOSTL |
data table(s) | CSKS, CSKT |
GET_DATA | /EPO1/ETL_ACCOUNT |
SYNC | /EPO1/ETL_ACCOUNT_SYNC |
Sync-Prefix | BUKRS (mandatory for SYNC) |
ETL-key | BUKRS, SAKNR |
CDHDR-key | KTOPL, SAKNR |
CDHDR-ID | SACH |
data table(s) | SKA1, SKB1, SKAT |
GET_DATA | /EPO1/ETL_ASSET |
SYNC | /EPO1/ETL_ASSET_SYNC |
Sync-Prefix | BUKRS |
ETL-key | BUKRS, ANLN1, ANLN2 |
CDHDR-key | BUKRS, ANLN1, ANLN2 |
CDHDR-ID | ANLA |
data table(s) | ANLA, ANLH, ANLU, ANLZ |
GET_DATA | /EPO1/ETL_CUSTOMER |
SYNC | /EPO1/ETL_CUSTOMER_SYNC |
Sync-Prefix | BUKRS |
ETL-key | BUKRS, KUNNR |
CDHDR-key | KUNNR |
CDHDR-ID | DEBI |
data table(s) | KNA1, KNB2, KNB5, KNBK, KNAS, KNVV, ADRC |
Report | /EPO1/ETL_FICTR |
Rep-Prefix | FIKRS |
GET_DATA | /EPO1/ETL_FICTR |
SYNC | /EPO1/ETL_FICTR_SYNC |
Sync-Prefix | FIKRS |
ETL-key | FIKRS, FICTR |
CDHDR-key | -- |
CDHDR-ID | -- |
data table(s) | FMFCTR, FMFCTRT |
GET_DATA | /EPO1/ETL_FIPOSTING |
SYNC | /EPO1/ETL_FIPOSTING_SYNC |
Sync-Prefix | BUKRS |
ETL-key | BUKRS, BELNR, GJAHR |
CDHDR-key | MANDT, BUKRS, BELNR, GJAHR |
CDHDR-ID | BELEG |
data table(s) | BKPF, BSEG, BSET, BSEC |
Report | /EPO1/ETL_COMPCODE |
Rep-Prefix | -- |
GET_DATA | /EPO1/ETL_ORGSTRUCT |
SYNC | /EPO1/ETL_ORGSTRUCT_SYNC |
Sync-Prefix | BUKRS |
ETL-key | BUKRS |
CDHDR-key | -- |
CDHDR-ID | -- |
data table(s) | T001, TKA02, TVKO, T001K, T001W |
GET_DATA | /EPO1/ETL_VENDOR |
SYNC | /EPO1/ETL_VENDOR_SYNC |
Sync-Prefix | BUKRS |
ETL-key | BUKRS, LIFNR |
CDHDR-key | LIFNR |
CDHDR-ID | KRED |
data table(s) | LFA1, LFB1, LFB5, LFBK, LFAS, LFM1, LFM2, ADRC |
Report | /EPO1/ETL_MATERIAL |
Rep-Prefix | BUKRS |
GET_DATA | /EPO1/ETL_MATERIAL |
SYNC | /EPO1/ETL_MATERIAL_SYNC |
Sync-Prefix | BUKRS |
ETL-key | MATNR |
CDHDR-key | MATERIAL |
CDHDR-ID | MATNR |
data table(s) | MARA, MAKT |
Export data
Note: there is no change log, so we will sync all material classes
Report | /EPO1/ETL_MATKL |
Rep-Prefix | BUKRS |
GET_DATA | /EPO1/ETL_MATKL |
SYNC | /EPO1/ETL_MATKL_SYNC |
Sync-Prefix | -- |
ETL-key | MATKL |
CDHDR-key | -- |
CDHDR-ID | -- |
data table(s) | T023T |
Export data
Report | /EPO1/ETL_PO |
Rep-Prefix | BUKRS |
GET_DATA | /EPO1/ETL_PO |
SYNC | /EPO1/ETL_PO_SYNC |
Sync-Prefix | BUKRS |
ETL-key | EBELN |
CDHDR-key | EBELN |
CDHDR-ID | EINKBELEG |
data table(s) | EKKO, EKPO, EKKN, EKET, ADRC |
transactions | ME21N, ME22N, ME23N |
Export data
Report | /EPO1/ETL_RAUMN_COMPCODE |
Rep-Prefix | WERKS |
GET_DATA | /EPO1/ETL_RAUMN |
SYNC | /EPO1/ETL_RAUMN_SYNC |
Sync-Prefix | BUKRS |
ETL-key | WERKS, RAUMN |
CDHDR-key | BUKRS, ANLN1, ANLN2 |
CDHDR-ID | ANLA |
data table(s) | T001W, ANLZ |
Report | /EPO1/ETL_STAND |
Rep-Prefix | WERKS |
GET_DATA | /EPO1/ETL_STAND |
SYNC | /EPO1/ETL_STAND_SYNC |
Sync-Prefix | BUKRS |
ETL-key | WERKS, STAND |
CDHDR-key | -- |
CDHDR-ID | -- |
data table(s) | T499S, ADRC |
Report | /EPO1/ETL_WERKS |
Rep-Prefix | WERKS |
GET_DATA | /EPO1/ETL_WERKS |
SYNC | /EPO1/ETL_WERKS_SYNC |
Sync-Prefix | BUKRS |
ETL-key | WERKS |
CDHDR-key | -- |
CDHDR-ID | -- |
data table(s) | T001W, ADRC |
Report | /EPO1/ETL_EQUIPMENT |
Rep-Selection | BUKRS, IWERK, EQUNR |
GET_DATA | /EPO1/ETL_EQUIPMENT |
SYNC | /EPO1/ETL_EQUIPMENT_SYNC |
Sync-Prefix | BUKRS |
ETL-key | EQUNR |
CDHDR-key | EQUNR |
CDHDR-ID | IFLO |
data table(s) | EQUI, EQKT |
transactions | IE08, IE02, IE03 |
Export data
Report | /EPO1/ETL_FUNCT_LOC |
Rep-Selection | BUKRS, WERKS, TPLNR |
GET_DATA | /EPO1/ETL_FUNCT_LOC |
SYNC | /EPO1/ETL_FUNCT_LOC_SYNC |
Sync-Prefix | BUKRS |
ETL-key | TPLNR |
CDHDR-key | TPLNR (internal format) |
CDHDR-ID | IFLO |
data table(s) | IFLOT, IFLOTX |
transactions | IL08, IL02, IL03 |
Export data
Version 3.5.7
Transportauftrag WK1K904xxx ??.??.2024
Aktivitäten vor dem Import:
Version 3.5.5
Transportauftrag WK1K904321 22.03.2024
Aktivitäten vor dem Import:
Version 3.5.4
Transportauftrag WK1K904286 15.03.2024
Aktivitäten vor dem Import:
Version 3.5.3
Transportauftrag WK1K904273 12.03.2024
Aktivitäten vor dem Import:
Version 3.5.2
Transportauftrag WK1K904220 26.02.2024
Aktivitäten vor dem Import:
Version 3.5.1
Transportauftrag WK1K904204 21.02.2024
Aktivitäten vor dem Import:
Version 3.2.3
Transportauftrag WK1K903883 08.11.2023
Aktivitäten vor dem Import: