Versandkosten berechnen (Plugin)

Hallo, ich versuche schon den ganzen Tag die Versandkosten zu berechnen, aber bekomme es nicht hin.
Ziel ist es, auf der Produktseite die Versandkosten für dieses spezifische Produkt, für alle verfügbaren Länder anzuzeigen.

In der Theorie müsste ich also einen temporären Cart erzeugen, den Artikel hinzufügen, das Lieferland und die Versandart festlegen und dann berechnen lassen.
Ich bekomme jedoch immer auf 0. Ausnahme ist, wenn ich mir die Deliveries aus dem Kundenwarenkorb kopiere, dann werden die verwendet, aber das ist ja nicht gewollt.

Ich wäre wirklich sehr dankbar, wenn mir da irgendwer weiterhelfen kann.

Ich habe mittlerweile schon so viel herumprobiert, dass mein Code ein bisschen wild aussieht.
Ich habs mal ein bisschen getrimmt, damit man zumindest sieht, was ich bis jetzt versucht habe:

public function getShippingCost(): string
{
	$shippingCosts = [];
	if($productEntity = $this->getProduct())
	{
		$shippingMethodRoute = $this->getContainer()->get(ShippingMethodRoute::class);
		$countryRepository = $this->getContainer()->get('country.repository');

		$lineItem = new LineItem($productEntity->getId(), 'product', $productEntity->getId(), 1);
		$originalCart = $this->getCartService()->getCart($this->getSalesChannelContext()->getToken(), $this->getSalesChannelContext());

		$countries = $countryRepository->search((new Criteria())->addFilter(new EqualsFilter('active', true)), $this->getSalesChannelContext()->getContext())->getEntities();
		$shippingMethods = $shippingMethodRoute->load(new Request(), $this->getSalesChannelContext(), (new Criteria())->addFilter(new EqualsFilter('active', true)))->getShippingMethods();
		foreach($shippingMethods as $shippingMethod)
		{
			foreach($countries as $country)
			{
				$cart = $this->getCartService()->createNew($this->getSalesChannelContext()->getToken(), 'ShippingCostCalculatorCart');
				// $this->getCartService()->add($cart, $lineItem, $this->getSalesChannelContext()); // throws Access to property "mediaTypeRaw" not allowed
				$cart->setLineItems(new LineItemCollection([$lineItem]));

				$deliveries = new DeliveryCollection();
				foreach($originalCart->getDeliveries() as $originalDelivery)
				{
					$productPriceDefinition = new QuantityPriceDefinition($productEntity->getPrice()->get(Defaults::CURRENCY)->getGross(), new TaxRuleCollection(), 1);

					$deliveryPositionCollection = new DeliveryPositionCollection();
					$deliveryPositionCollection->add(new DeliveryPosition($lineItem->getReferencedId(), $lineItem, 1, $this->getQuantityPriceCalculator()->calculate($productPriceDefinition, $this->getSalesChannelContext()), $originalDelivery->getDeliveryDate()));

					//$deliveries->add(new Delivery($deliveryPositionCollection, $originalDelivery->getDeliveryDate(), $shippingMethod, ShippingLocation::createFromCountry($country), $originalDelivery->getShippingCosts()));
					$deliveries->add(new Delivery($deliveryPositionCollection, $originalDelivery->getDeliveryDate(), $shippingMethod, ShippingLocation::createFromCountry($country), new CalculatedPrice(0, 0, new CalculatedTaxCollection(), new TaxRuleCollection())));
				}
				$cart->setDeliveries($deliveries);
				$cart->markModified();
				$cart->getData()->set(DeliveryProcessor::buildKey($shippingMethod->getId()), $shippingMethod);
				// $this->getCartService()->recalculate($cart, $this->getSalesChannelContext()); // throws Access to property "mediaTypeRaw" not allowed
				$this->getDeliveryCalculator()->calculate($cart->getData(), $cart, $deliveries, $this->getSalesChannelContext());

				$isoCode = $country->getIso();
				if(!array_key_exists($isoCode, $shippingCosts))
					$shippingCosts[$isoCode] = [];

				$shippingCosts[$isoCode][$shippingMethod->getId()] = $cart->getDeliveries()->getShippingCosts()->sum()->getTotalPrice();
			}
		}
	}
	return print_r($shippingCosts, true);
}

Ich habs jetzt doch noch hinbekommen.
Das waren meine ersten Berührungspunkte mit Symfony und Shopware, mein lieber Schwan, war ganz schön wild :rofl:
Aber ich habe auch direkt ne Menge vom Framework gelernt :slight_smile:

Die Hauptprobleme, die ich hatte, waren, dass die MediaDaten vom Produkt und das Payload der Regeln im Context nicht ApiAware sind.
Wenn man CartService verwendet, werden die Felder aber aufgerufen bzw. serialisiert, was direkt zu einer Exception führt.
Die MediaDaten beim Produkt zur Berechnung überschreiben, ist kein Problem, braucht man ja auch nicht.
Für die Rules musste ich mir einen eigenen CartRuleLoader erstellen, welcher beim Laden der Rules das payload aus der FieldVisibility entfernt.

mehr nicht :stuck_out_tongue_winking_eye: