Admin-API: Produkt mit Varianten anlegen

wie legt man am einfachsten ein Produkt mit Varianten an über die Admin-API (JSON)?

Ich hab schon den Parameter properties gefüllt, das kommt auch im Shop korrekt an.

Außerdem habe ich den Parameter _ options _gesetzt, aber das macht keinen Unterschied.

Muss man hier irgendwie mit Parent-ID arbeiten? Falls ja, wo gebe ich dann Stock, Price & Co. der Varianten an?

Muss man hier mit dem Call für /product-configurator-setting arbeiten?

Hi FloC3,

ein gesamtes Variantenprodukt besteht aus dem Produkt-Container, von dem alle Varianten dann ableiten.
Der Container sollte hierbei die properties und configuratorSettings beinhalten, sodass die properties vererbt und über configuratorSettings die möglichen Variatenoptionen definiert werden. 

Die Varianten selbst sind eigenständige Produkte und müssen den Container als parentId beinhalten, sodass diese von dem Container alle Felder erben (z.B. properties, stock etc.). Außerdem sollten die Varianten die options beinhalten, darüber wird definiert welche Optionen dies Variante umfasst (z.B. rot in XL).

Somit müsste man den Container und dessen Varianten einzeln anlegen und über die genannten Verbindungen mit einander verknüpfen. Man kann aber auch, um API-Calls zu sparen das gesamte Variantenprodukt (Container und alle Variaten) in einem API-Call anlegen über das Feld children. Generell gillt alle Verbindungen, an denen ein Objekt in der Definitionsdatei (in diesem Fall ProdcutDefinition) hängt, kann per API in demselben Call angelegt werden.

In der Shopware 5 - Migration z.B. legen wir den Container mit der SW5-Hauptvariante in einem Rutsch an, da SW5 kein Container kennt, aber sich dieser aus der Hauptvariante ergibt.

Ich hoffe dies hilft dir weiter. Wenn du nicht genau weißt, wie Struktur der einzelnen Objekte aussieht kannst du immer in die jeweilige Definitiondatei schauen.

Gruß

Krispin

1 „Gefällt mir“

Hallo @Krispin‍,

erstmal Danke für deine Tipps.

Meinst du den Parent-Artikel, wenn du von “Container” sprichst?

was muss man denn bei “configuratorSettings” angeben?

 

ich fasse zusammen, bitte korrigier mich wenn ich falsch liege

  1. ich lege den Parent-Artikel an (mit properties)
  2. ich lege alle einzelnen Varianten als eigenständige Artikel mit options und mit parentId des Parent-Artikels von 1. an
  3. ich muss configuratorSettings beim Parent-Artikel an. Was muss ich hier angeben?
  4. fertig?

 

ps: wo find ich denn diese Definitions-Datei? Wenn ich meine Source durchsuche nach “ProdcutDefinition” finde ich nix…

 

EDIT: ich kriegs einfach nicht hin… muss eine Variante genauso aufgebaut sein wie ein normales Produkt? (Texte, Preise, Steuer, Titel, etc.)?

habe nun versucht, sie einzeln anzulegen. Also erst ein normales Produkt und dann die Varianten mittels parentId zuzuweisen.

