162 lines
8.4 KiB
C#
162 lines
8.4 KiB
C#
using Blazorise;
|
|
using Gremlin_BlazorServer.Data.EntityClasses;
|
|
using MySqlX.XDevAPI.Common;
|
|
|
|
namespace Gremlin_BlazorServer.Services;
|
|
|
|
public class GenericImporter {
|
|
|
|
public static async Task ImportCsvAsync<T>(string fileContent) where T : class, IMetadata {
|
|
Console.WriteLine($"GENERIC IMPORTER: Importing {typeof(T)} from csv...");
|
|
List<string[]> splitLines = await Task.Run(() => SplitLines(fileContent));
|
|
Console.WriteLine($"Found {splitLines.Count} potential {typeof(T)} in csv.");
|
|
await ParseLinesToResultSet<T>(splitLines);
|
|
Console.WriteLine($"GENERIC IMPORTER: Ready!");
|
|
}
|
|
|
|
private static List<string[]> SplitLines(string fileContent) {
|
|
IEnumerable<string> fileLines = fileContent.Split(Environment.NewLine.ToCharArray());
|
|
List<string[]> fileList = (from clipboardLine in fileLines where clipboardLine != "" select clipboardLine.Split('\t')).ToList();
|
|
return fileList;
|
|
}
|
|
|
|
private static async Task ParseLinesToResultSet<T>(IEnumerable<string[]> lineList) where T : class, IMetadata
|
|
{
|
|
Result<T>? result = null;
|
|
foreach (string[] line in lineList.Select(strings => strings.Select(x => x.Replace("\"", string.Empty)).ToArray())) { // Delete all ""
|
|
if (typeof(T) == typeof(Account)) result = await ParseToAccount(line) as Result<T>;
|
|
if (typeof(T) == typeof(Contact)) result = await ParseToContact(line) as Result<T>;
|
|
|
|
if (result is null) continue;
|
|
|
|
if (result.NewItem is not null) await GenericController.InsertAsync(result.NewItem);
|
|
if (result.UpdatedItem is not null) await GenericController.UpdateAsync(result.UpdatedItem);
|
|
}
|
|
}
|
|
|
|
private static async Task<Result<Account>?> ParseToAccount(IReadOnlyList<string> line) { // "ID" "Name" "Street" "City" "BP Role" "Postal Code" "Customer Type" "Market Indicator" "Phone" "E-Mail" "Market code"
|
|
if (line[0].Contains("ID")) return null; //HACK: skip first row if header
|
|
if (!uint.TryParse(line[0], out uint sapAccountNumber)) return null; //HACK: skip wrong SapAccountNumbers
|
|
if (!uint.TryParse(line[5], out uint zip)) return null; //HACK: skip wrong ZIPs
|
|
|
|
Result<Account> result = new();
|
|
|
|
string accountTypeCode = line[6];
|
|
if (accountTypeCode is "" or null) accountTypeCode = "FPC"; // standard AccountType
|
|
|
|
string subMarketCode = line[7];
|
|
if (subMarketCode is "" or null) subMarketCode = "CCH"; // standard AccountType
|
|
|
|
Account readAccount = new() {
|
|
SapAccountNumber = sapAccountNumber,
|
|
AccountName = line[1], //System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(line[1].ToLower())
|
|
Street = line[2],
|
|
City = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(line[3].ToLower()), //line[3].ToUpper().First() + line[3][1..].ToLower(),
|
|
Zip = zip,
|
|
PhoneNumber = line[8],
|
|
EMail = line[9],
|
|
DataModificationByUser = "Gremlin Generic Importer",
|
|
AccountTypeCode = accountTypeCode,
|
|
SubMarketCode = subMarketCode
|
|
};
|
|
|
|
Account? existingAccount = GenericController.Get<Account>(a => a.SapAccountNumber == sapAccountNumber
|
|
|| a.AccountName == readAccount.AccountName);
|
|
|
|
if (existingAccount is not null) {
|
|
if (IsEqualAccount(readAccount, existingAccount)) return null;
|
|
existingAccount.DataModificationDate = DateTime.Now;
|
|
existingAccount.DataVersionNumber++;
|
|
existingAccount.DataModificationByUser = "Updated by Gremlin Generic Importer";
|
|
existingAccount.AccountName = readAccount.AccountName;
|
|
existingAccount.City = readAccount.City;
|
|
existingAccount.EMail = readAccount.EMail;
|
|
existingAccount.PhoneNumber = readAccount.PhoneNumber;
|
|
existingAccount.Street = readAccount.Street;
|
|
existingAccount.Zip = readAccount.Zip;
|
|
Console.WriteLine($"Update in Account {existingAccount.SapAccountNumber}:{existingAccount.AccountName}");
|
|
result.UpdatedItem = existingAccount;
|
|
}
|
|
else {
|
|
Console.WriteLine($"Account {readAccount.SapAccountNumber}:{readAccount.AccountName} ist neu!");
|
|
result.NewItem = readAccount;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private static async Task<Result<Contact>?> ParseToContact(IReadOnlyList<string> line) { //"Contact ID" "Account ID" "Last Name" "First Name" "Acct Name 1 and 2" "Street - Work Address" "Postal Code - Work Address" "City - Work Address" "E-Mail" "Phone" "E-Mail Opt"
|
|
if (line[0].Contains("ID")) return null; //HACK: skip first row if header
|
|
if (!uint.TryParse(line[0], out uint sapContactNumber)) return null; //HACK: skip wrong SapContactNumbers
|
|
if (!uint.TryParse(line[1], out uint sapAccountNumber)) return null; //HACK: skip wrong SapAccountNumbers
|
|
Account? account = GenericController.Get<Account>(a => a.SapAccountNumber.Equals(sapAccountNumber));
|
|
if (account is null) {
|
|
Console.WriteLine($"Account with SapAccountNumber {sapAccountNumber} is not existing!!");
|
|
return null; //HACK: skip empty Accounts
|
|
}
|
|
|
|
Result<Contact> result = new();
|
|
|
|
Contact readContact = new() {
|
|
SapContactNumber = sapContactNumber,
|
|
AccountId = account.AccountId,
|
|
LastName = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(line[2].ToLower()),
|
|
FirstName = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(line[3].ToLower()),
|
|
EMail = line[8].ToLower(),
|
|
EmailBounced = line[8].Contains("bounced"),
|
|
PhoneNumber = line[9],
|
|
OptInStatus = line[10] == "Opt In",
|
|
DataModificationByUser = "Gremlin Generic Importer",
|
|
Gender = 0
|
|
};
|
|
|
|
Contact? existingContact = GenericController.Get<Contact>(a => a.SapContactNumber == sapContactNumber
|
|
|| (a.LastName == readContact.LastName && a.FirstName == readContact.FirstName));
|
|
if (existingContact is not null) {
|
|
|
|
if (IsEqualContact(readContact, existingContact)) {
|
|
Console.WriteLine($"---> The contact {readContact.SapContactNumber}:{readContact.FirstName} {readContact.LastName} ist aktuell.");
|
|
return null;
|
|
}
|
|
|
|
existingContact.DataModificationDate = DateTime.Now;
|
|
existingContact.DataVersionNumber++;
|
|
existingContact.DataModificationByUser = "Updated by Gremlin Generic Importer";
|
|
existingContact.AccountId = readContact.AccountId;
|
|
existingContact.LastName = readContact.LastName;
|
|
existingContact.EMail = readContact.EMail;
|
|
existingContact.PhoneNumber = readContact.PhoneNumber;
|
|
existingContact.EmailBounced = readContact.EmailBounced;
|
|
existingContact.OptInStatus = readContact.OptInStatus;
|
|
Console.WriteLine($"Update in Contact {existingContact.SapContactNumber}:{existingContact.FirstName} {existingContact.LastName}");
|
|
result.UpdatedItem = existingContact;
|
|
}
|
|
else {
|
|
Console.WriteLine($"Contact {readContact.SapContactNumber}:{readContact.FirstName} {readContact.LastName} ist neu!");
|
|
result.NewItem = readContact;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private static bool IsEqualAccount(Account account, Account existingAccount)
|
|
=> account.AccountName == existingAccount.AccountName
|
|
&& account.City == existingAccount.City
|
|
&& account.EMail == existingAccount.EMail
|
|
&& account.PhoneNumber == existingAccount.PhoneNumber
|
|
&& account.Street == existingAccount.Street
|
|
&& account.Zip == existingAccount.Zip;
|
|
|
|
private static bool IsEqualContact(Contact contact, Contact existingContact)
|
|
=> contact.LastName == existingContact.LastName
|
|
&& contact.FirstName == existingContact.FirstName
|
|
&& contact.EMail == existingContact.EMail
|
|
&& contact.PhoneNumber == existingContact.PhoneNumber
|
|
&& contact.EmailBounced == existingContact.EmailBounced
|
|
&& contact.OptInStatus == existingContact.OptInStatus;
|
|
}
|
|
|
|
internal class Result<T> {
|
|
public T? NewItem { get; set; }
|
|
public T? UpdatedItem { get; set; }
|
|
} |