Grundsätzliche Frage(n) zur API Nutzung

Hallo zusammmen,

ich bin gerade dabei einen OnlineShop per API an sevDesk anzubinden. Jetzt stellen sich mir aber einige grundsätzliche Fragen zum korrekten Ablauf einer solchen Anbindung.

Meine Grundidee war/ist, bei einer Bestellung aus dem Shop die entsprechenden Daten an sevDesk zu übermitteln. D.h. check ob Kunde in sevDesk existiert, sonst neu anlegen (funktioniert), ggf. noch Adresse zum Kunden anlegen (funktioniert). Dann die Shopbestellung als Angebot anlegen und die einzelnen Produkte zum Angebot hionzufügen, klappt per API soweit auch und auch die Umwandlung vom Angebot zum Auftrag scheint zu funktionieren. ABER …

  1. wenn ich mich dann bei sevDesk anmelde, sehe ich keine Produkte beim Angebot (Summe stimmt), sondern erst beim Auftrag, ist das korrekt?!?
  2. Außerdem ist mir nicht möglich aus dem Auftrag (oder Angebot) eine Rechnung zu erzeugen, weder im BackEnd bei sevDesk noch über die API?!

Nachdem ich mich hier im Forum ein wenig umgeschaut habe, fällt mir außerdem noch auf, das die meisten User hier mit der API wohl gar nicht erst mit Angeboten/Aufträgen arbeiten, sondern direkt die Rechnung(en) bei sevDesk erzeugen.

  1. Daher stellt sich für mich die Frage, ist mein Vorgehen evtl. grundsätzlich der falsche Ansatz oder habe ich etwas übersehen?! Für Ideen, Anmerkungen, Hinweise und gern auch mit Zaunpfahl wäre ich echt dankbar, ich bin momentan ein wenig überfragt?!

Vielen Dank

Ein Angebot anzulegen um daraus eine Rechnung zu erzeugen ist für einen normalen B2C Online Shop meiner Meinung nach Overkill. Normale Rechnungen zu erzeugen würden hier genügen und reduziert auch deutlich die Komplexität der Integration.

Falls du den aktuellen Workflow beibehalten möchtest, kannst du aus Orders direkt eine Invoice per
[POST] /v1/Invoice/Factory/createInvoiceFromOrder erstellen:

{
   order: {
      id: <id>,
      objectName: "Order"
   },
   optArray: null,
   type: "percentage",
   amount: 100
}

Supi, das hilft doch schon mal enorm weiter, vielen Dank dafür.

Allerdings habe ich jetzt noch zwei „Features“ :wink:

Zum einen bekomme ich keine korrekte Auftragsnummer?! „Order/Factory/getNextOrderNumber“ mit dem order_type „AB“ sorgt leider nur dafür, dass die Angebotsnummer sich nochmal erhöht und so in Zweierschritten hochzählt. Das wäre aber m.E. zu vernachlässigen.

Zum Anderen muss ich einen ggf. mal einen Rabatt (discount) mit übergeben. Das scheint mit der „createInvoiceFromOrder“ nicht zu funktionieren, oder? Muss ich dafür echt ein PUT auf die Invoice machen und die bestehende Rechnung komplett updaten? Laut Doku (sevDesk - InvoiceAPI) wären dann dort wieder sämtliche Felder „required“, obwohl ja eigentlich vorhanden, es geht ja „nur“ um ein Update einer bestehenden Rechnung, oder was sehe ich hier falsch?!

Bei getNextOrderNumber muss in dem Fall useNextNumber auf False gesetzt werden.

createInvoiceFromOrder erlaubt nur das Erstellen von Normalen, Teil bzw. Abschlagsrechnungen über das „amount“ Feld in Prozent. Ist letztendlich aber kein Rabatt. Die Invoice wird als Entwurf angelegt, hier muss dann anschließend der Rabatt gesetzt werden. Ist letztendlich ähnlich zum User-Workflow im UI.

