Categories
Code-Schnipsel News Plugins WooCommerce Wordpress

WooCommerce – Ein Shop-Plugin für WordPress – Teil 8

In den letzten Teilen ging es hauptsächlich darum, den Checkout des WordPress Plugins WooCommerce so für den deutschen Markt zu gestalten, dass es auf der einen Seite keine rechtlichen Bedenken gibt und auf der anderen Seite die Gestaltung funktionell und optisch ansprechend ist. Meiner Meinung nach ist uns dies gut gelungen. Nun ist zwar der Bestellvorgang abgeschlossen, aber natürlich wollen und können wir unsere Kunden damit nicht im Regen stehen lassen, sondern wollen die getätigte Bestellung bestätigen. Einmal direkt auf dem heimischen Bildschirm, aber auch in Form einer E-Mail Bestätigung.

Abschluss der Bestellung von WooCommerce

Hier lauert eine weitere Hürde für den deutschen Markt. Bevor wir aber näher auf die Details eingehen, möchte ich Euch kurz in einem vorher- / nachher-Vergleich zeigen, wie bei mir der Bestellabschluss vom WooCommerce Plugin auf dem Bildschirm und durch die begleitende E-Mail aussieht bzw. aussah:

Bestellübersicht WooCommerce - vorher:

Bestellübersicht WooCommerce vorher

Bestellübersicht WooCommerce - nachher:

Bestellübersicht WooCommerce - nachher

Die Änderungen in der Nachher-Ansicht habe ich markiert. Einige dieser optischen Veränderungen habe ich nachträglich auch in den WooCommerce Checkout einfließen lassen. Also der Reihe nach.

Zusätzliche Spalten für das Bild, den Einzelpreis und für die Menge einfügen

Bevor wir die einzelnen Schritte umsetzen, kopiert bitte, wenn noch nicht geschehen, die "order-details.php" aus dem Ordner "woocommerce/templates/order" in EUREN "woocommerce/templates/order"-Ordner in EUREM Theme-Verzeichnis. Noch einmal zum Verständnis: Dies ist wirklich wichtig an dieser Stelle. Denn wenn Ihr mit den Original-Dateien von WooCommerce arbeitet, lauft Ihr Gefahr, dass im Rahmen eines WooCommerce Updates alle Eure individuellen Änderungen verloren gehen. Und WooCommerce hat in letzter Zeit viele Updates veröffentlicht!

Öffnet die "order-detials.php" und navigiert zu folgender Stelle:

<h2><?php _e( 'Order Details', 'woocommerce' ); ?></h2>
<table class="shop_table order_details">
	<thead>
		<tr>
			<th class="product-name"><?php _e( 'Product', 'woocommerce' ); ?></th>
			<th class="product-total"><?php _e( 'Total', 'woocommerce' ); ?></th>
		</tr>
	</thead>

Vor Zeile 5 fügen wir die Spaltenüberschrift "Bild" ein und zwischen die beiden markierten Zeilen 5 und 6 kommt der Code für die neuen Spalten-Überschriften für den Einzelpreis und die Menge.

<h2><?php _e( 'Order Details', 'woocommerce' ); ?></h2>
<table class="shop_table order_details">
	<thead>
		<tr>
			<th class="product-name"><?php echo "Bild" ?></th>						<!-- Thumbnail -->
			<th class="product-name"><?php _e( 'Product', 'woocommerce' ); ?></th>
			<th class="product-name"><?php echo "Einzelpreis" ?></th>				<!-- Einzelpreis in Tabelle einfügen -->
			<th class="product-name"><?php echo "Menge" ?></th>						<!-- Spalte mit Menge einfügen -->
			<th class="product-total"><?php _e( 'Total', 'woocommerce' ); ?></th>
		</tr>
	</thead>

Jetzt müssen wir noch die übrige Tabelle in die richtige Form bringen. Weiterhin habe ich bei der Bestellübersicht von WooCommerce den Hinweis, dass alle Preise inkl. Mehrwertsteuer und Versandkosten sind, anders gelöst. Dafür habe ich die entsprechenden Summenzeilen mit einem Sternchen versehen und unter die Tabelle die Hinweiszeile gepackt. Dies geschieht dann wieder mit einem Hook. Dazu aber später mehr. Hier der Code für die Tabelle. Sucht Euch die entsprechende Passage heraus, die hinzugefügten bzw. geänderten Zeilen habe ich markiert.

