Aktuelle Produktpreis zu ProduktID in Plugin ermitteln schlägt fehl

Eventuell sieht jemand auf Anhieb das Problem, ich sitze hier seit Stunden und versuche diese eigentlich 08/15 Aufgabe bisher erfolglos zu bewältigen, aber in Shopware 6 muss ja alles so lange umgeschichtet und verstrukturiert werden, bis am Ende überhaupt nichts mehr funktioniert…

Ich benötige lediglich den aktuell im Shop gültigen Preis zu einem Produkt, dessen ID ich während des Aufrufs ermittle.

Codeausschnitt:


...

use Shopware\Core\System\SalesChannel\Entity\SalesChannelRepository;

class Subscriber implements EventSubscriberInterface {

    private RequestStack $requestStack;
    private SalesChannelRepository  $productRepository;
    private LineItemFactoryRegistry $factory;
    private CartPersister $persister;
    private CartService $cartService;
    private QuantityPriceCalculator $calculator;
    private ProductListingLoader $proload;

    public function __construct(RequestStack $requestStack, SalesChannelRepository  $productRepository, LineItemFactoryRegistry $factory, CartPersister $persister, CartService $cartservice, QuantityPriceCalculator $calculator, ProductListingLoader $proload) {
        $this->requestStack      = $requestStack;
        $this->productRepository = $productRepository;
        $this->factory           = $factory;
        $this->persister         = $persister;
        $this->cartService       = $cartservice;
        $this->calculator        = $calculator;
        $this->proload           = $proload;
    }

Gefolgt von getSubscribedEvents, etc. etc.

    public function OnCartLoad(CartLoadedEvent $event) :void {

        $context    = $event->getSalesChannelContext();
        $salechannel= $context->getSalesChannelId();
        //$session_id = $this->requestStack->getMainRequest()->getSession()->getId();
        $request    = $this->requestStack->getCurrentRequest();


        ... // Ermitteln der entsprechenden ArtikelID/UUID


        $criteria = new Criteria([strtolower($tmpergarr["artid"])]);
        $criteria->addAssociation('prices');
        $criteria->addAssociation('tax');

        //$product = $this->proload->load($criteria, $context); // Versuch ProductListingLoader
        $product = $this->productRepository->search($criteria, $context)->first();

       die("<pre>".print_r($product->jsonSerialize(),true)."</pre>");

An dieser Stelle spuckt mir Shopware ein riesiges Produkt aus mit dem Ergebnis:

[calculatedPrices:protected] => Shopware\Core\Checkout\Cart\Price\Struct\PriceCollection Object
                        (
                            [extensions:protected] => Array
                                (
                                )

                            [elements:protected] => Array
                                (
                                )

                        )

Daraufhin behaupted Shopware der aktuelle Preis sei der Basispreis, was nicht stimmt, da aufgrund des Subshops / der Standardkundengruppe des Subshops (nicht angemeldet), eigentlich eine Preisrule greiffen müsste und den Preis entsprechend für den Subshop anpassen…

Gehe ich im Shop über das Listing/die Suche auf den Artikel wird mir der korrekte Preis angezeigt.

Gebe ich mir den Kontext aus, finde ich darin sowohl Preisgruppe, Subshop als auch Tax Informationen, es sollte also eigentlich alles vorhanden sein…

Leute, es kann doch nicht angehen, dass selbst von Shopware selbst es einfach niemand schafft, sich hier einmal zu absolut grundsätzlichen Problemen zu äußern?

Den aktuellen Shoppreis eines Artikel in einem Plugin auszulesen sollte doch eigentlich absolute Basisfunktionalität sein. Wie ist es bitte möglich, dass Shopware 6 selbst daran massiv scheitert?

Das gesamte System ist überhaupt nicht mehr Kundenfreundlich, geschweige denn auf Händler ausgelegt, wenn selbst Entwickler damit nicht mehr zurecht kommen.

Ich habe mir den aktuellen SalesChannelContext gedebugged und durchgeschaut, folgende preisrelevante Infos sind gegeben:

          "SalesChannelId" => $context->getSalesChannelId(),
          "CustomerGroupId" => $context->getCurrentCustomerGroup()->getId(),
          "CurrencyId" => $context->getCurrencyId(),
          "ContextRules" => $context->getRuleIds()

v

Array
(
    [SalesChannelId] => 018b0645690772eebfb5748835f19571
    [CustomerGroupId] => 018b0645689871179694b11239666379
    [CurrencyId] => b7d2554b0ce847cd82f3ac9bd1c0dfca
    [ContextRules] => Array
        (
        )
)

Ergo besitzt der Context die nötigen Informationen, um die PreisRule (SalesChannel = X OR CustomerGroup = Y) aufzulösen, wie kann es dann sein, dass im Produkt folgendes zurück kommt:

    [calculatedPrices] => Shopware\Core\Checkout\Cart\Price\Struct\PriceCollection Object
        (
            [extensions:protected] => Array
                (
                )

            [elements:protected] => Array
                (
                )

        )

    [calculatedPrice] => Shopware\Core\Checkout\Cart\Price\Struct\CalculatedPrice Object
        (
            [extensions:protected] => Array
                (
                )

            [unitPrice:protected] => 10000
            [quantity:protected] => 1
            [totalPrice:protected] => 10000
            [calculatedTaxes:protected] => Shopware\Core\Checkout\Cart\Tax\Struct\CalculatedTaxCollection Object
                (
                    [extensions:protected] => Array
                        (
                        )

                    [elements:protected] => Array
                        (
                            [19] => Shopware\Core\Checkout\Cart\Tax\Struct\CalculatedTax Object
                                (
                                    [extensions:protected] => Array
                                        (
                                        )

                                    [tax:protected] => 1596.64
                                    [taxRate:protected] => 19
                                    [price:protected] => 10000
                                )

                        )

                )

            [taxRules:protected] => Shopware\Core\Checkout\Cart\Tax\Struct\TaxRuleCollection Object
                (
                    [extensions:protected] => Array
                        (
                        )

                    [elements:protected] => Array
                        (
                            [19] => Shopware\Core\Checkout\Cart\Tax\Struct\TaxRule Object
                                (
                                    [extensions:protected] => Array
                                        (
                                        )

                                    [taxRate:protected] => 19
                                    [percentage:protected] => 100
                                )

                        )

                )

            [referencePrice:protected] => 
            [listPrice:protected] => 
            [regulationPrice:protected] => 
        )

Die 10000 sind Basis-Testpreise, welche wir anfänglich hinterlegt hatten, der SalesChannel/Kundengruppen-bezogene Preis sollte ca. 7.95 zurück liefern, was auf der Produktdetail-Seite auch problemlos funktioniert.

In der Service.xml sind folgende arguments eingetragen:

            <argument type="service" id="request_stack"/>
            <argument type="service" id="sales_channel.product.repository"/>

Irgendjemand eine Idee oder Vermutung, woran es noch liegen könnte oder ist das Forum bis auf wenige Agenturen mittlerweile gänzlich gestorben und wir schauen nur noch zu wie Shopware 6 nach und nach in (fraglicher) schönheit stirbt weil damit einfach kein normaler Mensch mehr zurecht kommt?

Nein, das ist kein „grundsätzliches Problem“ und nein, dieses Forum ist nicht gestorben und nein, es stirbt nicht in fraglicher Schönheit - nur weil du keine Antwort auf dein Problem findest. Es gibt kaum etwas simpleres, als Produkte mit Preisen für den aktuellen Kontext zu laden (inkl. korrekt berechneter MwSt, Währung etc.) - und das ist richtig gut. Aber wer so schon Fragen stellt, der muss sich auch nicht wundern, dass niemand antwortet…

Kurz:

  • sales_channel.product.repository zum Lesen von Produkten nutzen
  • hier werden automatisch die Preise für den aktuellen sales channel context geladen
  • der „Standard“ Preis steht in calculatedPrice, korrekt für den aktuellen Kontext berechnet
  • ein oder mehrere (bei Staffelpreisen) erweiterten Preise (für die erste gültige Regel) stehen in calculatedPrices
  • das heißt: 1.) wenn keine calculatedPrices existieren, dann nutze calculatedPrice und 2.) wenn calculatedPrices existieren, dann nimm den ersten Preis, der für deine gewünschte Stückzahl passt