Rabatt kann über PUT gesetzt werden. Hier muss letztendlich nur das Feld übergeben werden, dass tatsächlich geändert werden soll und nicht das gesamte Dokument.

Vielen Dank erst mal für die rasche und kompetente Hilfe.

Aber was die getNextOrderNumber angeht, ist es bei mir egal, ob true/false bei useNextNumber, es wird immer nur eine neue Angebotsnummer erstellt, beim Auftrag bleibt die Nummer immer auf dem Anfangswert. Aber wie gesagt, das ist denke ich mal zu vernachlässigen.

Mehr Sorgen macht mir die Sache mit dem Rabatt, denn ich will ja kein Skonto einrichten, sonder muss wohl mit „discountSave“ arbeiten, aber das klappt beim update (PUT) irgendwie nicht. Hatte das mit folgendem Array probiert (sollen 10 EUR auf die gesamte Bestellung sein):

'discountSave' => array('discount' => '1', 'text' => 'Kundengruppen Rabatt', 'percentage' => '0', 'value' => '10', 'objectName' => 'Discounts', 'mapAll' => 'true' )

Es kommt zwar kein Fehler zurück, aber ein Rabatt wird leider nicht eingerichtet!?

Außerdem ist mir noch nicht ganz klar, wie ich die Versandkosten abbilde? Habe ich da etwas übersehen?

1 „Gefällt mir“

getNextOrderNumber gibt die nächste freie Nummer im aktuellen Nummernkreis, es wird keine Nummer bei einem Angebot oder Invoice geändert.

Um invoicePos bzw. discountPos zu editieren, kann entweder die Deprecated API verwendet werden (Nicht Empfohlen) oder /v1/Invoice/Factory/saveInvoice.

Das würde so aussehen:
[POST] /v1/Invoice/Factory/saveInvoice

{
  'invoice': {
    'id': <id>',
    'objectName': 'Invoice'
  },
  "discountSave": [
    {
      "discount": true,
      "text": "DISCOUNT",
      "percentage": false,
      "value": "<SUMME>",
      "isNet": false,
      "objectName": "Discounts",
      "mapAll": true
    },
    {
      "discount": false,
      "text": "VERSANDKOSTEN",
      "percentage": false,
      "value": "<SUMME>",
      "isNet": false,
      "objectName": "Discounts",
      "mapAll": true
    }
  ]
}

Ist zwar etwas unintuitive, aber du kannst Versandkosten über „Surcharges“ hinzufügen, wenn keine normale Rechnungsposition gewünscht. Entsprechend ein negativer Discount. Wichtig ist „isNet“ auf false zu setzen, sonst wird die Umsatzsteuer automatisch auf die Position gerechnet.

Sorry, aber ich komm nicht klar?!?! Wenn ich folgendes Array:

Array
(
    [invoice] => Array
        (
            [id] => 33681342
            [objectName] => Invoice
        )

    [discountSave] => Array
        (
            [discount] => 1
            [text] => Rabatt Kundengruppe
            [percentage] => 0
            [value] => 10
            [isNet] => 0
            [objectName] => Discounts
            [mapAll] => 1
        )

)

an die „Invoice/Factory/saveInvoice“ schicke, kommt folgende Fehlermeldung zurück: discountSave expected array with ‚id‘ and ‚objectName‘. string given

Baue ich das Array so auf:

Array
(
    [invoice] => Array
        (
            [id] => 33681342
            [objectName] => Invoice
            [discountSave] => Array
                (
                    [discount] => 1
                    [text] => Rabatt Kundengruppe
                    [percentage] => 0
                    [value] => 10
                    [isNet] => 0
                    [objectName] => Discounts
                    [mapAll] => 1
                )

        )

)

läuft zwar alles sauber durch, aber es wird kein Rabatt angelegt?!

discountSave muss eine Liste von Dictionaries/Maps sein.

??? Und das heißt bitte was? Wie muss ein passendes Array dafür aussehen?

