Update of existing Accounts possible

pull/1/head
DJh2o2 2023-02-24 15:04:53 +07:00
parent 0c6c68441b
commit 8f6e3b28f3
8 changed files with 713 additions and 418 deletions

@ -40,7 +40,7 @@ public class DownloadPersonalDataModel : PageModel {
personalData.Add("Authenticator Key", await _userManager.GetAuthenticatorKeyAsync(user));
Response.Headers.Add("Content-Disposition", "attachment; filename=PersonalData.json");
Response.Headers.Append("Content-Disposition", "attachment; filename=PersonalData.json");
return new FileContentResult(JsonSerializer.SerializeToUtf8Bytes(personalData), "application/json");
}
}

@ -90,9 +90,7 @@ public class ExternalLoginsModel : PageModel {
if (user == null) return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
string userId = await _userManager.GetUserIdAsync(user);
ExternalLoginInfo info = await _signInManager.GetExternalLoginInfoAsync(userId);
if (info == null) throw new InvalidOperationException("Unexpected error occurred loading external login info.");
ExternalLoginInfo info = await _signInManager.GetExternalLoginInfoAsync(userId) ?? throw new InvalidOperationException("Unexpected error occurred loading external login info.");
IdentityResult result = await _userManager.AddLoginAsync(user, info);
if (!result.Succeeded) {
StatusMessage = "The external login was not added. External logins can only be associated with one account.";

File diff suppressed because it is too large Load Diff

@ -81,50 +81,48 @@
@code {
[CascadingParameter]
private Task<AuthenticationState>? authenticationStateTask { get; set; }
[CascadingParameter]
private Task<AuthenticationState>? authenticationStateTask { get; set; }
private IList<Account>? accounts;
private Account? selectedAccount;
private bool isImportingAccounts;
private IList<Account>? accounts;
private Account? selectedAccount;
private bool isImportingAccounts;
protected override async Task OnInitializedAsync() {
if (authenticationStateTask != null) {
ClaimsPrincipal user = (await authenticationStateTask).User;
protected override async Task OnInitializedAsync() {
if (authenticationStateTask != null) {
ClaimsPrincipal user = (await authenticationStateTask).User;
if (user.Identity is {IsAuthenticated: true }) {
accounts = genericController.GetAll<Account>();
}
}
if (user.Identity is {IsAuthenticated: true }) {
accounts = genericController.GetAll<Account>();
}
}
}
private void OnSelectedAccountChanged(Account sA) {
selectedAccount = sA;
selectedAccount.Contacts = genericController.GetAll<Contact>(c => c.AccountId == selectedAccount.AccountId);
}
private void OnSelectedAccountChanged(Account _selectedAccount) {
selectedAccount = _selectedAccount;
selectedAccount.Contacts = genericController.GetAll<Contact>(c => c.AccountId == selectedAccount.AccountId);
}
private async Task OnImportAccounts(FileChangedEventArgs fileChangedEventArgs) {
isImportingAccounts = true;
try
{
foreach (IFileEntry? file in fileChangedEventArgs.Files)
{
using MemoryStream stream = new();
await file.WriteToStreamAsync(stream);
stream.Seek(0, SeekOrigin.Begin);
using StreamReader reader = new(stream);
string fileContent = await reader.ReadToEndAsync();
bool success = await genericImporter.ImportCsvAsync<Account>(fileContent);
}
}
catch (Exception exception)
private async Task OnImportAccounts(FileChangedEventArgs fileChangedEventArgs) {
isImportingAccounts = true;
try
{
foreach (IFileEntry? file in fileChangedEventArgs.Files)
{
Console.WriteLine(exception.Message);
using MemoryStream stream = new();
await file.WriteToStreamAsync(stream);
stream.Seek(0, SeekOrigin.Begin);
using StreamReader reader = new(stream);
string fileContent = await reader.ReadToEndAsync();
_ = await genericImporter.ImportCsvAsync<Account>(fileContent);
}
Console.WriteLine("Account import successfull");
isImportingAccounts = false;
StateHasChanged();
return;
}
catch (Exception exception)
{
Console.WriteLine(exception.Message);
}
isImportingAccounts = false;
StateHasChanged();
return;
}
}

@ -263,7 +263,7 @@
}
private Task OnSave() {
if (GenericController.Insert(quote))
if (GenericController.Insert(quote) > 0)
NavigationManager.NavigateTo("Quotes/QuoteIndex");
return Task.CompletedTask;

@ -37,40 +37,31 @@ public class GenericController {
return gremlinDb.Set<TResult>().AsEnumerable().Last();
}
public bool Insert<T>(T entity) where T : class, IMetadata
public int Insert<T>(T entity) where T : class, IMetadata
{
try
{
gremlinDb.Set<T>().Add(entity);
if (typeof(T) == typeof(Account))
{
#pragma warning disable CS8600 // Das NULL-Literal oder ein möglicher NULL-Wert wird in einen Non-Nullable-Typ konvertiert.
Account account = entity as Account;
#pragma warning restore CS8600 // Das NULL-Literal oder ein möglicher NULL-Wert wird in einen Non-Nullable-Typ konvertiert.
#pragma warning disable CS8602 // Dereferenzierung eines möglichen Nullverweises.
Console.WriteLine($"Added {account.SapAccountNumber}:{account.AccountName} to database, try to save...");
#pragma warning restore CS8602 // Dereferenzierung eines möglichen Nullverweises.
}
return gremlinDb.SaveChanges() > 0;
return gremlinDb.SaveChanges();
}
catch (Exception exception)
{
Console.WriteLine(exception.InnerException);
return false;
return 0;
}
}
public bool Insert<T>(List<T> entities) where T : class, IMetadata
public int Insert<T>(List<T> entities) where T : class, IMetadata
{
try
{
gremlinDb.Set<T>().AddRange(entities);
return gremlinDb.SaveChanges() > 0;
return gremlinDb.SaveChanges();
}
catch (Exception exception)
{
Console.WriteLine(exception.InnerException);
return false;
return 0;
}
}
@ -78,4 +69,32 @@ public class GenericController {
{
return gremlinDb.Set<T>().AsEnumerable().Any(t => search(t));
}
public int Update<T>(T entity) where T : class, IMetadata
{
try
{
gremlinDb.Set<T>().Update(entity);
return gremlinDb.SaveChanges();
}
catch (Exception exception)
{
Console.WriteLine(exception.InnerException);
return 0;
}
}
public int Update<T>(List<T> entities) where T : class, IMetadata
{
try
{
gremlinDb.Set<T>().UpdateRange(entities);
return gremlinDb.SaveChanges();
}
catch (Exception exception)
{
Console.WriteLine(exception.InnerException);
return 0;
}
}
}

@ -1,23 +1,26 @@
using Gremlin_BlazorServer.Data.DBClasses;
using Gremlin_BlazorServer.Data.EntityClasses;
using Gremlin_BlazorServer.Data.EntityClasses;
using Gremlin_BlazorServer.Pages;
namespace Gremlin_BlazorServer.Services;
public class GenericImporter
{
private readonly GenericController genericController = new();
private List<Account> newAccounts = new();
private List<Account> updatedAccounts = new();
public async Task<bool> ImportCsvAsync<T>(string fileContent) where T : class, IMetadata
{
Console.WriteLine($"Importing accounts from csv...");
IList<string[]> splitLines = await Task.Run(() => SplitLines(fileContent));
if (typeof(T) == typeof(Account))
{
List<Account> listOfAccounts = await Task.Run(() => ParseListToAccounts(splitLines));
return genericController.Insert(listOfAccounts);
//foreach (Account account in listOfAccounts)
//{
// _ = genericController.Insert(account);
//}
ParseListToAccounts(splitLines);
int countNewAccounts = genericController.Insert(newAccounts);
int countUpdatedAccounts = genericController.Update(updatedAccounts);
Console.WriteLine($"Added {countNewAccounts} new Accounts to database and updated {updatedAccounts.Count} Accounts.");
return countNewAccounts > 0 || updatedAccounts.Count > 0;
}
return false;
@ -36,9 +39,9 @@ public class GenericImporter
return fileList;
}
private List<Account> ParseListToAccounts(IList<string[]> lineList)
private void ParseListToAccounts(IList<string[]> lineList) // ID;Acct Name 1 and 2;Street;City;BP Role;Postal Code;Customer Type;Market Indicator;
{
List<Account> listOfAccounts = new();
List<Account> existingAccounts = new();
foreach (string[] line in lineList)
{
@ -47,14 +50,7 @@ public class GenericImporter
if (uint.TryParse(line[0], out uint sapAccountNumber) && uint.TryParse(line[5], out uint zip)) //HACK: skip lines with wrong uint
{
if (AccountExists(sapAccountNumber))
{
//TODO: Check for changes
Console.WriteLine($"Account with SapAccountNumber {sapAccountNumber} already exists...");
continue;
};
Account account = new()
Account readAccount = new()
{
SapAccountNumber = sapAccountNumber,
AccountName = line[1],
@ -63,29 +59,62 @@ public class GenericImporter
Zip = zip,
AccountType = new(),
SubMarket = new(),
PhoneNumber = line[8],
EMail = line[9],
ParentAccountId = 0,
DataModificationByUser = "Gremlin Generic Importer"
};
AccountType? accountType = genericController.Get<AccountType>(aT => aT.AccountTypeCode == line[6]);
if (accountType == null) continue;
account.AccountType.AccountTypeCode = accountType.AccountTypeCode;
account.AccountType = genericController.Get<AccountType>(aT => aT.AccountTypeCode == account.AccountType.AccountTypeCode);
if (accountType == null) { continue; }
readAccount.AccountType.AccountTypeCode = accountType.AccountTypeCode;
readAccount.AccountType = genericController.Get<AccountType>(aT => aT.AccountTypeCode == readAccount.AccountType.AccountTypeCode);
SubMarket? subMarket = genericController.Get<SubMarket>(sM => sM.SubMarketCode == line[7]);
if (subMarket == null) { continue; }
account.SubMarket.SubMarketCode = subMarket.SubMarketCode;
account.SubMarket = genericController.Get<SubMarket>(sM => sM.SubMarketCode == account.SubMarket.SubMarketCode);
if (account?.SubMarket.SubMarketCode == null || account?.AccountType?.AccountTypeCode == null) continue; //HACK: skip Accounts with no SubMarket or AccountType
readAccount.SubMarket.SubMarketCode = subMarket.SubMarketCode;
readAccount.SubMarket = genericController.Get<SubMarket>(sM => sM.SubMarketCode == readAccount.SubMarket.SubMarketCode);
Console.WriteLine($"Found new account {account.SapAccountNumber}:{account.AccountName}!");
listOfAccounts.Add(account);
if (readAccount?.SubMarket?.SubMarketCode == null || readAccount?.AccountType?.AccountTypeCode == null) continue; //HACK: skip Accounts with no SubMarket or AccountType
if (AccountExists(sapAccountNumber))
{
Account? existingAccount = genericController.Get<Account>(a => a.SapAccountNumber == readAccount.SapAccountNumber);
if (existingAccount == null) continue; //Account does not exist
if (!IsEqualAccount(readAccount, existingAccount))
{
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;
//genericController.Update(existingAccount);
Console.WriteLine($"Update in Account {existingAccount.SapAccountNumber}:{existingAccount.AccountName}");
updatedAccounts.Add(existingAccount);
}
}
else
{
newAccounts.Add(readAccount);
}
}
}
}
return listOfAccounts;
}
private static bool IsEqualAccount(Account account, Account existingAccount)
{
return 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 bool AccountExists(uint sapAccountNumber)

@ -32,7 +32,7 @@ internal class HostingService
return quote;
}
public string? GetPdfUrl(Quote quote)
public static string? GetPdfUrl(Quote quote)
{
if (quote.Path == null || quote.QuotationNumber == null || quote.Recipient?.Account?.AccountName == null || quote.Description == null)
{