Beantwortet

Standard-API AngebotCreate -> Invalid key (id) messageCode 5


Benutzerebene 4
Abzeichen +2

Ich habe die gleiche Fehlermeldung, die hier schon mind. 3x im Forum vorkommt, aber bei AngebotCreate:

<action>AngebotCreate</action>
<message>Invalid key (id)</message>
<messageCode>5</messageCode>

Es scheint ja leider keine aktuelle Doku zur Standard-API zu geben (hier und hier sind unvollständig, veraltet oder haben tote Links), also vllt mache ich auch was falsch.

AngebotGet habe ich hinbekommen:

declare methodname=AngebotGet
declare id=995
curl --data @- --digest -su "$XENTRAL_API_USER_SCRIPT_USER:$XENTRAL_API_USER_SCRIPT_PASSWORD" "${XENTRAL_API_URL_STANDARD}$methodname?id=$id" <<TEXT
<?xml version="1.0" encoding="UTF-8"?>
<request>
<status>
<function>$methodname</function>
</status>
<xml>
</xml>
</request>
TEXT

Aber bei AngebotCreate kommt eben dieser Fehler-Status oben:

declare methodname=AngebotCreate
curl --data @- --digest -su "$XENTRAL_API_USER_SCRIPT_USER:$XENTRAL_API_USER_SCRIPT_PASSWORD" "${XENTRAL_API_URL_STANDARD}$methodname" <<TEXT
<?xml version="1.0" encoding="UTF-8"?>
<request>
<status>
<function>$methodname</function>
</status>
<xml>
<<xml-for-angebotcreate>>
</xml>
</request>
TEXT

Für <<xml-for-angebotcreate>> habe ich vom Support ein Beispiel bekommen, das ich verwendet habe. Aber ich glaube der Fehler liegt woanders.

Wenn ich übrigens bei AngebotGet den query string parameter ?id=xxx in der URL weglasse kommt die gleiche Fehlermeldung!

icon

Beste Antwort von Jakob Schöttl 25 August 2022, 19:15

Original anzeigen

16 Antworten

Benutzerebene 3
Abzeichen +1

Also mit diesem xml

<xml>
<kundennummer>347105</kundennummer>
<artikelliste>
<position>
<nummer>179</nummer>
<preis>79.95</preis>
<menge>1</menge>
<waehrung>EUR</waehrung>
</position>
</artikelliste>
</xml>

wobei kundennummer NICHT die ID des kunden ist, klappt es problemlos.

Ich feuere curl via php ab. Nur so nebenbei. Da funktionieren in der tat alle API-Aufrufe, die man in der doku findet. 

 

Benutzerebene 4
Abzeichen +2

Danke jav666.

Ich hatte ein ähnliches minimales Beispiel, allerdings

  • mit <adresse>ID statt wie bei dir <kundennummer>KNR und
  • mit <position><id>ID statt wie bei dir <position><nummer>ANR

Aber wenn ich deine XML einsetze und nur Kundennummer und Artikelnummer abändere kommt bei mir nach wie vor der gleiche Fehler.

Benutzerebene 3
Abzeichen +1

Also das funktioniert:

https://masterlevel.de/xentralapi/?t=112

 

 

Benutzerebene 3
Abzeichen +1

wollte dir einen link schicken, mit dem du das testen kannst…

aber darf man hier nicht.

das funktioniert einwandfrei. knappe 20 zeilen gecurlt mit php...

 

Array
(
[status] => Array
(
[action] => AngebotCreate
[message] => OK
[messageCode] => 1
)

[xml] => Array
(
[id] => 2
[belegnr] => 100001
)

)

 

Benutzerebene 3
Abzeichen +1
<?php

$xml = "<xml>
<kundennummer>10000</kundennummer>
<artikelliste>
<position>
<nummer>179</nummer>
<preis>79.95</preis>
<menge>1</menge>
<waehrung>EUR</waehrung>
</position>
</artikelliste>
</xml>";




$apiAufruf = "AngebotCreate";
$username = "blabla";
$password = "blubb";
$deineZahlen = "1234afc6b1234";

$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($curl, CURLOPT_USERPWD, "$username:$password");
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://' . $deineZahlen . '.xentral.biz/api/' . $apiAufruf,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_POSTFIELDS =>$xml,
CURLOPT_HTTPHEADER => array(
'Content-Type: application/xml'
),
));
$response = curl_exec($curl);
curl_close($curl);


echo "<pre>";
echo htmlentities($response);
echo "</pre>";

sollte klappen.

Benutzerebene 4
Abzeichen +2

Danke, das funktioniert bei mir auch!

In deinem Code steht CUSTOMREQUEST = ‘GET’, obwohl es ja ein POST ist. Weißt du warum?

Ich hab content type header und request GET mit command-line curl versucht, aber daran liegt’s wohl noch nicht.

Ich werde mal weiter deine CURL Optionen durchgehen.

Benutzerebene 3
Abzeichen +1

Gute Frage ;) Google findet da ja einiges hochwissentschaftliches zum Thema “CUSTOMREQUEST” … ich glaube, so genau muss ich das nicht wissen ;)

Benutzerebene 4
Abzeichen +2