<?php
		if ( $totals = $order->get_order_item_totals() ) foreach ( $totals as $total ) :
			?>
			<tr>
				<th></th>																<!-- leere Spalte einfügen -->
				<th scope="row"><?php echo $total['label']; ?><sup><span style="color:red; font-size:11px;">*</span></sup></th>		<!-- einfuegen * für Hinweis auf MwSt. und Versand; Einbindung über Hook 'woocommerce_order_details_after_order_table' in functions.php -->
				<th></th>																<!-- leere Spalte einfügen -->
				<th></th>																<!-- leere Spalte einfügen -->
				<td><?php echo $total['value']; ?></td>
			</tr>
			<?php
		endforeach;
	?>

Das Ergebnis bis hierhin sieht so aus:

Bestellübersicht WooCommerce

Wir Ihr seht, ist die Tabelle halbfertig. Die Inhalte stimmen noch nicht, aber dies ist nicht weiter schlimm. Die eingefügten bzw. ergänzten Code-Zeilen sind für die Überschriften und für den zusammenfassenden Block unter den Produktdetails verantwortlich. Mit der Auflistung der Produkte beschäftigen wir uns jetzt.

WooCommerce Bestellübersicht - Produkt-Loop

Dazu schauen wir uns jetzt den Block mit der "foreach"-Schleife für die Produktauflistung an:

if (sizeof($order->get_items())>0) {

			foreach($order->get_items() as $item) {

				$_product = get_product( $item['variation_id'] ? $item['variation_id'] : $item['product_id'] );

				echo '
					<tr class = "' . esc_attr( apply_filters( 'woocommerce_order_table_item_class', 'order_table_item', $item, $order ) ) . '">
						<td class="product-name">' .
							apply_filters( 'woocommerce_order_table_product_title', '<a href="' . get_permalink( $item['product_id'] ) . '">' . $item['name'] . '</a>', $item ) . ' ' .
							apply_filters( 'woocommerce_order_table_item_quantity', '<strong class="product-quantity">&times; ' . $item['qty'] . '</strong>', $item );

				$item_meta = new WC_Order_Item_Meta( $item['item_meta'] );
				$item_meta->display();

				if ( $_product && $_product->exists() && $_product->is_downloadable() && $order->is_download_permitted() ) {

					$download_file_urls = $order->get_downloadable_file_urls( $item['product_id'], $item['variation_id'], $item );

					$i     = 0;
					$links = array();

					foreach ( $download_file_urls as $file_url => $download_file_url ) {

						$filename = woocommerce_get_filename_from_url( $file_url );

						$links[] = '<small><a href="' . $download_file_url . '">' . sprintf( __( 'Download file%s', 'woocommerce' ), ( count( $download_file_urls ) > 1 ? ' ' . ( $i + 1 ) . ': ' : ': ' ) ) . $filename . '</a></small>';

						$i++;
					}

					echo implode( '<br/>', $links );
				}

				echo '</td><td class="product-total">' . $order->get_formatted_line_subtotal( $item ) . '</td></tr>';

				// Show any purchase notes
				if ($order->status=='completed' || $order->status=='processing') {
					if ($purchase_note = get_post_meta( $_product->id, '_purchase_note', true))
						echo '<tr class="product-purchase-note"><td colspan="3">' . apply_filters('the_content', $purchase_note) . '</td></tr>';
				}

			}
		}

Keine Angst. Ihr müsst dies nicht alles bis ins kleinste Detail verstehen. Wichtig ist das Gesamtverständnis, um die richtigen Bereiche für unsere Ergänzungen und Änderungen finden zu können. Als erstes ermitteln wir die Einzelpreise für unsere Artikel. Hier habe ich jetzt mein Beispiel schlecht gewählt, da die Einzelpreise mit den Produktgesamtpreisen übereinstimmen, aber Ihr wisst was ich meine. Dann müssen wir in der richtigen Spalte die jeweiligen Produktbilder (" $thumbnail = apply_filters( 'woocommerce_in_cart_product_thumbnail', $_product->get_image(), $values, $cart_item_key ") und unter dem Artikelnamen die Kurzbeschreibung ("apply_filters( 'woocommerce_short_description', $_product->post->post_excerpt ") einfügen. Da der Code-Block sich hierdurch in vielen Bereichen verändert, gebe ich hier nicht die Änderungen im Einzelnen, sondern nur den neuen Block in Gänze wieder. Alle Änderungen liegen zwischen dem ersten IF-Aufruf (" if (sizeof($order->get_items())>0) ") und der letzten geschweiften Klammer:

if (sizeof($order->get_items())>0) {

			foreach($order->get_items() as $item) {

				$_product = get_product( $item['variation_id'] ? $item['variation_id'] : $item['product_id'] );

				// Variable für Einzelpreisermittlung
						$product_price = get_option('woocommerce_tax_display_cart') == 'excl' ? $_product->get_price_excluding_tax() : $_product->get_price_including_tax();  // Produktpreis speichern
				?>
				<tr class = "' . esc_attr( apply_filters( 'woocommerce_order_table_item_class', 'order_table_item', $item, $order ) ) . '">
						<td class="product-thumbnail">
						<?php
								$thumbnail = apply_filters( 'woocommerce_in_cart_product_thumbnail', $_product->get_image(), $values, $cart_item_key );

								if ( ! $_product->is_visible() || ( ! empty( $_product->variation_id ) && ! $_product->parent_is_visible() ) )
									echo $thumbnail;
								else
									printf('<a href="%s">%s</a>', esc_url( get_permalink( apply_filters('woocommerce_in_cart_product_id', $values['product_id'] ) ) ), $thumbnail );
							?>
						</td>
						<?php /* Ende neuer Block*/ ?>

						<?php

				echo '

						<td class="product-name">' .
							apply_filters( 'woocommerce_order_table_product_title', '<a href="' . get_permalink( $item['product_id'] ) . '">' . $item['name'] . '</a>', $item ) . ' ' .
							apply_filters( 'woocommerce_short_description', $_product->post->post_excerpt ) . ' ' .							// Kurzbeschreibung einfügen
						'</td>
						<td>' .
							apply_filters('woocommerce_cart_item_price_html', woocommerce_price( $product_price ), $values, $cart_item_key   ) . ' ' .  //Einzelpreis einfügen
						'</td>
						<td>' .
							apply_filters( 'woocommerce_order_table_item_quantity', '<strong class="product-quantity"> ' . $item['qty'] . '</strong>', $item ); // &times entfernen

				$item_meta = new WC_Order_Item_Meta( $item['item_meta'] );
				$item_meta->display();

				if ( $_product && $_product->exists() && $_product->is_downloadable() && $order->is_download_permitted() ) {

					$download_file_urls = $order->get_downloadable_file_urls( $item['product_id'], $item['variation_id'], $item );

					$i     = 0;
					$links = array();

					foreach ( $download_file_urls as $file_url => $download_file_url ) {

						$filename = woocommerce_get_filename_from_url( $file_url );

						$links[] = '<small><a href="' . $download_file_url . '">' . sprintf( __( 'Download file%s', 'woocommerce' ), ( count( $download_file_urls ) > 1 ? ' ' . ( $i + 1 ) . ': ' : ': ' ) ) . $filename . '</a></small>';

						$i++;
					}

					echo implode( '<br/>', $links );
				}
				echo '</td><td class="product-total">' . $order->get_formatted_line_subtotal( $item ) . '</td></tr>';

				// Show any purchase notes
				if ($order->status=='completed' || $order->status=='processing') {
					if ($purchase_note = get_post_meta( $_product->id, '_purchase_note', true))
						echo '<tr class="product-purchase-note"><td colspan="3">' . apply_filters('the_content', $purchase_note) . '</td></tr>';
				}

			}
		}

Hinweis auf Mehrwertsteuer und Versand

Jetzt fehlt nur noch ein kleiner Teil, nämlich der Hinweis für unser kleines " * " auf die Mehrwertsteuer und den Versand. Dies erledigen wir mit einem WooCommerce Hook und der passenden Funktion. Beides kommt in Eure " functions.php ":

<?php
function mwst_order_table() {
?>
<sup><span style="color:red; font-size:11px;">*</span></sup> inkl. gesetzl. MwSt. und <a href="https://www.vertrieb-im-netz.de/versand/">Versand</a><br><br>
<?php
}
add_action ('woocommerce_order_details_after_order_table','mwst_order_table');
?>

Damit ist die Bestellübersicht von WooCommerce fertig. Im nächsten Teil gehe ich dann auf die Bestätigungs-Mail ein. Hier sind auch einige Änderungen bzw. Ergänzungen erforderlich, insbesondere was die eingangs angesprochene Hürde für den deutschen Markt betrifft. Dazu aber dann mehr im nächsten Teil. Ich hoffe, dass auch dieser Teil für Euch sinnvoll war und freue mich auf Euer Feedback.

[fb_share]
0 0 votes
Article Rating
Abonnieren
Benachrichtige mich bei
guest
25 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments
Petra
Petra
10 Jahre zuvor

Hallo Ralf,

leider habe ich noch eine Frage:

Die order-detail.php möchte ich gerne so abändern, dass
a)die Produktkurzbeschreibung entweder via CSS formatierbar ist und
b)die Artikelnummer einfügen.

In meiner review-order.php klappt a) schön mit

<?php echo '‘;
echo apply_filters( ‚woocommerce_short_description‘, $_product->post->post_excerpt );
echo “; ?>

bzw.

cart->get_item_data( $cart_item ); ?>

und für b) mit folgendem Code in der functions.php:

