PHP Versandkostenregeln

CodeSwagg

Newbie
Registriert
Okt. 2016
Beiträge
5
Mahlzeit,

ich bin ein absoluter Noob und verzweifel momentan an einer Aufgabe, die ich dem Script hinzufügen soll.
Leider weiss ich nicht weiter...

Aufgabe:

Bei Artikel mit product_code unter 100 sind die Versandkosten 0,70€.
Bei Artikel mit product_code über 100 sind die Versandkosten 6,99€.
Habe ich beide (product_code < 100 und product_code > 100) im Warenkorb,
bleiben die Versandkosten 6,99€.


Problem:

Im folgendem Script klappt das nicht so ganz.
Entweder habe ich als Versandkosten 0,70€ oder 6,99€ - kommt darauf an, was der Kunde als letztes in den Warenkorb gelegt hat.
Wie erreiche ich also, dass die Versandkosten bei 6,99€ bleiben selbst wenn ich als letztes Artikel X (product_code < 100) in den Warenkorb lege ?

PHP:
<?php

if(isset($_SESSION["products"]) && count($_SESSION["products"])>0){
$total 			= 0;
$list_tax 		= '';
$gs = 0.70;
$vfree = "Versandkostenfrei";

$cart_box 		= '<ul class="view-cart">';

foreach($_SESSION["products"] as $product){ //Print each item, quantity and price.
$product_name = $product["product_name"];
$product_qty = $product["product_qty"];
$product_price = $product["product_price"];
$product_code = $product["product_code"];
                                                     		
$item_price 	= ($product_price * $product_qty);  // price x qty = total item price
$cart_box 		.=  "<li class=\"view-cart-total\">$product_code &ndash; $product_name &ndash; Anzahl : $product_qty = <strong>" .number_format($item_price, 2, ",", "."). "&nbsp;".$currency."</strong></li>";   
$subtotal 		= ($product_price * $product_qty); //Multiply item quantity * price
$total 			= ($total + $subtotal); //Add up to total price

}
// MEIN VERSUCH
if($product_code < 100){
$shipping_cost = $gs;} //Gutschein-Versandkosten  
elseif($product_code > 100){
$shipping_cost = 6.99;} //Gutschein-Versandkosten     
else {$shipping_cost = 6.99;}      
                                                            
$grand_zw = number_format($total, 2, ",", "."); //Zwischensumme
// if($grand_zw > 20){$shipping_cost = 0; $gs = 0;} //Versandkostenfrei wenn Zwischensumme>20€    
$grand_total = $total + $shipping_cost; //Gesamtbetrag                          

foreach($taxes as $key => $value){ //list and calculate all taxes in array
$tax_amount 	= ($grand_total - ($grand_total / 119 * 100)); //MwSt
$tax_item[$key] = $tax_amount;
$grand_total 	= $grand_total + 0; 
}

foreach($tax_item as $key => $value){ //taxes List
$list_tax .= $key. ' ' .number_format($value, 2, ",", "."). '&nbsp;'.$currency. '<br />';
}
                                                       	

$grand_netto = ($grand_total - $tax_amount);
$shipping_cost = ($shipping_cost)?'Versandkosten = '. number_format($shipping_cost, 2, ",", ".").' '.$currency.'<br />':'';

//Print Shipping, VAT and Total
$cart_box .= "<li class=\"view-cart-total\"><strong>Zwischensumme = $grand_zw $currency</strong></li><li class=\"view-cart-total\">$shipping_cost</li><li class=\"view-cart-total\"><strong>Gesamtbetrag = " .number_format($grand_total, 2, ",", "."). "&nbsp;".$currency."</strong></li><li class=\"view-cart-total\">Nettobetrag = " .number_format($grand_netto, 2, ",", "."). "&nbsp;".$currency."</li><li class=\"view-cart-total\">$list_tax</li>";
$cart_box .= "</ul>";


echo $cart_box;
} 
else{

echo "Der Warenkorb ist leer.";
}
?>

Kann mir jemand helfen ?
 
Die schnellste Lösung: Schau nach, ob die Versandkosten schon auf 6.99 gesetzt sind, und ändere sie nicht mehr, falls das der Fall ist.
 
hi,
In der foreach-Schleife in welcher der product_code ausgelesen wird, immer folgendes machen:
$max_product_code= max($max_product_code, $product_code);

Und nach der Schleife kannst du dann deinen Vergleich anhand von $max_product_code.

Ansonsten:
magic numbers sind schlechter stil (Beispiel: 119)

hth
 
in der config.php auch 6.99

PHP:
<?php
$db_username        = 'root'; //USERNAME
$db_password        = ''; //PASSWORD
$db_name            = 'ssv1'; //DB_NAME
$db_host            = 'localhost'; //HOST