Hab’s! Anscheinend darf man bei AngebotCreate nur ein XML-Snippet übergeben, aber nicht den kompletten, validen XML-Request aus der Doku. Bei AngebotGet darf (oder muss?) man dagegen den kompletten XML-Request übergeben.

Das funktioniert:

declare methodname=AngebotCreate
curl --data @- --digest -su "$XENTRAL_API_USER_SCRIPT_USER:$XENTRAL_API_USER_SCRIPT_PASSWORD" "${XENTRAL_API_URL_STANDARD}$methodname" \
-H 'Content-Type: application/xml' <<TEXT
<xml>
<kundennummer>10405</kundennummer>
<artikelliste>
<position>
<nummer>5027</nummer>
<preis>79.95</preis>
<menge>1</menge>
<waehrung>EUR</waehrung>
</position>
</artikelliste>
</xml>
TEXT

Und weil man kein gültiges XML-Dokument sendet, muss man den Content-Type Header selbst setzen. Das ist der Diff zu meiner ursprünglichen Lösung von ganz oben:

 declare methodname=AngebotCreate
-curl --data @- --digest -su "$XENTRAL_API_USER_SCRIPT_USER:$XENTRAL_API_USER_SCRIPT_PASSWORD" "${XENTRAL_API_URL_STANDARD}$methodname" <<TEXT
- <?xml version="1.0" encoding="UTF-8"?>
- <request>
- <status>
- <function>$methodname</function>
- </status>
+curl --data @- --digest -su "$XENTRAL_API_USER_SCRIPT_USER:$XENTRAL_API_USER_SCRIPT_PASSWORD" "${XENTRAL_API_URL_STANDARD}$methodname" \
+ -H 'Content-Type: application/xml' <<TEXT
<xml>
<<xml-for-angebotcreate>>
</xml>
- </request>
TEXT

 

 

Benutzerebene 4
Abzeichen +2

PS: Anscheinend geht AngebotGet dann auch ohne XML als reines HTTP GET:

declare methodname=AngebotGet
declare id=995
curl --digest -su "$XENTRAL_API_USER_SCRIPT_USER:$XENTRAL_API_USER_SCRIPT_PASSWORD" "${XENTRAL_API_URL_STANDARD}$methodname?id=$id"

 

Benutzerebene 3
Abzeichen +1

auf jeden Fall. Bei allen “blablablaGets” kann das XML leer bleiben. Gefordert wird nur die ID oder belegnr

Benutzerebene 4
Abzeichen +2

Weißt du zufällig, wenn wir schon dabei sind, ob bei den Positionen <id> und <menge> ausreicht? Alles andere könnte ja theoretisch aus den Stammdaten gezogen werden. Das wäre voll praktisch! Andernfalls muss ich ja bei jeder Änderung in den Artikelstammdaten die Artikelliste exportieren und in meinem API-Client hinterlegen...

Benutzerebene 3
Abzeichen +1

war schwer untergwegs in ganz, ganz weit weg ;)

id und menge reicht!

 

 

Benutzerebene 4
Abzeichen +2

Danke! OK, leider der gleiche Bug wie beim Belege Importer: Artikelbeschreibung taucht nicht im Angebot auf. Diese muss ich also im API Client und in Xentral pflegen :(

Benutzerebene 4
Abzeichen +2

Die JSON-API hat leider auch nen Bug:

  {
"kundennummer": "10405",
"artikelliste": [
{
"nummer": "5034",
"menge": 1
}
]
}

Angebot wird zwar angelegt, es wird auch eine Position mit Menge 1 hinzugefügt, aber diese Position hat keine Artikelnummer/Artikelname/Preis. Die selben Nummern mit XML funktionieren.

Benutzerebene 4
Abzeichen +2

Noch ein Bug :(

Die Artikelbeschreibung wird ja leider nicht aus den Stammdaten gezogen; wenn man sie aber aus Xentral exportiert und diese dann dann mit AngebotCreate wieder importiert kommt diese vielsagende Fehlermeldung:

<?xml version="1.0" encoding="UTF-8"?>
<response>
<status>
<action>AngebotCreate</action>
<message>Invalid key (id)</message>
<messageCode>5</messageCode>
</status>
<xml>address not found</xml>
</response>

XML-Input des API-Aufrufs war:

<artikelliste>
<position>
<nummer>1118</nummer>
<menge>1</menge>
<beschreibung>Verschwei&szlig;ung</beschreibung>
</position>
</artikelliste>
<kundennummer>10465</kundennummer>
<projekt>1</projekt>
<status>angelegt</status>

Grund für den Bug: XML-Entities mit Namen (z.B. &szlig; für ß) werden von Xentral exportiert aber werden beim API-Aufruf nicht verstanden. Der entsprechende Zahlencode &#223; würde funktionieren.

Aber das bedeuted, dass ich alle von Xentral exportierten Daten erst umkodieren muss :(

Benutzerebene 4
Abzeichen +2

Und der schlimmste Bug bis jetzt:

Angebot kann nicht freigegeben werden, weil es angeblich bereits freigegeben ist. #159923

Wahrscheinlich der gleiche Bug wie beim Belege-Importer #155591.

Antworten