add_filter( ‚woocommerce_cart_item_name‘, ‚add_sku_in_cart‘, 20, 3);
function add_sku_in_cart( $title, $values, $cart_item_key ) {
$sku = $values[‚data‘]->get_sku();
return $sku ? $title . sprintf(„Artikelnr. %s“, $sku) : $title;

Hast du einen Tipp für mich?

LG!

Petra
Petra
10 Jahre zuvor
Reply to  Ralf

Hallo lieber Ralf,

in der order-details.php ist ein solches div nicht eingefügt. Leider verstehe ich von php so gut wie nichts, so dass ich den Block

‚ .
apply_filters( ‚woocommerce_order_table_product_title‘, ‚‚ . $item[’name‘] . ‚‚, $item ) . ‚ ‚ .
apply_filters( ‚woocommerce_short_descriptio // Kurzbeschreibung einfügenn‘, $_product->post->post_excerpt ) . ‚ ‚ .

nicht anzupassen weiß.

LG!

Petra
Petra
10 Jahre zuvor
Reply to  Petra

P.S.:

Das Formatierungsproblem habe ich mittels td.product-name {…} lösen können. Tomaten auf den Augen… sorry!

Für das Einfügen der Artikelnummer in der Bestellbestätigung hat das Einfügen von

echo $_product->get_sku();

nicht geholfen. Egal, wo ich den Code in der order-details.php einfüge, es zeigt keine Wirkung in der Tabelle oberhalb der Produktbeschreibung.

Petra
Petra
10 Jahre zuvor

Hallo lieber Ralf,

der letzte Code (mit dem Sternchen) wird mir leider nicht genommen. Ich erhalte Parse-Errors. Woran könnte das liegen?

LG!

Petra
Petra
10 Jahre zuvor
Reply to  Ralf

Hallo lieber Ralf,

ich übernehme die Code-Zeilen 1- 8 in meine functions.php, speichere und erhalte:

Parse error: syntax error, unexpected ‚<' in /…/…/…/wp-content/themes/celestino.free/functions.php on line 128

Zeile 128 ist der Beginn des o.g. Codeblocks, also das <?php.

Petra
Petra
10 Jahre zuvor
Reply to  Petra

Wenn ich das erste weglasse, funktioniert es.

Christian
Christian
10 Jahre zuvor

Hallo,
vielen Dank für deine sensationelle Arbeit und das du das alles teilst! Das ist nicht selbstverständlich. Danke vielmals!!

Ich habe soweit alles umgesetzt was du geschrieben hast. Mir fehlt jetzt noch die E-Mail und das PDF Template.
Wie weit bist du denn mit der E-Mail? Oder muss ich mich doch selbst versuchen? Weiß nicht ob ich es alleine schaffe 🙂

Grüße, Christian

Christian
Christian
10 Jahre zuvor
Reply to  Ralf

Ja das ist auch gut, daran hab ich gar nicht gedacht 🙂

Ne ich meinte die Tabellenauflistung. Das da auch Bild, Einzelpreis, Menge und MwSt/Versand Hinweis drin ist.

Gruß,
Christian

Christian
Christian
10 Jahre zuvor
Reply to  Ralf

Hi!
Ist es mit dem deutschen Recht nicht so, das man auch eine „Bestellung prüfen“ Seite benötigt? Also das nach dem Button „Kaufen“, nochmal eine Übersicht kommt und dort erst der Button „Kaufen“. Dann könnte man den Button auf der jetzigen auch „Bestellung prüfen“ nennen.

Gruß, Christian

Jana
10 Jahre zuvor

Hallo Ralf,

nach dem gestrigen Update (ich arbeite mit Datei-Kopien im eigenen Theme-Ordner) ist die Checkout-Seite völlig hinüber. Es werden überhaupt keine Bestelldetails mehr angezeigt; der Hintergrund ist auch weg und das komplette Layout ist verschoben. Ich geh mal davon aus, dass es größere Änderungen im Code gab? Also gerade an der foreach-Schleife hakt es…

Gruß,
Jana

Jana
10 Jahre zuvor
Reply to  admin

Hi Ralf,
ich meinte die E-Mail-Bestellbestätigung – sorry, das kam in meinem Beitrag nicht klar raus.
Bei den Dateien müsste es sich um die customer-processing-order.php bzw. die email-order-items.php handeln.
Falls du da irgendwas hast, kannst du es mir zu Bastelnd Testzwecke gerne schicken!
Klar arbeite ich mit einem Child-Theme 😉
Viele Grüße,
Jana

Jana
10 Jahre zuvor
Reply to  admin

Hi Ralf,
das hört sich doch super an! Ich brauche die zusätzlichen Spalten grundsätzlich nicht… evtl. aber den Hook, der MwSt. & Versand IN die Tabelle einbindet? Das wäre klasse 🙂 Wie hast du die AGB und die Widerrufsbelehrung angehängt? Als PDF? Wo kann man das einstellen?

Entschuldige, dass ich dich so bombardiere 😉

LG,
Jana

Jana
10 Jahre zuvor

Hallo!
Vielen, vielen, VIELEN Dank für dieses super-ausführlich und zu 100% funktionierende Tutorial!
Ich weiß nicht, wie viele Stunden Arbeit du mir damit erspart hast – ich bin absolut happy 🙂
Eine kurze Frage anbei: Wann ist mit Teil 9 zu rechnen?
Liebe Grüße,
Jana

Jana
10 Jahre zuvor
Reply to  admin

Hallo Ralf,
vielen Dank für deine Antwort.
Ich sitze gerade daran, die Tabelle in der Bestellbestätigung entsprechend deutschem Recht anzupassen.
Per Hook konnte ich immerhin schon die „MwSt. und Versand“-Zeile unterhalb der Tabelle einfügen und die Tabelle von 3 auf 5 Spalten erweitern (ganz ähnlich der Anleitung Teil 8) allerdings habe ich große Schwierigkeiten, die Tabelle weiter auszufüllen (Produktbild, Einzelpreis etc.). Oben im Beitrag wurde dafür die “foreach“-Schleife geändert – und genau das ist das Problem. Ich finde nirgends unter den E-Mail-Templates eine ähnliche Regelung… Weißt du da Rat?
Viele Grüße,
Jana

25
0
Would love your thoughts, please comment.x