Pfand/Depot Modul

Hallo zusammen

Für mein neues Getränke-Shop Projekt benötigte ich ein Modul das zu einigen Artikel automatisch das entsprechende Pfand hinzurechnet. Zuerst wollte ich dafür ein Modul kaufen - aber um Kosten zu sparen habe ich den selbstversuch gewagt. Nach “nächtelangem” :smiley: rumpröbeln mit Bundles und Lösungssuche im Forum, bin ich per Zufall auf folgenden Thread von R.Nitzer gestossen. Den Lösungsvorschlag habe ich nun in ein Modul gepackt, da ich es nirgends gefunden habe. Zu meinem besseren Verständnis habe ich jedoch meine Variablen benutzt, aber im Prinzip ist es die Lösung des Users R.Nitzer.
Getestet habe ich mit der CE 4.8.6, aber mit ein paar Anpassungen sollte es sicher noch erweiterbar, anpassbar sein und sich auch für andere Probleme eigenen.

@Marco darfst Du gerne auf GitHub veröffentlichen.

LG Pasquale

Kann man absoltue Beträge eingeben, denn Pfand ist doch immer ein festgesetzter Betrag pro Flasche? ? Achso, mach noch eine Lizenz rein.

Es wird die oxarticles um das Feld Pfand (Double) erweitert, in der Artikelverwaltung im 1. Tab ganz unten, dort kannst das entsprechende Pfand eingeben. Das Modul prüft ob ein Betrag vorhanden ist, falls nicht wird die Berechnung übersprungen. Da Pfandartikel ja von der MwSt befreit sind kannst Du in den Moduleinstellungen den MwSt Satz selbst bestimmen…
Lizenz? Hab doch nur kopiert…

Ich probiere es aus. Danke!

Abgeänderte Version des Moduls -> Flüchtigkeitsfehler korrigiert:

  • Variable im SQL falsch
  • Artikelbildpfad korrigiert
  • beim Erstellen des Artikels wird neu die OXPICSGENERATED auf 0 gesetzt damit das Icon, Thumb ect. beim Aufruf automatisch generiert wird.

LG Pasquale

Hmmmm, oxpicsgenerated wird doch gar nicht mehr benutzt und ist obsolet. Zumindest stand das mal im Changelog, als sich damals das Imagehandling geändert hat.

Hallo Chris

oxpicsgenerated wird doch gar nicht mehr benutzt und ist obsolet

Hab ich nicht gewusst, aber besten Dank für den Hinweis. Steht natürlich jedem frei den Quellcode entsprechend anzupassen.

LG Pasquale

> @Marco darfst Du gerne auf GitHub veröffentlichen.

Öhm - is grad gaaanz schlecht :slight_smile:
http://www.marco-steinhaeuser.de/parental-leave-in-july-and-august.html

Gruß

…aber hier steht wie es geht :wink:

(gar nich so schwer)

Hallo Marco und Ray

@Marco
Cool :slight_smile: wünsch Dir auf jeden Fall eine schöne Zeit, viele unvergessliche Momente und viel Spass mit dem Nachwuchs!

@Ray
Werd ich mir mal anschauen. Habs eben schon mal probiert und festgestellt das Github und ich wohl keine guten “Freunde” sind (werden) :smiley:

LG Pasquale

Hi,

sehr gute Arbeit. :smiley: Bin leider nicht mehr Zeitlich dazu gekommen das als Modul zu verpacken.

