diff --git a/appendix.tex b/appendix.tex index 5e93e32..8a135bb 100644 --- a/appendix.tex +++ b/appendix.tex @@ -8,4 +8,5 @@ \input{appendix/fragebogen-extern} \input{appendix/interview-protokoll} \input{appendix/pflichtenheft} + \input{appendix/class-diagram} \end{appendices} diff --git a/appendix/class-diagram.tex b/appendix/class-diagram.tex new file mode 100644 index 0000000..39053c3 --- /dev/null +++ b/appendix/class-diagram.tex @@ -0,0 +1,3 @@ +\chapter{Klassendiagramm} +\label{chap:anhang-class-diagram} +\includepdf[pages=-]{images/class-diagram.pdf} diff --git a/chapters/anforderungserfassung.tex b/chapters/anforderungserfassung.tex index 6528221..48f9482 100644 --- a/chapters/anforderungserfassung.tex +++ b/chapters/anforderungserfassung.tex @@ -41,7 +41,7 @@ Um nähere Anforderungen zu ermitteln, werden die Befragungstechniken \enquote{I \cite{bib:heinemann-vorlesung-re}. \section{Interview mit Product Owner} -Zunächst wird ein Interview mit dem Product Owner geführt. Ziel dieses Interviews ist +Zunächst wird ein Interview mit dem \ac{PO} geführt. Ziel dieses Interviews ist es, konkrete Fragen zu Anforderungen zu beantworten und somit konkrete Anforderungen zu formulieren. Aufgrund der individuellen Gesprächsführung wurde sich für ein \enquote{Teil-standardisiertes Interview} entschieden. Bei einem Teil-standartisiertem Interview gibt es vordefinierte Fragen, @@ -63,13 +63,13 @@ Daher ist es wichtig für jede Stakeholdergruppe einen eigenen Fragebogen zu ent und die bestimmten Perspektiven beim Entwurf der Fragebögen zu beachten. Ebenso ist es wichtig, die wichtigsten Fragen am Anfang zu stellen, da Formulare nicht immer vollständig ausgefüllt werden \cite{bib:kleine-re-fibel}. -Sämtliche Fragen an die Stakeholdergruppe \enquote{Mitarbeiter \ac{WM}} wurden bereits im Interview mit dem Product Owner +Sämtliche Fragen an die Stakeholdergruppe \enquote{Mitarbeiter \ac{WM}} wurden bereits im Interview mit dem \ac{PO} beantwortet und als Anforderungen festgehalten. Insofern gibt es schlichtweg keine offnen Fragen, die diese Stakeholdergruppe beantworten könnte. Damit fällt ein Onlinefragebogen für \enquote{Mitarbeiter \ac{WM}} weg. Der Fragebogen der Stakeholdergruppe \enquote{teilnehmende Weingüter} liegt in \fullref{chap:anhang-fragebogen-extern} bei. \section{Ergebnisse} -Aus dem Interview mit dem Product Owner und dem Fragebogen an die Winzer ergibt ein Pflichtenheft. +Aus dem Interview mit dem \ac{PO} und dem Fragebogen an die Winzer ergibt ein Pflichtenheft. Dieses ist im Anhang unter \fullref{chap:anhang-pflichtenheft} zu finden. Das Interviewprotokoll und Fragebogenergebnisse sind im Anhang unter \fullref{chap:anhang-interview-protokoll} und XXXX zu finden. diff --git a/chapters/einleitung.tex b/chapters/einleitung.tex index d6e43fc..0d17911 100644 --- a/chapters/einleitung.tex +++ b/chapters/einleitung.tex @@ -42,4 +42,4 @@ in der TYPO3-Backend-Oberfläche implementiert werden. \\ \\ Somit lautet die \textbf{Forschungsfrage}:\\ -\textit{Wie kann die Anmeldung und Zustellung von Weinen für Weinproben des Regionalverbunds für Weine in der Weinregion Mosel am effektivsten durch eine TYPO3-Erweiterung realisiert werden, um einen maximalen Nutzen zu erzielen?} +\textit{Wie kann die Anmeldung und Zustellung von Weinen für Weinproben des Regionalverbunds für Weine in der Weinregion Mosel effizient und profitabel durch eine TYPO3-Erweiterung realisiert werden?} diff --git a/chapters/konzeption-entwicklung.tex b/chapters/konzeption-entwicklung.tex index 6c0588c..ea14ebd 100644 --- a/chapters/konzeption-entwicklung.tex +++ b/chapters/konzeption-entwicklung.tex @@ -1,2 +1,82 @@ -\chapter{Konzeption und Entwicklung} -\label{chap:konzeption-entwicklung} +\chapter{Umsetzung} +\label{chap:umsetzung} +Infolge der Anforderungsanalyse befasst sich das Kapitel \enquote{Umsetzung} mit der Implementation der Anforderungen in dem +Brown-Field Projekt \cite{bib:schwarzer-vorlesung-swa} in Form einer TYPO3-Extension. + +\section{Setup einer TYPO3-Extension} +TYPO3-Extension werden via Composer installiert \cite{bib:typo3-docs-managing-extensions}. +Um eine TYPO3-Extension zu erstellen muss also ein Composer-Paket erstellt werden. +Um vermeidbare Komplexität zu verhindern wird das Composer-Paket das eine die hier betrachtete +TYPO3-Extension darstellt, lokal in den versionierten Ordner \enquote{packages} gelegt. +Dieses Verzeichnis wird als Quelle für Composer-Pakete in der +Haupt-composer.json-Datei hinterlegt. +Somit wird ein Composer-Paket nur für dieses Projekt bereitgestellt, +ohne den Aufwand, der mit dem Bereitstellen eines Paketes einhergeht, zu haben. +\\ +\\ +Um das grundlegende Setup einer Extension effizient durchzuführen wurde eine +existierende Extension vergleichbarem Funktionsumfanges kopiert, umbenannt, und eingefügt. +Spezifisch ist der \enquote{vergleichbare Funktionsumfang}, dass es Datenmodelle und Plugins +gibt. + +\section{Digitization} +Die Phase der Digitazion befasst sich mit der digitalen Abbildung von Objekten der realen Welt +in einer Art und Weise sodass diese elektronisch weiterverarbeitet werden können \cite{bib:dougherty, bib:loebbecke}. +Das bedeutet, dass in diese Phase Datenobjekte definiert und implementiert werden. +Ein Datenobjekt besteht nach firmeninternen Konventionen aus zumindest +vier Komponenten: +\begin{description} + \item{Datenbanktabelle} \\ + Die Datenbanktabelle persistiert Informationen. + \item{Domain Model} \\ + Das Domain Model (auch Model genannt) ist eine PHP-Klasse, + die jeweils die Daten einer Zeile der Datenbanktabelle abbildet. + \item{Repository} \\ + Ein Repository ist eine PHP-Klasse, die die Schnittstelle + zwischen der Datenbank und der Model-Klasse darstellt. + \item{\ac{TCA}} \\ + Der \ac{TCA} des Modells definiert, wie diese Objekte im TYPO3-Backend dargestellt werden + und bearbeitbar sind. +\end{description} +\cite{bib:typo3-docs-extbase-reference}. + +Im Folgenden wurde ein semiformales Diagramm der Objekte und ihren Relationen nach dem +Pflichtenheft angefertigt und in Rücksprache mit dem \ac{PO} finalisiert. + +\begin{nicepic} + \includegraphics[width=1\textwidth]{images/objektrelationen-weinlandmosel-einlieferungswerkzeug.png} + \captionof{figure}{Objektrelationen} + \caption*{Quelle: Eigene Darstellung} + \label{fig:objektrelationen} +\end{nicepic} + +Nachdem in Erfahrung gebracht wurde, welche konkreten Datenobjekte benötigt werden, +wurden Attribute dieser Objekte dem Pflichtenheft entnommen. Diese wurden in einem +formalen Klassendiagramm festgehalten und in Rücksprache mit dem \ac{PO} +weiter bis zu festen Datentypen und Auswahlmöglichkeiten konkretisiert. +Beispielsweise, dass Wettbewerbskategorien als TYPO3-Categories verschachtelt gepflegt +werden und dass Geschmacksrichtungen, Qualitätsstufen, Rebsorten, Weinlagen und +Weineigenschaften eigene Datenobjekte +sein sollen. Geschmack und Qualität sollen daher eigene Objekte sein, damit sich Nutzer +für einen festen, nominalen Eintrag via einem Dropdown-Menü entscheiden müssen, +diese allerdings immer noch im TYPO3-Backend pflegbar sind. Weinlagen sind allerdings im Brown-Field bereits vorhanden, also sollen hierfür +existierenden Einträge verwendet werden. Weineigenschaften sollen pro Wein beliebig viele +auswählbar sein, Wettbewerbskategorien, etc, jeweils genau ein Element. +Notizen zu diesem Gespräch sind im Anhang unter \fullref{chap:anhang-notizen-digitization} +zu finden. +\\ +\\ +Da das Klassendiagramm gegeben lesbarer Schrift nicht auf eine Textseite passt, +befindet es sich vollseitig im Anhang unter \fullref{chap:anhang-class-diagram}. +Die weitere Implementation der Datenobjekte ist unkompliziert und besteht hauptsächlich aus +repetitivem Schreiben von SQL-Tabellen, Domain-Model-Klassen und \acp{TCA}. +Um $m,n$-Beziehungen wie Beispielsweise der Menge der für eine Probe zugelassenen Weinlagen +\enquote{allowedVinesites} zwischen \enquote{Jahresauswahlprobe} und \enquote{Vineyardsite} zu +ermöglichen, werden MM-Tabellen (many-to-many) benötigt, die diese Beziehungen in Form zweier +Foreign Keys speichern. Die Repository-Klassen können \enquote{leer} gelassen werden, +da zu diesem Zeitpunkt keine erweiterte Auswahllogik für Datenbankanfragen benötigt wird. +Wichtig ist hierbei, dass eine Repository-Klasse existiert. Alle unverzichtbaren +Schnittstellen werden über die Basisklasse \enquote{Repository} geerbt +\cite{bib:typo3-docs-extdev-tut-tea-repositories}. +Mit Abschluss der Digitization können alle Datenstrukturen im TYPO3-Backend händisch angelegt, +eingesehen, gelöscht und bearbeitet werden. diff --git a/config.tex b/config.tex index 6488cd1..d9987f5 100644 --- a/config.tex +++ b/config.tex @@ -4,7 +4,7 @@ % Document title \newcommand{\cfgDocTitle}{Bachelorarbeit} -\newcommand{\cfgDocSubTitle}{Wie kann die Anmeldung und Zustellung von Weinen für Weinproben des Regionalverbunds für Weine in der Weinregion Mosel am effektivsten durch eine TYPO3-Erweiterung realisiert werden, um einen maximalen Nutzen zu erzielen?} +\newcommand{\cfgDocSubTitle}{Wie kann die Anmeldung und Zustellung von Weinen für Weinproben des Regionalverbunds für Weine in der Weinregion Mosel effizient und profitabel durch eine TYPO3-Erweiterung realisiert werden?} % Document classification \newcommand{\cfgDocClassification}{Abschlussarbeit} diff --git a/dexes/acrodex.tex b/dexes/acrodex.tex index 75aaccc..98c80f0 100644 --- a/dexes/acrodex.tex +++ b/dexes/acrodex.tex @@ -24,6 +24,12 @@ \acro{JAP}[JAP]{Jahresauswahlprobe} \acroplural{JAP}[JAPs]{Jahresauswahlproben} + +\acro{TCA}[TCA]{Table configuration array} +\acroplural{TCA}[TCAs]{Table configuration arrays} + +\acro{PO}[PO]{Product owner} +\acroplural{PO}[POs]{Product owner} % % \end{acronym} diff --git a/dexes/glossarydex.tex b/dexes/glossarydex.tex index 58fdc2f..9261f4f 100644 --- a/dexes/glossarydex.tex +++ b/dexes/glossarydex.tex @@ -5,6 +5,29 @@ \chapter{Glossar} \begin{description} + \item [Frontend] \hfill \\ \quotecite{Das Frontend einer Webseite ist der Teil der Webseite, der Endnutzern präsentiert wird. Ein Frontend besteht aus HTML und Cascading Style Sheets} \cite{bib:udjaja}. + + \item [TYPO3-Backend] \hfill \\ + \quotecite{The backend's main role is to enable users to create and publish + content for their site. + The backend is also used to configure a TYPO3 installation. Domains, + languages and other information that determine how a site behaves are managed + via the backend. Tasks such as adding backend users and managing + third-party extensions also take place in the backend. + } \cite{bib:typo3-docs-concepts}. + + \item [TYPO3-Extension] \hfill \\ + \quotecite{Developed by the community, extensions provide a range of solutions that + help extend TYPO3} \cite{bib:typo3-docs-concepts}. + + \item [TYPO3-Plugin] \hfill \\ + \quotecite{Plugins are a specific type of content elements [...] + Plugins often use additional database tables which contain records which + are dynamically displayed via the plugin - often in a list view, a + single view, optionally with pagination and search functionality. + An extension may provide several plugins, each with a dedicated function, + such as the list view.} \cite{bib:typo3-docs-content-elements-plugins-introduction} + \end{description} diff --git a/dexes/literature.bib b/dexes/literature.bib index 8088225..644067d 100644 --- a/dexes/literature.bib +++ b/dexes/literature.bib @@ -12,6 +12,13 @@ publisher = {Hochschule Worms}, } +@book{bib:schwarzer-vorlesung-swa, + author = {Volker Schwarzer}, + title = {Vorlesung: Software Architecture}, + year = {2021}, + publisher = {Hochschule Worms}, +} + @article{bib:Parviainen_Tihinen_Kaariainen_Teppola_2022, title={Tackling the digitalization challenge: how to benefit from digitalization in practice}, volume={5}, @@ -296,3 +303,51 @@ year = {2023}, note = {Zugriff: Januar 2023} } + +@misc{bib:typo3-docs-managing-extensions, + author = {{TYPO3 Contributors}}, + howpublished = "\url{https://docs.typo3.org/m/typo3/tutorial-getting-started/main/en-us/Extensions/Management.html}", + title = {{Managing Extensions}}, + year = {2023}, + note = {Zugriff: Februar 2023} +} + +@misc{bib:typo3-docs-concepts, + author = {{TYPO3 Contributors}}, + howpublished = "\url{https://docs.typo3.org/m/typo3/tutorial-getting-started/main/en-us/Concepts}", + title = {{TYPO3 Concepts}}, + year = {2023}, + note = {Zugriff: Februar 2023} +} + +@misc{bib:typo3-docs-file-structure, + author = {{TYPO3 Contributors}}, + howpublished = "\url{https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ExtensionArchitecture/FileStructure/Index.html}", + title = {{TYPO3 Extension Development File Structure}}, + year = {2023}, + note = {Zugriff: Februar 2023} +} + +@misc{bib:typo3-docs-content-elements-plugins-introduction, + author = {{TYPO3 Contributors}}, + howpublished = "\url{https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ApiOverview/ContentElements/Introduction.html}", + title = {{What are Content Elements?}}, + year = {2023}, + note = {Zugriff: Februar 2023} +} + +@misc{bib:typo3-docs-extbase-reference, + author = {{TYPO3 Contributors}}, + howpublished = "\url{https://docs.typo3.org/m/typo3/reference-coreapi/11.5/en-us/ExtensionArchitecture/Extbase/Reference/Index.html}", + title = {{Extbase reference}}, + year = {2023}, + note = {Zugriff: Februar 2023} +} + +@misc{bib:typo3-docs-extdev-tut-tea-repositories, + author = {{TYPO3 Contributors}}, + howpublished = "\url{https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ExtensionArchitecture/Tutorials/Tea/Repository.html}", + title = {{Extension development / Tutorials / Tea in a nutshell / Repository}}, + year = {2023}, + note = {Zugriff: Februar 2023} +} diff --git a/images/class-diagram.pdf b/images/class-diagram.pdf new file mode 100644 index 0000000..6724d3e Binary files /dev/null and b/images/class-diagram.pdf differ diff --git a/images/class-diagram.png b/images/class-diagram.png index d6597d2..e4574c2 100644 Binary files a/images/class-diagram.png and b/images/class-diagram.png differ diff --git a/images/class-diagram.puml b/images/class-diagram.puml index bb56f24..c5ddcd0 100644 --- a/images/class-diagram.puml +++ b/images/class-diagram.puml @@ -5,6 +5,8 @@ skinparam legendBackgroundColor black +!define GROUP_PACKAGE + class Category #OUT_OF_SCOPE_COLOR { -uid: Int -name: String @@ -17,45 +19,6 @@ class Category #OUT_OF_SCOPE_COLOR { +setDescription(description: String): void } -class MasterRecord #OUT_OF_SCOPE_COLOR { - -properties: List - -mitgliedsnummer: Int - -fe_user: fe_user - +getProperties(): List - +setProperties(properties: List): void - +getMitgliedsnummer(): Int - +setMitgliedsnummer(nmr: Int): void - +getFeUser(): fe_user - +setFeUser(feUser: fe_user): void -} - -class Address #OUT_OF_SCOPE_COLOR { - -street: String - -zip: String - -name: String - -city: String - +getStreet(): String - +setStreet(street: String): void - +getZip(): String - +setZip(zip: String): void - +getName(): String - +setName(name: String): void - +getCity(): String - +setCity(city: String): void -} - -class Property #OUT_OF_SCOPE_COLOR { - -addresses: List
- +getAddresses(): List
- +setAddresses(addresses: List
): void -} - -class Winery #OUT_OF_SCOPE_COLOR { - -name: String - +getName(): String - +setName(name: String): void -} - class Grape #IMPLEMENTED_COLOR { -uid: Int -name: String @@ -68,7 +31,31 @@ class Grape #IMPLEMENTED_COLOR { +setDescription(description: String): void } -class Vinesite #IMPLEMENTED_COLOR { +class Taste #IMPLEMENTED_COLOR { + -uid: Int + -name: String + -description: String + +getUid(): Int + +setUid(uid: Int): void + +getName(): String + +setName(name: String): void + +getDescription(): String + +setDescription(description: String): void +} + +class Quality #IMPLEMENTED_COLOR { + -uid: Int + -name: String + -description: String + +getUid(): Int + +setUid(uid: Int): void + +getName(): String + +setName(name: String): void + +getDescription(): String + +setDescription(description: String): void +} + +class Vinesite #OUT_OF_SCOPE_COLOR { -uid: Int -name: String -description: String @@ -110,8 +97,8 @@ class Wine #IMPLEMENTED_COLOR { -vinesite: Vinesite -category: Category -vintage: int - -quality: int - -taste: String + -quality: Quality + -taste: Taste -winekinds: List -ap_nr: String -acidity: float @@ -136,10 +123,10 @@ class Wine #IMPLEMENTED_COLOR { +setCategory(category: Category): void +getVintage(): int +setVintage(vintage: int): void - +getQuality(): int - +setQuality(quality: int): void - +getTaste(): String - +setTaste(taste: String): void + +getQuality(): Quality + +setQuality(quality: Quality): void + +getTaste(): Taste + +setTaste(taste: Taste): void +getWinekinds(): List +setWinekinds(winekinds: List): void +getApNr(): String @@ -191,14 +178,12 @@ class Jahresauswahlprobe #IMPLEMENTED_COLOR { +setUid(uid: Int): void } -MasterRecord "1" --> "1" Participant -MasterRecord "1" --> "*" Property -Property "1" --> "*" Address -Property <|-- Winery Category "1" <-- "*" Wine Grape "1" <-- "*" Wine Vinesite "1" <-- "*" Wine Participant "1" <-- "*" Wine +Taste "1" <-- "*" Wine +Quality "1" <-- "*" Wine WineKind "1" <-- "*" Wine Jahresauswahlprobe "*" <-- "*" Wine diff --git a/main.pdf b/main.pdf index d6c99db..be4be1f 100644 Binary files a/main.pdf and b/main.pdf differ