Erweiterte Preise per Rest API

Guten Tag,

Wie erstelle ich über die Shopware 6 Rest API eine erweiterte Preisregel für ein Produkt? Ich möchte für Händler die Preise importieren und dies wird ja in Shopware über die erweiterten Preise als eigene Regel gelöst.

Ich hätte mir hierzu auch schon eine Regel im Backend angelegt, per API angezeigt und das Json 1 zu 1 nachgebaut. Allerdings funktioniert es so über die “listingPrices” nicht.
Fehler: Internal Server Error [detail] => Price rules json field will be set by indexer

Mfg,
Dominik

Hallo, ich habe das so gelöst:

{
   "prices":[
      {
         "productId":"e8b593b74deb42499e847c8e094c162c",
         "ruleId":"047e07702f6a4c66a38e04adc21e4845",
         "price":[
            {
               "currencyId":"b7d2554b0ce847cd82f3ac9bd1c0dfca",
               "net":16.8,
               "linked":true,
               "gross":19.99
            }
         ],
         "quantityStart":1,
         "quantityEnd":12
      },
      {
         "productId":"e8b593b74deb42499e847c8e094c162c",
         "ruleId":"047e07702f6a4c66a38e04adc21e4845",
         "price":[
            {
               "currencyId":"b7d2554b0ce847cd82f3ac9bd1c0dfca",
               "net":13.44,
               "linked":true,
               "gross":15.99
            }
         ],
         "quantityStart":13
      }
   ]
}

 

1 „Gefällt mir“

Das hat bei mir leider nicht funktioniert, welchen Endpoint und welche Methode hast du hier verwendet.

Ich habe den Endpoint product mit der Methode POST verwendet.

 

Welche Fehlermeldung hast du denn erhalten ? Endpoint ist bei mir ebenfalls product… ruleId und currencyId muss natürlich an deinen Shop angepasst werden. 

Ich poste in der Regel über die sync API, dann sind das nicht so viele Calls… das ist deutlich performanter… 

 

Fehlermeldung: 

 [code] =\> 0 [status] =\> 500 [title] =\> Internal Server Error [detail] =\> Cannot unset string offsets [file] =\> /var/www/html/vendor/shopware/core/Framework/DataAbstractionLayer/FieldSerializer/PriceFieldSerializer.php [line] =\> 48

 

Mein Post sieht folgendermaßen aus:

 

 [action] =\> upsert [entity] =\> product [payload] =\> Array ( [0] =\> stdClass Object ( [categories] =\> Array ( [0] =\> stdClass Object ( [id] =\> f2c4740c5f3c44d9b7c61d22ad391802 ) ) [productNumber] =\> Artikelnr [id] =\> 74f098bb72c24f58aafaa651fe134e09 [description] =\> Testdescription [keywords] =\> [name] =\> abcdefg [stock] =\> 0 [taxId] =\> 39e11bdb0d1f4305b7a890fd4cf08579 [price] =\> Array ( [0] =\> stdClass Object ( [currencyId] =\> b7d2554b0ce847cd82f3ac9bd1c0dfca [gross] =\> xxx [net] =\> yyy [linked] =\> 1 [listPrice] =\> stdClass Object ( [currencyId] =\> b7d2554b0ce847cd82f3ac9bd1c0dfca [gross] =\> aaa [net] =\> bbb [linked] =\> 1 ) ) ) [prices] =\> Array ( [0] =\> stdClass Object ( [quantityStart] =\> 1 [ruleId] =\> 403bd142ac0b49fd9f6f60bbeeb6b126 [price] =\> stdClass Object ( [currencyId] =\> b7d2554b0ce847cd82f3ac9bd1c0dfca [gross] =\> 609.75 [net] =\> 512.39 [linked] =\> 1 ) ) ) ) )

Was ich so als Unterschied sehe ist, dass du die entity [price] nicht als array übergibst. 

in meinem funktionierenden Beispiel ist das so: 

Eckige Klammer definiert einen Array… geschweifte ein Objekt.  

Bei dir fehlt nach price der Array-Beginn. 

