Drupal Commerce mit Drupal 7

Fabian Müller

Version vom 02.11.2015


Inhaltsverzeichnis

1. Hinweise vorab
1.1. Über diese Seite und ihren Autor
1.2. CHANGELOG
1.3. Impressum
1.4. Datenschutzhinweise
2. Die Grundlagen
2.1. Installation
2.2. Aktivierung der deutschen Sprache
2.3. Artikel erstellen und anzeigen
2.4. Bild hinzufügen
2.5. Eine erste Testbestellung
2.6. Versandkosten
2.7. Ein eigener Abschnitt im Checkoutbereich
2.8. Allgemeine Geschäftsbedingungen (AGB) und Widerrufsbelehrung
2.9. Bestellungen

Abbildungsverzeichnis

2.1. Erste Darstellung unseres Artikels
2.2. Konfiguration der Anzeige des product types versendbarer Artikel
2.3. Konfiguration der Anzeige des Inhaltstyps Shopartikel
2.4. Darstellung des Artikels
2.5. Artikel mit Bild
2.6. Der Warenkorb
2.7. Bestellung abgeschlossen
2.8. Versandkosten konfigurieren
2.9. AGB und Widerrufsbelehrung

Kapitel 1. Hinweise vorab

1.1. Über diese Seite und ihren Autor

Auf drupalcommerceshop.de soll ein Platz mit Notizen zum Thema E-Commerce mit dem Drupalmodul Drupal Commerce entstehen.

