Artikel dazu berechnen

Ich habe zwar gesehen, dass es das Thema in einer ähnlichen, bzw. alten Form bereits gibt, aber eine gescheite Lösung habe ich nicht gefunden, also hier einmal mein Ansatz.

Warum soll eigentlich der “Artikel dazu” berechnet werden? Ich gestehe, dass ich hier eine bereits implementierte Funktion missbrauchen möchte. Beispiel: besonders bei individualisierbaren Artikeln fallen oft einmalige Vorkosten (Entwurf, Satz, Maschineneinrichtung, Filmkosten, o.ä.) an. Die sollen automatisch zum Artikel dazu kommen, allerdings auch berechnet werden.

Ich habe jetzt angefangen ein Modul zu schreiben und natürlich schon gleich mein erstes Problem gefunden.

Zum Vorgehen:
Ich überschreibe (zunächst) die Funktion _calcItemsPrice() aus vendor/oxid-esales/oxideshop-ce/source/Application/Model/Basket.php (Zeile 788ff).

Am ende der Funktion wird überprüft, ob es sich um einen “Artikel dazu” handelt (->isBundle())

837 elseif ($oBasketItem->isBundle()) {
838 // if bundles price is set to zero
839 $oPrice = oxNew(\OxidEsales\Eshop\Core\Price::class);
840 $oBasketItem->setPrice($oPrice);
841 }

Hier wird in Zeile 839 ein (leeres) Objekt erzeugt und in Zeile 840 der Preis davon (der erst einmal 0 ist) gesetzt.

Füge ich nach Zeile 839 ein:
$oPrice->setPrice(39); ist der Preis für ein “Artikel dazu” 39,- EUR. Fein. Allerdings möchte ich ja den Preis für den angelegten Artikel ausgeben (und nicht jedesmal 39,- EUR da stehen haben).
Also nehme ich statt dessen $oPrice->setPrice($oBasketItem->getPrice());. Jetzt ist der Preis gleich null. Hmmm, seltsam. Mal so aus Spaß:
$oPrice->setPrice($oBasketItem->getWeight());
oops, das funktioniert und zeigt mir das Gewicht vom “Artikel dazu” als Preis an.
Wo ist mein Fehler? Beides - getPrice() und getWeight() sind Funktionen der Klasse BasketItem!?

Btw.: die Summe im Warenkorb berücksichtigt den “Artikel dazu” noch nicht, das kommt dann später :}

Ok, irgendwie von hinten durchs Auge in die Brust, aber so geht es scheinbar:

elseif ($oBasketItem->isBundle()) 
{   // if bundles price is set to zero
    $oArticle = $oBasketItem->getArticle(true);
    $oPrice = $oArticle->getBasketPrice($oBasketItem->getAmount(), $oBasketItem->getSelList(), $this);
    $oBasketItem->setPrice($oPrice);
    $this->_oProductsPriceList->addToPriceList($oPrice);
}

Mit der letzten Zeile wird auch der Preis zur Summe addiert, allerdings stimmt dann die Berechnung der MwSt. noch nicht.

Hallo Matze,

setPrice auf einem oxPrice Objekt erwartet einen Zahlenwert.

 /**
 * Sets new price and VAT percent(optional). Recalculates price by
 * price entering mode
 *
 * @param double $dPrice new price
 * @param double $dVat   VAT
 */
public function setPrice($dPrice, $dVat = null)

Du übergibst mit $oBasketItem->getPrice() ein oxPrice Objekt. Du könntest mal versuchen: $oBasketItem->getPrice()->getPrice() das liefert den Zahlenwert.

Ich habe mir keine Gedanken über die anderen Sachen gemacht. Dazu hab ich gerade leider keine Zeit, aber das ist mir eben direkt ins Auge gesprungen. Vielleicht hilft dir das trotzdem für das Gesamt-Problem.

Danke, werde ich mal versuchen, wobei der Umweg über den Artikel (siehe mein 2. Post) ja funktioniert :slight_smile:

Ja, aber Du hast auch geschrieben, dass die MwSt. noch nicht stimmt… Von daher dachte ich, dass dein erster Ansatz vielleicht doch der richtigere Weg war, nur eben das NULL-Preis-Problem dir da rein grätscht. Wie gesagt, ich hab mir das Konstrukt drum herum jetzt nicht im Detail angeschaut, kann das also gerade nicht bewerten.

Also kurz getestet: $oBasketItem->getPrice()->getPrice() liefert einen Fehler. Egal.

Bei der MwSt. werden die (jetzt) kostenpflichtigen “Artikel dazu” ignoriert - das baue ich jetzt noch ein.

So, nachdem ich mich jetzt durch die Klassenhierarchie, die entsprechenden .tpl und .php Dateien gewühlt habe, war die Lösung jetzt wohl doch recht einfach. Bevor ich aber den Code jetzt hier poste wäre es mir lieb, wenn ihn vorher 1-2 interessierte testen. Wer mag einfach kurz eine PM, ich schicke dann die Daten rüber. Wenn alle nicken veröffentliche ich dann den Code unentgeldlich. Vielleicht hilft es ja jemandem :slight_smile:

Du kannst auch den Weg anders herum gehen, @Matze66: Einfach den Code (auf Github?) veröffentlichen, hier verlinken und dann warten bis jemand feststellt, dass irgendetwas nicht funktioniert :wink:

@marco.steinhaeuser ah, verstehe, den Kunden testen lassen. Geht leider nicht, ich bin ja nicht Miroschuft :wink:

Den Kunden würde ich das nicht sofort hinwerfen. Aber sobald der Code zumindest einsehbar ist, findet sich eher jemand, der ihn (in einer Testumgebung) ausprobiert.

1 Like