$currency			= '&euro;'; //WÄHRUNG
$shipping_cost		= 6.99; //ZUSTELLKOSTEN
$taxes				= array( //MEHRKOSTEN
							'MwSt =' => 0);

$mysqli_conn = new mysqli($db_host, $db_username, $db_password,$db_name); //MYSQL CONNECT!
if ($mysqli_conn->connect_error) {//ERROR OUTPUT!
    die('Error : ('. $mysqli_conn->connect_errno .') '. $mysqli_conn->connect_error);
}
Ergänzung ()

Danke für eure Antwort.

Die schnellste Lösung: Schau nach, ob die Versandkosten schon auf 6.99 gesetzt sind, und ändere sie nicht mehr, falls das der Fall ist.

Schon probiert und bleibt beim Problem.

In der foreach-Schleife in welcher der product_code ausgelesen wird, immer folgendes machen:
$max_product_code= max($max_product_code, $product_code);

Und nach der Schleife kannst du dann deinen Vergleich anhand von $max_product_code.

Kannst du das näher ausführen bzw. anhand eines Beispiels zeigen ?


Ich experimentiere mal weiter...
 
CodeSwagg schrieb:
Kannst du das näher ausführen bzw. anhand eines Beispiels zeigen ?

Code:
<?php
$gs = 0.70;  //Gutschein-Versandkosten  

$product_codes = array(50, 24, 123);
$max_product_code = 0;
foreach ($product_codes as $product_code) {
   $max_product_code = max($max_product_code, $product_code);
}

echo $max_product_code.PHP_EOL;
if ($max_product_code < 100){
  $shipping_cost = $gs; 
} else {
  //normale Versandkosten
  $shipping_cost = 6.99;
}
 
Code:
    $normal_shipping_cost = 6.99;
    $max_product_code = 100;
    $shipping_cost = $gs;

    foreach ($_SESSION["products"] as $product) {
        /* ... */

        // Versandkosten anpassen
        if($product_code > $max_product_code && $shipping_cost != $normal_shipping_cost) {
            $shipping_cost = $normal_shipping_cost;
        }

        /* ... */
    }

Ungetestet!
 
Nice, mit Antwort hatte ich nicht mehr gerechnet! Natürlich habe ich das Wochenende nicht viel erreichen können, weil ich nicht genau wusste wo hinten und vorne ist:watt: Aber das meinte ich ja mit :"Ich bin ein Noob!"...

$product_codes = array(50, 24, 123);
$max_product_code = 0;
foreach ($product_codes as $product_code) {
$max_product_code = max($max_product_code, $product_code);
}

echo $max_product_code.PHP_EOL; // Ausgabe höchster WERT?
if ($max_product_code < 100){
$shipping_cost = $gs;
} else {
//normale Versandkosten
$shipping_cost = 6.99;
}

Habs versucht irgendwie einzubauen. Der gibt dann den letzten Wert vom Array aus.Die Versandkosten bleiben , egal was im Warenkorb ist, auf 0,7€.


$normal_shipping_cost = 6.99;
$max_product_code = 100;
$shipping_cost = $gs;

foreach ($_SESSION["products"] as $product) {
/* ... */

// Versandkosten anpassen
if($product_code > $max_product_code && $shipping_cost != $normal_shipping_cost) {
$shipping_cost = $normal_shipping_cost;
}

/* ... */
}

Da bleibts irgendwie auf 6,99€. Egal, was im Warenkorb ist... :freak:


Sorry, ich glaub ich bin zu blöd! :lol:
Ergänzung ()

Das hier habe ich gestern zusammen gefrickelt und auch nur durch externe Hilfe :