Aber wenn Du einmal dabei bist habe ich gleich noch 2 kleine Änderungen die ich noch gemacht hatte. Es trat ein Problem auf wenn 2 verschiedene Artikel mit Pfand in den Warenkorb gelegt wurden:


    /**
     * Iterates through basket contents and adds bundles to items + adds
     * global basket bundles
     *
     * @return null
     */
    protected function _addBundles()
    {
        $aBundles = array();
        // iterating through articles and binding bundles
        foreach ( $this->_aBasketContents as $key => $oBasketItem ) {
            try {
                // adding discount type bundles
                if ( !$oBasketItem->isDiscountArticle() && !$oBasketItem->isBundle() ) {
                    $aBundles = $this->_getItemBundles( $oBasketItem, $aBundles );
                } else {
                    continue;
                }

                    // adding item type bundles
                    $aArtBundles = $this->_getArticleBundles( $oBasketItem );

                    if(!empty($oBasketItem->getArticle()->oxarticles__wapawn->value))
                    {
                        $pAId = $this->getPawnArticleId($oBasketItem->getArticle()->oxarticles__wapawn->value);
                       // ################### ANFANG
                        $oBundleItem = $this->addToBasket( $pAId, $oBasketItem->getAmount(), null, null, false, true,null,$key );
                       // ################### ENDE

                        if($oBasketItem->getLink() && $oBundleItem) {
                            $oBundleItem->setLink($oBasketItem->getLink());
                       // ################### ANFANG
                            $oBundleItem->setTitle($oBundleItem->getTitle() . " " . $oBasketItem->getTitle() );
                       // ################### ENDE
                        }
                    }

                    // adding bundles to basket
                    $this->_addBundlesToBasket( $aArtBundles );
            } catch ( oxNoArticleException $oEx ) {
                $this->removeItem( $key );
                oxRegistry::get("oxUtilsView")->addErrorToDisplay( $oEx );
            } catch( oxArticleInputException $oEx ) {
                $this->removeItem( $key );
                oxRegistry::get("oxUtilsView")->addErrorToDisplay( $oEx );
            }
        }

        // adding global basket bundles
        $aBundles = $this->_getBasketBundles( $aBundles );

        // adding all bundles to basket
        if ( $aBundles ) {
            $this->_addBundlesToBasket( $aBundles );
        }
    }