"price":[
            {
               "currencyId":"b7d2554b0ce847cd82f3ac9bd1c0dfca",
               "net":13.44,
               "linked":true,
               "gross":15.99
            }
         ],

 

 

 

2 „Gefällt mir“

Super hat geklappt, das war das Problem:

 [prices] =\> Array ( [0] =\> stdClass Object ( [quantityStart] =\> 1 [ruleId] =\> 403bd142ac0b49fd9f6f60bbeeb6b126 [price] =\> stdClass Object ( [currencyId] =\> b7d2554b0ce847cd82f3ac9bd1c0dfca [gross] =\> 609.75 [net] =\> 512.39 [linked] =\> 1 ) ) )

Problem ist nun das dabei immer wieder ein Preis dazukommt, gibt es eine Möglichkeit alle vorhandenen vorher zu entfernen ohne jeden einzelnen Preis anzupacken, da das ganze über die sync-API läuft?

Problem ist nun das dabei immer wieder ein Preis dazukommt, gibt es eine Möglichkeit alle vorhandenen vorher zu entfernen ohne jeden einzelnen Preis anzupacken, da das ganze über die sync-API läuft?

Dazu habe ich leider auch noch keinen Weg gefunden und auch hier im Forum eine Anfrage an die Wissenden gestellt… aber leider noch keine Antwort erhalten. 

https://forum.shopware.com/discussion/70342/staffelpreise-aktualisieren#latest

Ich hole mir tatsächlich derzeit immer alle IDs der Preise und lösche die zunächst, bevor ich sie neu schreibe… in meinem Fall sogar noch etwas aufwändiger, weil es sich bei mir wirklich um Staffelpreise aus 6 Preisregeln handelt…  

Machst du das auch über die sync-API? 

Hast du da evtl. ein Beispiel für mich?

Ja, habe ich :slight_smile:

Das hier schicke ich als Payload über die sync API… allerdings hole ich mir vorher über einen gesamten Dump die Preis-IDs der betroffenen zu aktualisierenden Einträge und speichere mir die zur Verarbeitung in einem record. 

Letztlich schicke ich in einem Block die deletes und dann anschliessend die inserts … alles in einem Payload. 

Hier mein Payload:

{
   "delete-prices-10013363-1":{
      "entity":"product_price",
      "action":"delete",
      "payload":[
         {
            "productId":"f6d7a38eea064818bbba1b8dd0b7328d",
            "id":"5f8f5991f3ad4785a8aea276a08e0a2a"
         },
         {
            "productId":"f6d7a38eea064818bbba1b8dd0b7328d",
            "id":"e05a760ac0654823a53d41fa57207056"
         },
         {
            "productId":"f6d7a38eea064818bbba1b8dd0b7328d",
            "id":"e1515f82dab3445b88957adba9d0c5ba"
         }
      ]
   },
   "insert-prices-10013363-1":{
      "entity":"product_price",
      "action":"upsert",
      "payload":[
         {
            "productId":"f6d7a38eea064818bbba1b8dd0b7328d",
            "ruleId":"92c24dd21c13419c8275a65f48d19975",
            "price":[
               {
                  "currencyId":"b7d2554b0ce847cd82f3ac9bd1c0dfca",
                  "net":1.79,
                  "linked":true,
                  "gross":2.1301
               }
            ],
            "quantityStart":1,
            "quantityEnd":71
         },
         {
            "productId":"f6d7a38eea064818bbba1b8dd0b7328d",
            "ruleId":"92c24dd21c13419c8275a65f48d19975",
            "price":[
               {
                  "currencyId":"b7d2554b0ce847cd82f3ac9bd1c0dfca",
                  "net":1.69,
                  "linked":true,
                  "gross":2.0111
               }
            ],
            "quantityStart":72,
            "quantityEnd":215
         },
         {
            "productId":"f6d7a38eea064818bbba1b8dd0b7328d",
            "ruleId":"92c24dd21c13419c8275a65f48d19975",
            "price":[
               {
                  "currencyId":"b7d2554b0ce847cd82f3ac9bd1c0dfca",
                  "net":1.49,
                  "linked":true,
                  "gross":1.7731
               }
            ],
            "quantityStart":216,
            "quantityEnd":null
         }
      ]
   },
   "delete-prices-10013363-3":{
      "entity":"product_price",
      "action":"delete",
      "payload":[
         {
            "productId":"f6d7a38eea064818bbba1b8dd0b7328d",
            "id":"a5b72035697d40bb8e67da9370f66c6c"
         }
      ]
   },
   "insert-prices-10013363-3":{
      "entity":"product_price",
      "action":"upsert",
      "payload":[
         {
            "productId":"f6d7a38eea064818bbba1b8dd0b7328d",
            "ruleId":"b689215513f94d199e112248173557c5",
            "price":[
               {
                  "currencyId":"b7d2554b0ce847cd82f3ac9bd1c0dfca",
                  "net":1.49,
                  "linked":true,
                  "gross":1.7731
               }
            ],
            "quantityStart":1,
            "quantityEnd":null
         }
      ]
   },
}

