docs: clean up, remove clearpages
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				CI / Get Changed Files (pull_request) Successful in 14s
				
			
		
			
				
	
				CI / eslint (pull_request) Has been skipped
				
			
		
			
				
	
				Label PRs based on size / Check PR size (pull_request) Successful in 13s
				
			
		
			
				
	
				CI / oxlint (pull_request) Has been skipped
				
			
		
			
				
	
				CI / Backend Tests (pull_request) Has been skipped
				
			
		
			
				
	
				CI / prettier (pull_request) Has been skipped
				
			
		
			
				
	
				CI / Checkstyle Main (pull_request) Has been skipped
				
			
		
			
				
	
				CI / test-build (pull_request) Has been skipped
				
			
		
			
				
	
				Pull Request Labeler / labeler (pull_request_target) Successful in 8s
				
			
		
			
				
	
				CI / Docker frontend validation (pull_request) Has been skipped
				
			
		
			
				
	
				CI / Docker backend validation (pull_request) Has been skipped
				
			
		
			
				
	
				CI / Playwright (pull_request) Has been skipped
				
			
		
			
				
	
				Build docs / build-docs (pull_request) Successful in 26s
				
			
		
			
				
	
				Claude PR Review / claude-code (pull_request) Successful in 4m32s
				
			
		
		
	
	
		
	| 
						 | 
				
			
			@ -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}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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•–®Ü˜jþ‘™‰kËÐÔ‰<YÔÊ¢6jkæKäèðgG„Jáœî¥]V6$<08>y¨
 | 
			
		||||
¸»{>Úì:×}}ÉXw„ûôuÑü¬ÿÊî§ö¬<C3B6>f1G–Ýêæ¶ûð‰ÆA<>=HÌMløïÝ›néÁ,4ÍÁ.U’mÏú¦M×Ι´ç<e=Ñ«Œf)M–«Q™ùÕØÿ¬¾¥º\…LÒfÞÑ Œ\ul‹Òh|4aÂ85\A„Ù%ŸÒ ï{ÔBºÆ©ÔŠAËÃûÆë{Â[Ò)}Öë–^
¼}I8kà<6B>XTðBº%=ô„ÁfA®Ö8ÅF b›CS«6{cŒYÌ;áX©ÔÙ7«vGPj7ŠƒÑCo¢_ 'ôôÚ]Æ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
 | 
			
		||||
| 
						 | 
				
			
			@ -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^ëTp³œù ÙuÙËaÌóHǺ#Ügž›Õ×þ¯ú‘z¤Wë4[(Šl—<6C>}óð#zþqÚ¤¡æ\ä‡÷í<C3B7>îÖf¥
 | 
			
		||||
v©‘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
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 65 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								projektdokumentation/Bilder/component-diagram.drawio.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 261 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								projektdokumentation/Bilder/container-diagram.drawio.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 84 KiB  | 
| 
		 Before Width: | Height: | Size: 347 KiB  | 
| 
		 Before Width: | Height: | Size: 115 KiB  | 
| 
		 Before Width: | Height: | Size: 93 KiB  | 
| 
		 Before Width: | Height: | Size: 1 KiB  | 
| 
		 Before Width: | Height: | Size: 952 B  | 
| 
		 Before Width: | Height: | Size: 1.2 KiB  | 
| 
		 Before Width: | Height: | Size: 1.2 KiB  | 
| 
		 Before Width: | Height: | Size: 1.6 KiB  | 
| 
						 | 
				
			
			@ -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.
 | 
			
		||||
| 
						 | 
				
			
			@ -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}.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,4 +1,3 @@
 | 
			
		|||
\clearpage
 | 
			
		||||
\section{Coinflip}
 | 
			
		||||
 | 
			
		||||
\subsection{Was ist Coinflip?}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,3 @@
 | 
			
		|||
\clearpage
 | 
			
		||||
\section{Dice}
 | 
			
		||||
 | 
			
		||||
\subsection{Was ist Dice?}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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.
 | 
			
		||||
| 
						 | 
				
			
			@ -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.
 | 
			
		||||
| 
						 | 
				
			
			@ -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.
 | 
			
		||||
| 
						 | 
				
			
			@ -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.
 | 
			
		||||
| 
						 | 
				
			
			@ -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.
 | 
			
		||||
| 
						 | 
				
			
			@ -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.
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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');
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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>
 | 
			
		||||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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"
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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());
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
?>
 | 
			
		||||
| 
						 | 
				
			
			@ -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
									
								
							
							
						
						| 
						 | 
				
			
			@ -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!
 | 
			
		||||