Soweit ich das auf die schnelle überblicke hatte ich hier noch den Titel richtig setzen lassen und den key des “Vater Artikels” (also der Artikel zu dem der Pfand gehört) mit übergeben.
(Habe die betreffenden Zeilen mal mit dem Kommentar // ################### versehen)

Dazu passend die addToBasket Funktion die den key mit verarbeitet und den Pfand an die richtige Stelle plaziert.


    /**
     * Adds user item to basket. Returns oxBasketItem object if adding succeeded
     *
     * @param string $sProductID        id of product
     * @param double $dAmount           product amount
     * @param mixed  $aSel              product select lists (default null)
     * @param mixed  $aPersParam        product persistent parameters (default null)
     * @param bool   $blOverride        marker to accumulate passed amount or renew (default false)
     * @param bool   $blBundle          marker if product is bundle or not (default false)
     * @param mixed  $sOldBasketItemId  id if old basket item if to change it
     * @param string $pawnParentKey     key of pawn Parent
     *
     * @throws oxOutOfStockException oxArticleInputException, oxNoArticleException
     *
     * @return object
     */
    public function addToBasket( $sProductID, $dAmount, $aSel = null, $aPersParam = null, $blOverride = false, $blBundle = false, $sOldBasketItemId = null, $pawnParentKey = null )
    {
        // enabled ?
        if ( !$this->isEnabled() )
            return null;

        // basket exclude
        if ( $this->getConfig()->getConfigParam( 'blBasketExcludeEnabled' ) ) {
            if ( !$this->canAddProductToBasket( $sProductID ) ) {
                $this->setCatChangeWarningState( true );
                return null;
            } else {
                $this->setCatChangeWarningState( false );
            }
        }

        if(!empty($pawnParentKey)) {
            $sItemId = $this->getItemKey( $sProductID.$pawnParentKey, $aSel, $aPersParam, $blBundle );
        } else {
            $sItemId = $this->getItemKey( $sProductID, $aSel, $aPersParam, $blBundle );
        }
        if ( $sOldBasketItemId && ( strcmp( $sOldBasketItemId, $sItemId ) != 0 ) ) {
            if ( isset( $this->_aBasketContents[$sItemId] ) ) {
                // we are merging, so params will just go to the new key
                unset( $this->_aBasketContents[$sOldBasketItemId] );
                // do not override stock
                $blOverride = false;
            } else {
                // value is null - means isset will fail and real values will be filled
                $this->_changeBasketItemKey( $sOldBasketItemId, $sItemId );
            }
        }

        // after some checks item must be removed from basket
        $blRemoveItem = false;

        // initialling exception storage
        $oEx = null;

        if ( isset( $this->_aBasketContents[$sItemId] ) ) {

            //updating existing
            try {
                // setting stock check status
                $this->_aBasketContents[$sItemId]->setStockCheckStatus( $this->getStockCheckMode() );
                //validate amount
                //possibly throws exception
                $this->_aBasketContents[$sItemId]->setAmount( $dAmount, $blOverride, $sItemId );
            } catch( oxOutOfStockException $oEx ) {
                // rethrow later
            }

        } else {
            //inserting new
            $oBasketItem = oxNew( 'oxbasketitem' );
            try {
                $oBasketItem->setStockCheckStatus( $this->getStockCheckMode() );
                $oBasketItem->init( $sProductID, $dAmount, $aSel, $aPersParam, $blBundle );
            } catch( oxNoArticleException $oEx ) {
                // in this case that the article does not exist remove the item from the basket by setting its amount to 0
                //$oBasketItem->dAmount = 0;
                $blRemoveItem = true;

            } catch( oxOutOfStockException $oEx ) {
                // rethrow later
            } catch ( oxArticleInputException $oEx ) {
                // rethrow later
                $blRemoveItem = true;
            }

            if(empty($pawnParentKey)) {
                $this->_aBasketContents[$sItemId] = $oBasketItem;
            } else {
                $this->_aBasketContents = $this->array_insert_after($this->_aBasketContents, $pawnParentKey, Array( $sItemId => $oBasketItem));
            }
        }

        //in case amount is 0 removing item
        if ( $this->_aBasketContents[$sItemId]->getAmount() == 0 || $blRemoveItem ) {
            $this->removeItem( $sItemId );
        } elseif ( $blBundle ) {
            //marking bundles
            $this->_aBasketContents[$sItemId]->setBundle( true );
        }

        //calling update method
        $this->onUpdate();

        if ( $oEx ) {
            throw $oEx;
        }

        // notifying that new basket item was added
        if (!$blBundle) {
            $this->_addedNewItem( $sProductID, $dAmount, $aSel, $aPersParam, $blOverride, $blBundle, $sOldBasketItemId );
        }

        // returning basket item object
        return $this->_aBasketContents[$sItemId];
    }

    function array_insert_after($array, $key, $new)
    {
        $keys = array_keys($array);
        $pos = (int) array_search($key, $keys);
        return array_merge(
            array_slice($array, 0, $pos+1),
            $new,
            array_slice($array, $pos+1)
        );
    }

Nun sollte auch kein Problem mehr bestehen wenn 2 Verschiedene Artikel den selben Pfand haben.
Da ich die ID des Pfand mit der ID des Vaterartikels konkatiniert habe.

Bei Fragen zu den Bugfix kannst du mich gerne per PM anschreiben oder im Thread posten. :slight_smile:

Danke für die Arbeit!

P.S.: Alle Änderungen/Funktionen sind in der _oxbasket.php

Hallo R.Nitzer

Danke für den Hinweis, habe beim Erstellen des Moduls nur gerade 2 Artikel mit unterschiedlichem Pfand getestet - es hat funktioniert :).
Hab jedoch gesehen das keine Artikelnummer vergeben wird und hab mir überlegt eine zuzuweisen mit dem Pfandwert und vor dem Erstellen des Artikel zu prüfen ob das Pfand bereits existiert…
Nun, Deine Lösung funktioniert natürlich auch, werde das in den nächsten Tagen ins Modul packen und wenn Github (ich mag keine Konsolenanwendungen… :mad:) mein Freund wird, lade ichs dann hoch.
To be continued… :slight_smile:

