Myposter Backend Bewerbung

Willkommen

Vielen Dank für deine Bewerbung bei uns! Um die praktischen Fähigkeiten unserer Bewerber zu prüfen, muss jeder unserer Bewerber die anschließende Aufgabe bearbeiten. Diese beschreibt einen Ablauf von Aufgaben mit welchen wir uns jeden Tag beschäftigen. Neben den meisten unserer Wettbewerber zeichnen wir uns dadurch aus, dass wir nicht nur einen Onlineshop, sondern auch direkt unsere eigene Produktion betreiben.

Dadurch ergeben sich für uns immense Vorteile in der Optimierung unserer Produktionsanbindung, jedoch auch eine deutlich größere Komplexität. In der folgenden Aufgabe beschäftigen wir uns mit einer sehr abstrakten Form eines Produktlebenszyklus.

Die Aufgabe ist so ausgelegt, dass sie in ungefähr 3-4 Stunden abgeschlossen werden kann. Bitte nimm dir hierfür ausreichend Zeit, um dein bestmögliches Ergebnis einzureichen.

Um deine vollendete Aufgabe einzureichen, schicke uns bitte eine .zip Datei, welche den gesamten Quellcode beinhaltet.

Erklärung meiner Lösungen

Zunächst möchte ich mich nochmal bedanken für die Gelegenheit eine doch sehr interessante Aufgabe bearbeiten zu können! Ich habe etwas über 4 Stunden gebraucht und danach aus eigenem Interesse noch einige Sachen ausprobiert.

Zum vierten Teil der Aufgabe habe ich noch einige Anmerkungen. Die bestehende Struktur kann in einige Richtungen optimiert werden und ich war mir nicht sicher, ob diese gekoppelt ist an die voranstehenden Aufgaben. Die orders haben in meiner Lösung das status Feld behalten. Hier würde ich tatsächlich eher den Status der jeweiligen Bestellungen sehen und keine direkten Produktionsschritte, wie in der Aufgabe 1. Ich würde selber auch eine articles Tabelle für möglich halten um die Produkte darzustellen.

Ich habe hier auch mich auf meine Erfahrung mit eCommerce Systemen verlassen und hier versucht so weit ich konnte mir eine solide Struktur zu überlegen. Ich habe bewusst eine Tabelle für Artikeltypen weggelassen, da ich persönlich es immer Vorziehe so etwas in Code festzuhalten mit Validierung etc. wie auch in Teilaufgabe 1. So kann sichergestellt werden, dass Implementierungsdetails direkt mitgeliefert werden zu eventuellen neuen Artikeltypen.

Weitergehend kann man das natürlich komplett weiter auszeichnen mit verschiedenen Stufen im Produktions- und Bestellprozess, damit man Entitäten besser darstellen kann und hier auch zum Beispiel geschützt davor ist, wenn eine Adresse angepasst wird. Hier kann man mit einer order_addresses Tabelle arbeiten oder aus orders weiter gehen und invoices machen etc. Selber schaue ich hierfür gerne nach was zum Beispiel in Magento 2 geschiet oder ähnliche Systeme!

Aufgabenbeschreibung

Die Aufgabe besteht aus insgesamt vier Teilen mit unterschiedlicher Komplexität. Zu Beginn wird ein Prozessmanager implementiert, welcher die Zustände eines Produktes während der Produktion verwaltet. Im zweiten Teil wird ein Logger implementiert, welcher für den Prozessmanager genutzt werden kann. Im dritten Schritt wird eine Adressvalidierung für den Versand des Produktes implementiert und im vierten Teil wird ein Datenbankschema optimiert.

Für alle Aufgaben gilt:

  • Die Grundstruktur der Aufgaben sollte beibehalten werden
  • Es können alle mitgelieferten Dateien bearbeitet werden
  • Es können neue Dateien hinzugefügt werden
  • Alle mitgelieferten Klassen, Methoden, Variablen, usw. können erweitert oder angepasst werden.
  • Unit Tests können erweitert oder angepasst werden

Teil 1 - Prozessmanager

Jedes Produkt, das bei uns im Onlineshop bestellt wird, muss durch unsere Produktion laufen, bis es am Ende zum Kunden verschickt werden kann. Für die meisten Artikel besteht der Produktionsprozess aus mehreren Schritten, die in einer bestimmten Reihenfolge aufeinander folgen und nur wenn ein Schritt erfolgreich abgeschlossen wurde, kann der darauffolgende Schritt auch starten.

Für diese Aufgabe schauen wir uns beispielhaft zwei Produkte an:

  • Gerahmtes Poster
  • Bedruckte Glasplatte

Zusätzlich kann der Kunde bei der Bestellung für beide Produkte wählen, ob diese mit einer Geschenkverpackung versehen werden sollen oder nicht. Sollte der Kunde diese Option wählen, so wird im Produktionsablauf ein weiterer (optionaler) Schritt ausgeführt. Damit sehen die Produktionsabläufe der beiden Produkte wie folgt aus:

