Merge pull request 'docs: clean up, remove clearpages' (!318) from c4-diagrams into main
All checks were successful
Build docs / build-docs (push) Successful in 15s

Reviewed-on: #318
Reviewed-by: Constantin Simonis <constantin@simonis.lol>
This commit is contained in:
Phan Huy Tran 2025-06-12 18:41:44 +00:00
commit eb04c03208
No known key found for this signature in database
GPG key ID: 944223E4D46B7412
51 changed files with 21 additions and 901 deletions

View file

@ -13,27 +13,7 @@
% Die Option (in den eckigen Klammern) enthält das längste Label oder
% einen Platzhalter der die Breite der linken Spalte bestimmt.
\begin{acronym}[WWWWW]
\acro{API}{Application Programming Interface}
\acro{CI}{Continuous Integration}
\acro{CI/CD}{Continuous Integration/Continuous Deployment}
\acro{CLI}{Command Line Interface}
\acro{CRM}{Customer Relationship Management}
\acro{CRON}{Vorgangsausführung gemäß geplanten Zeitabläufen für UNIX Programme}
\acro{E2E}{End-to-End}
\acro{eCommerce}{Electronic Commerce}
\acro{ERM}{Entity-Relationship-Model}
\acro{GUI}{Graphical User Interface}
\acro{HTTP}{Hypertext Transfer Protocol}
\acro{IDE}{Integrated Development Environment}
\acro{IX}{Intex Fusion Pro Omnichannel CRM}
\acro{JSON}{JavaScript Object Notation}
\acro{M2}{\textsc{Magento 2} eCommerce Platform}
\acro{NSD}{\textsc{neusta software development} GmbH}
\acro{NXP}{\textsc{neusta experience} GmbH}
\acro{PHP}{Hypertext Preprocessor}\acused{PHP}
\acro{SQL}{Structured Query Language}
\acro{URL}{Uniform Resource Locator}\acused{URL}
\acro{VM}{Virtual Machine}
\acro{XML}{Extensible Markup Language}
\acro{JWT}{JSON Web Token}
\end{acronym}

View file

@ -1,17 +1,5 @@
% !TEX root = Projektdokumentation.tex
\section{Anhang}
\subsection{Detaillierte Zeitplanung}
\label{app:Zeitplanung}
\tabelleAnhang{ZeitplanungKomplett}
\input{Anhang/AnhangLastenheft.tex}
\clearpage
\input{Anhang/AnhangRessourcen.tex}
\clearpage
\subsection{Implementierungsbeispiele}
\label{app:CodeSchichten}

View file

