Compare commits

..

20 Commits

Author SHA1 Message Date
7b29c7df40 Abgabe (Calcan_Conze) - Vollendung 2024-09-04 09:07:56 +02:00
5795489f1e Fehlerbehebung im Export (Database) nach Testing 2024-09-02 20:09:45 +02:00
1a7a05f2f0 Kommentare, Autoren & Projektablauf 2024-09-02 18:47:52 +02:00
d052784121 Code CleanUp - Export leider doch fehlerhaft 2024-09-02 14:09:35 +02:00
eac696921a Fertigstellung - Testing fehlt noch 2024-09-02 13:55:13 +02:00
6953b36930 Leichte Anpassungen am Export 2024-08-30 10:41:40 +02:00
4b682a8b46 Import & Database Verbindung vollendet - Anfang vom Export 2024-08-30 08:09:49 +02:00
aeb2707699 Beginn dbConnection 2024-08-28 08:55:39 +02:00
ebcc615de4 Leichte Anpassungen / Einlesen funktioniert jetzt über den Pfad 2024-08-26 22:24:50 +02:00
26c62d000d Komplette Überarbeitung - Import technisch richtig / File wird noch nicht gefunden 2024-08-23 10:42:39 +02:00
9f2e9cbec8 Export hinzugefügt, Import überarbeitet 2024-07-05 11:08:37 +02:00
5c51f68e6c Erweiterung mit Kommentaren 2024-06-19 12:18:57 +02:00
6a05c7b75b Lösungsvariante hinzugefügt 2024-06-19 11:54:33 +02:00
b5daf727d0 Ideenfindung + Dokumentation + Leichte Änderungen 2024-06-12 12:58:13 +02:00
5be00c2e03 no message 2024-06-12 11:43:05 +02:00
0156f3e3ac Überlegungen & Ansätze erweitert 2024-06-07 11:19:49 +02:00
de62de21ab Aufgabenstellung erweitert 2024-06-07 10:32:07 +02:00
8e94f38b7b Git Ignore edit 2 2024-05-29 12:40:55 +02:00
380af838a6 gitignore added 2024-05-29 12:36:45 +02:00
822a8f4f6f Nur zum testen bruder 2024-05-29 12:34:35 +02:00
35 changed files with 3709 additions and 31 deletions

400
.gitignore vendored Normal file
View File

@@ -0,0 +1,400 @@
*.vsidx
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.tlog
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
*.vbp
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
*.dsw
*.dsp
# Visual Studio 6 technical files
*.ncb
*.aps
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# Visual Studio History (VSHistory) files
.vshistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
# VS Code files for those working on multiple tools
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
# Local History for Visual Studio Code
.history/
# Windows Installer files from build outputs
*.cab
*.msi
*.msix
*.msm
*.msp
# JetBrains Rider
*.sln.iml

73
Dateien/import_yutani.csv Normal file
View File

@@ -0,0 +1,73 @@
Frau;Sabrina;Schröder;11.02.1992
Adresse;Brückenstraße 9;93047;Regensburg
E-Mail;sabrina.schroder@example.com;;
Telefon;941;77990011;
Telefon;179;77889900;
Herr;Alexander;Neumann;27.03.1983
Adresse;Am Rathaus 4;94032;Passau
E-Mail;alexander.neumann@example.com;;
Telefon;170;88990011;
Telefon;851;11224433;
Frau;Nina;Schwarz;09.10.1989
Adresse;Hafenstraße 3;18055;Rostock
E-Mail;nina.schwarz@example.com;;
Telefon;172;99001122;
Telefon;381;66554433;
Herr;Markus;Zimmermann;30.12.1986
Adresse;Friedrichstraße 10;10178;Berlin
E-Mail;markus.zimmermann@example.com;;
Telefon;40;22335544;
Telefon;176;10111213;
Frau;Lisa;Krüger;15.06.1991
Adresse;Schloßallee 1;80333;München
E-Mail;lisa.kruger@example.com;;
Telefon;30;44667788;
Telefon;179;12131415;
Herr;Christian;Hartmann;23.01.1980
Adresse;Wilhelmstraße 5;50679;Köln
E-Mail;christian.hartmann@example.com;;
Telefon;30;13141516;
Frau;Melanie;Werner;19.09.1987
Adresse;Heinrich-Heine-Platz 7;20097;Hamburg
E-Mail;melanie.werner@example.com;;
Telefon;40;14151617;
Herr;Patrick;Krause;05.05.1984
Adresse;Neustadt 3;30159;Hannover
E-Mail;patrick.krause@example.com;;
Telefon;89;15161718;
Frau;Claudia;Meier;02.03.1990
Adresse;Alte Straße 22;1067;Dresden
E-Mail;claudia.meier@example.com;;
Telefon;221;16171819;
Herr;Tobias;Lehmann;26.11.1985
Adresse;Markt 11;4109;Leipzig
E-Mail;tobias.lehmann@example.com;;
Telefon;511;17181920;
Frau;Sandra;Maier;17.04.1988
Adresse;Rathausplatz 8;34117;Kassel
E-Mail;sandra.maier@example.com;;
Telefon;331;18192021;
Herr;Jan;Huber;08.08.1983
Adresse;Hauptplatz 15;65183;Wiesbaden
E-Mail;jan.huber@example.com;;
Telefon;361;19202122;
Frau;Susanne;Schulz;21.06.1992
Adresse;Am Markt 6;49074;Osnabrück
E-Mail;susanne.schulz@example.com;;
Telefon;551;20212223;
Herr;Benjamin;Lang;09.12.1986
Adresse;Hofgartenweg 1;86150;Augsburg
E-Mail;benjamin.lang@example.com;;
Telefon;381;21222324;
Frau;Kerstin;Böhm;02.07.1987
Adresse;Mühlweg 18;99084;Erfurt
E-Mail;kerstin.bohm@example.com;;
Telefon;561;22232425;
Herr;Florian;Kuhn;16.05.1982
Adresse;Burgstraße 2;37073;Göttingen
E-Mail;florian.kuhn@example.com;;
Frau;Anja;Peters;11.08.1991
Adresse;Schillerplatz 9;14467;Potsdam
E-Mail;anja.peters@example.com;;
Herr;Tim;Franke;22.10.1980
E-Mail;tim.franke@example.com;;
1 Frau Sabrina Schröder 11.02.1992
2 Adresse Brückenstraße 9 93047 Regensburg
3 E-Mail sabrina.schroder@example.com
4 Telefon 941 77990011
5 Telefon 179 77889900
6 Herr Alexander Neumann 27.03.1983
7 Adresse Am Rathaus 4 94032 Passau
8 E-Mail alexander.neumann@example.com
9 Telefon 170 88990011
10 Telefon 851 11224433
11 Frau Nina Schwarz 09.10.1989
12 Adresse Hafenstraße 3 18055 Rostock
13 E-Mail nina.schwarz@example.com
14 Telefon 172 99001122
15 Telefon 381 66554433
16 Herr Markus Zimmermann 30.12.1986
17 Adresse Friedrichstraße 10 10178 Berlin
18 E-Mail markus.zimmermann@example.com
19 Telefon 40 22335544
20 Telefon 176 10111213
21 Frau Lisa Krüger 15.06.1991
22 Adresse Schloßallee 1 80333 München
23 E-Mail lisa.kruger@example.com
24 Telefon 30 44667788
25 Telefon 179 12131415
26 Herr Christian Hartmann 23.01.1980
27 Adresse Wilhelmstraße 5 50679 Köln
28 E-Mail christian.hartmann@example.com
29 Telefon 30 13141516
30 Frau Melanie Werner 19.09.1987
31 Adresse Heinrich-Heine-Platz 7 20097 Hamburg
32 E-Mail melanie.werner@example.com
33 Telefon 40 14151617
34 Herr Patrick Krause 05.05.1984
35 Adresse Neustadt 3 30159 Hannover
36 E-Mail patrick.krause@example.com
37 Telefon 89 15161718
38 Frau Claudia Meier 02.03.1990
39 Adresse Alte Straße 22 1067 Dresden
40 E-Mail claudia.meier@example.com
41 Telefon 221 16171819
42 Herr Tobias Lehmann 26.11.1985
43 Adresse Markt 11 4109 Leipzig
44 E-Mail tobias.lehmann@example.com
45 Telefon 511 17181920
46 Frau Sandra Maier 17.04.1988
47 Adresse Rathausplatz 8 34117 Kassel
48 E-Mail sandra.maier@example.com
49 Telefon 331 18192021
50 Herr Jan Huber 08.08.1983
51 Adresse Hauptplatz 15 65183 Wiesbaden
52 E-Mail jan.huber@example.com
53 Telefon 361 19202122
54 Frau Susanne Schulz 21.06.1992
55 Adresse Am Markt 6 49074 Osnabrück
56 E-Mail susanne.schulz@example.com
57 Telefon 551 20212223
58 Herr Benjamin Lang 09.12.1986
59 Adresse Hofgartenweg 1 86150 Augsburg
60 E-Mail benjamin.lang@example.com
61 Telefon 381 21222324
62 Frau Kerstin Böhm 02.07.1987
63 Adresse Mühlweg 18 99084 Erfurt
64 E-Mail kerstin.bohm@example.com
65 Telefon 561 22232425
66 Herr Florian Kuhn 16.05.1982
67 Adresse Burgstraße 2 37073 Göttingen
68 E-Mail florian.kuhn@example.com
69 Frau Anja Peters 11.08.1991
70 Adresse Schillerplatz 9 14467 Potsdam
71 E-Mail anja.peters@example.com
72 Herr Tim Franke 22.10.1980
73 E-Mail tim.franke@example.com

