Import of Contacts

pull/3/head
Sascha Woitschetzki 2023-08-14 13:28:15 +07:00
parent 79a2dc545a
commit d70383bbc1
8 changed files with 98 additions and 72 deletions

@ -45,7 +45,7 @@ public partial class Accounts {
_ = stream.Seek(0, SeekOrigin.Begin);
using StreamReader reader = new(stream);
string fileContent = await reader.ReadToEndAsync();
await GenericImporter.ImportCsvAsync<Account>(fileContent);
GenericImporter.ImportCsv<Account>(fileContent);
}
}
catch (Exception exception) {
@ -55,19 +55,21 @@ public partial class Accounts {
StateHasChanged();
}
private static async Task OnRowInsertedAsync(SavedRowItem<Account, Dictionary<string, object>> account) {
private static Task OnRowInsertedAsync(SavedRowItem<Account, Dictionary<string, object>> account) {
Account newAccount = ResolveAccountAsync(account.Item);
// if (newAccount.AccountType is null || newAccount.SubMarket is null) return;
int count = await GenericController.InsertAsync(newAccount);
int count = GenericController.Insert(newAccount);
Console.WriteLine($"Inserted {count} properties for new account {newAccount.AccountId}: {newAccount.AccountName}.");
return Task.CompletedTask;
}
private static async Task OnRowUpdatedAsync(SavedRowItem<Account, Dictionary<string, object>> account) {
private static Task OnRowUpdatedAsync(SavedRowItem<Account, Dictionary<string, object>> account) {
Account newAccount = ResolveAccountAsync(account.Item);
if (newAccount.AccountType == null || newAccount.SubMarket == null)
return;
int count = await GenericController.UpdateAsync(account.Item);
return Task.CompletedTask;
int count = GenericController.Update(account.Item);
Console.WriteLine($"Updated {count} properties in account {newAccount.AccountId}: {newAccount.AccountName}.");
return Task.CompletedTask;
}
private static async Task OnRowRemovedAsync(Account account) {

@ -38,14 +38,14 @@ public partial class Contacts {
private async Task OnRowInsertedAsync(SavedRowItem<Contact, Dictionary<string, object>> contact) {
Contact newContact = await ResolveContactAsync(contact.Item);
// if (newContact.Account is null) return;
int count = await GenericController.InsertAsync(newContact);
int count = GenericController.Insert(newContact);
Console.WriteLine($"Inserted {count} properties for new contact {newContact.ContactId}: {newContact.FirstName} {newContact.LastName}.");
}
private async Task OnRowUpdatedAsync(SavedRowItem<Contact, Dictionary<string, object>> contact) {
Contact newContact = await ResolveContactAsync(contact.Item);
// if (newContact.Account is null) return;
int count = await GenericController.UpdateAsync(contact.Item);
int count = GenericController.Update(contact.Item);
Console.WriteLine($"Updated {count} properties in contact {newContact.ContactId}: {newContact.FirstName} {newContact.LastName}.");
}
@ -80,7 +80,7 @@ public partial class Contacts {
_ = stream.Seek(0, SeekOrigin.Begin);
using StreamReader reader = new(stream);
string fileContent = await reader.ReadToEndAsync();
await GenericImporter.ImportCsvAsync<Contact>(fileContent);
GenericImporter.ImportCsv<Contact>(fileContent);
}
}
catch (Exception exception) {

@ -34,7 +34,7 @@ public partial class CustomDescriptions {
_ = stream.Seek(0, SeekOrigin.Begin);
using StreamReader reader = new(stream);
string fileContent = await reader.ReadToEndAsync();
await GenericImporter.ImportCsvAsync<CustomDescription>(fileContent);
GenericImporter.ImportCsv<CustomDescription>(fileContent);
}
}
catch (Exception exception) {
@ -43,16 +43,18 @@ public partial class CustomDescriptions {
StateHasChanged();
}
private static async Task OnRowInsertedAsync(SavedRowItem<CustomDescription, Dictionary<string, object>> customDescription) {
private static Task OnRowInsertedAsync(SavedRowItem<CustomDescription, Dictionary<string, object>> customDescription) {
CustomDescription newCustomDescription = ResolveCustomDescriptionAsync(customDescription.Item);
int count = await GenericController.InsertAsync(newCustomDescription);
int count = GenericController.Insert(newCustomDescription);
Console.WriteLine($"Inserted {count} properties for new custom description {newCustomDescription.ProductNumber}#{newCustomDescription.OptionNumber}: {newCustomDescription.Heading}");
return Task.CompletedTask;
}
private static async Task OnRowUpdatedAsync(SavedRowItem<CustomDescription, Dictionary<string, object>> customDescription) {
private static Task OnRowUpdatedAsync(SavedRowItem<CustomDescription, Dictionary<string, object>> customDescription) {
CustomDescription newCustomDescription = ResolveCustomDescriptionAsync(customDescription.Item);
int count = await GenericController.UpdateAsync(customDescription.Item);
int count = GenericController.Update(customDescription.Item);
Console.WriteLine($"Updated {count} properties for custom description {newCustomDescription.ProductNumber}#{newCustomDescription.OptionNumber}: {newCustomDescription.Heading}");
return Task.CompletedTask;
}
private static async Task OnRowRemovedAsync(CustomDescription customDescription) {

@ -36,13 +36,13 @@ public partial class ProductLines {
private async Task OnRowInsertedAsync(SavedRowItem<ProductLine, Dictionary<string, object>> productLine) {
ProductLine newProductLine = await ResolveProductAsync(productLine.Item);
int count = await GenericController.InsertAsync(newProductLine);
int count = GenericController.Insert(newProductLine);
Console.WriteLine($"Inserted {count} properties for new ProductLine {newProductLine.ProductLineCode}.");
}
private async Task OnRowUpdatedAsync(SavedRowItem<ProductLine, Dictionary<string, object>> productLine) {
ProductLine newProductLine = await ResolveProductAsync(productLine.Item);
int count = await GenericController.UpdateAsync(productLine.Item);
int count = GenericController.Update(productLine.Item);
Console.WriteLine($"Updated {count} properties in ProductLine {newProductLine.ProductLineCode}.");
}

@ -221,7 +221,7 @@ public partial class QuoteAdd {
//TODO need to wait for modal!
//Insert new CustomDescription to db
int count = await GenericController.InsertAsync(newCustomDescription);
int count = GenericController.Insert(newCustomDescription);
Console.WriteLine($"Inserted {count} new CustomDescriptions");
// Product product = await GenericController.GetAsync<Product>(p => p.ProductNumber.Equals(lineItem.ProductNumber) && p.OptionNumber.Equals(lineItem.OptionNumber));
@ -308,13 +308,14 @@ public partial class QuoteAdd {
if (quote is { LineItems: not null, Recipient.Account: not null }) lineItemsNotReady = false;
}
private async Task OnSave() {
if (await GenericController.InsertAsync(quote) > 0) {
// if (await GenericController.InsertAsync(quote.LineItems) > 0) {
Console.WriteLine($"Succesfully added quote {quote.QuotationNumber} to db with {quote.LineItems.Count} lineitems and a total net of {quote.TotalNet} euros.");
NavigationManager.NavigateTo("Quotes/QuoteIndex");
// }
}
private Task OnSave() {
if (GenericController.Insert(quote) <= 0) return Task.CompletedTask;
// if (await GenericController.InsertAsync(quote.LineItems) > 0) {
Console.WriteLine($"Succesfully added quote {quote.QuotationNumber} to db with {quote.LineItems.Count} lineitems and a total net of {quote.TotalNet} euros.");
NavigationManager.NavigateTo("Quotes/QuoteIndex");
// }
return Task.CompletedTask;
}
private async Task OnCreateTex() {
@ -383,16 +384,18 @@ public partial class QuoteAdd {
isReloadingLineItems = false;
}
private static async Task OnRowInsertedAsync(SavedRowItem<CustomDescription, Dictionary<string, object>> customDescription) {
private static Task OnRowInsertedAsync(SavedRowItem<CustomDescription, Dictionary<string, object>> customDescription) {
CustomDescription nCd = ResolveCustomDescription(customDescription.Item);
int count = await GenericController.InsertAsync(nCd);
int count = GenericController.Insert(nCd);
Console.WriteLine($"Inserted {count} properties for new custom description {nCd.ProductNumber}#{nCd.OptionNumber}: {nCd.Heading}");
return Task.CompletedTask;
}
private static async Task OnRowUpdatedAsync(SavedRowItem<CustomDescription, Dictionary<string, object>> customDescription) {
private static Task OnRowUpdatedAsync(SavedRowItem<CustomDescription, Dictionary<string, object>> customDescription) {
CustomDescription nCd = ResolveCustomDescription(customDescription.Item);
int count = await GenericController.UpdateAsync(customDescription.Item);
int count = GenericController.Update(customDescription.Item);
Console.WriteLine($"Updated {count} properties for custom description {nCd.ProductNumber}#{nCd.OptionNumber}: {nCd.Heading}");
return Task.CompletedTask;
}
private static async Task OnRowRemovedAsync(CustomDescription customDescription) {

@ -125,10 +125,10 @@ public class GenericController {
}
}
public static async Task<int> InsertAsync<T>(T entity) where T : class, IMetadata {
public static int Insert<T>(T entity) where T : class, IMetadata {
try {
gremlinDb.Set<T>().Add(entity);
return await gremlinDb.SaveChangesAsync();
return gremlinDb.SaveChanges();
}
catch (DbUpdateException ex) {
Console.WriteLine($"{ex.InnerException}");
@ -141,11 +141,11 @@ public class GenericController {
}
}
public static async Task<int> InsertAsync<T>(IEnumerable<T> entities) where T : class, IMetadata {
public static int Insert<T>(IEnumerable<T> entities) where T : class, IMetadata {
// gremlinDb.Set<T>().ToList(); //Get newest versions fresh from db
try {
gremlinDb.Set<T>().AddRange(entities);
return await gremlinDb.SaveChangesAsync();
return gremlinDb.SaveChanges();
}
catch (DbUpdateException ex) {
HandleConcurrencyExceptions(ex);
@ -167,11 +167,10 @@ public class GenericController {
}
}
public static async Task<int> UpdateAsync<T>(T entity) where T : class, IMetadata {
Task<T?> task = gremlinDb.Set<T>().FirstOrDefaultAsync(t => t.Equals(entity)); //Get newest version fresh from db
public static int Update<T>(T entity) where T : class, IMetadata {
try {
gremlinDb.Set<T>().Update(entity);
return await gremlinDb.SaveChangesAsync(false);
return gremlinDb.SaveChanges(false);
}
catch (DbUpdateException ex) {
HandleConcurrencyExceptions(ex);
@ -183,12 +182,10 @@ public class GenericController {
}
}
public static async Task<int> UpdateAsync<T>(IEnumerable<T> entities) where T : class, IMetadata {
// IQueryable<T> list = gremlinDb.Set<T>().Where(t => t.Equals(entities)); //Get newest version fresh from db
public static int Update<T>(IEnumerable<T> entities) where T : class, IMetadata {
try {
await Task.Run(() => gremlinDb.Set<T>().UpdateRange(entities));
return await gremlinDb.SaveChangesAsync();
gremlinDb.Set<T>().UpdateRange(entities);
return gremlinDb.SaveChanges();
}
catch (DbUpdateException ex) {
HandleConcurrencyExceptions(ex);

@ -7,12 +7,11 @@ namespace Gremlin_BlazorServer.Services;
public class GenericImporter {
public static async Task ImportCsvAsync<T>(string fileContent) where T : class, IMetadata, new() {
public static void ImportCsv<T>(string fileContent) where T : class, IMetadata, new() {
Console.WriteLine($"GENERIC IMPORTER: Importing {typeof(T)} from csv...");
List<string[]> splitLines = await Task.Run(() => SplitLines(fileContent));
List<string[]> splitLines = SplitLines(fileContent);
Console.WriteLine($"Found {splitLines.Count} potential {typeof(T)} in csv.");
ParseLinesToResultSet<T>(splitLines);
Console.WriteLine($"GENERIC IMPORTER: Ready!");
Console.WriteLine(ParseLinesToResultSet<T>(splitLines) ? $"GENERIC IMPORTER: Ready." : $"GENERIC IMPORTER: Error by writing to db!");
}
private static List<string[]> SplitLines(string fileContent) {
@ -21,7 +20,7 @@ public class GenericImporter {
return fileList;
}
private static async void ParseLinesToResultSet<T>(IEnumerable<string[]> lineList) where T : class, IMetadata, new() {
private static bool ParseLinesToResultSet<T>(IEnumerable<string[]> lineList) where T : class, IMetadata, new() {
Tuple<T?, T?>? resultSet = new(new(), new());
List<T> updatedItems = new();
List<T> newItems = new();
@ -35,9 +34,12 @@ public class GenericImporter {
if (resultSet.Item2 is not null) newItems.Add(resultSet.Item2);
}
int success = 0;
Console.WriteLine($"Found {updatedItems.Count} updates and {newItems.Count} new items.");
if (updatedItems.Count > 0) await GenericController.UpdateAsync(updatedItems);
if (newItems.Count > 0) await GenericController.InsertAsync(newItems);
if (updatedItems.Count > 0) success += GenericController.Update(updatedItems);
if (newItems.Count > 0) success += GenericController.Insert(newItems);
return success > 0;
}
private static Tuple<Account?, Account?>? ParseToAccount(IReadOnlyList<string> line) { // "ID" "Name" "Street" "City" "BP Role" "Postal Code" "Customer Type" "Market Indicator" "Phone" "E-Mail" "Market code"
@ -81,7 +83,6 @@ public class GenericImporter {
existingAccount.PhoneNumber = readAccount.PhoneNumber;
existingAccount.Street = readAccount.Street;
existingAccount.Zip = readAccount.Zip;
Console.WriteLine($"Update in Account {existingAccount.SapAccountNumber}:{existingAccount.AccountName}");
updatedAccount = existingAccount;
}
else {
@ -119,12 +120,11 @@ public class GenericImporter {
Gender = 0
};
Contact? existingContact = GenericController.Get<Contact>(a => a.SapContactNumber == sapContactNumber
|| (a.LastName == readContact.LastName && a.FirstName == readContact.FirstName));
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.");
// Console.WriteLine($"---> The contact {readContact.SapContactNumber}:{readContact.FirstName} {readContact.LastName} ist aktuell.");
return null;
}
@ -148,24 +148,46 @@ public class GenericImporter {
return new(updatedContact, newContact);
}
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; }
private static bool IsEqualAccount(Account readAccount, Account existingAccount) {
bool equalAccount = true;
if (readAccount.AccountName != existingAccount.AccountName) {
equalAccount = false;
Console.WriteLine($"--- UPDATE in Account {readAccount.SapAccountNumber} ---");
Console.WriteLine($"{readAccount.AccountName} | {existingAccount.AccountName}");
}
if (readAccount.City != existingAccount.City) {
equalAccount = false;
Console.WriteLine($"--- UPDATE in Account {readAccount.SapAccountNumber} ---");
Console.WriteLine($"{readAccount.City} | {existingAccount.City}");
}
if (readAccount.EMail != existingAccount.EMail) {
equalAccount = false;
Console.WriteLine($"--- UPDATE in Account {readAccount.SapAccountNumber} ---");
Console.WriteLine($"{readAccount.EMail} | {existingAccount.EMail}");
}
if (readAccount.PhoneNumber != existingAccount.PhoneNumber) {
equalAccount = false;
Console.WriteLine($"--- UPDATE in Account {readAccount.SapAccountNumber} ---");
Console.WriteLine($"{readAccount.PhoneNumber} | {existingAccount.PhoneNumber}");
}
if (readAccount.Street != existingAccount.Street) {
equalAccount = false;
Console.WriteLine($"--- UPDATE in Account {readAccount.SapAccountNumber} ---");
Console.WriteLine($"{readAccount.Street} | {existingAccount.Street}");
}
if (readAccount.Zip != existingAccount.Zip) {
equalAccount = false;
Console.WriteLine($"--- UPDATE in Account {readAccount.SapAccountNumber} ---");
Console.WriteLine($"{readAccount.Zip} | {existingAccount.Zip}");
}
return equalAccount;
}
private static bool IsEqualContact(Contact readContact, Contact existingContact)
=> readContact.LastName == existingContact.LastName
&& readContact.FirstName == existingContact.FirstName
&& readContact.EMail == existingContact.EMail
&& readContact.PhoneNumber == existingContact.PhoneNumber
&& readContact.EmailBounced == existingContact.EmailBounced
&& readContact.OptInStatus == existingContact.OptInStatus;
}

@ -206,7 +206,7 @@ public class QuoteHandling {
AccountId = 1
};
int count = await GenericController.InsertAsync(newCustomDescription);
int count = GenericController.Insert(newCustomDescription);
Console.WriteLine($"Inserted {count} new CustomDescriptions");
// Product product = await GenericController.GetAsync<Product>(p => p.ProductNumber.Equals(lineItem.ProductNumber) && p.OptionNumber.Equals(lineItem.OptionNumber));