Import & Database Verbindung vollendet - Anfang vom Export

This commit is contained in:
Jan Conze 2024-08-30 08:09:49 +02:00
parent aeb2707699
commit 4b682a8b46
25 changed files with 762 additions and 199 deletions

View File

@ -2,10 +2,6 @@
"Version": 1,
"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\\repository\\dbconnection.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\\repository\\dbconnection.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"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\\import.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\\import.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
@ -15,28 +11,32 @@
"RelativeMoniker": "D:0:0:{44DD7752-6BB5-4C3A-9053-671D8ADE49C4}|Projekt_Calcan_Conze\\Projekt_Calcan_Conze.csproj|solutionrelative:projekt_calcan_conze\\programm.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"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\\models\\customer.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\\models\\customer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
"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\\models\\phonenumber.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\\models\\phonenumber.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"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\\models\\address.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\\models\\address.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
"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\\repository\\dbconnection.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\\repository\\dbconnection.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"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\\constants.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\\constants.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"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\\dtos\\customerdto.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\\dtos\\customerdto.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
"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\\models\\address.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\\models\\address.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"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\\models\\customer.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\\models\\customer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"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\\dtos\\customerattributedto.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\\dtos\\customerattributedto.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"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\\models\\phonenumber.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\\models\\phonenumber.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
"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\\dtos\\customerdto.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\\dtos\\customerdto.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
}
],
"DocumentGroupContainers": [
@ -46,50 +46,50 @@
"DocumentGroups": [
{
"DockedWidth": 200,
"SelectedChildIndex": 2,
"SelectedChildIndex": 1,
"Children": [
{
"$type": "Document",
"DocumentIndex": 2,
"DocumentIndex": 1,
"Title": "Programm.cs",
"DocumentMoniker": "C:\\Jan_bib_Module\\PMC\\Projekt\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze\\Programm.cs",
"RelativeDocumentMoniker": "Projekt_Calcan_Conze\\Programm.cs",
"ToolTip": "C:\\Jan_bib_Module\\PMC\\Projekt\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze\\Programm.cs",
"RelativeToolTip": "Projekt_Calcan_Conze\\Programm.cs",
"ViewState": "AgIAAAkAAAAAAAAAAAAAACcAAAAUAAAAAAAAAA==",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAgAAAAiAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2024-08-23T08:36:46.981Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 1,
"DocumentIndex": 0,
"Title": "Import.cs",
"DocumentMoniker": "C:\\Jan_bib_Module\\PMC\\Projekt\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze\\Import.cs",
"RelativeDocumentMoniker": "Projekt_Calcan_Conze\\Import.cs",
"ToolTip": "C:\\Jan_bib_Module\\PMC\\Projekt\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze\\Import.cs",
"RelativeToolTip": "Projekt_Calcan_Conze\\Import.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAHQAAAAAAAAAAAAAAA==",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAoAAABYAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2024-08-26T06:25:21.455Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 0,
"DocumentIndex": 3,
"Title": "dbConnection.cs",
"DocumentMoniker": "C:\\Jan_bib_Module\\PMC\\Projekt\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze\\Repository\\dbConnection.cs",
"RelativeDocumentMoniker": "Projekt_Calcan_Conze\\Repository\\dbConnection.cs",
"ToolTip": "C:\\Jan_bib_Module\\PMC\\Projekt\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze\\Repository\\dbConnection.cs",
"RelativeToolTip": "Projekt_Calcan_Conze\\Repository\\dbConnection.cs",
"ViewState": "AgIAABIAAAAAAAAAAAAAACIAAAArAAAAAAAAAA==",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAkAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2024-08-27T08:20:43.501Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 5,
"DocumentIndex": 4,
"Title": "Constants.cs",
"DocumentMoniker": "C:\\Jan_bib_Module\\PMC\\Projekt\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze\\Constants.cs",
"RelativeDocumentMoniker": "Projekt_Calcan_Conze\\Constants.cs",
@ -97,11 +97,12 @@
"RelativeToolTip": "Projekt_Calcan_Conze\\Constants.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAcAAAA/AAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2024-08-26T06:25:15.786Z"
"WhenOpened": "2024-08-26T06:25:15.786Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 4,
"DocumentIndex": 5,
"Title": "Address.cs",
"DocumentMoniker": "C:\\Jan_bib_Module\\PMC\\Projekt\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze\\Models\\Address.cs",
"RelativeDocumentMoniker": "Projekt_Calcan_Conze\\Models\\Address.cs",
@ -109,11 +110,12 @@
"RelativeToolTip": "Projekt_Calcan_Conze\\Models\\Address.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2024-08-26T06:25:38.242Z"
"WhenOpened": "2024-08-26T06:25:38.242Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 3,
"DocumentIndex": 6,
"Title": "Customer.cs",
"DocumentMoniker": "C:\\Jan_bib_Module\\PMC\\Projekt\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze\\Models\\Customer.cs",
"RelativeDocumentMoniker": "Projekt_Calcan_Conze\\Models\\Customer.cs",
@ -134,11 +136,12 @@
"RelativeToolTip": "Projekt_Calcan_Conze\\DTOs\\CustomerAttributeDto.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAQAAAAzAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2024-08-26T06:25:41.319Z"
"WhenOpened": "2024-08-26T06:25:41.319Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 6,
"DocumentIndex": 8,
"Title": "CustomerDto.cs",
"DocumentMoniker": "C:\\Jan_bib_Module\\PMC\\Projekt\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze\\DTOs\\CustomerDto.cs",
"RelativeDocumentMoniker": "Projekt_Calcan_Conze\\DTOs\\CustomerDto.cs",
@ -146,11 +149,12 @@
"RelativeToolTip": "Projekt_Calcan_Conze\\DTOs\\CustomerDto.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAIAAAAVAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2024-08-26T06:25:42.556Z"
"WhenOpened": "2024-08-26T06:25:42.556Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 8,
"DocumentIndex": 2,
"Title": "PhoneNumber.cs",
"DocumentMoniker": "C:\\Jan_bib_Module\\PMC\\Projekt\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze\\Models\\PhoneNumber.cs",
"RelativeDocumentMoniker": "Projekt_Calcan_Conze\\Models\\PhoneNumber.cs",
@ -158,7 +162,8 @@
"RelativeToolTip": "Projekt_Calcan_Conze\\Models\\PhoneNumber.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2024-08-26T06:25:35.981Z"
"WhenOpened": "2024-08-26T06:25:35.981Z",
"EditorCaption": ""
}
]
}

View File

@ -5,6 +5,7 @@ internal static class Constants
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,11 +0,0 @@
namespace Projekt_Calcan_Conze.DTOs;
internal class CustomerAttributeDto
{
public CustomerAttributeDto(List<string> parts)
{
this.Parts = parts;
}
public List<string> Parts { get; }
}

View File

@ -1,13 +0,0 @@
namespace Projekt_Calcan_Conze.DTOs;
using Projekt_Calcan_Conze.DTOs;
internal class CustomerDto
{
public CustomerDto(List<CustomerAttributeDto> attributes)
{
this.Attributes = attributes;
}
public List<CustomerAttributeDto> Attributes { get; }
}

View File

@ -0,0 +1,14 @@
namespace Projekt_Calcan_Conze.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,11 @@
namespace Projekt_Calcan_Conze.DTOs;
internal class UserDto
{
public UserDto(List<UserAttributeDto> attributes)
{
this.Attributes = attributes;
}
public List<UserAttributeDto> Attributes { get; }
}

View File

@ -0,0 +1,17 @@
namespace Projekt_Calcan_Conze.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

@ -1,25 +1,24 @@
namespace Projekt_Calcan_Conze;
using System.Net.Mail;
using System.Net.Mail;
using Projekt_Calcan_Conze.DTOs;
using Projekt_Calcan_Conze.Models;
using Microsoft.VisualBasic;
using Projekt_Calcan_Conze.Models;
internal static class Import
namespace Projekt_Calcan_Conze;
internal static class ImportUsers
{
public static (List<Customer> Customers, List<string> Protocol) For(string filePath)
public static (List<User> User, List<string> Protocol) FromCsv(string filePath)
{
var (customerDtos, protocol) = Import.ReadCustomerDtos(filePath);
var customers = Import.ParseCustomers(customerDtos, protocol);
return (customers, protocol);
var (userDtos, protocol) = ReadUserDtos(filePath);
var users = ParseUsers(userDtos, protocol);
return (users, protocol);
}
private static (List<CustomerDto> CustomerDtos, List<string> Protocol) ReadCustomerDtos(
string filePath)
private static (List<UserDto> UserDtos, List<string> Protocol) ReadUserDtos(string filePath)
{
List<string> protocol = [];
List<CustomerDto> customerDtos = [];
List<UserDto> userDtos = [];
List<string> lines;
try
@ -32,10 +31,10 @@ internal static class Import
catch (Exception)
{
Console.WriteLine("The file does not exist or is currently used by another program.");
return (customerDtos, protocol);
return (userDtos, protocol);
}
CustomerDto? currentCustomer = null;
UserDto? currentUser = null;
foreach (string line in lines)
{
@ -47,18 +46,21 @@ internal static class Import
string title = lineParts[0];
if (title is Constants.FemaleAttributeIdentifier or Constants.MaleAttributeIdentifier)
if (title
is Constants.FemaleAttributeIdentifier
or Constants.MaleAttributeIdentifier
or Constants.DiverseAttributeIdentifier)
{
if (currentCustomer is not null)
if (currentUser is not null)
{
customerDtos.Add(currentCustomer);
userDtos.Add(currentUser);
}
currentCustomer = new CustomerDto([new CustomerAttributeDto(lineParts)]);
currentUser = new UserDto([new UserAttributeDto(lineParts, line)]);
}
else if (currentCustomer is not null)
else if (currentUser is not null)
{
currentCustomer.Attributes.Add(new CustomerAttributeDto(lineParts));
currentUser.Attributes.Add(new UserAttributeDto(lineParts, line));
}
else
{
@ -66,39 +68,38 @@ internal static class Import
}
}
if (currentCustomer is not null)
if (currentUser is not null)
{
customerDtos.Add(currentCustomer);
userDtos.Add(currentUser);
}
return (customerDtos, protocol);
return (userDtos, protocol);
}
private static List<Customer> ParseCustomers(List<CustomerDto> customerDtos,
List<string> protocol)
private static List<User> ParseUsers(List<UserDto> userDtos, List<string> protocol)
{
List<Customer> customers = [];
List<User> users = [];
foreach (CustomerDto customerDto in customerDtos)
foreach (var userDto in userDtos)
{
Customer? customer = Import.ParseCustomer(customerDto);
var user = ParseUser(userDto);
if (customer is not null)
if (user is not null)
{
customers.Add(customer);
users.Add(user);
}
else
{
Import.LogInvalidCustomer(protocol, customerDto);
protocol.AddRange(userDto.Attributes.Select(attribute => attribute.OriginalCsvLine));
}
}
return customers;
return users;
}
private static Customer? ParseCustomer(CustomerDto customer)
private static User? ParseUser(UserDto user)
{
CustomerAttributeDto firstAttribute = customer.Attributes[0];
var firstAttribute = user.Attributes[0];
if (firstAttribute.Parts.Count != 4)
{
@ -111,7 +112,7 @@ internal static class Import
DateOnly? dateOfBirth =
DateOnly.TryParseExact(firstAttribute.Parts[3], Constants.DateOfBirthFormat,
out DateOnly date)
out var date)
? date
: null;
@ -124,7 +125,7 @@ internal static class Import
Address? address = null;
List<PhoneNumber> phoneNumbers = [];
foreach (CustomerAttributeDto attribute in customer.Attributes.Skip(1))
foreach (var attribute in user.Attributes.Skip(1))
{
var attributeParts = attribute.Parts;
string identifier = attributeParts[0];
@ -185,6 +186,10 @@ internal static class Import
{
phoneNumbers.Add(new PhoneNumber(areaCode, number));
}
else
{
return null;
}
}
else
{
@ -197,7 +202,7 @@ internal static class Import
}
}
return new Customer(
return new User(
title: title,
firstName: fistName,
lastName: lastName,
@ -206,12 +211,4 @@ internal static class Import
address: address,
phoneNumbers: phoneNumbers);
}
private static void LogInvalidCustomer(List<string> protocol, CustomerDto customerDto)
{
protocol.AddRange(
customerDto
.Attributes
.Select(attribute => string.Join(Constants.Separator, attribute.Parts)));
}
}

View File

@ -1,11 +1,10 @@
namespace Projekt_Calcan_Conze.Models;
using System.Text;
using Projekt_Calcan_Conze.Models;
using System.Text;
namespace Projekt_Calcan_Conze.Models;
internal class Customer
internal class User
{
public Customer(
public User(
string title,
string firstName,
string lastName,
@ -59,6 +58,56 @@ internal class Customer
{
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

@ -0,0 +1,76 @@
using Projekt_Calcan_Conze;
using Projekt_Calcan_Conze.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

@ -1,46 +0,0 @@
using Projekt_Calcan_Conze;
using Projekt_Calcan_Conze.Models;
string? filePath = null;
while (string.IsNullOrEmpty(filePath))
{
Console.WriteLine("Bitte gib einen Dateipfad an:");
filePath = Console.ReadLine();
}
if (filePath.StartsWith('\"'))
{
filePath = filePath.Substring(startIndex: 1, length: filePath.Length - 1);
}
if (filePath.EndsWith('\"'))
{
filePath = filePath.Substring(startIndex: 0, length: filePath.Length - 1);
}
string? customerId = null;
while (customerId is null)
{
Console.WriteLine("Bitte gib eine Kundennummer an:");
customerId = Console.ReadLine();
}
var (customers, protocol) = Import.For(filePath);
Console.WriteLine();
Console.WriteLine("Importierte Kunden:");
foreach (Customer customer in customers)
{
Console.WriteLine(customer.ToString());
}
Console.WriteLine();
Console.WriteLine("Ungültige nicht importierte Zeilen/Kunden:");
foreach (string protocolLine in protocol)
{
Console.WriteLine(protocolLine);
}

View File

@ -0,0 +1,296 @@
using System.Data;
using Projekt_Calcan_Conze.DTOs;
using Projekt_Calcan_Conze.Models;
namespace Projekt_Calcan_Conze.Repositories;
using MySql.Data.MySqlClient;
internal static class Database
{
//set the correct values for your server, user, password and database name
private const string ConnectionString = "server=localhost;uid=root;pwd=root;database=import_export";
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(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(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

@ -1,43 +0,0 @@
namespace Project_Calcan_Conze;
using MySql.Data;
using MySql.Data.MySqlClient;
using MySqlX.XDevAPI;
using System.Data.Common;
using System.Reflection.PortableExecutable;
using System.Xml;
MySql.Data.MySqlClient.MySqlConnection myConnection;
string myConnectionString;
//set the correct values for your server, user, password and database name
myConnectionString = "server=localhost;uid=root;pwd=root;database=vr_contact";
try
{
myConnection = new MySql.Data.MySqlClient.MySqlConnection(myConnectionString);
//open a connection
myConnection.Open();
// create a MySQL command and set the SQL statement with parameters
MySqlCommand myCommand = new MySqlCommand();
myCommand.Connection = myConnection;
myCommand.CommandText = @"SELECT * FROM workshop WHERE maxParticipants = @code;";
myCommand.Parameters.AddWithValue("@code", "12");
// execute the command and read the results
using MySqlDataReader myReader = myCommand.ExecuteReader();
while (myReader.Read())
{
int id = myReader.GetInt32("maxParticipants");
string name = myReader.GetString("title");
Console.WriteLine(id + " " + name);
}
myConnection.Close();
}
catch (MySql.Data.MySqlClient.MySqlException ex)
{
}

View File

@ -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+ebcc615de4c72eb9d786776bf6bd0ceb5640648c")]
[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")]

View File

@ -1 +1 @@
9c166b10907dc4b5eb71f19b5658d875cd05601f289a7fc5eb6bb564b59f3775
12accfb452c230216e3ac941872f0c73361c12ee69c2b99c250749ff72d74495

View File

@ -1791,9 +1791,9 @@
"project": {
"version": "1.0.0",
"restore": {
"projectUniqueName": "C:\\Jan_bib_Module\\PMC\\Projekt\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze.csproj",
"projectName": "Projekt_Calcan_Conze",
"projectPath": "C:\\Jan_bib_Module\\PMC\\Projekt\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze.csproj",
"projectUniqueName": "C:\\Jan_bib_Module\\PMC\\Projekt\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze_Import.csproj",
"projectName": "Projekt_Calcan_Conze_Import",
"projectPath": "C:\\Jan_bib_Module\\PMC\\Projekt\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze_Import.csproj",
"packagesPath": "C:\\Users\\bib\\.nuget\\packages\\",
"outputPath": "C:\\Jan_bib_Module\\PMC\\Projekt\\Projekt_Calcan_Conze\\Projekt_Calcan_Conze\\obj\\",
"projectStyle": "PackageReference",

View File

@ -1,8 +1,8 @@
{
"version": 2,
"dgSpecHash": "3YDIWICGXm0=",
"dgSpecHash": "xTy/jRXZQLw=",
"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": [
"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",

View File

@ -0,0 +1,10 @@
namespace Projekt_Calcan_Conze_Export;
internal static class Constants
{
public const string DateFormat = "yyyy-MM-dd";
public const string Separator = ";";
public const string MoneyFormat = "F2";
}

View File

@ -0,0 +1,80 @@
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 =
[
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)
];
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; }
public double TotalAmount => this.BaseAmount * this.Count;
}

View File

@ -0,0 +1,110 @@
using System.Globalization;
using Projekt_Calcan_Conze_Export;
using Projekt_Calcan_Conze_Export.Models;
using Microsoft.VisualBasic;
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;
}
}
List<Billing> billings =
[
new Billing(
startDate: startDate.Value,
endDate: endDate.Value,
customerNumber: clientNumber,
customerName: "Max Mustermann",
positions:
[
new BillingPosition(
description: "Testposition",
baseAmount: 100.0,
count: 3)
])
];
string fileName =
$"{DateTime.Today.ToString(Constants.DateFormat)}_{clientNumber}_{startDate.Value.ToString(Constants.DateFormat)}_{endDate.Value.ToString(Constants.DateFormat)}.csv";
File.WriteAllLines(
Path.Combine(directoryPath, fileName),
billings.SelectMany(billing => billing.ToCsvLines()));
}
catch (Exception ex)
{
Console.WriteLine($"Ein Fehler ist aufgetreten: {ex.Message}");
}

View File

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