@ -1,68 +0,0 @@
%PDF-1.5
%µí®û
3 0 obj
<< /Length 4 0 R
/Filter /FlateDecode
>>
stream
xœm“MŽ1 …÷9EÖ,L;Çਤ™Y àþÏŽSÝ ¨¥ê|ñOÞsª~¦’í÷ë=ý^òûïT•®Ü˜™‰kË­ÐÔ‰<YÔÊ¢6jkæ KäèðgG„Jáœî¥]V6$<08>y­¨
¸»{>Úì:×}}ÉXw„ûôuÑü¬ÿÊî§ö¬<C3B6>f1GÝêæ¶ûð‰ÆA<>=HÌMløïÝnéÁ,4ÍÁ.UmÏú¦M×Ι´ç<e=Ñ«Œf)M«Q™ùÕØÿ¬¾¥º\…LÒfÞÑ Œ\ulÒh|4aÂ8­5\A„Ù%ŸÒ ï{ÔBºÆ©ÔŠAËÃûÆë{Â[Ò)}Öë–^ ¼}I8kà<6B>XTðBº%=ôÁfA®Ö8ÅF bCS«6{cŒYÌ;áX©ÔÙ7«v GPj7ŠƒÑC_ 'ôôÚ]ÆVw¢L #HlCŸã[ˆ(&45Nàå•÷ñ Š«yF<79><46>t£6ÆoÛA1ôŠ.Â|ß#üøûp%ßÒ<>Ò'
endstream
endobj
4 0 obj
414
endobj
2 0 obj
<<
/ExtGState <<
/a0 << /CA 1 /ca 1 >>
>>
>>
endobj
5 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 51.200001 51.200001 ]
/Contents 3 0 R
/Group <<
/Type /Group
/S /Transparency
/CS /DeviceRGB
>>
/Resources 2 0 R
>>
endobj
1 0 obj
<< /Type /Pages
/Kids [ 5 0 R ]
/Count 1
>>
endobj
6 0 obj
<< /Creator (cairo 1.10.2 (http://cairographics.org))
/Producer (cairo 1.10.2 (http://cairographics.org))
>>
endobj
7 0 obj
<< /Type /Catalog
/Pages 1 0 R
>>
endobj
xref
0 8
0000000000 65535 f
0000000812 00000 n
0000000528 00000 n
0000000015 00000 n
0000000506 00000 n
0000000600 00000 n
0000000877 00000 n
0000001004 00000 n
trailer
<< /Size 8
/Root 7 0 R
/Info 6 0 R
>>
startxref
1056
%%EOF

View file

@ -1,68 +0,0 @@
%PDF-1.5
%µí®û
3 0 obj
<< /Length 4 0 R
/Filter /FlateDecode
>>
stream
xœmRIŽÜ0 ¼ëz#nZž'fæ09$ù?<3F>"¥v÷<04>[%eY¿J«ñü~¯ß~´úþ§ˆÑ²U<C2B2>IêÏÊL,^½Ñ´‰<]ämá N¾f½pDŽ<44>|wD¨5®áÞä +ʆf^ëTœù ÙuÙËaÌóHǺ#ÜgžÕ×þ¯úz¤Wë4[(Šl—<6C>}óð#zþqÚ¤¡æ\ä‡÷í<C3B7>îÖ
nyÁ[6ºvÎ<ÁxÏGÙO΄àjÃ#Åue7¦³~ö?©o…<6F>lAÆ8,Ö)ÙÕÁŸ• ŒB^X„°í;,<2C>ÌÛ|¹˜fU´(S4¢Fb@=NM,ÖÓ‰a“Àvls‡Ÿ;YA*ó<>Á³ÂeçhøsxÅ¢©÷htö*8.7o hºBŒÏžá4át /jÚ! ü!•i ˜+ ÛŒÉ8µpµC鈪ÿóSSp´76Ó5ázævñß5otK8%ŽÈÊ~×!âƒÒåËÇuô&‰¦%¡è#V2ÙÆ¾èù?“þRª˜ã“¸a¬3°,Ll»¤h§æ«~5Më_½•ïå/ÅÏÕ
endstream
endobj
4 0 obj
447
endobj
2 0 obj
<<
/ExtGState <<
/a0 << /CA 1 /ca 1 >>
>>
>>
endobj
5 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 51.200001 51.200001 ]
/Contents 3 0 R
/Group <<
/Type /Group
/S /Transparency
/CS /DeviceRGB
>>
/Resources 2 0 R
>>
endobj
1 0 obj
<< /Type /Pages
/Kids [ 5 0 R ]
/Count 1
>>
endobj
6 0 obj
<< /Creator (cairo 1.10.2 (http://cairographics.org))
/Producer (cairo 1.10.2 (http://cairographics.org))
>>
endobj
7 0 obj
<< /Type /Catalog
/Pages 1 0 R
>>
endobj
xref
0 8
0000000000 65535 f
0000000845 00000 n
0000000561 00000 n
0000000015 00000 n
0000000539 00000 n
0000000633 00000 n
0000000910 00000 n
0000001037 00000 n
trailer
<< /Size 8
/Root 7 0 R
/Info 6 0 R
>>
startxref
1089
%%EOF

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 347 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 952 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -1,11 +0,0 @@
% !TEX root = ../Projektdokumentation.tex
\section{Abnahmephase}
\label{sec:Abnahmephase}
Die Anwendung wurde gemäß der in Abschnitt~\ref{sec:Entwicklungsprozess}: \nameref{sec:Entwicklungsprozess} agilen Entwicklung stetig von Mitarbeitern der \ac{NSD}
per Code Review abgenommen. Die Code Review erfolgte über das webbasierte Development Operations Lebenszyklus Tool GitLab \footnote{GitLab - \url{https://gitlab.com}}, in dessen Repository die Anwendung per git \footnote{git - \url{https://git-scm.com/}}
versioniert wurde. Sofern ein neues Feature vom Autor fertiggestellt wurde, erstellte der Autor einen sogenannten Merge Request in GitLab. Dieser Merge Request hat zur Folge,
dass ein zugeteilter Mitarbeiter der \ac{NSD} den Code freigeben muss und dieser dann erst in den Quellcode der Anwendung übernommen werden kann.
Teil der Abnahmebedingungen war, dass der zu implementierende Code sinnvoll mit Unit Tests abgedeckt ist. Exemplarisch hierfür steht der \Anhang{app:UnitTest}, welcher
einen beispielhaften Unit Test für die Komponente neusta-m2-intex-client-config zeigt.

View file

@ -1,105 +0,0 @@
% !TEX root = ../Projektdokumentation.tex
\section{Analysephase}
\label{sec:Analysephase}
\subsection{Ist-Analyse}
\label{sec:IstAnalyse}
Ein Direktimport über Schnittstellen wird für \ac{M2} nicht zur Verfügung gestellt.
Derzeit werden solche Importer per Modul für jeden Webshop individuell selbst entwickelt und angepasst.
Als Modul bezeichnet man im \ac{M2} Umfeld eine Erweiterung des Frameworks durch neue Funktionalitäten.
Die hierfür neu entwickelnden Module stellen \acs{API}-Abfragen an \ac{IX} und importieren die Daten ohne temporäres Zwischenspeichern in \ac{M2}.
Vorhandene Fehlerquellen sind hier die benötigte Verbindung zur \ac{IX}-\acs{API} und die unbedingte Richtigkeit der übertragenen Daten.
Kommen Fehler beim Import aufgrund von fehlender oder unvollständiger Datensätze zustande, bricht der komplette Import ab.
Gleiches gilt für die Export Funktionen zum Exportieren von Bestellungen von \ac{M2} zu \ac{IX}.
\subsection{Wirtschaftlichkeitsanalyse}
\label{sec:Wirtschaftlichkeitsanalyse}
Aufgrund des in den Abschnitten~\ref{sec:Projektbegruendung}: \nameref{sec:Projektbegruendung} und~\ref{sec:IstAnalyse}: \nameref{sec:IstAnalyse}
geschilderten und erläuterten derzeitigen Zustandes von Import/Export-Modulen in Abhängigkeit zum \ac{CRM} \ac{IX} für \ac{M2}, ist die Umsetzung
des Projektes unbedingt erforderlich. Eine gerechtfertigte Realisierung aus wirtschaftlichen Gesichtspunkten wird in den folgenden Abschnitten analysiert.
\subsubsection{\gqq{Make or Buy}-Entscheidung}
\label{sec:MakeOrBuyEntscheidung}
Bei dem Projekt handelt es sich um die Erfüllung von kundenspezifischen Anforderungen, sofern \ac{IX} als \ac{CRM} genutzt wird.
Hierfür lässt sich auf dem Markt keine Lösung finden, die eine Integration der Warenwirtschaft in ein \ac{M2} ermöglicht.
Daher soll das Projekt in Eigenentwicklung durchgeführt und durch Nutzung von Open Source Anwendungen erweitert werden.
\subsubsection{Projektkosten}
\label{sec:Projektkosten}
Im folgenden sollen die Kosten kalkuliert werden, die während der Entwicklung des Projektes anfallen. Neben Personalkosten, die durch die Umsetzung
des Projektes verursacht werden, mussten auch Aufwendungen für die in Abschnitt~\ref{sec:Ressourcenplanung}: \nameref{sec:Ressourcenplanung} genannten Ressourcen
berücksichtigt werden. Da Personalkosten im Original nicht herausgegeben werden dürfen, erfolgte die Kalkulation anhand von unterstellten Werten.
Die Durchführungszeit des Projekts beträgt 70 Stunden.
Unterstellt wurde ein Stundensatz in Höhe von \eur{10} für Auszubildende sowie \eur{25} für Mitarbeiter.
Für die o.g. Ressourcennutzung wurde ein pauschaler Satz von \eur{15} angenommen.
Eine Aufstellung der Kosten lassen sich der Tabelle~\ref{tab:Kostenaufstellung} entnehmen und betragen insgesamt \eur{2910}.
\tabelle{Kostenaufstellung}{tab:Kostenaufstellung}{Kostenaufstellung.tex}
\subsubsection{Amortisationsdauer}
\label{sec:Amortisationsdauer}
Der folgende Abschnitt dient zur Ermittlung des Zeitpunktes, ab welchem sich die Entwicklung der Anwendung amortisiert hat.
Anhand dieses Wertes kann beurteilt werden, ob die Umsetzung des Projektes aus wirtschaftlicher Sicht sinnvoll ist und sich hieraus
Kostenvorteile ergeben.
Nachfolgend soll nun die Amortisationsdauer berechnet werden. Diese gibt an, ab welchem Zeitpunkt die Anschaffungs- und Entwicklungskosten durch die
Zeitersparnis beglichen werden kann.
\tabelle{Zeitersparnis}{tab:Zeitersparnis}{Zeitersparnis} \\
\textbf{Berechnung der Amortisationsdauer:}
\begin{align}
415\ \frac{min}{Monat} \cdot 12\ \frac{Monate}{Jahr} = 4980\ \frac{min}{Jahr} = 83\ \frac{h}{Jahr}
\end{align}
\begin{align}
83\ \frac{h}{Jahr} \cdot (\eur{25} + \eur{15}) = 3320\ \frac{\eur{}}{Jahr}
\end{align}
\begin{align}
\frac{\eur{3320}}{2910 \frac{\eur{}}{Jahr}} = 1,14\ Jahre \approx 1\ Jahr\ \&\ 1,5\ Monate
\end{align}
Zusätzlich wurde die Amortisation grafisch dargestellt. Das Diagramm enthält die variablen Kosten (pro Jahr) der neuen Lösung sowie die Kosten,
die für die Entwicklung der neuen Umsetzung angefallen sind. Die Grafik findet sich im~\Anhang{app:Amortisation}.
Anhand der Amortisationsrechnung ergibt sich für das Projekt eine Amortisationsdauer von einem Jahr und ca. eineinhalb Monaten. Dies definiert den Zeitraum, über den
die neue Anwendung mindestens eingesetzt werden muss, um Anschaffungskosten und Kosteneinsparung auszugleichen. Da das Projekt von der \ac{NSD} langfristig eingesetzt
werden soll, kann das Projekt unter wirtschaftlichen Gesichtspunkten als sinnvoll eingestuft werden.
\subsection{Nutzwertanalyse}
\label{sec:Nutzwertanalyse}
Durch die in den Abschnitten~\ref{sec:Projektkosten}: \nameref{sec:Projektkosten} und~\ref{sec:Amortisationsdauer}: \nameref{sec:Amortisationsdauer} aufgeführten Ergebnisse wird die Realisierung
des Projektes bereits ausreichend gerechtfertigt. Hierdurch soll an dieser Stelle auf eine detaillierte Analyse nicht-monetärer Vorteile verzichtet werden.
Nicht-monetäre Vorteile der Anwendung wären aber \zB die angenehmere Wartbarkeit durch bessere Übersicht der neu implementierten Modulstruktur sowie die Implementierung von aussagekräftigeren Fehlermeldungen
und der Möglichkeit, die Anwendung schnell für individuelle Wünsche anzupassen.
\subsection{Anwendungsfälle}
\label{sec:Anwendungsfaelle}
Eine grobe Übersicht über die von der Anwendung abzudeckenden Anwendungsfälle wurde im Laufe der Analysephase per Use-Case-Diagramm dargestellt.
Dieses Diagramm befindet sich im \Anhang{app:UseCase} und bildet alle Funktionen ab, welche aus Anwendersicht benötigt werden.
Dem Entwickler stehen der Vollimport sowie die Teilimporte der Daten für Nutzer- und Produktdaten zur Verfügung. Die Teilimporte sind erforderlich,
um mögliche Fehlimporte im Kleinen neu anstoßen zu können und so einen erneuten Vollimport zu verhindern.
Beim Auslösen des Import-Vorgangs werden die Daten von der \ac{IX}-\acs{API} angefordert und zwischengespeichert, um abermalige Requests zu verhindern.
Die zwischengespeicherten Daten werden dann zu \ac{M2} importiert und dem Webshop zur Verfügung gestellt.
Der Vorgang des Vollimports wird außerdem auch über einen \acs{CRON}-Job in geplanten Zeitabständen zur Verfügung gestellt, um ein abermaliges, manuelles
Anstoßen zu umgehen.
\subsection{Qualitätsanforderungen}
\label{sec:Qualitaetsanforderungen}
Die Anwendung soll unter Green Development \footnote{Sustainable Web Design - \url{https://sustainablewebdesign.org/}} Grundsätzen entwickelt werden. Dies bedeutet, dass auf effiziente Datenabfragen sowie auf Minderung von Komplexität während
der Entwicklung geachtet wird. Weitere Punkte der Qualitätsanforderungen sind die Möglichkeit nachvollziehbare Logs einzusehen, falls Fehler während
eines Importes entstehen sowie die Wartbarkeit der Anwendung durch modulare und entkoppelte Entwicklung. Außerdem soll die Anwendung mit Unit-Tests abgedeckt sein,
um die Funktionalität des Codes zu gewährleisten.
\subsection{Lastenheft/Fachkonzept}
\label{sec:Lastenheft}
Am Ende der Analysephase wurde mit den Mitarbeitern der \ac{NSD} sowie der \ac{NXP} ein Lastenheft erstellt. Dieses umfasst alle Anforderungen,
welche an die neue Anwendung gestellt werden. Ein Auszug aus dem erstellten Lastenheft befindet sich im \Anhang{app:Lastenheft}.

View file

@ -1,4 +1,3 @@
\clearpage
\section{Coinflip}
\subsection{Was ist Coinflip?}

View file

@ -1,4 +1,3 @@
\clearpage
\section{Dice}
\subsection{Was ist Dice?}

View file

@ -1,7 +0,0 @@
% !TEX root = ../Projektdokumentation.tex
\section{Dokumentation}
\label{sec:Dokumentation}
Die Dokumentation der Anwendung besteht aus zwei Bestandteilen: der Projektdokumentation, in welcher der Autor die einzelnen
Phasen, die während der Projektumsetzung durchlaufen wurden, beschreibt sowie der Entwicklerdokumentation, bei der es sich um eine
detaillierte Beschreibung der Klassen, die von der Anwendung genutzt werden, handelt. Außerdem werden auch deren Attribute und Methoden sowie die
Abhängigkeiten der jeweiligen Klassen untereinander erläutert.

View file

@ -1,12 +0,0 @@
% !TEX root = ../Projektdokumentation.tex
\section{Einführungsphase}
\label{sec:Einfuehrungsphase}
Durch die in Abschnitt~\ref{sec:ImplementierungGeschaeftslogik}: \nameref{sec:ImplementierungGeschaeftslogik} vorgenommene Implementierung
der Anwendung als Composer basierte Packages, ist das zur Verfügung stellen der Anwendung an den \ac{NSD} internen Satis \footnote{Composer Satis - \url{https://github.com/composer/satis}} Server angebunden.
Der interne Satis dient als Composer Repository und stellt so eigen entwickelte Module für die \ac{NSD} für alle Kundenprojekte zur Verfügung.
Die Komponenten der Anwendung werden dort aufgeführt und können in die realen Kundenprojekte nach Fertigstellung der ausgelassenen
Funktionen per Composer implementiert werden. Hier kommt nun auch der größte Vorteil zu tragen, da eine Änderung der Module lediglich
in der Grundversion, die dem Satis zur Verfügung steht, vorgenommen muss und somit automatisch per Composer bei Deployments für Live Umgebungen übernommen werden.
So müssen Änderungen nicht code-seitig an den Projekten vorgenommen werden.

View file

@ -1,73 +0,0 @@
% !TEX root = ../Projektdokumentation.tex
\section{Entwurfsphase}
\label{sec:Entwurfsphase}
\subsection{Zielplattform}
\label{sec:Zielplattform}
Das Abschlussprojekt soll, wie in Abschnitt~\ref{sec:Projektziel}: \nameref{sec:Projektziel} beschrieben, aufgrund des Aspektes der Fehlerminimierung als \ac{M2}-Modul
umgesetzt werden. Zur temporären Zwischenspeicherung der importierten Datensätze von \ac{IX} wird eine Tabelle in das
bestehende Datenbank-System der \ac{M2} Instanz implementiert.
Die Auswahl der Programmiersprache, mit der das Projekt realisiert werden soll, wurde anhand der Anforderungen von \ac{M2}
als \ac{eCommerce} Platform durchgeführt. Um eine Fehler minimierende Einbindung in bestehende Shops zu garantieren, wurde beschlossen,
auf eine Nutzwertanalyse zu verzichten und den genannten Anforderungen von \ac{M2} Folge zu leisten.
Daher ist die Programmiersprache \ac{PHP}, unter Berücksichtigung der genannten Gesichtspunkte, am besten geeignet und soll für die Umsetzung des Projektes verwendet werden.
\subsection{Architekturdesign}
\label{sec:Architekturdesign}
Die Implementierung der einzelnen Import-Funktionen für Benutzer- und Produktdaten sollen auf Basis des Factory Design Pattern \footnote{PHP the Right Way - Factory Pattern - \url{https://phptherightway.com/pages/Design-Patterns.html}}
umgesetzt werden. Demnach wird jede Import-Komponente durch eine zugehörige Factory per Singleton Prinzip instanziiert.
So wird sichergestellt, dass jeweils nur eine Instanz des Imports vorhanden ist und Rechenlast während der Nutzung der Anwendung
minimiert wird.
Zusätzlich wird jede Funktionalität modular als Composer \footnote{Composer - \url{https://getcomposer.org}} Package eingebunden, sodass die einzelnen Komponenten nur eine Basis-Komponente zum
Funktionieren benötigen. Die Basis-Komponente bindet alle gewünschten Komponenten ein und kann sie anhand des o.g. Factory Patterns instanziieren.
Diese Modularität bildet eine übersichtliche Anwendungsgestaltung, die nachträglich - ohne viel Aufwand - um mehr Funktionalität erweitert werden kann.
\subsection{Entwurf der Benutzeroberfläche}
\label{sec:Benutzeroberflaeche}
Der Autor hat sich auf Grund des festgelegten Projektumfangs sowie des festgelegten Nutzerkreises, der aus Mitarbeitern der \ac{NSD} besteht,
für eine Umsetzung der Benutzeroberfläche als \ac{CLI}, zur Ausführung der in
Abschnitt~\ref{sec:Anwendungsfaelle}: \nameref{sec:Anwendungsfaelle} beschriebenen Anwendungsfälle, entschieden.
Die Einbindung der Konsolenbefehle soll über die standardisierte \ac{M2} Implementierungsmöglichkeit für \ac{CLI} Befehle erfolgen.
\subsection{Datenmodell}
\label{sec:Datenmodell}
Um eine Zwischenspeicherung der Daten, die von der \ac{IX}-\ac{API} bereitgestellt werden, zu realisieren, wird eine Tabelle zur
Datenstruktur vom betroffenen \ac{M2} Webshop hinzugefügt. Diese Tabelle soll lediglich Informationen über die importierten Daten und den
jeweiligen Zeitstempel zur Nachvollziehbarkeit enthalten.
Da keine komplexen Entitäten hierfür benötigt werden, wurde vom Autor darauf verzichtet ein \ac{ERM} sowie eine Datenbankstruktur zu
erstellen.
\subsection{Geschäftslogik}
\label{sec:Geschaeftslogik}
Wie in Abschnitt~\ref{sec:Architekturdesign}: \nameref{sec:Architekturdesign} beschrieben, wird die Anwendung in mehrere Komponenten aufgeteilt.
Die Aufteilung der Komponenten erfolgt per Registrierung als Composer Package. Composer als \ac{PHP} Package Manager bietet die Möglichkeit,
Abhängigkeiten der genutzten Software zu versionieren und in einem kontrollierten Umfeld zu nutzen. Durch die Aufteilung der Anwendung in solche
Packages, erlangt der Autor eine entkoppelte Anwendung, die ohne großen Aufwand ebenfalls erweitert werden kann.
Es wird eine Basis-Komponente geben von der jede Subkompenente ableitet. Diese Basis-Komponente beinhaltet die Grundabhängigkeiten,
damit die Anwendung im jeweiligen \ac{M2} Umfeld lauffähig ist. Diese Grundabhängigkeiten beinhalten die Version der Programmiersprache
\ac{PHP}, die Version des genutzten \ac{M2} sowie die genauen Abhängigkeiten der genutzten \ac{M2} Kern-Komponenten. Zusätzlich wird eine Version
der Anwendung selbst definiert, sodass in der weiteren Entwicklung eigene Versionen für verschiedene \ac{M2} Versionen (\zB ältere) zur Verfügung gestellt
werden könnten. Die Basis Komponente wird den Namen neusta-m2-intex-base tragen.
neusta-m2-intex-base wird erweitert um folgende Subkomponenten:
\begin{itemize}
\item neusta-m2-intex-client: Subkomponente zur Verbindung zur \ac{IX} \ac{API}
\item neusta-m2-intex-client-config: Subkomponente zur Konfiguration des Key-Value Mappings für Daten von \ac{IX}
\item neusta-m2-intex-cli: Subkomponente zur Implementierung der Benutzeroberfläche
\item neusta-m2-intex-customer: Subkomponente zur Implementierung der Import Logik für Nutzerdaten
\item neusta-m2-intex-catalog: Subkomponente zur Implementierung der Import Logik für Produktdaten
\end{itemize}
Durch die Namenskonvention, die vom Autor gewählt wurde, ist für aussenstehende Entwickler schneller ersichtig, in welcher Komponente
welche Logik eingebaut wurde. So wird weiterhin die Wartungsfähigkeit der Anwendung in den Vordergrund gestellt.

View file

@ -1,38 +0,0 @@
% !TEX root = ../Projektdokumentation.tex
\section{Fazit}
\label{sec:Fazit}
\subsection{Soll-/Ist-Vergleich}
\label{sec:SollIstVergleich}
Bei der rückblickenden Betrachtung des Projektes, wird vom Autor festgehalten, dass die zuvor festgelegten Anforderungen erfüllt wurden.
Die Entwicklung des Projektes hat einen Grundstein für ein modulares Import/Export System von \ac{M2} zu \ac{IX} gelegt, welches allerdings zur vollständigen
Ersetzung der alten Module noch erweitert werden muss. Der Autor hat dies allerdings berücksichtigt und gemäß Abschnitt~\ref{sec:Projektabgrenzung}: \nameref{sec:Projektabgrenzung}
aufgrund des begrenzten Projektumfangs eingeplant.
Wie der Tabelle~\ref{tab:Vergleich} zu entnehmen ist, konnte ebenfalls die Zeitplanung bis auf wenige Ausnahmen eingehalten werden.
\tabelle{Soll-/Ist-Vergleich}{tab:Vergleich}{Zeitnachher.tex}
\subsection{Lessons Learned}
\label{sec:LessonsLearned}
Der Autor konnte während des Projektes wertvolle Erfahrungen \bzgl der Planung und Durchführung von Software-Projekten
sammeln. Hierbei wurde besonders deutlich, welch große Bedeutung stetige Rücksprache und Kommunikation mit den Projektbeteiligten
für den Projekterfolg hat. Zusätzlich konnte der Autor neue Kompetenzen und Sicherheiten im Umgang mit \ac{M2} erlangen, welche
für die zukünftige, angestrebte Tätigkeit im \ac{eCommerce} hilfreich sind.
Abschließend lässt sich sagen, dass die Realisierung des Projektes eine Erleichterung zur alltäglichen Arbeit mit \ac{M2}
Webshops, die eine \ac{IX} Schnittstelle nutzen, darstellt und auch für den Autor während der Entwicklung eine Bereicherung war.
\subsection{Ausblick}
\label{sec:Ausblick}
Die im Lastenheft definierten Anforderungen wurden zwar realisiert, dennoch können in Zukunft noch weitere Anforderungen \bzw
Erweiterungsmöglichkeiten entwickelt werden. Es kann \zB die Erweiterung der Benutzeroberfläche in das bestehende \ac{M2} Administrator
Backend als \ac{GUI} vorgenommen werden. Gleichzeitig können die Funktionen um weitere Datentypen erweitert werden, wie \zB
Mediadaten und Bestellungen. Eine Möglichkeit zum Export von allen importierten Daten zu \ac{IX} selbst, sind ebenfalls Aussichten für die Zukunft.
Aufgrund des im Abschnitt~\ref{sec:Architekturdesign}: \nameref{sec:Architekturdesign} beschriebenen modularen Aufbaus, können die Anpassungen
\bzw Erweiterungen einfach vorgenommen werden. Die Modularität der Anwendung ermöglicht somit eine gute Wart- und Erweiterbarkeit.

View file

@ -1,82 +0,0 @@
% !TEX root = ../Projektdokumentation.tex
\section{Implementierungsphase}
\label{sec:Implementierungsphase}
\subsection{Implementierung der Datenstrukturen}
\label{sec:ImplementierungDatenstrukturen}
Wie in Abschnitt~\ref{sec:Datenmodell}: \nameref{sec:Datenmodell} beschrieben, ermöglicht \ac{M2} eine Einbindung von individuell benötigten \acs{SQL}
Tabellen in die vorhandene Datenstruktur.
Dem \Anhang{app:InstallData} kann ein \acs{XML} entnommen werden, welches der Komponente neusta-m2-intex-base hinzugefügt wurde.
Dieses deklarative Initialisieren von Datenstrukturen wird ebenfalls vom Framework Symfony genutzt. Es ermöglicht dem Entwickler anzugeben,
wie die Datenstruktur einer Tabelle aussehen soll. \ac{M2} bestimmt dann den Unterschied der derzeitigen Tabellenstruktur und der Struktur, die durch
vorhandene \acs{XML} Definitionen angegeben wurde. Diese Unterschiede werden dann durch atomare \acs{SQL} Operationen wiedergespiegelt.
Zusätzlich priorisiert \ac{M2} deklarative Schemen und führt diese generell vor allen älteren Schema \ac{PHP} Scripten aus.
Die bestehende Datenbank wurde durch o.g. vorgehen um eine Basis-Tabelle erweitert, welche zur Nachvollziehbarkeit der Import-Vorgänge beitragen soll.
\subsection{Implementierung der Benutzeroberfläche}
\label{sec:ImplementierungBenutzeroberflaeche}
Die Implementierung der Benutzeroberfläche erfolgte, wie bereits im Abschnitt~\ref{sec:Benutzeroberflaeche}: \nameref{sec:Benutzeroberflaeche} geplant,
mit Hilfe der \ac{M2} eigenen Möglichkeiten zur Einbindung von \ac{CLI}-Befehlen.
Durch die Entscheidung des Autors, die Anwendung als \ac{M2} Modul umzusetzen, ergibt sich hier der Vorteil, dass die gewünschten und benötigten
\ac{CLI} Befehle per Dependency Injection direkt in die \ac{M2} Befehlsliste aufgenommen werden können. Somit können Entwickler bei der Nutzung der Anwendung
auf das Standard Interface von \ac{M2} zurückgreifen und separate Zugangsdaten oder Aufrufe werden vermieden.
Um der \ac{M2} Instanz die gewünschten Befehle zuzufügen, wurde die Klasse CliCommand der Komponente neusta-m2-intex-cli hinzugefügt. Diese Klasse
leitet von der abstrakten \ac{M2} Klasse Command ab und bindet in \ac{M2} inkludierte Symfony-Komponenten zur Verarbeitung von Ein- und Ausgabe ein.
\subsection{Implementierung der Geschäftslogik}
\label{sec:ImplementierungGeschaeftslogik}
Da die Implementierung der Geschäftslogik den Kernbestandteil des gesamten Projektes darstellt, soll diese im folgenden Abschnitt
genauer erläutert werden. Um die Implementierung möglichst komfortabel durchzuführen, wurde die Entwicklungsumgebung JetBrains PHPStorm 2019 hierfür
vom Autor gewählt.
Zu Beginn der Implementierung wurde das Grundgerüst der Komponenten für die Anwendung erstellt. Hierzu wurde für jede in
Abschnitt~\ref{sec:Geschaeftslogik}: \nameref{sec:Geschaeftslogik} erwähnte Komponente und Subkomponente die Grundlage zur Einbindung als
Composer Package gelegt. Jede Komponente beinhaltet eine \acs{JSON} Datei, die Angaben zum Namen des Packages, der Version, einer Package-Typ Definition
(hier: magento2-module), Abhängigkeiten zu anderen Packages sowie Informationen zum Autor beinhaltet (Beispiel: \Anhang{app:ComposerJson}). Somit konnten die Komponenten
im einzelnen als separates Projekt angesehen werden.
Nachdem die Grundlagen zur Aufteilung der Anwendung in modulare Komponenten gelegt wurde, befasste sich der Autor damit, die lokale Entwicklungsumgebung aufzusetzen.
Hierzu wurde ein für \ac{M2} bereits vorhandenes Docker \footnote{Docker - \url{https://www.docker.com}} Setup der \ac{NSD} genutzt. Docker ist ein \ac{VM} Container System, welches im genutzten Setup Container für
jeweils den Quellcode der \ac{M2} Instanz, der Datenbank sowie dem benötigten NGINX \footnote{NGINX - \url{https://www.nginx.com/}} Server bereit stellt. Dem Autor wurde hiermit ein natives Aufsetzen einer \ac{M2} Instanz
erspart, was zur Qualität der Entwicklung erheblich beitrug und gleichzeitig garantiert, dass die Anwendung auf der tatsächlichen Serverumgebung lauffähig ist.
Nach der Fertigstellung des Grundgerüstes und der lokalen Umgebung konnte mit der eigentlichen Implementierung fortgesetzt werden.
Wie in Abschnitt~\ref{sec:Entwicklungsprozess}: \nameref{sec:Entwicklungsprozess} beschrieben, entschied der Autor sich für eine agile Umsetzung in einer Mischung
aus Kanban und Scrum. Jede einzelne Komponente ergab somit eine Story im Kanban Board, welche nach Scrum Prinzip zusammen mit den Mitarbeitern der \ac{NSD} priorisiert wurden.
Die Implementierung des Basis Moduls neusta-m2-intex-base wurde zügig Vollzogen, da die Komponente lediglich als Wrapper für alle Funktionen dienen soll.
Die o.g. Priorisierung gemäß Scrum sah nun vor, dass die Implementierung der Verbindungslogik zu \ac{IX} am wichtigsten ist, da alle weiteren Logik-Komponenten hierrauf aufbauen müssen.
Deswegen soll an dieser Stelle die Implementierung der Komponente neusta-m2-intex-client als Beispiel herangezogen werden.
Zunächst wurde in der \acs{JSON} Datei für Composer definiert, dass neusta-m2-intex-base die Grundabhängigkeit für das Modul darstellt. So wurden duplizierte
Einträge in der Konfiguration vermieden, da diese bereits in der Komponente neusta-m2-intex-base inkludiert sind. Zusätzlich besteht eine Abhängigkeit zur Komponente
neusta-m2-intex-client-config, da in der Komponente die Konfigurationen für die \ac{IX}-\acs{API} Zugriffe vorgenommen werden sollen. Die Konfigurationen beinhalten neben
den Key-Value Paaren zum Mapping der Produkt- und Nutzerattribute auf den \ac{M2} Standard auch die grundlegenden Informationen wie Passwort und Nutzername zur Verbindung
mit \ac{IX}.
Die Aufgabe des neusta-m2-intex-client in der Anwendung soll sein, jegliche Datenverbindung von der entwickelnden Anwendung mit der \ac{IX}-\acs{API}
herzustellen und gleichzeitig ein nachvollziehbares Logging dieser Verbindungen und eventuell auftretender Fehler zur Verfügung zu stellen.
Wie in Abschnitt~\ref{sec:Architekturdesign}: \nameref{sec:Architekturdesign} beschrieben, sah der Entwurf vor, das Factory Design Pattern zu nutzen und so
mehrere Instanzen der Verbindungen zu vermeiden. Hierzu wurde in der Komponente neusta-m2-intex-client die Klasse Factory implementiert, welche die Instanziierung
der Klassen abbildete, die neusta-m2-intex-client der Anwendung zur Verfügung stellen soll. Der Grundgedanke ist hierbei, dass die Komponente zum Import der Nutzerdaten
(hier: neusta-m2-intex-customer) die Factory des neusta-m2-intex-client nutzen und so seine Verbindung zu \ac{IX} herstellen lassen kann. Der Quellcode der Factory kann
dem \Anhang{app:Factory} entnommen werden.
Um Requests zur \ac{IX}-\acs{API} zu verarbeiten, entschied der Autor, den Open Source \ac{HTTP} Client GuzzlePhp \footnote{GuzzlePhp - \url{https://github.com/guzzle/guzzle}} zu nutzen. Hierdurch erlangte der Autor die Möglichkeit,
asynchrone Requests an die \acs{API} von \ac{IX} zu stellen, ohne einen eigenen \ac{PHP} \acs{HTTP} Client entwickeln zu müssen.
Die Factory instanziiert nun die beim Aufruf angeforderte Klasse. Hier als Beispiel CustomerConnection (siehe \Anhang{app:CustomerConnection} und \Anhang{app:Connection}), welche im
CustomerDataController in der Komponente neusta-m2-intex-customer instanziiert wird (siehe \Anhang{app:CustomerDataController}).
Durch den Fokus auf das Fertigstellen der neusta-m2-intex-client Komponente, waren alle folgenden Subkomponenten trivialer zu implementieren, da bei einem Datenimport
die Abfrage der Daten der Hauptbestandteil einer solchen Anwendung darstellt. Dem folgend wurde vom Autor in Reihenfolge die Logik zur Verarbeitung der erhaltenen Daten
implementiert (neusta-m2-intex-customer \& neusta-m2-intex-catalog) sowie die Möglichkeit die Funktionalität über einen \acs{CRON}-Job anstoßen zu können, welche
im \ac{M2} Standard per \acs{XML} Datei inkludiert werden kann.

View file

@ -1,48 +0,0 @@
% !TEX root = ../Projektdokumentation.tex
\section{Projektplanung}
\label{sec:Projektplanung}
\subsection{Projektphasen}
\label{sec:Projektphasen}
Für die Umsetzung des Projektes standen dem Autor 70 Stunden zur Verfügung. Zu Projektbeginn wurden diese auf, wie in der
Softwareentwicklung üblich, verschiedene Phasen verteilt, die während der Entwicklung durchlaufen werden.
Eine grobe Zeitplanung sowie die Hauptphasen lassen sich der Tabelle~\ref{tab:Zeitplanung} entnehmen.
Eine Pufferzeit wurde bereits in der Planung der Implementierung inkludiert.
Die Hauptphasen werden außerdem noch in kleinere Unterpunkte zerlegt. Eine detaillierte Übersicht der Phasen befindet sich im \Anhang{app:Zeitplanung}.
\tabelle{Zeitplanung}{tab:Zeitplanung}{ZeitplanungKurz}\\
\subsection{Ressourcenplanung}
\label{sec:Ressourcenplanung}
Eine genaue Auflistung der verwendeten Ressourcen, welche für das Projekt eingesetzt wurden, kann der Übersicht im
\Anhang{app:Ressourcen} entnommen werden. Hiermit sind sowohl Hard- und Softwareressourcen als auch Personal vom Autor berücksichtigt worden.
Bei der Auswahl der verwendeten Software wurde darauf geachtet, dass diese kostenfrei (\zB als Open Source) zur Verfügung
steht oder die \ac{NSD} bereits Lizenzen für diese besitzt. Hierdurch sollen anfallende Projektkosten so gering wie möglich
gehalten werden.
\subsection{Entwicklungsprozess}
\label{sec:Entwicklungsprozess}
Bevor mit der Realisierung des Projektes begonnen werden konnte, musste sich der Autor für eine geeignete Vorgehensweise zur Umsetzung entscheiden.
Der Autor hat sich auf einen agilen Entwicklungsprozess festgelegt. Hierbei wird in Anlehnung
an das Vorgehensmodell Kanban \footnote{Wikipedia Kanban Definition - \url{https://en.wikipedia.org/wiki/Kanban}} gearbeitet, welches durch Elemente des Vorgehensmodells Scrum \footnote{Scrum.org - \url{https://www.scrum.org}} erweitert werden soll.
Die für Scrum typischen Iterationen der Projektphasen sowie die damit verbundene, stetige Rücksprache
mit den Stakeholdern sind einige Merkmale, die diesen agilen Entwicklungsprozess auszeichnen und in diesem Abschlussprojekt Anwendung finden.
Eine flexible Umsetzung der Anforderung wird durch die relativ kurzen Entwicklungszyklen ermöglicht. Hierdurch können den Mitarbeitern der \ac{NSD}
zeitnah Resultate präsentiert werden. Aufgrund dieser Tatsache wurde bei der Projektplanung in Abschnitt~\ref{sec:Projektphasen}: \nameref{sec:Projektphasen} für die Entwurfsphase
weniger Zeit eingeplant, da sich Teile dieser Phase erst im Laufe der Entwicklung der Anwendung ergeben.
Das stetige Feedback zur Anwendung, resultierend aus der engen Kommunikation mit den Mitarbeitern, gewährleistet eine bessere und flexiblere Reaktionsfähigkeit
auf Änderungswünsche. So können die Kollegen des Autors während der Entwicklung mit dem System vertraut gemacht werden, welches zur Folge den Vorteil bringt,
dass bei Projektabnahme und -einführung Zeit eingespart werden kann. Dies wurde vom Autor in der Zeitkalkulation bereits berücksichtigt.
Außerdem soll der agile Entwicklungsprozess durch die Praktik der testabgedeckten Entwicklung erweitert werden. Hierbei werden Softwaretests nach der Implementierung
des Quellcodes erstellt. Dies hat zum Vorteil, dass nachträgliche Änderungen immer das gleiche Endresultat in der Datenausgabe erwarten und erhöht somit die Wartbarkeit
der gesamten Anwendung.

View file

@ -1,139 +0,0 @@
<?php declare(strict_types=1);
namespace Neusta\IntexClient\Connection\Model;
use GuzzleHttp\Exception\RequestException;
use Psr\Http\Message\ResponseInterface;
use Psr\Log\LoggerInterface;
use Neusta\IntexClientConfig\Model\Config\Config;
use Neusta\IntexClientConfig\Provider\JsonConfigProvider;
use \GuzzleHttp\Client as GuzzleHttpClient;
use \GuzzleHttp\Event\BeforeEvent;
use \GuzzleHttp\Event\CompleteEvent;
use function sprintf;
abstract class Connection
{
protected const HTTP_STATUS_CODE_OK = 200;
/**
* @var GuzzleHttpClient
*/
protected $httpClient;
/**
* @var Config
*/
protected $serverConfig;
/**
* @var LoggerInterface
*/
protected $logger;
public function __construct(JsonConfigProvider $configProvider, LoggerInterface $logger)
{
$this->logger = $logger;
$this->serverConfig = $configProvider->getConfig('server');
$this->httpClient = new GuzzleHttpClient(
$this->getHttpClientOptions()
);
$this->initHttpEventEmitter();
}
protected function authenticate(): bool
{
$result = false;
$response = $this->createPost(
$this->serverConfig->getAuthUri()
);
$statusCode = $response->getStatusCode();
if ($statusCode === self::HTTP_STATUS_CODE_OK) {
$this->logger->info('authentication successful');
$result = true;
} else {
$this->logger->info(
sprintf('authentication failed with Code: %s', $statusCode)
);
}
return $result;
}
protected function createPost(string $uri, array $options = []): ?ResponseInterface
{
$result = null;
$request = $this->httpClient->postAsync($uri, $options);
$request->then(
static function (ResponseInterface $response) {
$result = $response;
},
function (RequestException $exception) {
$this->logger->info(
sprintf('Crucial Error: %s \n Trace: %u', $exception->getMessage(), $exception->getTraceAsString())
);
}
);
return $result;
}
protected function createGet(string $uri, array $options = []): ?ResponseInterface
{
$result = null;
$request = $this->httpClient->getAsync($uri, $options);
$request->then(
static function (ResponseInterface $response) {
$result = $response;
},
function (RequestException $exception) {
$this->logger->info(
sprintf('Crucial Error: %s \n Trace: %u', $exception->getMessage(), $exception->getTraceAsString())
);
}
);
return $result;
}
protected function initHttpEventEmitter(): void
{
// initialize the EventEmitters to get a good Logging whether the Request was send
// or failed
$this->httpClient->getEmitter()->on('before', static function (BeforeEvent $event) {
$this->logger->info(
sprintf('About to send Request: %s', $event->getRequest())
);
});
$this->httpClient->getEmitter()->on('complete', static function (CompleteEvent $event) {
$this->logger->info(
sprintf('Request %s finished', $event->getRequest())
);
});
$this->httpClient->getEmitter()->on('error', static function (ErrorEvent $event) {
$this->logger->info(
sprintf('Request %s failed', $event->getRequest())
);
});
}
protected function getHttpClientOptions(): array
{
// Configure Base URL for all ongoing Requests and set Cookies to true,
// so we can handle the auth cookie over and over again without using authenticate() multiple times
return [
'base_url' => $this->serverConfig->getBaseUrl(),
'cookies' => true
];
}
}

View file

@ -1,33 +0,0 @@
<?php declare(strict_types=1);
namespace Neusta\IntexClient\Connection\Model;
use Neusta\IntexClientConfig\Model\Config\Config;
use Neusta\IntexClientConfig\Provider\JsonConfigProvider;
use Psr\Log\LoggerInterface;
use function json_decode;
class CustomerConnection extends Connection
{
/**
* @var Config
*/
private $customerConfig;
public function __construct(JsonConfigProvider $configProvider, LoggerInterface $logger)
{
parent::__construct($configProvider, $logger);
$this->customerConfig = $configProvider->getConfig('customer');
}
public function loadCustomerData(): array
{
$response = $this->createGet(
$this->customerConfig->getCustomerUri()
);
return json_decode($response->getBody(), true);
}
}

View file

@ -1,28 +0,0 @@
<?php declare(strict_types=1);
namespace Neusta\IntexCustomer\Controller;
use Neusta\IntexClient\Connection\Model\CustomerConnection;
class CustomerDataController
{
/**
* @var CustomerConnection
*/
private $connection;
public function __construct(\Neusta\IntexClient\Connection\Factory $connectionFactory, \Neusta\IntexCustomer\Handler\DataHandler $dataHandler)
{
$this->connection = $connectionFactory->create('customer');
$this->customerDataHandler = $dataHandler;
}
public function getCustomerData(): void
{
$customerData = $this->connection->loadCustomerData();
$this->customerDataHandler->saveCustomerData($customerData);
}
}

View file

@ -1,27 +0,0 @@
<?php declare(strict_types=1);
namespace Neusta\IntexClient\Connection;
use Neusta\IntexClient\Connection\Model\Connection;
use function class_exists;
use function sprintf;
use function ucwords;
use function strtolower;
class Factory
{
public static function create(string $connectionType): Connection
{
$connectionPath = sprintf(
'\Neusta\IntexClient\Model\Connection\%sConnection',
ucwords(strtolower($connectionType))
);
if (class_exists($connectionPath)) {
return new $connectionPath();
}
throw new \RuntimeException('Invalid Connection Type given');
}
}

View file

@ -1,28 +0,0 @@
<?xml version="1.0" ?>
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="neusta_intex_import" resource="default" engine="innodb"
comment="Neusta IntexImport Logging Table">
<column xsi:type="int" name="value_id" padding="11" unsigned="false" nullable="false" identity="true" comment="Value ID"/>
<column xsi:type="smallint" name="attribute_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Attribute ID"/>
<column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Store ID"/>
<column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Entity ID"/>
<column xsi:type="datetime" name="value" on_update="false" nullable="true" comment="Value"/>
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="value_id"/>
</constraint>
<constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_DTIME_ATTR_ID_EAV_ATTR_ATTR_ID" table="catalog_product_entity_datetime" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/>
<constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_DTIME_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_entity_datetime" column="entity_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/>
<constraint xsi:type="foreign" referenceId="CATALOG_PRODUCT_ENTITY_DATETIME_STORE_ID_STORE_STORE_ID" table="catalog_product_entity_datetime" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/>
<constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID_STORE_ID">
<column name="entity_id"/>
<column name="attribute_id"/>
<column name="store_id"/>
</constraint>
<index referenceId="CATALOG_PRODUCT_ENTITY_DATETIME_ATTRIBUTE_ID" indexType="btree">
<column name="attribute_id"/>
</index>
<index referenceId="CATALOG_PRODUCT_ENTITY_DATETIME_STORE_ID" indexType="btree">
<column name="store_id"/>
</index>
</table>
</schema>

View file

@ -1,39 +0,0 @@
<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;
use Neusta\IntexClient\Connection\Factory;
use Neusta\IntexClient\Connection\Model\CustomerConnection;
class FactoryTest extends TestCase
{
/**
* @var Factory
*/
private $subject;
public function setUp()
{
$this->subject = new Factory();
}
/**
* @test
*/
public function createMustReturnInstanceOfCustomerConnectionWithValidIdentifierGiven()
{
$expectedInstance = $this->subject->create('customer');
self::assertInstanceOf(CustomerConnection::class, $expectedInstance);
}
/**
* @test
* @throws RuntimeException
*/
public function createMustThrowRuntimeExceptionIfInvalidIdentifierIsGiven()
{
$unexpectedInstance = $this->subject->create('fooBar');
self::expectException(RuntimeException::class);
}
}

View file

@ -1,21 +0,0 @@
{
"name": "neusta/m2-intex-client",
"license": "proprietary",
"description": "Client for Magento2 Intex Import/Export",
"type": "magento2-module",
"version": "0.0.1",
"require": {
"php": "7.4.33",
"magento/framework": "~101.0",
"neusta/m2-intex-base": "0.0.1",
"guzzlehttp/guzzle": "6.5.*"
},
"autoload": {
"files": [
"registration.php"
],
"psr-4": {
"Neusta\\IntexClient\\": "src"
}
}
}

View file

@ -1,33 +0,0 @@
<?php
include(dirname(__FILE__).'/../bootstrap/Propel.php');
$t = new lime_test(13);
$t->comment('Empty Information');
$emptyComparedInformation = new ComparedNaturalModuleInformation(array());
$t->is($emptyComparedInformation->getCatalogSign(), ComparedNaturalModuleInformation::EMPTY_SIGN, 'Has no catalog sign');
$t->is($emptyComparedInformation->getSourceSign(), ComparedNaturalModuleInformation::SIGN_CREATE, 'Source has to be created');
$t->comment('Perfect Module');
$criteria = new Criteria();
$criteria->add(NaturalmodulenamePeer::NAME, 'SMTAB');
$moduleName = NaturalmodulenamePeer::doSelectOne($criteria);
$t->is($moduleName->getName(), 'SMTAB', 'Right modulename selected');
$comparedInformation = $moduleName->loadNaturalModuleInformation();
$t->is($comparedInformation->getSourceSign(), ComparedNaturalModuleInformation::SIGN_OK, 'Source sign shines global');
$t->is($comparedInformation->getCatalogSign(), ComparedNaturalModuleInformation::SIGN_OK, 'Catalog sign shines global');
$infos = $comparedInformation->getNaturalModuleInformations();
foreach($infos as $info)
{
$env = $info->getEnvironmentName();
$t->is($info->getSourceSign(), ComparedNaturalModuleInformation::SIGN_OK, 'Source sign shines at ' . $env);
if($env != 'SVNENTW')
{
$t->is($info->getCatalogSign(), ComparedNaturalModuleInformation::SIGN_OK, 'Catalog sign shines at ' . $info->getEnvironmentName());
}
else
{
$t->is($info->getCatalogSign(), ComparedNaturalModuleInformation::EMPTY_SIGN, 'Catalog sign is empty at ' . $info->getEnvironmentName());
}
}
?>

View file

@ -53,12 +53,6 @@
\pagenumbering{arabic}
\input{Inhalt.tex}
% Literatur ------------------------------------------------------------------
\clearpage
\renewcommand{\refname}{Literaturverzeichnis}
\bibliography{Bibliographie}
\bibliographystyle{Allgemein/natdin} % DIN-Stil des Literaturverzeichnisses
% Anhang ---------------------------------------------------------------------
\clearpage
\appendix

21
texput.log Normal file
View file

@ -0,0 +1,21 @@
This is pdfTeX, Version 3.141592653-2.6-1.40.22 (TeX Live 2022/dev/Debian) (preloaded format=pdflatex 2025.6.5) 12 JUN 2025 19:40
entering extended mode
restricted \write18 enabled.
%&-line parsing enabled.
**Projektdokumentation.tex
! Emergency stop.
<*> Projektdokumentation.tex
End of file on the terminal!
Here is how much of TeX's memory you used:
3 strings out of 478287
131 string characters out of 5849290
289007 words of memory out of 5000000
18302 multiletter control sequences out of 15000+600000
469259 words of font info for 28 fonts, out of 8000000 for 9000
1141 hyphenation exceptions out of 8191
0i,0n,0p,1b,6s stack positions out of 5000i,500n,10000p,200000b,80000s
! ==> Fatal error occurred, no output PDF file produced!