Produkt Zustände
Gerahmtes Poster - Ordered
- Printed
- Sliced
- Framed
- Gift-Wrapped (Optional)
- Shipped
Bedruckte Glasplatte - Ordered
- Printed
- Gift-Wrapped (Optional)
- Shipped

Die Produkte werden manuell von einem Schritt zum nächsten befördert, wodurch es vorkommen kann, dass ein Artikel einen falschen Zustand erhält. Die Einhaltung der korrekten Reihenfolge der Zustände ist jedoch verpflichtend, weshalb eine entsprechende Fehlermeldung geworfen werden muss.

Für diese Aufgabe ist bereits eine Grundstruktur im Ordner src/Production/* gegeben. Im Ordner tests/Production befindet sich die Datei ArticleTest.php um den Prozessmanager zu testen.

Teil 2 - Logger

Für den Fall, dass ein Artikel nicht wie gewünscht produziert wurde, ist es notwendig nachverfolgen zu können was bisher passiert ist. Hierfür möchten wir einen Logger implementieren, der entsprechend die Änderungen mitschreibt und uns alle notwendigen Informationen gibt einen entsprechenden Fehler zu finden. Der Logger soll im Prozessmanager aus Teil 1 genutzt werden.

Wenn für einen Artikel die Option "Geschenkverpackung" aktiviert wird, soll ein debug Eintrag geloggt werden. Für den Fall, dass ein Artikel in einem invaliden Zustand ist, soll zusätzlich zur Exception auch ein entsprechender error Eintrag erstellt werden.

Anforderungen für den Logger:

  • Der Logger soll verschiedene Prioritäten unterstützen (debug, info, warn, error, ...)
  • Eine Exception soll mit mehr Informationen geloggt werden als die normalen Log-Einträge, um späteres debuggen zu ermöglichen
  • Für jeden Logeintrag soll zusätzlich die aktuelle Uhrzeit und Priorität mitgespeichert werden
  • Der Logger soll mindestens zwei verschiedene Speicherarten unterstützen, z.B. Konsole, Datenbank oder Filesystem.
  • Der Logger soll zur Laufzeit jeweils nur eine der beiden Speicherarten verwenden
  • Das Abspeichern selbst muss nicht implementiert werden (Testen ob Datenbank/Datei existiert usw.)
  • Die Funktionalität des Loggers soll durch PHPUnit-Tests abgedeckt sein. Die Speicherarten müssen nicht getestet werden, da deren Implementierung nicht notwendig ist.
  • Die Grundprinzipien von OOP sollen eingehalten werden.

Teil 3 - Versand

Für den Versand unserer Produkte ist es notwendig die Adressen unserer Kunden zu validieren. Sind die Adressen nicht korrekt, können die Pakete nicht zugestellt werden und werden vom Versanddienstleister zurückgesendet.

Hierfür werden von einer API entsprechend die Kundendaten bezogen um sie danach validieren zu können.

Implementiere in der Klasse Myposter\Shipping\AddressValidator eine Methode um die Adressdaten von der Klasse Myposter\API\CustomerDataApiMock zu beziehen. Danach soll jeweils die Straße des Kunden in Straßenname und Hausnummer getrennt werden. Die Straßen sollen wie folgt getrennt werden:

Name: Einsteinstr., Hausnummer: 7
Name: Einsteinstrasse, Hausnummer: 7
Name: Curd-Jürgens-Str., Hausnummer: 30
...

Eine weitere Validierung der Adressen ist für diese Aufgabe nicht notwendig. Im Ordner tests/Shipping befindet sich die Datei AddressTest.php um die geteilten Adressen zu prüfen.

Teil 4 - Datenbank

In der Datei database\database.sqlite bzw. database\database.sql befindet sich eine Datenbank mit einer Tabelle orders und Beispieldaten. Diese beinhaltet Bestellungen von Kunden und die dazugehörigen Daten. Mit der aktuellen Datenbankstruktur lassen sich nur schwer Statistiken über Bestellungen berechnen.

Spaltenname Beschreibung
customer_id Die Kundenummer des Kunden
customer_name Der Name des Kunden
delivery_address Die Adresse wo die Bestellung hingeschickt werden soll
invoice_address Die Adresse für die Rechnung
order Eine Übersicht über alle bestellten Produkte und ihre Eigenschaften
order_date Das Datum der Bestellung
order_status Der aktuelle Status der Bestellung

Ziel dieser Aufgabe ist es, die Datenbankstruktur soweit wie möglich nach aktuellen Datenbankstandards zu optimieren, sodass zusammengehörige Daten in entsprechenden Tabellen zu finden sind. Für diese Aufgabe kann entweder auf Basis der *.sqlite oder der *.sql Datei gearbeitet werden.

Zusätzlich zur neuen Struktur sollen hier auch die vorhandenen Daten vom alten in das neue Format migriert werden.