{"errors":[{"code":"0","status":"500","title":"Internal Server Error","detail":"Warning: Invalid argument supplied for foreach()","meta":{"trace":
/core\/Framework\/DataAbstractionLayer\/Write\/WriteCommandExtractor.php","line":152,"function":"encode","class":"Shopware\\Core\\Framework\\DataAbstractionLayer\\FieldSerializer\\PriceFieldSerializer","type":"-\u003E","args":[{"storageName":"price","propertyMapping":[],"default":null,"flags":[{},{}],"propertyName":"price","extensions":[]},{},{},{}]},

wieso gibts denn eigentlich keine besch**** Doku für die API… gefühlt weiß kein Mensch wie das Zeug funktioniert, wenn man sich so im Forum umschaut…

Hi FloC3,

genau, ich meine mit Container das Parent-Produkt (Hinweis: Der Container ist kein kaufbares Produkt, nur die Varianten).

  1. Genau, Parent-Produkt mit properties und configuratorSettings.

  2. Richtig, die Variante ist auch wiederrum ein normales Produkt, wo einfach die parentId mit angegeben wird.

  3. Ein Beispiel des Inhaltes des configuratorSettings-Feldes innerhalb eines JSON-Arrays vom Product:

    “configuratorSettings”:[
    {
    “id”:“31ef635390e5447ba66b33dbb33f6f83”,
    “productId”:“d32f66e9e28045b08ea97f5efee860e9”,
    “optionId”:“ed9e5fa44983470286ceabc6d389945d”
    },
    {
    “id”:“47d80738fe8548b093b05abf2d4f5b4e”,
    “productId”:“d32f66e9e28045b08ea97f5efee860e9”,
    “optionId”:“a748a10abf2041159e3e9ad464a82815”
    }
    ],

Die Definitionsdatein sind in platform zu finden. Z.B.:

In den Definitionsdateien findet man alle Felder, die man per API / DAL - Call angeben kann, hier sieht man auch welche Pflichtfelder es gibt.
Eine andere Möglichkeit ist in die Swagger-Dokumentation von uns zu schauen, “/api/v1/_info/swagger.html” bei deinem SW6-Shop (FriendsOfShopware haben auch eine öffentliche: https://api-doc.friendsofshopware.com/ bereitgestellt). In der Swagger-Doku findest du eigentlich alles was die API kann bzw. die wie Struktur der Calls aussehen muss. Der Hinweis auf die Swagger-Doku steht auch in der SW6-Dokumentation: https://docs.shopware.com/en/shopware-platform-dev-en/admin-api-guide/writing-entities?category=shopware-platform-dev-en/admin-api-guide#routes ;)

Ich hoffe dies kann dir weiterhelfen.

Gruß

Krispin

die Swagger-Doku kenne ich schon, allerdings ist da natürlich auch keine Erklärung dabei, was welches Feld bedeutet und wofür es gut ist…

 

Hi FloC3,

die id ist die UUID für das ConfiguratorSetting-Item, also die Relation selbst, diese wird automatisch bestimmt, wenn du keine angibst.
Die productId ist die UUID des Produktes, wenn du das ConfiguratorSetting mit einem Produkt schreibst, brauchst du auch dies nicht angeben, da das DAL das Produkt schon kennt. Somit bleibt dir dann nur noch die optionId. Die OptionId ist die UUID der Option, die du mit dem Produkt über das ConfiguratorSetting-Item verknüpfen willst.

Ich hoffe das soweit verständlich.

Gruß

Krispin

Hi,

das hat mir jetzt schon mal viel weiter geholfen. AIm Backend sieht das jetzt gut aus. Allerdings ist im Frontend nur die Hauptvariante sichtbar. Man sieht auch nicht den Varianten-Umschalter. Hab dann im Backend die Varianten nochmal generieren lassen, dann siehts im Frontend gut aus.

fehlt also noch irgendwas was?

"id" => md5("1233243"),
"name" => "TEST",
"taxId" => "8ea962e6a8954b589b0eaf496fdf7c80",
"stock" => 1,
"price" => [
    [
        "net" => 1,
        "gross" => 1.16,
        "currencyId" => "b7d2554b0ce847cd82f3ac9bd1c0dfca",
        "linked" => true
    ]
],
"manufacturerId" => "a5e9e8cd976e4304a52b5653d620479f",
"productNumber" => "ABCDEFG",
"properties" => [
    [
        "id" => "23a294da4839daf7a4691a76dbafe12c",
        "group" => [
            "id" => "70b3ae053a0fc490dbb1ea05642b5ef8"
        ]
    ],
    [
        "id" => "97dee52295d1d9ed1780d89961c4b718",
        "group" => [
            "id" => "70b3ae053a0fc490dbb1ea05642b5ef8"
        ]
    ]
],
"children" => [
    [
        "parentId" => md5("1233243"),
        "name" => "TEST.1",
        "taxId" => "8ea962e6a8954b589b0eaf496fdf7c80",
        "stock" => 45,
        "price" => [
            [
                "net" => 1,
                "gross" => 14.16,
                "currencyId" => "b7d2554b0ce847cd82f3ac9bd1c0dfca",
                "linked" => true
            ]
        ],
        "manufacturerId" => "a5e9e8cd976e4304a52b5653d620479f",
        "productNumber" => "ABCDEFG.1",
        "options" => [
            [
                "id" => "23a294da4839daf7a4691a76dbafe12c",
                "group" => [
                    "id" => "70b3ae053a0fc490dbb1ea05642b5ef8"
                ]
            ]
         ]
    ],
    [...]
]

Kategorien und Sales-Channel-Visibility hab ich schnell über das Backend ergänzt, sollte ja gehen. 

Hier die Ansicht im Backend:

und hier dann die Ansicht im Frontend. Wie man sieht, fehlt der Varianten-Umschalter für Größe 42/44

@Krispin‍ vielleicht kannst du mir mit dem Problem noch helfen, dann hätten wirs endlich  hinter uns :slight_smile:

Hi FloC3,

sehe jetzt in dem JSON-Array keinen Punkt “configuratorSettings”, hast du das vergessen mit in das Beispiel zu packen, oder gar nicht bei dem Request mitgeschickt?

Gruß

Krispin

1 „Gefällt mir“

hi @Krispin‍ ,

 

Gott… ich war wohl Freitag dann einfach nicht mehr denkfähig… da diskutiert man lang über das Thema “configuratorSettings” und dann vergess ich es in meinem Test-Call … DANKE! Jetzt läuft das alles.

Muss es jetzt nur noch in den regulären Schnittstellen-Abgleich packen. Vielen vielen Dank dir für die Hilfe!

Hi FloC3,

ach, kein Problem, kennt man ja selbst :wink:
Hauptsache es funktioniert jetzt  Thumb-Up
Gern geschehen.

Gruß

Krispin

das war bei SW5 aber echt irgendwie einfacher oder?

Hi FloC3,

das Anlegen vielleicht, aber dafür gabe es ja auch keine Vererbung etc.

Gruß

Krispin

ich weiß nicht was jetzt anders ist, aber jetzt funktionieren die Varianten nicht mehr …

{"errors":[{"status":"400","code":"FRAMEWORK__WRITE_MALFORMED_INPUT","title":"Bad Request","detail":"Expected data to be array.","meta":{"parameters":[]}}]}

array(17) {
  ["parentId"]=>
  string(32) "9b22f152d5352d5a23cdad0785d86fec"
  ["options"]=>
  array(1) {
    [0]=>
    array(2) {
      ["id"]=>
      string(32) "2111231d12800b0aabd5d99f64412660"
      ["group"]=>
      array(1) {
        ["id"]=>
        string(32) "70b3ae053a0fc490dbb1ea05642b5ef8"
      }
    }
  }
  ["id"]=>
  string(32) "12e06943b2a3ee473e009377e49d82d3"
  ["name"]=>
  string(8) "--------"
  ["active"]=>
  bool(false)
  ["productNumber"]=>
  string(16) "429445 1130 41,5"
  ["ean"]=>
  string(13) "2000002810667"
  ["manufacturerName"]=>
  string(0) ""
  ["taxId"]=>
  string(32) "8ea962e6a8954b589b0eaf496fdf7c80"
  ["purchasePrice"]=>
  float(192)
  ["price"]=>
  array(1) {
    [0]=>
    array(4) {
      ["currencyId"]=>
      string(32) "b7d2554b0ce847cd82f3ac9bd1c0dfca"
      ["gross"]=>
      float(470)
      ["net"]=>
      float(470)
      ["linked"]=>
      bool(true)
    }
  }
  ["stock"]=>
  int(0)
  ["isCloseout"]=>
  bool(true)
  ["deliveryTime"]=>
  string(8) "1-3 Tage"
  ["weight"]=>
  float(0)
  ["deliveryTimeId"]=>
  string(32) "96e284c0f3314a09bb1659828875a08c"
  ["manufacturerId"]=>
  string(32) "a5e9e8cd976e4304a52b5653d620479f"
}

was genau ist daran denn jetzt falsch? Was sollte ein Array sein und ist keines?

Hi FloC3,

anscheinend versucht du es jetzt per Repository und per Upsert oder Insert - Methode, richtig?
Wenn du diese benutzt, geht er davon aus ein Array von Entities zu erhalten, also musst du dein Produkt in ein Array paken. Bei den Repositories kannst du immer mehrere Elemente gleichzeitig erstellen / updaten / löschen und nicht so wie bei der API nur ein Element.

Gruß

Krispin

Hallo @Krispin‍,

hab den Fehler gefunden.

problel war, ich habe ein Feld “deliveryTime” als String mitgeschickt. Das stammte noch vom Import der CSV … intern hab ich das schon umgewandelt in die DeliveryTimeId.

shopware API erwartet aber für deliveryTime zufällig ein Array … darf also das Feld nicht mitsenden

Wir haben eine Applikation, mit der Sie Produkte und Varianten importieren können
https://acceptance.onlineshopconnector.com/

Einfach und snell

Hi FloC3,

stimmt, die DeliveryTime ist eine eigene Relation, die hierfür benötigten Felder kannst du in der DeliveryTimeDefinition finden.

(Felder: ID, name, min, max, unit, name)

Gruß

Krispin

Hallo,

wir müssten vom ERP-System bei Änderungen an den Varianten die Configurator-Settings neu mappen.

Ist das Löschen in product_configurator_setting nur via der Uuid der Association möglich:
{{url}}/api/v3/product/c04ea4ff431a4eabbbaeb4370352652c/configurator-settings/16742d5a9acf4e149d8cea3f2b35bb06

oder gibt es auch eine Möglichkeit (route) via productId und optionID zu löschen z.B., dazu habe ich nichts gefunden. Uns ist im ERP nur die productId und die optionId bekannt.

{
  „productId“: „c04ea4ff431a4eabbbaeb4370352652c“,
  „optionId“: „16742d5a9acf4e149d8cea3f2b35bb06“
}

Product-Options            
GET    
http://shopware.p573257.webspaceconfig.de/api/v3/product/b4b90959f62647e1acddb70a82be31e1/options?_response=basic

DELETE    
http://shopware.p573257.webspaceconfig.de/api/v3/product/b4b90959f62647e1acddb70a82be31e1/options/ebc4ac04ae5d47aea882561967fbf19e?_response=basic

PATCH    
http://shopware.p573257.webspaceconfig.de/api/v3/product/b4b90959f62647e1acddb70a82be31e1?_response=basic
    Body: { „options“: [ { „id“: „ebc4ac04ae5d47aea882561967fbf19e“ }] }