Mindestbestellmenge auf Warengruppen

Habe für Oxid mal ein Mindestbestellmengensystem auf Kategoriebasis gebastelt
da es sowas in dieser Art nicht gibt.

Das Mindestbestellmengensystem von Oxid wird auf ALLE Artikel angesetzt und die
käuflichen Module sind auf Artikelbasis. Ich brauchte aber ein System auf Warengruppenbasis.

Da der Kunde z.b. 10 St. einer Warengruppe kaufen muss.
Also 3x Artikel a, 3x Artikel b und 4x Artikel c (einer Warengruppe)

und z.b.: 5St. einer anderen (2x Artikel f und 3x Artikel g)

Es ist zwar nicht nach irgendwelchen richtlinien oder sowas aber es funktioniert.

Hierfür wird das Rabattsystem von Oxid “missbraucht”

Wenn die Mindestbestellmenge für eine Warengruppe auf z.B. min. 4 St. eingestellt ist und ein Kunde nur 3 St. im Warenkorb hat wird eine Dreingabe hinzugefügt die den Kunden drauf hinweist das er zu wenig im Warenkorb hat.
Dies ändert dann den “Weiter zum nächsten Schritt” Button in einen Popup button der nurnoch ausgibt das die Mindestbestellmenge nicht erreicht wurde und den Kunden nicht weiterlässt.

Im Minibasket wurde der “zur Kasse” Button entfernt und durch “Weiter Shoppen” ersetzt. im Warenkorb wurde alle Verlinkungen zur Adressauswahl entfernt (und weiterführenden…)

Als erstes legt man einen “Mindestbestellmengen Artikel” an
Stamm:
Aktiv: JA
Titel: "Das ist der Mindestbestellmengenartikel"
Art.-Nr.: MBMxxxxxx (wichtig ist nur das die ersten 3 Zeichen MBM beinhalten)
Preis: 0
Langtextbeschreibung: Irgendwas was dem Kunden mitteilt das auf diese Warengruppe ine Mindestbestellmenge hinterlegt ist

Erweitert:
Versandkostenfrei: JA
Alle neg. Nachlässe ignorieren. JA

Nun muss man unter Shopeinstellungen --> Rabatte
einen neuen “Rabatt” anlegen.

