Compare commits
20 Commits
e8c5a43816
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 7b29c7df40 | |||
| 5795489f1e | |||
| 1a7a05f2f0 | |||
| d052784121 | |||
| eac696921a | |||
| 6953b36930 | |||
| 4b682a8b46 | |||
| aeb2707699 | |||
| ebcc615de4 | |||
| 26c62d000d | |||
| 9f2e9cbec8 | |||
| 5c51f68e6c | |||
| 6a05c7b75b | |||
| b5daf727d0 | |||
| 5be00c2e03 | |||
| 0156f3e3ac | |||
| de62de21ab | |||
| 8e94f38b7b | |||
| 380af838a6 | |||
| 822a8f4f6f |
400
.gitignore
vendored
Normal file
400
.gitignore
vendored
Normal 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
73
Dateien/import_yutani.csv
Normal 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;;
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -3,8 +3,8 @@
|
||||
"WorkspaceRootPath": "C:\\Jan_bib_Module\\PMC\\Projekt\\Projekt_Calcan_Conze\\",
|
||||
"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}",
|
||||
"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}"
|
||||
"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:{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": [
|
||||
@@ -19,14 +19,14 @@
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 0,
|
||||
"Title": "Program.cs",
|
||||
"DocumentMoniker": "C:\\Jan_bib_Module\\PMC\\Projekt\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze\\Program.cs",
|
||||
"RelativeDocumentMoniker": "Projekt_Calcan_Conze\\Program.cs",
|
||||
"ToolTip": "C:\\Jan_bib_Module\\PMC\\Projekt\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze\\Program.cs",
|
||||
"RelativeToolTip": "Projekt_Calcan_Conze\\Program.cs",
|
||||
"ViewState": "AQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
|
||||
"Title": "Database.cs",
|
||||
"DocumentMoniker": "C:\\Jan_bib_Module\\PMC\\Projekt\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze_Export\\Repositories\\Database.cs",
|
||||
"RelativeDocumentMoniker": "Projekt_Calcan_Conze_Export\\Repositories\\Database.cs",
|
||||
"ToolTip": "C:\\Jan_bib_Module\\PMC\\Projekt\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze_Export\\Repositories\\Database.cs",
|
||||
"RelativeToolTip": "Projekt_Calcan_Conze_Export\\Repositories\\Database.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAABOAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2024-05-24T09:06:25.212Z",
|
||||
"WhenOpened": "2024-09-02T18:06:03.752Z",
|
||||
"EditorCaption": ""
|
||||
}
|
||||
]
|
||||
|
||||
@@ -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;
|
||||
|
@@ -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;
|
||||
|
38
Projekt_Calcan_Conze/Core/Constants.cs
Normal file
38
Projekt_Calcan_Conze/Core/Constants.cs
Normal 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";
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
@@ -3,7 +3,11 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.10.34916.146
|
||||
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
|
||||
Global
|
||||
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}.Release|Any CPU.ActiveCfg = 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
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
13
Projekt_Calcan_Conze/Projekt_Calcan_Conze/DTOs/UserDto.cs
Normal file
13
Projekt_Calcan_Conze/Projekt_Calcan_Conze/DTOs/UserDto.cs
Normal 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; }
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
215
Projekt_Calcan_Conze/Projekt_Calcan_Conze/ImportUsers.cs
Normal file
215
Projekt_Calcan_Conze/Projekt_Calcan_Conze/ImportUsers.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
19
Projekt_Calcan_Conze/Projekt_Calcan_Conze/Models/Address.cs
Normal file
19
Projekt_Calcan_Conze/Projekt_Calcan_Conze/Models/Address.cs
Normal 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; }
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
116
Projekt_Calcan_Conze/Projekt_Calcan_Conze/Models/User.cs
Normal file
116
Projekt_Calcan_Conze/Projekt_Calcan_Conze/Models/User.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -1,2 +1,78 @@
|
||||
// See https://aka.ms/new-console-template for more information
|
||||
Console.WriteLine("Hello, World!");
|
||||
// Import: Jan Conze / PBS2H23ACO mit Unterstützung durch Radu Catalin Calcan
|
||||
|
||||
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}");
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ using System.Reflection;
|
||||
[assembly: System.Reflection.AssemblyCompanyAttribute("Projekt_Calcan_Conze")]
|
||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||
[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.AssemblyTitleAttribute("Projekt_Calcan_Conze")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||
|
||||
@@ -1 +1 @@
|
||||
e1c6e387605f1c707ceb8546e762bcd639e196f219432ea9dd58bf0b1473eacb
|
||||
12accfb452c230216e3ac941872f0c73361c12ee69c2b99c250749ff72d74495
|
||||
|
||||
Binary file not shown.
@@ -21,7 +21,8 @@
|
||||
"net8.0"
|
||||
],
|
||||
"sources": {
|
||||
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}
|
||||
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
|
||||
"https://api.nuget.org/v3/index.json": {}
|
||||
},
|
||||
"frameworks": {
|
||||
"net8.0": {
|
||||
@@ -43,6 +44,12 @@
|
||||
"frameworks": {
|
||||
"net8.0": {
|
||||
"targetAlias": "net8.0",
|
||||
"dependencies": {
|
||||
"MySql.Data": {
|
||||
"target": "Package",
|
||||
"version": "[8.4.0, )"
|
||||
}
|
||||
},
|
||||
"imports": [
|
||||
"net461",
|
||||
"net462",
|
||||
@@ -59,7 +66,7 @@
|
||||
"privateAssets": "all"
|
||||
}
|
||||
},
|
||||
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\8.0.300/PortableRuntimeIdentifierGraph.json"
|
||||
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\8.0.400/PortableRuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
|
||||
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\bib\.nuget\packages\</NuGetPackageFolders>
|
||||
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.10.0</NuGetToolVersion>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.11.0</NuGetToolVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<SourceRoot Include="C:\Users\bib\.nuget\packages\" />
|
||||
|
||||
@@ -1,2 +1,6 @@
|
||||
<?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>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,41 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dgSpecHash": "ee2VgL4Z9vU=",
|
||||
"dgSpecHash": "4Akg//gURuM=",
|
||||
"success": true,
|
||||
"projectFilePath": "C:\\Jan_bib_Module\\PMC\\Projekt\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze.csproj",
|
||||
"expectedPackageFiles": [],
|
||||
"projectFilePath": "C:\\Jan_bib_Module\\PMC\\Projekt\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze_Import.csproj",
|
||||
"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": []
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
106
Projekt_Calcan_Conze/Projekt_Calcan_Conze_Export/Program.cs
Normal file
106
Projekt_Calcan_Conze/Projekt_Calcan_Conze_Export/Program.cs
Normal 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}");
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
73
Projekt_Calcan_Conze/import_yutani.csv
Normal file
73
Projekt_Calcan_Conze/import_yutani.csv
Normal 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;;
|
||||
|
30
Projekt_Calcan_Conze/import_yutani_protocol.csv
Normal file
30
Projekt_Calcan_Conze/import_yutani_protocol.csv
Normal 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;
|
||||
|
Reference in New Issue
Block a user