EDIT: Alles klar, so muss das Array aussehen:

Array
(
    [invoice] => Array
        (
            [id] => 33681342
            [objectName] => Invoice
        )

    [discountSave] => Array
        (
            [0] => Array
                (
                    [discount] => 1
                    [text] => Rabatt Kundengruppe
                    [percentage] => 
                    [value] => 10
                    [isNet] => 
                    [objectName] => Discounts
                    [mapAll] => 1
                )

        )

)

Hierzu hab ich noch mal eine Frage, was bedeutet aktueller Nummernkreis? Ich habe das so verstanden: ein Aufruf von „Order/Factory/getNextOrderNumber?order_type=AB&use_next_number=false“ sollte doch die nächste Nummer aus dem Kreis „AB“ (Auftragsbestätigung) liefern, oder nicht?! Denn bei mir kommt egal bei welchem order_type immer nur die nächste Angebotsnummer (AN) zurück?!

Außerdem noch eine Frage zu Lieferscheinen, kann ich die auch aus einer „normalen“ Order (AN) erzeugen, so wie die Auftragsbestätigung (Order/Factory/createContractNoteFromOrder) oder die Rechnung (Invoice/Factory/createInvoiceFromOrder)? Wenn ja, wie :wink: und wenn nein, heißt das dann, ich muss den Lieferschein (und auch die Produkte dazu) als eigene Order mit dem Bezug zum Angebot über origin anlegen?

Und zum Schluss nochmal zum „discountSave“, funktioniert das auch mit der Order (also für die Auftragsbestätigung)?

Ich habe getNextOrderNumber jetzt etwas getestet und es scheint tatsächlich nicht so zu funktionieren wie es soll oder zumindest meiner Interpretation nach.

Grundsätzlich dachte ich es gibt immer die nächste „freie“ Nummer im Nummernkreis. Das verhält sich aber nicht so, sondern es wird die letzte verwendete zurückgegeben (useNextNumber=false) oder es wird bei jedem einzelnen Aufruf eine neue Nummer erzeugt (letztendlich um eins erhöht), egal ob vergeben oder nicht (useNextNumber=true). @Eduard_von_sevDesk Bug?

Hierzu hab ich noch mal eine Frage, was bedeutet aktueller Nummernkreis? Ich habe das so verstanden: ein Aufruf von „Order/Factory/getNextOrderNumber?order_type=AB&use_next_number=false“ sollte doch die nächste Nummer aus dem Kreis „AB“ (Auftragsbestätigung) liefern, oder nicht?! Denn bei mir kommt egal bei welchem order_type immer nur die nächste Angebotsnummer (AN) zurück?!

Die Parameternamen sind falsch. orderType und useNextNumber sind korrekt.

Außerdem noch eine Frage zu Lieferscheinen, kann ich die auch aus einer „normalen“ Order (AN) erzeugen, so wie die Auftragsbestätigung (Order/Factory/createContractNoteFromOrder) oder die Rechnung (Invoice/Factory/createInvoiceFromOrder)? Wenn ja, wie :wink: und wenn nein, heißt das dann, ich muss den Lieferschein (und auch die Produkte dazu) als eigene Order mit dem Bezug zum Angebot über origin anlegen?

[POST] /v1/Order/Factory/createPackingListFromOrder

{
   order: {
      id: <id>,
      objectName: "Order",
   },
   optArray: null,
   optAddress: null
}

Und zum Schluss nochmal zum „discountSave“, funktioniert das auch mit der Order (also für die Auftragsbestätigung)?

Das funktioniert wie bei einer Invoice über discountSave. Lediglich der API Endpunkt ändert sich auf /v1/Order/Factory/saveOrder

Vielen Dank für die tolle Unterstützung!!!

Jetzt läuft bei meinem Projekt erst mal alles wie ich es mir vorgestellt habe, jetzt kann man es nach und nach perfektionieren :wink:

1 „Gefällt mir“