Für Varianten wäre evtl. noch calculatedCheapestPrice interessant.

Viele Grüße

Wenn man sich schon auf die Frage bezieht und derart nörgelt, nachdem Personen seit Tagen versuchen, dieses Problem nach wie vor erfolglos in Shopware zu lösen, dann hätte man eventuell auch lesen sollen, was in den Code-Abschnitten steht und bereits versucht wurde.

sales_channel.product.repository WIRD genutzt, ist über die services.xml eingebunden (wie oben gezeigt) und wird danach korrekt bei Aufruf der Funktion in $this->productRepository gepackt, von wo aus dann per ->search($criteria, $context)->first() der Artikel gesucht und gefunden wird - jedoch mit eben dem falschen Preis.

Steht alles oben drin, wäre es „so einfach“ und würde über diese Schritte funktionieren wie es sollte, dann hätte ich ja das Problem nicht.

Preisstaffeln existieren nicht, der Preis wird eben NICHT für den aktuellen Kontext berechnet, sondern einfach der Standard ausgespuckt und genau das ist mein Problem, dass hier sowohl ShopID als auch CustomerGroupId ignoriert werden, welche per „OR“ als einzige Voraussetzungen der Regel für den richtigen Shoppreis hinterlegt sind.

Im Bereich prices der Produktrückgabe steht der richtige Preis drin, inklusive der RuleID, welche hier Anwendung finden müsste.

Ist dies evtl. ein Problem mit der Shopware-Version 6.5.6.0?

Nein, das ist kein generelles Problem. Bei dir wird - warum auch immer - die Preisregel nach den Kriterien des Rule Builders gefiltert und als ungültig erkannt. Mit 99%-iger Wahrscheinlichkeit ist schlichtweg deine Regel falsch oder es gibt eine Inkompatibilität mit einem anderen Plugin.

Auch die Suche im Shop geht exakt diesen Weg und prüft dann auf calculatedPrices innerhalb des Templates: shopware/src/Storefront/Resources/views/storefront/layout/header/search-suggest.html.twig at trunk · shopware/shopware · GitHub

Viele Grüße

Dass es ein Grundsätzliches Problem mit der Rule ist kann man fast ausschließen, im gesamten Shop funktioniert die Preisfindung ja korrekt.

Listing, Suche und Details zeigen alle den richtigen Preis an, nur an dieser Stelle in meinem Plugin schafft er es irgendwie nicht ebenfalls auf diesen aufzulösen…

Wie gesagt haben wir die PreisRule bereits so angepasst, dass schon der Sales-Channel ODER die Kundengruppe ausreichen müssten, um auf dem Preis zu landen…