LG Pasquale

…gibt auch ne GUI für GIT :slight_smile:

[QUOTE=vendingtechnik;147877]Hallo R.Nitzer

Danke für den Hinweis, habe beim Erstellen des Moduls nur gerade 2 Artikel mit unterschiedlichem Pfand getestet - es hat funktioniert :).
[/QUOTE]
Genau das selbe hatte ich auch gemacht damals, weswegen mir der Fehler anfänglich nicht aufviel :slight_smile:

So! - das Ganze jetzt aktualisiert auf Github. Thanks an Ray für den letzten Tipp und R.Nitzer für die Lösung.
So macht Communitiy Spass! :slight_smile:

LG Pasquale

Mir ist gerade eingefallen das man dieses Modul auch für irgendwelche Gebühren oder Aufschläge (Tickets, ect.) benutzen könnte. Es müssten halt einfach die entsprechenden Texte im Translationordner angepasst werden…

LG Pasquale

Ich habe das Modul jetzt auch in einem Shop (CE 4.7.8) im Einsatz. Es funktioniert soweit sehr gut. Allerdings gibt es in diesem Shop ein Problem mit Billsafe weil der Pfandartikel keine Artikelnummer hat und Billsafe diese erwartet. Wenn der Kunde die Billsafe Rechnung im Checkout auswählt kommt er nicht weiter.

Könnte man das Modul erweitern so das für die Pfandartikel eine eindeutige Artikelnummer vergeben wird?

Hallo Thomas

Schau mal in der Datei vtec_oxbasket.php nach, dort wird der Artikel erstellt:


$oArticle->assign( array( 'oxarticles__active' => 1,
                                         'oxarticles__oxprice' => $price,
                                         'oxarticles__oxissearch' => 0,           
                                         'oxarticles__oxpic1' => 'pfand.jpg',
                                         'oxarticles__oxvat' => $vtec_mwst,
                              ));

Dort müsstest Du eine Artikelnummer vergeben. Zuerst die Variable anlegen:


$vtec_mwst = oxConfig::getInstance()->getConfigParam('vtec_pfand_mwst');
// Artikelnummer erzeugen
$bsartnum = rand();
// und zuweisen
$sSelect = "SELECT oxid FROM oxarticles WHERE oxtitle = '" . $title . "' AND oxprice = '" . $price . "' LIMIT 1";

Das Array zum Beispiel so erweitern:


'oxarticles__oxartnum' => $bsartnum; 

Hoffe dieses ungetestete Beispiel hilft Dir weiter.

LG Pasquale

PS: oxarticles__oxpicsgenerated, kannst Du löschen wird ab CE 4.8.0 nicht mehr unterstützt…

Hallo Pasquale,

danke für Deine Hilfe, das hört sich gut an. Ich werde es mal testen, aber ich denke das ich damit weiter komme.

Gruß,
Thomas

Hi,

habe eben noch einen Fehler entdeckt. Bei der Pfanderstellung wird der Preis leider nicht auf alle Preisgruppen festgelegt was dazu führt das die anderen Preisgruppen einen Pfand von 0 haben.

Folgende Änderung in der vtec_oxbackset.php in der Funktion PfandArtikelID sollte das Problem beheben.

Das


 $oArticle->assign( array( 'oxarticles__active' => 1,
'oxarticles__oxprice' => $price,
'oxarticles__oxissearch' => 0,
'oxarticles__oxpic1' => 'pfand.jpg',
'oxarticles__oxvat' => $vtec_mwst,
));

in das umändern:


 $oArticle->assign( array( 'oxarticles__active' => 1,
'oxarticles__oxprice' => $price,
'oxarticles__oxpricea' => $price,
'oxarticles__oxpriceb' => $price,
'oxarticles__oxpricec' => $price,
'oxarticles__oxissearch' => 0,
'oxarticles__oxpic1' => 'pfand.jpg',
'oxarticles__oxvat' => $vtec_mwst,
));