View File

@@ -3,8 +3,8 @@
"WorkspaceRootPath": "C:\\Jan_bib_Module\\PMC\\Projekt\\Projekt_Calcan_Conze\\", "WorkspaceRootPath": "C:\\Jan_bib_Module\\PMC\\Projekt\\Projekt_Calcan_Conze\\",
"Documents": [ "Documents": [
{ {
"AbsoluteMoniker": "D:0:0:{44DD7752-6BB5-4C3A-9053-671D8ADE49C4}|Projekt_Calcan_Conze\\Projekt_Calcan_Conze.csproj|c:\\jan_bib_module\\pmc\\projekt\\projekt_calcan_conze\\projekt_calcan_conze\\program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "AbsoluteMoniker": "D:0:0:{9E018F4D-EED3-44D0-9179-E6637B984D74}|Projekt_Calcan_Conze_Export\\Projekt_Calcan_Conze_Export.csproj|c:\\jan_bib_module\\pmc\\projekt\\projekt_calcan_conze\\projekt_calcan_conze_export\\repositories\\database.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{44DD7752-6BB5-4C3A-9053-671D8ADE49C4}|Projekt_Calcan_Conze\\Projekt_Calcan_Conze.csproj|solutionrelative:projekt_calcan_conze\\program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" "RelativeMoniker": "D:0:0:{9E018F4D-EED3-44D0-9179-E6637B984D74}|Projekt_Calcan_Conze_Export\\Projekt_Calcan_Conze_Export.csproj|solutionrelative:projekt_calcan_conze_export\\repositories\\database.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
} }
], ],
"DocumentGroupContainers": [ "DocumentGroupContainers": [
@@ -19,14 +19,14 @@
{ {
"$type": "Document", "$type": "Document",
"DocumentIndex": 0, "DocumentIndex": 0,
"Title": "Program.cs", "Title": "Database.cs",
"DocumentMoniker": "C:\\Jan_bib_Module\\PMC\\Projekt\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze\\Program.cs", "DocumentMoniker": "C:\\Jan_bib_Module\\PMC\\Projekt\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze_Export\\Repositories\\Database.cs",
"RelativeDocumentMoniker": "Projekt_Calcan_Conze\\Program.cs", "RelativeDocumentMoniker": "Projekt_Calcan_Conze_Export\\Repositories\\Database.cs",
"ToolTip": "C:\\Jan_bib_Module\\PMC\\Projekt\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze\\Program.cs", "ToolTip": "C:\\Jan_bib_Module\\PMC\\Projekt\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze_Export\\Repositories\\Database.cs",
"RelativeToolTip": "Projekt_Calcan_Conze\\Program.cs", "RelativeToolTip": "Projekt_Calcan_Conze_Export\\Repositories\\Database.cs",
"ViewState": "AQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAABOAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2024-05-24T09:06:25.212Z", "WhenOpened": "2024-09-02T18:06:03.752Z",
"EditorCaption": "" "EditorCaption": ""
} }
] ]

View File

@@ -0,0 +1,7 @@
Rechnungszeitraum (von);Rechnungszeitraum (bis);Kundennummer;Kundenname;Gesamtbetrag
2024-06-01;2024-08-25;K-12345;bibtastic GmbH;29.264
Bereich;Grundbetrag;Anzahl;Betrag;
Verkaufsgespräch;0.030;8;0.240;
Tarif Orange XL 12 Monate;12.000;2;24.000;
Tarif Orange S 12 Monate;5.000;1;5.000;
Newsletter wöchentlich;0.001;24;0.024;
1 Rechnungszeitraum (von) Rechnungszeitraum (bis) Kundennummer Kundenname Gesamtbetrag
2 2024-06-01 2024-08-25 K-12345 bibtastic GmbH 29.264
3 Bereich Grundbetrag Anzahl Betrag
4 Verkaufsgespräch 0.030 8 0.240
5 Tarif Orange XL 12 Monate 12.000 2 24.000
6 Tarif Orange S 12 Monate 5.000 1 5.000
7 Newsletter wöchentlich 0.001 24 0.024

View File

@@ -0,0 +1,6 @@
Rechnungszeitraum (von);Rechnungszeitraum (bis);Kundennummer;Kundenname;Gesamtbetrag
2024-06-01;2024-08-25;K2-0002;Weyland-Yutani Corporation;5.785
Bereich;Grundbetrag;Anzahl;Betrag;
Anfrage Besichtigung;0.005;7;0.035;
Besichtigungstermin vereinbart;1.000;4;4.000;
Prospekt wöchentlich;0.050;35;1.750;
1 Rechnungszeitraum (von) Rechnungszeitraum (bis) Kundennummer Kundenname Gesamtbetrag
2 2024-06-01 2024-08-25 K2-0002 Weyland-Yutani Corporation 5.785
3 Bereich Grundbetrag Anzahl Betrag
4 Anfrage Besichtigung 0.005 7 0.035
5 Besichtigungstermin vereinbart 1.000 4 4.000
6 Prospekt wöchentlich 0.050 35 1.750

View File

@@ -0,0 +1,38 @@
// Die eindeutige Einteilung von Klassen und Methoden ist quasi unmöglich.
// Radu hat mehr beim Export gemacht
// Jan hat mehr beim Import gemacht
// Im Verlauf haben wir aber immer auch mal Code vom anderen angepasst, verändert und ausgeholfen
// Im SourceTree findest du nur Einträge von mir (Jan) allerdings lag das an dem endlosen Fehler in SourceTree auf Seiten Radus
// Viele Sachen hat er mir als Datei oder Bild zukommen lassen, sodass ich das einfügen und hochladen konnte
// Zur Vollendung wurde keine KI benutzt allerdings mussten wir einiges ergoggeln und parallel habe ich einige Tipps zur Struktur
// von einem guten Freund bekommen
// Konstanten durch beide Partien bei Bedarf erweitert
namespace Core;
public static class Constants
{
public const string ConnectionString = "server=localhost;uid=root;pwd=root;database=import_export";
public const string DateOfBirthFormat = "dd.MM.yyyy";
public const string DateFormat = "yyyy-MM-dd";
public const string MoneyFormat = "F3";
public const char Separator = ';';
public const string FemaleAttributeIdentifier = "Frau";
public const string MaleAttributeIdentifier = "Herr";
public const string DiverseAttributeIdentifier = "Divers";
public const string AddressAttributeIdentifier = "Adresse";
public const string EmailAttributeIdentifier = "E-Mail";
public const string PhoneNumberAttributeIdentifier = "Telefon";
}

View File

@@ -1,7 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>

View File