Der Autor arbeitet als selbstständiger Entwickler (http://www.open-tk.de) im Bereich der PHP-Programmierung.

1.2. CHANGELOG

Auf der Seite CHANGELOG notiere ich stichpunktartig, was sich in welcher Version dieser Notizen geändert hat. Das Datum in der Datei beschreibt das Veröffentlichungsdatum der Änderungen.

1.3. Impressum

Fabian Müller
Fibigerstr. 275
22419 Hamburg
Tel.: +49 40 5390 8867
E-Mail: fabian.mueller@open-tk.de

1.4. Datenschutzhinweise

Die Hinweise zum Thema Datenschutz finden Sie auf der Seite Datenschutzhinweise.

Kapitel 2. Die Grundlagen

2.1. Installation

Die folgende Beschreibung geht davon aus, dass Sie Drupal 7 von http://www.drupal.org/project/drupal installiert haben. Außerdem benötigen Sie die Module von den Seiten

Jedes dieser Pakete enthält mehrere Module. Wenn Sie auf /admin/modules alle Module im Abschnitt Commerce aktivieren, werden die erforderlichen anderen Module automatisch ebenfalls aktiviert.

2.2. Aktivierung der deutschen Sprache

Folgende Schritte aktivieren die deutsche Sprache

  • Auf /admin/modules das Modul 'local' aktivieren.

  • Auf /admin/config/regional/language/add Sprache "German (Deutsch)" hinzufügen.

  • Auf /admin/config/regional/language Default auf German setzen. Die Seite /admin/config/regional/translate zeigt, dass aktuell 0% übersetzt ist

  • Das Modul l10n_update von http://drupal.org/project/l10n_update herunterladen und aktivieren.

  • Auf /admin/config/regional/translate/update auf den Link "Check manually" und anschließend auf den Button "Update translations" klicken.

    Sollten dabei Fehlermeldungen auftreten, achten Sie darauf, dass das Verzeichnis sites/all/translations vom Webserver beschreibbar ist.

  • Die Seite /admin/config/regional/translate zeigt nun 8455/9627 (87.83%), oder einen vergleichbar hohen Wert.

2.3. Artikel erstellen und anzeigen

Unter Drupal Commerce gibt es den Begriff product type, der nichts mit dem Begriff Inhaltstyp zu tun, der unter Drupal verwendet wird. Ein product type ist also kein Inhaltstyp. Nach der Installation von Drupal Commerce existiert genau ein product type, der den Namen product hat. Der Shopbetreiber kann beliebig viele weitere product types anlegen. Die Seite /admin/commerce/products/types listet alle product types. Dort gibt es außerdem einen Link zu einer Seite, auf der man einen weiteren product type anlegen kann. Wenn $productTypeName den Namen eines product types enthält, dann definiert man auf /admin/commerce/products/types/$productTypeName/fields, welche Felder $productTypeName enthalten soll. Auf /admin/commerce/products/types/$productTypeName/display trifft man Einstellungen bezüglich der Darstellung der Felder. Dort hat man auch die Möglichkeit, für bestimmte view modes (Line item, Node: Teaser, Admin display, ...) individuelle Darstellungen festzulegen. Dies ist also alles analog zu der Situation bei den Inhaltstypen, obwohl es sich bei einem product type wie gesagt nicht um einen Inhaltstyp handelt. Wir sehen das auch schon an der URL. Die beiden eben genannten Adressen beginnen mit /admin/commerce/. Pfade zum Bearbeiten der Inhaltstypen beginnen mit /admin/structure/, wie z. B. admin/structure/types/manage/article/fields zum Bearbeiten der Felder des Inhaltstyps "article".

Unser erstes Ziel soll die Erstellung einer Seite sein, die den Shopbesucher_innen einen Artikel zeigt, den sie in den Warenkorb legen und somit bestellen können. Das Wort Artikel wird im Folgenden ausschließlich in dieser Bedeutung verwendet und hat nichts mit dem Inhaltstyp mit dem Namen Article zu tun.

Zunächst müssen wir uns überlegen, von welchem product type unser Artikel sein soll. Um das System besser erklären zu können und um einen eigenen product type zu erstellen, verwenden wir nicht den Standard-product type von Drupal Commerce.

Wir nehmen an, dass wir in unserem Beispielshop gedruckte Bilder verkaufen wollen. Da wir diese unseren Kund_innen zusenden möchten, erstellen wir einen neuen product type mit dem Namen versendbarer Artikel. (Anmerkung: Ein gänzlich anderer product type wäre z. B. Downloadartikel, den man z. B. für herunterladbare Bilder oder Ebooks verwenden könnte.)

Den product type mit dem Namen versendbarer Artikel erstellen wir, indem wir auf /admin/commerce/products/types/add in das Feld "Name" den Wert versendbarer Artikel eintragen und auf "Produktart speichern" klicken. Die Seite /admin/commerce/products/types zeigt nun unseren neuen product type.

Nun wollen wir unseren konkreten Artikel, also ein konkretes versendbares Bild, anlegen. Das Bild, welches wir im nächsten Abschnitt hinzufügen werden, zeigt eine Fackel, eine fahrende Ubahn und den Mond. Wir nennen unseren Artikel "Durchfahrenes Mondfeuer".

Den Artikel Durchfahrenes Mondfeuer vom product type versendbarer Artikel erstellen wir auf der Seite /admin/commerce/products/add/versendbarer-artikel. (Anmerkung: Der Name unseres product types erscheint in der URL.) Auf der Seite schreiben wir "Durchfahrenes Mondfeuer" in das Feld Titel. In das Feld Produkt-Artikelnummer (SKU) schreiben wir 001 und in das Feld Preis schreiben wir 25.18. Mit einem Klick auf den Button "Produkt speichern" speichern wir unseren Artikel.

Die Seite /admin/commerce/products zeigt alle Artikel. Dort sollte nun unser Artikel mit dem Titel Durchfahrenes Mondfeuer und vom Typ versendbarer Artikel gelistet sein.

Wir haben also nun einen Artikel mit dem Namen (dem Titel) Durchfahrenes Mondfeuer vom product type versendbarer Artikel.

Eine wichtige Erkenntnis beim Verstehen des Systems ist, dass wir, obwohl wir ja unseren Artikel bereits angelegt haben, noch keinen Inhalt im Sinne eines "Drupalinhalts" erstellt haben. Die Seite /admin/content/node zeigt also, dass keine Inhalte vorhanden sind.

Eine weitere wichtige Erkenntnis ist, dass wir unseren angelegten Artikel jetzt auch noch gar nicht anzeigen können. Damit ist gemeint, dass die Seite node/add keinen Inhaltstyp anbietet, der in der Lage ist, unseren Artikel darzustellen. Gelistet werden dort ja jetzt lediglich die beiden Standard-Inhaltstypen von Drupal, nämlich "Article" und "Basic page" - und keiner von beiden kann unseren Artikel Durchfahrenes Mondfeuer anzeigen. Daher erstellen wir jetzt wie folgt einen Inhaltstyp, der dazu in der Lage ist.

  1. /admin/structure/types/add

    • Name: Shopartikel

    • Beschreibung: Inhalte dieses Types stellen Artikel vom Typ "versendbarer Artikel" dar.

    • Im Bereich Anzeigeeinstellungen die Option "Autor- und Datumsinformationen anzeigen" deaktivieren.

    • Auf Inhaltstyp speichern klicken.

  2. /admin/structure/types/manage/shopartikel/fields

    • Im Feld Neues Feld hinzufügen: den Wert anzuzeigender Artikel eintragen.

    • Im Dropdown-Menü in der Spalte Feldtyp den Wert Produktreferenz auswählen.

    • Im Dropdown-Menü in der Spalte Steuerelement den Wert Kontrollkästchen/Auswahlknöpfe auswählen.

    • Auf Speichern klicken.

  3. Auf der nun erscheinenden Seite auf den Button Feldeinstellungen speichern klicken, ohne irgendetwas auszufüllen.

  4. Auf der nun erscheinenden Seite folgende Aktionen durchführen:

    • Im Abschnitt Einstellungen für Shopartikel die Checkbox bei Pflichtfeld aktivieren.

    • Im Abschnitt "Warengruppen, die referenziert werden können", unseren neu angelegten product Type versendbarer Artikel auswählen.

    • Alle anderen Einstellungen unverändert lassen und auf Einstellungen speichern klicken.

Nun werden wir unser erstes gestecktes Ziel erreichen, nämlich die Erstellung einer Seite, die den Shopbesucher_innen unseren bereits erstellten Artikel anzeigt. Dazu erstellen wir einen Node vom Inhaltstyp Shopartikel, indem wir auf zunächst auf /node/add auf den Link Shopartikel klicken. Dadurch landen wir auf der Seite node/add/shopartikel, auf der wir folgende Eingaben machen.

  • Title: Nodetitle: Durchfahrenes Mondfeuer

    Wir setzen also den Titel auf Nodetitle: Durchfahrenes Mondfeuer, damit wir ihn vom Titel unseres Artikels, der ja Durchfahrenes Mondfeuer lautet, unterscheiden können. Dies dient zu Demonstrationszwecken, um das System besser zu verstehen.

  • Body: Von meinem Balkon aus, wo dieses Foto entstanden ist, kann man manchmal den Mond und gleichzeitig die Ubahn sehen. Dieses Foto hält bei einer Belichtungszeit von 20 Sekunden zusätzlich noch eine im Vordergrund platzierte Fackel fest. Durch die weit geschlossene Blende (f/14.0) kommt es zu den Strahlen am Mond. Die Nachbearbeitung des im RAW-Modus aufgenommenen Bildes habe ich mit dem Open Source Programm Darktable vorgenommen.

  • anzuzeigender Artikel: Hier wählen wir den einzigen bis jetzt vorhandenen Artikel aus, nämlich 001: Durchfahrenes Mondfeuer

  • Alles andere unverändert lassen und auf Speichern klicken.

Nun wurden wir direkt auf die Seite des gerade erstellten Nodes weitergeleitet. Das folgende Bild zeigt, wie der neu erstellte Node unseren Artikel anzeigt.

Abbildung 2.1. Erste Darstellung unseres Artikels

Erste Darstellung unseres Artikels

Man beachte, dass hier der Titel unseres Artikels nicht auftaucht. Hier steht lediglich der Titel unseres Nodes. (Um das zu sehen, wurde oben für den Node ein vom Artikel abweichender Titel eingegeben.) Auch die Artikelnummer unseres Artikels fehlt. Um das zu ändern, müssen wir uns weiter mit der Anzeige unseres Artikels befassen. Relevant dafür sind zwei Seiten, nämlich die folgenden beiden.

  1. admin/commerce/products/types/versendbarer-artikel/display

    Da die Adresse mit '/admin/commerce/products/types' beginnt, sieht man schon, dass es hier nicht um Inhaltstypen geht, sondern um product types. Diese Seite bietet die Möglichkeit, die Darstellung der Felder des product types versendbarer Artikel zu bearbeiten. Beachten Sie, dass hier die view modes Standard, Position und Beitrag: Anrisstext zur Verfügung stehen. Die Links zum Bearbeiten der view modes finden Sie rechts über der Tabelle. Das folgende Bild zeigt die Seite zur Bearbeitung der Anzeige des product types.

    Abbildung 2.2. Konfiguration der Anzeige des product types versendbarer Artikel

    Konfiguration der Anzeige des product types versendbarer Artikel

    Die Spalte Format zeigt für das Feld Preis aktuell den Wert Formatierter Betrag. Wählen Sie in dem Dropdown-Menü doch einmal den Wert ausgeblendet, speichern die Änderung und laden die Seite mit dem Artikel neu. Sie werden nun sehen, dass kein Preis mehr angezeigt wird. Da wir einen Preis anzeigen wollen, sollten Sie seine Anzeige nun wieder aktivieren. Wir können hier also die Anzeige des Preises aktivieren und deaktivieren. Da bei den Feldern Artikelnummer (SKU) und Titel in der Spalte Format der Wert sichtbar ausgewählt ist, würden wir wohl insbesondere aufgrund unserer Erfahrungen mit dem Preis erwarten, dass auf der Seite mit unserem Artikel auch die Artikelnummer und der Titel unseres Artikels erscheinen. Warum das nicht so ist, erläutert der folgende Punkt zwei.

  2. /admin/structure/types/manage/shopartikel/display

    Da die Adresse mit '/admin/structure/types' beginnt, sieht man schon, dass es hier um die Konfiguration von Inhaltstypen geht. Diese Seite bietet die Möglichkeit, die Darstellung der Felder des Inhaltstyps mit dem Namen Shopartikel anzupassen. Das folgende Bild zeigt einen Screenshot.

    Abbildung 2.3. Konfiguration der Anzeige des Inhaltstyps Shopartikel

    Konfiguration der Anzeige des Inhaltstyps Shopartikel

Auf der zweiten genannten Seite, also auf /admin/structure/types/manage/shopartikel/display, finden wir die Antwort darauf, warum die Artikelnummer und der Titel des Artikels nicht erscheinen: Die Anzeige der Felder ist bei dem Inhaltstypen deaktiviert, denn im Dropdown-Menü in der Spalte Format ist bei den beiden Feldern der Wert Ausgeblendet ausgewählt. Wenn wir dies in den Wert Sichtbar ändern, speichern und die Artikelseite neu laden, dann erscheinen die vermissten Felder. Der Artikel sollte nun so dargestellt werden, wie in dem folgenden Bild gezeigt.

Abbildung 2.4. Darstellung des Artikels

Darstellung des Artikels

Jetzt sehen wir sowohl den Titel unseres Nodes als auch den Titel unseres Artikels.

Damit ein Feld eines Artikels auf der Seite, die den Artikel darstellt, angezeigt wird, muss das Feld also sowohl bei den Anzeigeeinstellungen des product types als auch bei den Anzeigeeinstellungen des Inhaltstyps aktiviert werden.

Wir wollen nun allerdings die Anzeige des Titels von dem Artikel wieder deaktivieren, weil wir nicht zweimal die Nennung des Titels benötigen. Dazu setzen wir auf der Seite, auf der wir die Anzeige des Inhaltstyps Shopartikel bearbeiten können, also auf admin/structure/types/manage/shopartikel/display der Wert Format für das Feld Produkt: Titel auf ausgeblendet.

Der Text anzuzeigender Artikel in unserer Artikeldarstellung macht dort nicht viel Sinn. Daher deaktivieren wir die Anzeige des Textes auf der Seite, auf der wir die Anzeigeeinstellungen unseres Inhaltstyps Shopartikel bearbeiten können, also auf admin/structure/types/manage/shopartikel/display. Dort wählen wir im Dropdown-Menü in der Spalte Beschriftung des Feldes anzuzeigender Artikel den Wert Ausgeblendet. Nach Speichern und Neuladen der Artikelseite sehen wir, dass der Text wunschgemäß verschwunden ist.

Betrachten wir nun nochmal die Konfigurationsmöglichkeiten unseres Inhaltstyps Shopartikel etwas genauer. Dazu wollen wir einmal die Felder auf den folgenden beiden Seiten vergleichen:

  • /admin/structure/types/manage/shopartikel/fields

  • /admin/structure/types/manage/shopartikel/display

Es fällt auf, dass auf der Seite Anzeige verwalten (zweiter Link) Felder zu sehen sind, die auf der Seite Felder verwalten (erster Link) nicht erscheinen. Felder, die wir dem product type hinzugefügt haben, erscheinen auf der Seite Anzeige verwalten aber nicht auf der Seite Felder verwalten. Bei unserer aktuellen Konfiguration ist das lediglich das Feld Produkt: Bild. Ebenso erscheinen die Felder Produkt: Artikelnummer (SKU), Produkt: Titel und Produkt: Preis ausschließlich auf der Seite Anzeige verwalten. Die Seite Anzeige verwalten bietet also die Möglichkeit, Felder des Inhaltstyps und des product types zu mischen. Es kann also erst ein Feld des Inhaltstyps angezeigt werden, dann eins des product types, dann wieder eines des Inhaltstyps und so weiter.

Beachten Sie, dass Sie auf der Seite Anzeige verwalten das Feld anzuzeigender Artikel durch einen Klick auf das Zahnradsymbol konfigurieren können. Es gibt z. B. die Möglichkeit, ein Feld anzeigen zu lassen, mit dem der Shopbesucher angeben kann, wie oft er den Artikel bestellen möchte.

2.4. Bild hinzufügen

Wir wollen nun die Möglichkeit schaffen, ein Bild auf unserer Artikelseite anzuzeigen. Dazu müssen wir ein Feld für diesen Zweck erstellen, mit dem wir das Bild zeigen können. Die Frage ist, ob wir das Feld dem Inhaltstyp Shopartikel oder dem product type versendbarer Artikel hinzufügen wollen. Wir weisen das Feld unserem product type zu, weil es direkt mit dem product type verbunden sein soll und jeder Artikel vom Typ versendbarer Artikel ein Bild enthalten können soll. Das machen wir auf der Seite /admin/commerce/products/types/versendbarer-artikel/fields. Sie stellt ein Frontend zur Verwaltung der Felder, die dem product type mit dem Namen Shopartikel zugeordnet sind, zur Verfügung. Um ein neues Feld für das Bild hinzuzufügen, haben wir in der Zeile "Neues Feld hinzufügen" zwei Angaben zu machen:

  1. In das Feld Beschriftung schreiben wir Bild.

  2. In dem Dropdown-Menü Der zu speichernde Datentyp wählen wir Bild.

Wir bestätigen die Eingaben mit einem Klick auf "Speichern", klicken auf der nun erscheinenden Seite auf "Feldeinstellungen speichern" und nun, ohne irgendwelche Änderungen vorzunehmen, auf "Einstellungen speichern". Wir haben das Bildfeld dem product type hinzugefügt, nicht dem Inhaltstyp. Daher haben wir auf der Bearbeitungsseite des Nodes, der unseren Artikel anzeigt, nun auch keine Möglichkeit, ein Bild hochzuladen. Wir müssen das direkt auf der Bearbeitungsseite unseres Artikels machen. Zu der Seite gelangen Sie, indem Sie auf /admin/commerce/products bei unserem Artikel auf den Link "Bearbeiten" klicken. Laden Sie auf der Seite ein Bild hoch und klicken auf Produkt speichern. Das Bild sollte von den Abmessungen her nicht zu groß sein, weil es im Moment noch nicht automatisch verkleinert wird, sondern in der Originalgröße in die Artikelansichtsseite eingefügt wird.

Über dem Bild erscheint der Text Bild:. Seine Darstellung deaktivieren wir auf admin/commerce/products/types/versendbarer-artikel/display, indem wir für das Feld Bild den Wert in der Spalte Beschriftung auf Ausgeblendet setzen.

Auf admin/structure/types/manage/shopartikel/display ändern wir noch die Reihenfolge der Felder, indem wir die Zeilen mit Hilfe des Kreuzes zu Beginn jeder Zeile verschieben. Die neue Reihenfolge sollte Body, Produkt: Bild, Produkt: Artikelnummer (SKU), Produkt: Preis und dann anzuzeigender Artikel sein.

Wenn wir den Titel des Nodes noch von Nodetitle: Durchfahrenes Mondfeuer in Durchfahrenes Mondfeuer ändern, dann sollte die Darstellung des Artikels nun wie folgt aussehen:

Abbildung 2.5. Artikel mit Bild

Artikel mit Bild

2.5. Eine erste Testbestellung

Wenn wir unseren Artikel nun in den Warenkorb legen und als nicht eingeloggter Besucher die Seite /cart betrachten, dann sehen wir eine Darstellung wie in folgendem Screenshot.

Abbildung 2.6. Der Warenkorb

Der Warenkorb

Aktuell gibt es dort keine Möglichkeit, den Checkoutprozess abzuschließen. Das liegt daran, weil Seitenbesuchern der Rolle Gast die entsprechende Berechtigung fehlt. Auf der Seite /admin/people/permissions aktivieren wir daher für die Rolle Gast die Berechtigung Zugriff auf den Checkout. Dadurch wird auf der Warenkorbseite zusätzlich zu dem schon vorhandenen Button Warenkorb aktualisieren der Button Kasse angezeigt.

Standardmäßig wird für einen Kunden, der eine Bestellung abgeschlossen hat, ein neuer Benutzer angelegt, worüber der Kunde in einer Mail informiert wird. Dies wollen wir zunächst verhindern, indem wir auf /admin/config/workflow/rules die Regel Erstellen Sie ein neues Konto für eine anonyme Bestellung deaktivieren.

Durchlaufen Sie nun einmal den Checkoutprozess. Dabei müssen Sie auch eine Emailadresse eingeben. Zu Testzwecken sollten Sie hier einmal eine Emailadresse eingeben, die Sie bei dieser Drupalinstallation noch nicht verwendet haben. Wenn Sie den Bestellprozess komplett durchlaufen haben, sehen sie folgende Infoseite:

Abbildung 2.7. Bestellung abgeschlossen

Bestellung abgeschlossen

Wenn Sie dort auf den Link "view your order" klicken, erhalten Sie lediglich die Meldung Sie haben keine Zugriffsberechtigung für diese Seite. Der Link sollte eigentlich gar nicht angezeigt werden, weil ja gar kein neuer Benutzer erstellt wurde und sicher daher der Kunde auch nicht einloggen kann, um seine Bestellungen anzuschauen.

An die Emailadresse, die Sie im Checkoutprozess eingegeben haben, wurde eine Bestätigungsmail zu der Bestellung geschickt, die etwa wie folgt aussieht:

Vielen Dank für Ihre Bestellung 4 bei localhost.

Falls dies Ihre erste Bestellung bei uns war, erhalten Sie eine weitere
E-Mail mit Anmeldedaten. Sobald Sie sich mit Ihrem Benutzernamen und Passwort
auf unserer Seite angemeldet haben, können Sie Ihre Bestellhistorie und
weitere Informationen abrufen:

http://localhost/drupalcommerce/user

Den Status Ihrer aktuellen Bestellung finden Sie unter:

http://localhost/drupalcommerce/user/13/orders/4

Wir stehen Ihnen für weitere Fragen zu Ihrer Bestellung gerne zur
Verfügung.

Selbstverständlich macht auch dieser Text nicht viel Sinn, weil kein neuer Benutzer erstellt wurde.

Wir werden uns um diese Ungereimtheiten zunächst nicht weiter kümmern.

2.6. Versandkosten

Zur Einrichtung von Versandkosten laden wir die beiden Module

herunter und aktivieren auf admin/modules die Module Flat Rate, Shipping und Shipping UI.

Die Seite /admin/commerce/config/shipping/methods listet alle aktuell verfügbaren Versandarten (shipping methods). Da wir das Modul Commerce Flat Rate aktiviert haben, erscheint dort die Versandart Pauschale. Die Seite /admin/commerce/config/shipping zeigt, dass für die shipping method mit dem Namen Pauschale noch kein shipping service definiert ist. Es gibt in Zusammenhang mit Versandkosten also zwei Dinge:

  1. Shipping services die auf /admin/commerce/config/shipping gelistet sind.

  2. Shipping methods die auf /admin/commerce/config/shipping/methods gelistet sind.

Um dem Kunden Versandkosten anzeigen zu können, müssen wir für die shipping method mit dem Namen Pauschale einen shipping service hinzufügen. Das machen wir, indem wir auf der Seite /admin/commerce/config/shipping auf den Link "Add a flat rate service" klicken. Wir sehen dann ein Formular, welches wir so ausfüllen, wie es der folgende Screenshot zeigt.

Abbildung 2.8. Versandkosten konfigurieren

Versandkosten konfigurieren

Unser neuer shipping service sollte nun auf /admin/commerce/config/shipping zu sehen sein.

Bereits jetzt werden die gerade erstellten Versandkosten bei jeder Bestellung berechnet. Im Warenkorb auf der Seite /cart und auf /checkout/[orderId] erscheinen sie nicht. Klickt man auf der zuletzt genannten Seite auf den Button "weiter zum nächsten Schritt", so gelangt man auf die Seite /checkout/[orderId]/shipping, wo der Kunde die Versandkosten sieht. Auf /checkout/[orderId]/review sieht er dann den Rechnungsbetrag inklusive Versandkosten, wobei die Versankosten als Einzelposten aufgeführt sind.

2.7. Ein eigener Abschnitt im Checkoutbereich

Wir wollen uns nun ansehen, wie wir einen neuen Abschnitt in den Checkoutbereich einfügen. Dazu erstellen wir in sites/all/modules/ ein neues Verzeichnis mit dem Namen checkoutpanetest. Darin legen wir die Datei checkoutpanetest.info mit dem Inhalt

name = checkoutpanetest
description = Ein paar Tests mit Checkoutpanes
core = 7.x

und die Datei checkoutpanetest.module mit dem Inhalt

<?php
/**
 * Implementiert hook_commerce_checkout_page_info()
 */
function checkoutpanetest_commerce_checkout_pane_info() {
  $panes['erscheintInURL'] = array(
    'title' => t('Der Name des Abschnitts'),
  );
  return $panes;
}

an. Nachdem wir das Modul aktiviert haben, listet die Seite /admin/commerce/config/checkout unseren neuen Abschnitt mit dem Titel "Der Name des Abschnitts" im Bereich "Kasse". Die Abschnitte, die Sie hier im Bereich "Kasse" sehen, erscheinen im Checkoutprozess auf der Seite /checkout/[bestellNummer]. Fügen Sie einmal direkt dem Array den Schlüssel 'page' mit dem Wert 'review' hinzu und laden dann die Seite /admin/commerce/config/checkout neu. Sie sehen dann, dass der Abschnitt im Bereich "Bestellung überprüfen" gelistet ist. Im Checkoutprozess ist das die Seite /checkout/[bestellNummer]/review.

Achtung: Auf der Seite /admin/commerce/config/checkout haben Sie ja die Möglichkeit, den Abschnitt mit dem Namen "Der Name des Abschnitts" per Hand in einen anderen Bereich zu verschieben. Wenn Sie den Abschnitt nun in den Bereich "Kasse" verschieben, wird folgender SQL-Befehl ausgeführt:

INSERT INTO commerce_checkout_pane (pane_id, page, fieldset, collapsible, collapsed, weight, enabled, review)
                            VALUES ('erscheintInURL', 'checkout', '1', '0', '0', '-17', '1', '1')

Daran sehen wir, dass 'erscheintInURL' die ID des Abschnitts (die pane id) ist. Nachdem dieser INSERT-Befehl ausgeführt wurde, hat der Arraykey 'page' in der Funktion checkoutpanetest_commerce_checkout_pane_info() keine Bedeutung mehr. Er dient also nur für die initiale Platzierung des Abschnitts. Der Benutzer kann diese Einstellung überschreiben.

Da wir den Abschnitt aber auf der Checkout-Seite anzeigen wollen, entfernen wir den Schlüssel "page" wieder. Wenn Sie auf der Seite /admin/commerce/config/checkout bei unserem Abschnitt auf "configure" klicken, dann kommen Sie auf die Seite /admin/commerce/config/checkout/form/pane/erscheintInURL. In der URL steht die Zeichenkette "erscheintInURL", die ja auch in unserem Modul steht.

Wenn Sie nun /checkout/[bestellNummer] aufrufen, dann sehen Sie dort keinen neuen Abschnitt, was daran liegt, dass wir noch keine Formularfelder definiert haben. Folgende Funktion leistet genau das.

/**
 * Implementiert base_checkout_form()
 */
function erscheintInURL_checkout_form($form, $form_state, $checkout_pane, $order) {
  $checkout_form['einFeldname'] = array(
    '#type' => 'textarea',
    '#title' => t('Was haben Sie heute gefrühstückt?'),
  );
  return $checkout_form;
}

Wenn Sie nun /checkout/[bestellNummer] neu laden, sehen Sie einen neuen Abschnitt mit der Überschrift "Der Name des Abschnitts" mit einem Eingabefeld, über dem die Frage "Was haben Sie heute gefrühstückt?" steht. Beachten Sie, dass in dem Namen der Funktion erscheintInURL_checkout_form(), die base_checkout_form() implementiert, der maschinenlesbare Name des Abschnitts (nämlich erscheintInURL) auftaucht. Wenn wir uns den Spaß machen, und unserem Modul die Funktion

/**
 * Implementiert base_checkout_form_submit()
 */
function erscheintInURL_checkout_form_validate($form, &$form_state, $checkout_pane, $order) {
  return false;
}

hinzufügen, führt ein Klick auf "Continue to next step" auf der Seite /checkout/[bestellNummer] nicht mehr auf die Seite /checkout/[bestellNummer]/review, sondern wieder auf /checkout/[bestellNummer]/. Die eben hinzugefügte Funktion zeigt an, dass die Eingabe immer ungültig ist. Schreiben wir

return empty($form['erscheintInURL']['einFeldname']['#value']) ? false : true;

anstelle von

return false;

dann gelangt der Kunde nur dann auf die Review-Seite, wenn er einen Wert eingegeben hat, den empty() nicht als leer interpretiert. Beantwortet der Kunde die Frage nach seinem Frühstück nicht, landet er wieder auf /checkout/[bestellNummer]. Allerdings erscheint keine Fehlermeldung. Er erfährt also nicht, was er falsch gemacht hat. Die Anzeige einer Fehlermeldung in dem Fall, in dem der Kunde einen Wert eingibt, den empty() als leer interpretiert, funktioniert standardmäßig wie folgt über die Form-API:

function erscheintInURL_checkout_form_validate($form, &$form_state, $checkout_pane, $order) {
  if (empty($form['erscheintInURL']['einFeldname']['#value'])) {
    form_set_error('einFeldname', t('Bitte schreiben Sie uns, was Sie heute gefrühstückt haben.'));
    return false;
  } else {
    return true;
  }
}

Als nächstes wollen wir dem Anwender unseres Moduls die Möglichkeit geben, die Frage zu ändern. Wie wir schon gesehen haben, existiert bereits eine Seite zur Konfiguration unseres Abschnitts, nämlich /admin/commerce/config/checkout/form/pane/erscheintInURL. Um auf der Seite ein Feld zur Bearbeitung der Frage hinzuzufügen, schreiben wir folgende Funktion in die Datei checkoutpanetest.module:

/**
 * Implementiert base_settings_form()
 */
function erscheintInURL_settings_form($checkout_pane) {
  $form['nameVomLustigenFeld'] = array(
    '#type' => 'textfield',
    '#title' => t('Welche Frage möchten Sie Ihrem Kunden stellen?'),
    '#default_value' => variable_get('nameVomLustigenFeld', ''),
  );
  return $form;
}

Diese Funktion gibt das übliche Drupal-Form-Array zurück. Wenn wir nun erneut die Konfigurationsseite unseres Abschnitts aufrufen, sehen wir ein Eingabefeld für die Eingabe einer Frage an unseren Kunden. Im Quelltext sieht das so aus:

<fieldset class="form-wrapper" id="edit-settings">
  <legend><span class="fieldset-legend">Checkout pane configuration</span></legend>
  <div class="fieldset-wrapper">
    <div class="fieldset-description">These settings are specific to this checkout pane.</div>
    <div class="form-item form-type-textfield form-item-nameVomLustigenFeld">
      <label for="edit-namevomlustigenfeld">Welche Frage möchten Sie Ihrem Kunden stellen?</label>
      <input type="text" id="edit-namevomlustigenfeld" name="nameVomLustigenFeld" value="" size="60" maxlength="128" class="form-text" />
    </div>
  </div>
</fieldset>

Schreiben Sie doch einmal "Warum haben Sie eigentlich nicht noch mehr gekauft?" in das Feld und klicken anschließend auf "Save configuration". Obwohl wir uns noch nicht darum gekümmert haben, den Wert in dem Feld abzuspeichern, hat Drupal Commerce unsere Eingabe gespeichert:

mysql> select value from variable where name = 'nameVomLustigenFeld';
+-------------------------------------------------------------+
| value                                                       |
+-------------------------------------------------------------+
| s:51:"Warum haben Sie eigentlich nicht noch mehr gekauft?"; |
+-------------------------------------------------------------+
1 row in set (0.00 sec)

mysql>

Drupal Commerce hat unsere Frage in der Tabelle "variable" gespeichert. Dort existiert nun eine Variable mit dem Namen nameVomLustigenFeld, der unserer Frage zugewiesen ist. Wenn Sie nun wieder /admin/commerce/config/checkout/form/pane/erscheintInURL aufrufen, ist das Formularfeld bereits mit unserer Frage vorausgefüllt. Dafür sorgt die Zeile

'#default_value' => variable_get('nameVomLustigenFeld', ''),

in der Funktion erscheintInURL_settings_form(). Nun soll die neue Frage aber natürlich auch auf /checkout/[bestellNummer] zu sehen sein. Dazu ändern wir in der Funktion erscheintInURL_checkout_form() die Zeile

'#title' => t('Was haben Sie heute gefrühstückt?'),

in die Zeile

'#title' => variable_get('nameVomLustigenFeld', ''),

Wenn der Kunde unsere neue Frage nicht beantwortet, bekommt er immernoch "Bitte schreiben Sie uns, was Sie heute gefrühstückt haben." als Fehlermeldung angezeigt. Um diesen Text auch konfigurierbar zu machen, verwenden wir die folgenden Funktionen, die die vorhandenen beiden ersetzen:

/**
 * Implementiert base_checkout_form_submit()
 */
function erscheintInURL_checkout_form_validate($form, &$form_state, $checkout_pane, $order) {
  if (empty($form['erscheintInURL']['einFeldname']['#value'])) {
    form_set_error('einFeldname', variable_get('fehlerfeld', ''));
    return false;
  } else {
    return true;
  }
}

/**
 * Implementiert base_settings_form()
 */
function erscheintInURL_settings_form($checkout_pane) {
  $form['nameVomLustigenFeld'] = array(
    '#type' => 'textfield',
    '#title' => t('Welche Frage möchten Sie Ihrem Kunden stellen?'),
    '#default_value' => variable_get('nameVomLustigenFeld', ''),
  );
  $form['fehlerfeld'] = array(
    '#type' => 'textfield',
    '#title' => t('Welche Meldung soll im Fehlerfall erscheinen?'),
    '#default_value' => variable_get('fehlerfeld', ''),
  );
  return $form;
}

Wenn Sie nun /admin/commerce/config/checkout/form/pane/erscheintInURL aufrufen, sehen Sie ein weiteres Eingabefeld mit dem Titel "Welche Meldung soll im Fehlerfall erscheinen?" Dort können Sie eine höflich klingende Fehlermeldung wie z. B. "Hey, wir wollen das wirklich wissen. Also beantworten Sie gefälligst die Frage!" eingeben.

2.8. Allgemeine Geschäftsbedingungen (AGB) und Widerrufsbelehrung

Dieser Abschnitt beschreibt die Module "Commerce Extra Panes" und "Commerce Extra Panes - Terms of service", die in dem Paket commerce_extra_panes-7.x-1.1.tar.gz, welches Sie von http://drupal.org/project/commerce_extra_panes herunterladen können, enthalten sind. Wir werden sehen, dass diese Module eine Möglichkeit bieten, dafür zu sorgen, dass der Käufer Allgemeine Geschäftsbedingungen akzeptieren und die Kenntnisnahme der Widerrufsbelehrung bestätigen muss.

Der Ausdruck "Checkout-Seite" bezeichnet im folgenden die Seite /checkout/[$bestellNummer]. Der Ausdruck "Review order-Seite" bezeichnet die Seite /checkout/[$bestellNummer]/review. In beiden Adressen ist die Zeichenkette [$bestellNummer] durch eine gültige Bestellnummer zu ersetzen.

Das Modul "Commerce Extra Panes" dient dem Zweck, einen beliebigen Node als eigenen Abschnitt im Checkoutprozess anzuzeigen, was wir uns nun genauer anschauen wollen.

Zunächst erstellen wir auf /node/add/page eine neue Seite mit dem Titel "Infos anzuzeigen im Checkout". Auf der Seite /admin/commerce/config/checkout/extra geben wir in das Autocomplete Feld mit der Beschreibung "Einen Beitrag zur Verwendung als Checkout-Pane wählen." den Wert "Infos anzuzeigen im Checkout" ein und klicken auf "Panel-Inhalt hinzufügen". /admin/commerce/config/checkout listet unseren Node mit dem Titel "Infos anzuzeigen im Checkout" im Abschnitt "Kasse". Dass der Node tatsächlich angezeigt wird, sehen wir auf der Checkout-Seite /checkout/[$bestellNummer].

Wenn der Käufer bestätigen soll, dass er den Text in dem Node gelesen hat, wie es ja z. B. bei allgemeinen Geschäftsbedingungen der Fall ist, dann können wir dies auf /admin/commerce/config/checkout/form/pane/extra_pane__node__[$nodeId] so konfigurieren. (Die Zeichenkette [$nodeId] müssen Sie durch die ID des Nodes ersetzen, der im Checkout angezeigt wird.) Auf der genannten Seite aktivieren wir im Abschnitt "Zusätzliche Panes Allgemeine Geschäftsbedingungen" die Checkboxen bei

  • "Aktiviere diese Pane als Allgemeine Geschäftsbedingungen." und bei

  • "Die Allgemeinen Geschäftsbedingungen als erforderlich kennzeichnen."

Auf der Seite /checkout/[$bestellNummer] finden Sie nun unter dem Inhalt des Nodes eine Checkbox mit dem Text "Ich akzeptiere die Allgemeine Geschäftsbedingungen", die der Kunde anklicken muss, um den Checkoutprozess fortführen zu können. Tut er dies und klickt auf den Button "Weiter zum nächsten Schritt", so gelangt er auf die Review order-Seite /checkout/[$bestellNummer]/review, wo er erneut den Inhalt des Nodes präsentiert bekommt. Wenn Sie das nicht möchten, deaktivieren Sie auf /admin/commerce/config/checkout/form/pane/extra_pane__node__[$nodeId] die Checkbox bei "Fügen Sie diesen Bereich zur Überprüfung beim Bezahlvorgang hinzu."

Falls Sie einen Node ausschließlich auf der "Review order"-Seite anzeigen lassen möchten, aber nicht auf der Checkout-Seite, dann verschieben Sie auf der Seite /admin/commerce/config/checkout den Node "Infos anzuzeigen im Checkout" vom Abschnitt "Kasse" in den Abschnitt "Bestellung überprüfen".

Das Modul Commerce Extra Panes stellt einen View Mode mit dem Namen "Checkout-Bereich" zur Verfügung. Für den Inhaltstyp "Basic page" bearbeiten Sie diesen auf der Seite /admin/structure/types/manage/page/display/checkout_pane.

Die bisher vorgestellte Lösung ist nicht praxistauglich, weil die AGB meist lang sind. Würde man diese direkt ohne eine gesonderte mit CSS erstelle Scrollbox in die Checkout-Seite einbinden, so würde diese sehr lang und damit unübersichtlich. Mit folgenden Schritten werden wir daher die bis jetzt realisierte Lösung so umkonfigurieren, dass wir unsere AGB nicht auf der Checkout-Seite anzeigen, sondern in dem Text "Ich akzeptiere die AGB und bin über das 14-tägige Widerrufsrecht informiert worden.", der neben der Checkbox erscheinen wird, verlinken:

  1. Auf /node/add/page erstellen Sie eine neue Seite mit dem Titel "Allgemeine Geschäftsbedingungen". In den Body schreiben Sie die AGB. An irgendeiner Stelle sollte der Text

    <a name="widerrufsrecht">Widerrufsbelehrung</a>

    erscheinen, damit wir direkt in der Seite zum Abschnitt mit der Widerrufsbelehrung verlinken können. Im folgenden gehe ich davon aus, dass der Node unter der id 5 gespeichert wurde.

  2. Auf /admin/config/regional/translate/translate nach "I agree with the Terms of Service" suchen und bei der gefundenen Zeichenkette auf "Bearbeiten" klicken. Die Übersetzung "Ich akzeptiere die Allgemeine Geschäftsbedingungen" durch

    Ich akzeptiere die <a href="/drupal-commerce/node/5">AGB</a> und bin über das 14-tägige <a href="/drupal-commerce/node/5#widerrufsrecht">Widerrufsrecht</a> informiert worden.

    ersetzen, wobei die Node ID durch die ID des Nodes ersetzt werden muss, der Ihre AGB enthält.

Vorher hatten wir ja einen Node mit dem Titel "Infos anzuzeigen im Checkout" erstellt. Auf der Checkout-Seite erscheint nun nach wie vor der Inhalt dieses Nodes über der Checkbox mit dem Text "Ich akzeptiere die AGB und bin über das 14-tägige Widerrufsrecht informiert worden." Wir bearbeiten also den entsprechenden Node so, dass der Titel "Infos anzuzeigen im Checkout" lautet und der Body leer ist. Auf der Checkout Seite sollte der Abschnitt nun wie folgt aussehen:

Abbildung 2.9. AGB und Widerrufsbelehrung

AGB und Widerrufsbelehrung

2.9. Bestellungen

Wenn man einen Artikel in den Warenkorb legt, dann erstellt Drupal Commerce in dem Moment bereits eine Bestellung. Zwar listet die Seite /admin/commerce/orders/list diese Bestellung nicht, aber in der Datenbank wird dadurch, dass ein Artikel in den Warenkorb gelegt wird, in der Tabelle commerce_order ein neuer Datensatz hinzugefügt. Das Feld created in der Tabelle commerce_order enthält den Timestamp von der Zeit, zu der der Artikel in den Warenkorb gelegt wurde.

Der Warenkorb macht also nicht anderes, als eine Bestellung anzuzeigen - eine Bestellung, deren Status (also das Feld status in der Tabelle commerce_order) auf den Wert cart gesetzt ist.

Warum zeigt /admin/commerce/orders/list diese Bestellungen nicht an? Antwort: Diese Seite ist eine View, die Bestellungen mit dem Status cart nicht anzeigt. Auf /admin/structure/views/view/commerce_orders/edit editieren wir die View. Klicke auf den Link unter Filter criteria. Der Radio Button unter Operator ist auf Is not one of gesetzt und rechts unter State sind Shopping cart und Checkout ausgewählt. Wenn die Seite /admin/commerce/orders/list alle Bestellungen anzeigen soll, dann müssen wir den Operator auf Is one of setzen und dann bei Status alle markieren.

Klickt man im Warenkorb auf "Checkout", dann wird der Status der Bestellung in der Datenbank auf checkout_checkout geändert. /admin/commerce/orders/list zeigt als Status nun "Checkout: Checkout" an. Hat man auf /checkout/1 alles ausgefüllt und klickt auf "Next step", dann ändert sich der Status in der Datenbank auf checkout_review und /admin/commerce/orders/list zeigt Checkout: Review. Klickt man auf /checkout/1/review auf "Next", dann wird der Status auf pending gesetzt.

Wie lange bleibt eine Bestellung im Status "cart" erhalten? Anders ausgedrückt? Wie lange werden Artikel im Warenkorb angezeigt? Antwort: Es gibt keinen Mechanismus, der sie löscht und daher "für immer". Siehe auch http://drupal.org/node/1272474.

Also nochmal: Die Seite /admin/commerce/orders/list zeigt Bestellungen an. Eine der Spalten lautet Created. Was würde man intuitiv vermuten, was für ein Datum dadrin steht? Doch vermutlich das Datum, an dem der Benutzer seine Bestellung abgeschlossen hat. Aber das Datum steht dort nicht. Dort steht das Datum, an dem der Benutzer seinen Artikel in den Warenkorb gelegt hat. In der Regel wird zwischen beiden Zeiten nicht viel Zeit vergehen, aber es kann sein, dass er den Artikel in den Warenkorb legt und ein paar Wochen später die Bestellung abschließt. Wenn in der Zwischenzeit schon eine Menge anderer Bestellungen eingegangen sind, kann es leicht passieren, dass diese Bestellung aus dem Blickfeld gerät, weil die Seite /admin/commerce/orders/list normalerweise absteigend nach Datum sortiert wird und die Bestellung daher nicht mehr auf der ersten Seite zu sehen ist. Man kann aber folgende rule importieren, damit das Datum bei created auf die Zeit gestellt wird, zu der der Benutzer die Bestellung tatsächlich abgeschlossen hat:

{ "rules_update_the_created_timestamp_to_now" : {
"LABEL" : "Update the created timestamp to now",
"PLUGIN" : "reaction rule",
"REQUIRES" : [ "rules", "commerce_checkout" ],
"ON" : [ "commerce_checkout_complete" ],
"DO" : [
{ "data_set" : { "data" : [ "commerce-order:created" ], "value" : "now" } }
]
}
}