PHP:
<?php
if(isset($_SESSION["products"]) && count($_SESSION["products"])>0){
  $total 			= 0;
  $list_tax 		= '';
  $gs = 0.70;
  $vfree = "Versandkostenfrei";
  
  $cart_box 		= '<ul class="view-cart">';
  foreach($_SESSION["products"] as $product){ //Print each item, quantity and price.
  $product_name = $product["product_name"];
  $product_qty = $product["product_qty"];
  $product_price = $product["product_price"];
  $product_code = $product["product_code"];
                                                     		
  $item_price 	= ($product_price * $product_qty);  // price x qty = total item price
  $cart_box 		.= "<li class=\"view-cart-total\">$product_code &ndash; $product_name &ndash; Anzahl : $product_qty = <strong>" .number_format($item_price, 2, ",", "."). "&nbsp;".$currency."</strong></li>";   
  $subtotal 		= ($product_price * $product_qty); //Multiply item quantity * price
  $total 			= ($total + $subtotal); //Add up to total price
  
  // VERSANDKOSTEN!
  if($product_code < 100) {
  $shipping_cost = $gs;
  }
  if(count($_SESSION["products"])>1) {
  $shipping_cost = 6.99;
  }

}
                                                            
$grand_zw = number_format($total, 2, ",", "."); //Zwischensumme
//if($grand_zw > 20){$shipping_cost = 0; $gs = 0;} //Versandkostenfrei wenn Zwischensumme>20€    
$grand_total = $total + $shipping_cost; //Gesamtbetrag                          

foreach($taxes as $key => $value){ //list and calculate all taxes in array
$tax_amount 	= ($grand_total - ($grand_total / 119 * 100)); //MwSt
$tax_item[$key] = $tax_amount;
$grand_total 	= $grand_total + 0; 
}

foreach($tax_item as $key => $value){ //taxes List
$list_tax .= $key. ' ' .number_format($value, 2, ",", "."). '&nbsp;'.$currency. '<br />';
}
                                                     	

$grand_netto = ($grand_total - $tax_amount);
$shipping_cost = ($shipping_cost)?'Versandkosten = '. number_format($shipping_cost, 2, ",", ".").' '.$currency.'<br />':'';

//Print Shipping, VAT and Total
$cart_box .= "<li class=\"view-cart-total\"><strong>Zwischensumme = $grand_zw $currency</strong></li><li class=\"view-cart-total\">$shipping_cost</li><li class=\"view-cart-total\"><strong>Gesamtbetrag = " .number_format($grand_total, 2, ",", "."). "&nbsp;".$currency."</strong></li><li class=\"view-cart-total\">Nettobetrag = " .number_format($grand_netto, 2, ",", "."). "&nbsp;".$currency."</li><li class=\"view-cart-total\">$list_tax</li>";
$cart_box .= "</ul>";


echo $cart_box;
} 
else{

echo "Der Warenkorb ist leer.";
}
?>

Wenn ich dann einen Artikel ( produkt_code = 94-97) im Warenkorb liegen habe, ist 0,7€.
Ab 2 Artikel ( product_code EGAL ) sind automatisch 6,99€.

Aber selbst bei 2x, 3x, 4x Artikel X soll es bei 0,7 bleiben.
Erst wenn noch Artikel Y (ab product_code 100) im Warenkorb liegt, soll der Versand auf 6,99 gesetzt werden.
 
CodeSwagg schrieb:
Habs versucht irgendwie einzubauen. Der gibt dann den letzten Wert vom Array aus.Die Versandkosten bleiben , egal was im Warenkorb ist, auf 0,7€.
hi,
ja, der Code gibt einmal den maximalen Wert aus dem product_codes-Array aus (waren nur Beispieldaten, dass es ausgerechnet das letzte war war eher Zufall).

Nochmal von vorne:
Du hast die Anforderung, dass die Versandkosten davon abhängig sind, ob im Warenkorb ein product_code größer oder gleich 100 enthalten sind oder nicht.
Dazu musst du also wissen was der höchste product_code-Wert ist.
Dein im ersten Post gezeigter Code nimmt nicht den höchsten product_code, sondern immer den letzten.
Dein Code funktioniert nur, weil PHP (IMHO) so kaputt ist, die Variable $product_code nach der Schleife nicht als undefined zu deklarieren.
Stichwort Gültigkeitsbereich, bzw hier der Handbuch-Eintrag:
http://php.net/manual/en/language.variables.scope.php


Alles was du machen musst ist, meinen Beispielcode auf deinen Code anzuwenden.
 
Ich empfehle aber mal an dieser Stelle: PHP: The Right Way - Code Style Guide
Einfach mal den phpcbf drueber jagen um den Code wenigstens leserlich zu machen.
Eine Template Engine kann auch nicht schaden :D

Habe das Ding aus reiner Langeweile mal umgeschrieben. Die Mehrwertsteuer macht mir in deinem und meinem Code aber noch sorgen. Die muss auf jedenfall anders berechnet werden. :D
Code:
<?php

