Try to avoid database errors

pull/1/head
Sascha Woitschetzki 2023-06-21 10:28:32 +07:00
parent 5e3e55dd93
commit 7232d9ee77
21 changed files with 469 additions and 482 deletions

@ -18,7 +18,7 @@ public class Account : IMetadata
public SubMarket? SubMarket { get; set; }
public IList<Contact>? Contacts { get; set; }
public IList<SalesRep> SalesReps { get; set; }
public IList<SalesRep>? SalesReps { get; set; }
// public IList<CustomDescription>? CustomDescriptions { get; set; }
//class properties:

@ -6,7 +6,7 @@ public class AccountType : IMetadata {
//primary key:
//public uint AccountTypeId { get; set; }
[Key] //Fluent API .HasKey funktioniert nicht
public string? AccountTypeCode { get; set; }
public string AccountTypeCode { get; set; } = string.Empty;
//navigation properties:
public IList<Account>? Accounts { get; set; }

@ -7,7 +7,7 @@ public class LineItem : IMetadata {
//foreign keys:
public uint QuoteId { get; set; }
public uint ProductId { get; set; }
public uint? ProductId { get; set; }
// public uint CustomDescriptionId { get; set; }
//navigation properties:

@ -10,7 +10,7 @@ public class Product : IMetadata {
public CustomDescription? CustomDescription { get; set; }
//foreign keys
public string? ProductLineCode { get; set; }
public string ProductLineCode { get; set; } = string.Empty;
public uint CustomDescriptionId { get; set; }
//Agilent-specific properties:

@ -5,7 +5,7 @@ namespace Gremlin_BlazorServer.Data.EntityClasses;
public class ProductLine : IMetadata {
//primary key:
//public uint ProductLineId { get; set; }
[Key] public string? ProductLineCode { get; set; }
[Key] public string ProductLineCode { get; set; } = string.Empty;
//navigation properties:
public IList<Product>? Products { get; set; }

@ -11,8 +11,8 @@ public class Quote : IMetadata {
// public uint ProductId { get; set; }
//navigation properties:
public Contact? Recipient { get; set; } = new() { Account = new() };
public SalesRep? SalesRep { get; set; } = new() { Account = new() };
public Contact Recipient { get; set; } = new() { Account = new() };
public SalesRep SalesRep { get; set; } = new() { Account = new() };
public IList<LineItem>? LineItems { get; set; }
@ -38,7 +38,7 @@ public class Quote : IMetadata {
public bool ShowSinglePrices { get; set; } = true;
public bool ShowDiscounts { get; set; } = true;
public bool ShowBrutto { get; set; } = true;
public string? QuoteDescription { get; set; }
public string? QuoteDescription { get; set; } = "Gerät";
public string? Tex { get; set; }
public string? Description { get; set; }
public string? Path { get; set; }

@ -9,14 +9,14 @@ public class SalesRep : IMetadata {
// public uint QuoteId { get; set; }
//navigation properties:
public Account? Account { get; set; }
public IList<Quote>? ListOfQuotes { get; set; }
public Account Account { get; set; } = new();
public IList<Quote> ListOfQuotes { get; set; } = new List<Quote>();
//class properties:
public string? TerritoryId { get; set; }
public string? AcademicTitle { get; set; }
public string? FirstName { get; set; }
public string? LastName { get; set; }
public string FirstName { get; set; } = string.Empty;
public string LastName { get; set; } = string.Empty;
public byte Gender { get; set; }
public string? PhoneNumber { get; set; }
public string? MobileNumber { get; set; }

@ -3,6 +3,7 @@
@using Gremlin_BlazorServer.Data.EntityClasses
@inject GenericController GenericController;
@inject ILoadingIndicatorService ApplicationLoadingIndicatorService
<AuthorizeView>
<Authorized Context="auth">

@ -2,25 +2,33 @@ using System.Security.Claims;
using Gremlin_BlazorServer.Data.EntityClasses;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;
using NuGet.Packaging;
namespace Gremlin_BlazorServer.Pages;
public partial class AccountTypes {
private IList<AccountType>? accountTypes;
private AccountType? selectedAccountType;
private readonly IList<AccountType> accountTypes = new List<AccountType>();
private AccountType selectedAccountType = new();
[CascadingParameter] private Task<AuthenticationState>? AuthenticationStateTask { get; set; }
protected override async Task OnInitializedAsync() {
if (AuthenticationStateTask != null) {
ClaimsPrincipal user = (await AuthenticationStateTask).User;
if (user.Identity is { IsAuthenticated: true }) accountTypes = await GenericController.GetAllAsync<AccountType>("Accounts");
if (user.Identity is{ IsAuthenticated: true }) {
await ApplicationLoadingIndicatorService.Show();
accountTypes.AddRange(await GenericController.GetAllAsync<AccountType>());
selectedAccountType = accountTypes.First();
await OnSelectedAccountTypeChanged(selectedAccountType);
await ApplicationLoadingIndicatorService.Hide();
}
await base.OnInitializedAsync();
}
}
private async Task OnSelectedAccountTypeChanged(AccountType selectedAccountType) {
if (selectedAccountType != null) this.selectedAccountType = await GenericController.GetAsync<AccountType>(aC => aC.AccountTypeCode == selectedAccountType.AccountTypeCode, "Accounts");
private async Task OnSelectedAccountTypeChanged(AccountType newSelectedAccountType) {
await ApplicationLoadingIndicatorService.Show();
selectedAccountType = await GenericController.GetAsync<AccountType>(aC => aC.AccountTypeCode.Equals(newSelectedAccountType.AccountTypeCode), "Accounts");
await ApplicationLoadingIndicatorService.Hide();
}
}

@ -2,29 +2,33 @@ using System.Security.Claims;
using Blazorise;
using Blazorise.DataGrid;
using Gremlin_BlazorServer.Data.EntityClasses;
using Gremlin_BlazorServer.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;
using NuGet.Packaging;
namespace Gremlin_BlazorServer.Pages;
public partial class Accounts {
private IList<Account>? accounts;
private Account? selectedAccount;
private readonly IList<Account> accounts = new List<Account>();
private Account selectedAccount = new();
[CascadingParameter] private Task<AuthenticationState>? AuthenticationStateTask { get; set; }
protected override async Task OnInitializedAsync() {
if (AuthenticationStateTask != null) {
ClaimsPrincipal user = (await AuthenticationStateTask).User;
if (user.Identity is { IsAuthenticated: true }) accounts = await GenericController.GetAllAsync<Account>("AccountType", "SubMarket");
if (user.Identity is{ IsAuthenticated: true }) {
accounts.AddRange(await GenericController.GetAllAsync<Account>());
selectedAccount = accounts.First();
}
await base.OnInitializedAsync();
}
}
private void OnSelectedAccountChanged(Account selectedAccount) {
this.selectedAccount = selectedAccount;
this.selectedAccount.Contacts = GenericController.GetAll<Contact>(c => c.AccountId == this.selectedAccount.AccountId);
private async Task OnSelectedAccountChanged(Account newSelectedAccount) {
selectedAccount = newSelectedAccount;
selectedAccount.Contacts = await GenericController.GetAllAsync<Contact>(c => c.AccountId.Equals(selectedAccount.AccountId));
}
private async Task OnImportAccounts(FileChangedEventArgs fileChangedEventArgs) {
@ -47,8 +51,7 @@ public partial class Accounts {
private async Task OnRowInsertedAsync(SavedRowItem<Account, Dictionary<string, object>> account) {
Account newAccount = await ResolveAccountAsync(account.Item);
if (newAccount.AccountType == null || newAccount.SubMarket == null)
return;
// if (newAccount.AccountType is null || newAccount.SubMarket is null) return;
int count = await GenericController.InsertAsync(newAccount);
Console.WriteLine($"Inserted {count} properties for new account {newAccount.AccountId}: {newAccount.AccountName}.");
}
@ -69,8 +72,8 @@ public partial class Accounts {
private async Task<Account> ResolveAccountAsync(Account newAccount) {
newAccount.DataModificationByUser = "Gremlin Blazor Server GUI";
newAccount.DataVersionNumber++;
newAccount.AccountType = await GenericController.GetAsync<AccountType>(aT => aT.AccountTypeCode.Equals("SUP"));
newAccount.SubMarket = await GenericController.GetAsync<SubMarket>(sM => sM.SubMarketCode.Equals("VEN"));
// newAccount.AccountType = await GenericController.GetAsync<AccountType>(aT => aT.AccountTypeCode.Equals("SUP"));
// newAccount.SubMarket = await GenericController.GetAsync<SubMarket>(sM => sM.SubMarketCode.Equals("VEN"));
return newAccount;
}
}

@ -3,57 +3,53 @@ using System.Security.Claims;
using Blazorise;
using Blazorise.DataGrid;
using Gremlin_BlazorServer.Data.EntityClasses;
using Gremlin_BlazorServer.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;
using NuGet.Packaging;
namespace Gremlin_BlazorServer.Pages;
public partial class Contacts {
private readonly CultureInfo cultureInfo = new("de-DE");
private readonly List<Contact>? selectedContacts;
private readonly int totalContacts;
private IList<Contact>? contacts;
private Contact? selectedContact;
private Quote? selectedQuote;
private readonly IList<Contact> contacts = new List<Contact>();
private Contact selectedContact = new();
private Quote selectedQuote = new();
[CascadingParameter] private Task<AuthenticationState>? AuthenticationStateTask { get; set; }
protected override async Task OnInitializedAsync() {
if (AuthenticationStateTask != null) {
ClaimsPrincipal user = (await AuthenticationStateTask).User;
if (user.Identity is { IsAuthenticated: true }) contacts = await GenericController.GetAllAsync<Contact>();
if (user.Identity is{ IsAuthenticated: true }) {
contacts.AddRange(await GenericController.GetAllAsync<Contact>());
selectedContact = contacts.First();
}
}
await base.OnInitializedAsync();
}
private async Task OnSelectedContactChanged(Contact selectedContact) {
if (selectedContact != null) {
this.selectedContact = selectedContact;
this.selectedContact.Quotes = await GenericController.GetAllAsync<Quote>(q => q.RecipientId.Equals(this.selectedContact.ContactId));
}
private async Task OnSelectedContactChanged(Contact newSelectedContact) {
selectedContact = newSelectedContact;
selectedContact.Quotes = await GenericController.GetAllAsync<Quote>(q => q.RecipientId.Equals(selectedContact.ContactId));
}
private async Task OnSelectedQuoteChanged(Quote selectedQuote) {
if (selectedQuote != null) {
this.selectedQuote = selectedQuote;
this.selectedQuote.LineItems = await GenericController.GetAllAsync<LineItem>(lI => lI.QuoteId.Equals(this.selectedQuote.QuoteId));
}
private async Task OnSelectedQuoteChanged(Quote newSelectedQuote) {
selectedQuote = newSelectedQuote;
selectedQuote.LineItems = await GenericController.GetAllAsync<LineItem>(lI => lI.QuoteId.Equals(selectedQuote.QuoteId));
}
private async Task OnRowInsertedAsync(SavedRowItem<Contact, Dictionary<string, object>> contact) {
Contact newContact = await ResolveContactAsync(contact.Item);
if (newContact.Account == null)
return;
// if (newContact.Account is null) return;
int count = await GenericController.InsertAsync(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 == null)
return;
// if (newContact.Account is null) return;
int count = await GenericController.UpdateAsync(contact.Item);
Console.WriteLine($"Updated {count} properties in contact {newContact.ContactId}: {newContact.FirstName} {newContact.LastName}.");
}
@ -64,9 +60,9 @@ public partial class Contacts {
}
private async Task<Contact> ResolveContactAsync(Contact newContact) {
newContact.Account = await GenericController.ResolveAccountById(newContact.AccountId);
// newContact.Account = await GenericController.ResolveAccountById(newContact.AccountId);
if (newContact.Account != null) {
if (newContact.Account is not null) {
newContact.NoPhoneCalls = false;
newContact.EmailBounced = false;
newContact.NoHardcopyMailing = false;

@ -2,6 +2,7 @@ using System.Security.Claims;
using Blazorise;
using Blazorise.DataGrid;
using Gremlin_BlazorServer.Data.EntityClasses;
using Gremlin_BlazorServer.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;

@ -3,6 +3,7 @@
@using Gremlin_BlazorServer.Data.EntityClasses
@inject GenericController GenericController
@inject ILoadingIndicatorService ApplicationLoadingIndicatorService
<AuthorizeView>
<Authorized Context="auth">

@ -3,23 +3,33 @@ using System.Security.Claims;
using Gremlin_BlazorServer.Data.EntityClasses;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;
using NuGet.Packaging;
namespace Gremlin_BlazorServer.Pages;
public partial class LineItems {
private readonly CultureInfo cultureInfo = new("de-DE");
private IList<LineItem>? lineItems;
private LineItem? selectedLineItem;
private readonly IList<LineItem> lineItems=new List<LineItem>();
private LineItem selectedLineItem = new();
[CascadingParameter] private Task<AuthenticationState>? AuthenticationStateTask { get; set; }
protected override async Task OnInitializedAsync() {
if (AuthenticationStateTask != null) {
ClaimsPrincipal user = (await AuthenticationStateTask).User;
if (user.Identity is { IsAuthenticated: true }) lineItems = GenericController.GetAll<LineItem>();
if (user.Identity is{ IsAuthenticated: true }) {
await ApplicationLoadingIndicatorService.Show();
lineItems.AddRange(await GenericController.GetAllAsync<LineItem>());
selectedLineItem = lineItems.First();
await OnSelectedLineItemChanged(selectedLineItem);
await ApplicationLoadingIndicatorService.Hide();
}
}
}
private void OnSelectedLineItemChanged(LineItem newSelectedLineItem) => selectedLineItem = newSelectedLineItem;
private async Task OnSelectedLineItemChanged(LineItem newSelectedLineItem) {
await ApplicationLoadingIndicatorService.Show();
selectedLineItem = newSelectedLineItem;
await ApplicationLoadingIndicatorService.Hide();
}
}

@ -1,49 +1,51 @@
using System.Security.Claims;
using Blazorise.DataGrid;
using Gremlin_BlazorServer.Data.EntityClasses;
using Gremlin_BlazorServer.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;
using NuGet.Packaging;
namespace Gremlin_BlazorServer.Pages;
public partial class ProductLines {
private IList<ProductLine>? productLines;
private ProductLine? selectedProductLine;
private readonly IList<ProductLine> productLines = new List<ProductLine>();
private ProductLine selectedProductLine = new();
[CascadingParameter] private Task<AuthenticationState>? AuthenticationStateTask { get; set; }
protected override async Task OnParametersSetAsync() {
if (AuthenticationStateTask != null) {
ClaimsPrincipal user = (await AuthenticationStateTask).User;
if (user.Identity is { IsAuthenticated: true }) productLines = await GenericController.GetAllAsync<ProductLine>();
if (user.Identity is{ IsAuthenticated: true }) {
await ApplicationLoadingIndicatorService.Show();
productLines.AddRange(await GenericController.GetAllAsync<ProductLine>());
selectedProductLine = productLines.First();
await ApplicationLoadingIndicatorService.Hide();
}
await base.OnInitializedAsync();
}
}
private async Task OnSelectedProductLineChanged(ProductLine newSelectedProductLine) {
await ApplicationLoadingIndicatorService.Show();
selectedProductLine = await GenericController.GetAsync<ProductLine>(pL => pL.ProductLineCode == newSelectedProductLine.ProductLineCode, "Products");
selectedProductLine = await GenericController.GetAsync<ProductLine>(pL => pL.ProductLineCode.Equals(newSelectedProductLine.ProductLineCode), "Products");
await ApplicationLoadingIndicatorService.Hide();
}
private async Task OnRowInsertedAsync(SavedRowItem<ProductLine, Dictionary<string, object>> productLine) {
ProductLine newProductLine = await ResolveProductAsync(productLine.Item);
if (newProductLine.ProductLineCode == null)
return;
int count = await GenericController.InsertAsync(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);
if (newProductLine.ProductLineCode == null)
return;
int count = await GenericController.UpdateAsync(productLine.Item);
Console.WriteLine($"Updated {count} properties in ProductLine {newProductLine.ProductLineCode}.");
}
private async Task OnRowRemovedAsync(ProductLine productLine) {
private static async Task OnRowRemovedAsync(ProductLine productLine) {
int count = await GenericController.RemoveAsync(productLine);
Console.WriteLine($"Removed {count} properties and ProductLine {productLine.ProductLineCode}.");
}
@ -51,7 +53,7 @@ public partial class ProductLines {
private async Task<ProductLine> ResolveProductAsync(ProductLine newProductLine) {
newProductLine.DataModificationByUser = "Gremlin Blazor Server GUI";
newProductLine.DataVersionNumber++;
newProductLine.Products = await GenericController.GetAllAsync<Product>(p => p.ProductLineCode == newProductLine.ProductLineCode);
newProductLine.Products = await GenericController.GetAllAsync<Product>(p => p.ProductLineCode.Equals(newProductLine.ProductLineCode));
return newProductLine;
}
}

@ -1,5 +1,6 @@
using System.Security.Claims;
using Gremlin_BlazorServer.Data.EntityClasses;
using Gremlin_BlazorServer.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;

@ -7,32 +7,33 @@ using Gremlin_BlazorServer.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.JSInterop;
using NuGet.Packaging;
namespace Gremlin_BlazorServer.Pages.Quotes;
public partial class QuoteAdd {
private static CustomDescription newCustomDescription;
private static readonly CustomDescription newCustomDescription = new();
private readonly CultureInfo cultureInfo = new("de-DE");
private readonly bool debug;
private const bool debug = true;
private IList<Contact>? contacts;
private IList<Contact> contacts = new List<Contact>();
private bool isCreatingPdf;
private bool isCreatingTex;
private bool lineItemsNotReady = true;
private bool pdfNotReady = true;
private Quote quote = new();
private Contact? selectedContact;
private Contact selectedContact = new();
private LineItem? selectedLineItem;
private LineItem selectedLineItem = new();
// private List<CustomDescription>? suggestedCustomDescriptions;
private bool texNotReady = true;
private string? url;
private string url = string.Empty;
[CascadingParameter] private Task<AuthenticationState>? AuthenticationStateTask { get; set; }
[Inject] public static IModalService ModalService { get; set; }
[Inject] public static IModalService? ModalService { get; set; }
public static Task ShowCustomDescriptionModal(List<CustomDescription> suggestedCustomDescriptions) {
return ModalService.Show<CustomDescriptionModal>(builder => {
public static Task? ShowCustomDescriptionModal(List<CustomDescription> suggestedCustomDescriptions) {
return ModalService?.Show<CustomDescriptionModal>(builder => {
builder.Add(parameter => parameter.CustomDescription, newCustomDescription);
builder.Add(parameter => parameter.SuggestedCustomDescriptions, suggestedCustomDescriptions);
});
@ -42,20 +43,10 @@ public partial class QuoteAdd {
if (AuthenticationStateTask is not null) {
ClaimsPrincipal user = (await AuthenticationStateTask).User;
if (user.Identity is { IsAuthenticated: true }) {
contacts = await GenericController.GetAllAsync<Contact>();
selectedContact = contacts?.FirstOrDefault();
if (selectedContact is not null)
await SelectedContactChanged(selectedContact);
SalesRep newSalesRep = new() {
LastName = "Woitschetzki",
FirstName = "Sascha",
TerritoryId = "83PE89",
PhoneNumber = "+49 176 22285334",
EMail = "sascha.woitschetzki@non.agilent.com",
AccountId = 2262,
Gender = 1
};
contacts.AddRange(await GenericController.GetAllAsync<Contact>());
selectedContact = contacts.First();
SalesRep newSalesRep = await GenericController.GetAsync<SalesRep>(sr => sr.FirstName.Equals("Sascha"));
quote = await GenerateNewQuote(quote, newSalesRep);
}
@ -65,12 +56,12 @@ public partial class QuoteAdd {
}
private async Task<Quote> GenerateNewQuote(Quote newQuote, SalesRep newSalesRep) {
newQuote.SalesRep = newSalesRep; //await genericController.GetAsync<SalesRep>(sR => sR.LastName.Equals(newSalesRep.LastName));
newQuote.SalesRep.Account = await GenericController.GetAsync<Account>(a => a.AccountId.Equals(newQuote.SalesRep.AccountId));
newQuote.SalesRep = await GenericController.GetAsync<SalesRep>(sR => sR.LastName.Equals(newSalesRep.LastName));
// newQuote.SalesRep.Account = await GenericController.GetAsync<Account>(a => a.AccountId.Equals(newQuote.SalesRep.AccountId));
Quote? lastQuote = GenericController.GetLast<Quote>();
newQuote.QuoteId = lastQuote is not null ? lastQuote.QuoteId + 1 : 1;
newQuote.QuotationNumber = $"DE-{newQuote.SalesRep?.TerritoryId}-{DateTime.Now:My}-{newQuote.QuoteId}";
Quote lastQuote = await GenericController.GetLastAsync<Quote>();
newQuote.QuoteId = lastQuote.QuoteId + 1;
newQuote.QuotationNumber = $"DE-{newQuote.SalesRep.TerritoryId}-{DateTime.Now:My}-{newQuote.QuoteId}";
newQuote.Description = "Gerät";
return newQuote;
@ -92,7 +83,7 @@ public partial class QuoteAdd {
Console.WriteLine(exc.Message);
}
finally {
if (quote.Recipient != null) lineItemsNotReady = false;
lineItemsNotReady = false;
StateHasChanged();
}
}
@ -105,16 +96,13 @@ public partial class QuoteAdd {
Console.WriteLine($"File: {e.File.Name} Progress: {e.Percentage}");
}
private async Task SelectedContactChanged(Contact newSelectedContact) {
quote.Recipient = await GenericController.GetAsync<Contact>(c => c.ContactId.Equals(newSelectedContact.ContactId));
if (quote.Recipient is not null)
//Read account seperatly to avoid new generation
quote.Recipient.Account = await GenericController.GetAsync<Account>(a => a.AccountId.Equals(quote.Recipient.AccountId));
private Task SelectedContactChanged(Contact newSelectedContact) {
quote.RecipientId = newSelectedContact.ContactId;
// quote.Recipient = await GenericController.GetAsync<Contact>(c => c.ContactId.Equals(newSelectedContact.ContactId));
// quote.Recipient.Account = await GenericController.GetAsync<Account>(a => a.AccountId.Equals(quote.Recipient.AccountId));
if (quote is { LineItems: not null, Recipient.Account: not null }) lineItemsNotReady = false;
selectedContact = newSelectedContact;
return Task.CompletedTask;
}
private async Task OnSave() {

@ -1,6 +1,7 @@
using System.Globalization;
using System.Security.Claims;
using Gremlin_BlazorServer.Data.EntityClasses;
using Gremlin_BlazorServer.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;

@ -6,9 +6,11 @@ using Microsoft.EntityFrameworkCore.ChangeTracking;
namespace Gremlin_BlazorServer.Services;
public class GenericController {
private static readonly GremlinDb gremlinDb = new();
public IList<TResult>? GetAll<TResult>() where TResult : class, IMetadata {
try {
using (GremlinDb gremlinDb = new()) return gremlinDb.Set<TResult>().ToList();
return gremlinDb.Set<TResult>().ToList();
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
@ -18,7 +20,7 @@ public class GenericController {
public IList<TResult>? GetAll<TResult>(string include) where TResult : class, IMetadata {
try {
using (GremlinDb gremlinDb = new()) return gremlinDb.Set<TResult>().Include(include).ToList();
return gremlinDb.Set<TResult>().Include(include).ToList();
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
@ -29,7 +31,7 @@ public class GenericController {
public IList<TResult>? GetAll<TResult>(Predicate<TResult> search) where TResult : class, IMetadata {
ArgumentNullException.ThrowIfNull(search);
try {
using (GremlinDb gremlinDb = new()) return gremlinDb.Set<TResult>().AsEnumerable().Where(t => search(t)).ToList();
return gremlinDb.Set<TResult>().AsEnumerable().Where(t => search(t)).ToList();
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
@ -39,7 +41,7 @@ public class GenericController {
public async Task<IList<TResult>?> GetAllAsync<TResult>() where TResult : class, IMetadata {
try {
await using (GremlinDb gremlinDb = new()) return await gremlinDb.Set<TResult>().ToListAsync();
return await gremlinDb.Set<TResult>().ToListAsync();
}
catch (DbUpdateConcurrencyException exception) {
await HandleDbUpdateConcurrencyException<TResult>(exception);
@ -50,7 +52,7 @@ public class GenericController {
public async Task<IList<TResult>?> GetAllAsync<TResult>(string include) where TResult : class, IMetadata {
try {
await using (GremlinDb gremlinDb = new()) return await gremlinDb.Set<TResult>().Include(include).ToListAsync();
return await gremlinDb.Set<TResult>().Include(include).ToListAsync();
}
catch (DbUpdateConcurrencyException exception) {
await HandleDbUpdateConcurrencyException<TResult>(exception);
@ -61,7 +63,7 @@ public class GenericController {
public async Task<IList<TResult>?> GetAllAsync<TResult>(string include1, string include2) where TResult : class, IMetadata {
try {
await using (GremlinDb gremlinDb = new()) return await gremlinDb.Set<TResult>().Include(include1).Include(include2).ToListAsync();
return await gremlinDb.Set<TResult>().Include(include1).Include(include2).ToListAsync();
}
catch (DbUpdateConcurrencyException exception) {
await HandleDbUpdateConcurrencyException<TResult>(exception);
@ -73,7 +75,7 @@ public class GenericController {
public async Task<IList<TResult>?> GetAllAsync<TResult>(Predicate<TResult> search) where TResult : class, IMetadata {
ArgumentNullException.ThrowIfNull(search);
try {
await using (GremlinDb gremlinDb = new()) return await Task.Run(() => gremlinDb.Set<TResult>().AsEnumerable().Where(t => search(t)).ToList());
return await Task.Run(() => gremlinDb.Set<TResult>().AsEnumerable().Where(t => search(t)).ToList());
}
catch (DbUpdateConcurrencyException exception) {
await HandleDbUpdateConcurrencyException<TResult>(exception);
@ -85,7 +87,7 @@ public class GenericController {
public async Task<IList<TResult>?> GetAllAsync<TResult>(Predicate<TResult> search, string include) where TResult : class, IMetadata {
ArgumentNullException.ThrowIfNull(search);
try {
await using (GremlinDb gremlinDb = new()) return await Task.Run(() => gremlinDb.Set<TResult>().Include(include).AsEnumerable().Where(t => search(t)).ToList());
return await Task.Run(() => gremlinDb.Set<TResult>().Include(include).AsEnumerable().Where(t => search(t)).ToList());
}
catch (DbUpdateConcurrencyException exception) {
await HandleDbUpdateConcurrencyException<TResult>(exception);
@ -94,118 +96,114 @@ public class GenericController {
}
}
public IList<TResult>? GetAll<TResult>(Predicate<TResult> search, string include) where TResult : class, IMetadata {
ArgumentNullException.ThrowIfNull(search);
try {
using (GremlinDb gremlinDb = new()) return gremlinDb.Set<TResult>().Include(include).AsEnumerable().Where(t => search(t)).ToList();
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
return null;
}
}
// public IList<TResult>? GetAll<TResult>(Predicate<TResult> search, string include) where TResult : class, IMetadata {
// ArgumentNullException.ThrowIfNull(search);
// try {
// return gremlinDb.Set<TResult>().Include(include).AsEnumerable().Where(t => search(t)).ToList();
// }
// catch (Exception exception) {
// Console.WriteLine(exception.InnerException);
// return null;
// }
// }
public TResult? Get<TResult>(Predicate<TResult> search) where TResult : class, IMetadata {
ArgumentNullException.ThrowIfNull(search);
try {
using (GremlinDb gremlinDb = new()) return gremlinDb.Set<TResult>().AsEnumerable().FirstOrDefault(t => search(t));
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
return null;
}
}
// public TResult? Get<TResult>(Predicate<TResult> search) where TResult : class, IMetadata {
// ArgumentNullException.ThrowIfNull(search);
// try {
// using GremlinDb gremlinDb = new();
// return gremlinDb.Set<TResult>().AsEnumerable().FirstOrDefault(t => search(t));
// }
// catch (Exception exception) {
// Console.WriteLine(exception.InnerException);
// return null;
// }
// }
public async Task<TResult?> GetAsync<TResult>(Predicate<TResult> search) where TResult : class, IMetadata {
ArgumentNullException.ThrowIfNull(search);
public static async Task<TResult> GetAsync<TResult>(Predicate<TResult> search) where TResult : class, IMetadata, new() {
try {
await using (GremlinDb gremlinDb = new()) return await Task.Run(() => gremlinDb.Set<TResult>().AsEnumerable().FirstOrDefault(t => search(t)));
return await Task.Run(() => gremlinDb.Set<TResult>().AsEnumerable().First(t => search(t)));
}
catch (DbUpdateConcurrencyException exception) {
await HandleDbUpdateConcurrencyException<TResult>(exception);
Console.WriteLine(exception.InnerException);
return null;
catch (Exception e) {
Console.WriteLine(e.InnerException);
return new();
}
}
public TResult? Get<TResult>(Predicate<TResult> search, string include) where TResult : class, IMetadata {
ArgumentNullException.ThrowIfNull(search);
try {
using (GremlinDb gremlinDb = new()) return gremlinDb.Set<TResult>().AsNoTracking().Include(include).AsEnumerable().FirstOrDefault(t => search(t));
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
return null;
}
}
// public TResult? Get<TResult>(Predicate<TResult> search, string include) where TResult : class, IMetadata {
// ArgumentNullException.ThrowIfNull(search);
// try {
// using GremlinDb gremlinDb = new();
// return gremlinDb.Set<TResult>().AsNoTracking().Include(include).AsEnumerable().FirstOrDefault(t => search(t));
// }
// catch (Exception exception) {
// Console.WriteLine(exception.InnerException);
// return null;
// }
// }
public async Task<TResult?> GetAsync<TResult>(Predicate<TResult> search, string include1) where TResult : class, IMetadata {
public async Task<TResult> GetAsync<TResult>(Predicate<TResult> search, string include1) where TResult : class, IMetadata, new() {
ArgumentNullException.ThrowIfNull(search);
try {
await using (GremlinDb gremlinDb = new()) return await Task.Run(() => gremlinDb.Set<TResult>().Include(include1).AsEnumerable().FirstOrDefault(t => search(t)));
return await Task.Run(() => gremlinDb.Set<TResult>().Include(include1).AsEnumerable().First(t => search(t)));
}
catch (DbUpdateConcurrencyException exception) {
await HandleDbUpdateConcurrencyException<TResult>(exception);
Console.WriteLine(exception.InnerException);
return null;
return new();
}
}
public async Task<TResult?> GetAsync<TResult>(Predicate<TResult> search, string include1, string include2) where TResult : class, IMetadata {
public async Task<TResult> GetAsync<TResult>(Predicate<TResult> search, string include1, string include2) where TResult : class, IMetadata, new() {
ArgumentNullException.ThrowIfNull(search);
try {
await using (GremlinDb gremlinDb = new()) return await Task.Run(() => gremlinDb.Set<TResult>().Include(include1).Include(include2).AsEnumerable().FirstOrDefault(t => search(t)));
return await Task.Run(() => gremlinDb.Set<TResult>().Include(include1).Include(include2).AsEnumerable().First(t => search(t)));
}
catch (DbUpdateConcurrencyException exception) {
await HandleDbUpdateConcurrencyException<TResult>(exception);
Console.WriteLine(exception.InnerException);
return null;
return new();
}
}
public TResult? GetLast<TResult>() where TResult : class, IMetadata {
public static async Task<TResult> GetLastAsync<TResult>() where TResult : class, IMetadata, new() {
try {
using (GremlinDb gremlinDb = new()) return gremlinDb.Set<TResult>().AsEnumerable().Last();
return await Task.Run(() => gremlinDb.Set<TResult>().AsEnumerable().Last());
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
return null;
return new();
}
}
public int Insert<T>(T entity) where T : class, IMetadata {
try {
using (GremlinDb gremlinDb = new()) {
gremlinDb.Set<T>().Add(entity);
return gremlinDb.SaveChanges();
}
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
return 0;
}
}
// public int Insert<T>(T entity) where T : class, IMetadata {
// try {
// using GremlinDb gremlinDb = new();
// gremlinDb.Set<T>().Add(entity);
// return gremlinDb.SaveChanges();
// }
// catch (Exception exception) {
// Console.WriteLine(exception.InnerException);
// return 0;
// }
// }
public int Insert<T>(IEnumerable<T> entities) where T : class, IMetadata {
try {
using (GremlinDb gremlinDb = new()) {
gremlinDb.Set<T>().AddRange(entities);
return gremlinDb.SaveChanges();
}
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
return 0;
}
}
// public int Insert<T>(IEnumerable<T> entities) where T : class, IMetadata {
// try {
// using GremlinDb gremlinDb = new();
// gremlinDb.Set<T>().AddRange(entities);
// return gremlinDb.SaveChanges();
// }
// catch (Exception exception) {
// Console.WriteLine(exception.InnerException);
// return 0;
// }
// }
public async Task<int> InsertAsync<T>(T entity) where T : class, IMetadata {
try {
await using (GremlinDb gremlinDb = new()) {
gremlinDb.Set<T>().Add(entity);
return await gremlinDb.SaveChangesAsync();
}
}
catch (DbUpdateConcurrencyException exception) {
await HandleDbUpdateConcurrencyException<T>(exception);
Console.WriteLine(exception.InnerException);
@ -215,11 +213,9 @@ public class GenericController {
public async Task<int> InsertAsync<T>(IEnumerable<T> entities) where T : class, IMetadata {
try {
await using (GremlinDb gremlinDb = new()) {
gremlinDb.Set<T>().AddRange(entities);
return await gremlinDb.SaveChangesAsync();
}
}
catch (DbUpdateConcurrencyException exception) {
await HandleDbUpdateConcurrencyException<T>(exception);
Console.WriteLine(exception.InnerException);
@ -227,10 +223,9 @@ public class GenericController {
}
}
public static bool IsExisting<T>(Predicate<T> search) where T : class, IMetadata {
ArgumentNullException.ThrowIfNull(search);
public static async Task<bool> IsExistingAsync<T>(Predicate<T> search) where T : class, IMetadata {
try {
using (GremlinDb gremlinDb = new()) return gremlinDb.Set<T>().AsEnumerable().Any(t => search(t));
return await Task.Run(() => gremlinDb.Set<T>().AsEnumerable().Any(t => search(t)));
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
@ -238,21 +233,19 @@ public class GenericController {
}
}
public int Update<T>(T entity) where T : class, IMetadata {
try {
using (GremlinDb gremlinDb = new()) {
gremlinDb.Set<T>().Update(entity);
return gremlinDb.SaveChanges();
}
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
return 0;
}
}
// public int Update<T>(T entity) where T : class, IMetadata {
// try {
// using GremlinDb gremlinDb = new();
// gremlinDb.Set<T>().Update(entity);
// return gremlinDb.SaveChanges();
// }
// catch (Exception exception) {
// Console.WriteLine(exception.InnerException);
// return 0;
// }
// }
public async Task<int> UpdateAsync<T>(T entity) where T : class, IMetadata {
await using (GremlinDb gremlinDb = new()) {
try {
gremlinDb.Set<T>().Update(entity);
return await gremlinDb.SaveChangesAsync(false);
@ -263,19 +256,17 @@ public class GenericController {
return 0;
}
}
}
private async Task HandleDbUpdateConcurrencyException<T>(DbUpdateConcurrencyException exception) where T : class, IMetadata {
private static async Task HandleDbUpdateConcurrencyException<T>(DbUpdateConcurrencyException exception) where T : class, IMetadata {
// Loop through the entities that caused the concurrency conflict
foreach (EntityEntry? entry in exception.Entries) {
if (entry.Entity is T) {
T? clientValues = (T)entry.Entity;
if (entry.Entity is not T clientValues) throw new NotSupportedException($"Concurrency conflicts for entities of type {entry.Entity.GetType().Name} are not supported.");
PropertyValues? databaseEntry = await entry.GetDatabaseValuesAsync();
if (databaseEntry is null)
// The record has been deleted from the database
// Notify the user or handle the error in some other way
throw new("The record has been deleted from the database.");
T? databaseValues = (T)databaseEntry.ToObject();
T databaseValues = (T)databaseEntry.ToObject();
// Compare the database values with the client values
if (databaseValues.DataVersionNumber != clientValues.DataVersionNumber)
// The name has been changed by another user
@ -284,60 +275,57 @@ public class GenericController {
// The conflict is caused by a property other than the name
// Notify the user or handle the error in some other way
throw new("A concurrency conflict occurred.");
}
// Handle concurrency conflicts for other entity types, if necessary
throw new NotSupportedException($"Concurrency conflicts for entities of type {entry.Entity.GetType().Name} are not supported.");
}
}
public int Update<T>(IEnumerable<T> entities) where T : class, IMetadata {
try {
using (GremlinDb gremlinDb = new()) {
gremlinDb.Set<T>().UpdateRange(entities);
return gremlinDb.SaveChanges();
}
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
return 0;
}
}
// public int Update<T>(IEnumerable<T> entities) where T : class, IMetadata {
// try {
// using GremlinDb gremlinDb = new();
// gremlinDb.Set<T>().UpdateRange(entities);
// return gremlinDb.SaveChanges();
// }
// catch (Exception exception) {
// Console.WriteLine(exception.InnerException);
// return 0;
// }
// }
public async Task<int> UpdateAsync<T>(IEnumerable<T> entities) where T : class, IMetadata {
public static async Task<int> UpdateAsync<T>(IEnumerable<T> entities) where T : class, IMetadata {
try {
await using (GremlinDb gremlinDb = new()) {
gremlinDb.Set<T>().UpdateRange(entities);
await Task.Run(() => gremlinDb.Set<T>().UpdateRange(entities));
return await gremlinDb.SaveChangesAsync();
}
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
return 0;
}
}
public async Task<int> RemoveAsync<T>(T entity) where T : class, IMetadata {
public static async Task<int> RemoveAsync<T>(T entity) where T : class, IMetadata {
try {
await using (GremlinDb gremlinDb = new()) {
gremlinDb.Set<T>().Remove(entity);
await Task.Run(() => gremlinDb.Set<T>().Remove(entity));
return await gremlinDb.SaveChangesAsync();
}
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
return 0;
}
}
public async Task<Account> ResolveAccountById(uint accountId){
try {
await using (GremlinDb gremlinDb = new()) {
return gremlinDb.Accounts.First(a => a.AccountId.Equals(accountId));
}
}
catch {
return new Account();
}
}
// public async Task<Account?> ResolveAccountById(uint accountId){
// try {
//
// if (gremlinDb.Accounts != null)
// return gremlinDb.Accounts.First(a => a.AccountId.Equals(accountId));
// else {
// return null;
// }
// }
// catch (Exception exception){
// Console.WriteLine(exception.InnerException);
// return null;
// }
// }
}

@ -11,15 +11,13 @@ public class GenericImporter {
Console.WriteLine("Importing accounts from csv...");
IList<string[]> splitLines = await Task.Run(() => SplitLines(fileContent));
if (typeof(T) == typeof(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.");
if (typeof(T) != typeof(Account)) return false;
await ParseListToAccounts(splitLines);
int countNewAccounts = await genericController.InsertAsync(newAccounts);
int countUpdatedAccounts = await GenericController.UpdateAsync(updatedAccounts);
Console.WriteLine($"Added {countNewAccounts} new Accounts to database and updated {countUpdatedAccounts} Accounts.");
return countNewAccounts > 0 || updatedAccounts.Count > 0;
}
return false;
}
private static IList<string[]> SplitLines(string fileContent) {
@ -30,14 +28,11 @@ public class GenericImporter {
return fileList;
}
private void ParseListToAccounts(IList<string[]> lineList) // ID;Acct Name 1 and 2;Street;City;BP Role;Postal Code;Customer Type;Market Indicator;
private async Task ParseListToAccounts(IList<string[]> lineList) // ID;Acct Name 1 and 2;Street;City;BP Role;Postal Code;Customer Type;Market Indicator;
{
List<Account> existingAccounts = new();
foreach (string[] line in lineList) {
if (!line[0].Contains("ID")) //HACK: skip first row if header
if (uint.TryParse(line[0], out uint sapAccountNumber) && uint.TryParse(line[5], out uint zip)) //HACK: skip lines with wrong uint
{
if (line[0].Contains("ID")) continue; //HACK: skip first row if header
if (!uint.TryParse(line[0], out uint sapAccountNumber) || !uint.TryParse(line[5], out uint zip)) continue; //HACK: skip lines with wrong uint
Account readAccount = new() {
SapAccountNumber = sapAccountNumber,
AccountName = line[1],
@ -52,23 +47,19 @@ public class GenericImporter {
DataModificationByUser = "Gremlin Generic Importer"
};
AccountType? accountType = genericController.Get<AccountType>(aT => aT.AccountTypeCode == line[6]);
if (accountType == null) continue;
AccountType accountType = await GenericController.GetAsync<AccountType>(aT => aT.AccountTypeCode == line[6]);
readAccount.AccountType.AccountTypeCode = accountType.AccountTypeCode;
readAccount.AccountType = genericController.Get<AccountType>(aT => aT.AccountTypeCode == readAccount.AccountType.AccountTypeCode);
readAccount.AccountType = await GenericController.GetAsync<AccountType>(aT => aT.AccountTypeCode == readAccount.AccountType.AccountTypeCode);
SubMarket? subMarket = genericController.Get<SubMarket>(sM => sM.SubMarketCode == line[7]);
if (subMarket == null) continue;
SubMarket subMarket = await GenericController.GetAsync<SubMarket>(sM => sM.SubMarketCode == line[7]);
readAccount.SubMarket.SubMarketCode = subMarket.SubMarketCode;
readAccount.SubMarket = genericController.Get<SubMarket>(sM => sM.SubMarketCode == readAccount.SubMarket.SubMarketCode);
readAccount.SubMarket = await GenericController.GetAsync<SubMarket>(sM => sM.SubMarketCode == readAccount.SubMarket.SubMarketCode);
if (readAccount?.SubMarket?.SubMarketCode == null || readAccount?.AccountType?.AccountTypeCode == null) continue; //HACK: skip Accounts with no SubMarket or AccountType
if (readAccount.SubMarket?.SubMarketCode is null || readAccount.AccountType?.AccountTypeCode is 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)) {
if (await AccountExists(sapAccountNumber)) {
Account existingAccount = await GenericController.GetAsync<Account>(a => a.SapAccountNumber.Equals(readAccount.SapAccountNumber));
if (IsEqualAccount(readAccount, existingAccount)) continue;
existingAccount.DataModificationDate = DateTime.Now;
existingAccount.DataVersionNumber++;
existingAccount.DataModificationByUser = "Updated by Gremlin Generic Importer";
@ -82,17 +73,13 @@ public class GenericImporter {
Console.WriteLine($"Update in Account {existingAccount.SapAccountNumber}:{existingAccount.AccountName}");
updatedAccounts.Add(existingAccount);
}
}
else {
newAccounts.Add(readAccount);
}
}
}
}
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 bool AccountExists(uint sapAccountNumber) {
return GenericController.IsExisting<Account>(a => a.SapAccountNumber == sapAccountNumber);
}
private async Task<bool> AccountExists(uint sapAccountNumber) => await GenericController.IsExistingAsync<Account>(a => a.SapAccountNumber.Equals(sapAccountNumber));
}

@ -185,7 +185,7 @@ public class QuoteHandling {
//TODO Load all relevant CustomDescriptions upfront
foreach (LineItem lineItem in quote.LineItems) {
CustomDescription newCustomDescription = await genericController.GetAsync<CustomDescription>(newCustomDescription => newCustomDescription.ProductNumber.Equals(lineItem.ProductNumber, StringComparison.Ordinal) && newCustomDescription.OptionNumber.Equals(lineItem.OptionNumber, StringComparison.Ordinal));
CustomDescription newCustomDescription = await GenericController.GetAsync<CustomDescription>(newCustomDescription => newCustomDescription.ProductNumber.Equals(lineItem.ProductNumber, StringComparison.Ordinal) && newCustomDescription.OptionNumber.Equals(lineItem.OptionNumber, StringComparison.Ordinal));
if (newCustomDescription is null) {
Console.WriteLine($"Keine CustomDescription für {lineItem.ProductNumber}#{lineItem.OptionNumber} verfügbar!");
@ -201,10 +201,10 @@ public class QuoteHandling {
_ = await genericController.InsertAsync(newCustomDescription);
}
lineItem.Product = await genericController.GetAsync<Product>(p => p.ProductNumber.Equals(lineItem.ProductNumber) && p.OptionNumber.Equals(lineItem.OptionNumber));
lineItem.Product = await GenericController.GetAsync<Product>(p => p.ProductNumber.Equals(lineItem.ProductNumber) && p.OptionNumber.Equals(lineItem.OptionNumber));
if (lineItem.Product is null) return quote;
lineItem.ProductId = lineItem.Product.ProductId;
lineItem.Product.CustomDescription = await genericController.GetAsync<CustomDescription>(cD => cD.ProductNumber.Equals(lineItem.ProductNumber) && cD.OptionNumber.Equals(lineItem.OptionNumber));
lineItem.Product.CustomDescription = await GenericController.GetAsync<CustomDescription>(cD => cD.ProductNumber.Equals(lineItem.ProductNumber) && cD.OptionNumber.Equals(lineItem.OptionNumber));
lineItem.Quote = quote;
lineItem.QuoteId = lineItem.Quote.QuoteId;
}