Hier noch der Link zur offiziellen Doku, wo auch beschrieben steht, warum ich keys verwende… wie “insert-prices-10013363-3”

https://docs.shopware.com/en/shopware-platform-dev-en/admin-api-guide/sync-api

Grüße

Holger 

3 „Gefällt mir“

Perfekt,

wusste nicht dass man product_price auch als entity mit der Sync-API verwenden kann

@hloettgen‍

Wenn ich das so mache wie du in dem /product POST Aufruf, dann kommt der fehler, dass price nicht leer sein darf

was muss in price rein?

Gruß

balram

@balram‍

Poste doch bitte mal deinen Payload… dann sehen wir bestimmt, wo das Problem sein kann… 

„price“ ist ja in jedem Fall ein array… 

Grüße

Holger 

Hallo Holger,

Es funktioniert jetzt. man muss den “price” array hinzufügen habe ihn vorher weggelassen, da ich ja schon “prices” hatte. man braucht den für “price” aber trotzdem.

Gruß

balram

Meine aktuelle Alternative: man kann die ID definieren und dann einfach immer bei „upsert“ mitgeben, ich generiere die ID einfach aus productid+ruleid:

Python:

sync_payload = {
    "insert-prices-10013363-1":{
        "entity":"product_price",
        "action":"upsert",
        "payload":[
            {
                "id": hashlib.md5(''.join([product_id, price_rule])).hexdigest(),
                "productId": "6aa0acedfadb3be0cf2c70d1f500978b",
                "ruleId": '687a70c2c58e4e6f988294d65d4b1ef9',
                "price": [{
                    "gross": gross,
                    "net": net,
                    "currencyId": "b7d2554b0ce847cd82f3ac9bd1c0dfca",
                    "linked": True,
                }],
                "quantityStart": 1,
            }
        ]
    },
}

Falls man Preise löschen möchte geht das natürlich nicht, und die Lösung von hloettgen ist besser, aber rein zum Erstellen und Aktualisieren ohne Duplikate scheint es auch so zu klappen.

1 „Gefällt mir“

@phhe , @hloettgen wenn ich eure Methode nachbaue, werden bei mir die „delete“ methoden einfach nicht ausgeführt, jedoch kommt immer wieder eine neue Regel hinzu :frowning:

ich nutze /api/_action/sync und sende folgendes JSON:

{

    "delete-pricerules":{

        "entity": "product_price",

        "action": "delete",

        "payload": [

            {

                "productId": "cef7c97a8e76452e9611a5fd72f5529f",

                "ruleId": "7b6a7b273f064c41b58c9c552ff8cd3e"

            },

            {

                "productId": "cef7c97a8e76452e9611a5fd72f5529f",

                "ruleId": "7b6a7b273f064c41b58c9c552ff8cd3e"

            },

            {

                "productId": "cef7c97a8e76452e9611a5fd72f5529f",

                "ruleId": "7b6a7b273f064c41b58c9c552ff8cd3e"

            }

        ]

    },

    "upsert-pricerules":{

        "entity": "product_price",

        "action": "upsert",

        "payload": [

            {

                "productId": "cef7c97a8e76452e9611a5fd72f5529f",

                "ruleId": "7b6a7b273f064c41b58c9c552ff8cd3e",

                "price":[

                    {

                    "currencyId": "b7d2554b0ce847cd82f3ac9bd1c0dfca",

                    "net": 100.00,

                    "linked": true,

                    "gross": 119.00

                    }

                ],

                "quantityStart": 1

            }

        ]

    }

}

