Preismanipulation – Preis im Warenkorb falsch

Hallo!

Ich versuche aus unserem bestehenden xt:Commerce-Shop eine Funktionalität nach Shopware zu übertragen: Schöne USD-Preise. Weil bei einem Europreis von 379 ein USD-Preis von 358,37 einfach nicht schön aussieht soll er auf 359 gerundet werden. 

Ich hab mir dazu den price_calculation_service ersetzt (dekorieren geht nicht da alle Funktionen private):

$this->subscribeEvent(
    'Enlight_Bootstrap_AfterInitResource_shopware_storefront.price_calculation_service',
    'registerPriceCalculationService'
);

Die Function calculatePrice() hat eine entsprechende Änderung, dass bei Währung USD eine Rundung auf den nächsten 5er oder 9er stattfindet. Das funktioniert auch alles soweit prima, überall wird der gerundete USD-Preis angezeigt.
Sobald man aber das Produkt in den Warenkorb legt landet es dort nicht mit den erwarteten 359 USD sondern es wird der Euro-Preis von 379 angezeigt.

Ich hab dann auf Twitter (Link zur Diskussion) noch den Tipp bekommen, das über den Event Shopware_Modules_Basket_getPriceForUpdateArticle_FilterPrice zu lösen. Damit kann ich zwar den Preis überschreiben, aber die 359 tauchen nirgends auf. Selbst wenn ich mir die Preise hier nochmal hole für das Produkt tauchen leider nur die 379 auf:

$return = $arguments->getReturn();
$repository = Shopware()->Models()->getRepository('Shopware\Models\Article\Detail');
$article = $repository->findOneBy(array('id' => $return['articleID']));
\Doctrine\Common\Util\Debug::dump($article->getPrices());

(es gibt keine Doku zu dem Event, von daher ist mir leider unklar wie ich ohne erneuten Weg über das Repository an die Artikeldaten komme)

array(1) {
  [0]=>
  object(stdClass)#1792 (15) {
    [" __CLASS__"]=>
    string(29) "Shopware\Models\Article\Price"
    ["id"]=>
    int(7118)
    ["articleId"]=>
    int(38)
    ["articleDetailsId"]=>
    int(38)
    ["customerGroupKey"]=>
    string(2) "EK"
    ["from"]=>
    int(1)
    ["to"]=>
    string(8) "beliebig"
    ["price"]=>
    float(318.48739495798)
    ["pseudoPrice"]=>
    float(0)
    ["basePrice"]=>
    float(0)
    ["percent"]=>
    float(0)
    ["detail"]=>
    string(30) "Shopware\Models\Article\Detail"
    ["customerGroup"]=>
    string(54) "Shopware\Proxies\ __CG__ \Shopware\Models\Customer\Group"
    ["attribute"]=>
    NULL
    ["article"]=>
    string(55) "Shopware\Proxies\ __CG__ \Shopware\Models\Article\Article"
  }
}

Es scheint so als würde der Basket den price_calculation_service gar nicht erst benutzen. Die zentrale Frage ist jetzt: Wie kann ich es trotzdem erreichen, dass auch im Warenkorb der Preis angezeigt wird, den ich haben will?

Matt

Hi Matt,

das im Post genannte Event wird ja an dieser Stelle gefeuert:
 shopware/sBasket.php at 5.1 · shopware/shopware · GitHub
Es ist also ein Filter-Event und der Rückgabe-Wert wird als Preis im Warenkorb gespeichert.
Mit: 
 $return[‚price‘] = round($return[‚price‘]);
 return $return;
solltest du also den Warenkrob-Preis bestimmen können.

Gruß Heiner

1 „Gefällt mir“

Danke, das würde den Preis aber nur runden und nicht auf den nächsten 5er oder 9er aufrunden. Ich müsste also die Funktionalität duplizieren, die ich in calculatePrice() schon habe, was ich aber natürlich irgendwie vermeiden wollte…

Hi,

dafür kannst du dir ja ein Service anlegen:
 Plugin services

Gruß Heiner

Ich hab ja aber schon den price_calculation_service, den ich überschreibe. Ich hab nur keine wirkliche Idee mit was ich dann den $context-Parameter füllen muss.

Hi,

du meinst den ProductContext in der \Shopware\Bundle\StoreFrontBundle\Service\Core\PriceCalculationService::calculateProduct? Das Context-Objekt kannst du dir aus dem Service shopware_storefront.context_service ziehen. Dahinter stecken letztlich Infos Steuerregeln und Preisgruppen, die wir zur Berechnung von Preisen benötigen.

Besten Gruß,

Daniel