QuoteIndex with Tabs

pull/1/head
DJh2o2 2023-01-27 09:54:17 +07:00
parent 049270637f
commit 82eaf16c7a
14 changed files with 364 additions and 209 deletions

@ -24,7 +24,7 @@ namespace Gremlin_BlazorServer.Data.DBClasses
try
{
_ = optionsBuilder.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString)).EnableSensitiveDataLogging().EnableDetailedErrors();
optionsBuilder.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString)).EnableSensitiveDataLogging().EnableDetailedErrors();
}
catch (Exception e)
{
@ -60,10 +60,10 @@ namespace Gremlin_BlazorServer.Data.DBClasses
_ = modelBuilder.ApplyConfigurationsFromAssembly(typeof(GremlinDb).Assembly);
//AutoInclude all NavigationParameters in Entities
_ = modelBuilder.Entity<Account>().Navigation(db => db.Contacts).AutoInclude();
_ = modelBuilder.Entity<Account>().Navigation(db => db.AccountType).AutoInclude();
_ = modelBuilder.Entity<Account>().Navigation(db => db.SubMarket).AutoInclude();
_ = modelBuilder.Entity<Account>().Navigation(db => db.CustomDescriptions).AutoInclude();
// _ = modelBuilder.Entity<Account>().Navigation(db => db.Contacts).AutoInclude();
// _ = modelBuilder.Entity<Account>().Navigation(db => db.AccountType).AutoInclude();
// _ = modelBuilder.Entity<Account>().Navigation(db => db.SubMarket).AutoInclude();
// _ = modelBuilder.Entity<Account>().Navigation(db => db.CustomDescriptions).AutoInclude();
//modelBuilder.Entity<Contact>().Navigation(db => db.Account).AutoInclude();
@ -74,9 +74,8 @@ namespace Gremlin_BlazorServer.Data.DBClasses
//modelBuilder.Entity<Quote>().Navigation(db => db.LineItems).AutoInclude();
//modelBuilder.Entity<Quote>().Navigation(db => db.Recipient).AutoInclude();
_ = modelBuilder.Entity<Product>().Navigation(db => db.CustomDescription).AutoInclude();
_ = modelBuilder.Entity<Product>().Navigation(db => db.ProductLine).AutoInclude();
// _ = modelBuilder.Entity<Product>().Navigation(db => db.CustomDescription).AutoInclude();
// _ = modelBuilder.Entity<Product>().Navigation(db => db.ProductLine).AutoInclude();
//Generic AutoInclude method not yet working
//ConfigureAutoIncludeFor<Account>(modelBuilder);

@ -3,7 +3,7 @@
@using Gremlin_BlazorServer.Data.EntityClasses;
@using Gremlin_BlazorServer.Services;
@inject GenericController genericController;
@inject GenericController GenericController;
<AuthorizeView>
<Authorized>
@ -38,13 +38,18 @@
@code {
IList<AccountType>? accountTypes;
AccountType? selectedAccountType;
List<Account>? accountsOfSelectedAccountType;
IList<Account>? accountsOfSelectedAccountType;
protected override Task OnInitializedAsync()
{
accountTypes = genericController.GetAll<AccountType>("Accounts");
accountTypes = GenericController.GetAll<AccountType>("Accounts");
return Task.CompletedTask;
}
private void OnSelectedAccountTypeChanged(AccountType sAt) => selectedAccountType = sAt;
private void OnSelectedAccountTypeChanged(AccountType sAt)
{
selectedAccountType = sAt;
accountsOfSelectedAccountType = GenericController.GetAll<Account>(account => account.AccountType == selectedAccountType);
}
}

@ -4,7 +4,7 @@
@using Gremlin_BlazorServer.Services;
@using System.Globalization;
@inject GenericController genericController
@inject GenericController GenericController
<h1>Contacts</h1>
<AuthorizeView>
@ -59,28 +59,22 @@
private IList<Contact>? contacts;
private Contact? selectedContact;
private Quote? selectedQuote;
private IList<Quote>? quotesOfSelectedContact;
private IList<LineItem>? lineItemsInSelectedQuote;
private readonly CultureInfo cultureInfo = new("de-DE");
protected override Task OnInitializedAsync()
{
contacts = genericController.GetAll<Contact>();
contacts = GenericController.GetAll<Contact>();
return base.OnInitializedAsync();
}
private Task OnSelectedContactChanged(Contact sC)
{
selectedContact = null;
quotesOfSelectedContact = genericController.GetAll<Quote>(q => q.Recipient == sC);
selectedContact = sC;
return Task.CompletedTask;
}
private Task OnSelectedQuoteChanged(Quote sQ)
{
selectedQuote = null;
lineItemsInSelectedQuote = genericController.GetAll<LineItem>(l => l.Quote == sQ);
selectedQuote = sQ;
return Task.CompletedTask;
}

@ -2,8 +2,9 @@
@using Gremlin_BlazorServer.Data.EntityClasses;
@using Gremlin_BlazorServer.Services;
@using System.Security.Claims
@inject GenericController genericController
@inject GenericController GenericController
<AuthorizeView>
<Authorized>
@ -24,20 +25,20 @@
@code {
[CascadingParameter]
private Task<AuthenticationState>? authenticationStateTask { get; set; }
private Task<AuthenticationState>? AuthenticationStateTask { get; set; }
private IList<CustomDescription>? customDescriptions;
private CustomDescription? selectedCustomDescription;
protected override async Task OnInitializedAsync()
{
if (authenticationStateTask != null)
if (AuthenticationStateTask != null)
{
var user = (await authenticationStateTask).User;
ClaimsPrincipal user = (await AuthenticationStateTask).User;
if (user.Identity != null && user.Identity.IsAuthenticated)
if (user.Identity is {IsAuthenticated: true })
{
customDescriptions = genericController.GetAll<CustomDescription>();
customDescriptions = GenericController.GetAll<CustomDescription>();
}
}
}

@ -5,7 +5,7 @@
<h2>Welcome to new App!</h2>
<AuthorizeView>
<Authorized>
@if(context != null && context.User != null && context.User.Identity != null)
@if(context.User.Identity != null)
{
<h3>You are logged in as @context.User.Identity.Name</h3>
}

@ -2,9 +2,10 @@
@using Gremlin_BlazorServer.Data.EntityClasses;
@using Gremlin_BlazorServer.Services;
@using System.Globalization;
@using System.Security.Claims
@inject GenericController genericController
@inject GenericController GenericController
icController
<AuthorizeView>
<Authorized>
@ -39,20 +40,20 @@
@code {
[CascadingParameter]
private Task<AuthenticationState>? authenticationStateTask { get; set; }
private Task<AuthenticationState>? AuthenticationStateTask { get; set; }
private IList<LineItem>? lineItems;
private LineItem? selectedLineItem;
protected override async Task OnInitializedAsync()
{
if (authenticationStateTask != null)
if (AuthenticationStateTask != null)
{
var user = (await authenticationStateTask).User;
ClaimsPrincipal user = (await AuthenticationStateTask).User;
if (user.Identity != null && user.Identity.IsAuthenticated)
if (user.Identity is {IsAuthenticated: true })
{
lineItems = genericController.GetAll<LineItem>();
lineItems = GenericController.GetAll<LineItem>();
}
}
}

@ -3,7 +3,7 @@
@using Gremlin_BlazorServer.Data.EntityClasses;
@using Gremlin_BlazorServer.Services;
@inject GenericController genericController
@inject GenericController GenericController
<AuthorizeView>
<Authorized>
@ -41,14 +41,14 @@
protected override Task OnParametersSetAsync()
{
productLines = genericController.GetAll<ProductLine>();
productLines = GenericController.GetAll<ProductLine>();
return Task.CompletedTask;
}
private Task OnSelectedProductLineChanged(ProductLine pL)
{
selectedProductLine = pL;
productsOfSelectedProductLine = genericController.GetAll<Product>(product => product.ProductLine == selectedProductLine);
productsOfSelectedProductLine = GenericController.GetAll<Product>(product => product.ProductLine == selectedProductLine);
return Task.CompletedTask;
}
}

@ -4,7 +4,7 @@
@using Gremlin_BlazorServer.Services;
@using System.Globalization
@inject GenericController genericController
@inject GenericController GenericController
<AuthorizeView>
<Authorized>
@ -48,7 +48,7 @@
protected override Task OnInitializedAsync()
{
products = genericController.GetAll<Product>();
products = GenericController.GetAll<Product>();
return Task.CompletedTask;
}

@ -1,12 +1,10 @@
@page "/Quotes/QuoteAdd"
@using Gremlin_BlazorServer.Data.EntityClasses;
@using Gremlin_BlazorServer.Services;
@using System.Text;
@using System.Globalization;
@using System.Diagnostics
@inject GenericController genericController
@inject NavigationManager navigationManager
@inject GenericController GenericController
@inject NavigationManager NavigationManager
<h1>Create New Quote</h1>
@ -120,15 +118,15 @@
protected override Task OnParametersSetAsync()
{
contacts = genericController.GetAll<Contact>("Account");
contacts = GenericController.GetAll<Contact>("Account");
GenerateNewQuote("Woitschetzki"); //TODO: get salesRep from Login
return Task.CompletedTask;
}
private void GenerateNewQuote(string salesRep)
{
quote.SalesRep = genericController.Get<Contact>(c => c.LastName == salesRep);
quote.QuoteId = genericController.GetLast<Quote>().QuoteId + 1;
quote.SalesRep = GenericController.Get<Contact>(c => c.LastName == salesRep);
quote.QuoteId = GenericController.GetLast<Quote>().QuoteId + 1;
if (quote.SalesRep != null)
{
quote.QuotationNumber = quote.SalesRep.LastName switch
@ -156,7 +154,7 @@
if (quote.Recipient?.Account?.AccountName != null)
quote.Path = $"{Directory.GetCurrentDirectory()}{Path.DirectorySeparatorChar}Quotes{Path.DirectorySeparatorChar}{quote.Recipient.Account.AccountName}{Path.DirectorySeparatorChar}{DateTime.Today.Year}-{quote.Recipient.LastName}-{quote.Description}";
FileService.WriteClipboardToTsv(fileContent, quote);
FileService.WriteQuoteToTsv(fileContent, quote);
}
}
catch (Exception exc)
@ -177,14 +175,14 @@
{
selectedContact = sC;
quote.Recipient = selectedContact;
Debug.WriteLine($"New selected contact: {selectedContact.LastName}");
quote.Recipient.Account = GenericController.Get<Account>(account => account.AccountId == quote.Recipient.AccountId);
return Task.CompletedTask;
}
private Task OnSave()
{
if (genericController.Insert(quote))
navigationManager.NavigateTo("Quotes/QuoteIndex");
if (GenericController.Insert(quote))
NavigationManager.NavigateTo("Quotes/QuoteIndex");
return Task.CompletedTask;
@ -192,8 +190,8 @@
private Task OnCreateTex()
{
StringBuilder texStringBuilder = QuoteHandling.CreateTex(quote);
quote.Tex = texStringBuilder.ToString();
quote.Tex = QuoteHandling.CreateTex(quote)?.ToString();
if (quote.Tex == null) return Task.CompletedTask;
FileService.WriteTexFile(quote);
return Task.CompletedTask;
}
@ -258,14 +256,14 @@
private Task OnCancel()
{
navigationManager.NavigateTo("Quotes/QuoteIndex");
NavigationManager.NavigateTo("Quotes/QuoteIndex");
return Task.CompletedTask;
}
private Task OnSelectedLineItemChanged(LineItem lI)
{
selectedLineItem = lI;
customDescriptionOfSelectedLineItem = genericController.Get<CustomDescription>(cD => cD.ProductNumber == lI.ProductNumber && cD.OptionNumber == lI.OptionNumber);
customDescriptionOfSelectedLineItem = GenericController.Get<CustomDescription>(cD => cD.ProductNumber == lI.ProductNumber && cD.OptionNumber == lI.OptionNumber);
return Task.CompletedTask;
}
}

@ -4,8 +4,8 @@
@using Gremlin_BlazorServer.Services;
@using System.Globalization;
@inject GenericController genericController
@inject NavigationManager navigationManager
@inject GenericController GenericController
@inject NavigationManager NavigationManager
<h1>Quotes</h1>
@ -30,57 +30,69 @@
@if (selectedQuote != null)
{
<h2>Quote Details</h2>
<Row>
<Column ColumnSize="ColumnSize.Is4">
<Fields>
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">Angebotsname:</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6"><TextEdit Text="@selectedQuote.Description"/></FieldBody></Field>
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">Angebotsnummer:</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6"><TextEdit Text="@selectedQuote.QuotationNumber"/></FieldBody></Field>
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">Angebotspfad:</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6">@selectedQuote.Path</FieldBody></Field>
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">Gewährleistung (Monate):</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6">@selectedQuote.Warranty.ToString(CultureInfo.CurrentCulture)</FieldBody></Field>
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">Angebotsgültigkeit (Tage):</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6"><TextEdit Text="@selectedQuote.ValidFor.ToString(CultureInfo.CurrentCulture)"/></FieldBody></Field>
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">Mehrwertsteuer (%):</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6"><TextEdit Text="@selectedQuote.Vat.ToString(CultureInfo.CurrentCulture)"/></FieldBody></Field>
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">Versandkosten (%):</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6"><TextEdit Text="@selectedQuote.Freight.ToString(CultureInfo.CurrentCulture)" /></FieldBody></Field>
</Fields>
</Column>
<Tabs SelectedTab="@selectedTab" SelectedTabChanged="@OnSelectedTabChanged">
<Items>
<Tab Name="details">Details</Tab>
<Tab Name="lineitems">LineItems</Tab>
</Items>
<Content>
<TabPanel Name="details">
<Row>
<Column ColumnSize="ColumnSize.Is4">
<Fields>
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">Angebotsname:</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6"><TextEdit Text="@selectedQuote.Description"/></FieldBody></Field>
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">Angebotsnummer:</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6"><TextEdit Text="@selectedQuote.QuotationNumber"/></FieldBody></Field>
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">Angebotspfad:</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6"><TextEdit ReadOnly Text="@selectedQuote.Path"/></FieldBody></Field>
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">Gewährleistung (Monate):</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6">@selectedQuote.Warranty.ToString(CultureInfo.CurrentCulture)</FieldBody></Field>
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">Angebotsgültigkeit (Tage):</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6"><TextEdit Text="@selectedQuote.ValidFor.ToString(CultureInfo.CurrentCulture)"/></FieldBody></Field>
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">Mehrwertsteuer (%):</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6"><TextEdit Text="@selectedQuote.Vat.ToString(CultureInfo.CurrentCulture)"/></FieldBody></Field>
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">Versandkosten (%):</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6"><TextEdit Text="@selectedQuote.Freight.ToString(CultureInfo.CurrentCulture)" /></FieldBody></Field>
</Fields>
</Column>
<Column ColumnSize="ColumnSize.Is3">
<Fields>
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">Empfänger Nachname:</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6"><TextEdit Text="@selectedQuote.Recipient.LastName"/></FieldBody></Field>
</Fields>
</Column>lineItemsInSelectedQuote
<Column ColumnSize="ColumnSize.Is3">
<Fields>
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">FirstName:</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6"><TextEdit ReadOnly Text="@selectedQuote.Recipient.FirstName"/></FieldBody></Field>
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">LastName:</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6"><TextEdit ReadOnly Text="@selectedQuote.Recipient.LastName"/></FieldBody></Field>
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">AccountName:</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6"><TextEdit ReadOnly Text="@selectedQuote.Recipient.Account.AccountName"/></FieldBody></Field>
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">Street:</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6"><TextEdit ReadOnly Text="@selectedQuote.Recipient.Account.Street"/></FieldBody></Field>
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">Zip:</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6"><TextEdit ReadOnly Text="@selectedQuote.Recipient.Account.Zip.ToString()"/></FieldBody></Field>
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">City:</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6"><TextEdit ReadOnly Text="@selectedQuote.Recipient.Account.City"/></FieldBody></Field>
</Fields>
</Column>
<Column ColumnSize="ColumnSize.Is2">
<Check TValue="bool" ReadOnly Checked="@selectedQuote.IsPriceInformation">Preisinformation</Check>
<Check TValue="bool" ReadOnly Checked="@selectedQuote.ShowBrutto">Bruttopreise anzeigen</Check>
<Check TValue="bool" ReadOnly Checked="@selectedQuote.ShowSinglePrices">Einzelpreise ausweisen</Check>
<Check TValue="bool" ReadOnly Checked="@selectedQuote.ShowDiscounts">Discounts ausweisen</Check>
</Column>
<Column ColumnSize="ColumnSize.Is2">
<Check TValue="bool" ReadOnly Checked="@selectedQuote.IsPriceInformation">Preisinformation</Check>
<Check TValue="bool" ReadOnly Checked="@selectedQuote.ShowBrutto">Bruttopreise anzeigen</Check>
<Check TValue="bool" ReadOnly Checked="@selectedQuote.ShowSinglePrices">Einzelpreise ausweisen</Check>
<Check TValue="bool" ReadOnly Checked="@selectedQuote.ShowDiscounts">Discounts ausweisen</Check>
</Column>
<Column ColumnSize="ColumnSize.Is3">
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">Listenpreis netto:</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6"><TextEdit ReadOnly Text="@selectedQuote.TotalListprice.ToString("C", CultureInfo.CurrentCulture)"></TextEdit></FieldBody></Field>
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">Summe netto:</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6"><TextEdit ReadOnly Text="@selectedQuote.TotalNet.ToString("C", CultureInfo.CurrentCulture)"></TextEdit></FieldBody></Field>
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">Versandkosten:</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6"><TextEdit ReadOnly Text="@selectedQuote.TotalFreightOnly.ToString("C", CultureInfo.CurrentCulture)"></TextEdit></FieldBody></Field>
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">Gesamtsumme netto:</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6"><TextEdit ReadOnly Text="@selectedQuote.TotalFreight.ToString("C", CultureInfo.CurrentCulture)"></TextEdit></FieldBody></Field>
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">Mehrwertsteuer:</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6"><TextEdit ReadOnly Text="@selectedQuote.TotalVat.ToString("C", CultureInfo.CurrentCulture)"></TextEdit></FieldBody></Field>
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">Gesamtsumme brutto:</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6"><TextEdit ReadOnly Text="@selectedQuote.TotalGross.ToString("C", CultureInfo.CurrentCulture)"></TextEdit></FieldBody></Field>
</Column>
</Row>
<h2>Line Items</h2>
@if (lineItemsInSelectedQuote != null)
{
<DataGrid TItem="LineItem" Data="@lineItemsInSelectedQuote" Bordered Hoverable Sortable Striped Responsive>
<DataGridCommandColumn />
<DataGridColumn Field="@nameof(LineItem.Position)" Caption="#"/>
<DataGridColumn Field="@nameof(LineItem.Amount)" Caption="Amount" Editable />
<DataGridColumn Field="@nameof(LineItem.ProductNumber)" Caption="ProductNumber" Editable />
<DataGridColumn Field="@nameof(LineItem.OptionNumber)" Caption="OptionNumber" Editable />
<DataGridColumn Field="@nameof(LineItem.ProductLine)" Caption="ProductLine" Editable />
<DataGridColumn Field="@nameof(LineItem.ListPrice)" Caption="ListPrice" DisplayFormat="{0:C}" DisplayFormatProvider=cultureInfo Editable />
<DataGridColumn Field="@nameof(LineItem.TotalDiscount)" Caption="TotalDiscount" DisplayFormat="{0:C}" DisplayFormatProvider=cultureInfo Editable />
<DataGridColumn Field="@nameof(LineItem.Total)" Caption="Total" DisplayFormat="{0:C}" DisplayFormatProvider=cultureInfo Editable />
</DataGrid>
}
<Column ColumnSize="ColumnSize.Is3">
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">Listenpreis netto:</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6"><TextEdit ReadOnly Text="@selectedQuote.TotalListprice.ToString("C", CultureInfo.CurrentCulture)"></TextEdit></FieldBody></Field>
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">Summe netto:</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6"><TextEdit ReadOnly Text="@selectedQuote.TotalNet.ToString("C", CultureInfo.CurrentCulture)"></TextEdit></FieldBody></Field>
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">Versandkosten:</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6"><TextEdit ReadOnly Text="@selectedQuote.TotalFreightOnly.ToString("C", CultureInfo.CurrentCulture)"></TextEdit></FieldBody></Field>
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">Gesamtsumme netto:</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6"><TextEdit ReadOnly Text="@selectedQuote.TotalFreight.ToString("C", CultureInfo.CurrentCulture)"></TextEdit></FieldBody></Field>
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">Mehrwertsteuer:</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6"><TextEdit ReadOnly Text="@selectedQuote.TotalVat.ToString("C", CultureInfo.CurrentCulture)"></TextEdit></FieldBody></Field>
<Field Horizontal><FieldLabel ColumnSize="ColumnSize.Is4">Gesamtsumme brutto:</FieldLabel><FieldBody ColumnSize="ColumnSize.Is6"><TextEdit ReadOnly Text="@selectedQuote.TotalGross.ToString("C", CultureInfo.CurrentCulture)"></TextEdit></FieldBody></Field>
</Column>
</Row>
</TabPanel>
<TabPanel Name="lineitems">
<DataGrid TItem="LineItem" Data="@selectedQuote.LineItems" Bordered Hoverable Sortable Striped Responsive>
<DataGridCommandColumn/>
<DataGridColumn Field="@nameof(LineItem.Position)" Caption="#"/>
<DataGridColumn Field="@nameof(LineItem.Amount)" Caption="Amount" Editable/>
<DataGridColumn Field="@nameof(LineItem.ProductNumber)" Caption="ProductNumber" Editable/>
<DataGridColumn Field="@nameof(LineItem.OptionNumber)" Caption="OptionNumber" Editable/>
<DataGridColumn Field="@nameof(LineItem.ProductLine)" Caption="ProductLine" Editable/>
<DataGridColumn Field="@nameof(LineItem.ListPrice)" Caption="ListPrice" DisplayFormat="{0:C}" DisplayFormatProvider=cultureInfo Editable/>
<DataGridColumn Field="@nameof(LineItem.TotalDiscount)" Caption="TotalDiscount" DisplayFormat="{0:C}" DisplayFormatProvider=cultureInfo Editable/>
<DataGridColumn Field="@nameof(LineItem.Total)" Caption="Total" DisplayFormat="{0:C}" DisplayFormatProvider=cultureInfo Editable/>
</DataGrid>
</TabPanel>
</Content>
</Tabs>
}
</Authorized>
@ -91,26 +103,32 @@
</AuthorizeView>
@code {
private Task<AuthenticationState>? authenticationStateTask { get; set; }
private IList<Quote>? quotes;
private Quote? selectedQuote;
//private Contact? recipient;
private IList<LineItem>? lineItemsInSelectedQuote;
private readonly CultureInfo cultureInfo = new("de-DE");
private string selectedTab = "details";
protected override Task OnInitializedAsync()
{
quotes = genericController.GetAll<Quote>("Recipient");
quotes = GenericController.GetAll<Quote>("Recipient");
return Task.CompletedTask;
}
private void OnSelectedQuoteChanged(Quote sQ)
{
selectedQuote = null;
//recipient = genericController.Get<Contact>(contact => contact == sQ.Recipient, "Account");
lineItemsInSelectedQuote = genericController.GetAll<LineItem>(lineItem => lineItem.Quote == sQ);
selectedQuote = sQ;
if (selectedQuote.Recipient != null)
{
selectedQuote.Recipient.Account = GenericController.Get<Account>(a => a.AccountId == sQ.Recipient?.AccountId);
}
selectedQuote.LineItems = GenericController.GetAll<LineItem>(lineItem => lineItem.Quote == selectedQuote);
}
private void OnCreateNewQuote() => navigationManager.NavigateTo("Quotes/QuoteAdd");
private void OnCreateNewQuote() => NavigationManager.NavigateTo("Quotes/QuoteAdd");
private Task OnSelectedTabChanged(string sT)
{
selectedTab = sT;
return Task.CompletedTask;
}
}

@ -0,0 +1,180 @@
\documentclass[a4paper,ngerman,parskip,10pt]{scrlttr2}
\usepackage{lmodern}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage[hidelinks]{hyperref}
\usepackage[left=2cm, right=2cm, top=2cm, bottom=2cm]{geometry}
\usepackage[table]{xcolor}
\usepackage[right]{{eurosym}}
\usepackage[locale=DE]{{siunitx}}
\usepackage{{scrlayer-scrpage}}
\usepackage{{lastpage}}
\usepackage{{graphicx}}
\usepackage{{multirow}}
\usepackage{{longtable}}
\usepackage{{enumitem}}
\usepackage{{fp, xstring, spreadtab, numprint}}
\DeclareSIUnit{{\sieuro}}{{\mbox{{\euro}}}}
\rohead{DE-83PE89-123-197}
\cfoot{Seite \thepage/\pageref{LastPage}}
\sisetup{round-integer-to-decimal,round-precision=2,round-mode=places}
\newcommand{\produkttitel}[1]{\textsc{#1}}
\renewcommand{\arraystretch}{1.2}
\definecolor{AgilentBlau}{HTML}{0085d5}
\setlist{noitemsep}
\begin{document}
\begin{tabular}{p{0.4\hsize}p{0.5\hsize}}
\multirow{4}{*}{\includegraphics[width=0.9\hsize]{agilentLogo.png}}
&\normalsize{Agilent Technologies Deutschland GmbH}\\
&\normalsize{Life Sciences \& Chemical Analysis}\\
&\normalsize{Hewlett-Packard-Str. 8}\\
&\normalsize{D-76337 Waldbronn}
\end{tabular}
\par
\begin{flushright}
\colorbox{AgilentBlau}{\textcolor{white}{\textsc{\Huge{Angebot}}}}
\end{flushright}
\begin{tabular}{p{0.4\hsize}p{0.6\hsize}}
&
\multirow{4}{*}{
\begin{tabular}{|ll|}
\hline
\textbf{Angebotsnummer:}&DE-83PE89-123-197\\
Angebotdatum:&\today\\
Angebotsgültigkeit:&90 Tage\\\textbf{Ansprechpartner:}&Sascha Woitschetzki\\
Telefon: &+49 208 74129134\\
Mobil:&+49 176 22285334\\
E-Mail:&\href{mailto:sascha.woitschetzki@non.agilent.com}{sascha.woitschetzki@non.agilent.com}\\
\textbf{Auftragsannahme:}&\href{mailto:salesservices\_germany@agilent.com}{salesservices\_germany@agilent.com}\\
\hline
\end{tabular}
}\\
Herr Karl De Jong
\\
Stadtwerke Aachen AG Strom-Gas-Wasser-Wärme
\\
Lombardenstr 12-22
\\
52070 Aachen
\\
&\\
&\\
\end{tabular}
\vspace{1cm}\par
Sehr geehrter Herr De Jong,\par
nachfolgend erhalten Sie Ihr gewünschtes Angebot über ein(e) Gerät.\\
Es umfasst im Einzelnen:
\begin{itemize}
\item Flexible Pumpe (max. 800 bar) mit 4 Kanälen, integriertem Entgaser, BlendAssist und ISET (\#1)
\begin{itemize}
\item Werkzeug (\#2)
\item InfinityLab StaySafe Starter-Kit (\#3)
\item Poroshell 120 Säule (\#4)
\end{itemize}
\item Vialsampler (\#5)
\begin{itemize}
\item Probenteller für 6x11 2,0 ml Vials (\#6)
\item Vorhandene Agilent CDS-Lizenz (\#7)
\item Probenthermostat (\#8)
\end{itemize}
\item Säulenthermostat (\#9)
\item InfinityLab Quick Connect Assembly (\#10)
\item InfinityLab Quick Connect Assembly (\#11)
\item Diodenarraydetektor WR (\#12)
\begin{itemize}
\item Standardflusszelle (\#13)
\end{itemize}
\item Fluoreszenzspektrendetektor (\#14)
\item Fraktionssammler (\#15)
\item OpenLab CDS 2 Instrument Connection (\#17)
\begin{itemize}
\item OpenLab CDS 2 IC für LC (\#18)
\item OpenLab CDS 2 IC für 3D-UV/DAD (\#19)
\end{itemize}
\item 1260 Infinity II HPLC mit Zusatzfunktionen (\#20)
\begin{itemize}
\item Erweiterte Gewährleistung Plus (3 Jahre) (\#21)
\item Einweisung und First Run Assist (\#22)
\item Installation and Operational Qualification (\#23)
\end{itemize}
\item Agilent Training Credits (\#24)
\end{itemize}
Für Rückfragen und Änderungswünsche stehe ich Ihnen gerne zur Verfügung.\par
Mit freundlichen Grüßen\\
\includegraphics[width = 5cm]{signWoitschetzki.png}
\vspace{1cm} \\
\begin{center}
\begin{longtable}
{| cp{0.595\textwidth} crr |} \hline
\textbf{\#} & \textbf{Produktbeschreibung} (Produktnummer) & \textbf{Menge} & \textbf{Discount} & \textbf{Preis}\\ \hline \endhead
1 &\textbf{1260 Infinity II Prime Flexible Pumpe} (G7104C)\newline 1260 Infinity II Prime Flexible Pumpe mit 1290 II Technologie für höchste Präzision und Genauigkeit. \newline Quaternäre Pumpe (bis zu 800 bar und 5 ml/min) mit integriertem Entgaser, Niederdruckmischer, aktiver Kolbenhinterspülung, ISET und BlendAssist.\newline Listenpreis: \SI{34511}{\sieuro}&1&\SI{45}{\%}&\SI{18981.05}{\sieuro}\\
2 &\textbf{Werkzeugsatz} (G7104C\#001)\newline Werkzeugsatz für Agilent 1260/1290 Infinity II LC-Systeme.\newline Listenpreis: \SI{390}{\sieuro}&1&\SI{45}{\%}&\SI{214.5}{\sieuro}\\
3 &\textbf{InfinityLab StaySafe Starter-Kit} (G7104C\#034)\newline Enthält StaySafe-Verschlüsse für Lösemittelflaschen, Belüftungsventile mit Indikatorstreifen und Fittinge.\newline Listenpreis: \SI{687}{\sieuro}&1&\SI{45}{\%}&\SI{377.85}{\sieuro}\\
4 &\textbf{Poroshell 120 Säule} (G7104C\#097)\newline Poroshell 120 EC-C18, 3,0 x 150 mm, 2,7 µm.\newline Listenpreis: \SI{1}{\sieuro}&1&\SI{45}{\%}&\SI{0.55}{\sieuro}\\
5 &\textbf{Vialsampler} (G7129C)\newline 1260 Infinity II Prime automatischer Flüssigprobengeber zur Verwendung bei bis zu 800 bar. Mit integriertem Nadelspülanschluss zur Minimierung der Verschleppung, 100 µl Dosiereinheit und 100 µl Probenschleife. Inklusive Gerätetreiber für ein LC-System (2D-UV).\newline Listenpreis: \SI{19966}{\sieuro}&1&\SI{45}{\%}&\SI{10981.3}{\sieuro}\\
6 &\textbf{Probenteller für 6x11 2,0 ml Vials} (G7129C\#010)\newline \newline Listenpreis: \SI{371}{\sieuro}&1&\SI{45}{\%}&\SI{204.05}{\sieuro}\\
7 &\textbf{Vorhandene Agilent CDS-Lizenz} (G7129C\#060)\newline Es ist vorgesehen, dass dieses Agilent LC- System von dem Agilent OpenLAB Chromatography Datensystem 2.x gesteuert wird. Es wird eine vorhandene Lizenz genutzt.\newline Listenpreis: \SI{-1793}{\sieuro}&1&\SI{45}{\%}&\SI{-986.15}{\sieuro}\\
8 &\textbf{Probenthermostat} (G7129C\#101)\newline Agilent InfinityLab Thermostat zur Probentemperierung zwischen 4 °C und 40 °C.\newline Listenpreis: \SI{5928}{\sieuro}&1&\SI{45}{\%}&\SI{3260.4}{\sieuro}\\
9 &\textbf{Säulenthermostat} (G7116A)\newline 1260 Infinity II Thermostat für bis zu vier 30 cm Säulen, Temperaturbereich: 10° unter Raumtemperatur (min. 4 °C) bis max. 85 °C, inkl. Säulenidentifikations-Kit. Ventilantrieb optional.\newline Listenpreis: \SI{6494}{\sieuro}&1&\SI{45}{\%}&\SI{3571.7}{\sieuro}\\
10 &\textbf{InfinityLab Quick Connect Assembly} (5067-6166)\newline Quick Connect Fitting mit Edelstahlkapillare (0,17 x 105 mm) für dauerhaft dichte Kapillarverbindungen ohne Totvolumen bis 1300 bar einfach, schnell, wiederverwendbar.\newline Listenpreis: \SI{361}{\sieuro}&1&\SI{45}{\%}&\SI{198.55}{\sieuro}\\
11 &\textbf{InfinityLab Quick Connect Assembly} (5067-5960)\newline Quick Connect Fitting mit Edelstahlkapillare (0,12 x 280 mm) für dauerhaft dichte Kapillarverbindungen ohne Totvolumen bis 1300 bar einfach, schnell, wiederverwendbar.\newline Listenpreis: \SI{360}{\sieuro}&1&\SI{45}{\%}&\SI{198}{\sieuro}\\
12 &\textbf{Diodenarraydetektor WR} (G7115A)\newline 1260 Infinity II Diodenarray-Detektor wide range (Messbereich 190 950 nm), schnelle Multiwellenlängen- und Spektralanalysen mit Datenraten bis zu 120 Hz. RFID-Tags für Durchflusszelle und Lampe, inkl. Deuterium- und Wolframlampen mit langer Lebensdauer.\newline Listenpreis: \SI{23432}{\sieuro}&1&\SI{45}{\%}&\SI{12887.6}{\sieuro}\\
13 &\textbf{Flusszelle für DAD} (G7115A\#018)\newline Standarddurchflusszelle: 10 mm, 13 µl, max. 120 bar.\newline Listenpreis: \SI{1514}{\sieuro}&1&\SI{45}{\%}&\SI{832.7}{\sieuro}\\
14 &\textbf{Fluoreszenzspektrendetektor} (G7121B)\newline 1260 Infinity II Fluoreszenzdetektor, spektrenfähig.\newline Für Multiwellenlängen-Detektion, Online-Aufnahme von  Anregungs- und Emissionsspektren (200 1200 nm), Datenrate bis 148 Hz. Inkl. Standard-Durchflusszelle (V = 8 µl, max. 20 bar).\newline Listenpreis: \SI{21984}{\sieuro}&1&\SI{45}{\%}&\SI{12091.2}{\sieuro}\\
15 &\textbf{Fraktionssammler} (G1364F)\newline 1260 Infinity II Analytischer Fraktionssammler, maximale Flussrate bis 10 ml/min. Mit Standardkapillarkit, optimiert für Flüsse von 1-5 ml/min.\newline Listenpreis: \SI{15916}{\sieuro}&1&\SI{45}{\%}&\SI{8753.8}{\sieuro}\\
16 &\textbf{} (G1364-84545)\newline \newline Listenpreis: \SI{1059}{\sieuro}&1&\SI{45}{\%}&\SI{582.45}{\sieuro}\\
17 &\textbf{OpenLab CDS 2 Instrument Connection} (M8431AA)\newline \newline Listenpreis: \SI{1364}{\sieuro}&2&\SI{45}{\%}&\SI{1500.4}{\sieuro}\\
18 &\textbf{OpenLab CDS 2 IC für LC} (M8431AA\#001)\newline Lizenz und Treiber zur Gerätesteuerung unter OpenLab CDS. Gerätetyp: LC (ohne DAD)\newline Listenpreis: \SI{0}{\sieuro}&1&\SI{45}{\%}&\SI{0}{\sieuro}\\
19 &\textbf{OpenLab CDS 2 IC für 3D-UV/DAD} (M8431AA\#005)\newline Lizenz und Treiber zur Gerätesteuerung unter OpenLab CDS. Gerätetyp: 3D-UV/DAD\newline Listenpreis: \SI{0}{\sieuro}&1&\SI{45}{\%}&\SI{0}{\sieuro}\\
20 &\textbf{1260 Infinity II HPLC mit Zusatzfunktionen} (SYS-LC-1260IIE)\newline \newline Listenpreis: \SI{0}{\sieuro}&1&\SI{20}{\%}&\SI{0}{\sieuro}\\
21 &\textbf{Erweiterte Gewährleistung Plus (3 Jahre)} (SYS-LC-1260IIE\#1A3)\newline Erweiterte Gewährleistung Plus - 3 Jahre insgesamt. Enthält zusätzlich zur Gewährleistung ein vorbeugende Wartung nach einem Jahr.\newline Listenpreis: \SI{19031}{\sieuro}&1&\SI{20}{\%}&\SI{15224.8}{\sieuro}\\
22 &\textbf{Einweisung und First Run Assist} (SYS-LC-1260IIE\#2C9)\newline Einweisung für neue Anwender und zusätzlich Unterstützung bei der Einrichtung der ersten Methode (erfordert Prüfung der Methode vorab durch Agilent).\newline Listenpreis: \SI{1193}{\sieuro}&1&\SI{20}{\%}&\SI{954.4}{\sieuro}\\
23 &\textbf{Installation and Operational Qualification} (SYS-LC-1260IIE\#6H9)\newline Gerätequalifizierung (IQ/OQ) im Rahmen der Installation.\newline Listenpreis: \SI{5519}{\sieuro}&1&\SI{20}{\%}&\SI{4415.2}{\sieuro}\\
24 &\textbf{Agilent Training Credits} (R4999A)\newline Dedicated Agilent University Training Credits: Kursinfo online nachschlagbar: \url{www.agilent.com/chem/course_lookup}\newline Listenpreis: \SI{1.27}{\sieuro}&8800&\SI{20}{\%}&\SI{8976}{\sieuro}\\
\hline
\end{longtable}
\end{center}
\vspace{-2cm}
\begin{flushright}
\begin{tabular}{|rr|}
\hline
\textbf{Summe netto} & \SI{103220.35}{\sieuro}\\
\textbf{Versand und Bereitstellungskosten (3\%)} & \SI{3000}{\sieuro}\\
\textbf{Gesamtsumme netto} & \SI{106220.35}{\sieuro}\\
\textbf{Umsatzsteuer (19\%)} & \SI{20181.8665}{\sieuro}\\
\textbf{Gesamtsumme brutto} & \SI{126402.2165}{\sieuro}\\
\hline
\end{tabular}
\end{flushright}
Der Betrag versteht sich zzgl. der gesetzlichen Steuern.\\
Diese werden im Rechnungszeitraum auf der Rechnung gesondert ausgewiesen.\\
Zahlungsbedingungen: 30 Tage netto ab Rechnungsdatum.\\
Incoterm (2010) für Lieferungen innerhalb Deutschlands: DDP.
\begin{small}
\textbf{Gewährleistung:}\\
Die Gewährleistung für Zubehör und Ersatzteilprodukte und für Analytik-Hardwareprodukte beträgt 12 Monate.
\textbf{Hinweis:}\\
Für den Verkauf der in diesem Angebot aufgeführten Standard-Produkte und -Services gelten die aktuellen \emph{Agilent Geschäftsbedingungen} und alle sonstigen anwendbaren Zusatzbedingungen sowie zusätzliche Bedingungen, soweit darauf hier Bezug genommen wird. Soweit Produkte oder Services nach speziellen Kundenanforderungen hergestellt, konfiguriert oder angepasst werden, gelten für den Verkauf aller in diesem Angebot aufgeführten Produkte und Services die aktuellen \emph{Agilent Geschäftsbedingungen für kundenspezifische Produkte} und alle sonstigen anwendbaren Zusatzbedingungen sowie zusätzliche Bedingungen, soweit darauf hier Bezug genommen wird. Eine Kopie der maßgeblichen Bedingungen ist entweder beigefügt oder wurde Ihnen bereits zur Verfügung gestellt. Sollten Sie keine Kopie erhalten haben oder eine weitere Kopie benötigen, setzen Sie sich bitte mit uns in Verbindung. Soweit Sie mit Agilent eine gesonderte Vereinbarung getroffen haben, die den Verkauf der in diesem Angebot aufgeführten Produkte und Services umfasst, sind die Bestimmungen dieser Vereinbarung anwendbar. Abweichende oder ergänzende Vereinbarungen, insbesondere widersprechende Geschäftsbedingungen, sind nur gültig, wenn sie ausdrücklich schriftlich vereinbart worden sind. Die angegebenen Daten zur Verfügbarkeit von Produkten und Services sind vorläufig. Die tatsächlichen Lieferzeiten bzw. Lieferperioden werden Ihnen bei Auftragsbestätigung mitgeteilt. Waren, Technologien oder Software, die aus den Vereinigten Staaten von Amerika (\emph{USA}) oder anderen exportierenden Ländern ausgeführt werden, unterliegen den Ausfuhrbestimmungen der USA sowie anderer Rechtsordnungen. Bei Ausfuhr ist der Kunde dafür verantwortlich, dass die anwendbaren Ausfuhrbestimmungen eingehalten werden.
\end{small}
\begin{scriptsize}
Agilent Technologies Deutschland GmbH, Hewlett-Packard-Str. 8, D-76337 Waldbronn\\
Telefon +49 (0)7243-602-0\\
USt.-IdNr.: DE812729296, WEEE-Reg.-Nr. DE 86631749\\
Sitz der Gesellschaft: Waldbronn Amtsgericht Mannheim, HRB 723782\\
Geschäftsführer: Dr. Andreas Kistner (Vorsitzender der Geschäftsführung), Armin Jehle, Norbert Sabatzki, Dr. Knut Wintergerst\\
\href{www.agilent.com}{www.agilent.com}
\end{scriptsize}
\end{document}

@ -0,0 +1,26 @@
# Part Number Opt PL Description Qty Price EUR Breaks EUR Uplift % Total Discount % Net EUR Total EUR Sales Discount YA9% Contractual Discount Y99% Promotion Discount Y07% Demo Discount Y04% PH Code PH Description YMax
1 G7104C 29 1260 Infinity II Flexible Pumpe 1 34511 0 0 45 18981.05 18981.05 45 0 0 0 ISL100P1 Pumps
2 G7104C 001 29 HPLC System Tool-Kit 1260 Infinity II 1 390 0 0 45 214.5 214.5 45 0 0 0
3 G7104C 034 29 InfinityLab Stay Safe Verschl., St.-Kit 1 687 0 0 45 377.85 377.85 45 0 0 0
4 G7104C 097 29 Poroshell 120 EC-C18 3,0x150mm, 2,7um 1 1 0 0 45 0.55 0.55 45 0 0 0
5 G7129C 29 1260 Inf. II Fluessigprobengeber 1 19966 0 0 45 10981.3 10981.3 45 0 0 0 ISL100A1 Autosamplers
6 G7129C 010 29 Standard-Schublade (6x11 Probenflaschen) 1 371 0 0 45 204.05 204.05 45 0 0 0
7 G7129C 060 29 Nutzung vorhandene Lizenz 1 -1793 0 0 45 -986.15 -986.15 45 0 0 0
8 G7129C 101 29 Agilent InfinityLab Proben-Thermostat 1 5928 0 0 45 3260.4 3260.4 45 0 0 0
9 G7116A 29 1260 Infinity II Therm. f. mehr. Saeulen 1 6494 0 0 45 3571.7 3571.7 45 0 0 0 ISL100LC1 LC Hardware
10 5067-6166 58 Quick Connect Einheit ST 0,17 x 105mm 1 361 0 0 45 198.55 198.55 45 0 0 0 CSSL00SL20 LC General Supplies
11 5067-5960 58 Quick Connect Einheit ST 0,12 x 280mm 1 360 0 0 45 198 198 45 0 0 0 CSSL00SL20 LC General Supplies
12 G7115A 29 1260 Infinity II Diodenarray-Detektor WR 1 23432 0 0 45 12887.6 12887.6 45 0 0 0 ISL100D1 Detectors
13 G7115A 018 29 Standarddurchflussz. 10mm, 13ul, 120bar 1 1514 0 0 45 832.7 832.7 45 0 0 0
14 G7121B 29 1260 Infinity II FLD Spektren 1 21984 0 0 45 12091.2 12091.2 45 0 0 0 ISL100D1 Detectors
15 G1364F 29 1260 Infinity II Analyt. Fraktionssamml. 1 15916 0 0 45 8753.8 8753.8 45 0 0 0 ISL100FC Fraction Collectors
16 G1364-84545 AA Teller fuer 126 Leitungen 16x100mm 14 ml 1 1059 0 0 45 582.45 582.45 45 0 0 0 CSSL01SL40 LC Instrument Supplies
17 M8431AA LI OpenLAB CDS Geraeteverbindung 2 1364 0 0 45 750.2 1500.4 45 0 0 0 ISF300F100 OpenLAB CDS Software
18 M8431AA 001 LI LC-Geraeteverbindung 1 0 0 0 45 0 0 45 0 0 0
19 M8431AA 005 LI 3D UV/DAD-Verb. 1 0 0 0 45 0 0 45 0 0 0
20 SYS-LC-1260IIE 74 LC 1260 Infinity II System m. Zusatzfkt. 1 0 0 0 20 0 0 20 0 0 0 TSSYS0SYLC Service Systems - Liquid Chromatography
21 SYS-LC-1260IIE 1A3 74 Erweit. Gewaehrl. Plus 3 Jahre insg. 1 19031 0 0 20 15224.8 15224.8 13 0 7 0 TSSYS3 Serviced As Systems - 3 YR
22 SYS-LC-1260IIE 2C9 74 Einweisung zum ersten Methodenlauf 1 1193 0 0 20 954.4 954.4 20 0 0 0 TSSTRN Training Services
23 SYS-LC-1260IIE 6H9 74 Analysegeraet-Qualifizierung-auf Wunsch 1 5519 0 0 20 4415.2 4415.2 20 0 0 0 TSSYS1 Serviced As Systems - 1 YR
24 R4999A 74 1 Agilent Training Credit 8800 1.27 0 0 20 1.02 8976 20 0 0 0 TSSTRN Training Services
1 # Part Number Opt PL Description Qty Price EUR Breaks EUR Uplift % Total Discount % Net EUR Total EUR Sales Discount YA9% Contractual Discount Y99% Promotion Discount Y07% Demo Discount Y04% PH Code PH Description YMax
2 1 G7104C 29 1260 Infinity II Flexible Pumpe 1 34511 0 0 45 18981.05 18981.05 45 0 0 0 ISL100P1 Pumps
3 2 G7104C 001 29 HPLC System Tool-Kit 1260 Infinity II 1 390 0 0 45 214.5 214.5 45 0 0 0
4 3 G7104C 034 29 InfinityLab Stay Safe Verschl., St.-Kit 1 687 0 0 45 377.85 377.85 45 0 0 0
5 4 G7104C 097 29 Poroshell 120 EC-C18 3,0x150mm, 2,7um 1 1 0 0 45 0.55 0.55 45 0 0 0
6 5 G7129C 29 1260 Inf. II Fluessigprobengeber 1 19966 0 0 45 10981.3 10981.3 45 0 0 0 ISL100A1 Autosamplers
7 6 G7129C 010 29 Standard-Schublade (6x11 Probenflaschen) 1 371 0 0 45 204.05 204.05 45 0 0 0
8 7 G7129C 060 29 Nutzung vorhandene Lizenz 1 -1793 0 0 45 -986.15 -986.15 45 0 0 0
9 8 G7129C 101 29 Agilent InfinityLab Proben-Thermostat 1 5928 0 0 45 3260.4 3260.4 45 0 0 0
10 9 G7116A 29 1260 Infinity II Therm. f. mehr. Saeulen 1 6494 0 0 45 3571.7 3571.7 45 0 0 0 ISL100LC1 LC Hardware
11 10 5067-6166 58 Quick Connect Einheit ST 0,17 x 105mm 1 361 0 0 45 198.55 198.55 45 0 0 0 CSSL00SL20 LC General Supplies
12 11 5067-5960 58 Quick Connect Einheit ST 0,12 x 280mm 1 360 0 0 45 198 198 45 0 0 0 CSSL00SL20 LC General Supplies
13 12 G7115A 29 1260 Infinity II Diodenarray-Detektor WR 1 23432 0 0 45 12887.6 12887.6 45 0 0 0 ISL100D1 Detectors
14 13 G7115A 018 29 Standarddurchflussz. 10mm, 13ul, 120bar 1 1514 0 0 45 832.7 832.7 45 0 0 0
15 14 G7121B 29 1260 Infinity II FLD Spektren 1 21984 0 0 45 12091.2 12091.2 45 0 0 0 ISL100D1 Detectors
16 15 G1364F 29 1260 Infinity II Analyt. Fraktionssamml. 1 15916 0 0 45 8753.8 8753.8 45 0 0 0 ISL100FC Fraction Collectors
17 16 G1364-84545 AA Teller fuer 126 Leitungen 16x100mm 14 ml 1 1059 0 0 45 582.45 582.45 45 0 0 0 CSSL01SL40 LC Instrument Supplies
18 17 M8431AA LI OpenLAB CDS Geraeteverbindung 2 1364 0 0 45 750.2 1500.4 45 0 0 0 ISF300F100 OpenLAB CDS Software
19 18 M8431AA 001 LI LC-Geraeteverbindung 1 0 0 0 45 0 0 45 0 0 0
20 19 M8431AA 005 LI 3D UV/DAD-Verb. 1 0 0 0 45 0 0 45 0 0 0
21 20 SYS-LC-1260IIE 74 LC 1260 Infinity II System m. Zusatzfkt. 1 0 0 0 20 0 0 20 0 0 0 TSSYS0SYLC Service Systems - Liquid Chromatography
22 21 SYS-LC-1260IIE 1A3 74 Erweit. Gewaehrl. Plus – 3 Jahre insg. 1 19031 0 0 20 15224.8 15224.8 13 0 7 0 TSSYS3 Serviced As Systems - 3 YR
23 22 SYS-LC-1260IIE 2C9 74 Einweisung zum ersten Methodenlauf 1 1193 0 0 20 954.4 954.4 20 0 0 0 TSSTRN Training Services
24 23 SYS-LC-1260IIE 6H9 74 Analysegeraet-Qualifizierung-auf Wunsch 1 5519 0 0 20 4415.2 4415.2 20 0 0 0 TSSYS1 Serviced As Systems - 1 YR
25 24 R4999A 74 1 Agilent Training Credit 8800 1.27 0 0 20 1.02 8976 20 0 0 0 TSSTRN Training Services

@ -12,13 +12,10 @@ namespace Gremlin_BlazorServer.Services
public static string ReadResource(string name)
{
Assembly assembly = Assembly.GetExecutingAssembly();
// Format: "{Namespace}.{Folder}.{filename}.{Extension}"
string resourcePath = name.StartsWith(nameof(Gremlin_BlazorServer)) ? name : assembly.GetManifestResourceNames().Single(str => str.EndsWith(name));
using Stream? stream = assembly.GetManifestResourceStream(resourcePath);
if (stream == null) { return ""; }
using StreamReader reader = new(stream);
return reader.ReadToEnd();
}
@ -32,41 +29,34 @@ namespace Gremlin_BlazorServer.Services
return encoding;
}
public static void WriteClipboardToTsv(string clipboard, Quote quote)
public static void WriteQuoteToTsv(string quoteContent, Quote quote)
{
string datei = $"{quote.Path}{Path.DirectorySeparatorChar}{quote.QuotationNumber}.tsv";
FileInfo fileInfo = new(datei);
if (fileInfo.Directory == null)
{
return;
}
if (fileInfo.Directory == null) return;
if (!fileInfo.Directory.Exists)
{
try { _ = Directory.CreateDirectory(fileInfo.DirectoryName ?? ""); }
catch (Exception ex) { Debug.WriteLine(ex); }
try
{
Directory.CreateDirectory(fileInfo.DirectoryName ?? "");
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
}
using StreamWriter writer = new(datei, false, Encoding.UTF8);
{
writer.WriteLine(clipboard);
writer.WriteLine(quoteContent);
}
}
public static void WriteTexFile(Quote quote)
{
string datei = $"{quote.Path}{Path.DirectorySeparatorChar}{quote.QuotationNumber}.tex";
FileInfo fileInfo = new(datei);
if (fileInfo.Directory == null)
{
return;
}
if (fileInfo.Directory == null) return;
if (!fileInfo.Directory.Exists) { _ = Directory.CreateDirectory(fileInfo.DirectoryName ?? ""); }
using StreamWriter writer = new(datei, false, Encoding.UTF8);
{
writer.WriteLine(quote.Tex);

@ -8,7 +8,6 @@ namespace Gremlin_BlazorServer.Utilities.GUClasses
private readonly Dictionary<string, int> mappingTable; //Mapping Spaltenzahl <-> Property/(übersetzte) Spaltenüberschrift
private List<DataIdType> DataTypes { get; set; } = new();
public DataIdentificator(Dictionary<string, int> mT)
{
mappingTable = mT;
@ -27,12 +26,10 @@ namespace Gremlin_BlazorServer.Utilities.GUClasses
if (qualifier.DataType == currentDataType)
{
identifierOfCurrentType.Add(qualifier.Identifier);
if (qualifier == dataIdentifier[^1]) //letztes Element der Liste
{
DataIdType typeToBeAdded = new(currentDataType, identifierOfCurrentType);
DataTypes.Add(typeToBeAdded);
//_currentDataType = qualifier.DataType;
}
if (qualifier != dataIdentifier[^1]) continue; //letztes Element der Liste
DataIdType typeToBeAdded = new(currentDataType, identifierOfCurrentType);
DataTypes.Add(typeToBeAdded);
//_currentDataType = qualifier.DataType;
}
else
{
@ -48,84 +45,38 @@ namespace Gremlin_BlazorServer.Utilities.GUClasses
public List<string> Identify(bool mustMatchAllQualifer = true)
{
List<string> winners = new();
foreach (DataIdType datatype in DataTypes)
{
foreach (string qualifier in datatype.Qualifiers)
{
if (mappingTable.ContainsKey(qualifier))
{
datatype.AddFoundQualfier(qualifier);
}
if (mappingTable.ContainsKey(qualifier)) datatype.AddFoundQualfier(qualifier);
}
}
if (mustMatchAllQualifer)
{
foreach (DataIdType dataType in DataTypes) //may return multiple winners
{
if (dataType.AllQualifierMatched)
{
winners.Add(dataType.DataType);
}
}
}
winners.AddRange(from dataType in DataTypes
where dataType.AllQualifierMatched
select dataType.DataType);
else //return the winner by highest score:
{
winners.Add(DataTypes.Aggregate((x, y) => x.Score > y.Score ? x : y).DataType.ToString());
}
//Plausibilty checkpoint:
//1. Remove "PL", "AccountType", "Submarket" from Winner-List, if detected datatype is "LSAG" or "Account".
//2. LSAG = Account + Contact --> when LSAG is a winner, remove "LSAG" and add "Account" and "Contact" to use their dedicated import methods.
//3. Remove any other winner, when winner is one of "PL", "AccountType", "Submarket" AND fields[].count = 2.
if (mustMatchAllQualifer && winners.Contains("LSAG"))
{
if (winners.Contains("ProductLine"))
{
_ = winners.Remove("ProductLine");
}
if (winners.Contains("AccountType"))
{
_ = winners.Remove("AccountType");
}
if (winners.Contains("SubMarket"))
{
_ = winners.Remove("SubMarket");
}
if (winners.Contains("Account"))
{
_ = winners.Remove("Account");
}
if (winners.Contains("Contact"))
{
_ = winners.Remove("Contact");
}
if (winners.Contains("ProductLine")) winners.Remove("ProductLine");
if (winners.Contains("AccountType")) winners.Remove("AccountType");
if (winners.Contains("SubMarket")) winners.Remove("SubMarket");
if (winners.Contains("Account")) winners.Remove("Account");
if (winners.Contains("Contact")) winners.Remove("Contact");
}
switch (mustMatchAllQualifer)
{
case true when winners.Contains("Account"):
{
if (winners.Contains("ProductLine"))
{
_ = winners.Remove("ProductLine");
}
if (winners.Contains("AccountType"))
{
_ = winners.Remove("AccountType");
}
if (winners.Contains("SubMarket"))
{
_ = winners.Remove("SubMarket");
}
if (winners.Contains("ProductLine")) winners.Remove("ProductLine");
if (winners.Contains("AccountType")) winners.Remove("AccountType");
if (winners.Contains("SubMarket")) winners.Remove("SubMarket");
break;
}
case false when mappingTable.Count == 2:
@ -135,23 +86,19 @@ namespace Gremlin_BlazorServer.Utilities.GUClasses
winners.Clear();
winners.Add("ProductLine");
}
if (winners.Contains("AccountType"))
{
winners.Clear();
winners.Add("AccountType");
}
if (winners.Contains("SubMarket"))
{
winners.Clear();
winners.Add("SubMarket");
}
break;
}
}
return winners;
}
@ -160,11 +107,7 @@ namespace Gremlin_BlazorServer.Utilities.GUClasses
List<DataIdentifier> result = new(50);
string fileInput = FileService.ReadResource("DataIdentifier.txt");
string[] lines = fileInput.Split(Environment.NewLine);
foreach (string line in lines)
{
string[] fields = line.Split("|");
result.Add(new(fields[0], fields[1]));
}
result.AddRange(lines.Select(line => line.Split("|")).Select(fields => new DataIdentifier(fields[0], fields[1])));
return result;
}