Auf dieses Payload erhalte ich folgenden Response:

{
    "success": true,
    "data": {
        "delete-pricerules": {
            "result": [
                {
                    "entities": {
                        "product": [
                            "cef7c97a8e76452e9611a5fd72f5529f"
                        ]
                    },
                    "errors": []
                },
                {
                    "entities": {
                        "product": [
                            "cef7c97a8e76452e9611a5fd72f5529f"
                        ]
                    },
                    "errors": []
                },
                {
                    "entities": {
                        "product": [
                            "cef7c97a8e76452e9611a5fd72f5529f"
                        ]
                    },
                    "errors": []
                }
            ],
            "extensions": []
        },
        "upsert-pricerules": {
            "result": [
                {
                    "entities": {
                        "product": [
                            "cef7c97a8e76452e9611a5fd72f5529f"
                        ],
                        "product_price": [
                            "3a510b2e5ccc46ce936a72200c6240d6"
                        ]
                    },
                    "errors": []
                }
            ],
            "extensions": []
        }
    },
    "extensions": []
}

Ich erhalte eine 200er Antwort des Servers, jedoch kommt nur eine neue Regel hinzu und die bereits erstellten werden einfach addiert…

Könnt ihr mir da Abhilfe verschaffen?

MfG

Hallo @yolomir,

ich glaube, du hast da ein Verständnisproblem mit ruleID und PreisID.
Bevor ich Preise neu schreibe, lösche ich die Preise… aber eben nicht über die ruleID, sondern über productID und der id des Preises. Das heißt, ich lese vom Artikel erst mal alle vorhandenen Preise und die entsprechenden IDs aus… mit denen starte ich dann einen Löschvorgang, bevor ich neue Preise hochlade.
Mein JSON würde dann mit deinen Daten eher so aussehen:


"delete-prices":{
        "entity": "product_price",
        "action": "delete",
        "payload": [
            {
                "productId": "cef7c97a8e76452e9611a5fd72f5529f",
                "id": "7b6a7b273f064c41b58c9c552ff8cd3e"
            },
            {
                "productId": "cef7c97a8e76452e9611a5fd72f5529f",
                "id": "7b6a7b273f064c41b58c9c552ff8cd3e"
            },
            {
                "productId": "cef7c97a8e76452e9611a5fd72f5529f",
                "id": "7b6a7b273f064c41b58c9c552ff8cd3e"
            }
        ]

Wobei du als id immer die ruleID hast… deshalb stimmt das Beispiel inhaltlich nicht… es muss da natürlich die id des Preises stehen und nicht „7b6a7b273f064c41b58c9c552ff8cd3e“.

Herzliche Grüße
Holger

Hey @hloettgen :slight_smile: ,

Du hattest recht! :slight_smile: hab deine Erklärung nun perfekt verstanden und konnte mein Problem beheben :partying_face:

Vielleicht solltest du zukünftig die Doku für SW schreiben :smiley:

Ich bedanke mich herzlich für deine Hilfe und wünsche dir nur das Beste!

MfG Louis

@yolomir Danke für die herzliche Rückmeldung… :blush:

Hallo, ich verwende ebenfalls den Weg von dir hloettgen um die Preise in den Preisregeln der Artikel zu aktualisieren. Damit nicht jedes mal eine neue Rule angelegt wird habe ich eine rule angelegt und die ID nutze ich nun für alle anderen Artikel hardgecoded. Jetzt habe ich das seltsame Verhalten, dass wenn ich einen Artikel aktualisiere die Preisregeln dem Artikel hinterlegt werden. Das ist auch alles Super und soll so.
Wenn ich jetzt aber eine Reihe von Artikeln aktualisiere, alle jeweils immer mit einem http call also 50 Artikel 50 http calls mit dem selben Code, hat keiner die Preisregeln hinterlegt. Die anderen Werte wie Artikelbeschreibung oder sonstiges werden aktualisiert. Jemand eine Idee woran das liegen kann?