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 SubMarket? SubMarket { get; set; }
public IList<Contact>? Contacts { 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; } // public IList<CustomDescription>? CustomDescriptions { get; set; }
//class properties: //class properties:

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

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

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

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

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

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

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

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

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

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

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

@ -3,23 +3,33 @@ using System.Security.Claims;
using Gremlin_BlazorServer.Data.EntityClasses; using Gremlin_BlazorServer.Data.EntityClasses;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Components.Authorization;
using NuGet.Packaging;
namespace Gremlin_BlazorServer.Pages; namespace Gremlin_BlazorServer.Pages;
public partial class LineItems { public partial class LineItems {
private readonly CultureInfo cultureInfo = new("de-DE"); private readonly CultureInfo cultureInfo = new("de-DE");
private IList<LineItem>? lineItems; private readonly IList<LineItem> lineItems=new List<LineItem>();
private LineItem? selectedLineItem; private LineItem selectedLineItem = new();
[CascadingParameter] private Task<AuthenticationState>? AuthenticationStateTask { get; set; } [CascadingParameter] private Task<AuthenticationState>? AuthenticationStateTask { get; set; }
protected override async Task OnInitializedAsync() { protected override async Task OnInitializedAsync() {
if (AuthenticationStateTask != null) { if (AuthenticationStateTask != null) {
ClaimsPrincipal user = (await AuthenticationStateTask).User; 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 System.Security.Claims;
using Blazorise.DataGrid; using Blazorise.DataGrid;
using Gremlin_BlazorServer.Data.EntityClasses; using Gremlin_BlazorServer.Data.EntityClasses;
using Gremlin_BlazorServer.Services;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Components.Authorization;
using NuGet.Packaging;
namespace Gremlin_BlazorServer.Pages; namespace Gremlin_BlazorServer.Pages;
public partial class ProductLines { public partial class ProductLines {
private IList<ProductLine>? productLines; private readonly IList<ProductLine> productLines = new List<ProductLine>();
private ProductLine? selectedProductLine; private ProductLine selectedProductLine = new();
[CascadingParameter] private Task<AuthenticationState>? AuthenticationStateTask { get; set; } [CascadingParameter] private Task<AuthenticationState>? AuthenticationStateTask { get; set; }
protected override async Task OnParametersSetAsync() { protected override async Task OnParametersSetAsync() {
if (AuthenticationStateTask != null) { if (AuthenticationStateTask != null) {
ClaimsPrincipal user = (await AuthenticationStateTask).User; 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(); await base.OnInitializedAsync();
} }
} }
private async Task OnSelectedProductLineChanged(ProductLine newSelectedProductLine) { private async Task OnSelectedProductLineChanged(ProductLine newSelectedProductLine) {
await ApplicationLoadingIndicatorService.Show(); 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(); await ApplicationLoadingIndicatorService.Hide();
} }
private async Task OnRowInsertedAsync(SavedRowItem<ProductLine, Dictionary<string, object>> productLine) { private async Task OnRowInsertedAsync(SavedRowItem<ProductLine, Dictionary<string, object>> productLine) {
ProductLine newProductLine = await ResolveProductAsync(productLine.Item); ProductLine newProductLine = await ResolveProductAsync(productLine.Item);
if (newProductLine.ProductLineCode == null)
return;
int count = await GenericController.InsertAsync(newProductLine); int count = await GenericController.InsertAsync(newProductLine);
Console.WriteLine($"Inserted {count} properties for new ProductLine {newProductLine.ProductLineCode}."); Console.WriteLine($"Inserted {count} properties for new ProductLine {newProductLine.ProductLineCode}.");
} }
private async Task OnRowUpdatedAsync(SavedRowItem<ProductLine, Dictionary<string, object>> productLine) { private async Task OnRowUpdatedAsync(SavedRowItem<ProductLine, Dictionary<string, object>> productLine) {
ProductLine newProductLine = await ResolveProductAsync(productLine.Item); ProductLine newProductLine = await ResolveProductAsync(productLine.Item);
if (newProductLine.ProductLineCode == null)
return;
int count = await GenericController.UpdateAsync(productLine.Item); int count = await GenericController.UpdateAsync(productLine.Item);
Console.WriteLine($"Updated {count} properties in ProductLine {newProductLine.ProductLineCode}."); 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); int count = await GenericController.RemoveAsync(productLine);
Console.WriteLine($"Removed {count} properties and ProductLine {productLine.ProductLineCode}."); Console.WriteLine($"Removed {count} properties and ProductLine {productLine.ProductLineCode}.");
} }
@ -51,7 +53,7 @@ public partial class ProductLines {
private async Task<ProductLine> ResolveProductAsync(ProductLine newProductLine) { private async Task<ProductLine> ResolveProductAsync(ProductLine newProductLine) {
newProductLine.DataModificationByUser = "Gremlin Blazor Server GUI"; newProductLine.DataModificationByUser = "Gremlin Blazor Server GUI";
newProductLine.DataVersionNumber++; 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; return newProductLine;
} }
} }

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

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

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

@ -6,338 +6,326 @@ using Microsoft.EntityFrameworkCore.ChangeTracking;
namespace Gremlin_BlazorServer.Services; namespace Gremlin_BlazorServer.Services;
public class GenericController { public class GenericController {
public IList<TResult>? GetAll<TResult>() where TResult : class, IMetadata { private static readonly GremlinDb gremlinDb = new();
try {
using (GremlinDb gremlinDb = new()) return gremlinDb.Set<TResult>().ToList();
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
return null;
}
}
public IList<TResult>? GetAll<TResult>(string include) where TResult : class, IMetadata { public IList<TResult>? GetAll<TResult>() where TResult : class, IMetadata {
try { try {
using (GremlinDb gremlinDb = new()) return gremlinDb.Set<TResult>().Include(include).ToList(); return gremlinDb.Set<TResult>().ToList();
} }
catch (Exception exception) { catch (Exception exception) {
Console.WriteLine(exception.InnerException); Console.WriteLine(exception.InnerException);
return null; return null;
} }
} }
public IList<TResult>? GetAll<TResult>(Predicate<TResult> search) where TResult : class, IMetadata { public IList<TResult>? GetAll<TResult>(string include) where TResult : class, IMetadata {
ArgumentNullException.ThrowIfNull(search); try {
try { return gremlinDb.Set<TResult>().Include(include).ToList();
using (GremlinDb gremlinDb = new()) return gremlinDb.Set<TResult>().AsEnumerable().Where(t => search(t)).ToList(); }
} catch (Exception exception) {
catch (Exception exception) { Console.WriteLine(exception.InnerException);
Console.WriteLine(exception.InnerException); return null;
return null; }
} }
}
public async Task<IList<TResult>?> GetAllAsync<TResult>() where TResult : class, IMetadata { public IList<TResult>? GetAll<TResult>(Predicate<TResult> search) where TResult : class, IMetadata {
try { ArgumentNullException.ThrowIfNull(search);
await using (GremlinDb gremlinDb = new()) return await gremlinDb.Set<TResult>().ToListAsync(); try {
} return gremlinDb.Set<TResult>().AsEnumerable().Where(t => search(t)).ToList();
catch (DbUpdateConcurrencyException exception) { }
await HandleDbUpdateConcurrencyException<TResult>(exception); catch (Exception exception) {
Console.WriteLine(exception.InnerException); Console.WriteLine(exception.InnerException);
return null; return null;
} }
} }
public async Task<IList<TResult>?> GetAllAsync<TResult>(string include) where TResult : class, IMetadata { public async Task<IList<TResult>?> GetAllAsync<TResult>() where TResult : class, IMetadata {
try { try {
await using (GremlinDb gremlinDb = new()) return await gremlinDb.Set<TResult>().Include(include).ToListAsync(); return await gremlinDb.Set<TResult>().ToListAsync();
} }
catch (DbUpdateConcurrencyException exception) { catch (DbUpdateConcurrencyException exception) {
await HandleDbUpdateConcurrencyException<TResult>(exception); await HandleDbUpdateConcurrencyException<TResult>(exception);
Console.WriteLine(exception.InnerException); Console.WriteLine(exception.InnerException);
return null; return null;
} }
} }
public async Task<IList<TResult>?> GetAllAsync<TResult>(string include1, string include2) where TResult : class, IMetadata { public async Task<IList<TResult>?> GetAllAsync<TResult>(string include) where TResult : class, IMetadata {
try { try {
await using (GremlinDb gremlinDb = new()) return await gremlinDb.Set<TResult>().Include(include1).Include(include2).ToListAsync(); return await gremlinDb.Set<TResult>().Include(include).ToListAsync();
} }
catch (DbUpdateConcurrencyException exception) { catch (DbUpdateConcurrencyException exception) {
await HandleDbUpdateConcurrencyException<TResult>(exception); await HandleDbUpdateConcurrencyException<TResult>(exception);
Console.WriteLine(exception.InnerException); Console.WriteLine(exception.InnerException);
return null; return null;
} }
} }
public async Task<IList<TResult>?> GetAllAsync<TResult>(Predicate<TResult> search) where TResult : class, IMetadata { public async Task<IList<TResult>?> GetAllAsync<TResult>(string include1, string include2) where TResult : class, IMetadata {
ArgumentNullException.ThrowIfNull(search); try {
try { return await gremlinDb.Set<TResult>().Include(include1).Include(include2).ToListAsync();
await using (GremlinDb gremlinDb = new()) return await Task.Run(() => gremlinDb.Set<TResult>().AsEnumerable().Where(t => search(t)).ToList()); }
} catch (DbUpdateConcurrencyException exception) {
catch (DbUpdateConcurrencyException exception) { await HandleDbUpdateConcurrencyException<TResult>(exception);
await HandleDbUpdateConcurrencyException<TResult>(exception); Console.WriteLine(exception.InnerException);
Console.WriteLine(exception.InnerException); return null;
return null; }
} }
}
public async Task<IList<TResult>?> GetAllAsync<TResult>(Predicate<TResult> search, string include) where TResult : class, IMetadata { public async Task<IList<TResult>?> GetAllAsync<TResult>(Predicate<TResult> search) where TResult : class, IMetadata {
ArgumentNullException.ThrowIfNull(search); ArgumentNullException.ThrowIfNull(search);
try { 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>().AsEnumerable().Where(t => search(t)).ToList());
} }
catch (DbUpdateConcurrencyException exception) { catch (DbUpdateConcurrencyException exception) {
await HandleDbUpdateConcurrencyException<TResult>(exception); await HandleDbUpdateConcurrencyException<TResult>(exception);
Console.WriteLine(exception.InnerException); Console.WriteLine(exception.InnerException);
return null; return null;
} }
} }
public IList<TResult>? GetAll<TResult>(Predicate<TResult> search, string include) where TResult : class, IMetadata { public async Task<IList<TResult>?> GetAllAsync<TResult>(Predicate<TResult> search, string include) where TResult : class, IMetadata {
ArgumentNullException.ThrowIfNull(search); ArgumentNullException.ThrowIfNull(search);
try { try {
using (GremlinDb gremlinDb = new()) return 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 (Exception exception) { catch (DbUpdateConcurrencyException exception) {
Console.WriteLine(exception.InnerException); await HandleDbUpdateConcurrencyException<TResult>(exception);
return null; Console.WriteLine(exception.InnerException);
} return null;
} }
}
public TResult? Get<TResult>(Predicate<TResult> search) where TResult : class, IMetadata { // public IList<TResult>? GetAll<TResult>(Predicate<TResult> search, string include) where TResult : class, IMetadata {
ArgumentNullException.ThrowIfNull(search); // ArgumentNullException.ThrowIfNull(search);
try { // try {
using (GremlinDb gremlinDb = new()) return gremlinDb.Set<TResult>().AsEnumerable().FirstOrDefault(t => search(t)); // return gremlinDb.Set<TResult>().Include(include).AsEnumerable().Where(t => search(t)).ToList();
} // }
catch (Exception exception) { // catch (Exception exception) {
Console.WriteLine(exception.InnerException); // Console.WriteLine(exception.InnerException);
return null; // return null;
} // }
} // }
public async Task<TResult?> GetAsync<TResult>(Predicate<TResult> search) where TResult : class, IMetadata { // public TResult? Get<TResult>(Predicate<TResult> search) where TResult : class, IMetadata {
ArgumentNullException.ThrowIfNull(search); // ArgumentNullException.ThrowIfNull(search);
try { // try {
await using (GremlinDb gremlinDb = new()) return await Task.Run(() => gremlinDb.Set<TResult>().AsEnumerable().FirstOrDefault(t => search(t))); // using GremlinDb gremlinDb = new();
} // return gremlinDb.Set<TResult>().AsEnumerable().FirstOrDefault(t => search(t));
catch (DbUpdateConcurrencyException exception) { // }
await HandleDbUpdateConcurrencyException<TResult>(exception); // catch (Exception exception) {
Console.WriteLine(exception.InnerException); // Console.WriteLine(exception.InnerException);
return null; // return null;
} // }
} // }
public TResult? Get<TResult>(Predicate<TResult> search, string include) where TResult : class, IMetadata { public static async Task<TResult> GetAsync<TResult>(Predicate<TResult> search) where TResult : class, IMetadata, new() {
ArgumentNullException.ThrowIfNull(search); try {
try { return await Task.Run(() => gremlinDb.Set<TResult>().AsEnumerable().First(t => search(t)));
using (GremlinDb gremlinDb = new()) return gremlinDb.Set<TResult>().AsNoTracking().Include(include).AsEnumerable().FirstOrDefault(t => search(t)); }
} catch (Exception e) {
catch (Exception exception) { Console.WriteLine(e.InnerException);
Console.WriteLine(exception.InnerException); return new();
return null; }
} }
}
public async Task<TResult?> GetAsync<TResult>(Predicate<TResult> search, string include1) where TResult : class, IMetadata { // public TResult? Get<TResult>(Predicate<TResult> search, string include) where TResult : class, IMetadata {
ArgumentNullException.ThrowIfNull(search); // ArgumentNullException.ThrowIfNull(search);
try { // try {
await using (GremlinDb gremlinDb = new()) return await Task.Run(() => gremlinDb.Set<TResult>().Include(include1).AsEnumerable().FirstOrDefault(t => search(t))); // using GremlinDb gremlinDb = new();
} // return gremlinDb.Set<TResult>().AsNoTracking().Include(include).AsEnumerable().FirstOrDefault(t => search(t));
catch (DbUpdateConcurrencyException exception) { // }
await HandleDbUpdateConcurrencyException<TResult>(exception); // catch (Exception exception) {
Console.WriteLine(exception.InnerException); // Console.WriteLine(exception.InnerException);
return null; // return null;
} // }
} // }
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) where TResult : class, IMetadata, new() {
ArgumentNullException.ThrowIfNull(search); ArgumentNullException.ThrowIfNull(search);
try { 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).AsEnumerable().First(t => search(t)));
} }
catch (DbUpdateConcurrencyException exception) { catch (DbUpdateConcurrencyException exception) {
await HandleDbUpdateConcurrencyException<TResult>(exception); await HandleDbUpdateConcurrencyException<TResult>(exception);
Console.WriteLine(exception.InnerException); Console.WriteLine(exception.InnerException);
return null; return new();
} }
} }
public TResult? GetLast<TResult>() where TResult : class, IMetadata { public async Task<TResult> GetAsync<TResult>(Predicate<TResult> search, string include1, string include2) where TResult : class, IMetadata, new() {
try { ArgumentNullException.ThrowIfNull(search);
using (GremlinDb gremlinDb = new()) return gremlinDb.Set<TResult>().AsEnumerable().Last(); try {
} return await Task.Run(() => gremlinDb.Set<TResult>().Include(include1).Include(include2).AsEnumerable().First(t => search(t)));
catch (Exception exception) { }
Console.WriteLine(exception.InnerException); catch (DbUpdateConcurrencyException exception) {
return null; await HandleDbUpdateConcurrencyException<TResult>(exception);
} Console.WriteLine(exception.InnerException);
} return new();
}
}
public int Insert<T>(T entity) where T : class, IMetadata { public static async Task<TResult> GetLastAsync<TResult>() where TResult : class, IMetadata, new() {
try { try {
using (GremlinDb gremlinDb = new()) { return await Task.Run(() => gremlinDb.Set<TResult>().AsEnumerable().Last());
gremlinDb.Set<T>().Add(entity); }
return gremlinDb.SaveChanges(); catch (Exception exception) {
} Console.WriteLine(exception.InnerException);
} return new();
catch (Exception exception) { }
Console.WriteLine(exception.InnerException); }
return 0;
}
}
public int Insert<T>(IEnumerable<T> entities) where T : class, IMetadata { // public int Insert<T>(T entity) where T : class, IMetadata {
try { // try {
using (GremlinDb gremlinDb = new()) { // using GremlinDb gremlinDb = new();
gremlinDb.Set<T>().AddRange(entities); // gremlinDb.Set<T>().Add(entity);
return gremlinDb.SaveChanges(); // return gremlinDb.SaveChanges();
} // }
} // catch (Exception exception) {
catch (Exception exception) { // Console.WriteLine(exception.InnerException);
Console.WriteLine(exception.InnerException); // return 0;
return 0; // }
} // }
}
public async Task<int> InsertAsync<T>(T entity) where T : class, IMetadata { // public int Insert<T>(IEnumerable<T> entities) where T : class, IMetadata {
try { // try {
await using (GremlinDb gremlinDb = new()) { // using GremlinDb gremlinDb = new();
gremlinDb.Set<T>().Add(entity); // gremlinDb.Set<T>().AddRange(entities);
return await gremlinDb.SaveChangesAsync(); // return gremlinDb.SaveChanges();
} // }
} // catch (Exception exception) {
catch (DbUpdateConcurrencyException exception) { // Console.WriteLine(exception.InnerException);
await HandleDbUpdateConcurrencyException<T>(exception); // return 0;
Console.WriteLine(exception.InnerException); // }
return 0; // }
}
}
public async Task<int> InsertAsync<T>(IEnumerable<T> entities) where T : class, IMetadata { public async Task<int> InsertAsync<T>(T entity) where T : class, IMetadata {
try { try {
await using (GremlinDb gremlinDb = new()) { gremlinDb.Set<T>().Add(entity);
gremlinDb.Set<T>().AddRange(entities); return await gremlinDb.SaveChangesAsync();
return await gremlinDb.SaveChangesAsync(); }
} catch (DbUpdateConcurrencyException exception) {
} await HandleDbUpdateConcurrencyException<T>(exception);
catch (DbUpdateConcurrencyException exception) { Console.WriteLine(exception.InnerException);
await HandleDbUpdateConcurrencyException<T>(exception); return 0;
Console.WriteLine(exception.InnerException); }
return 0; }
}
}
public static bool IsExisting<T>(Predicate<T> search) where T : class, IMetadata { public async Task<int> InsertAsync<T>(IEnumerable<T> entities) where T : class, IMetadata {
ArgumentNullException.ThrowIfNull(search); try {
try { gremlinDb.Set<T>().AddRange(entities);
using (GremlinDb gremlinDb = new()) return gremlinDb.Set<T>().AsEnumerable().Any(t => search(t)); return await gremlinDb.SaveChangesAsync();
} }
catch (Exception exception) { catch (DbUpdateConcurrencyException exception) {
Console.WriteLine(exception.InnerException); await HandleDbUpdateConcurrencyException<T>(exception);
return false; Console.WriteLine(exception.InnerException);
} return 0;
} }
}
public int Update<T>(T entity) where T : class, IMetadata { public static async Task<bool> IsExistingAsync<T>(Predicate<T> search) where T : class, IMetadata {
try { try {
using (GremlinDb gremlinDb = new()) { return await Task.Run(() => gremlinDb.Set<T>().AsEnumerable().Any(t => search(t)));
gremlinDb.Set<T>().Update(entity); }
return gremlinDb.SaveChanges(); catch (Exception exception) {
} Console.WriteLine(exception.InnerException);
} return false;
catch (Exception exception) { }
Console.WriteLine(exception.InnerException); }
return 0;
}
}
public async Task<int> UpdateAsync<T>(T entity) where T : class, IMetadata { // public int Update<T>(T entity) where T : class, IMetadata {
await using (GremlinDb gremlinDb = new()) { // try {
try { // using GremlinDb gremlinDb = new();
gremlinDb.Set<T>().Update(entity); // gremlinDb.Set<T>().Update(entity);
return await gremlinDb.SaveChangesAsync(false); // return gremlinDb.SaveChanges();
} // }
catch (DbUpdateConcurrencyException exception) { // catch (Exception exception) {
await HandleDbUpdateConcurrencyException<T>(exception); // Console.WriteLine(exception.InnerException);
Console.WriteLine(exception.InnerException); // return 0;
return 0; // }
} // }
}
}
private async Task HandleDbUpdateConcurrencyException<T>(DbUpdateConcurrencyException exception) where T : class, IMetadata { public async Task<int> UpdateAsync<T>(T entity) where T : class, IMetadata {
// Loop through the entities that caused the concurrency conflict try {
foreach (EntityEntry? entry in exception.Entries) { gremlinDb.Set<T>().Update(entity);
if (entry.Entity is T) { return await gremlinDb.SaveChangesAsync(false);
T? clientValues = (T)entry.Entity; }
PropertyValues? databaseEntry = await entry.GetDatabaseValuesAsync(); catch (DbUpdateConcurrencyException exception) {
if (databaseEntry is null) await HandleDbUpdateConcurrencyException<T>(exception);
// The record has been deleted from the database Console.WriteLine(exception.InnerException);
// Notify the user or handle the error in some other way return 0;
throw new("The record has been deleted from the database."); }
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
// Notify the user or handle the error in some other way
throw new("The record has been modified by another user.");
// 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 private static async Task HandleDbUpdateConcurrencyException<T>(DbUpdateConcurrencyException exception) where T : class, IMetadata {
throw new NotSupportedException($"Concurrency conflicts for entities of type {entry.Entity.GetType().Name} are not supported."); // Loop through the entities that caused the concurrency conflict
} foreach (EntityEntry? entry in exception.Entries) {
} 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();
// Compare the database values with the client values
if (databaseValues.DataVersionNumber != clientValues.DataVersionNumber)
// The name has been changed by another user
// Notify the user or handle the error in some other way
throw new("The record has been modified by another user.");
// 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.");
public int Update<T>(IEnumerable<T> entities) where T : class, IMetadata { // Handle concurrency conflicts for other entity types, if necessary
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 int Update<T>(IEnumerable<T> entities) where T : class, IMetadata {
try { // try {
await using (GremlinDb gremlinDb = new()) { // using GremlinDb gremlinDb = new();
gremlinDb.Set<T>().UpdateRange(entities); // gremlinDb.Set<T>().UpdateRange(entities);
return await gremlinDb.SaveChangesAsync(); // return gremlinDb.SaveChanges();
} // }
} // catch (Exception exception) {
catch (Exception exception) { // Console.WriteLine(exception.InnerException);
Console.WriteLine(exception.InnerException); // return 0;
return 0; // }
} // }
}
public async Task<int> RemoveAsync<T>(T entity) where T : class, IMetadata { public static async Task<int> UpdateAsync<T>(IEnumerable<T> entities) where T : class, IMetadata {
try { try {
await using (GremlinDb gremlinDb = new()) { await Task.Run(() => gremlinDb.Set<T>().UpdateRange(entities));
gremlinDb.Set<T>().Remove(entity); return await gremlinDb.SaveChangesAsync();
return await gremlinDb.SaveChangesAsync(); }
} catch (Exception exception) {
} Console.WriteLine(exception.InnerException);
catch (Exception exception) { return 0;
Console.WriteLine(exception.InnerException); }
return 0; }
}
} public static async Task<int> RemoveAsync<T>(T entity) where T : class, IMetadata {
try {
public async Task<Account> ResolveAccountById(uint accountId){ await Task.Run(() => gremlinDb.Set<T>().Remove(entity));
try { return await gremlinDb.SaveChangesAsync();
await using (GremlinDb gremlinDb = new()) { }
return gremlinDb.Accounts.First(a => a.AccountId.Equals(accountId)); catch (Exception exception) {
} Console.WriteLine(exception.InnerException);
} return 0;
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..."); Console.WriteLine("Importing accounts from csv...");
IList<string[]> splitLines = await Task.Run(() => SplitLines(fileContent)); IList<string[]> splitLines = await Task.Run(() => SplitLines(fileContent));
if (typeof(T) == typeof(Account)) { if (typeof(T) != typeof(Account)) return false;
ParseListToAccounts(splitLines); await ParseListToAccounts(splitLines);
int countNewAccounts = genericController.Insert(newAccounts); int countNewAccounts = await genericController.InsertAsync(newAccounts);
int countUpdatedAccounts = genericController.Update(updatedAccounts); int countUpdatedAccounts = await GenericController.UpdateAsync(updatedAccounts);
Console.WriteLine($"Added {countNewAccounts} new Accounts to database and updated {updatedAccounts.Count} Accounts."); Console.WriteLine($"Added {countNewAccounts} new Accounts to database and updated {countUpdatedAccounts} Accounts.");
return countNewAccounts > 0 || updatedAccounts.Count > 0; return countNewAccounts > 0 || updatedAccounts.Count > 0;
}
return false;
} }
private static IList<string[]> SplitLines(string fileContent) { private static IList<string[]> SplitLines(string fileContent) {
@ -30,69 +28,58 @@ public class GenericImporter {
return fileList; 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) { foreach (string[] line in lineList) {
if (!line[0].Contains("ID")) //HACK: skip first row if header 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)) //HACK: skip lines with wrong uint 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() {
Account readAccount = new() { SapAccountNumber = sapAccountNumber,
SapAccountNumber = sapAccountNumber, AccountName = line[1],
AccountName = line[1], Street = line[2],
Street = line[2], City = line[3].ToUpper().First() + line[3].Substring(1).ToLower(),
City = line[3].ToUpper().First() + line[3].Substring(1).ToLower(), Zip = zip,
Zip = zip, AccountType = new(),
AccountType = new(), SubMarket = new(),
SubMarket = new(), PhoneNumber = line[8],
PhoneNumber = line[8], EMail = line[9],
EMail = line[9], // ParentAccountId = 0,
// ParentAccountId = 0, DataModificationByUser = "Gremlin Generic Importer"
DataModificationByUser = "Gremlin Generic Importer" };
};
AccountType accountType = await GenericController.GetAsync<AccountType>(aT => aT.AccountTypeCode == line[6]);
AccountType? accountType = genericController.Get<AccountType>(aT => aT.AccountTypeCode == line[6]); readAccount.AccountType.AccountTypeCode = accountType.AccountTypeCode;
if (accountType == null) continue; readAccount.AccountType = await GenericController.GetAsync<AccountType>(aT => aT.AccountTypeCode == readAccount.AccountType.AccountTypeCode);
readAccount.AccountType.AccountTypeCode = accountType.AccountTypeCode; SubMarket subMarket = await GenericController.GetAsync<SubMarket>(sM => sM.SubMarketCode == line[7]);
readAccount.AccountType = genericController.Get<AccountType>(aT => aT.AccountTypeCode == readAccount.AccountType.AccountTypeCode); readAccount.SubMarket.SubMarketCode = subMarket.SubMarketCode;
readAccount.SubMarket = await GenericController.GetAsync<SubMarket>(sM => sM.SubMarketCode == readAccount.SubMarket.SubMarketCode);
SubMarket? subMarket = genericController.Get<SubMarket>(sM => sM.SubMarketCode == line[7]);
if (subMarket == null) continue; if (readAccount.SubMarket?.SubMarketCode is null || readAccount.AccountType?.AccountTypeCode is 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); if (await AccountExists(sapAccountNumber)) {
Account existingAccount = await GenericController.GetAsync<Account>(a => a.SapAccountNumber.Equals(readAccount.SapAccountNumber));
if (readAccount?.SubMarket?.SubMarketCode == null || readAccount?.AccountType?.AccountTypeCode == null) continue; //HACK: skip Accounts with no SubMarket or AccountType if (IsEqualAccount(readAccount, existingAccount)) continue;
existingAccount.DataModificationDate = DateTime.Now;
if (AccountExists(sapAccountNumber)) { existingAccount.DataVersionNumber++;
Account? existingAccount = genericController.Get<Account>(a => a.SapAccountNumber == readAccount.SapAccountNumber); existingAccount.DataModificationByUser = "Updated by Gremlin Generic Importer";
if (existingAccount == null) continue; //Account does not exist existingAccount.AccountName = readAccount.AccountName;
if (!IsEqualAccount(readAccount, existingAccount)) { existingAccount.City = readAccount.City;
existingAccount.DataModificationDate = DateTime.Now; existingAccount.EMail = readAccount.EMail;
existingAccount.DataVersionNumber++; existingAccount.PhoneNumber = readAccount.PhoneNumber;
existingAccount.DataModificationByUser = "Updated by Gremlin Generic Importer"; existingAccount.Street = readAccount.Street;
existingAccount.AccountName = readAccount.AccountName; existingAccount.Zip = readAccount.Zip;
existingAccount.City = readAccount.City; //genericController.Update(existingAccount);
existingAccount.EMail = readAccount.EMail; Console.WriteLine($"Update in Account {existingAccount.SapAccountNumber}:{existingAccount.AccountName}");
existingAccount.PhoneNumber = readAccount.PhoneNumber; updatedAccounts.Add(existingAccount);
existingAccount.Street = readAccount.Street; }
existingAccount.Zip = readAccount.Zip; else {
//genericController.Update(existingAccount); newAccounts.Add(readAccount);
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 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) { private async Task<bool> AccountExists(uint sapAccountNumber) => await GenericController.IsExistingAsync<Account>(a => a.SapAccountNumber.Equals(sapAccountNumber));
return GenericController.IsExisting<Account>(a => a.SapAccountNumber == sapAccountNumber);
}
} }

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