function calculateCart($products, $settings = [])
{
    $cart = [
        'settings' => [
            'basicShippingCost' => 0.7,
            'normalShippingCost' => 6.99,
            'maxProductCode' => 100,
            'freeShippingAt' => 20,
            'currency' => 'EUR',
            'taxes' => [
                // 'MwSt 7%' => 7,
                'MwSt 19%' => 19,
            ],
        ],
        'shippingCost' => 0,
        'subTotal' => 0,
        'total' => 0,
        'products' => [],
    ];

    // merge settings
    $cart['settings'] = array_merge($cart['settings'], $settings);

    // set default shipping costs
    $cart['shippingCost'] = $cart['settings']['basicShippingCost'];

    foreach ($products as $product) {
        $product['subTotal'] = $product['price'] * $product['qty'];
        // $product['taxTotal'] = $product['price'] + ($product['subTotal'] * $product['tax'] / 100);
        // $product['taxAmount'] = $product['subTotal'] * $product['tax'] / 100;

        $cart['products'][] = $product;
        $cart['subTotal'] += $product['subTotal'];

        // change shipping costs if product code is higher then the configured value
        if ($product['code'] > $cart['settings']['maxProductCode'] && $cart['shippingCost'] != $cart['settings']['normalShippingCost']) {
            $cart['shippingCost'] = $cart['settings']['normalShippingCost'];
        }
    }

    // if($cart['subTotal'] > $cart['settings']['freeShippingAt']) {
    //     $cart['shippingCost'] = 0;
    // }

    $cart['total'] += $cart['subTotal'] + $cart['shippingCost'];

    foreach ($cart['settings']['taxes'] as $taxName => $taxValue) {
        //list and calculate all taxes in array
        $cart['taxItems'][$taxName] = ($cart['total'] - ($cart['total'] * $taxValue / 100));
        $cart['nettoTotal'] = $cart['total'] - ($cart['total'] * $taxValue / 100);
    }

    return $cart;
}

function currencyFormat($value, $currency = '')
{
    $currency = trim($currency);

    return sprintf('%s %s', number_format($value, 2, ',', '.'), $currency);
}

function createCartOutput($cart)
{
    $htmlOutput = '<ul class="view-cart">';
    $currency = $cart['settings']['currency'];

    foreach ($cart['products'] as $product) {
        $htmlOutput .= '<li class="view-cart-total">'.$product['code'].' &ndash; '.$product['name'];
        $htmlOutput .= ' &ndash; Anzahl : '.$product['qty'].' = <strong>'.currencyFormat($product['subTotal'], $currency);
        $htmlOutput .= '</strong></li>';
    }

    $htmlOutput .= '<li class="view-cart-total"><strong>Zwischensumme = '.$cart['subTotal'].' '.$currency.'</strong></li>';
    $htmlOutput .= '<li class="view-cart-total">'.($cart['shippingCost'] > 0 ? 'Versandkosten = '.currencyFormat($cart['shippingCost'], $currency) : 'Versandkostenfrei').'</li>';

    $htmlOutput .= '<li class="view-cart-total"><strong>Gesamtbetrag = '.currencyFormat($cart['total'], $currency).'</strong></li>';
    $htmlOutput .= '<li class="view-cart-total">Nettobetrag = '.currencyFormat($cart['nettoTotal'], $currency).'</li>';
    $htmlOutput .= '<li class="view-cart-total">';

    foreach ($cart['taxItems'] as $name => $amount) {
        //taxes List
            $htmlOutput .= $name.' '.currencyFormat($amount, $currency).'<br />';
    }
    $htmlOutput .= '</li>';
    $htmlOutput .= '</ul>';

    return $htmlOutput;
}

$_SESSION['products'] = [
    [
        'name' => 'Product 1',
        'qty' => 1,
        'price' => 10,
        'code' => 10,
        'tax' => 19,
    ],
    [
        'name' => 'Product 2',
        'qty' => 1,
        'price' => 20,
        'code' => 120,
        'tax' => 19,
    ],
    [
        'name' => 'Product 3',
        'qty' => 1,
        'price' => 30,
        'code' => 30,
        'tax' => 19,
    ],
    [
        'name' => 'Product 4',
        'qty' => 2,
        'price' => 40,
        'code' => 40,
        'tax' => 19,
    ],
];

if (!isset($_SESSION['products']) || count($_SESSION['products']) === 0) {
    echo 'Der Warenkorb ist leer.';
    return;
}

$products = $_SESSION['products'];

$cart = calculateCart($products);

echo '<pre>';
print_r($cart);
echo createCartOutput($cart);
echo '</pre>';
 
Wow :o Mal eben aus Langeweile so einen Code rauszuhauen :
RESPEKT! Was meine Skills betrifft, bin ich eher noch ganz weit am Anfang. Deshalb erstmal ein fettes Dankeschön.
Mal schauen, was sich mit deinem Code machen lässt.

Ich empfehle aber mal an dieser Stelle: PHP: The Right Way - Code Style Guide
Einfach mal den phpcbf drueber jagen um den Code wenigstens leserlich zu machen.
Eine Template Engine kann auch nicht schaden

Auch hier danke für den Tipp!
 
Zurück
Oben