@@ -3,7 +3,11 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17 # Visual Studio Version 17
VisualStudioVersion = 17.10.34916.146 VisualStudioVersion = 17.10.34916.146
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Projekt_Calcan_Conze", "Projekt_Calcan_Conze\Projekt_Calcan_Conze.csproj", "{44DD7752-6BB5-4C3A-9053-671D8ADE49C4}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Projekt_Calcan_Conze_Import", "Projekt_Calcan_Conze\Projekt_Calcan_Conze_Import.csproj", "{44DD7752-6BB5-4C3A-9053-671D8ADE49C4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Projekt_Calcan_Conze_Export", "Projekt_Calcan_Conze_Export\Projekt_Calcan_Conze_Export.csproj", "{9E018F4D-EED3-44D0-9179-E6637B984D74}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core", "Core\Core.csproj", "{1A945077-A135-4756-974C-A87109DF411E}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -15,6 +19,14 @@ Global
{44DD7752-6BB5-4C3A-9053-671D8ADE49C4}.Debug|Any CPU.Build.0 = Debug|Any CPU {44DD7752-6BB5-4C3A-9053-671D8ADE49C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{44DD7752-6BB5-4C3A-9053-671D8ADE49C4}.Release|Any CPU.ActiveCfg = Release|Any CPU {44DD7752-6BB5-4C3A-9053-671D8ADE49C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{44DD7752-6BB5-4C3A-9053-671D8ADE49C4}.Release|Any CPU.Build.0 = Release|Any CPU {44DD7752-6BB5-4C3A-9053-671D8ADE49C4}.Release|Any CPU.Build.0 = Release|Any CPU
{9E018F4D-EED3-44D0-9179-E6637B984D74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9E018F4D-EED3-44D0-9179-E6637B984D74}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9E018F4D-EED3-44D0-9179-E6637B984D74}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9E018F4D-EED3-44D0-9179-E6637B984D74}.Release|Any CPU.Build.0 = Release|Any CPU
{1A945077-A135-4756-974C-A87109DF411E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1A945077-A135-4756-974C-A87109DF411E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1A945077-A135-4756-974C-A87109DF411E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1A945077-A135-4756-974C-A87109DF411E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@@ -0,0 +1,16 @@
// Import: Jan Conze / PBS2H23ACO mit Unterstützung durch Radu Catalin Calcan
namespace Projekt_Calcan_Conze_Import.DTOs;
internal class UserAttributeDto
{
public UserAttributeDto(List<string> parts, string originalCsvLine)
{
this.Parts = parts;
this.OriginalCsvLine = originalCsvLine;
}
public List<string> Parts { get; }
public string OriginalCsvLine { get; }
}

View File

@@ -0,0 +1,13 @@
// Import: Jan Conze / PBS2H23ACO mit Unterstützung durch Radu Catalin Calcan
namespace Projekt_Calcan_Conze_Import.DTOs;
internal class UserDto
{
public UserDto(List<UserAttributeDto> attributes)
{
this.Attributes = attributes;
}
public List<UserAttributeDto> Attributes { get; }
}

View File

@@ -0,0 +1,19 @@
// Import: Jan Conze / PBS2H23ACO mit Unterstützung durch Radu Catalin Calcan
namespace Projekt_Calcan_Conze_Import.DTOs;
internal class UserIdentifierDto
{
public UserIdentifierDto(string title, string firstName, string lastName)
{
this.Title = title;
this.FirstName = firstName;
this.LastName = lastName;
}
public string Title { get; }
public string FirstName { get; }
public string LastName { get; }
}

View File

@@ -0,0 +1,215 @@
// Import: Jan Conze / PBS2H23ACO mit Unterstützung durch Radu Catalin Calcan
using Core;
using Projekt_Calcan_Conze_Import.DTOs;
using Projekt_Calcan_Conze_Import.Models;
using System.Net.Mail;
namespace Projekt_Calcan_Conze_Import;
internal static class ImportUsers
{
public static (List<User> User, List<string> Protocol) FromCsv(string filePath)
{
var (userDtos, protocol) = ReadUserDtos(filePath);
var users = ParseUsers(userDtos, protocol);
return (users, protocol);
}
private static (List<UserDto> UserDtos, List<string> Protocol) ReadUserDtos(string filePath)
{
List<string> protocol = [];
List<UserDto> userDtos = [];
List<string> lines;
try
{
lines =
File.ReadAllLines(filePath)
.Where(line => !string.IsNullOrWhiteSpace(line)) // remove empty lines
.ToList();
}
catch (Exception)
{
Console.WriteLine("The file does not exist or is currently used by another program.");
return (userDtos, protocol);
}
UserDto? currentUser = null;
foreach (string line in lines)
{
var lineParts =
line.Split(Constants.Separator)
.Select(linePart => linePart.Trim())
.Where(linePart => !string.IsNullOrWhiteSpace(linePart)) // remove empty parts
.ToList(); // remove whitespace
string title = lineParts[0];
if (title
is Constants.FemaleAttributeIdentifier
or Constants.MaleAttributeIdentifier
or Constants.DiverseAttributeIdentifier)
{
if (currentUser is not null)
{
userDtos.Add(currentUser);
}
currentUser = new UserDto([new UserAttributeDto(lineParts, line)]);
}
else if (currentUser is not null)
{
currentUser.Attributes.Add(new UserAttributeDto(lineParts, line));
}
else
{
protocol.Add(line);
}
}
if (currentUser is not null)
{
userDtos.Add(currentUser);
}
return (userDtos, protocol);
}
private static List<User> ParseUsers(List<UserDto> userDtos, List<string> protocol)
{
List<User> users = [];
foreach (var userDto in userDtos)
{
var user = ParseUser(userDto);
if (user is not null)
{
users.Add(user);
}
else
{
protocol.AddRange(userDto.Attributes.Select(attribute => attribute.OriginalCsvLine));
}
}
return users;
}
private static User? ParseUser(UserDto user)
{
var firstAttribute = user.Attributes[0];
if (firstAttribute.Parts.Count != 4)
{
return null;
}
string title = firstAttribute.Parts[0];
string fistName = firstAttribute.Parts[1];
string lastName = firstAttribute.Parts[2];
DateOnly? dateOfBirth =
DateOnly.TryParseExact(firstAttribute.Parts[3], Constants.DateOfBirthFormat,
out var date)
? date
: null;
if (dateOfBirth is null)
{
return null;
}
string? email = null;
Address? address = null;
List<PhoneNumber> phoneNumbers = [];
foreach (var attribute in user.Attributes.Skip(1))
{
var attributeParts = attribute.Parts;
string identifier = attributeParts[0];
switch (identifier)
{
case Constants.AddressAttributeIdentifier:
if (attributeParts.Count == 4)
{
string postalCode = attributeParts[2];
if (postalCode.Length == 5)
{
address =
new Address(
streetAndHouseNumber: attributeParts[1],
postalCode: postalCode,
city: attributeParts[3]);
}
else
{
return null;
}
}
break;
case Constants.EmailAttributeIdentifier:
if (attributeParts.Count == 2)
{
try
{
email = attributeParts[1];
_ = new MailAddress(
email); // validate the format of the email address
}
catch (Exception)
{
return null;
}
}
else
{
return null;
}
break;
case Constants.PhoneNumberAttributeIdentifier:
if (attributeParts.Count == 3)
{
string areaCode = attributeParts[1];
string number = attributeParts[2];
if (areaCode.Length is >= 3 and <= 5
&& number.Length is >= 4 and <= 10)
{
phoneNumbers.Add(new PhoneNumber(areaCode, number));
}
else
{
return null;
}
}
else
{
return null;
}
break;
default: return null;
}
}
return new User(
title: title,
firstName: fistName,
lastName: lastName,
dateOfBirth: dateOfBirth.Value,
email: email,
address: address,
phoneNumbers: phoneNumbers);
}
}

View File

@@ -0,0 +1,19 @@
// Import: Jan Conze / PBS2H23ACO mit Unterstützung durch Radu Catalin Calcan
namespace Projekt_Calcan_Conze_Import.Models;
internal class Address
{
public Address(string streetAndHouseNumber, string postalCode, string city)
{
this.StreetAndHouseNumber = streetAndHouseNumber;
this.PostalCode = postalCode;
this.City = city;
}
public string StreetAndHouseNumber { get; }
public string PostalCode { get; }
public string City { get; }
}

View File

@@ -0,0 +1,16 @@
// Import: Jan Conze / PBS2H23ACO mit Unterstützung durch Radu Catalin Calcan
namespace Projekt_Calcan_Conze_Import.Models;
internal class PhoneNumber
{
public PhoneNumber(string areaCode, string number)
{
this.AreaCode = areaCode;
this.Number = number;
}
public string AreaCode { get; }
public string Number { get; }
}

View File

@@ -0,0 +1,116 @@
// Import: Jan Conze / PBS2H23ACO mit Unterstützung durch Radu Catalin Calcan
using Core;
using System.Text;
namespace Projekt_Calcan_Conze_Import.Models;
internal class User
{
public User(
string title,
string firstName,
string lastName,
DateOnly dateOfBirth,
string? email,
Address? address,
List<PhoneNumber> phoneNumbers)
{
this.Title = title;
this.FirstName = firstName;
this.LastName = lastName;
this.DateOfBirth = dateOfBirth;
this.Email = email;
this.Address = address;
this.PhoneNumbers = phoneNumbers;
}
public string Title { get; }
public string FirstName { get; }
public string LastName { get; }
public DateOnly DateOfBirth { get; }
public string? Email { get; }
public Address? Address { get; }
public List<PhoneNumber> PhoneNumbers { get; }
public override string ToString()
{
StringBuilder builder = new();
builder.Append($"{this.Title} {this.FirstName} {this.LastName}");
builder.Append($"{Constants.Separator} {this.DateOfBirth.ToString(Constants.DateOfBirthFormat)}");
if (this.Email is not null)
{
builder.Append($"{Constants.Separator} {this.Email}");
}
if (this.Address is not null)
{
builder.Append($"{Constants.Separator} {this.Address.StreetAndHouseNumber}");
builder.Append($"{Constants.Separator} {this.Address.PostalCode} {this.Address.City}");
}
foreach (PhoneNumber phoneNumber in this.PhoneNumbers)
{
builder.Append($"{Constants.Separator} {phoneNumber.AreaCode} {phoneNumber.Number}");
}
return builder.ToString();
}
public IEnumerable<string> ToCsv()
{
List<string> csvLines =
[
this.Title
+ Constants.Separator
+ this.FirstName
+ Constants.Separator
+ this.LastName
+ Constants.Separator
+ this.DateOfBirth.ToString("dd.MM.yyyy")
];
if (this.Address is not null)
{
csvLines.Add(
Constants.AddressAttributeIdentifier
+ Constants.Separator
+ this.Address.StreetAndHouseNumber
+ Constants.Separator
+ this.Address.PostalCode
+ Constants.Separator
+ this.Address.City);
}
if (this.Email is not null)
{
csvLines.Add(
Constants.EmailAttributeIdentifier
+ Constants.Separator
+ this.Email
+ Constants.Separator
+ Constants.Separator);
}
csvLines.AddRange(
this.PhoneNumbers
.Select(
phoneNumber =>
Constants.PhoneNumberAttributeIdentifier
+ Constants.Separator
+ phoneNumber.AreaCode
+ Constants.Separator
+ phoneNumber.Number
+ Constants.Separator));
return csvLines;
}
}

View File

@@ -1,2 +1,78 @@
// See https://aka.ms/new-console-template for more information // Import: Jan Conze / PBS2H23ACO mit Unterstützung durch Radu Catalin Calcan
Console.WriteLine("Hello, World!");
using Projekt_Calcan_Conze_Import;
using Projekt_Calcan_Conze_Import.Repositories;
try
{
string? filePath = null;
while (string.IsNullOrEmpty(filePath))
{
Console.WriteLine("Bitte gib einen Dateipfad an:");
filePath = Console.ReadLine();
if (filePath?.StartsWith('\"') ?? false)
{
filePath = filePath.Substring(startIndex: 1, length: filePath.Length - 1);
}
if (filePath?.EndsWith('\"') ?? false)
{
filePath = filePath.Substring(startIndex: 0, length: filePath.Length - 1);
}
if (!File.Exists(filePath))
{
Console.WriteLine("Die Datei existiert nicht.");
filePath = null;
}
}
string? clientNumber = null;
while (string.IsNullOrEmpty(clientNumber))
{
Console.WriteLine("Bitte gib eine Kundennummer an:");
clientNumber = Console.ReadLine();
}
var (users, protocol) = ImportUsers.FromCsv(filePath);
var existingUsers = await Database.GetUserIdentifiers(clientNumber);
var duplicateUsers =
users.Where(
user =>
existingUsers.Any(
existingUser =>
existingUser.FirstName == user.FirstName
&& existingUser.LastName == user.LastName
&& existingUser.Title == user.Title))
.ToList();
foreach (var duplicateUser in duplicateUsers)
{
protocol.AddRange(duplicateUser.ToCsv());
}
var usersToCreate = users.Except(duplicateUsers).ToList();
await Database.CreateUsers(usersToCreate, clientNumber);
if (protocol.Any())
{
string protocolFilePath =
Path.Combine(
Path.GetDirectoryName(filePath),
Path.GetFileNameWithoutExtension(filePath) + "_protocol.csv");
await File.WriteAllLinesAsync(protocolFilePath, protocol);
Console.WriteLine($"Protokoll wurde unter \"{protocolFilePath}\" gespeichert.");
}
else
{
Console.WriteLine("Alle Nutzer wurden erfolgreich importiert.");
}
}
catch (Exception ex)
{
Console.WriteLine($"Ein Fehler ist aufgetreten: {ex.Message}");
}

View File

@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MySql.Data" Version="8.4.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Core\Core.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,296 @@
// Import: Jan Conze / PBS2H23ACO mit Unterstützung durch Radu Catalin Calcan
using Core;
using System.Data;
namespace Projekt_Calcan_Conze_Import.Repositories;
using MySql.Data.MySqlClient;
using Projekt_Calcan_Conze_Import.DTOs;
using Projekt_Calcan_Conze_Import.Models;
internal static class Database
{
public static async Task<List<UserIdentifierDto>> GetUserIdentifiers(string clientNumber)
{
var users = new List<UserIdentifierDto>();
try
{
// use "using" to automatically close the connection when done
await using var dbConnection = new MySqlConnection(Constants.ConnectionString);
// open a connection
await dbConnection.OpenAsync();
var usersCommand =
new MySqlCommand
{
Connection = dbConnection,
CommandText =
$"""
SELECT *
FROM user
INNER JOIN client ON user.clientId = client.id
INNER JOIN gender ON user.genderId = gender.id
WHERE client.clientno = @{nameof(clientNumber)}
"""
};
usersCommand.Parameters.AddWithValue($"@{nameof(clientNumber)}", clientNumber);
// execute the command and read the results
await using var sqlReader = await usersCommand.ExecuteReaderAsync();
while (await sqlReader.ReadAsync())
{
string title = sqlReader.GetString("description");
string firstName = sqlReader.GetString("firstname");
string lastName = sqlReader.GetString("lastname");
users.Add(
new UserIdentifierDto(
title: title,
firstName: firstName,
lastName: lastName));
}
}
catch (Exception ex)
{
Console.WriteLine("An error occurred while reading the database: " + ex.Message);
}
return users;
}
public static async Task CreateUsers(List<User> usersToCreate, string clientNumber)
{
try
{
await using var dbConnection = new MySqlConnection(Constants.ConnectionString);
await dbConnection.OpenAsync();
var transaction = await dbConnection.BeginTransactionAsync();
try
{
var getClientIdCommand =
new MySqlCommand
{
Connection = dbConnection,
Transaction = transaction,
CommandText = "SELECT id FROM client WHERE clientno = @clientno"
};
getClientIdCommand.Parameters.AddWithValue("@clientno", clientNumber);
object? clientIdResult = await getClientIdCommand.ExecuteScalarAsync();
long clientId;
if (clientIdResult is int cId)
{
clientId = cId;
}
else
{
throw new Exception("Client not found");
}
foreach (var user in usersToCreate)
{
var getGenderCommand =
new MySqlCommand
{
Connection = dbConnection,
Transaction = transaction,
CommandText = "SELECT id FROM gender WHERE gender.description = @title "
};
getGenderCommand.Parameters.AddWithValue("@title", user.Title);
await using var genderReader = await getGenderCommand.ExecuteReaderAsync();
long genderId;
if (await genderReader.ReadAsync())
{
genderId = genderReader.GetByte("id");
await genderReader.CloseAsync();
}
else
{
await genderReader.CloseAsync();
genderId =
await GetNextIdForTable(
table: "gender",
idColumn: "id",
idType: typeof(byte),
dbConnection,
transaction);
var insertGenderCommand =
new MySqlCommand
{
Connection = dbConnection,
Transaction = transaction,
CommandText =
"""
INSERT INTO gender (id, description)
VALUES (@id, @title)
"""
};
insertGenderCommand.Parameters.AddWithValue("@id", genderId);
insertGenderCommand.Parameters.AddWithValue("@title", user.Title);
insertGenderCommand.ExecuteNonQuery();
}
long userId =
await GetNextIdForTable(
table: "user",
idColumn: "id",
idType: typeof(int),
dbConnection,
transaction);
var userCommand =
new MySqlCommand
{
Connection = dbConnection,
Transaction = transaction,
CommandText =
"""
INSERT INTO user (id, clientId, genderId, firstname, lastname, birthdate)
VALUES (@id, @clientId, @genderId, @firstname, @lastname, @dateofbirth)
"""
};
userCommand.Parameters.AddWithValue("@id", userId);
userCommand.Parameters.AddWithValue("@clientId", clientId);
userCommand.Parameters.AddWithValue("@genderId", genderId);
userCommand.Parameters.AddWithValue("@firstname", user.FirstName);
userCommand.Parameters.AddWithValue("@lastname", user.LastName);
userCommand.Parameters.AddWithValue("@dateofbirth", user.DateOfBirth.ToString("yyyy-MM-dd"));
await userCommand.ExecuteNonQueryAsync();
if (user.Email is not null)
{
long emailId =
await GetNextIdForTable(
table: "email",
idColumn: "id",
idType: typeof(int),
dbConnection,
transaction);
var emailCommand =
new MySqlCommand
{
Connection = dbConnection,
Transaction = transaction,
CommandText =
"""
INSERT INTO email (id, userId, email)
VALUES (@id, @userId, @email)
"""
};
emailCommand.Parameters.AddWithValue("@id", emailId);
emailCommand.Parameters.AddWithValue("@userId", userId);
emailCommand.Parameters.AddWithValue("@email", user.Email);
await emailCommand.ExecuteNonQueryAsync();
}
if (user.Address is not null)
{
long addressId =
await GetNextIdForTable(
table: "address",
idColumn: "id",
idType: typeof(int),
dbConnection,
transaction);
var addressCommand =
new MySqlCommand
{
Connection = dbConnection,
Transaction = transaction,
CommandText =
"""
INSERT INTO address (id, userId, street, postalcode, city)
VALUES (@id, @userId, @street, @postalcode, @city)
"""
};
addressCommand.Parameters.AddWithValue("@id", addressId);
addressCommand.Parameters.AddWithValue("@userId", userId);
addressCommand.Parameters.AddWithValue("@street", user.Address.StreetAndHouseNumber);
addressCommand.Parameters.AddWithValue("@postalcode", user.Address.PostalCode);
addressCommand.Parameters.AddWithValue("@city", user.Address.City);
await addressCommand.ExecuteNonQueryAsync();
}
foreach (var phoneNumber in user.PhoneNumbers)
{
long phoneId =
await GetNextIdForTable(
table: "phone",
idColumn: "id",
idType: typeof(int),
dbConnection,
transaction);
var phoneNumberCommand =
new MySqlCommand
{
Connection = dbConnection,
Transaction = transaction,
CommandText =
"""
INSERT INTO phone (id, userId, phoneprefix, phonenumber)
VALUES (@id, @userId, @areacode, @number)
"""
};
phoneNumberCommand.Parameters.AddWithValue("@id", phoneId);
phoneNumberCommand.Parameters.AddWithValue("@userId", userId);
phoneNumberCommand.Parameters.AddWithValue("@areacode", phoneNumber.AreaCode);
phoneNumberCommand.Parameters.AddWithValue("@number", phoneNumber.Number);
await phoneNumberCommand.ExecuteNonQueryAsync();
}
}
}
catch (Exception)
{
await transaction.RollbackAsync();
throw;
}
await transaction.CommitAsync();
}
catch (Exception ex)
{
Console.WriteLine("An error occurred while writing to the database: " + ex.Message);
}
}
private static async Task<long> GetNextIdForTable(
string table,
string idColumn,
Type idType,
MySqlConnection connection,
MySqlTransaction transaction)
{
var getMaxIdCommand =
new MySqlCommand
{
Connection = connection,
Transaction = transaction,
CommandText = $"SELECT MAX({idColumn}) FROM {table}"
};
await using var maxIdReader = await getMaxIdCommand.ExecuteReaderAsync();
return await maxIdReader.ReadAsync()
? idType switch
{
{ } t when t == typeof(byte) => maxIdReader.GetByte(0) + 1,
{ } t when t == typeof(short) => maxIdReader.GetInt16(0) + 1,
{ } t when t == typeof(int) => maxIdReader.GetInt32(0) + 1,
{ } t when t == typeof(long) => maxIdReader.GetInt64(0) + 1,
_ => throw new ArgumentException("Unsupported id type")
}
: 1;
}
}

View File

@@ -14,7 +14,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("Projekt_Calcan_Conze")] [assembly: System.Reflection.AssemblyCompanyAttribute("Projekt_Calcan_Conze")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+aeb270769978c1cbdf2f285654502b991156aa86")]
[assembly: System.Reflection.AssemblyProductAttribute("Projekt_Calcan_Conze")] [assembly: System.Reflection.AssemblyProductAttribute("Projekt_Calcan_Conze")]
[assembly: System.Reflection.AssemblyTitleAttribute("Projekt_Calcan_Conze")] [assembly: System.Reflection.AssemblyTitleAttribute("Projekt_Calcan_Conze")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@@ -1 +1 @@
e1c6e387605f1c707ceb8546e762bcd639e196f219432ea9dd58bf0b1473eacb 12accfb452c230216e3ac941872f0c73361c12ee69c2b99c250749ff72d74495

View File

@@ -21,7 +21,8 @@
"net8.0" "net8.0"
], ],
"sources": { "sources": {
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {} "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
"https://api.nuget.org/v3/index.json": {}
}, },
"frameworks": { "frameworks": {
"net8.0": { "net8.0": {
@@ -43,6 +44,12 @@
"frameworks": { "frameworks": {
"net8.0": { "net8.0": {
"targetAlias": "net8.0", "targetAlias": "net8.0",
"dependencies": {
"MySql.Data": {
"target": "Package",
"version": "[8.4.0, )"
}
},
"imports": [ "imports": [
"net461", "net461",
"net462", "net462",
@@ -59,7 +66,7 @@
"privateAssets": "all" "privateAssets": "all"
} }
}, },
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\8.0.300/PortableRuntimeIdentifierGraph.json" "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\8.0.400/PortableRuntimeIdentifierGraph.json"
} }
} }
} }

View File

@@ -7,7 +7,7 @@
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot> <NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\bib\.nuget\packages\</NuGetPackageFolders> <NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\bib\.nuget\packages\</NuGetPackageFolders>
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle> <NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.10.0</NuGetToolVersion> <NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.11.0</NuGetToolVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' "> <ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<SourceRoot Include="C:\Users\bib\.nuget\packages\" /> <SourceRoot Include="C:\Users\bib\.nuget\packages\" />

View File

@@ -1,2 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?> <?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" /> <Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<Import Project="$(NuGetPackageRoot)system.text.json\7.0.1\buildTransitive\net6.0\System.Text.Json.targets" Condition="Exists('$(NuGetPackageRoot)system.text.json\7.0.1\buildTransitive\net6.0\System.Text.Json.targets')" />
</ImportGroup>
</Project>

View File

@@ -1,8 +1,41 @@
{ {
"version": 2, "version": 2,
"dgSpecHash": "ee2VgL4Z9vU=", "dgSpecHash": "4Akg//gURuM=",
"success": true, "success": true,
"projectFilePath": "C:\\Jan_bib_Module\\PMC\\Projekt\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze.csproj", "projectFilePath": "C:\\Jan_bib_Module\\PMC\\Projekt\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze_Import.csproj",
"expectedPackageFiles": [], "expectedPackageFiles": [
"C:\\Users\\bib\\.nuget\\packages\\bouncycastle.cryptography\\2.2.1\\bouncycastle.cryptography.2.2.1.nupkg.sha512",
"C:\\Users\\bib\\.nuget\\packages\\google.protobuf\\3.25.1\\google.protobuf.3.25.1.nupkg.sha512",
"C:\\Users\\bib\\.nuget\\packages\\k4os.compression.lz4\\1.3.5\\k4os.compression.lz4.1.3.5.nupkg.sha512",
"C:\\Users\\bib\\.nuget\\packages\\k4os.compression.lz4.streams\\1.3.5\\k4os.compression.lz4.streams.1.3.5.nupkg.sha512",
"C:\\Users\\bib\\.nuget\\packages\\k4os.hash.xxhash\\1.0.8\\k4os.hash.xxhash.1.0.8.nupkg.sha512",
"C:\\Users\\bib\\.nuget\\packages\\microsoft.netcore.platforms\\3.1.0\\microsoft.netcore.platforms.3.1.0.nupkg.sha512",
"C:\\Users\\bib\\.nuget\\packages\\microsoft.netcore.targets\\1.1.0\\microsoft.netcore.targets.1.1.0.nupkg.sha512",
"C:\\Users\\bib\\.nuget\\packages\\microsoft.win32.systemevents\\4.7.0\\microsoft.win32.systemevents.4.7.0.nupkg.sha512",
"C:\\Users\\bib\\.nuget\\packages\\mysql.data\\8.4.0\\mysql.data.8.4.0.nupkg.sha512",
"C:\\Users\\bib\\.nuget\\packages\\system.buffers\\4.5.1\\system.buffers.4.5.1.nupkg.sha512",
"C:\\Users\\bib\\.nuget\\packages\\system.configuration.configurationmanager\\4.4.1\\system.configuration.configurationmanager.4.4.1.nupkg.sha512",
"C:\\Users\\bib\\.nuget\\packages\\system.diagnostics.diagnosticsource\\7.0.2\\system.diagnostics.diagnosticsource.7.0.2.nupkg.sha512",
"C:\\Users\\bib\\.nuget\\packages\\system.drawing.common\\4.7.0\\system.drawing.common.4.7.0.nupkg.sha512",
"C:\\Users\\bib\\.nuget\\packages\\system.io\\4.3.0\\system.io.4.3.0.nupkg.sha512",
"C:\\Users\\bib\\.nuget\\packages\\system.io.pipelines\\6.0.3\\system.io.pipelines.6.0.3.nupkg.sha512",
"C:\\Users\\bib\\.nuget\\packages\\system.reflection\\4.3.0\\system.reflection.4.3.0.nupkg.sha512",
"C:\\Users\\bib\\.nuget\\packages\\system.reflection.primitives\\4.3.0\\system.reflection.primitives.4.3.0.nupkg.sha512",
"C:\\Users\\bib\\.nuget\\packages\\system.runtime\\4.3.0\\system.runtime.4.3.0.nupkg.sha512",
"C:\\Users\\bib\\.nuget\\packages\\system.runtime.compilerservices.unsafe\\6.0.0\\system.runtime.compilerservices.unsafe.6.0.0.nupkg.sha512",
"C:\\Users\\bib\\.nuget\\packages\\system.runtime.loader\\4.3.0\\system.runtime.loader.4.3.0.nupkg.sha512",
"C:\\Users\\bib\\.nuget\\packages\\system.security.accesscontrol\\4.7.0\\system.security.accesscontrol.4.7.0.nupkg.sha512",
"C:\\Users\\bib\\.nuget\\packages\\system.security.cryptography.protecteddata\\4.4.0\\system.security.cryptography.protecteddata.4.4.0.nupkg.sha512",
"C:\\Users\\bib\\.nuget\\packages\\system.security.permissions\\4.7.0\\system.security.permissions.4.7.0.nupkg.sha512",
"C:\\Users\\bib\\.nuget\\packages\\system.security.principal.windows\\4.7.0\\system.security.principal.windows.4.7.0.nupkg.sha512",
"C:\\Users\\bib\\.nuget\\packages\\system.text.encoding\\4.3.0\\system.text.encoding.4.3.0.nupkg.sha512",
"C:\\Users\\bib\\.nuget\\packages\\system.text.encoding.codepages\\4.4.0\\system.text.encoding.codepages.4.4.0.nupkg.sha512",
"C:\\Users\\bib\\.nuget\\packages\\system.text.encodings.web\\7.0.0\\system.text.encodings.web.7.0.0.nupkg.sha512",
"C:\\Users\\bib\\.nuget\\packages\\system.text.json\\7.0.1\\system.text.json.7.0.1.nupkg.sha512",
"C:\\Users\\bib\\.nuget\\packages\\system.threading.tasks\\4.3.0\\system.threading.tasks.4.3.0.nupkg.sha512",
"C:\\Users\\bib\\.nuget\\packages\\system.threading.tasks.extensions\\4.5.4\\system.threading.tasks.extensions.4.5.4.nupkg.sha512",
"C:\\Users\\bib\\.nuget\\packages\\system.windows.extensions\\4.7.0\\system.windows.extensions.4.7.0.nupkg.sha512",
"C:\\Users\\bib\\.nuget\\packages\\zstdsharp.port\\0.7.1\\zstdsharp.port.0.7.1.nupkg.sha512"
],
"logs": [] "logs": []
} }

View File

@@ -0,0 +1,100 @@
// Export: Radu Catalin Calcan / PBS2H23Aca mit Unterstützung durch Jan Conze
using Core;
namespace Projekt_Calcan_Conze_Export.Models;
internal class Billing
{
public Billing(
DateOnly startDate,
DateOnly endDate,
string customerNumber,
string customerName,
List<BillingPosition> positions)
{
this.StartDate = startDate;
this.EndDate = endDate;
this.CustomerNumber = customerNumber;
this.CustomerName = customerName;
this.Positions = positions;
}
public DateOnly StartDate { get; }
public DateOnly EndDate { get; }
public string CustomerNumber { get; }
public string CustomerName { get; }
public double TotalAmount => this.Positions.Sum(p => p.TotalAmount);
public List<BillingPosition> Positions { get; }
public IEnumerable<string> ToCsvLines()
{
List<string> lines =
[
"Rechnungszeitraum (von)"
+ Constants.Separator
+ "Rechnungszeitraum (bis)"
+ Constants.Separator
+ "Kundennummer"
+ Constants.Separator
+ "Kundenname"
+ Constants.Separator
+ "Gesamtbetrag",
this.StartDate.ToString(Constants.DateFormat)
+ Constants.Separator
+ this.EndDate.ToString(Constants.DateFormat)
+ Constants.Separator
+ this.CustomerNumber
+ Constants.Separator
+ this.CustomerName
+ Constants.Separator
+ this.TotalAmount.ToString(Constants.MoneyFormat),
"Bereich"
+ Constants.Separator
+ "Grundbetrag"
+ Constants.Separator
+ "Anzahl"
+ Constants.Separator
+ "Betrag"
+ Constants.Separator
];
lines.AddRange(
this.Positions
.Select(
position =>
position.Description
+ Constants.Separator
+ position.BaseAmount.ToString(Constants.MoneyFormat)
+ Constants.Separator
+ position.Count
+ Constants.Separator
+ position.TotalAmount.ToString(Constants.MoneyFormat)
+ Constants.Separator));
return lines;
}
}
internal class BillingPosition
{
public BillingPosition(string description, double baseAmount, int count)
{
this.Description = description;
this.BaseAmount = baseAmount;
this.Count = count;
}
public string Description { get; }
public double BaseAmount { get; }
public int Count { get; set; }
public double TotalAmount => this.BaseAmount * this.Count;
}

View File

@@ -0,0 +1,106 @@
// Export: Radu Catalin Calcan / PBS2H23Aca mit Unterstützung durch Jan Conze
using Core;
using Projekt_Calcan_Conze_Export.Repositories;
using System.Globalization;
try
{
string? clientNumber = null;
while (string.IsNullOrEmpty(clientNumber))
{
Console.WriteLine("Bitte gib eine Kundennummer an:");
clientNumber = Console.ReadLine();
}
Console.WriteLine();
DateOnly? startDate = null;
while (startDate is null)
{
Console.WriteLine($"Bitte gib das Startdatum im folgenden Format an ({Constants.DateFormat}):");
startDate =
DateOnly.TryParseExact(
Console.ReadLine() ?? string.Empty,
Constants.DateFormat,
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out var start)
? start
: null;
}
Console.WriteLine();
DateOnly? endDate = null;
while (endDate is null)
{
Console.WriteLine($"Bitte gib das Enddatum im folgenden Format an ({Constants.DateFormat}):");
endDate =
DateOnly.TryParseExact(
Console.ReadLine() ?? string.Empty,
Constants.DateFormat,
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out var end)
? end
: null;
if (endDate is not null
&& endDate < startDate)
{
Console.WriteLine("Das Enddatum darf nicht vor dem Startdatum liegen.");
endDate = null;
}
}
Console.WriteLine();
string? directoryPath = null;
while (string.IsNullOrEmpty(directoryPath))
{
Console.WriteLine("Bitte gib einen Dateipfad für die Ausgabe an:");
directoryPath = Console.ReadLine();
if (directoryPath?.StartsWith('\"') ?? false)
{
directoryPath = directoryPath.Substring(startIndex: 1, length: directoryPath.Length - 1);
}
if (directoryPath?.EndsWith('\"') ?? false)
{
directoryPath = directoryPath.Substring(startIndex: 0, length: directoryPath.Length - 1);
}
if (!Path.Exists(directoryPath))
{
Console.WriteLine("Der angegebene Dateipfad existiert nicht.");
directoryPath = null;
}
}
Console.WriteLine();
var billing = await Database.CreateBilling(startDate.Value, endDate.Value, clientNumber);
if (billing is null)
{
Console.WriteLine("Es konnte keine Rechnung erstellt werden.");
}
else
{
string fileName =
$"{DateTime.Today.ToString(Constants.DateFormat)}_{clientNumber}_{startDate.Value.ToString(Constants.DateFormat)}_{endDate.Value.ToString(Constants.DateFormat)}.csv";
string filePath = Path.Combine(directoryPath, fileName);
File.WriteAllLines(filePath, billing.ToCsvLines());
Console.WriteLine($"Die Rechnung wurde unter \"{filePath}\" abgelegt.");
}
}
catch (Exception ex)
{
Console.WriteLine($"Ein Fehler ist aufgetreten: {ex.Message}");
}

View File

@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Core\Core.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="MySql.Data" Version="9.0.0" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,163 @@
// Export: Radu Catalin Calcan / PBS2H23Aca mit Unterstützung durch Jan Conze
using Core;
using MySql.Data.MySqlClient;
using Projekt_Calcan_Conze_Export.Models;
using System.Data;
namespace Projekt_Calcan_Conze_Export.Repositories;
internal static class Database
{
public static async Task<Billing?> CreateBilling(DateOnly startDate, DateOnly endDate, string customerNumber)
{
Billing? billing = null;
try
{
await using var dbConnection = new MySqlConnection(Constants.ConnectionString);
await dbConnection.OpenAsync();
var transaction = await dbConnection.BeginTransactionAsync();
try
{
// ensure wasBilled column exists and activityDateTime does not refresh on update
var createWasBilledColumnCommand =
new MySqlCommand
{
Connection = dbConnection,
Transaction = transaction,
CommandText =
"""
ALTER TABLE activity ADD IF NOT EXISTS wasBilled BIT NOT NULL DEFAULT 0;
ALTER TABLE activity CHANGE COLUMN activityDatetime activityDatetime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
ALTER TABLE activity ALTER COLUMN activityDatetime DROP DEFAULT;
"""
};
await createWasBilledColumnCommand.ExecuteNonQueryAsync();
// tables: activityType, activity, contract, user, client
// one activityType can be assigned to multiple contracts, one contract has one activityType
// one contract can have multiple activities, one activity belongs to one contract
// one activity has one user, one user can have multiple activities
// one user belongs to one client, one client can have multiple users
// one contract belongs to one client, one client can have multiple contracts
// get all contracts of the client by the client number and the start and end date
// include all activities of the contracts
// include the client name (column of client table)
// only get activities that were not billed yet (wasBilled = 0)
var getActivities =
new MySqlCommand
{
Connection = dbConnection,
Transaction = transaction,
CommandText =
"""
SELECT
activity.id,
activity.contractId,
contract.amount,
contract.description
FROM activity
JOIN contract ON activity.contractId = contract.id
JOIN activityType ON contract.activityTypeId = activityType.id
JOIN user ON activity.userId = user.id
JOIN client ON contract.clientId = client.id
WHERE client.clientno = @clientNumber
AND activity.activityDateTime >= @startDate
AND activity.activityDateTime <= @endDate
AND activity.wasBilled = 0
"""
};
getActivities.Parameters.AddWithValue("@clientNumber", customerNumber);
getActivities.Parameters.AddWithValue("@startDate", startDate.ToString("yyyy-MM-dd"));
getActivities.Parameters.AddWithValue("@endDate", endDate.ToString("yyyy-MM-dd"));
await using var activityReader = await getActivities.ExecuteReaderAsync();
Dictionary<int, BillingPosition> positions = [];
List<int> activityIds = [];
while (await activityReader.ReadAsync())
{
activityIds.Add(activityReader.GetInt32("id"));
int contractId = activityReader.GetInt32("contractId");
if (positions.TryGetValue(contractId, out var positionDto))
{
positionDto.Count++;
}
else
{
positions[contractId] =
new BillingPosition(
description: activityReader.GetString("description"),
baseAmount: activityReader.GetDouble("amount"),
count: 1);
}
}
await activityReader.CloseAsync();
// get the customer name separately in case we have no activities
var getCustomerNameCommand =
new MySqlCommand
{
Connection = dbConnection,
Transaction = transaction,
CommandText =
"""
SELECT name
FROM client
WHERE clientno = @clientNumber
"""
};
getCustomerNameCommand.Parameters.AddWithValue("@clientNumber", customerNumber);
string customerName = await getCustomerNameCommand.ExecuteScalarAsync() as string ?? string.Empty;
billing =
new Billing(
startDate: startDate,
endDate: endDate,
customerNumber: customerNumber,
customerName: customerName,
positions: positions.Values.ToList());
// set wasBilled to 1 for all retrieved activities
if (activityIds.Any())
{
string activityIdsString = string.Join(',', activityIds.Select((_, i) => $"@activityId{i}"));
var updateWasBilledCommand =
new MySqlCommand
{
Connection = dbConnection,
Transaction = transaction,
CommandText = $"UPDATE activity SET wasBilled = 1 WHERE id IN ({activityIdsString})"
};
for (int i = 0; i < activityIds.Count; i++)
{
updateWasBilledCommand.Parameters.AddWithValue($"@activityId{i}", activityIds[i]);
}
await updateWasBilledCommand.ExecuteNonQueryAsync();
}
}
catch (Exception)
{
await transaction.RollbackAsync();
throw;
}
await transaction.CommitAsync();
}
catch (Exception ex)
{
Console.WriteLine("An error occurred while writing to or reading from the database: " + ex.Message);
}
return billing;
}
}

View File

@@ -0,0 +1,73 @@
Frau;Sabrina;Schröder;11.02.1992
Adresse;Brückenstraße 9;93047;Regensburg
E-Mail;sabrina.schroder@example.com;;
Telefon;941;77990011;
Telefon;179;77889900;
Herr;Alexander;Neumann;27.03.1983
Adresse;Am Rathaus 4;94032;Passau
E-Mail;alexander.neumann@example.com;;
Telefon;170;88990011;
Telefon;851;11224433;
Frau;Nina;Schwarz;09.10.1989
Adresse;Hafenstraße 3;18055;Rostock
E-Mail;nina.schwarz@example.com;;
Telefon;172;99001122;
Telefon;381;66554433;
Herr;Markus;Zimmermann;30.12.1986
Adresse;Friedrichstraße 10;10178;Berlin
E-Mail;markus.zimmermann@example.com;;
Telefon;40;22335544;
Telefon;176;10111213;
Frau;Lisa;Krüger;15.06.1991
Adresse;Schloßallee 1;80333;München
E-Mail;lisa.kruger@example.com;;
Telefon;30;44667788;
Telefon;179;12131415;
Herr;Christian;Hartmann;23.01.1980
Adresse;Wilhelmstraße 5;50679;Köln
E-Mail;christian.hartmann@example.com;;
Telefon;30;13141516;
Frau;Melanie;Werner;19.09.1987
Adresse;Heinrich-Heine-Platz 7;20097;Hamburg
E-Mail;melanie.werner@example.com;;
Telefon;40;14151617;
Herr;Patrick;Krause;05.05.1984
Adresse;Neustadt 3;30159;Hannover
E-Mail;patrick.krause@example.com;;
Telefon;89;15161718;
Frau;Claudia;Meier;02.03.1990
Adresse;Alte Straße 22;1067;Dresden
E-Mail;claudia.meier@example.com;;
Telefon;221;16171819;
Herr;Tobias;Lehmann;26.11.1985
Adresse;Markt 11;4109;Leipzig
E-Mail;tobias.lehmann@example.com;;
Telefon;511;17181920;
Frau;Sandra;Maier;17.04.1988
Adresse;Rathausplatz 8;34117;Kassel
E-Mail;sandra.maier@example.com;;
Telefon;331;18192021;
Herr;Jan;Huber;08.08.1983
Adresse;Hauptplatz 15;65183;Wiesbaden
E-Mail;jan.huber@example.com;;
Telefon;361;19202122;
Frau;Susanne;Schulz;21.06.1992
Adresse;Am Markt 6;49074;Osnabrück
E-Mail;susanne.schulz@example.com;;
Telefon;551;20212223;
Herr;Benjamin;Lang;09.12.1986
Adresse;Hofgartenweg 1;86150;Augsburg
E-Mail;benjamin.lang@example.com;;
Telefon;381;21222324;
Frau;Kerstin;Böhm;02.07.1987
Adresse;Mühlweg 18;99084;Erfurt
E-Mail;kerstin.bohm@example.com;;
Telefon;561;22232425;
Herr;Florian;Kuhn;16.05.1982
Adresse;Burgstraße 2;37073;Göttingen
E-Mail;florian.kuhn@example.com;;
Frau;Anja;Peters;11.08.1991
Adresse;Schillerplatz 9;14467;Potsdam
E-Mail;anja.peters@example.com;;
Herr;Tim;Franke;22.10.1980
E-Mail;tim.franke@example.com;;
1 Frau Sabrina Schröder 11.02.1992
2 Adresse Brückenstraße 9 93047 Regensburg
3 E-Mail sabrina.schroder@example.com
4 Telefon 941 77990011
5 Telefon 179 77889900
6 Herr Alexander Neumann 27.03.1983
7 Adresse Am Rathaus 4 94032 Passau
8 E-Mail alexander.neumann@example.com
9 Telefon 170 88990011
10 Telefon 851 11224433
11 Frau Nina Schwarz 09.10.1989
12 Adresse Hafenstraße 3 18055 Rostock
13 E-Mail nina.schwarz@example.com
14 Telefon 172 99001122
15 Telefon 381 66554433
16 Herr Markus Zimmermann 30.12.1986
17 Adresse Friedrichstraße 10 10178 Berlin
18 E-Mail markus.zimmermann@example.com
19 Telefon 40 22335544
20 Telefon 176 10111213
21 Frau Lisa Krüger 15.06.1991
22 Adresse Schloßallee 1 80333 München
23 E-Mail lisa.kruger@example.com
24 Telefon 30 44667788
25 Telefon 179 12131415
26 Herr Christian Hartmann 23.01.1980
27 Adresse Wilhelmstraße 5 50679 Köln
28 E-Mail christian.hartmann@example.com
29 Telefon 30 13141516
30 Frau Melanie Werner 19.09.1987
31 Adresse Heinrich-Heine-Platz 7 20097 Hamburg
32 E-Mail melanie.werner@example.com
33 Telefon 40 14151617
34 Herr Patrick Krause 05.05.1984
35 Adresse Neustadt 3 30159 Hannover
36 E-Mail patrick.krause@example.com
37 Telefon 89 15161718
38 Frau Claudia Meier 02.03.1990
39 Adresse Alte Straße 22 1067 Dresden
40 E-Mail claudia.meier@example.com
41 Telefon 221 16171819
42 Herr Tobias Lehmann 26.11.1985
43 Adresse Markt 11 4109 Leipzig
44 E-Mail tobias.lehmann@example.com
45 Telefon 511 17181920
46 Frau Sandra Maier 17.04.1988
47 Adresse Rathausplatz 8 34117 Kassel
48 E-Mail sandra.maier@example.com
49 Telefon 331 18192021
50 Herr Jan Huber 08.08.1983
51 Adresse Hauptplatz 15 65183 Wiesbaden
52 E-Mail jan.huber@example.com
53 Telefon 361 19202122
54 Frau Susanne Schulz 21.06.1992
55 Adresse Am Markt 6 49074 Osnabrück
56 E-Mail susanne.schulz@example.com
57 Telefon 551 20212223
58 Herr Benjamin Lang 09.12.1986
59 Adresse Hofgartenweg 1 86150 Augsburg
60 E-Mail benjamin.lang@example.com
61 Telefon 381 21222324
62 Frau Kerstin Böhm 02.07.1987
63 Adresse Mühlweg 18 99084 Erfurt
64 E-Mail kerstin.bohm@example.com
65 Telefon 561 22232425
66 Herr Florian Kuhn 16.05.1982
67 Adresse Burgstraße 2 37073 Göttingen
68 E-Mail florian.kuhn@example.com
69 Frau Anja Peters 11.08.1991
70 Adresse Schillerplatz 9 14467 Potsdam
71 E-Mail anja.peters@example.com
72 Herr Tim Franke 22.10.1980
73 E-Mail tim.franke@example.com

View File

@@ -0,0 +1,30 @@
Herr;Markus;Zimmermann;30.12.1986
Adresse;Friedrichstraße 10;10178;Berlin
E-Mail;markus.zimmermann@example.com;;
Telefon;40;22335544;
Telefon;176;10111213;
Frau;Lisa;Krüger;15.06.1991
Adresse;Schloßallee 1;80333;München
E-Mail;lisa.kruger@example.com;;
Telefon;30;44667788;
Telefon;179;12131415;
Herr;Christian;Hartmann;23.01.1980
Adresse;Wilhelmstraße 5;50679;Köln
E-Mail;christian.hartmann@example.com;;
Telefon;30;13141516;
Frau;Melanie;Werner;19.09.1987
Adresse;Heinrich-Heine-Platz 7;20097;Hamburg
E-Mail;melanie.werner@example.com;;
Telefon;40;14151617;
Herr;Patrick;Krause;05.05.1984
Adresse;Neustadt 3;30159;Hannover
E-Mail;patrick.krause@example.com;;
Telefon;89;15161718;
Frau;Claudia;Meier;02.03.1990
Adresse;Alte Straße 22;1067;Dresden
E-Mail;claudia.meier@example.com;;
Telefon;221;16171819;
Herr;Tobias;Lehmann;26.11.1985
Adresse;Markt 11;4109;Leipzig
E-Mail;tobias.lehmann@example.com;;
Telefon;511;17181920;
1 Herr Markus Zimmermann 30.12.1986
2 Adresse Friedrichstraße 10 10178 Berlin
3 E-Mail markus.zimmermann@example.com
4 Telefon 40 22335544
5 Telefon 176 10111213
6 Frau Lisa Krüger 15.06.1991
7 Adresse Schloßallee 1 80333 München
8 E-Mail lisa.kruger@example.com
9 Telefon 30 44667788
10 Telefon 179 12131415
11 Herr Christian Hartmann 23.01.1980
12 Adresse Wilhelmstraße 5 50679 Köln
13 E-Mail christian.hartmann@example.com
14 Telefon 30 13141516
15 Frau Melanie Werner 19.09.1987
16 Adresse Heinrich-Heine-Platz 7 20097 Hamburg
17 E-Mail melanie.werner@example.com
18 Telefon 40 14151617
19 Herr Patrick Krause 05.05.1984
20 Adresse Neustadt 3 30159 Hannover
21 E-Mail patrick.krause@example.com
22 Telefon 89 15161718
23 Frau Claudia Meier 02.03.1990
24 Adresse Alte Straße 22 1067 Dresden
25 E-Mail claudia.meier@example.com
26 Telefon 221 16171819
27 Herr Tobias Lehmann 26.11.1985
28 Adresse Markt 11 4109 Leipzig
29 E-Mail tobias.lehmann@example.com
30 Telefon 511 17181920