Stamm:
Name: Mindestbestellmenge deiner Warengruppe (deiner Warengruppe durch die Kategorie austauschen. (ist nur für eure Information)
Aktiv: JA
Einkaufsmenge: 1-3 (für eine Mindestbestellmenge von 4St. (MBM-Artikel zählt als +1 für die Kategorie)
Rabatt: itm
Erstellten “Mindestbestellmengenartikel” zuordnen

Artikel:
Kategorie zuordnen (hier die Warengruppe auf der die Mindestbestellmenge angewendet werden soll angeben)

So das war der einfach teil :slight_smile:

Nun ändern wir die tpl/widget/minibasket/minibasket.tpl

und suchen diese Abschnitt Zeile 75
(Ersetzen des Buttons “zur Kasse” in “Weiter Shoppen”)

<p class="functions clear">
                       [{if $oxcmp_user}]
                            <a href="[{ oxgetseourl ident=$oViewConf->getSelfLink()|cat:"cl=payment" }]" class="submitButton largeButton">[{ oxmultilang ident="WIDGET_MINIBASKET_CHECKOUT" }]</a>
                       [{else}]
                            <a href="[{ oxgetseourl ident=$oViewConf->getSelfLink()|cat:"cl=user" }]" class="submitButton largeButton">[{ oxmultilang ident="WIDGET_MINIBASKET_CHECKOUT" }]</a>
                       [{/if}]
                       <a href="[{ oxgetseourl ident=$oViewConf->getSelfLink()|cat:"cl=basket" }]" class="textButton">[{ oxmultilang ident="WIDGET_MINIBASKET_DISPLAY_BASKET" }]</a>
                    </p>

und ersetzen ihn hiermit

<p class="functions clear">
                       <a href="[{ oxgetseourl ident=$oViewConf->getSelfLink()|cat:"cl=basket" }]" class="textButton">[{ oxmultilang ident="WIDGET_MINIBASKET_DISPLAY_BASKET" }]</a>
                       [{if $oxcmp_user}]
                     
                            <a  class="submitButton largeButton closePop">[{ oxmultilang ident="PAGE_CHECKOUT_BASKET_CONTINUESHOPPING" }]</a>
                       [{else}]
                            <a href="[{ oxgetseourl ident=$oViewConf->getSelfLink()|cat:"cl=user" }]" class="submitButton largeButton">[{ oxmultilang ident="WIDGET_MINIBASKET_CHECKOUT" }]</a>
                       [{/if}]
                       
                    </p>

Dann ändern wir die tpl/page/checkout/basket.tpl

und kommentieren Zeile 27-39 aus
(Oberen button “zum nächsten Schritt” entfernen)

 [{if $oView->isLowOrderPrice() }]
                    [{block name="checkout_basket_loworderprice_top"}]
                        <div>[{ oxmultilang ident="PAGE_CHECKOUT_BASKET_MINORDERPRICE" }] [{ $oView->getMinOrderPrice() }] [{ $currency->sign }]</div>
                    [{/block}]
                [{else}]
                    [{block name="basket_btn_next_top"}]
                        <form action="[{ $oViewConf->getSslSelfLink() }]" method="post">
                            [{ $oViewConf->getHiddenSid() }]
                            <input type="hidden" name="cl" value="user">
                            <button type="submit" class="submitButton largeButton nextStep">[{ oxmultilang ident="PAGE_CHECKOUT_BASKET_NEXTSTEP" }]</button>
                        </form>
                    [{/block}]
                [{/if}]

in

[{*if $oView->isLowOrderPrice() }]
                    [{block name="checkout_basket_loworderprice_top"}]
                        <div>[{ oxmultilang ident="PAGE_CHECKOUT_BASKET_MINORDERPRICE" }] [{ $oView->getMinOrderPrice() }] [{ $currency->sign }]</div>
                    [{/block}]
                [{else}]
                    [{block name="basket_btn_next_top"}]
                        <form action="[{ $oViewConf->getSslSelfLink() }]" method="post">
                            [{ $oViewConf->getHiddenSid() }]
                            <input type="hidden" name="cl" value="user">
                            <button type="submit" class="submitButton largeButton nextStep">[{ oxmultilang ident="PAGE_CHECKOUT_BASKET_NEXTSTEP" }]</button>
                        </form>
                    [{/block}]
                [{/if*}]

Zeile 42
von
(Scope einsetzen das die iclude Variablen benutzt werden können)

[{include file="page/checkout/inc/basketcontents.tpl" editable=true}]

in

[{include file="page/checkout/inc/basketcontents.tpl" editable=true scope="parent"}]

Zeile 96
(Ersetzen des “zum nächsten Schritt” Button durch die if abfrage ob eine Mindestebestellmenge vorhanden ist und Ausgabe des richtigen Buttons)

<button type="submit" class="submitButton largeButton nextStep">[{ oxmultilang ident="PAGE_CHECKOUT_BASKET_NEXTSTEP" }]</button>

in

  [{if $moq}]
                            <button type="button" class="submitButton largeButton nextStep" value="[{ oxmultilang ident="MOQ_BUTTON_INTERN_VALUE" }]" onclick="alert('[{ oxmultilang ident="MOQ_BUTTON_ALERT" }]');"> [{ oxmultilang ident="MOQ_BUTTON_VALUE" }]</button> 
                            
                          
                           
                            [{else}]
                           <button type="submit" class="submitButton largeButton nextStep">[{ oxmultilang ident="PAGE_CHECKOUT_BASKET_NEXTSTEP" }]</button>
                            [{/if}]

Dann ändern wir die tpl/page/checkout/inc/basketcontents.tpl

Zeile 70

von
(Erstzen der Artikelnummer durch blindtext)

[{ oxmultilang ident="PAGE_CHECKOUT_BASKETCONTENTS_ARTNOMBER" }] [{ $basketproduct->oxarticles__oxartnum->value }]

in

[{if $basketproduct->oxarticles__oxartnum->value|@substr:0:3 == MBM }] 
              <font color="#ff0000"><b>[{ oxmultilang ident="MOQ_ART_VALUE" }]<b/></font>
            [{assign var="moq" value="moq" }]
         [{else}]
              [{ oxmultilang ident="PAGE_CHECKOUT_BASKETCONTENTS_ARTNOMBER" }] [{ $basketproduct->oxarticles__oxartnum->value }]
      [{/if}]  

Dann ändern wir die tpl/page/checkout/inc/steps.tpl

Zeile 19

von
(Im Warenkorb bei den Steps herausnehmen des Links für “Adresse wählen”)

[{assign var=showStepLinks value=true}]

in

[{assign var=showStepLinks value=false}]

weiter im nächsten Post…

Dann ändern wir die core/smarty/Smarty_Compiler.class.php

Zeile 969-1014
(Hier wird dem Compiler die Funktionalität zur Vererbung beigebracht)

 function _compile_include_tag($tag_args)
    {
        $attrs = $this->_parse_attrs($tag_args);
        $arg_list = array();

        if (empty($attrs['file'])) {
            $this->_syntax_error("missing 'file' attribute in include tag", E_USER_ERROR, __FILE__, __LINE__);
        }

        foreach ($attrs as $arg_name => $arg_value) {
            if ($arg_name == 'file') {
                $include_file = $arg_value;
                continue;
            } else if ($arg_name == 'assign') {
                $assign_var = $arg_value;
                continue;
            }
            if (is_bool($arg_value))
                $arg_value = $arg_value ? 'true' : 'false';
            $arg_list[] = "'$arg_name' => $arg_value";
        }

        $output = '<?php ';

        if (isset($assign_var)) {
            $output .= "ob_start();
";
        }

        $output .=
            "\$_smarty_tpl_vars = \$this->_tpl_vars;
";


        $_params = "array('smarty_include_tpl_file' => " . $include_file . ", 'smarty_include_vars' => array(".implode(',', (array)$arg_list)."))";
        $output .= "\$this->_smarty_include($_params);
" .
        "\$this->_tpl_vars = \$_smarty_tpl_vars;
" .
        "unset(\$_smarty_tpl_vars);
";

        if (isset($assign_var)) {
            $output .= "\$this->assign(" . $assign_var . ", ob_get_contents()); ob_end_clean();
";
        }

        $output .= ' ?>';

        return $output;

    }

in

function _compile_include_tag($tag_args)
    {
        $attrs = $this->_parse_attrs($tag_args);
       // $scope_action = "\$this->_tpl_vars = array_merge((array)\$_smarty_tpl_vars,\$GLOBALS[\"_smarty_tpl_vars_temp\"]);
";
        $scope_action = "\$this->_tpl_vars = array_merge((array)\$_smarty_tpl_vars, (array)\$GLOBALS[\"_smarty_tpl_vars_temp\"]);
";
        $arg_list = array();

        if (empty($attrs['file'])) {
            $this->_syntax_error("missing 'file' attribute in include tag", E_USER_ERROR, __FILE__, __LINE__);
        }

        foreach ($attrs as $arg_name => $arg_value) {
            if ($arg_name == 'file') {
                $include_file = $arg_value;
                continue;
            } else if ($arg_name == 'assign') {
                $assign_var = $arg_value;
                continue;
            }
            
            // ADD: Startin block
 else if( $arg_name == 'scope' )
 {
 $scope = @$this->_dequote($arg_value);
 if( $scope != 'local' &&
 $scope != 'parent' &&
 $scope != 'global')
 $this->_syntax_error("invalid 'scope' attribute value");
 if( $scope == 'parent' )
 $scope_action = "";
 if( $scope == 'global' )
 {
 $scope_action = "".
 "\$array_diff = array_diff( array_keys(\$this->_tpl_vars), array_keys(\$_smarty_tpl_vars) );".
 "foreach( \$array_diff as \$key=>\$value ){".
 "\$GLOBALS[\"_smarty_tpl_vars_temp\"][\$value] = \$this->_tpl_vars[\$value];
".
 "}";
 }
 }
 // Ending block
 
            
            if (is_bool($arg_value))
                $arg_value = $arg_value ? 'true' : 'false';
         //ori
           // $arg_list[] = "'$arg_name' => $arg_value";
          
          // REPLACE THIS LINE WITH THE NEXT TWO
 // $arg_list[] = "'$arg_name' => $arg_value";
 if( $arg_name != 'scope' )
 $arg_list[] = "'$arg_name' => $arg_value";

        }

        $output = '<?php ';

        if (isset($assign_var)) {
            $output .= "ob_start();
";
        }

        $output .=
            "\$_smarty_tpl_vars = \$this->_tpl_vars;
";


        $_params = "array('smarty_include_tpl_file' => " . $include_file . ", 'smarty_include_vars' => array(".implode(',', (array)$arg_list)."))";
        $output .= "\$this->_smarty_include($_params);
" .
        // REPLACE THIS LINE WITH THE NEXT ONE
 // "\$this->_tpl_vars = \$_smarty_tpl_vars;
" .
 $scope_action."
".

 "unset(\$_smarty_tpl_vars);
";
/*        original code
 "\$this->_tpl_vars = \$_smarty_tpl_vars;
" .
 "unset(\$_smarty_tpl_vars);
";        */
        
        
        //ori
       // "\$this->_tpl_vars = \$_smarty_tpl_vars;
" .
     //  "unset(\$_smarty_tpl_vars);
";

        if (isset($assign_var)) {
            $output .= "\$this->assign(" . $assign_var . ", ob_get_contents()); ob_end_clean();
";
        }

        $output .= ' ?>';

        return $output;

    }

Dieser Code stammt aus der Mailingliste


Fertig :slight_smile:

Verbesserungsvorschläge sind gerne gesehen.

Vll kann man ja den ein oder anderen Code noch optimieren oder vereinfachen.

Das Mindestbrestellmengensystem ist für Oxid CE 4.5.9 Azure Theme
für das ältere Versionen bzw. Basix muss nicht an der Smarty_Compiler.class.php rumgeschraubt werden da der Basketcontent nicht included wird sondern in der gleichen Datei vorliegt.

Noch ein Vielen Dank an Earlybird der mir die ganze zeit für Fragen und Antworten zur Seite stand.

Gruß
Fabi

PS.: in der tpl/widget/minibasket/minibasket.tpl muss für endkunden shops mein Code noch ein bisschen abgeändert werden da der Kunde bei mir immer eingelogged sein muss das er einkaufen kann daher ist die If Abfrage bei mir nebensächlich