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,9 +6,11 @@ using Microsoft.EntityFrameworkCore.ChangeTracking;
namespace Gremlin_BlazorServer.Services; namespace Gremlin_BlazorServer.Services;
public class GenericController { public class GenericController {
private static readonly GremlinDb gremlinDb = new();
public IList<TResult>? GetAll<TResult>() where TResult : class, IMetadata { public IList<TResult>? GetAll<TResult>() where TResult : class, IMetadata {
try { try {
using (GremlinDb gremlinDb = new()) return gremlinDb.Set<TResult>().ToList(); return gremlinDb.Set<TResult>().ToList();
} }
catch (Exception exception) { catch (Exception exception) {
Console.WriteLine(exception.InnerException); Console.WriteLine(exception.InnerException);
@ -18,7 +20,7 @@ public class GenericController {
public IList<TResult>? GetAll<TResult>(string include) where TResult : class, IMetadata { public IList<TResult>? GetAll<TResult>(string include) where TResult : class, IMetadata {
try { try {
using (GremlinDb gremlinDb = new()) return gremlinDb.Set<TResult>().Include(include).ToList(); return gremlinDb.Set<TResult>().Include(include).ToList();
} }
catch (Exception exception) { catch (Exception exception) {
Console.WriteLine(exception.InnerException); Console.WriteLine(exception.InnerException);
@ -29,7 +31,7 @@ public class GenericController {
public IList<TResult>? GetAll<TResult>(Predicate<TResult> search) where TResult : class, IMetadata { public IList<TResult>? GetAll<TResult>(Predicate<TResult> search) where TResult : class, IMetadata {
ArgumentNullException.ThrowIfNull(search); ArgumentNullException.ThrowIfNull(search);
try { 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) { catch (Exception exception) {
Console.WriteLine(exception.InnerException); Console.WriteLine(exception.InnerException);
@ -39,7 +41,7 @@ public class GenericController {
public async Task<IList<TResult>?> GetAllAsync<TResult>() 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>().ToListAsync(); return await gremlinDb.Set<TResult>().ToListAsync();
} }
catch (DbUpdateConcurrencyException exception) { catch (DbUpdateConcurrencyException exception) {
await HandleDbUpdateConcurrencyException<TResult>(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 { 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(include).ToListAsync(); return await gremlinDb.Set<TResult>().Include(include).ToListAsync();
} }
catch (DbUpdateConcurrencyException exception) { catch (DbUpdateConcurrencyException exception) {
await HandleDbUpdateConcurrencyException<TResult>(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 { public async Task<IList<TResult>?> GetAllAsync<TResult>(string include1, string include2) 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(include1).Include(include2).ToListAsync();
} }
catch (DbUpdateConcurrencyException exception) { catch (DbUpdateConcurrencyException exception) {
await HandleDbUpdateConcurrencyException<TResult>(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 { 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>().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);
@ -85,7 +87,7 @@ public class GenericController {
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, 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(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) { catch (DbUpdateConcurrencyException exception) {
await HandleDbUpdateConcurrencyException<TResult>(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 { // 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>().Include(include).AsEnumerable().Where(t => search(t)).ToList(); // 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 TResult? Get<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 {
using (GremlinDb gremlinDb = new()) return gremlinDb.Set<TResult>().AsEnumerable().FirstOrDefault(t => search(t)); // using GremlinDb gremlinDb = new();
} // return gremlinDb.Set<TResult>().AsEnumerable().FirstOrDefault(t => search(t));
catch (Exception exception) { // }
Console.WriteLine(exception.InnerException); // catch (Exception exception) {
return null; // Console.WriteLine(exception.InnerException);
} // return null;
} // }
// }
public async Task<TResult?> GetAsync<TResult>(Predicate<TResult> search) where TResult : class, IMetadata { public static async Task<TResult> GetAsync<TResult>(Predicate<TResult> search) where TResult : class, IMetadata, new() {
ArgumentNullException.ThrowIfNull(search);
try { 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) { catch (Exception e) {
await HandleDbUpdateConcurrencyException<TResult>(exception); Console.WriteLine(e.InnerException);
Console.WriteLine(exception.InnerException); return new();
return null;
} }
} }
public TResult? Get<TResult>(Predicate<TResult> search, string include) 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 {
using (GremlinDb gremlinDb = new()) return gremlinDb.Set<TResult>().AsNoTracking().Include(include).AsEnumerable().FirstOrDefault(t => search(t)); // using GremlinDb gremlinDb = new();
} // return gremlinDb.Set<TResult>().AsNoTracking().Include(include).AsEnumerable().FirstOrDefault(t => search(t));
catch (Exception exception) { // }
Console.WriteLine(exception.InnerException); // catch (Exception exception) {
return null; // 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); ArgumentNullException.ThrowIfNull(search);
try { 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) { catch (DbUpdateConcurrencyException exception) {
await HandleDbUpdateConcurrencyException<TResult>(exception); await HandleDbUpdateConcurrencyException<TResult>(exception);
Console.WriteLine(exception.InnerException); 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); 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).Include(include2).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 static async Task<TResult> GetLastAsync<TResult>() where TResult : class, IMetadata, new() {
try { try {
using (GremlinDb gremlinDb = new()) return gremlinDb.Set<TResult>().AsEnumerable().Last(); return await Task.Run(() => gremlinDb.Set<TResult>().AsEnumerable().Last());
} }
catch (Exception exception) { catch (Exception exception) {
Console.WriteLine(exception.InnerException); Console.WriteLine(exception.InnerException);
return null; return new();
} }
} }
public int Insert<T>(T entity) 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>().Add(entity); // 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 int Insert<T>(IEnumerable<T> entities) where T : class, IMetadata { // public int Insert<T>(IEnumerable<T> entities) where T : class, IMetadata {
try { // try {
using (GremlinDb gremlinDb = new()) { // using GremlinDb gremlinDb = new();
gremlinDb.Set<T>().AddRange(entities); // gremlinDb.Set<T>().AddRange(entities);
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 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>().Add(entity);
return await gremlinDb.SaveChangesAsync(); return await gremlinDb.SaveChangesAsync();
} }
}
catch (DbUpdateConcurrencyException exception) { catch (DbUpdateConcurrencyException exception) {
await HandleDbUpdateConcurrencyException<T>(exception); await HandleDbUpdateConcurrencyException<T>(exception);
Console.WriteLine(exception.InnerException); Console.WriteLine(exception.InnerException);
@ -215,11 +213,9 @@ public class GenericController {
public async Task<int> InsertAsync<T>(IEnumerable<T> entities) where T : class, IMetadata { public async Task<int> InsertAsync<T>(IEnumerable<T> entities) where T : class, IMetadata {
try { try {
await using (GremlinDb gremlinDb = new()) {
gremlinDb.Set<T>().AddRange(entities); gremlinDb.Set<T>().AddRange(entities);
return await gremlinDb.SaveChangesAsync(); return await gremlinDb.SaveChangesAsync();
} }
}
catch (DbUpdateConcurrencyException exception) { catch (DbUpdateConcurrencyException exception) {
await HandleDbUpdateConcurrencyException<T>(exception); await HandleDbUpdateConcurrencyException<T>(exception);
Console.WriteLine(exception.InnerException); Console.WriteLine(exception.InnerException);
@ -227,10 +223,9 @@ public class GenericController {
} }
} }
public static bool IsExisting<T>(Predicate<T> search) where T : class, IMetadata { public static async Task<bool> IsExistingAsync<T>(Predicate<T> search) where T : class, IMetadata {
ArgumentNullException.ThrowIfNull(search);
try { 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) { catch (Exception exception) {
Console.WriteLine(exception.InnerException); Console.WriteLine(exception.InnerException);
@ -238,21 +233,19 @@ public class GenericController {
} }
} }
public int Update<T>(T entity) where T : class, IMetadata { // public int Update<T>(T entity) where T : class, IMetadata {
try { // try {
using (GremlinDb gremlinDb = new()) { // using GremlinDb gremlinDb = new();
gremlinDb.Set<T>().Update(entity); // gremlinDb.Set<T>().Update(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> UpdateAsync<T>(T entity) where T : class, IMetadata { public async Task<int> UpdateAsync<T>(T entity) where T : class, IMetadata {
await using (GremlinDb gremlinDb = new()) {
try { try {
gremlinDb.Set<T>().Update(entity); gremlinDb.Set<T>().Update(entity);
return await gremlinDb.SaveChangesAsync(false); return await gremlinDb.SaveChangesAsync(false);
@ -263,19 +256,17 @@ public class GenericController {
return 0; 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 // Loop through the entities that caused the concurrency conflict
foreach (EntityEntry? entry in exception.Entries) { foreach (EntityEntry? entry in exception.Entries) {
if (entry.Entity is T) { if (entry.Entity is not T clientValues) throw new NotSupportedException($"Concurrency conflicts for entities of type {entry.Entity.GetType().Name} are not supported.");
T? clientValues = (T)entry.Entity;
PropertyValues? databaseEntry = await entry.GetDatabaseValuesAsync(); PropertyValues? databaseEntry = await entry.GetDatabaseValuesAsync();
if (databaseEntry is null) if (databaseEntry is null)
// The record has been deleted from the database // The record has been deleted from the database
// Notify the user or handle the error in some other way // Notify the user or handle the error in some other way
throw new("The record has been deleted from the database."); 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 // Compare the database values with the client values
if (databaseValues.DataVersionNumber != clientValues.DataVersionNumber) if (databaseValues.DataVersionNumber != clientValues.DataVersionNumber)
// The name has been changed by another user // 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 // The conflict is caused by a property other than the name
// Notify the user or handle the error in some other way // Notify the user or handle the error in some other way
throw new("A concurrency conflict occurred."); throw new("A concurrency conflict occurred.");
}
// Handle concurrency conflicts for other entity types, if necessary // 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 { // public int Update<T>(IEnumerable<T> entities) where T : class, IMetadata {
try { // try {
using (GremlinDb gremlinDb = new()) { // using GremlinDb gremlinDb = new();
gremlinDb.Set<T>().UpdateRange(entities); // gremlinDb.Set<T>().UpdateRange(entities);
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> UpdateAsync<T>(IEnumerable<T> entities) 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>().UpdateRange(entities);
return await gremlinDb.SaveChangesAsync(); return await gremlinDb.SaveChangesAsync();
} }
}
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> RemoveAsync<T>(T entity) where T : class, IMetadata {
try { try {
await using (GremlinDb gremlinDb = new()) { await Task.Run(() => gremlinDb.Set<T>().Remove(entity));
gremlinDb.Set<T>().Remove(entity);
return await gremlinDb.SaveChangesAsync(); return await gremlinDb.SaveChangesAsync();
} }
}
catch (Exception exception) { catch (Exception exception) {
Console.WriteLine(exception.InnerException); Console.WriteLine(exception.InnerException);
return 0; return 0;
} }
} }
public async Task<Account> ResolveAccountById(uint accountId){ // public async Task<Account?> ResolveAccountById(uint accountId){
try { // try {
await using (GremlinDb gremlinDb = new()) { //
return gremlinDb.Accounts.First(a => a.AccountId.Equals(accountId)); // if (gremlinDb.Accounts != null)
} // return gremlinDb.Accounts.First(a => a.AccountId.Equals(accountId));
} // else {
catch { // return null;
return new Account(); // }
} // }
} // 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,14 +28,11 @@ 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],
@ -52,23 +47,19 @@ public class GenericImporter {
DataModificationByUser = "Gremlin Generic Importer" DataModificationByUser = "Gremlin Generic Importer"
}; };
AccountType? accountType = genericController.Get<AccountType>(aT => aT.AccountTypeCode == line[6]); AccountType accountType = await GenericController.GetAsync<AccountType>(aT => aT.AccountTypeCode == line[6]);
if (accountType == null) continue;
readAccount.AccountType.AccountTypeCode = accountType.AccountTypeCode; 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]); SubMarket subMarket = await GenericController.GetAsync<SubMarket>(sM => sM.SubMarketCode == line[7]);
if (subMarket == null) continue;
readAccount.SubMarket.SubMarketCode = subMarket.SubMarketCode; 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)) { if (await AccountExists(sapAccountNumber)) {
Account? existingAccount = genericController.Get<Account>(a => a.SapAccountNumber == readAccount.SapAccountNumber); Account existingAccount = await GenericController.GetAsync<Account>(a => a.SapAccountNumber.Equals(readAccount.SapAccountNumber));
if (existingAccount == null) continue; //Account does not exist if (IsEqualAccount(readAccount, existingAccount)) continue;
if (!IsEqualAccount(readAccount, existingAccount)) {
existingAccount.DataModificationDate = DateTime.Now; existingAccount.DataModificationDate = DateTime.Now;
existingAccount.DataVersionNumber++; existingAccount.DataVersionNumber++;
existingAccount.DataModificationByUser = "Updated by Gremlin Generic Importer"; existingAccount.DataModificationByUser = "Updated by Gremlin Generic Importer";
@ -82,17 +73,13 @@ public class GenericImporter {
Console.WriteLine($"Update in Account {existingAccount.SapAccountNumber}:{existingAccount.AccountName}"); Console.WriteLine($"Update in Account {existingAccount.SapAccountNumber}:{existingAccount.AccountName}");
updatedAccounts.Add(existingAccount); updatedAccounts.Add(existingAccount);
} }
}
else { else {
newAccounts.Add(readAccount); 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;
} }